@ohhwells/bridge 0.1.124 → 0.1.126-next.347

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,117 @@ 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
+ // Floor so YouTube's own control chrome (volume tooltip, CC, related-videos
1822
+ // overlay) has enough room on narrow mobile widths — 16:9 alone can shrink
1823
+ // below what that fixed-size chrome needs and it starts clipping.
1824
+ minHeight: 250,
1825
+ borderRadius: AI_TREE_TOKENS.radiusCard,
1826
+ overflow: "hidden",
1827
+ background: "#DBEAFE"
1828
+ },
1829
+ children: !videoId ? /* @__PURE__ */ jsx(
1830
+ "div",
1831
+ {
1832
+ style: {
1833
+ position: "absolute",
1834
+ inset: 0,
1835
+ display: "flex",
1836
+ alignItems: "center",
1837
+ justifyContent: "center",
1838
+ color: "#93C5FD",
1839
+ fontSize: 13
1840
+ },
1841
+ children: "video"
1842
+ }
1843
+ ) : playing ? /* @__PURE__ */ jsx(
1844
+ "iframe",
1845
+ {
1846
+ src: `https://www.youtube-nocookie.com/embed/${videoId}?autoplay=1&mute=1&rel=0`,
1847
+ title: caption || "YouTube video",
1848
+ style: { position: "absolute", inset: 0, width: "100%", height: "100%", border: 0 },
1849
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture",
1850
+ allowFullScreen: true,
1851
+ sandbox: "allow-scripts allow-same-origin allow-presentation allow-popups allow-popups-to-escape-sandbox",
1852
+ loading: "lazy"
1853
+ }
1854
+ ) : /* @__PURE__ */ jsxs(
1855
+ "button",
1856
+ {
1857
+ type: "button",
1858
+ onClick: () => setPlaying(true),
1859
+ "aria-label": "Play video",
1860
+ style: {
1861
+ position: "absolute",
1862
+ inset: 0,
1863
+ width: "100%",
1864
+ height: "100%",
1865
+ border: 0,
1866
+ padding: 0,
1867
+ margin: 0,
1868
+ cursor: "pointer",
1869
+ background: "none"
1870
+ },
1871
+ children: [
1872
+ /* @__PURE__ */ jsx(
1873
+ "img",
1874
+ {
1875
+ src: `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`,
1876
+ alt: "",
1877
+ style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
1878
+ }
1879
+ ),
1880
+ /* @__PURE__ */ jsx(
1881
+ "span",
1882
+ {
1883
+ style: {
1884
+ position: "absolute",
1885
+ top: "50%",
1886
+ left: "50%",
1887
+ transform: "translate(-50%, -50%)",
1888
+ width: 64,
1889
+ height: 64,
1890
+ borderRadius: "50%",
1891
+ background: "rgba(0,0,0,0.65)",
1892
+ display: "flex",
1893
+ alignItems: "center",
1894
+ justifyContent: "center"
1895
+ },
1896
+ children: /* @__PURE__ */ jsx(Play, { size: 28, color: "#fff", fill: "#fff" })
1897
+ }
1898
+ )
1899
+ ]
1900
+ }
1901
+ )
1902
+ }
1903
+ ),
1904
+ caption && /* @__PURE__ */ jsx(
1905
+ "div",
1906
+ {
1907
+ ...textAttrs(ctx, `${path}.caption`),
1908
+ style: {
1909
+ ...typeStyle(AI_TREE_TOKENS.type.bodyM, ctx.brand.fonts.body),
1910
+ color: ctx.brand.palette.dark,
1911
+ textAlign: "center"
1912
+ },
1913
+ children: caption
1914
+ }
1915
+ )
1916
+ ] });
1917
+ }
1760
1918
  function ButtonEl({
1761
1919
  slots,
1762
1920
  ctx,
@@ -2764,7 +2922,7 @@ function CollectionBlock({ node, ctx, path }) {
2764
2922
  return /* @__PURE__ */ jsx(
2765
2923
  "div",
2766
2924
  {
2767
- "data-ai-grid": "",
2925
+ "data-ai-grid": String(itemsPerRow),
2768
2926
  "data-ohw-pricing-collection": isPricing ? "" : void 0,
2769
2927
  style: {
2770
2928
  display: "grid",
@@ -2837,6 +2995,8 @@ function renderNode(node, ctx, path) {
2837
2995
  editPath: `${path}.source`
2838
2996
  }
2839
2997
  );
2998
+ case "video":
2999
+ return /* @__PURE__ */ jsx(VideoEmbed, { slots, ctx, path });
2840
3000
  case "media-list": {
2841
3001
  const stacked = slots.layout === "stack";
2842
3002
  return /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: stacked ? 0 : AI_TREE_TOKENS.spacing3 }, children: (node.children ?? []).map((child, i) => /* @__PURE__ */ jsx(
@@ -3123,6 +3283,7 @@ function AiTreeRenderer({
3123
3283
  {
3124
3284
  "data-ai-section": tree.tag ?? "",
3125
3285
  ...bgAttrs,
3286
+ "data-ai-responsive": "",
3126
3287
  style: {
3127
3288
  position: "relative",
3128
3289
  padding: `${pad}px 0`,
@@ -3133,12 +3294,13 @@ function AiTreeRenderer({
3133
3294
  color: settings.sectionBackground === "accent" ? blockBrand.palette.dark : void 0
3134
3295
  },
3135
3296
  children: [
3136
- isOverlay && backgroundUrl && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
3297
+ /* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
3137
3298
  /* @__PURE__ */ jsx("style", { children: AI_MOBILE_CSS }),
3299
+ isOverlay && backgroundUrl && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
3138
3300
  /* @__PURE__ */ jsx(
3139
3301
  "div",
3140
3302
  {
3141
- "data-ai-container": "",
3303
+ "data-ai-section-inner": "",
3142
3304
  style: {
3143
3305
  position: "relative",
3144
3306
  maxWidth: AI_TREE_TOKENS.sectionMaxWidth,
@@ -3149,7 +3311,7 @@ function AiTreeRenderer({
3149
3311
  children: tree.rows.map((row, r2) => /* @__PURE__ */ jsx(
3150
3312
  "div",
3151
3313
  {
3152
- "data-ai-row": "",
3314
+ "data-ai-columns": "",
3153
3315
  style: {
3154
3316
  display: "grid",
3155
3317
  gridTemplateColumns: "repeat(12, 1fr)",
@@ -3553,9 +3715,10 @@ function applyAiSectionsToDom(state, options) {
3553
3715
  if (existing && existing.serialized === serialized && existing.container.isConnected) {
3554
3716
  continue;
3555
3717
  }
3556
- const isNewMount = !existing || !existing.container.isConnected;
3557
3718
  let container = existing?.container;
3719
+ let isNewMount = false;
3558
3720
  if (!container || !container.isConnected) {
3721
+ isNewMount = true;
3559
3722
  existing?.root.unmount();
3560
3723
  container?.remove();
3561
3724
  container = document.createElement("div");
@@ -9343,7 +9506,7 @@ function FieldTypePicker({ onPick }) {
9343
9506
 
9344
9507
  // src/ui/MediaOverlay.tsx
9345
9508
  import * as React8 from "react";
9346
- import { Film, ImageIcon, Pause, Play, Volume2, VolumeX } from "lucide-react";
9509
+ import { Film, ImageIcon, Pause, Play as Play2, Volume2, VolumeX } from "lucide-react";
9347
9510
 
9348
9511
  // src/ui/button.tsx
9349
9512
  import * as React7 from "react";
@@ -9450,6 +9613,7 @@ function MediaOverlay({
9450
9613
  (prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
9451
9614
  );
9452
9615
  }, [isVideo]);
9616
+ const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
9453
9617
  const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
9454
9618
  const box = {
9455
9619
  position: "fixed",
@@ -9514,7 +9678,7 @@ function MediaOverlay({
9514
9678
  e.stopPropagation();
9515
9679
  onVideoSettingsChange?.(hover.key, { autoplay: !autoplay });
9516
9680
  },
9517
- children: autoplay ? /* @__PURE__ */ jsx15(Pause, { size: 14 }) : /* @__PURE__ */ jsx15(Play, { size: 14 })
9681
+ children: autoplay ? /* @__PURE__ */ jsx15(Pause, { size: 14 }) : /* @__PURE__ */ jsx15(Play2, { size: 14 })
9518
9682
  }
9519
9683
  ),
9520
9684
  /* @__PURE__ */ jsx15(
@@ -9548,11 +9712,10 @@ function MediaOverlay({
9548
9712
  className: "flex items-center justify-center cursor-pointer",
9549
9713
  style: {
9550
9714
  ...box,
9551
- // When text overlays this media, let clicks fall THROUGH to the text underneath. In the
9552
- // parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
9553
- // in-document, pointer-events does it natively. The button below opts back in, so
9554
- // Replace still works.
9555
- pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
9715
+ // Visual only. `pointer-events: auto` on this full-bleed rect covered the navbar
9716
+ // (hero bg includes the absolute TopNav) and swallowed CTA press-drag. Text overlay
9717
+ // and cueOnly also need clicks to fall through — Replace / video controls opt back in.
9718
+ pointerEvents: "none",
9556
9719
  // Selected: a firm component ring with no wash, so the image reads as chosen rather
9557
9720
  // than hovered. Hover keeps the existing tinted preview.
9558
9721
  boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
@@ -9579,17 +9742,17 @@ function MediaOverlay({
9579
9742
  },
9580
9743
  children: [
9581
9744
  isVideo ? /* @__PURE__ */ jsx15(Film, { size: 14 }) : /* @__PURE__ */ jsx15(ImageIcon, { size: 14 }),
9582
- isVideo ? "Replace video" : "Replace image"
9745
+ replaceLabel
9583
9746
  ]
9584
9747
  }
9585
9748
  ),
9586
- replaceMode === "none" || cueOnly ? null : /* @__PURE__ */ jsxs7(
9749
+ showChrome && replaceMode !== "none" && /* @__PURE__ */ jsxs7(
9587
9750
  Button,
9588
9751
  {
9589
9752
  "data-ohw-media-overlay": "",
9590
9753
  variant: "outline",
9591
9754
  size: "sm",
9592
- "aria-label": isVideo ? "Replace video" : "Replace image",
9755
+ "aria-label": replaceLabel,
9593
9756
  className: "gap-1.5 cursor-pointer hover:bg-background",
9594
9757
  style: {
9595
9758
  ...OVERLAY_BUTTON_STYLE,
@@ -9612,7 +9775,7 @@ function MediaOverlay({
9612
9775
  },
9613
9776
  children: [
9614
9777
  isVideo ? /* @__PURE__ */ jsx15(Film, { size: 14 }) : /* @__PURE__ */ jsx15(ImageIcon, { size: 14 }),
9615
- replaceMode === "full" ? isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image" : null
9778
+ replaceMode === "full" ? replaceLabel : null
9616
9779
  ]
9617
9780
  }
9618
9781
  )
@@ -11268,7 +11431,497 @@ function AiPricingCardOverlay({
11268
11431
  window.addEventListener("blur", onBlur);
11269
11432
  return () => window.removeEventListener("blur", onBlur);
11270
11433
  }, []);
11271
- useEffect6(() => {
11434
+ useEffect6(() => {
11435
+ const onKeyDown = (e) => {
11436
+ if (e.key !== "Escape") return;
11437
+ if (!activeRef.current) return;
11438
+ setActive(null);
11439
+ setError(null);
11440
+ };
11441
+ document.addEventListener("keydown", onKeyDown);
11442
+ return () => document.removeEventListener("keydown", onKeyDown);
11443
+ }, []);
11444
+ const findEntry = useCallback4(
11445
+ (sectionId) => {
11446
+ const state = parseAiSectionsState(aiSectionsRef.current);
11447
+ return state.sections.find((s) => s.id === sectionId) ?? null;
11448
+ },
11449
+ [aiSectionsRef]
11450
+ );
11451
+ const runMutation = useCallback4(
11452
+ async (sectionId, mutate) => {
11453
+ const entry = findEntry(sectionId);
11454
+ if (!entry) return false;
11455
+ const nextTree = mutate(entry.tree);
11456
+ if (!nextTree) return false;
11457
+ setPending(true);
11458
+ setError(null);
11459
+ const { ok, reasons } = await requestValidateTree2(postToParent2, nextTree);
11460
+ setPending(false);
11461
+ if (!ok) {
11462
+ setError(reasons[0] ?? "That change is not allowed.");
11463
+ return false;
11464
+ }
11465
+ applyTreeLocalRef.current?.({
11466
+ id: sectionId,
11467
+ mode: "replace",
11468
+ targetSectionId: sectionId,
11469
+ tree: nextTree,
11470
+ label: entry.label,
11471
+ media: entry.media,
11472
+ ...entry.brand ? { brand: entry.brand } : {},
11473
+ // The user is already looking at the card they just edited — recentering the
11474
+ // viewport on every tier add/remove/toggle reads as the section jumping around.
11475
+ skipScrollIntoView: true
11476
+ });
11477
+ return true;
11478
+ },
11479
+ [findEntry, postToParent2, applyTreeLocalRef]
11480
+ );
11481
+ const activeEntry = active ? findEntry(active.sectionId) : null;
11482
+ const activeCardRect = useLiveCardRect(active);
11483
+ const hoverHandleRect = useLiveCardRect(!active && hover ? hover : null);
11484
+ return /* @__PURE__ */ jsxs11(Fragment7, { children: [
11485
+ hoverHandleRect && hover && /* @__PURE__ */ jsx19(
11486
+ "button",
11487
+ {
11488
+ type: "button",
11489
+ "data-ohw-toolbar": "",
11490
+ onClick: () => setActive(hover),
11491
+ "aria-label": "Configure pricing tier",
11492
+ style: {
11493
+ position: "fixed",
11494
+ top: hoverHandleRect.top + 8,
11495
+ left: hoverHandleRect.left + hoverHandleRect.width - 36,
11496
+ width: 28,
11497
+ height: 28,
11498
+ borderRadius: 8,
11499
+ border: `1.5px dashed ${PRIMARY4}`,
11500
+ background: "#ffffff",
11501
+ color: PRIMARY4,
11502
+ display: "flex",
11503
+ alignItems: "center",
11504
+ justifyContent: "center",
11505
+ cursor: "pointer",
11506
+ zIndex: 2147483643,
11507
+ fontSize: 14,
11508
+ fontWeight: 700
11509
+ },
11510
+ children: /* @__PURE__ */ jsx19(Star2, { size: 14, style: { pointerEvents: "none" } })
11511
+ }
11512
+ ),
11513
+ activeCardRect && active && activeEntry && /* @__PURE__ */ jsx19(
11514
+ ItemInteractionLayer,
11515
+ {
11516
+ rect: activeCardRect,
11517
+ state: "active-top",
11518
+ toolbar: /* @__PURE__ */ jsx19(
11519
+ PricingCardToolbar,
11520
+ {
11521
+ entry: activeEntry,
11522
+ index: active.index,
11523
+ pending,
11524
+ error,
11525
+ onAddTier: () => runMutation(active.sectionId, addPricingTier),
11526
+ onRemoveTier: () => {
11527
+ void runMutation(active.sectionId, (tree) => removePricingTier(tree, active.index)).then(
11528
+ (applied) => {
11529
+ if (applied) setActive(null);
11530
+ }
11531
+ );
11532
+ },
11533
+ onToggleFeatured: (enabled) => runMutation(
11534
+ active.sectionId,
11535
+ (tree) => setPricingCardFeatured(tree, active.index, { enabled })
11536
+ ),
11537
+ onSetTreatment: (treatment) => runMutation(
11538
+ active.sectionId,
11539
+ (tree) => setPricingCardFeatured(tree, active.index, { enabled: true, treatment })
11540
+ ),
11541
+ onAddButton: () => runMutation(active.sectionId, (tree) => addPricingCardButton(tree, active.index, "Learn more")),
11542
+ onRemoveButton: () => runMutation(active.sectionId, (tree) => removePricingCardButton(tree, active.index)),
11543
+ onAddFeature: () => runMutation(active.sectionId, (tree) => addPricingCardFeature(tree, active.index, "New feature")),
11544
+ onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
11545
+ }
11546
+ )
11547
+ }
11548
+ )
11549
+ ] });
11550
+ }
11551
+
11552
+ // src/ui/ai-section/AiVideoOverlay.tsx
11553
+ import { useCallback as useCallback5, useEffect as useEffect7, useRef as useRef7, useState as useState9 } from "react";
11554
+ import { Star as Star3 } from "lucide-react";
11555
+
11556
+ // src/lib/ai-video-tree.ts
11557
+ function resolveVideoBlock(tree, path) {
11558
+ const segments = path.split(".");
11559
+ const rowSeg = segments[0];
11560
+ const blockSeg = segments[1];
11561
+ if (!rowSeg?.startsWith("r") || !blockSeg?.startsWith("b")) return null;
11562
+ let node = tree.rows[Number(rowSeg.slice(1))]?.blocks[Number(blockSeg.slice(1))];
11563
+ for (const seg of segments.slice(2)) {
11564
+ if (!node || !seg.startsWith("c")) return null;
11565
+ node = node.children?.[Number(seg.slice(1))];
11566
+ }
11567
+ return node && node.type === "video" ? node : null;
11568
+ }
11569
+ function withVideo(tree, path, mutate) {
11570
+ const next = JSON.parse(JSON.stringify(tree));
11571
+ const block = resolveVideoBlock(next, path);
11572
+ if (!block) return null;
11573
+ block.slots = block.slots ?? {};
11574
+ return mutate(block) ? next : null;
11575
+ }
11576
+ function videoIdAt(tree, path) {
11577
+ const block = resolveVideoBlock(tree, path);
11578
+ const id = block?.slots?.videoId;
11579
+ return typeof id === "string" ? id : "";
11580
+ }
11581
+ function setVideoId(tree, path, videoId) {
11582
+ return withVideo(tree, path, (block) => {
11583
+ block.slots = { ...block.slots, videoId };
11584
+ return true;
11585
+ });
11586
+ }
11587
+ function clearVideo(tree, path) {
11588
+ return withVideo(tree, path, (block) => {
11589
+ const slots = { ...block.slots };
11590
+ delete slots.videoId;
11591
+ block.slots = slots;
11592
+ return true;
11593
+ });
11594
+ }
11595
+
11596
+ // src/lib/youtube.ts
11597
+ var YOUTUBE_ID_PATTERN = /^[A-Za-z0-9_-]{11}$/;
11598
+ function extractYouTubeId(input) {
11599
+ const trimmed = input.trim();
11600
+ if (!trimmed) return null;
11601
+ if (YOUTUBE_ID_PATTERN.test(trimmed)) return trimmed;
11602
+ let url;
11603
+ try {
11604
+ url = new URL(trimmed);
11605
+ } catch {
11606
+ return null;
11607
+ }
11608
+ const host = url.hostname.replace(/^www\./, "");
11609
+ if (host !== "youtube.com" && host !== "m.youtube.com" && host !== "youtu.be" && host !== "youtube-nocookie.com") {
11610
+ return null;
11611
+ }
11612
+ let candidate = null;
11613
+ if (host === "youtu.be") {
11614
+ candidate = url.pathname.slice(1).split("/")[0] ?? null;
11615
+ } else if (url.pathname === "/watch") {
11616
+ candidate = url.searchParams.get("v");
11617
+ } else {
11618
+ const match = url.pathname.match(/^\/(?:embed|shorts)\/([^/]+)/);
11619
+ candidate = match ? match[1] : null;
11620
+ }
11621
+ return candidate && YOUTUBE_ID_PATTERN.test(candidate) ? candidate : null;
11622
+ }
11623
+
11624
+ // src/ui/ai-section/AiVideoOverlay.tsx
11625
+ import { Fragment as Fragment8, jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
11626
+ var PRIMARY5 = "#0885FE";
11627
+ var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY5})`;
11628
+ var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
11629
+ function findVideoBlockElement(sectionId, path) {
11630
+ const sectionEl = findByInstanceId(sectionId);
11631
+ if (!sectionEl) return null;
11632
+ const items = sectionEl.querySelectorAll("[data-ohw-video-block]");
11633
+ for (const el of Array.from(items)) {
11634
+ if (el.dataset.ohwVideoPath === path) return el;
11635
+ }
11636
+ return null;
11637
+ }
11638
+ function readRect4(ref) {
11639
+ const el = ref && findVideoBlockElement(ref.sectionId, ref.path);
11640
+ if (!el) return null;
11641
+ const r2 = el.getBoundingClientRect();
11642
+ if (r2.width <= 0 || r2.height <= 0) return null;
11643
+ return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
11644
+ }
11645
+ function useLiveBlockRect(ref) {
11646
+ const [rect, setRect] = useState9(null);
11647
+ useEffect7(() => {
11648
+ if (!ref) {
11649
+ setRect(null);
11650
+ return;
11651
+ }
11652
+ const update = () => {
11653
+ const next = readRect4(ref);
11654
+ setRect(
11655
+ (prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
11656
+ );
11657
+ };
11658
+ update();
11659
+ const opts = { capture: true, passive: true };
11660
+ window.addEventListener("scroll", update, opts);
11661
+ window.addEventListener("resize", update);
11662
+ const interval = setInterval(update, 500);
11663
+ return () => {
11664
+ window.removeEventListener("scroll", update, opts);
11665
+ window.removeEventListener("resize", update);
11666
+ clearInterval(interval);
11667
+ };
11668
+ }, [ref?.sectionId, ref?.path]);
11669
+ return rect;
11670
+ }
11671
+ function requestValidateTree3(postToParent2, tree) {
11672
+ return new Promise((resolve) => {
11673
+ const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
11674
+ const timeout = window.setTimeout(() => {
11675
+ window.removeEventListener("message", onMessage);
11676
+ resolve({ ok: false, reasons: ["Validation request timed out."] });
11677
+ }, 8e3);
11678
+ function onMessage(e) {
11679
+ if (e.data?.type !== "ow:ai-validate-tree-result" || e.data.id !== id) return;
11680
+ window.clearTimeout(timeout);
11681
+ window.removeEventListener("message", onMessage);
11682
+ resolve({ ok: e.data.ok === true, reasons: Array.isArray(e.data.reasons) ? e.data.reasons : [] });
11683
+ }
11684
+ window.addEventListener("message", onMessage);
11685
+ postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
11686
+ });
11687
+ }
11688
+ function Pill3({
11689
+ label,
11690
+ onClick,
11691
+ disabled
11692
+ }) {
11693
+ return /* @__PURE__ */ jsx20(
11694
+ "button",
11695
+ {
11696
+ type: "button",
11697
+ onClick,
11698
+ disabled,
11699
+ style: {
11700
+ height: 28,
11701
+ padding: "0 10px",
11702
+ display: "inline-flex",
11703
+ alignItems: "center",
11704
+ gap: 4,
11705
+ borderRadius: 999,
11706
+ border: "none",
11707
+ cursor: disabled ? "default" : "pointer",
11708
+ background: "#ffffff",
11709
+ color: OHW_BLUE_DARK3,
11710
+ opacity: disabled ? 0.4 : 1,
11711
+ fontSize: 12,
11712
+ lineHeight: "16px",
11713
+ fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
11714
+ whiteSpace: "nowrap",
11715
+ flex: "0 0 auto"
11716
+ },
11717
+ children: label
11718
+ }
11719
+ );
11720
+ }
11721
+ function watchUrl(id) {
11722
+ return `https://www.youtube.com/watch?v=${id}`;
11723
+ }
11724
+ function VideoUrlInput({ value, onCommit }) {
11725
+ const [draft, setDraft] = useState9(value ? watchUrl(value) : "");
11726
+ const [invalid, setInvalid] = useState9(false);
11727
+ useEffect7(() => {
11728
+ setDraft(value ? watchUrl(value) : "");
11729
+ setInvalid(false);
11730
+ }, [value]);
11731
+ const commit = () => {
11732
+ const next = draft.trim();
11733
+ if (!next) {
11734
+ setInvalid(false);
11735
+ if (value) onCommit(null);
11736
+ return;
11737
+ }
11738
+ const id = extractYouTubeId(next);
11739
+ if (!id) return setInvalid(true);
11740
+ setInvalid(false);
11741
+ setDraft(watchUrl(id));
11742
+ if (id !== value) onCommit(id);
11743
+ };
11744
+ const handleChange = (next) => {
11745
+ setDraft(next);
11746
+ const id = extractYouTubeId(next.trim());
11747
+ if (id && id !== value) {
11748
+ setInvalid(false);
11749
+ onCommit(id);
11750
+ }
11751
+ };
11752
+ return /* @__PURE__ */ jsxs12("div", { style: { display: "flex", flexDirection: "column", gap: 4, width: "100%", maxWidth: 280 }, children: [
11753
+ /* @__PURE__ */ jsxs12(
11754
+ "div",
11755
+ {
11756
+ style: {
11757
+ display: "flex",
11758
+ alignItems: "center",
11759
+ gap: 6,
11760
+ height: 28,
11761
+ padding: "0 12px",
11762
+ borderRadius: 999,
11763
+ background: "#ffffff",
11764
+ width: "100%",
11765
+ boxSizing: "border-box",
11766
+ boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
11767
+ },
11768
+ children: [
11769
+ /* @__PURE__ */ jsx20(
11770
+ "span",
11771
+ {
11772
+ style: {
11773
+ flex: "0 0 auto",
11774
+ color: OHW_BLUE_DARK3,
11775
+ fontSize: 10,
11776
+ lineHeight: "16px",
11777
+ fontWeight: 700,
11778
+ textTransform: "uppercase",
11779
+ letterSpacing: 0.4
11780
+ },
11781
+ children: "Video"
11782
+ }
11783
+ ),
11784
+ /* @__PURE__ */ jsx20(
11785
+ "input",
11786
+ {
11787
+ type: "text",
11788
+ inputMode: "url",
11789
+ value: draft,
11790
+ onChange: (e) => handleChange(e.target.value),
11791
+ onBlur: commit,
11792
+ onKeyDown: (e) => {
11793
+ if (e.key === "Enter") e.currentTarget.blur();
11794
+ if (e.key === "Escape") {
11795
+ setDraft(value ? watchUrl(value) : "");
11796
+ setInvalid(false);
11797
+ e.currentTarget.blur();
11798
+ }
11799
+ },
11800
+ placeholder: "Paste a YouTube URL",
11801
+ "aria-label": "YouTube video URL",
11802
+ "aria-invalid": invalid,
11803
+ style: {
11804
+ flex: 1,
11805
+ minWidth: 0,
11806
+ border: "none",
11807
+ outline: "none",
11808
+ background: "transparent",
11809
+ padding: 0,
11810
+ margin: 0,
11811
+ fontSize: 12,
11812
+ lineHeight: "16px",
11813
+ fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
11814
+ color: "#1f2937"
11815
+ }
11816
+ }
11817
+ )
11818
+ ]
11819
+ }
11820
+ ),
11821
+ 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." })
11822
+ ] });
11823
+ }
11824
+ function VideoToolbar({
11825
+ videoId,
11826
+ pending,
11827
+ error,
11828
+ onSetVideoId,
11829
+ onRemove
11830
+ }) {
11831
+ return /* @__PURE__ */ jsxs12(
11832
+ "div",
11833
+ {
11834
+ "data-ohw-bridge": "",
11835
+ "data-ohw-toolbar": "",
11836
+ onMouseDown: (e) => e.stopPropagation(),
11837
+ style: {
11838
+ display: "flex",
11839
+ flexDirection: "column",
11840
+ gap: 6,
11841
+ alignItems: "center",
11842
+ width: 280,
11843
+ background: OHW_BLUE3,
11844
+ padding: 8,
11845
+ borderRadius: 12,
11846
+ boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
11847
+ pointerEvents: pending ? "none" : "auto",
11848
+ opacity: pending ? 0.6 : 1
11849
+ },
11850
+ children: [
11851
+ /* @__PURE__ */ jsx20(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
11852
+ /* @__PURE__ */ jsx20(Pill3, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
11853
+ error && /* @__PURE__ */ jsx20("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
11854
+ ]
11855
+ }
11856
+ );
11857
+ }
11858
+ function AiVideoOverlay({
11859
+ postToParent: postToParent2,
11860
+ aiSectionsRef,
11861
+ applyTreeLocalRef,
11862
+ clearInteractionChromeRef
11863
+ }) {
11864
+ const [hover, setHover] = useState9(null);
11865
+ const [active, setActive] = useState9(null);
11866
+ const [pending, setPending] = useState9(false);
11867
+ const [error, setError] = useState9(null);
11868
+ const activeRef = useRef7(null);
11869
+ activeRef.current = active;
11870
+ useEffect7(() => {
11871
+ const onMove = (e) => {
11872
+ const t = e.target;
11873
+ if (!(t instanceof HTMLElement)) return;
11874
+ 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]")) {
11875
+ return;
11876
+ }
11877
+ const blockEl = t.closest("[data-ohw-video-block]");
11878
+ if (!blockEl) {
11879
+ setHover(null);
11880
+ return;
11881
+ }
11882
+ const sectionEl = blockEl.closest("[data-ohw-section]");
11883
+ const unit = sectionEl ? movableUnit(sectionEl) : null;
11884
+ const sectionId = unit ? instanceIdOf(unit) || null : null;
11885
+ const path = blockEl.dataset.ohwVideoPath;
11886
+ if (!sectionId || !path) {
11887
+ setHover(null);
11888
+ return;
11889
+ }
11890
+ setHover({ sectionId, path });
11891
+ };
11892
+ const onLeave = () => setHover(null);
11893
+ document.addEventListener("mousemove", onMove, { passive: true });
11894
+ document.documentElement.addEventListener("mouseleave", onLeave);
11895
+ return () => {
11896
+ document.removeEventListener("mousemove", onMove);
11897
+ document.documentElement.removeEventListener("mouseleave", onLeave);
11898
+ };
11899
+ }, []);
11900
+ useEffect7(() => {
11901
+ const onClick = (e) => {
11902
+ const current = activeRef.current;
11903
+ if (!current) return;
11904
+ const t = e.target;
11905
+ if (!(t instanceof HTMLElement)) return;
11906
+ if (t.closest("[data-ohw-item-interaction]")) return;
11907
+ const blockEl = findVideoBlockElement(current.sectionId, current.path);
11908
+ if (blockEl && blockEl.contains(t)) return;
11909
+ setActive(null);
11910
+ setError(null);
11911
+ };
11912
+ document.addEventListener("click", onClick, true);
11913
+ return () => document.removeEventListener("click", onClick, true);
11914
+ }, []);
11915
+ useEffect7(() => {
11916
+ const onBlur = () => {
11917
+ if (!activeRef.current) return;
11918
+ setActive(null);
11919
+ setError(null);
11920
+ };
11921
+ window.addEventListener("blur", onBlur);
11922
+ return () => window.removeEventListener("blur", onBlur);
11923
+ }, []);
11924
+ useEffect7(() => {
11272
11925
  const onKeyDown = (e) => {
11273
11926
  if (e.key !== "Escape") return;
11274
11927
  if (!activeRef.current) return;
@@ -11278,14 +11931,14 @@ function AiPricingCardOverlay({
11278
11931
  document.addEventListener("keydown", onKeyDown);
11279
11932
  return () => document.removeEventListener("keydown", onKeyDown);
11280
11933
  }, []);
11281
- const findEntry = useCallback4(
11934
+ const findEntry = useCallback5(
11282
11935
  (sectionId) => {
11283
11936
  const state = parseAiSectionsState(aiSectionsRef.current);
11284
11937
  return state.sections.find((s) => s.id === sectionId) ?? null;
11285
11938
  },
11286
11939
  [aiSectionsRef]
11287
11940
  );
11288
- const runMutation = useCallback4(
11941
+ const runMutation = useCallback5(
11289
11942
  async (sectionId, mutate) => {
11290
11943
  const entry = findEntry(sectionId);
11291
11944
  if (!entry) return false;
@@ -11293,7 +11946,7 @@ function AiPricingCardOverlay({
11293
11946
  if (!nextTree) return false;
11294
11947
  setPending(true);
11295
11948
  setError(null);
11296
- const { ok, reasons } = await requestValidateTree2(postToParent2, nextTree);
11949
+ const { ok, reasons } = await requestValidateTree3(postToParent2, nextTree);
11297
11950
  setPending(false);
11298
11951
  if (!ok) {
11299
11952
  setError(reasons[0] ?? "That change is not allowed.");
@@ -11306,26 +11959,28 @@ function AiPricingCardOverlay({
11306
11959
  tree: nextTree,
11307
11960
  label: entry.label,
11308
11961
  media: entry.media,
11309
- ...entry.brand ? { brand: entry.brand } : {},
11310
- // The user is already looking at the card they just edited — recentering the
11311
- // viewport on every tier add/remove/toggle reads as the section jumping around.
11312
- skipScrollIntoView: true
11962
+ ...entry.brand ? { brand: entry.brand } : {}
11313
11963
  });
11314
11964
  return true;
11315
11965
  },
11316
11966
  [findEntry, postToParent2, applyTreeLocalRef]
11317
11967
  );
11318
11968
  const activeEntry = active ? findEntry(active.sectionId) : null;
11319
- const activeCardRect = useLiveCardRect(active);
11320
- const hoverHandleRect = useLiveCardRect(!active && hover ? hover : null);
11321
- return /* @__PURE__ */ jsxs11(Fragment7, { children: [
11322
- hoverHandleRect && hover && /* @__PURE__ */ jsx19(
11969
+ const hoverHandleRect = useLiveBlockRect(!active && hover ? hover : null);
11970
+ const activeBlockRect = useLiveBlockRect(active);
11971
+ const TOOLBAR_APPROX_H = 90;
11972
+ const toolbarState = activeBlockRect && activeBlockRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
11973
+ return /* @__PURE__ */ jsxs12(Fragment8, { children: [
11974
+ hoverHandleRect && hover && /* @__PURE__ */ jsx20(
11323
11975
  "button",
11324
11976
  {
11325
11977
  type: "button",
11326
11978
  "data-ohw-toolbar": "",
11327
- onClick: () => setActive(hover),
11328
- "aria-label": "Configure pricing tier",
11979
+ onClick: () => {
11980
+ clearInteractionChromeRef.current();
11981
+ setActive(hover);
11982
+ },
11983
+ "aria-label": "Configure video",
11329
11984
  style: {
11330
11985
  position: "fixed",
11331
11986
  top: hoverHandleRect.top + 8,
@@ -11333,9 +11988,9 @@ function AiPricingCardOverlay({
11333
11988
  width: 28,
11334
11989
  height: 28,
11335
11990
  borderRadius: 8,
11336
- border: `1.5px dashed ${PRIMARY4}`,
11991
+ border: `1.5px dashed ${PRIMARY5}`,
11337
11992
  background: "#ffffff",
11338
- color: PRIMARY4,
11993
+ color: PRIMARY5,
11339
11994
  display: "flex",
11340
11995
  alignItems: "center",
11341
11996
  justifyContent: "center",
@@ -11344,41 +11999,29 @@ function AiPricingCardOverlay({
11344
11999
  fontSize: 14,
11345
12000
  fontWeight: 700
11346
12001
  },
11347
- children: /* @__PURE__ */ jsx19(Star2, { size: 14, style: { pointerEvents: "none" } })
12002
+ children: /* @__PURE__ */ jsx20(Star3, { size: 14, style: { pointerEvents: "none" } })
11348
12003
  }
11349
12004
  ),
11350
- activeCardRect && active && activeEntry && /* @__PURE__ */ jsx19(
12005
+ activeBlockRect && active && activeEntry && /* @__PURE__ */ jsx20(
11351
12006
  ItemInteractionLayer,
11352
12007
  {
11353
- rect: activeCardRect,
11354
- state: "active-top",
11355
- toolbar: /* @__PURE__ */ jsx19(
11356
- PricingCardToolbar,
12008
+ rect: activeBlockRect,
12009
+ state: toolbarState,
12010
+ toolbar: /* @__PURE__ */ jsx20(
12011
+ VideoToolbar,
11357
12012
  {
11358
- entry: activeEntry,
11359
- index: active.index,
12013
+ videoId: videoIdAt(activeEntry.tree, active.path),
11360
12014
  pending,
11361
12015
  error,
11362
- onAddTier: () => runMutation(active.sectionId, addPricingTier),
11363
- onRemoveTier: () => {
11364
- void runMutation(active.sectionId, (tree) => removePricingTier(tree, active.index)).then(
11365
- (applied) => {
11366
- if (applied) setActive(null);
11367
- }
12016
+ onSetVideoId: (videoId) => {
12017
+ void runMutation(
12018
+ active.sectionId,
12019
+ (tree) => videoId ? setVideoId(tree, active.path, videoId) : clearVideo(tree, active.path)
11368
12020
  );
11369
12021
  },
11370
- onToggleFeatured: (enabled) => runMutation(
11371
- active.sectionId,
11372
- (tree) => setPricingCardFeatured(tree, active.index, { enabled })
11373
- ),
11374
- onSetTreatment: (treatment) => runMutation(
11375
- active.sectionId,
11376
- (tree) => setPricingCardFeatured(tree, active.index, { enabled: true, treatment })
11377
- ),
11378
- onAddButton: () => runMutation(active.sectionId, (tree) => addPricingCardButton(tree, active.index, "Learn more")),
11379
- onRemoveButton: () => runMutation(active.sectionId, (tree) => removePricingCardButton(tree, active.index)),
11380
- onAddFeature: () => runMutation(active.sectionId, (tree) => addPricingCardFeature(tree, active.index, "New feature")),
11381
- onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
12022
+ onRemove: () => {
12023
+ void runMutation(active.sectionId, (tree) => clearVideo(tree, active.path));
12024
+ }
11382
12025
  }
11383
12026
  )
11384
12027
  }
@@ -11697,28 +12340,28 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
11697
12340
  }
11698
12341
 
11699
12342
  // src/ui/link-modal/LinkPopover.tsx
11700
- import { useEffect as useEffect10 } from "react";
12343
+ import { useEffect as useEffect11 } from "react";
11701
12344
 
11702
12345
  // src/ui/dialog.tsx
11703
12346
  import * as React9 from "react";
11704
12347
  import { Dialog as DialogPrimitive } from "radix-ui";
11705
12348
  import { X as X2 } from "lucide-react";
11706
- import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
12349
+ import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
11707
12350
  function Dialog2({
11708
12351
  ...props
11709
12352
  }) {
11710
- return /* @__PURE__ */ jsx20(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
12353
+ return /* @__PURE__ */ jsx21(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
11711
12354
  }
11712
12355
  function DialogPortal({
11713
12356
  ...props
11714
12357
  }) {
11715
- return /* @__PURE__ */ jsx20(DialogPrimitive.Portal, { ...props });
12358
+ return /* @__PURE__ */ jsx21(DialogPrimitive.Portal, { ...props });
11716
12359
  }
11717
12360
  function DialogOverlay({
11718
12361
  className,
11719
12362
  ...props
11720
12363
  }) {
11721
- return /* @__PURE__ */ jsx20(
12364
+ return /* @__PURE__ */ jsx21(
11722
12365
  DialogPrimitive.Overlay,
11723
12366
  {
11724
12367
  "data-slot": "dialog-overlay",
@@ -11731,9 +12374,9 @@ function DialogOverlay({
11731
12374
  var DialogContent = React9.forwardRef(
11732
12375
  ({ className, children, showCloseButton = true, container, ...props }, ref) => {
11733
12376
  const positionMode = container ? "absolute" : "fixed";
11734
- return /* @__PURE__ */ jsxs12(DialogPortal, { container: container ?? void 0, children: [
11735
- /* @__PURE__ */ jsx20(DialogOverlay, { className: cn(positionMode, "inset-0") }),
11736
- /* @__PURE__ */ jsxs12(
12377
+ return /* @__PURE__ */ jsxs13(DialogPortal, { container: container ?? void 0, children: [
12378
+ /* @__PURE__ */ jsx21(DialogOverlay, { className: cn(positionMode, "inset-0") }),
12379
+ /* @__PURE__ */ jsxs13(
11737
12380
  DialogPrimitive.Content,
11738
12381
  {
11739
12382
  ref,
@@ -11749,13 +12392,13 @@ var DialogContent = React9.forwardRef(
11749
12392
  ...props,
11750
12393
  children: [
11751
12394
  children,
11752
- showCloseButton ? /* @__PURE__ */ jsx20(
12395
+ showCloseButton ? /* @__PURE__ */ jsx21(
11753
12396
  DialogPrimitive.Close,
11754
12397
  {
11755
12398
  type: "button",
11756
12399
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
11757
12400
  "aria-label": "Close",
11758
- children: /* @__PURE__ */ jsx20(X2, { size: 16, "aria-hidden": true })
12401
+ children: /* @__PURE__ */ jsx21(X2, { size: 16, "aria-hidden": true })
11759
12402
  }
11760
12403
  ) : null
11761
12404
  ]
@@ -11769,13 +12412,13 @@ function DialogHeader({
11769
12412
  className,
11770
12413
  ...props
11771
12414
  }) {
11772
- return /* @__PURE__ */ jsx20("div", { className: cn("flex flex-col gap-1.5", className), ...props });
12415
+ return /* @__PURE__ */ jsx21("div", { className: cn("flex flex-col gap-1.5", className), ...props });
11773
12416
  }
11774
12417
  function DialogFooter({
11775
12418
  className,
11776
12419
  ...props
11777
12420
  }) {
11778
- return /* @__PURE__ */ jsx20(
12421
+ return /* @__PURE__ */ jsx21(
11779
12422
  "div",
11780
12423
  {
11781
12424
  className: cn("flex items-center justify-end gap-2", className),
@@ -11783,7 +12426,7 @@ function DialogFooter({
11783
12426
  }
11784
12427
  );
11785
12428
  }
11786
- var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx20(
12429
+ var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx21(
11787
12430
  DialogPrimitive.Title,
11788
12431
  {
11789
12432
  ref,
@@ -11795,7 +12438,7 @@ var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE
11795
12438
  }
11796
12439
  ));
11797
12440
  DialogTitle.displayName = DialogPrimitive.Title.displayName;
11798
- var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx20(
12441
+ var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx21(
11799
12442
  DialogPrimitive.Description,
11800
12443
  {
11801
12444
  ref,
@@ -11811,19 +12454,19 @@ import { Info, X as X4 } from "lucide-react";
11811
12454
 
11812
12455
  // src/ui/link-modal/DestinationBreadcrumb.tsx
11813
12456
  import { ArrowRight as ArrowRight2, File, GalleryVertical } from "lucide-react";
11814
- import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
12457
+ import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
11815
12458
  function DestinationBreadcrumb({
11816
12459
  pageTitle,
11817
12460
  sectionLabel
11818
12461
  }) {
11819
- return /* @__PURE__ */ jsxs13("div", { className: "flex w-full flex-col gap-2", children: [
11820
- /* @__PURE__ */ jsx21("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
11821
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-3", children: [
11822
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
11823
- /* @__PURE__ */ jsx21(File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
11824
- /* @__PURE__ */ jsx21("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
12462
+ return /* @__PURE__ */ jsxs14("div", { className: "flex w-full flex-col gap-2", children: [
12463
+ /* @__PURE__ */ jsx22("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
12464
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-3", children: [
12465
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
12466
+ /* @__PURE__ */ jsx22(File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
12467
+ /* @__PURE__ */ jsx22("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
11825
12468
  ] }),
11826
- /* @__PURE__ */ jsx21(
12469
+ /* @__PURE__ */ jsx22(
11827
12470
  ArrowRight2,
11828
12471
  {
11829
12472
  size: 16,
@@ -11831,8 +12474,8 @@ function DestinationBreadcrumb({
11831
12474
  "aria-hidden": true
11832
12475
  }
11833
12476
  ),
11834
- /* @__PURE__ */ jsxs13("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
11835
- /* @__PURE__ */ jsx21(
12477
+ /* @__PURE__ */ jsxs14("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
12478
+ /* @__PURE__ */ jsx22(
11836
12479
  GalleryVertical,
11837
12480
  {
11838
12481
  size: 16,
@@ -11840,7 +12483,7 @@ function DestinationBreadcrumb({
11840
12483
  "aria-hidden": true
11841
12484
  }
11842
12485
  ),
11843
- /* @__PURE__ */ jsx21("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
12486
+ /* @__PURE__ */ jsx22("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
11844
12487
  ] })
11845
12488
  ] })
11846
12489
  ] });
@@ -11848,22 +12491,22 @@ function DestinationBreadcrumb({
11848
12491
 
11849
12492
  // src/ui/link-modal/SectionTreeItem.tsx
11850
12493
  import { GalleryVertical as GalleryVertical2 } from "lucide-react";
11851
- import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
12494
+ import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
11852
12495
  function SectionTreeItem({
11853
12496
  section,
11854
12497
  onSelect,
11855
12498
  selected
11856
12499
  }) {
11857
12500
  const interactive = Boolean(onSelect);
11858
- return /* @__PURE__ */ jsxs14("div", { className: "flex h-9 w-full items-end pl-3", children: [
11859
- /* @__PURE__ */ jsx22(
12501
+ return /* @__PURE__ */ jsxs15("div", { className: "flex h-9 w-full items-end pl-3", children: [
12502
+ /* @__PURE__ */ jsx23(
11860
12503
  "div",
11861
12504
  {
11862
12505
  className: "-mr-px h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
11863
12506
  "aria-hidden": true
11864
12507
  }
11865
12508
  ),
11866
- /* @__PURE__ */ jsxs14(
12509
+ /* @__PURE__ */ jsxs15(
11867
12510
  "div",
11868
12511
  {
11869
12512
  role: interactive ? "button" : void 0,
@@ -11881,7 +12524,7 @@ function SectionTreeItem({
11881
12524
  interactive && selected && "border-bridge-primary"
11882
12525
  ),
11883
12526
  children: [
11884
- /* @__PURE__ */ jsx22(
12527
+ /* @__PURE__ */ jsx23(
11885
12528
  GalleryVertical2,
11886
12529
  {
11887
12530
  size: 16,
@@ -11889,7 +12532,7 @@ function SectionTreeItem({
11889
12532
  "aria-hidden": true
11890
12533
  }
11891
12534
  ),
11892
- /* @__PURE__ */ jsx22("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
12535
+ /* @__PURE__ */ jsx23("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
11893
12536
  ]
11894
12537
  }
11895
12538
  )
@@ -11897,14 +12540,14 @@ function SectionTreeItem({
11897
12540
  }
11898
12541
 
11899
12542
  // src/ui/link-modal/UrlOrPageInput.tsx
11900
- import { useEffect as useEffect7, useId as useId2, useRef as useRef7, useState as useState9 } from "react";
12543
+ import { useEffect as useEffect8, useId as useId2, useRef as useRef8, useState as useState10 } from "react";
11901
12544
 
11902
12545
  // src/ui/input.tsx
11903
12546
  import * as React10 from "react";
11904
- import { jsx as jsx23 } from "react/jsx-runtime";
12547
+ import { jsx as jsx24 } from "react/jsx-runtime";
11905
12548
  var Input = React10.forwardRef(
11906
12549
  ({ className, type, ...props }, ref) => {
11907
- return /* @__PURE__ */ jsx23(
12550
+ return /* @__PURE__ */ jsx24(
11908
12551
  "input",
11909
12552
  {
11910
12553
  type,
@@ -11923,9 +12566,9 @@ Input.displayName = "Input";
11923
12566
 
11924
12567
  // src/ui/label.tsx
11925
12568
  import { Label as LabelPrimitive } from "radix-ui";
11926
- import { jsx as jsx24 } from "react/jsx-runtime";
12569
+ import { jsx as jsx25 } from "react/jsx-runtime";
11927
12570
  function Label({ className, ...props }) {
11928
- return /* @__PURE__ */ jsx24(
12571
+ return /* @__PURE__ */ jsx25(
11929
12572
  LabelPrimitive.Root,
11930
12573
  {
11931
12574
  "data-slot": "label",
@@ -11937,11 +12580,11 @@ function Label({ className, ...props }) {
11937
12580
 
11938
12581
  // src/ui/link-modal/UrlOrPageInput.tsx
11939
12582
  import { ChevronDown as ChevronDown3, File as File2, X as X3 } from "lucide-react";
11940
- import { jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
12583
+ import { jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
11941
12584
  function FieldChevron({
11942
12585
  onClick
11943
12586
  }) {
11944
- return /* @__PURE__ */ jsx25(
12587
+ return /* @__PURE__ */ jsx26(
11945
12588
  "button",
11946
12589
  {
11947
12590
  type: "button",
@@ -11949,7 +12592,7 @@ function FieldChevron({
11949
12592
  onClick,
11950
12593
  "aria-label": "Open page list",
11951
12594
  tabIndex: -1,
11952
- children: /* @__PURE__ */ jsx25(ChevronDown3, { size: 16 })
12595
+ children: /* @__PURE__ */ jsx26(ChevronDown3, { size: 16 })
11953
12596
  }
11954
12597
  );
11955
12598
  }
@@ -11966,10 +12609,10 @@ function UrlOrPageInput({
11966
12609
  urlError
11967
12610
  }) {
11968
12611
  const inputId = useId2();
11969
- const inputRef = useRef7(null);
11970
- const rootRef = useRef7(null);
11971
- const [isFocused, setIsFocused] = useState9(false);
11972
- useEffect7(() => {
12612
+ const inputRef = useRef8(null);
12613
+ const rootRef = useRef8(null);
12614
+ const [isFocused, setIsFocused] = useState10(false);
12615
+ useEffect8(() => {
11973
12616
  if (!dropdownOpen) return;
11974
12617
  const isOutside = (e) => {
11975
12618
  const root = rootRef.current;
@@ -12010,11 +12653,11 @@ function UrlOrPageInput({
12010
12653
  "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]",
12011
12654
  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"
12012
12655
  );
12013
- return /* @__PURE__ */ jsxs15("div", { className: "flex w-full flex-col gap-2 p-0", children: [
12014
- /* @__PURE__ */ jsx25(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
12015
- /* @__PURE__ */ jsxs15("div", { ref: rootRef, className: "relative w-full", children: [
12016
- /* @__PURE__ */ jsxs15("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
12017
- selectedPage ? /* @__PURE__ */ jsx25("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ jsx25(
12656
+ return /* @__PURE__ */ jsxs16("div", { className: "flex w-full flex-col gap-2 p-0", children: [
12657
+ /* @__PURE__ */ jsx26(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
12658
+ /* @__PURE__ */ jsxs16("div", { ref: rootRef, className: "relative w-full", children: [
12659
+ /* @__PURE__ */ jsxs16("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
12660
+ selectedPage ? /* @__PURE__ */ jsx26("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ jsx26(
12018
12661
  File2,
12019
12662
  {
12020
12663
  size: 16,
@@ -12022,7 +12665,7 @@ function UrlOrPageInput({
12022
12665
  "aria-hidden": true
12023
12666
  }
12024
12667
  ) }) : null,
12025
- readOnly ? /* @__PURE__ */ jsx25("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ jsx25(
12668
+ readOnly ? /* @__PURE__ */ jsx26("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ jsx26(
12026
12669
  Input,
12027
12670
  {
12028
12671
  ref: inputRef,
@@ -12048,7 +12691,7 @@ function UrlOrPageInput({
12048
12691
  )
12049
12692
  }
12050
12693
  ),
12051
- selectedPage && !readOnly ? /* @__PURE__ */ jsx25(
12694
+ selectedPage && !readOnly ? /* @__PURE__ */ jsx26(
12052
12695
  "button",
12053
12696
  {
12054
12697
  type: "button",
@@ -12056,26 +12699,26 @@ function UrlOrPageInput({
12056
12699
  onMouseDown: clearSelection,
12057
12700
  "aria-label": "Clear selected page",
12058
12701
  tabIndex: -1,
12059
- children: /* @__PURE__ */ jsx25(X3, { size: 16, "aria-hidden": true })
12702
+ children: /* @__PURE__ */ jsx26(X3, { size: 16, "aria-hidden": true })
12060
12703
  }
12061
12704
  ) : null,
12062
- !readOnly ? /* @__PURE__ */ jsx25(FieldChevron, { onClick: toggleDropdown }) : null
12705
+ !readOnly ? /* @__PURE__ */ jsx26(FieldChevron, { onClick: toggleDropdown }) : null
12063
12706
  ] }),
12064
- dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ jsx25(
12707
+ dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ jsx26(
12065
12708
  "div",
12066
12709
  {
12067
12710
  "data-ohw-link-page-dropdown": "",
12068
12711
  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",
12069
12712
  onMouseDown: (e) => e.preventDefault(),
12070
- children: filteredPages.map((page) => /* @__PURE__ */ jsxs15(
12713
+ children: filteredPages.map((page) => /* @__PURE__ */ jsxs16(
12071
12714
  "button",
12072
12715
  {
12073
12716
  type: "button",
12074
12717
  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",
12075
12718
  onClick: () => onPageSelect(page),
12076
12719
  children: [
12077
- /* @__PURE__ */ jsx25(File2, { size: 16, className: "shrink-0", "aria-hidden": true }),
12078
- /* @__PURE__ */ jsx25("span", { className: "truncate", children: page.title })
12720
+ /* @__PURE__ */ jsx26(File2, { size: 16, className: "shrink-0", "aria-hidden": true }),
12721
+ /* @__PURE__ */ jsx26("span", { className: "truncate", children: page.title })
12079
12722
  ]
12080
12723
  },
12081
12724
  page.path
@@ -12083,34 +12726,34 @@ function UrlOrPageInput({
12083
12726
  }
12084
12727
  ) : null
12085
12728
  ] }),
12086
- urlError ? /* @__PURE__ */ jsx25("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
12729
+ urlError ? /* @__PURE__ */ jsx26("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
12087
12730
  ] });
12088
12731
  }
12089
12732
 
12090
12733
  // src/ui/link-modal/LinkEditorPanel.tsx
12091
- import { Fragment as Fragment8, jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
12734
+ import { Fragment as Fragment9, jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
12092
12735
  function LinkEditorPanel({ state, onClose }) {
12093
12736
  const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
12094
- return /* @__PURE__ */ jsxs16(Fragment8, { children: [
12095
- /* @__PURE__ */ jsx26(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx26(
12737
+ return /* @__PURE__ */ jsxs17(Fragment9, { children: [
12738
+ /* @__PURE__ */ jsx27(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx27(
12096
12739
  "button",
12097
12740
  {
12098
12741
  type: "button",
12099
12742
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
12100
12743
  "aria-label": "Close",
12101
12744
  onClick: onClose,
12102
- children: /* @__PURE__ */ jsx26(X4, { size: 16, "aria-hidden": true })
12745
+ children: /* @__PURE__ */ jsx27(X4, { size: 16, "aria-hidden": true })
12103
12746
  }
12104
12747
  ) }),
12105
- /* @__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 }) }),
12106
- /* @__PURE__ */ jsxs16("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
12107
- state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ jsx26(
12748
+ /* @__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 }) }),
12749
+ /* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
12750
+ state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ jsx27(
12108
12751
  DestinationBreadcrumb,
12109
12752
  {
12110
12753
  pageTitle: state.selectedPage.title,
12111
12754
  sectionLabel: state.selectedSection.label
12112
12755
  }
12113
- ) : /* @__PURE__ */ jsx26(
12756
+ ) : /* @__PURE__ */ jsx27(
12114
12757
  UrlOrPageInput,
12115
12758
  {
12116
12759
  value: state.searchValue,
@@ -12123,8 +12766,8 @@ function LinkEditorPanel({ state, onClose }) {
12123
12766
  urlError: state.urlError
12124
12767
  }
12125
12768
  ),
12126
- state.showChooseSection ? /* @__PURE__ */ jsxs16("div", { className: "flex flex-col justify-center gap-2", children: [
12127
- /* @__PURE__ */ jsx26(
12769
+ state.showChooseSection ? /* @__PURE__ */ jsxs17("div", { className: "flex flex-col justify-center gap-2", children: [
12770
+ /* @__PURE__ */ jsx27(
12128
12771
  Button,
12129
12772
  {
12130
12773
  type: "button",
@@ -12135,15 +12778,15 @@ function LinkEditorPanel({ state, onClose }) {
12135
12778
  children: "Choose a section"
12136
12779
  }
12137
12780
  ),
12138
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
12139
- /* @__PURE__ */ jsx26(Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
12140
- /* @__PURE__ */ jsx26("span", { children: "Pick a section this link should scroll to." })
12781
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
12782
+ /* @__PURE__ */ jsx27(Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
12783
+ /* @__PURE__ */ jsx27("span", { children: "Pick a section this link should scroll to." })
12141
12784
  ] })
12142
12785
  ] }) : null,
12143
- state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx26(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
12786
+ state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx27(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
12144
12787
  ] }),
12145
- /* @__PURE__ */ jsxs16(DialogFooter, { className: "w-full px-6 pb-6", children: [
12146
- /* @__PURE__ */ jsx26(
12788
+ /* @__PURE__ */ jsxs17(DialogFooter, { className: "w-full px-6 pb-6", children: [
12789
+ /* @__PURE__ */ jsx27(
12147
12790
  Button,
12148
12791
  {
12149
12792
  type: "button",
@@ -12158,7 +12801,7 @@ function LinkEditorPanel({ state, onClose }) {
12158
12801
  children: state.secondaryLabel
12159
12802
  }
12160
12803
  ),
12161
- /* @__PURE__ */ jsx26(
12804
+ /* @__PURE__ */ jsx27(
12162
12805
  Button,
12163
12806
  {
12164
12807
  type: "button",
@@ -12177,7 +12820,7 @@ function LinkEditorPanel({ state, onClose }) {
12177
12820
  }
12178
12821
 
12179
12822
  // src/ui/link-modal/SectionPickerOverlay.tsx
12180
- import { useCallback as useCallback5, useEffect as useEffect8, useMemo as useMemo2, useRef as useRef8, useState as useState10 } from "react";
12823
+ import { useCallback as useCallback6, useEffect as useEffect9, useMemo as useMemo2, useRef as useRef9, useState as useState11 } from "react";
12181
12824
  import { createPortal as createPortal2 } from "react-dom";
12182
12825
  import { ArrowLeft as ArrowLeft2, Check as Check2 } from "lucide-react";
12183
12826
  import { usePathname, useRouter as useRouter2 } from "next/navigation";
@@ -12201,7 +12844,7 @@ function getIframeChromeClip(parentScroll) {
12201
12844
  }
12202
12845
 
12203
12846
  // src/ui/link-modal/SectionPickerOverlay.tsx
12204
- import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
12847
+ import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
12205
12848
  var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
12206
12849
  function rectsEqual(a, b) {
12207
12850
  if (a.size !== b.size) return false;
@@ -12234,12 +12877,12 @@ function hitTestSectionId(x, y, sectionIds, rects) {
12234
12877
  return null;
12235
12878
  }
12236
12879
  function useSectionRects(sectionIdsKey, enabled) {
12237
- const [rects, setRects] = useState10(/* @__PURE__ */ new Map());
12880
+ const [rects, setRects] = useState11(/* @__PURE__ */ new Map());
12238
12881
  const sectionIds = useMemo2(
12239
12882
  () => sectionIdsKey ? sectionIdsKey.split("\0") : [],
12240
12883
  [sectionIdsKey]
12241
12884
  );
12242
- useEffect8(() => {
12885
+ useEffect9(() => {
12243
12886
  if (!enabled || sectionIds.length === 0) {
12244
12887
  setRects((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
12245
12888
  return;
@@ -12280,13 +12923,13 @@ function SectionPickerOverlay({
12280
12923
  }) {
12281
12924
  const router = useRouter2();
12282
12925
  const pathname = usePathname();
12283
- const [selectedId, setSelectedId] = useState10(null);
12284
- const [hoveredId, setHoveredId] = useState10(null);
12285
- const pointerRef = useRef8(null);
12286
- const pointerScreenRef = useRef8(null);
12287
- const iframeOffsetTopRef = useRef8(null);
12288
- const sectionIdsRef = useRef8([]);
12289
- const [chromeClip, setChromeClip] = useState10(
12926
+ const [selectedId, setSelectedId] = useState11(null);
12927
+ const [hoveredId, setHoveredId] = useState11(null);
12928
+ const pointerRef = useRef9(null);
12929
+ const pointerScreenRef = useRef9(null);
12930
+ const iframeOffsetTopRef = useRef9(null);
12931
+ const sectionIdsRef = useRef9([]);
12932
+ const [chromeClip, setChromeClip] = useState11(
12290
12933
  () => ({
12291
12934
  top: 0,
12292
12935
  bottom: typeof window !== "undefined" ? window.innerHeight : 0
@@ -12294,12 +12937,12 @@ function SectionPickerOverlay({
12294
12937
  );
12295
12938
  const normalizedTarget = normalizePath(pagePath);
12296
12939
  const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
12297
- useEffect8(() => {
12940
+ useEffect9(() => {
12298
12941
  if (isOnTargetPage) return;
12299
12942
  const search = readPreservedSearch();
12300
12943
  router.push(`${normalizedTarget}${search}`);
12301
12944
  }, [isOnTargetPage, normalizedTarget, router]);
12302
- useEffect8(() => {
12945
+ useEffect9(() => {
12303
12946
  document.documentElement.setAttribute("data-ohw-section-picking", "");
12304
12947
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
12305
12948
  el.removeAttribute("data-ohw-hovered");
@@ -12328,7 +12971,7 @@ function SectionPickerOverlay({
12328
12971
  );
12329
12972
  sectionIdsRef.current = sectionIds;
12330
12973
  const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
12331
- const applyHoverAt = useCallback5(
12974
+ const applyHoverAt = useCallback6(
12332
12975
  (x, y, liveRects) => {
12333
12976
  const ids = sectionIdsRef.current;
12334
12977
  const map = liveRects ?? readSectionRects(ids);
@@ -12337,7 +12980,7 @@ function SectionPickerOverlay({
12337
12980
  },
12338
12981
  []
12339
12982
  );
12340
- useEffect8(() => {
12983
+ useEffect9(() => {
12341
12984
  const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH, promptBarH = 0) => {
12342
12985
  const next = getIframeVisibleClip({
12343
12986
  iframeOffsetTop,
@@ -12381,12 +13024,12 @@ function SectionPickerOverlay({
12381
13024
  window.removeEventListener("resize", onResize);
12382
13025
  };
12383
13026
  }, [applyHoverAt]);
12384
- useEffect8(() => {
13027
+ useEffect9(() => {
12385
13028
  const ptr = pointerRef.current;
12386
13029
  if (!ptr) return;
12387
13030
  applyHoverAt(ptr.x, ptr.y, rects);
12388
13031
  }, [rects, applyHoverAt]);
12389
- useEffect8(() => {
13032
+ useEffect9(() => {
12390
13033
  const rememberPointer = (clientX, clientY) => {
12391
13034
  pointerRef.current = { x: clientX, y: clientY };
12392
13035
  const top = iframeOffsetTopRef.current;
@@ -12410,7 +13053,7 @@ function SectionPickerOverlay({
12410
13053
  window.removeEventListener("message", onPointerSync);
12411
13054
  };
12412
13055
  }, [rects, applyHoverAt]);
12413
- const handleSelect = useCallback5(
13056
+ const handleSelect = useCallback6(
12414
13057
  (section) => {
12415
13058
  if (selectedId) return;
12416
13059
  setSelectedId(section.id);
@@ -12418,7 +13061,7 @@ function SectionPickerOverlay({
12418
13061
  },
12419
13062
  [selectedId, onSelect]
12420
13063
  );
12421
- useEffect8(() => {
13064
+ useEffect9(() => {
12422
13065
  const onKeyDown = (e) => {
12423
13066
  if (e.key === "Escape") {
12424
13067
  e.preventDefault();
@@ -12432,7 +13075,7 @@ function SectionPickerOverlay({
12432
13075
  const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
12433
13076
  if (!portalRoot) return null;
12434
13077
  return createPortal2(
12435
- /* @__PURE__ */ jsxs17(
13078
+ /* @__PURE__ */ jsxs18(
12436
13079
  "div",
12437
13080
  {
12438
13081
  "data-ohw-section-picker": "",
@@ -12442,12 +13085,12 @@ function SectionPickerOverlay({
12442
13085
  role: "dialog",
12443
13086
  "aria-label": "Choose a section",
12444
13087
  children: [
12445
- /* @__PURE__ */ jsx27(
13088
+ /* @__PURE__ */ jsx28(
12446
13089
  "div",
12447
13090
  {
12448
13091
  className: "pointer-events-auto fixed left-5 z-[2]",
12449
13092
  style: { top: chromeClip.top + 20 },
12450
- children: /* @__PURE__ */ jsxs17(
13093
+ children: /* @__PURE__ */ jsxs18(
12451
13094
  Button,
12452
13095
  {
12453
13096
  type: "button",
@@ -12456,14 +13099,14 @@ function SectionPickerOverlay({
12456
13099
  className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
12457
13100
  onClick: onBack,
12458
13101
  children: [
12459
- /* @__PURE__ */ jsx27(ArrowLeft2, { className: "size-4 shrink-0", "aria-hidden": true }),
13102
+ /* @__PURE__ */ jsx28(ArrowLeft2, { className: "size-4 shrink-0", "aria-hidden": true }),
12460
13103
  "Back"
12461
13104
  ]
12462
13105
  }
12463
13106
  )
12464
13107
  }
12465
13108
  ),
12466
- /* @__PURE__ */ jsx27(
13109
+ /* @__PURE__ */ jsx28(
12467
13110
  "div",
12468
13111
  {
12469
13112
  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",
@@ -12476,7 +13119,7 @@ function SectionPickerOverlay({
12476
13119
  children: "Click on section to select"
12477
13120
  }
12478
13121
  ),
12479
- !isOnTargetPage ? /* @__PURE__ */ jsx27(
13122
+ !isOnTargetPage ? /* @__PURE__ */ jsx28(
12480
13123
  "div",
12481
13124
  {
12482
13125
  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",
@@ -12484,14 +13127,14 @@ function SectionPickerOverlay({
12484
13127
  children: "Loading page preview\u2026"
12485
13128
  }
12486
13129
  ) : null,
12487
- 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,
13130
+ 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,
12488
13131
  isOnTargetPage ? liveSections.map((section) => {
12489
13132
  const rect = rects.get(section.id);
12490
13133
  if (!rect || rect.width <= 0 || rect.height <= 0) return null;
12491
13134
  const isSelected = selectedId === section.id;
12492
13135
  const isHovered = hoveredId === section.id;
12493
13136
  const isLit = isSelected || isHovered;
12494
- return /* @__PURE__ */ jsxs17(
13137
+ return /* @__PURE__ */ jsxs18(
12495
13138
  "button",
12496
13139
  {
12497
13140
  type: "button",
@@ -12506,7 +13149,7 @@ function SectionPickerOverlay({
12506
13149
  "aria-label": `Select section ${section.label}`,
12507
13150
  onClick: () => handleSelect(section),
12508
13151
  children: [
12509
- isLit ? /* @__PURE__ */ jsx27(
13152
+ isLit ? /* @__PURE__ */ jsx28(
12510
13153
  "span",
12511
13154
  {
12512
13155
  className: "pointer-events-none absolute",
@@ -12519,13 +13162,13 @@ function SectionPickerOverlay({
12519
13162
  "aria-hidden": true
12520
13163
  }
12521
13164
  ) : null,
12522
- isSelected ? /* @__PURE__ */ jsx27(
13165
+ isSelected ? /* @__PURE__ */ jsx28(
12523
13166
  "span",
12524
13167
  {
12525
13168
  className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
12526
13169
  style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
12527
13170
  "aria-hidden": true,
12528
- children: /* @__PURE__ */ jsx27(Check2, { className: "size-5" })
13171
+ children: /* @__PURE__ */ jsx28(Check2, { className: "size-5" })
12529
13172
  }
12530
13173
  ) : null
12531
13174
  ]
@@ -12541,7 +13184,7 @@ function SectionPickerOverlay({
12541
13184
  }
12542
13185
 
12543
13186
  // src/ui/link-modal/useLinkModalState.ts
12544
- import { useCallback as useCallback6, useEffect as useEffect9, useMemo as useMemo3, useState as useState11 } from "react";
13187
+ import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo3, useState as useState12 } from "react";
12545
13188
  function useLinkModalState({
12546
13189
  open,
12547
13190
  mode,
@@ -12554,13 +13197,13 @@ function useLinkModalState({
12554
13197
  onSubmit
12555
13198
  }) {
12556
13199
  const availablePages = useMemo3(() => pages, [pages]);
12557
- const [searchValue, setSearchValue] = useState11("");
12558
- const [selectedPage, setSelectedPage] = useState11(null);
12559
- const [selectedSection, setSelectedSection] = useState11(null);
12560
- const [step, setStep] = useState11("input");
12561
- const [dropdownOpen, setDropdownOpen] = useState11(false);
12562
- const [urlError, setUrlError] = useState11("");
12563
- const reset = useCallback6(() => {
13200
+ const [searchValue, setSearchValue] = useState12("");
13201
+ const [selectedPage, setSelectedPage] = useState12(null);
13202
+ const [selectedSection, setSelectedSection] = useState12(null);
13203
+ const [step, setStep] = useState12("input");
13204
+ const [dropdownOpen, setDropdownOpen] = useState12(false);
13205
+ const [urlError, setUrlError] = useState12("");
13206
+ const reset = useCallback7(() => {
12564
13207
  setSearchValue("");
12565
13208
  setSelectedPage(null);
12566
13209
  setSelectedSection(null);
@@ -12568,7 +13211,7 @@ function useLinkModalState({
12568
13211
  setDropdownOpen(false);
12569
13212
  setUrlError("");
12570
13213
  }, []);
12571
- useEffect9(() => {
13214
+ useEffect10(() => {
12572
13215
  if (!open) return;
12573
13216
  if (mode === "edit" && initialTarget) {
12574
13217
  const { pageRoute } = parseTarget(initialTarget);
@@ -12705,7 +13348,7 @@ function useLinkModalState({
12705
13348
  }
12706
13349
 
12707
13350
  // src/ui/link-modal/LinkPopover.tsx
12708
- import { Fragment as Fragment9, jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
13351
+ import { Fragment as Fragment10, jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
12709
13352
  function postToParent(data) {
12710
13353
  window.parent?.postMessage(data, "*");
12711
13354
  }
@@ -12734,7 +13377,7 @@ function LinkPopover({
12734
13377
  onSubmit
12735
13378
  });
12736
13379
  const sectionPickerActive = state.showSectionPicker && Boolean(state.selectedPage);
12737
- useEffect10(() => {
13380
+ useEffect11(() => {
12738
13381
  if (!open) return;
12739
13382
  if (sectionPickerActive) {
12740
13383
  postToParent({ type: "ui:unlock" });
@@ -12801,15 +13444,15 @@ function LinkPopover({
12801
13444
  );
12802
13445
  };
12803
13446
  }, [open, sectionPickerActive]);
12804
- return /* @__PURE__ */ jsxs18(Fragment9, { children: [
12805
- /* @__PURE__ */ jsx28(
13447
+ return /* @__PURE__ */ jsxs19(Fragment10, { children: [
13448
+ /* @__PURE__ */ jsx29(
12806
13449
  Dialog2,
12807
13450
  {
12808
13451
  open: open && !sectionPickerActive,
12809
13452
  onOpenChange: (next) => {
12810
13453
  if (!next) onClose?.();
12811
13454
  },
12812
- children: /* @__PURE__ */ jsx28(
13455
+ children: /* @__PURE__ */ jsx29(
12813
13456
  DialogContent,
12814
13457
  {
12815
13458
  ref: panelRef,
@@ -12819,12 +13462,12 @@ function LinkPopover({
12819
13462
  "data-ohw-bridge": "",
12820
13463
  showCloseButton: false,
12821
13464
  className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
12822
- children: /* @__PURE__ */ jsx28(LinkEditorPanel, { state, onClose })
13465
+ children: /* @__PURE__ */ jsx29(LinkEditorPanel, { state, onClose })
12823
13466
  }
12824
13467
  )
12825
13468
  }
12826
13469
  ),
12827
- sectionPickerActive && state.selectedPage ? /* @__PURE__ */ jsx28(
13470
+ sectionPickerActive && state.selectedPage ? /* @__PURE__ */ jsx29(
12828
13471
  SectionPickerOverlay,
12829
13472
  {
12830
13473
  pagePath: state.selectedPage.path,
@@ -15946,6 +16589,7 @@ function readLogoSizeState(content, placement) {
15946
16589
  function getLogoElement(el) {
15947
16590
  const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
15948
16591
  if (marked) return marked;
16592
+ if (el.closest('[data-ohw-editable="icon"]')) return null;
15949
16593
  const root = el.closest("nav, [data-ohw-nav-root], footer");
15950
16594
  if (!root) return null;
15951
16595
  const anchor = el.closest("a");
@@ -16013,14 +16657,14 @@ function addFooterColumnWithPersist({
16013
16657
 
16014
16658
  // src/ui/FloatingPanel.tsx
16015
16659
  import {
16016
- useCallback as useCallback7,
16017
- useEffect as useEffect11,
16660
+ useCallback as useCallback8,
16661
+ useEffect as useEffect12,
16018
16662
  useLayoutEffect as useLayoutEffect4,
16019
- useRef as useRef9,
16020
- useState as useState12
16663
+ useRef as useRef10,
16664
+ useState as useState13
16021
16665
  } from "react";
16022
16666
  import { X as X5 } from "lucide-react";
16023
- import { jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
16667
+ import { jsx as jsx30, jsxs as jsxs20 } from "react/jsx-runtime";
16024
16668
  var PANEL_WIDTH = 256;
16025
16669
  var EDGE_MARGIN = 16;
16026
16670
  var HEADER_MIN = 56;
@@ -16080,10 +16724,10 @@ function FloatingPanel({
16080
16724
  className,
16081
16725
  bodyClassName
16082
16726
  }) {
16083
- const panelRef = useRef9(null);
16084
- const [measured, setMeasured] = useState12({ w: PANEL_WIDTH, h: 280 });
16085
- const dragRef = useRef9(null);
16086
- const homeRef = useRef9(null);
16727
+ const panelRef = useRef10(null);
16728
+ const [measured, setMeasured] = useState13({ w: PANEL_WIDTH, h: 280 });
16729
+ const dragRef = useRef10(null);
16730
+ const homeRef = useRef10(null);
16087
16731
  if (!open) {
16088
16732
  homeRef.current = null;
16089
16733
  } else if (position) {
@@ -16091,17 +16735,17 @@ function FloatingPanel({
16091
16735
  } else if (homeRef.current == null) {
16092
16736
  homeRef.current = defaultFloatingPanelPosition(parentScroll);
16093
16737
  }
16094
- const [liveScroll, setLiveScroll] = useState12(parentScroll);
16738
+ const [liveScroll, setLiveScroll] = useState13(parentScroll);
16095
16739
  const home = position ?? homeRef.current ?? defaultFloatingPanelPosition(parentScroll);
16096
16740
  const { y: fittedY, maxHeight } = fitPanelInClip(home.y, liveScroll, measured.h);
16097
16741
  const clamped = {
16098
16742
  x: clampX(home.x, measured.w),
16099
16743
  y: fittedY
16100
16744
  };
16101
- useEffect11(() => {
16745
+ useEffect12(() => {
16102
16746
  setLiveScroll(parentScroll);
16103
16747
  }, [parentScroll]);
16104
- useEffect11(() => {
16748
+ useEffect12(() => {
16105
16749
  if (!open) return;
16106
16750
  const onParentScroll = (e) => {
16107
16751
  if (e.data?.type !== "ow:parent-scroll") return;
@@ -16111,7 +16755,7 @@ function FloatingPanel({
16111
16755
  window.addEventListener("message", onParentScroll);
16112
16756
  return () => window.removeEventListener("message", onParentScroll);
16113
16757
  }, [open]);
16114
- const positionRef = useRef9(position);
16758
+ const positionRef = useRef10(position);
16115
16759
  useLayoutEffect4(() => {
16116
16760
  if (!open) {
16117
16761
  positionRef.current = position;
@@ -16131,7 +16775,7 @@ function FloatingPanel({
16131
16775
  const next = { w: el.offsetWidth || PANEL_WIDTH, h: contentH };
16132
16776
  setMeasured((prev) => prev.w === next.w && prev.h === next.h ? prev : next);
16133
16777
  }, [open, children, title, context]);
16134
- const onHeaderPointerDown = useCallback7(
16778
+ const onHeaderPointerDown = useCallback8(
16135
16779
  (e) => {
16136
16780
  if (e.button !== 0) return;
16137
16781
  if (e.target.closest("[data-ohw-floating-panel-close]")) return;
@@ -16150,7 +16794,7 @@ function FloatingPanel({
16150
16794
  },
16151
16795
  [clamped.x, clamped.y]
16152
16796
  );
16153
- const onHeaderPointerMove = useCallback7(
16797
+ const onHeaderPointerMove = useCallback8(
16154
16798
  (e) => {
16155
16799
  const drag = dragRef.current;
16156
16800
  if (!drag || drag.pointerId !== e.pointerId) return;
@@ -16176,7 +16820,7 @@ function FloatingPanel({
16176
16820
  },
16177
16821
  [measured.w, onPositionChange, liveScroll]
16178
16822
  );
16179
- const endDrag = useCallback7((e) => {
16823
+ const endDrag = useCallback8((e) => {
16180
16824
  const drag = dragRef.current;
16181
16825
  if (!drag || drag.pointerId !== e.pointerId) return;
16182
16826
  dragRef.current = null;
@@ -16186,13 +16830,13 @@ function FloatingPanel({
16186
16830
  } catch {
16187
16831
  }
16188
16832
  }, []);
16189
- useEffect11(() => {
16833
+ useEffect12(() => {
16190
16834
  if (open) return;
16191
16835
  document.documentElement.removeAttribute("data-ohw-panel-dragging");
16192
16836
  }, [open]);
16193
- useEffect11(() => () => document.documentElement.removeAttribute("data-ohw-panel-dragging"), []);
16837
+ useEffect12(() => () => document.documentElement.removeAttribute("data-ohw-panel-dragging"), []);
16194
16838
  if (!open) return null;
16195
- return /* @__PURE__ */ jsxs19(
16839
+ return /* @__PURE__ */ jsxs20(
16196
16840
  "div",
16197
16841
  {
16198
16842
  ref: panelRef,
@@ -16209,7 +16853,7 @@ function FloatingPanel({
16209
16853
  onPointerDown: (e) => e.stopPropagation(),
16210
16854
  onClick: (e) => e.stopPropagation(),
16211
16855
  children: [
16212
- /* @__PURE__ */ jsxs19(
16856
+ /* @__PURE__ */ jsxs20(
16213
16857
  "div",
16214
16858
  {
16215
16859
  "data-ohw-floating-panel-header": "",
@@ -16219,14 +16863,14 @@ function FloatingPanel({
16219
16863
  onPointerUp: endDrag,
16220
16864
  onPointerCancel: endDrag,
16221
16865
  children: [
16222
- /* @__PURE__ */ jsxs19("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
16223
- /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2", children: [
16224
- icon ? /* @__PURE__ */ jsx29("span", { className: "shrink-0 text-foreground", children: icon }) : null,
16225
- /* @__PURE__ */ jsx29("p", { className: "min-w-0 flex-1 text-lg font-semibold leading-7 text-foreground", children: title })
16866
+ /* @__PURE__ */ jsxs20("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
16867
+ /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2", children: [
16868
+ icon ? /* @__PURE__ */ jsx30("span", { className: "shrink-0 text-foreground", children: icon }) : null,
16869
+ /* @__PURE__ */ jsx30("p", { className: "min-w-0 flex-1 text-lg font-semibold leading-7 text-foreground", children: title })
16226
16870
  ] }),
16227
- context ? /* @__PURE__ */ jsx29("p", { className: "w-full text-sm leading-5 text-muted-foreground", children: context }) : null
16871
+ context ? /* @__PURE__ */ jsx30("p", { className: "w-full text-sm leading-5 text-muted-foreground", children: context }) : null
16228
16872
  ] }),
16229
- /* @__PURE__ */ jsx29(
16873
+ /* @__PURE__ */ jsx30(
16230
16874
  "button",
16231
16875
  {
16232
16876
  type: "button",
@@ -16238,13 +16882,13 @@ function FloatingPanel({
16238
16882
  onClose();
16239
16883
  },
16240
16884
  onPointerDown: (e) => e.stopPropagation(),
16241
- children: /* @__PURE__ */ jsx29(X5, { size: 16, "aria-hidden": true })
16885
+ children: /* @__PURE__ */ jsx30(X5, { size: 16, "aria-hidden": true })
16242
16886
  }
16243
16887
  )
16244
16888
  ]
16245
16889
  }
16246
16890
  ),
16247
- /* @__PURE__ */ jsx29(
16891
+ /* @__PURE__ */ jsx30(
16248
16892
  "div",
16249
16893
  {
16250
16894
  "data-ohw-floating-panel-body": "",
@@ -16262,15 +16906,15 @@ function FloatingPanel({
16262
16906
  }
16263
16907
 
16264
16908
  // src/ui/socials-display-panel.tsx
16265
- import { jsx as jsx30, jsxs as jsxs20 } from "react/jsx-runtime";
16909
+ import { jsx as jsx31, jsxs as jsxs21 } from "react/jsx-runtime";
16266
16910
  function DisplaySwitch({
16267
16911
  label,
16268
16912
  checked,
16269
16913
  disabled,
16270
16914
  onChange
16271
16915
  }) {
16272
- return /* @__PURE__ */ jsxs20("div", { className: "flex w-full items-center gap-2", children: [
16273
- /* @__PURE__ */ jsx30(
16916
+ return /* @__PURE__ */ jsxs21("div", { className: "flex w-full items-center gap-2", children: [
16917
+ /* @__PURE__ */ jsx31(
16274
16918
  "span",
16275
16919
  {
16276
16920
  className: cn(
@@ -16280,7 +16924,7 @@ function DisplaySwitch({
16280
16924
  children: label
16281
16925
  }
16282
16926
  ),
16283
- /* @__PURE__ */ jsx30(
16927
+ /* @__PURE__ */ jsx31(
16284
16928
  "button",
16285
16929
  {
16286
16930
  type: "button",
@@ -16294,7 +16938,7 @@ function DisplaySwitch({
16294
16938
  checked ? "bg-bridge-primary" : "bg-primary-50",
16295
16939
  disabled ? "cursor-default opacity-50" : "cursor-pointer"
16296
16940
  ),
16297
- children: /* @__PURE__ */ jsx30(
16941
+ children: /* @__PURE__ */ jsx31(
16298
16942
  "span",
16299
16943
  {
16300
16944
  className: cn(
@@ -16308,8 +16952,8 @@ function DisplaySwitch({
16308
16952
  ] });
16309
16953
  }
16310
16954
  function SocialsDisplayPanel({ display, onChange, className }) {
16311
- return /* @__PURE__ */ jsxs20("div", { className: cn("flex w-full flex-col gap-3", className), children: [
16312
- /* @__PURE__ */ jsx30(
16955
+ return /* @__PURE__ */ jsxs21("div", { className: cn("flex w-full flex-col gap-3", className), children: [
16956
+ /* @__PURE__ */ jsx31(
16313
16957
  DisplaySwitch,
16314
16958
  {
16315
16959
  label: "Text",
@@ -16318,7 +16962,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
16318
16962
  onChange: (text) => onChange({ ...display, text })
16319
16963
  }
16320
16964
  ),
16321
- /* @__PURE__ */ jsx30(
16965
+ /* @__PURE__ */ jsx31(
16322
16966
  DisplaySwitch,
16323
16967
  {
16324
16968
  label: "Icon",
@@ -17034,7 +17678,7 @@ function withAssignment(content, id, assignment) {
17034
17678
  }
17035
17679
 
17036
17680
  // src/ui/button-style-panel.tsx
17037
- import { jsx as jsx31, jsxs as jsxs21 } from "react/jsx-runtime";
17681
+ import { jsx as jsx32, jsxs as jsxs22 } from "react/jsx-runtime";
17038
17682
  var SIZE_LABEL = { s: "S", m: "M", l: "L" };
17039
17683
  function ButtonStylePanel({
17040
17684
  variants,
@@ -17048,15 +17692,15 @@ function ButtonStylePanel({
17048
17692
  }) {
17049
17693
  const preview = scaleGeometry(sizes.m, 0.75);
17050
17694
  const label = previewLabel.trim() || "Book Now";
17051
- return /* @__PURE__ */ jsxs21("div", { className: "flex w-full flex-col gap-5", children: [
17052
- /* @__PURE__ */ jsxs21("section", { className: "flex w-full flex-col gap-2.5", children: [
17053
- /* @__PURE__ */ jsx31("h3", { className: "text-xs font-semibold uppercase leading-4 tracking-[0.6px] text-stone-500 font-sans", children: "Variants" }),
17054
- /* @__PURE__ */ jsx31("div", { className: "flex w-full flex-col gap-2.5", children: BUTTON_VARIANT_IDS.map((id) => {
17695
+ return /* @__PURE__ */ jsxs22("div", { className: "flex w-full flex-col gap-5", children: [
17696
+ /* @__PURE__ */ jsxs22("section", { className: "flex w-full flex-col gap-2.5", children: [
17697
+ /* @__PURE__ */ jsx32("h3", { className: "text-xs font-semibold uppercase leading-4 tracking-[0.6px] text-stone-500 font-sans", children: "Variants" }),
17698
+ /* @__PURE__ */ jsx32("div", { className: "flex w-full flex-col gap-2.5", children: BUTTON_VARIANT_IDS.map((id) => {
17055
17699
  const chrome = variants[id];
17056
17700
  const selected = id === variant;
17057
17701
  const hasBorder = parseFloat(chrome.borderWidth) > 0;
17058
17702
  const cardSlot = previewSlotForChrome(chrome, slotBackground);
17059
- return /* @__PURE__ */ jsxs21(
17703
+ return /* @__PURE__ */ jsxs22(
17060
17704
  "button",
17061
17705
  {
17062
17706
  type: "button",
@@ -17072,12 +17716,12 @@ function ButtonStylePanel({
17072
17716
  selected ? "border-2 border-primary" : "border border-border"
17073
17717
  ),
17074
17718
  children: [
17075
- /* @__PURE__ */ jsx31(
17719
+ /* @__PURE__ */ jsx32(
17076
17720
  "div",
17077
17721
  {
17078
17722
  className: "flex w-full items-center justify-center py-4",
17079
17723
  style: { background: cardSlot },
17080
- children: /* @__PURE__ */ jsx31(
17724
+ children: /* @__PURE__ */ jsx32(
17081
17725
  "span",
17082
17726
  {
17083
17727
  className: "inline-flex items-center justify-center whitespace-nowrap font-semibold uppercase leading-none",
@@ -17099,12 +17743,12 @@ function ButtonStylePanel({
17099
17743
  )
17100
17744
  }
17101
17745
  ),
17102
- selected ? /* @__PURE__ */ jsx31(
17746
+ selected ? /* @__PURE__ */ jsx32(
17103
17747
  "span",
17104
17748
  {
17105
17749
  className: "absolute right-0.5 top-0.5 flex size-5 items-center justify-center rounded-full bg-primary text-primary-foreground",
17106
17750
  "aria-hidden": true,
17107
- children: /* @__PURE__ */ jsx31(Check3, { className: "size-3", strokeWidth: 3 })
17751
+ children: /* @__PURE__ */ jsx32(Check3, { className: "size-3", strokeWidth: 3 })
17108
17752
  }
17109
17753
  ) : null
17110
17754
  ]
@@ -17113,9 +17757,9 @@ function ButtonStylePanel({
17113
17757
  );
17114
17758
  }) })
17115
17759
  ] }),
17116
- /* @__PURE__ */ jsxs21("section", { className: "flex w-full flex-col gap-2.5", children: [
17117
- /* @__PURE__ */ jsx31("h3", { className: "text-xs font-semibold uppercase leading-4 tracking-[0.6px] text-stone-500 font-sans", children: "Size" }),
17118
- /* @__PURE__ */ jsx31(
17760
+ /* @__PURE__ */ jsxs22("section", { className: "flex w-full flex-col gap-2.5", children: [
17761
+ /* @__PURE__ */ jsx32("h3", { className: "text-xs font-semibold uppercase leading-4 tracking-[0.6px] text-stone-500 font-sans", children: "Size" }),
17762
+ /* @__PURE__ */ jsx32(
17119
17763
  "div",
17120
17764
  {
17121
17765
  className: "flex w-full items-start rounded-lg bg-stone-100 p-1",
@@ -17123,7 +17767,7 @@ function ButtonStylePanel({
17123
17767
  "aria-label": "Size",
17124
17768
  children: BUTTON_SIZE_IDS.map((id) => {
17125
17769
  const selected = id === size;
17126
- return /* @__PURE__ */ jsx31(
17770
+ return /* @__PURE__ */ jsx32(
17127
17771
  "button",
17128
17772
  {
17129
17773
  type: "button",
@@ -18027,7 +18671,7 @@ function hitTestNavDropSlot(clientX, clientY, draggedHrefKey, draggedEl) {
18027
18671
  }
18028
18672
 
18029
18673
  // src/useNavItemDrag.ts
18030
- import { useCallback as useCallback8, useEffect as useEffect12, useRef as useRef10, useState as useState13 } from "react";
18674
+ import { useCallback as useCallback9, useEffect as useEffect13, useRef as useRef11, useState as useState14 } from "react";
18031
18675
  function useNavItemDrag({
18032
18676
  isEditMode,
18033
18677
  editContentRef,
@@ -18051,11 +18695,11 @@ function useNavItemDrag({
18051
18695
  getNavigationItemAnchor: getNavigationItemAnchor2,
18052
18696
  isDragHandleDisabled: isDragHandleDisabled2
18053
18697
  }) {
18054
- const navDragRef = useRef10(null);
18055
- const [navDropSlots, setNavDropSlots] = useState13([]);
18056
- const [activeNavDropIndex, setActiveNavDropIndex] = useState13(null);
18057
- const navPointerDragRef = useRef10(null);
18058
- const clearNavDragVisuals = useCallback8(() => {
18698
+ const navDragRef = useRef11(null);
18699
+ const [navDropSlots, setNavDropSlots] = useState14([]);
18700
+ const [activeNavDropIndex, setActiveNavDropIndex] = useState14(null);
18701
+ const navPointerDragRef = useRef11(null);
18702
+ const clearNavDragVisuals = useCallback9(() => {
18059
18703
  const session = navDragRef.current;
18060
18704
  const nestedHrefKey = session?.draggedEl?.closest("[data-ohw-nav-children]") != null ? session.hrefKey : null;
18061
18705
  navDragRef.current = null;
@@ -18088,7 +18732,7 @@ function useNavItemDrag({
18088
18732
  document.documentElement.removeAttribute("data-ohw-nav-dragging-root");
18089
18733
  unlockItemDragInteraction();
18090
18734
  }, [setDraggedItemRect, setIsItemDragging, setSiblingHintRects]);
18091
- const refreshNavDragVisuals = useCallback8(
18735
+ const refreshNavDragVisuals = useCallback9(
18092
18736
  (session, activeSlot, clientX, clientY) => {
18093
18737
  setDraggedItemRect(session.draggedEl.getBoundingClientRect());
18094
18738
  if (typeof clientX === "number" && typeof clientY === "number") {
@@ -18106,13 +18750,13 @@ function useNavItemDrag({
18106
18750
  },
18107
18751
  [setDraggedItemRect, setSiblingHintRects]
18108
18752
  );
18109
- const refreshNavDragVisualsRef = useRef10(refreshNavDragVisuals);
18753
+ const refreshNavDragVisualsRef = useRef11(refreshNavDragVisuals);
18110
18754
  refreshNavDragVisualsRef.current = refreshNavDragVisuals;
18111
- const commitNavDragRef = useRef10(() => {
18755
+ const commitNavDragRef = useRef11(() => {
18112
18756
  });
18113
- const beginNavDragRef = useRef10(() => {
18757
+ const beginNavDragRef = useRef11(() => {
18114
18758
  });
18115
- const beginNavDrag = useCallback8(
18759
+ const beginNavDrag = useCallback9(
18116
18760
  (session) => {
18117
18761
  const rect = session.draggedEl.getBoundingClientRect();
18118
18762
  session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
@@ -18151,7 +18795,7 @@ function useNavItemDrag({
18151
18795
  ]
18152
18796
  );
18153
18797
  beginNavDragRef.current = beginNavDrag;
18154
- const commitNavDrag = useCallback8(
18798
+ const commitNavDrag = useCallback9(
18155
18799
  (clientX, clientY) => {
18156
18800
  const session = navDragRef.current;
18157
18801
  if (!session) {
@@ -18230,7 +18874,7 @@ function useNavItemDrag({
18230
18874
  [clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
18231
18875
  );
18232
18876
  commitNavDragRef.current = commitNavDrag;
18233
- const startNavLinkDrag = useCallback8(
18877
+ const startNavLinkDrag = useCallback9(
18234
18878
  (anchor, clientX, clientY, wasSelected) => {
18235
18879
  if (footerDragRef.current) return false;
18236
18880
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
@@ -18248,7 +18892,7 @@ function useNavItemDrag({
18248
18892
  },
18249
18893
  [beginNavDrag, footerDragRef, isDragHandleDisabled2, isCtaButton]
18250
18894
  );
18251
- const onNavDragOver = useCallback8(
18895
+ const onNavDragOver = useCallback9(
18252
18896
  (e) => {
18253
18897
  const session = navDragRef.current;
18254
18898
  if (!session) return false;
@@ -18260,7 +18904,7 @@ function useNavItemDrag({
18260
18904
  },
18261
18905
  []
18262
18906
  );
18263
- useEffect12(() => {
18907
+ useEffect13(() => {
18264
18908
  if (!isEditMode) return;
18265
18909
  const THRESHOLD = 10;
18266
18910
  const resolveWasSelected = (el) => {
@@ -18387,7 +19031,7 @@ function useNavItemDrag({
18387
19031
  setLinkPopover,
18388
19032
  suppressNextClickRef
18389
19033
  ]);
18390
- const armNavPressFromChrome = useCallback8(
19034
+ const armNavPressFromChrome = useCallback9(
18391
19035
  (selected, clientX, clientY, pointerId) => {
18392
19036
  const hrefKey = selected.getAttribute("data-ohw-href-key");
18393
19037
  if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
@@ -18419,7 +19063,7 @@ function useNavItemDrag({
18419
19063
  }
18420
19064
 
18421
19065
  // src/useSectionDrag.ts
18422
- import { useCallback as useCallback9, useEffect as useEffect13, useRef as useRef11, useState as useState14 } from "react";
19066
+ import { useCallback as useCallback10, useEffect as useEffect14, useRef as useRef12, useState as useState15 } from "react";
18423
19067
 
18424
19068
  // src/lib/section-dnd.ts
18425
19069
  function isFooterSection(el) {
@@ -18512,21 +19156,21 @@ function useSectionDrag({
18512
19156
  suppressNextClickRef,
18513
19157
  suppressClickUntilRef
18514
19158
  }) {
18515
- const sectionDragRef = useRef11(null);
18516
- const [sectionDropSlots, setSectionDropSlots] = useState14([]);
18517
- const [activeSectionDropIndex, setActiveSectionDropIndex] = useState14(null);
18518
- const [isSectionDragging, setIsSectionDragging] = useState14(false);
18519
- const sectionPointerDragRef = useRef11(null);
18520
- const autoScrollRafRef = useRef11(null);
18521
- const autoScrollDeltaRef = useRef11(0);
18522
- const stopAutoScroll = useCallback9(() => {
19159
+ const sectionDragRef = useRef12(null);
19160
+ const [sectionDropSlots, setSectionDropSlots] = useState15([]);
19161
+ const [activeSectionDropIndex, setActiveSectionDropIndex] = useState15(null);
19162
+ const [isSectionDragging, setIsSectionDragging] = useState15(false);
19163
+ const sectionPointerDragRef = useRef12(null);
19164
+ const autoScrollRafRef = useRef12(null);
19165
+ const autoScrollDeltaRef = useRef12(0);
19166
+ const stopAutoScroll = useCallback10(() => {
18523
19167
  if (autoScrollRafRef.current != null) {
18524
19168
  cancelAnimationFrame(autoScrollRafRef.current);
18525
19169
  autoScrollRafRef.current = null;
18526
19170
  }
18527
19171
  autoScrollDeltaRef.current = 0;
18528
19172
  }, []);
18529
- const tickAutoScroll = useCallback9(() => {
19173
+ const tickAutoScroll = useCallback10(() => {
18530
19174
  if (!sectionDragRef.current) {
18531
19175
  stopAutoScroll();
18532
19176
  return;
@@ -18536,7 +19180,7 @@ function useSectionDrag({
18536
19180
  }
18537
19181
  autoScrollRafRef.current = requestAnimationFrame(tickAutoScroll);
18538
19182
  }, [postToParentRef, stopAutoScroll]);
18539
- const updateAutoScroll = useCallback9(
19183
+ const updateAutoScroll = useCallback10(
18540
19184
  (clientY) => {
18541
19185
  const clip = getIframeChromeClip(parentScrollRef.current);
18542
19186
  let delta = 0;
@@ -18558,7 +19202,7 @@ function useSectionDrag({
18558
19202
  },
18559
19203
  [parentScrollRef, stopAutoScroll, tickAutoScroll]
18560
19204
  );
18561
- const clearSectionDragVisuals = useCallback9(() => {
19205
+ const clearSectionDragVisuals = useCallback10(() => {
18562
19206
  sectionDragRef.current?.draggedEl.removeAttribute("data-ohw-section-dragging");
18563
19207
  sectionDragRef.current = null;
18564
19208
  setSectionDropSlots([]);
@@ -18568,7 +19212,7 @@ function useSectionDrag({
18568
19212
  document.documentElement.removeAttribute("data-ohw-section-dragging-root");
18569
19213
  unlockItemDragInteraction();
18570
19214
  }, [stopAutoScroll]);
18571
- const refreshSectionDragVisuals = useCallback9(
19215
+ const refreshSectionDragVisuals = useCallback10(
18572
19216
  (session, clientX, clientY) => {
18573
19217
  session.lastClientX = clientX;
18574
19218
  session.lastClientY = clientY;
@@ -18582,7 +19226,7 @@ function useSectionDrag({
18582
19226
  },
18583
19227
  [updateAutoScroll]
18584
19228
  );
18585
- const beginSectionDrag = useCallback9(
19229
+ const beginSectionDrag = useCallback10(
18586
19230
  (session) => {
18587
19231
  sectionDragRef.current = session;
18588
19232
  setIsSectionDragging(true);
@@ -18593,7 +19237,7 @@ function useSectionDrag({
18593
19237
  },
18594
19238
  [refreshSectionDragVisuals]
18595
19239
  );
18596
- const commitSectionDrag = useCallback9(() => {
19240
+ const commitSectionDrag = useCallback10(() => {
18597
19241
  const session = sectionDragRef.current;
18598
19242
  if (!session) {
18599
19243
  clearSectionDragVisuals();
@@ -18622,7 +19266,7 @@ function useSectionDrag({
18622
19266
  });
18623
19267
  });
18624
19268
  }, [clearSectionDragVisuals, editContentRef, postToParentRef]);
18625
- const startSectionPressDrag = useCallback9(
19269
+ const startSectionPressDrag = useCallback10(
18626
19270
  (el, clientX, clientY, pointerId) => {
18627
19271
  if (navDragRef.current || footerDragRef.current || sectionDragRef.current) return false;
18628
19272
  const instanceId = instanceIdOf(el);
@@ -18639,7 +19283,7 @@ function useSectionDrag({
18639
19283
  },
18640
19284
  [footerDragRef, navDragRef]
18641
19285
  );
18642
- useEffect13(() => {
19286
+ useEffect14(() => {
18643
19287
  if (!isEditMode) return;
18644
19288
  const onPointerDown = (e) => {
18645
19289
  if (e.button !== 0) return;
@@ -18745,7 +19389,7 @@ function useSectionDrag({
18745
19389
 
18746
19390
  // src/ui/footer-container-chrome.tsx
18747
19391
  import { Plus as Plus2 } from "lucide-react";
18748
- import { jsx as jsx32, jsxs as jsxs22 } from "react/jsx-runtime";
19392
+ import { jsx as jsx33, jsxs as jsxs23 } from "react/jsx-runtime";
18749
19393
  function FooterContainerChrome({
18750
19394
  rect,
18751
19395
  onAdd,
@@ -18753,7 +19397,7 @@ function FooterContainerChrome({
18753
19397
  }) {
18754
19398
  const chromeGap = 6;
18755
19399
  const buttonMargin = 7;
18756
- return /* @__PURE__ */ jsx32(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx32(
19400
+ return /* @__PURE__ */ jsx33(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx33(
18757
19401
  "div",
18758
19402
  {
18759
19403
  "data-ohw-footer-container-chrome": "",
@@ -18765,8 +19409,8 @@ function FooterContainerChrome({
18765
19409
  width: rect.width + chromeGap * 2,
18766
19410
  height: rect.height + chromeGap * 2
18767
19411
  },
18768
- children: /* @__PURE__ */ jsxs22(Tooltip, { children: [
18769
- /* @__PURE__ */ jsx32(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx32(
19412
+ children: /* @__PURE__ */ jsxs23(Tooltip, { children: [
19413
+ /* @__PURE__ */ jsx33(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx33(
18770
19414
  "button",
18771
19415
  {
18772
19416
  type: "button",
@@ -18785,17 +19429,17 @@ function FooterContainerChrome({
18785
19429
  if (addDisabled) return;
18786
19430
  onAdd();
18787
19431
  },
18788
- children: /* @__PURE__ */ jsx32(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
19432
+ children: /* @__PURE__ */ jsx33(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
18789
19433
  }
18790
19434
  ) }),
18791
- /* @__PURE__ */ jsx32(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
19435
+ /* @__PURE__ */ jsx33(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
18792
19436
  ] })
18793
19437
  }
18794
19438
  ) });
18795
19439
  }
18796
19440
 
18797
19441
  // src/lib/carousel.ts
18798
- import { useEffect as useEffect14, useState as useState15 } from "react";
19442
+ import { useEffect as useEffect15, useState as useState16 } from "react";
18799
19443
  var CAROUSEL_ATTR = "data-ohw-carousel";
18800
19444
  var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
18801
19445
  var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
@@ -18857,8 +19501,8 @@ function applyCarouselNode(key, val) {
18857
19501
  return true;
18858
19502
  }
18859
19503
  function useOhwCarousel(key, initial) {
18860
- const [images, setImages] = useState15(initial);
18861
- useEffect14(() => {
19504
+ const [images, setImages] = useState16(initial);
19505
+ useEffect15(() => {
18862
19506
  const el = document.querySelector(
18863
19507
  `[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
18864
19508
  );
@@ -19278,13 +19922,13 @@ function deleteSelectedNavFooterItem(deps) {
19278
19922
 
19279
19923
  // src/ui/navbar-container-chrome.tsx
19280
19924
  import { Plus as Plus3 } from "lucide-react";
19281
- import { jsx as jsx33 } from "react/jsx-runtime";
19925
+ import { jsx as jsx34 } from "react/jsx-runtime";
19282
19926
  function NavbarContainerChrome({
19283
19927
  rect,
19284
19928
  onAdd
19285
19929
  }) {
19286
19930
  const chromeGap = 6;
19287
- return /* @__PURE__ */ jsx33(
19931
+ return /* @__PURE__ */ jsx34(
19288
19932
  "div",
19289
19933
  {
19290
19934
  "data-ohw-navbar-container-chrome": "",
@@ -19296,7 +19940,7 @@ function NavbarContainerChrome({
19296
19940
  width: rect.width + chromeGap * 2,
19297
19941
  height: rect.height + chromeGap * 2
19298
19942
  },
19299
- children: /* @__PURE__ */ jsx33(
19943
+ children: /* @__PURE__ */ jsx34(
19300
19944
  "button",
19301
19945
  {
19302
19946
  type: "button",
@@ -19313,7 +19957,7 @@ function NavbarContainerChrome({
19313
19957
  e.stopPropagation();
19314
19958
  onAdd();
19315
19959
  },
19316
- children: /* @__PURE__ */ jsx33(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
19960
+ children: /* @__PURE__ */ jsx34(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
19317
19961
  }
19318
19962
  )
19319
19963
  }
@@ -19322,7 +19966,7 @@ function NavbarContainerChrome({
19322
19966
 
19323
19967
  // src/ui/drop-indicator.tsx
19324
19968
  import * as React11 from "react";
19325
- import { jsx as jsx34 } from "react/jsx-runtime";
19969
+ import { jsx as jsx35 } from "react/jsx-runtime";
19326
19970
  var dropIndicatorVariants = cva(
19327
19971
  "ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
19328
19972
  {
@@ -19346,7 +19990,7 @@ var dropIndicatorVariants = cva(
19346
19990
  );
19347
19991
  var DropIndicator = React11.forwardRef(
19348
19992
  ({ className, direction, state, ...props }, ref) => {
19349
- return /* @__PURE__ */ jsx34(
19993
+ return /* @__PURE__ */ jsx35(
19350
19994
  "div",
19351
19995
  {
19352
19996
  ref,
@@ -19363,7 +20007,7 @@ var DropIndicator = React11.forwardRef(
19363
20007
  DropIndicator.displayName = "DropIndicator";
19364
20008
 
19365
20009
  // src/ui/badge.tsx
19366
- import { jsx as jsx35 } from "react/jsx-runtime";
20010
+ import { jsx as jsx36 } from "react/jsx-runtime";
19367
20011
  var badgeVariants = cva(
19368
20012
  "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",
19369
20013
  {
@@ -19381,13 +20025,13 @@ var badgeVariants = cva(
19381
20025
  }
19382
20026
  );
19383
20027
  function Badge({ className, variant, ...props }) {
19384
- return /* @__PURE__ */ jsx35("div", { className: cn(badgeVariants({ variant }), className), ...props });
20028
+ return /* @__PURE__ */ jsx36("div", { className: cn(badgeVariants({ variant }), className), ...props });
19385
20029
  }
19386
20030
 
19387
20031
  // src/OhhwellsBridge.tsx
19388
20032
  import { Brush as Brush2, Link as Link2, Plus as Plus4, Settings } from "lucide-react";
19389
- import { Fragment as Fragment10, jsx as jsx36, jsxs as jsxs23 } from "react/jsx-runtime";
19390
- var PRIMARY5 = "#0885FE";
20033
+ import { Fragment as Fragment11, jsx as jsx37, jsxs as jsxs24 } from "react/jsx-runtime";
20034
+ var PRIMARY6 = "#0885FE";
19391
20035
  var IMAGE_FADE_MS = 300;
19392
20036
  var MEDIA_SETTLE_TIMEOUT_MS = 2500;
19393
20037
  function runOpacityFade(el, onDone) {
@@ -19508,7 +20152,7 @@ function duplicateSchedulingWidget(instanceId, scheduleId) {
19508
20152
  schedulingRoots.set(container, root);
19509
20153
  flushSync2(() => {
19510
20154
  root.render(
19511
- /* @__PURE__ */ jsx36(
20155
+ /* @__PURE__ */ jsx37(
19512
20156
  SchedulingWidget,
19513
20157
  {
19514
20158
  notifyOnConnect: false,
@@ -19551,21 +20195,10 @@ function parseSchedulingInsertAfter(insertAfter) {
19551
20195
  insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
19552
20196
  };
19553
20197
  }
19554
- function resolveSchedulingInsert(insertAfter, explicitInsertBefore) {
19555
- const parsed = parseSchedulingInsertAfter(insertAfter);
19556
- const insertBefore = explicitInsertBefore ?? parsed.insertBefore;
19557
- const effectiveInsertAfter = insertBefore && parsed.insertBefore === null ? `${insertAfter}${INSERT_BEFORE_MARKER}${insertBefore}` : insertAfter;
19558
- return { effectiveInsertAfter, insertBefore };
19559
- }
19560
- function getSchedulingMountPoint(insertAfter) {
19561
- const { anchor } = parseSchedulingInsertAfter(insertAfter);
19562
- let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
19563
- if (!anchorEl && anchor === "scheduling") {
19564
- const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
19565
- anchorEl = widgets.at(-1) ?? null;
19566
- }
19567
- if (!anchorEl) return null;
19568
- return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
20198
+ function resolveEntryAnchor(entry) {
20199
+ if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
20200
+ const parsed = parseSchedulingInsertAfter(entry.insertAfter);
20201
+ return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
19569
20202
  }
19570
20203
  function schedulingMountDepth(insertAfter) {
19571
20204
  if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
@@ -19582,8 +20215,7 @@ function getPageSchedulingEntries(raw) {
19582
20215
  }
19583
20216
  }
19584
20217
  function isSchedulingWidgetMissing(entry) {
19585
- const { effectiveInsertAfter } = resolveSchedulingInsert(entry.insertAfter);
19586
- return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
20218
+ return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
19587
20219
  }
19588
20220
  function hasMissingSchedulingWidgets(entries) {
19589
20221
  return entries.some(isSchedulingWidgetMissing);
@@ -19621,17 +20253,18 @@ function initSectionsFromContent(content, removeExisting = false, currentPath =
19621
20253
  } catch {
19622
20254
  }
19623
20255
  }
19624
- function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId, explicitInsertBefore) {
19625
- const { effectiveInsertAfter, insertBefore } = resolveSchedulingInsert(insertAfter, explicitInsertBefore);
19626
- const sectionId = schedulingSectionId(effectiveInsertAfter);
20256
+ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
20257
+ const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
20258
+ const sectionId = schedulingSectionId(widgetId);
19627
20259
  if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
19628
- const mountPoint = getSchedulingMountPoint(effectiveInsertAfter);
19629
- if (!mountPoint) return false;
20260
+ const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
20261
+ if (!anchorEl) return false;
20262
+ const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
19630
20263
  const container = document.createElement("div");
19631
20264
  container.dataset.ohwSectionContainer = "scheduling";
19632
20265
  container.dataset.ohwInstance = sectionId;
19633
- if (insertBefore) {
19634
- const beforeAnchor = document.querySelector(`[data-ohw-section="${insertBefore}"]`);
20266
+ if (beforeId) {
20267
+ const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
19635
20268
  const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
19636
20269
  if (!beforePoint) return false;
19637
20270
  beforePoint.insertAdjacentElement("beforebegin", container);
@@ -19642,20 +20275,26 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
19642
20275
  }
19643
20276
  tail.insertAdjacentElement("afterend", container);
19644
20277
  }
19645
- const root = createRoot2(container);
19646
- schedulingRoots.set(container, root);
19647
- flushSync2(() => {
19648
- root.render(
19649
- /* @__PURE__ */ jsx36(
19650
- SchedulingWidget,
19651
- {
19652
- notifyOnConnect,
19653
- initialScheduleId: scheduleId,
19654
- insertAfter: effectiveInsertAfter
19655
- }
19656
- )
19657
- );
19658
- });
20278
+ try {
20279
+ const root = createRoot2(container);
20280
+ schedulingRoots.set(container, root);
20281
+ flushSync2(() => {
20282
+ root.render(
20283
+ /* @__PURE__ */ jsx37(
20284
+ SchedulingWidget,
20285
+ {
20286
+ notifyOnConnect,
20287
+ initialScheduleId: scheduleId,
20288
+ insertAfter: widgetId
20289
+ }
20290
+ )
20291
+ );
20292
+ });
20293
+ } catch (err) {
20294
+ console.error("[ow:scheduling] render threw", err);
20295
+ container.remove();
20296
+ return false;
20297
+ }
19659
20298
  const tracker = getSectionsTracker();
19660
20299
  let sections = [];
19661
20300
  try {
@@ -19663,10 +20302,12 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
19663
20302
  } catch {
19664
20303
  }
19665
20304
  const inEditor = typeof window !== "undefined" && window.self !== window.top;
19666
- if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === effectiveInsertAfter)) {
20305
+ if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
19667
20306
  sections.push({
19668
20307
  type: "scheduling",
19669
- insertAfter: effectiveInsertAfter,
20308
+ insertAfter: widgetId,
20309
+ anchorId,
20310
+ beforeId: beforeId ?? null,
19670
20311
  pagePath: window.location.pathname,
19671
20312
  ...scheduleId ? { scheduleId } : {}
19672
20313
  });
@@ -19680,7 +20321,8 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
19680
20321
  for (let i = pending.length - 1; i >= 0; i--) {
19681
20322
  const entry = pending[i];
19682
20323
  const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
19683
- if (mountSchedulingWidget(entry.insertAfter, shouldNotify, entry.scheduleId ?? null)) {
20324
+ const { anchorId, beforeId } = resolveEntryAnchor(entry);
20325
+ if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
19684
20326
  pending.splice(i, 1);
19685
20327
  }
19686
20328
  }
@@ -20147,7 +20789,7 @@ function getNavigationSelectionParent(el) {
20147
20789
  if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
20148
20790
  return getFooterLinksContainer();
20149
20791
  }
20150
- if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
20792
+ 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)) {
20151
20793
  return getNavigationRoot(el);
20152
20794
  }
20153
20795
  return null;
@@ -20369,13 +21011,12 @@ var ICONS = {
20369
21011
  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"/>',
20370
21012
  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"/>'
20371
21013
  };
20372
- var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
20373
21014
  var SELECTION_CHROME_GAP2 = 4;
20374
21015
  var TOOLBAR_STROKE_GAP2 = 4;
20375
21016
  var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
20376
21017
  var HOVER_STROKE_WIDTH = 1.5;
20377
21018
  var TEXT_HOVER_SIDE_PAD = 4;
20378
- var CHROME_PRIMARY = `var(--ohw-primary, ${PRIMARY5})`;
21019
+ var CHROME_PRIMARY = `var(--ohw-primary, ${PRIMARY6})`;
20379
21020
  var TOOLBAR_GROUPS = [
20380
21021
  [
20381
21022
  { cmd: "bold", title: "Bold" },
@@ -20401,7 +21042,7 @@ function EditGlowChrome({
20401
21042
  hideHandle = false
20402
21043
  }) {
20403
21044
  const GAP = SELECTION_CHROME_GAP2;
20404
- return /* @__PURE__ */ jsxs23(
21045
+ return /* @__PURE__ */ jsxs24(
20405
21046
  "div",
20406
21047
  {
20407
21048
  ref: elRef,
@@ -20416,7 +21057,7 @@ function EditGlowChrome({
20416
21057
  zIndex: 2147483646
20417
21058
  },
20418
21059
  children: [
20419
- /* @__PURE__ */ jsx36(
21060
+ /* @__PURE__ */ jsx37(
20420
21061
  "div",
20421
21062
  {
20422
21063
  style: {
@@ -20430,7 +21071,7 @@ function EditGlowChrome({
20430
21071
  }
20431
21072
  }
20432
21073
  ),
20433
- reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx36(
21074
+ reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx37(
20434
21075
  "div",
20435
21076
  {
20436
21077
  "data-ohw-drag-handle-container": "",
@@ -20442,7 +21083,7 @@ function EditGlowChrome({
20442
21083
  transform: "translate(calc(-100% - 7px), -50%)",
20443
21084
  pointerEvents: dragDisabled ? "none" : "auto"
20444
21085
  },
20445
- children: /* @__PURE__ */ jsx36(
21086
+ children: /* @__PURE__ */ jsx37(
20446
21087
  DragHandle,
20447
21088
  {
20448
21089
  "aria-label": `Reorder ${reorderHrefKey}`,
@@ -20646,7 +21287,7 @@ function FloatingToolbar({
20646
21287
  return () => ro.disconnect();
20647
21288
  }, [showEditLink, activeCommands]);
20648
21289
  const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
20649
- return /* @__PURE__ */ jsx36(
21290
+ return /* @__PURE__ */ jsx37(
20650
21291
  "div",
20651
21292
  {
20652
21293
  ref: setRefs,
@@ -20658,12 +21299,12 @@ function FloatingToolbar({
20658
21299
  zIndex: 2147483647,
20659
21300
  pointerEvents: "auto"
20660
21301
  },
20661
- children: /* @__PURE__ */ jsxs23(CustomToolbar, { children: [
20662
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs23(React12.Fragment, { children: [
20663
- gi > 0 && /* @__PURE__ */ jsx36(CustomToolbarDivider, {}),
21302
+ children: /* @__PURE__ */ jsxs24(CustomToolbar, { children: [
21303
+ TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs24(React12.Fragment, { children: [
21304
+ gi > 0 && /* @__PURE__ */ jsx37(CustomToolbarDivider, {}),
20664
21305
  btns.map((btn) => {
20665
21306
  const isActive = activeCommands.has(btn.cmd);
20666
- return /* @__PURE__ */ jsx36(
21307
+ return /* @__PURE__ */ jsx37(
20667
21308
  CustomToolbarButton,
20668
21309
  {
20669
21310
  title: btn.title,
@@ -20672,7 +21313,7 @@ function FloatingToolbar({
20672
21313
  e.preventDefault();
20673
21314
  onCommand(btn.cmd);
20674
21315
  },
20675
- children: /* @__PURE__ */ jsx36(
21316
+ children: /* @__PURE__ */ jsx37(
20676
21317
  "svg",
20677
21318
  {
20678
21319
  width: "16",
@@ -20693,7 +21334,7 @@ function FloatingToolbar({
20693
21334
  );
20694
21335
  })
20695
21336
  ] }, gi)),
20696
- showEditLink ? /* @__PURE__ */ jsx36(
21337
+ showEditLink ? /* @__PURE__ */ jsx37(
20697
21338
  CustomToolbarButton,
20698
21339
  {
20699
21340
  type: "button",
@@ -20707,7 +21348,7 @@ function FloatingToolbar({
20707
21348
  e.preventDefault();
20708
21349
  e.stopPropagation();
20709
21350
  },
20710
- children: /* @__PURE__ */ jsx36(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
21351
+ children: /* @__PURE__ */ jsx37(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
20711
21352
  }
20712
21353
  ) : null
20713
21354
  ] })
@@ -20724,7 +21365,7 @@ function StateToggle({
20724
21365
  states,
20725
21366
  onStateChange
20726
21367
  }) {
20727
- return /* @__PURE__ */ jsx36(
21368
+ return /* @__PURE__ */ jsx37(
20728
21369
  ToggleGroup,
20729
21370
  {
20730
21371
  "data-ohw-state-toggle": "",
@@ -20738,11 +21379,12 @@ function StateToggle({
20738
21379
  left: rect.right - 8,
20739
21380
  transform: "translateX(-100%)"
20740
21381
  },
20741
- children: states.map((state) => /* @__PURE__ */ jsx36(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
21382
+ children: states.map((state) => /* @__PURE__ */ jsx37(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
20742
21383
  }
20743
21384
  );
20744
21385
  }
20745
21386
  var contentCache = /* @__PURE__ */ new Map();
21387
+ var fetchedContentPaths = /* @__PURE__ */ new Set();
20746
21388
  var brandingCache = /* @__PURE__ */ new Map();
20747
21389
  var OHW_LOADER_STYLE = {
20748
21390
  position: "fixed",
@@ -20754,9 +21396,9 @@ var OHW_LOADER_STYLE = {
20754
21396
  justifyContent: "center"
20755
21397
  };
20756
21398
  function OhwLoaderSpinner() {
20757
- return /* @__PURE__ */ jsxs23("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", "aria-hidden": true, children: [
20758
- /* @__PURE__ */ jsx36("circle", { cx: "14", cy: "14", r: "11", stroke: "#E7E5E4", strokeWidth: "3" }),
20759
- /* @__PURE__ */ jsx36(
21399
+ return /* @__PURE__ */ jsxs24("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", "aria-hidden": true, children: [
21400
+ /* @__PURE__ */ jsx37("circle", { cx: "14", cy: "14", r: "11", stroke: "#E7E5E4", strokeWidth: "3" }),
21401
+ /* @__PURE__ */ jsx37(
20760
21402
  "circle",
20761
21403
  {
20762
21404
  cx: "14",
@@ -20766,7 +21408,7 @@ function OhwLoaderSpinner() {
20766
21408
  strokeWidth: "3",
20767
21409
  strokeDasharray: "17 52",
20768
21410
  strokeLinecap: "round",
20769
- children: /* @__PURE__ */ jsx36(
21411
+ children: /* @__PURE__ */ jsx37(
20770
21412
  "animateTransform",
20771
21413
  {
20772
21414
  attributeName: "transform",
@@ -20782,7 +21424,7 @@ function OhwLoaderSpinner() {
20782
21424
  ] });
20783
21425
  }
20784
21426
  function OhwBrandMark() {
20785
- return /* @__PURE__ */ jsxs23(
21427
+ return /* @__PURE__ */ jsxs24(
20786
21428
  "svg",
20787
21429
  {
20788
21430
  width: "16",
@@ -20793,7 +21435,7 @@ function OhwBrandMark() {
20793
21435
  style: { display: "block", flexShrink: 0 },
20794
21436
  xmlns: "http://www.w3.org/2000/svg",
20795
21437
  children: [
20796
- /* @__PURE__ */ jsx36(
21438
+ /* @__PURE__ */ jsx37(
20797
21439
  "mask",
20798
21440
  {
20799
21441
  id: "ohw-badge-mark",
@@ -20803,15 +21445,15 @@ function OhwBrandMark() {
20803
21445
  y: "0",
20804
21446
  width: "48",
20805
21447
  height: "48",
20806
- 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" })
21448
+ 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" })
20807
21449
  }
20808
21450
  ),
20809
- /* @__PURE__ */ jsxs23("g", { mask: "url(#ohw-badge-mark)", children: [
20810
- /* @__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" }),
20811
- /* @__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" }),
20812
- /* @__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" }),
20813
- /* @__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" }),
20814
- /* @__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" })
21451
+ /* @__PURE__ */ jsxs24("g", { mask: "url(#ohw-badge-mark)", children: [
21452
+ /* @__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" }),
21453
+ /* @__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" }),
21454
+ /* @__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" }),
21455
+ /* @__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" }),
21456
+ /* @__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" })
20815
21457
  ] })
20816
21458
  ]
20817
21459
  }
@@ -20848,7 +21490,7 @@ var OHW_BADGE_LABEL_STYLE = {
20848
21490
  whiteSpace: "nowrap"
20849
21491
  };
20850
21492
  function MadeWithOhhWells() {
20851
- return /* @__PURE__ */ jsxs23(
21493
+ return /* @__PURE__ */ jsxs24(
20852
21494
  "a",
20853
21495
  {
20854
21496
  href: "https://ohhwells.com",
@@ -20858,8 +21500,8 @@ function MadeWithOhhWells() {
20858
21500
  "data-ohw-badge": "",
20859
21501
  style: OHW_BADGE_STYLE,
20860
21502
  children: [
20861
- /* @__PURE__ */ jsx36(OhwBrandMark, {}),
20862
- /* @__PURE__ */ jsx36("span", { style: OHW_BADGE_LABEL_STYLE, children: "Made with OhhWells" })
21503
+ /* @__PURE__ */ jsx37(OhwBrandMark, {}),
21504
+ /* @__PURE__ */ jsx37("span", { style: OHW_BADGE_LABEL_STYLE, children: "Made with OhhWells" })
20863
21505
  ]
20864
21506
  }
20865
21507
  );
@@ -20905,8 +21547,8 @@ function OhhwellsBridge() {
20905
21547
  const router = useRouter3();
20906
21548
  const searchParams = useSearchParams();
20907
21549
  const isEditMode = isEditSessionActive();
20908
- const [bridgeRoot, setBridgeRoot] = useState16(null);
20909
- useEffect15(() => {
21550
+ const [bridgeRoot, setBridgeRoot] = useState17(null);
21551
+ useEffect16(() => {
20910
21552
  const figtreeFontId = "ohw-figtree-font";
20911
21553
  if (!document.getElementById(figtreeFontId)) {
20912
21554
  const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
@@ -20932,7 +21574,7 @@ function OhhwellsBridge() {
20932
21574
  };
20933
21575
  }, []);
20934
21576
  const subdomainFromQuery = searchParams.get("subdomain");
20935
- const [subdomain, setSubdomain] = useState16(() => resolveSubdomain(subdomainFromQuery));
21577
+ const [subdomain, setSubdomain] = useState17(() => resolveSubdomain(subdomainFromQuery));
20936
21578
  useLayoutEffect5(() => {
20937
21579
  const next = resolveSubdomain(subdomainFromQuery);
20938
21580
  if (next !== subdomain) setSubdomain(next);
@@ -20945,54 +21587,55 @@ function OhhwellsBridge() {
20945
21587
  }, 0);
20946
21588
  return () => window.clearTimeout(t);
20947
21589
  }, [subdomainFromQuery, subdomain]);
20948
- useEffect15(() => {
21590
+ useEffect16(() => {
20949
21591
  if (!subdomainFromQuery || typeof window === "undefined") return;
20950
21592
  const url = new URL(window.location.href);
20951
21593
  if (!url.searchParams.has("subdomain")) return;
21594
+ if (!resolveSubdomain(null)) return;
20952
21595
  url.searchParams.delete("subdomain");
20953
21596
  window.history.replaceState(null, "", url.pathname + url.search + url.hash);
20954
21597
  }, [subdomainFromQuery]);
20955
21598
  useLinkHrefGuardian(pathname, subdomain, isEditMode);
20956
21599
  useSavedLinkNavigation(isEditMode);
20957
- const postToParent2 = useCallback10((data) => {
21600
+ const postToParent2 = useCallback11((data) => {
20958
21601
  if (typeof window !== "undefined" && window.parent !== window) {
20959
21602
  window.parent.postMessage(data, "*");
20960
21603
  }
20961
21604
  }, []);
20962
- const [fetchState, setFetchState] = useState16("idle");
20963
- const [showBranding, setShowBranding] = useState16(false);
20964
- const autoSaveTimers = useRef12(/* @__PURE__ */ new Map());
20965
- const activeElRef = useRef12(null);
20966
- const pointerHeldRef = useRef12(false);
20967
- const selectedElRef = useRef12(null);
20968
- const selectedHrefKeyRef = useRef12(null);
20969
- const selectedFooterColAttrRef = useRef12(null);
20970
- const originalContentRef = useRef12(null);
20971
- const activeStateElRef = useRef12(null);
20972
- const parentScrollRef = useRef12(null);
20973
- const visibleViewportRef = useRef12(null);
20974
- const [dialogPortalContainer, setDialogPortalContainer] = useState16(null);
20975
- const attachVisibleViewport = useCallback10((node) => {
21605
+ const [fetchState, setFetchState] = useState17("idle");
21606
+ const [showBranding, setShowBranding] = useState17(false);
21607
+ const autoSaveTimers = useRef13(/* @__PURE__ */ new Map());
21608
+ const activeElRef = useRef13(null);
21609
+ const pointerHeldRef = useRef13(false);
21610
+ const selectedElRef = useRef13(null);
21611
+ const selectedHrefKeyRef = useRef13(null);
21612
+ const selectedFooterColAttrRef = useRef13(null);
21613
+ const originalContentRef = useRef13(null);
21614
+ const activeStateElRef = useRef13(null);
21615
+ const parentScrollRef = useRef13(null);
21616
+ const visibleViewportRef = useRef13(null);
21617
+ const [dialogPortalContainer, setDialogPortalContainer] = useState17(null);
21618
+ const attachVisibleViewport = useCallback11((node) => {
20976
21619
  visibleViewportRef.current = node;
20977
21620
  setDialogPortalContainer(node);
20978
21621
  if (node) applyVisibleViewport(node, parentScrollRef.current);
20979
21622
  }, []);
20980
- const toolbarElRef = useRef12(null);
20981
- const glowElRef = useRef12(null);
20982
- const hoveredImageRef = useRef12(null);
20983
- const hoveredImageHasTextOverlapRef = useRef12(false);
20984
- const dragOverElRef = useRef12(null);
20985
- const [mediaHover, setMediaHover] = useState16(null);
20986
- const [selectedAiSectionId, setSelectedAiSectionId] = useState16(null);
20987
- const selectedAiSectionIdRef = useRef12(null);
20988
- const handleAiSectionSelectionChange = useCallback10((id) => {
21623
+ const toolbarElRef = useRef13(null);
21624
+ const glowElRef = useRef13(null);
21625
+ const hoveredImageRef = useRef13(null);
21626
+ const hoveredImageHasTextOverlapRef = useRef13(false);
21627
+ const dragOverElRef = useRef13(null);
21628
+ const [mediaHover, setMediaHover] = useState17(null);
21629
+ const [selectedAiSectionId, setSelectedAiSectionId] = useState17(null);
21630
+ const selectedAiSectionIdRef = useRef13(null);
21631
+ const handleAiSectionSelectionChange = useCallback11((id) => {
20989
21632
  selectedAiSectionIdRef.current = id;
20990
21633
  setSelectedAiSectionId(id);
20991
21634
  }, []);
20992
- const [selectedMedia, setSelectedMedia] = useState16(null);
20993
- const selectedMediaElRef = useRef12(null);
20994
- const mediaKeyDropTokenRef = useRef12(0);
20995
- const clearMediaSelection = useCallback10(() => {
21635
+ const [selectedMedia, setSelectedMedia] = useState17(null);
21636
+ const selectedMediaElRef = useRef13(null);
21637
+ const mediaKeyDropTokenRef = useRef13(0);
21638
+ const clearMediaSelection = useCallback11(() => {
20996
21639
  const prev = selectedMediaElRef.current;
20997
21640
  selectedMediaElRef.current = null;
20998
21641
  setSelectedMedia(null);
@@ -21017,9 +21660,9 @@ function OhhwellsBridge() {
21017
21660
  window.postMessage({ type: "ow:media-key-drop", token }, "*");
21018
21661
  }
21019
21662
  }, []);
21020
- const clearMediaSelectionRef = useRef12(clearMediaSelection);
21663
+ const clearMediaSelectionRef = useRef13(clearMediaSelection);
21021
21664
  clearMediaSelectionRef.current = clearMediaSelection;
21022
- const selectMediaElement = useCallback10((el) => {
21665
+ const selectMediaElement = useCallback11((el) => {
21023
21666
  const r2 = el.getBoundingClientRect();
21024
21667
  const video = el.dataset.ohwEditable === "video" ? el.querySelector("video") : null;
21025
21668
  selectedMediaElRef.current = el;
@@ -21043,9 +21686,9 @@ function OhhwellsBridge() {
21043
21686
  keyLabel: el.dataset.ohwEditable === "video" ? "Video" : el.dataset.ohwEditable === "bg-image" ? "Background" : "Image"
21044
21687
  });
21045
21688
  }, []);
21046
- const selectMediaElementRef = useRef12(selectMediaElement);
21689
+ const selectMediaElementRef = useRef13(selectMediaElement);
21047
21690
  selectMediaElementRef.current = selectMediaElement;
21048
- useEffect15(() => {
21691
+ useEffect16(() => {
21049
21692
  if (!selectedMedia) return;
21050
21693
  const update = () => {
21051
21694
  const el = selectedMediaElRef.current;
@@ -21065,54 +21708,54 @@ function OhhwellsBridge() {
21065
21708
  window.removeEventListener("resize", update);
21066
21709
  };
21067
21710
  }, [selectedMedia !== null]);
21068
- const [carouselHover, setCarouselHover] = useState16(null);
21069
- const [uploadingRects, setUploadingRects] = useState16({});
21070
- const hoveredGapRef = useRef12(null);
21071
- const imageUnhoverTimerRef = useRef12(null);
21072
- const imageShowTimerRef = useRef12(null);
21073
- const editStylesRef = useRef12(null);
21074
- const activateRef = useRef12(() => {
21711
+ const [carouselHover, setCarouselHover] = useState17(null);
21712
+ const [uploadingRects, setUploadingRects] = useState17({});
21713
+ const hoveredGapRef = useRef13(null);
21714
+ const imageUnhoverTimerRef = useRef13(null);
21715
+ const imageShowTimerRef = useRef13(null);
21716
+ const editStylesRef = useRef13(null);
21717
+ const activateRef = useRef13(() => {
21075
21718
  });
21076
- const deactivateRef = useRef12(() => {
21719
+ const deactivateRef = useRef13(() => {
21077
21720
  });
21078
- const selectRef = useRef12(() => {
21721
+ const selectRef = useRef13(() => {
21079
21722
  });
21080
- const selectFrameRef = useRef12(() => {
21723
+ const selectFrameRef = useRef13(() => {
21081
21724
  });
21082
- const selectLogoRef = useRef12(() => {
21725
+ const selectLogoRef = useRef13(() => {
21083
21726
  });
21084
- const openLogoSizePanelRef = useRef12(() => {
21727
+ const openLogoSizePanelRef = useRef13(() => {
21085
21728
  });
21086
- const deselectRef = useRef12(() => {
21729
+ const deselectRef = useRef13(() => {
21087
21730
  });
21088
- const closeFloatingPanelOnlyRef = useRef12(() => {
21731
+ const closeFloatingPanelOnlyRef = useRef13(() => {
21089
21732
  });
21090
- const reselectNavigationItemRef = useRef12(() => {
21733
+ const reselectNavigationItemRef = useRef13(() => {
21091
21734
  });
21092
- const commitNavigationTextEditRef = useRef12(() => {
21735
+ const commitNavigationTextEditRef = useRef13(() => {
21093
21736
  });
21094
- const handleDeleteSelectedRef = useRef12(() => false);
21095
- const runPendingDeleteUndoRef = useRef12(() => false);
21096
- const isFooterFrameSelectionRef = useRef12(false);
21097
- const refreshActiveCommandsRef = useRef12(() => {
21737
+ const handleDeleteSelectedRef = useRef13(() => false);
21738
+ const runPendingDeleteUndoRef = useRef13(() => false);
21739
+ const isFooterFrameSelectionRef = useRef13(false);
21740
+ const refreshActiveCommandsRef = useRef13(() => {
21098
21741
  });
21099
- const postToParentRef = useRef12(postToParent2);
21742
+ const postToParentRef = useRef13(postToParent2);
21100
21743
  postToParentRef.current = postToParent2;
21101
- const aiSectionApiRef = useRef12(null);
21102
- const sectionsLoadedRef = useRef12(false);
21103
- const pendingScheduleConfigRequests = useRef12([]);
21104
- const [toolbarRect, setToolbarRect] = useState16(null);
21105
- const [formPickRect, setFormPickRect] = useState16(null);
21106
- const formPickElRef = useRef12(null);
21107
- const [formViewState, setFormViewStateUi] = useState16("default");
21108
- const [formPickCount, setFormPickCount] = useState16(null);
21109
- const [formHoverRect, setFormHoverRect] = useState16(null);
21110
- const formHoverElRef = useRef12(null);
21111
- const [fieldPickRect, setFieldPickRect] = useState16(null);
21112
- const fieldPickElRef = useRef12(null);
21113
- const [fieldPickState, setFieldPickState] = useState16(null);
21114
- const [fieldTypePickerOpen, setFieldTypePickerOpen] = useState16(false);
21115
- const clearFormPick = useCallback10(() => {
21744
+ const aiSectionApiRef = useRef13(null);
21745
+ const sectionsLoadedRef = useRef13(false);
21746
+ const pendingScheduleConfigRequests = useRef13([]);
21747
+ const [toolbarRect, setToolbarRect] = useState17(null);
21748
+ const [formPickRect, setFormPickRect] = useState17(null);
21749
+ const formPickElRef = useRef13(null);
21750
+ const [formViewState, setFormViewStateUi] = useState17("default");
21751
+ const [formPickCount, setFormPickCount] = useState17(null);
21752
+ const [formHoverRect, setFormHoverRect] = useState17(null);
21753
+ const formHoverElRef = useRef13(null);
21754
+ const [fieldPickRect, setFieldPickRect] = useState17(null);
21755
+ const fieldPickElRef = useRef13(null);
21756
+ const [fieldPickState, setFieldPickState] = useState17(null);
21757
+ const [fieldTypePickerOpen, setFieldTypePickerOpen] = useState17(false);
21758
+ const clearFormPick = useCallback11(() => {
21116
21759
  const form = formPickElRef.current;
21117
21760
  const editing = fieldPickElRef.current;
21118
21761
  if (commitPlaceholderEdit(editing) && editing) {
@@ -21132,7 +21775,7 @@ function OhhwellsBridge() {
21132
21775
  formPickElRef.current = null;
21133
21776
  setFormPickRect(null);
21134
21777
  }, []);
21135
- const clearFieldPick = useCallback10(() => {
21778
+ const clearFieldPick = useCallback11(() => {
21136
21779
  const wrapper = fieldPickElRef.current;
21137
21780
  if (commitPlaceholderEdit(wrapper) && wrapper) {
21138
21781
  const form = wrapper.closest('[data-ohw-editable="form"]');
@@ -21142,9 +21785,9 @@ function OhhwellsBridge() {
21142
21785
  setFieldPickRect(null);
21143
21786
  setFieldPickState(null);
21144
21787
  }, []);
21145
- const persistFieldsRef = useRef12(() => {
21788
+ const persistFieldsRef = useRef13(() => {
21146
21789
  });
21147
- const persistFields = useCallback10(
21790
+ const persistFields = useCallback11(
21148
21791
  (form) => {
21149
21792
  const key = formKeyOf(form);
21150
21793
  if (!key) return;
@@ -21155,7 +21798,7 @@ function OhhwellsBridge() {
21155
21798
  []
21156
21799
  );
21157
21800
  persistFieldsRef.current = persistFields;
21158
- const selectField = useCallback10((wrapper) => {
21801
+ const selectField = useCallback11((wrapper) => {
21159
21802
  if (fieldPickElRef.current && fieldPickElRef.current !== wrapper) {
21160
21803
  commitPlaceholderEdit(fieldPickElRef.current);
21161
21804
  }
@@ -21168,7 +21811,7 @@ function OhhwellsBridge() {
21168
21811
  setFieldPickState({ type: fieldTypeOf(wrapper), required: isFieldRequired(wrapper) });
21169
21812
  setFieldTypePickerOpen(false);
21170
21813
  }, []);
21171
- const withSelectedField = useCallback10(
21814
+ const withSelectedField = useCallback11(
21172
21815
  (run) => {
21173
21816
  const wrapper = fieldPickElRef.current;
21174
21817
  const form = formPickElRef.current;
@@ -21181,28 +21824,28 @@ function OhhwellsBridge() {
21181
21824
  },
21182
21825
  [persistFields]
21183
21826
  );
21184
- const handleFieldTypeChange = useCallback10(
21827
+ const handleFieldTypeChange = useCallback11(
21185
21828
  (type) => withSelectedField((_form, wrapper) => {
21186
21829
  applyFieldType(wrapper, type);
21187
21830
  selectField(wrapper);
21188
21831
  }),
21189
21832
  [selectField, withSelectedField]
21190
21833
  );
21191
- const handleFieldRequiredToggle = useCallback10(
21834
+ const handleFieldRequiredToggle = useCallback11(
21192
21835
  () => withSelectedField((_form, wrapper) => {
21193
21836
  setFieldRequired(wrapper, !isFieldRequired(wrapper));
21194
21837
  selectField(wrapper);
21195
21838
  }),
21196
21839
  [selectField, withSelectedField]
21197
21840
  );
21198
- const handleFieldDuplicate = useCallback10(
21841
+ const handleFieldDuplicate = useCallback11(
21199
21842
  () => withSelectedField((form, wrapper) => {
21200
21843
  const copy = duplicateField(form, wrapper);
21201
21844
  selectField(copy);
21202
21845
  }),
21203
21846
  [selectField, withSelectedField]
21204
21847
  );
21205
- const handleFieldDelete = useCallback10(
21848
+ const handleFieldDelete = useCallback11(
21206
21849
  () => withSelectedField((_form, wrapper) => {
21207
21850
  removeField(wrapper);
21208
21851
  clearFieldPick();
@@ -21210,7 +21853,7 @@ function OhhwellsBridge() {
21210
21853
  }),
21211
21854
  [clearFieldPick, withSelectedField]
21212
21855
  );
21213
- const handleAddField = useCallback10(
21856
+ const handleAddField = useCallback11(
21214
21857
  (type) => {
21215
21858
  const form = formPickElRef.current;
21216
21859
  if (!form) return;
@@ -21226,8 +21869,8 @@ function OhhwellsBridge() {
21226
21869
  },
21227
21870
  [persistFields, selectField]
21228
21871
  );
21229
- const fieldDragRef = useRef12(null);
21230
- const buildFieldDropSlots = useCallback10((form, draggedKey) => {
21872
+ const fieldDragRef = useRef13(null);
21873
+ const buildFieldDropSlots = useCallback11((form, draggedKey) => {
21231
21874
  const others = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== draggedKey);
21232
21875
  const slots = others.map((el) => {
21233
21876
  const rect = el.getBoundingClientRect();
@@ -21240,7 +21883,7 @@ function OhhwellsBridge() {
21240
21883
  }
21241
21884
  return slots;
21242
21885
  }, []);
21243
- const handleFieldDragStart = useCallback10(() => {
21886
+ const handleFieldDragStart = useCallback11(() => {
21244
21887
  const wrapper = fieldPickElRef.current;
21245
21888
  const form = formPickElRef.current;
21246
21889
  if (!wrapper || !form) return;
@@ -21249,18 +21892,18 @@ function OhhwellsBridge() {
21249
21892
  setFieldDragging(true);
21250
21893
  setFieldDropSlots(buildFieldDropSlots(form, key));
21251
21894
  }, [buildFieldDropSlots]);
21252
- const handleFieldDragEnd = useCallback10(() => {
21895
+ const handleFieldDragEnd = useCallback11(() => {
21253
21896
  fieldDragRef.current = null;
21254
21897
  setFieldDropIndex(null);
21255
21898
  setFieldDropSlots([]);
21256
21899
  setFieldDragging(false);
21257
21900
  }, []);
21258
- const [fieldDropIndex, setFieldDropIndex] = useState16(null);
21259
- const [fieldDropSlots, setFieldDropSlots] = useState16([]);
21260
- const [fieldDragging, setFieldDragging] = useState16(false);
21261
- const clearFormPickRef = useRef12(clearFormPick);
21901
+ const [fieldDropIndex, setFieldDropIndex] = useState17(null);
21902
+ const [fieldDropSlots, setFieldDropSlots] = useState17([]);
21903
+ const [fieldDragging, setFieldDragging] = useState17(false);
21904
+ const clearFormPickRef = useRef13(clearFormPick);
21262
21905
  clearFormPickRef.current = clearFormPick;
21263
- useEffect15(() => {
21906
+ useEffect16(() => {
21264
21907
  const el = fieldPickElRef.current;
21265
21908
  if (!el || fieldPickRect === null) return;
21266
21909
  const observer = new ResizeObserver(() => {
@@ -21269,7 +21912,7 @@ function OhhwellsBridge() {
21269
21912
  observer.observe(el);
21270
21913
  return () => observer.disconnect();
21271
21914
  }, [fieldPickRect !== null, fieldPickState]);
21272
- useEffect15(() => {
21915
+ useEffect16(() => {
21273
21916
  const el = formPickElRef.current;
21274
21917
  if (!el || formPickRect === null) return;
21275
21918
  const observer = new ResizeObserver(() => {
@@ -21278,25 +21921,25 @@ function OhhwellsBridge() {
21278
21921
  observer.observe(el);
21279
21922
  return () => observer.disconnect();
21280
21923
  }, [formPickRect !== null, formViewState]);
21281
- const [toolbarVariant, setToolbarVariant] = useState16("none");
21282
- const toolbarVariantRef = useRef12("none");
21924
+ const [toolbarVariant, setToolbarVariant] = useState17("none");
21925
+ const toolbarVariantRef = useRef13("none");
21283
21926
  toolbarVariantRef.current = toolbarVariant;
21284
- const [selectedIsCta, setSelectedIsCta] = useState16(false);
21285
- const [selectedIsSocial, setSelectedIsSocial] = useState16(false);
21286
- const [selectedIsSocialsRow, setSelectedIsSocialsRow] = useState16(false);
21287
- const [reorderHrefKey, setReorderHrefKey] = useState16(null);
21288
- const [reorderDragDisabled, setReorderDragDisabled] = useState16(false);
21289
- const [toggleState, setToggleState] = useState16(null);
21290
- const [maxBadge, setMaxBadge] = useState16(null);
21291
- const [activeCommands, setActiveCommands] = useState16(/* @__PURE__ */ new Set());
21292
- const [sectionGap, setSectionGap] = useState16(null);
21293
- const [toolbarShowEditLink, setToolbarShowEditLink] = useState16(false);
21294
- const hoveredNavContainerRef = useRef12(null);
21295
- const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState16(null);
21296
- const hoveredItemElRef = useRef12(null);
21297
- const [hoveredItemRect, setHoveredItemRect] = useState16(null);
21298
- const [hoveredTextRect, setHoveredTextRect] = useState16(null);
21299
- useEffect15(() => {
21927
+ const [selectedIsCta, setSelectedIsCta] = useState17(false);
21928
+ const [selectedIsSocial, setSelectedIsSocial] = useState17(false);
21929
+ const [selectedIsSocialsRow, setSelectedIsSocialsRow] = useState17(false);
21930
+ const [reorderHrefKey, setReorderHrefKey] = useState17(null);
21931
+ const [reorderDragDisabled, setReorderDragDisabled] = useState17(false);
21932
+ const [toggleState, setToggleState] = useState17(null);
21933
+ const [maxBadge, setMaxBadge] = useState17(null);
21934
+ const [activeCommands, setActiveCommands] = useState17(/* @__PURE__ */ new Set());
21935
+ const [sectionGap, setSectionGap] = useState17(null);
21936
+ const [toolbarShowEditLink, setToolbarShowEditLink] = useState17(false);
21937
+ const hoveredNavContainerRef = useRef13(null);
21938
+ const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState17(null);
21939
+ const hoveredItemElRef = useRef13(null);
21940
+ const [hoveredItemRect, setHoveredItemRect] = useState17(null);
21941
+ const [hoveredTextRect, setHoveredTextRect] = useState17(null);
21942
+ useEffect16(() => {
21300
21943
  const sync = () => {
21301
21944
  const el = document.querySelector(
21302
21945
  '[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]):not([data-ohw-editable="form"] *)'
@@ -21340,60 +21983,71 @@ function OhhwellsBridge() {
21340
21983
  });
21341
21984
  return () => observer.disconnect();
21342
21985
  }, []);
21343
- const siblingHintElRef = useRef12(null);
21344
- const [siblingHintRect, setSiblingHintRect] = useState16(null);
21345
- const [siblingHintRects, setSiblingHintRects] = useState16([]);
21346
- const [isItemDragging, setIsItemDragging] = useState16(false);
21347
- const [isFooterFrameSelection, setIsFooterFrameSelection] = useState16(false);
21986
+ const siblingHintElRef = useRef13(null);
21987
+ const [siblingHintRect, setSiblingHintRect] = useState17(null);
21988
+ const [siblingHintRects, setSiblingHintRects] = useState17([]);
21989
+ const [isItemDragging, setIsItemDragging] = useState17(false);
21990
+ const [isFooterFrameSelection, setIsFooterFrameSelection] = useState17(false);
21348
21991
  isFooterFrameSelectionRef.current = isFooterFrameSelection;
21349
- const [floatingPanel, setFloatingPanel] = useState16(null);
21350
- const floatingPanelOpenRef = useRef12(false);
21351
- floatingPanelOpenRef.current = floatingPanel !== null;
21352
- const floatingPanelRef = useRef12(null);
21353
- floatingPanelRef.current = floatingPanel;
21354
- const [floatingPanelPos, setFloatingPanelPos] = useState16(null);
21355
- const buttonCollectionDragRef = useRef12(null);
21356
- const buttonDropInsertIndexRef = useRef12(null);
21357
- const [buttonDropSlots, setButtonDropSlots] = useState16([]);
21358
- const [activeButtonDropIndex, setActiveButtonDropIndex] = useState16(null);
21359
- const buttonPointerDragRef = useRef12(null);
21360
- const [buttonStyleTick, setButtonStyleTick] = useState16(0);
21361
- const [logoSizeDraft, setLogoSizeDraft] = useState16(null);
21362
- const [editorViewport, setEditorViewport] = useState16("desktop");
21363
- const [parentScrollSnap, setParentScrollSnap] = useState16(null);
21364
- const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState16(null);
21365
- const [footerHeadingVisible, setFooterHeadingVisible] = useState16(null);
21366
- const footerDragRef = useRef12(null);
21367
- const [footerDropSlots, setFooterDropSlots] = useState16([]);
21368
- const [activeFooterDropIndex, setActiveFooterDropIndex] = useState16(null);
21369
- const [draggedItemRect, setDraggedItemRect] = useState16(null);
21370
- const footerPointerDragRef = useRef12(null);
21371
- const suppressNextClickRef = useRef12(false);
21372
- const suppressClickUntilRef = useRef12(0);
21373
- const [linkPopover, setLinkPopover] = useState16(null);
21374
- const linkPopoverSessionRef = useRef12(null);
21375
- const addNavAfterAnchorRef = useRef12(null);
21376
- const editContentRef = useRef12({});
21377
- const aiSectionsRef = useRef12("");
21378
- const applyTreeLocalRef = useRef12(
21992
+ const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState17(null);
21993
+ const [footerHeadingVisible, setFooterHeadingVisible] = useState17(null);
21994
+ const footerDragRef = useRef13(null);
21995
+ const [footerDropSlots, setFooterDropSlots] = useState17([]);
21996
+ const [activeFooterDropIndex, setActiveFooterDropIndex] = useState17(null);
21997
+ const [draggedItemRect, setDraggedItemRect] = useState17(null);
21998
+ const footerPointerDragRef = useRef13(null);
21999
+ const suppressNextClickRef = useRef13(false);
22000
+ const suppressClickUntilRef = useRef13(0);
22001
+ const [linkPopover, setLinkPopover] = useState17(null);
22002
+ const linkPopoverSessionRef = useRef13(null);
22003
+ const addNavAfterAnchorRef = useRef13(null);
22004
+ const editContentRef = useRef13({});
22005
+ const aiSectionsRef = useRef13("");
22006
+ const applyTreeLocalRef = useRef13(
21379
22007
  null
21380
22008
  );
21381
- const clearInteractionChromeRef = useRef12(() => {
22009
+ const clearInteractionChromeRef = useRef13(() => {
21382
22010
  });
21383
- const brandKitRef = useRef12("");
21384
- const stylesRef = useRef12("");
21385
- const appliedDrawerRef = useRef12(null);
21386
- const pendingDeleteUndoRef = useRef12(null);
21387
- const [sitePages, setSitePages] = useState16([]);
21388
- const [sectionsByPath, setSectionsByPath] = useState16({});
21389
- const sectionsPrefetchGenRef = useRef12(0);
21390
- const setLinkPopoverRef = useRef12(setLinkPopover);
21391
- const linkPopoverPanelRef = useRef12(null);
21392
- const linkPopoverOpenRef = useRef12(false);
21393
- const linkPopoverGraceUntilRef = useRef12(0);
22011
+ const brandKitRef = useRef13("");
22012
+ const stylesRef = useRef13("");
22013
+ const appliedDrawerRef = useRef13(null);
22014
+ const pendingDeleteUndoRef = useRef13(null);
22015
+ const [floatingPanel, setFloatingPanel] = useState17(null);
22016
+ const floatingPanelOpenRef = useRef13(false);
22017
+ const floatingPanelRef = useRef13(null);
22018
+ floatingPanelRef.current = floatingPanel;
22019
+ const setFloatingPanelRef = useRef13(setFloatingPanel);
22020
+ const [floatingPanelPos, setFloatingPanelPos] = useState17(null);
22021
+ const buttonCollectionDragRef = useRef13(null);
22022
+ const buttonDropInsertIndexRef = useRef13(null);
22023
+ const [buttonDropSlots, setButtonDropSlots] = useState17([]);
22024
+ const [activeButtonDropIndex, setActiveButtonDropIndex] = useState17(null);
22025
+ const buttonPointerDragRef = useRef13(null);
22026
+ const [buttonStyleTick, setButtonStyleTick] = useState17(0);
22027
+ const [logoSizeDraft, setLogoSizeDraft] = useState17(null);
22028
+ const [editorViewport, setEditorViewport] = useState17("desktop");
22029
+ const [parentScrollSnap, setParentScrollSnap] = useState17(null);
22030
+ const [sitePages, setSitePages] = useState17([]);
22031
+ const [sectionsByPath, setSectionsByPath] = useState17({});
22032
+ const sectionsPrefetchGenRef = useRef13(0);
22033
+ const setLinkPopoverRef = useRef13(setLinkPopover);
22034
+ const linkPopoverPanelRef = useRef13(null);
22035
+ const linkPopoverOpenRef = useRef13(false);
22036
+ const linkPopoverGraceUntilRef = useRef13(0);
21394
22037
  setLinkPopoverRef.current = setLinkPopover;
22038
+ setFloatingPanelRef.current = setFloatingPanel;
21395
22039
  linkPopoverSessionRef.current = linkPopover;
21396
- useEffect15(() => {
22040
+ floatingPanelOpenRef.current = Boolean(floatingPanel);
22041
+ useEffect16(() => {
22042
+ const syncViewport = () => {
22043
+ const next = window.innerWidth <= 480 ? "mobile" : "desktop";
22044
+ setEditorViewport((prev) => prev === next ? prev : next);
22045
+ };
22046
+ syncViewport();
22047
+ window.addEventListener("resize", syncViewport);
22048
+ return () => window.removeEventListener("resize", syncViewport);
22049
+ }, []);
22050
+ useEffect16(() => {
21397
22051
  setSectionOrderPersistHandler((entries) => {
21398
22052
  const currentPath = window.location.pathname;
21399
22053
  const merged = mergePageSectionOrder(editContentRef.current[SECTION_ORDER_KEY], currentPath, entries);
@@ -21449,7 +22103,7 @@ function OhhwellsBridge() {
21449
22103
  const bumpLinkPopoverGrace = () => {
21450
22104
  linkPopoverGraceUntilRef.current = Date.now() + 350;
21451
22105
  };
21452
- const runSectionsPrefetch = useCallback10((pages) => {
22106
+ const runSectionsPrefetch = useCallback11((pages) => {
21453
22107
  if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
21454
22108
  const gen = ++sectionsPrefetchGenRef.current;
21455
22109
  const paths = pages.map((p) => p.path);
@@ -21468,9 +22122,9 @@ function OhhwellsBridge() {
21468
22122
  );
21469
22123
  });
21470
22124
  }, [isEditMode, pathname]);
21471
- const runSectionsPrefetchRef = useRef12(runSectionsPrefetch);
22125
+ const runSectionsPrefetchRef = useRef13(runSectionsPrefetch);
21472
22126
  runSectionsPrefetchRef.current = runSectionsPrefetch;
21473
- useEffect15(() => {
22127
+ useEffect16(() => {
21474
22128
  if (!linkPopover) {
21475
22129
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
21476
22130
  return;
@@ -21498,7 +22152,7 @@ function OhhwellsBridge() {
21498
22152
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
21499
22153
  };
21500
22154
  }, [linkPopover, postToParent2]);
21501
- useEffect15(() => {
22155
+ useEffect16(() => {
21502
22156
  if (!isEditMode) return;
21503
22157
  const useFixtures = shouldUseDevFixtures();
21504
22158
  if (useFixtures) {
@@ -21522,14 +22176,14 @@ function OhhwellsBridge() {
21522
22176
  if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
21523
22177
  return () => window.removeEventListener("message", onSitePages);
21524
22178
  }, [isEditMode, postToParent2]);
21525
- useEffect15(() => {
22179
+ useEffect16(() => {
21526
22180
  if (!isEditMode || shouldUseDevFixtures()) return;
21527
22181
  void loadAllSectionsManifest().then((manifest) => {
21528
22182
  if (Object.keys(manifest).length === 0) return;
21529
22183
  setSectionsByPath((prev) => ({ ...manifest, ...prev }));
21530
22184
  });
21531
22185
  }, [isEditMode]);
21532
- useEffect15(() => {
22186
+ useEffect16(() => {
21533
22187
  const update = () => {
21534
22188
  const el = activeElRef.current ?? selectedElRef.current;
21535
22189
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
@@ -21553,10 +22207,10 @@ function OhhwellsBridge() {
21553
22207
  vvp.removeEventListener("resize", update);
21554
22208
  };
21555
22209
  }, []);
21556
- const refreshStateRules = useCallback10(() => {
22210
+ const refreshStateRules = useCallback11(() => {
21557
22211
  editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
21558
22212
  }, []);
21559
- const processConfigRequest = useCallback10((insertAfterVal) => {
22213
+ const processConfigRequest = useCallback11((insertAfterVal) => {
21560
22214
  const tracker = getSectionsTracker();
21561
22215
  let entries = [];
21562
22216
  try {
@@ -21579,7 +22233,7 @@ function OhhwellsBridge() {
21579
22233
  }
21580
22234
  window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
21581
22235
  }, [isEditMode]);
21582
- const deactivate = useCallback10(() => {
22236
+ const deactivate = useCallback11(() => {
21583
22237
  const el = activeElRef.current;
21584
22238
  if (!el) return;
21585
22239
  const isFormBlock = el.dataset.ohwEditable === "form";
@@ -21630,12 +22284,12 @@ function OhhwellsBridge() {
21630
22284
  setToolbarShowEditLink(false);
21631
22285
  postToParent2({ type: "ow:exit-edit" });
21632
22286
  }, [postToParent2]);
21633
- const clearSelectedAttr = useCallback10(() => {
22287
+ const clearSelectedAttr = useCallback11(() => {
21634
22288
  document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
21635
22289
  el.removeAttribute("data-ohw-selected");
21636
22290
  });
21637
22291
  }, []);
21638
- const deselect = useCallback10(() => {
22292
+ const deselect = useCallback11(() => {
21639
22293
  const nestedGroup = selectedElRef.current?.closest("[data-ohw-nav-children]") != null ? selectedElRef.current.closest("[data-ohw-nav-group]") : null;
21640
22294
  clearSelectedAttr();
21641
22295
  selectedElRef.current = null;
@@ -21670,20 +22324,20 @@ function OhhwellsBridge() {
21670
22324
  setToolbarVariant("none");
21671
22325
  }
21672
22326
  }, [clearSelectedAttr]);
21673
- const markSelected = useCallback10((el) => {
22327
+ const markSelected = useCallback11((el) => {
21674
22328
  clearSelectedAttr();
21675
22329
  el.removeAttribute("data-ohw-hovered");
21676
22330
  el.setAttribute("data-ohw-selected", "");
21677
22331
  }, [clearSelectedAttr]);
21678
- const isSelectedForHover = useCallback10((el) => {
22332
+ const isSelectedForHover = useCallback11((el) => {
21679
22333
  if (!el) return false;
21680
22334
  return [selectedElRef.current, activeElRef.current].some(
21681
22335
  (busy) => busy && (el === busy || busy.contains(el) || el.contains(busy))
21682
22336
  );
21683
22337
  }, []);
21684
- const isSelectedForHoverRef = useRef12(isSelectedForHover);
22338
+ const isSelectedForHoverRef = useRef13(isSelectedForHover);
21685
22339
  isSelectedForHoverRef.current = isSelectedForHover;
21686
- const resolveHrefKeyElement = useCallback10((hrefKey) => {
22340
+ const resolveHrefKeyElement = useCallback11((hrefKey) => {
21687
22341
  if (isFooterHrefKey(hrefKey)) {
21688
22342
  return document.querySelector(
21689
22343
  `footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
@@ -21698,7 +22352,7 @@ function OhhwellsBridge() {
21698
22352
  `[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
21699
22353
  );
21700
22354
  }, []);
21701
- const resyncSelectedNavigationItem = useCallback10(() => {
22355
+ const resyncSelectedNavigationItem = useCallback11(() => {
21702
22356
  const hrefKey = selectedHrefKeyRef.current;
21703
22357
  if (hrefKey) {
21704
22358
  const link = resolveHrefKeyElement(hrefKey);
@@ -21736,7 +22390,7 @@ function OhhwellsBridge() {
21736
22390
  );
21737
22391
  }
21738
22392
  }, [resolveHrefKeyElement]);
21739
- const reselectNavigationItem = useCallback10((navAnchor) => {
22393
+ const reselectNavigationItem = useCallback11((navAnchor) => {
21740
22394
  selectedElRef.current = navAnchor;
21741
22395
  selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
21742
22396
  selectedFooterColAttrRef.current = null;
@@ -21767,7 +22421,7 @@ function OhhwellsBridge() {
21767
22421
  setToolbarShowEditLink(false);
21768
22422
  setActiveCommands(/* @__PURE__ */ new Set());
21769
22423
  }, [markSelected]);
21770
- const commitNavigationTextEdit = useCallback10((navAnchor) => {
22424
+ const commitNavigationTextEdit = useCallback11((navAnchor) => {
21771
22425
  const el = activeElRef.current;
21772
22426
  if (!el) return;
21773
22427
  const key = el.dataset.ohwKey;
@@ -21800,7 +22454,7 @@ function OhhwellsBridge() {
21800
22454
  postToParent2({ type: "ow:exit-edit" });
21801
22455
  reselectNavigationItem(navAnchor);
21802
22456
  }, [postToParent2, reselectNavigationItem]);
21803
- const handleAddTopLevelNavItem = useCallback10(() => {
22457
+ const handleAddTopLevelNavItem = useCallback11(() => {
21804
22458
  const items = listNavbarRootItems();
21805
22459
  addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
21806
22460
  deselectRef.current();
@@ -21812,7 +22466,7 @@ function OhhwellsBridge() {
21812
22466
  intent: "add-nav"
21813
22467
  });
21814
22468
  }, []);
21815
- const maybeWarnNavLinkDropdownConflict = useCallback10(
22469
+ const maybeWarnNavLinkDropdownConflict = useCallback11(
21816
22470
  (anchor) => {
21817
22471
  if (!isNavbarHrefKey(anchor.getAttribute("data-ohw-href-key"))) return;
21818
22472
  if (!navDropdownsOpenOnClick()) return;
@@ -21825,7 +22479,7 @@ function OhhwellsBridge() {
21825
22479
  },
21826
22480
  [postToParent2]
21827
22481
  );
21828
- const handleNavDropdownOpenChange = useCallback10((open) => {
22482
+ const handleNavDropdownOpenChange = useCallback11((open) => {
21829
22483
  const selected = selectedElRef.current;
21830
22484
  if (!selected || !isNavigationItem2(selected)) return;
21831
22485
  if (isNestedNavChild(selected)) return;
@@ -21841,7 +22495,7 @@ function OhhwellsBridge() {
21841
22495
  }
21842
22496
  });
21843
22497
  }, []);
21844
- const handleFooterHeadingVisibleChange = useCallback10(
22498
+ const handleFooterHeadingVisibleChange = useCallback11(
21845
22499
  (visible) => {
21846
22500
  const selected = selectedElRef.current;
21847
22501
  if (!selected || !isFooterFrameSelectionRef.current) return;
@@ -21865,7 +22519,7 @@ function OhhwellsBridge() {
21865
22519
  },
21866
22520
  [postToParent2]
21867
22521
  );
21868
- const enterEditOnNewItem = useCallback10((anchor) => {
22522
+ const enterEditOnNewItem = useCallback11((anchor) => {
21869
22523
  const label = anchor.querySelector('[data-ohw-editable="text"]');
21870
22524
  if (!label) {
21871
22525
  selectRef.current(anchor);
@@ -21874,8 +22528,8 @@ function OhhwellsBridge() {
21874
22528
  setNavGroupForceOpen(anchor, true);
21875
22529
  activateRef.current(label);
21876
22530
  }, []);
21877
- const pendingSocialAddRef = useRef12(null);
21878
- const handleAddChildItem = useCallback10(() => {
22531
+ const pendingSocialAddRef = useRef13(null);
22532
+ const handleAddChildItem = useCallback11(() => {
21879
22533
  const selected = selectedElRef.current;
21880
22534
  if (!selected) return;
21881
22535
  const socialsRow = isSocialsRow(selected) ? selected : findSocialsRow(selected);
@@ -21986,7 +22640,7 @@ function OhhwellsBridge() {
21986
22640
  });
21987
22641
  });
21988
22642
  }, [enterEditOnNewItem, isFooterFrameSelection, maybeWarnNavLinkDropdownConflict, postToParent2]);
21989
- const handleAddFooterColumn = useCallback10(() => {
22643
+ const handleAddFooterColumn = useCallback11(() => {
21990
22644
  if (!canAddFooterColumn()) {
21991
22645
  postToParent2({
21992
22646
  type: "ow:toast",
@@ -22007,7 +22661,7 @@ function OhhwellsBridge() {
22007
22661
  selectRef.current(result.firstLink);
22008
22662
  });
22009
22663
  }, [postToParent2]);
22010
- const clearFooterDragVisuals = useCallback10(() => {
22664
+ const clearFooterDragVisuals = useCallback11(() => {
22011
22665
  footerDragRef.current = null;
22012
22666
  setSiblingHintRects([]);
22013
22667
  setFooterDropSlots([]);
@@ -22016,7 +22670,7 @@ function OhhwellsBridge() {
22016
22670
  setIsItemDragging(false);
22017
22671
  unlockFooterDragInteraction();
22018
22672
  }, []);
22019
- const refreshFooterDragVisuals = useCallback10((session, activeSlot, clientX, clientY) => {
22673
+ const refreshFooterDragVisuals = useCallback11((session, activeSlot, clientX, clientY) => {
22020
22674
  const dragged = session.draggedEl;
22021
22675
  setDraggedItemRect(dragged.getBoundingClientRect());
22022
22676
  if (typeof clientX === "number" && typeof clientY === "number") {
@@ -22048,13 +22702,13 @@ function OhhwellsBridge() {
22048
22702
  const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
22049
22703
  setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
22050
22704
  }, []);
22051
- const refreshFooterDragVisualsRef = useRef12(refreshFooterDragVisuals);
22705
+ const refreshFooterDragVisualsRef = useRef13(refreshFooterDragVisuals);
22052
22706
  refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
22053
- const commitFooterDragRef = useRef12(() => {
22707
+ const commitFooterDragRef = useRef13(() => {
22054
22708
  });
22055
- const beginFooterDragRef = useRef12(() => {
22709
+ const beginFooterDragRef = useRef13(() => {
22056
22710
  });
22057
- const beginFooterDrag = useCallback10(
22711
+ const beginFooterDrag = useCallback11(
22058
22712
  (session) => {
22059
22713
  const rect = session.draggedEl.getBoundingClientRect();
22060
22714
  session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
@@ -22074,7 +22728,7 @@ function OhhwellsBridge() {
22074
22728
  [refreshFooterDragVisuals]
22075
22729
  );
22076
22730
  beginFooterDragRef.current = beginFooterDrag;
22077
- const commitFooterDrag = useCallback10(
22731
+ const commitFooterDrag = useCallback11(
22078
22732
  (clientX, clientY) => {
22079
22733
  const session = footerDragRef.current;
22080
22734
  if (!session) {
@@ -22203,7 +22857,7 @@ function OhhwellsBridge() {
22203
22857
  [clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
22204
22858
  );
22205
22859
  commitFooterDragRef.current = commitFooterDrag;
22206
- const startFooterLinkDrag = useCallback10(
22860
+ const startFooterLinkDrag = useCallback11(
22207
22861
  (anchor, clientX, clientY, wasSelected) => {
22208
22862
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
22209
22863
  if (!hrefKey) return false;
@@ -22239,7 +22893,7 @@ function OhhwellsBridge() {
22239
22893
  },
22240
22894
  [beginFooterDrag]
22241
22895
  );
22242
- const startFooterColumnDrag = useCallback10(
22896
+ const startFooterColumnDrag = useCallback11(
22243
22897
  (columnEl, clientX, clientY, wasSelected) => {
22244
22898
  const columns = listFooterColumns();
22245
22899
  const idx = columns.indexOf(columnEl);
@@ -22259,7 +22913,7 @@ function OhhwellsBridge() {
22259
22913
  },
22260
22914
  [beginFooterDrag]
22261
22915
  );
22262
- const persistButtonCollectionDrag = useCallback10(
22916
+ const persistButtonCollectionDrag = useCallback11(
22263
22917
  (button, clientX) => {
22264
22918
  const insertIndex = buttonDropInsertIndexRef.current;
22265
22919
  if (insertIndex != null) insertButtonAtCollectionIndex(button, insertIndex);
@@ -22283,7 +22937,7 @@ function OhhwellsBridge() {
22283
22937
  },
22284
22938
  [postToParent2]
22285
22939
  );
22286
- const refreshButtonDragVisuals = useCallback10((button, clientX, clientY) => {
22940
+ const refreshButtonDragVisuals = useCallback11((button, clientX, clientY) => {
22287
22941
  const collection = buttonCollectionOf(button);
22288
22942
  if (!collection) {
22289
22943
  setButtonDropSlots([]);
@@ -22300,7 +22954,7 @@ function OhhwellsBridge() {
22300
22954
  setDraggedItemRect(button.getBoundingClientRect());
22301
22955
  if (selectedElRef.current === button) setToolbarRect(button.getBoundingClientRect());
22302
22956
  }, []);
22303
- const handleItemDragStart = useCallback10(
22957
+ const handleItemDragStart = useCallback11(
22304
22958
  (e) => {
22305
22959
  const selected = selectedElRef.current;
22306
22960
  if (!selected) {
@@ -22331,7 +22985,7 @@ function OhhwellsBridge() {
22331
22985
  },
22332
22986
  [startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag, refreshButtonDragVisuals]
22333
22987
  );
22334
- const handleItemDragEnd = useCallback10(
22988
+ const handleItemDragEnd = useCallback11(
22335
22989
  (e) => {
22336
22990
  const collectionButton = buttonCollectionDragRef.current;
22337
22991
  if (collectionButton) {
@@ -22362,7 +23016,7 @@ function OhhwellsBridge() {
22362
23016
  },
22363
23017
  [commitFooterDrag, commitNavDrag, navDragRef, persistButtonCollectionDrag]
22364
23018
  );
22365
- const handleItemChromePointerDown = useCallback10((e) => {
23019
+ const handleItemChromePointerDown = useCallback11((e) => {
22366
23020
  if (e.button !== 0) return;
22367
23021
  const selected = selectedElRef.current;
22368
23022
  if (!selected) return;
@@ -22403,7 +23057,7 @@ function OhhwellsBridge() {
22403
23057
  }
22404
23058
  if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
22405
23059
  }, [armNavPressFromChrome]);
22406
- const handleItemChromeClick = useCallback10((clientX, clientY) => {
23060
+ const handleItemChromeClick = useCallback11((clientX, clientY) => {
22407
23061
  if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
22408
23062
  suppressNextClickRef.current = false;
22409
23063
  return;
@@ -22416,7 +23070,7 @@ function OhhwellsBridge() {
22416
23070
  }, []);
22417
23071
  reselectNavigationItemRef.current = reselectNavigationItem;
22418
23072
  commitNavigationTextEditRef.current = commitNavigationTextEdit;
22419
- const select = useCallback10((anchor) => {
23073
+ const select = useCallback11((anchor) => {
22420
23074
  if (!isNavigationItem2(anchor)) return;
22421
23075
  if (activeElRef.current) deactivate();
22422
23076
  aiSectionApiRef.current?.selectFromElement(anchor);
@@ -22478,7 +23132,7 @@ function OhhwellsBridge() {
22478
23132
  setLogoSizeDraft(null);
22479
23133
  }
22480
23134
  }, [deactivate, markSelected]);
22481
- const selectFrame = useCallback10((el) => {
23135
+ const selectFrame = useCallback11((el) => {
22482
23136
  if (!isNavigationContainer(el)) return;
22483
23137
  if (activeElRef.current) deactivate();
22484
23138
  aiSectionApiRef.current?.selectFromElement(el);
@@ -22519,7 +23173,7 @@ function OhhwellsBridge() {
22519
23173
  setFloatingPanelPos(null);
22520
23174
  setLogoSizeDraft(null);
22521
23175
  }, [deactivate, markSelected, postToParent2]);
22522
- const selectLogo = useCallback10(
23176
+ const selectLogo = useCallback11(
22523
23177
  (logoEl) => {
22524
23178
  if (activeElRef.current) deactivate();
22525
23179
  selectedElRef.current = logoEl;
@@ -22548,7 +23202,7 @@ function OhhwellsBridge() {
22548
23202
  },
22549
23203
  [deactivate, markSelected]
22550
23204
  );
22551
- const openLogoSizePanel = useCallback10((logoEl) => {
23205
+ const openLogoSizePanel = useCallback11((logoEl) => {
22552
23206
  const placement = getLogoPlacement(logoEl);
22553
23207
  const draft = readLogoSizeState(editContentRef.current, placement);
22554
23208
  setLogoSizeDraft(draft);
@@ -22561,7 +23215,7 @@ function OhhwellsBridge() {
22561
23215
  placement
22562
23216
  });
22563
23217
  }, []);
22564
- const openSocialsDisplayPanel = useCallback10((row) => {
23218
+ const openSocialsDisplayPanel = useCallback11((row) => {
22565
23219
  setFloatingPanelPos(null);
22566
23220
  setParentScrollSnap(parentScrollRef.current);
22567
23221
  setFloatingPanel({
@@ -22572,7 +23226,7 @@ function OhhwellsBridge() {
22572
23226
  row
22573
23227
  });
22574
23228
  }, []);
22575
- const rememberButtonTokens = useCallback10(
23229
+ const rememberButtonTokens = useCallback11(
22576
23230
  (content, tokens, nodes) => {
22577
23231
  if (nodes.length === 0) return content;
22578
23232
  const next = { ...content };
@@ -22583,7 +23237,7 @@ function OhhwellsBridge() {
22583
23237
  },
22584
23238
  [postToParent2]
22585
23239
  );
22586
- const tokensForButton = useCallback10(
23240
+ const tokensForButton = useCallback11(
22587
23241
  (el, persistFallback = false) => {
22588
23242
  const stored = readStoredStyleTokens(editContentRef.current);
22589
23243
  if (stored) return stored;
@@ -22598,7 +23252,7 @@ function OhhwellsBridge() {
22598
23252
  },
22599
23253
  [rememberButtonTokens]
22600
23254
  );
22601
- const openButtonStylePanel = useCallback10(
23255
+ const openButtonStylePanel = useCallback11(
22602
23256
  (anchor) => {
22603
23257
  const id = buttonId(anchor);
22604
23258
  if (!id) return;
@@ -22616,7 +23270,7 @@ function OhhwellsBridge() {
22616
23270
  },
22617
23271
  [tokensForButton]
22618
23272
  );
22619
- const applySelectedButtonStyle = useCallback10(
23273
+ const applySelectedButtonStyle = useCallback11(
22620
23274
  (patch) => {
22621
23275
  const panel = floatingPanelRef.current;
22622
23276
  const id = panel?.kind === "button-style" ? panel.buttonId : null;
@@ -22634,7 +23288,7 @@ function OhhwellsBridge() {
22634
23288
  },
22635
23289
  [postToParent2]
22636
23290
  );
22637
- useEffect15(() => {
23291
+ useEffect16(() => {
22638
23292
  const onDragOver = (e) => {
22639
23293
  const dragged = buttonCollectionDragRef.current;
22640
23294
  if (!dragged) return;
@@ -22653,11 +23307,11 @@ function OhhwellsBridge() {
22653
23307
  document.removeEventListener("drop", onDrop);
22654
23308
  };
22655
23309
  }, [refreshButtonDragVisuals]);
22656
- const isEditModeRef = useRef12(false);
22657
- const requestMissingSocialIconsRef = useRef12(() => {
23310
+ const isEditModeRef = useRef13(false);
23311
+ const requestMissingSocialIconsRef = useRef13(() => {
22658
23312
  });
22659
- const askedSocialIconsRef = useRef12(/* @__PURE__ */ new Set());
22660
- const requestMissingSocialIcons = useCallback10(() => {
23313
+ const askedSocialIconsRef = useRef13(/* @__PURE__ */ new Set());
23314
+ const requestMissingSocialIcons = useCallback11(() => {
22661
23315
  const items = Array.from(document.querySelectorAll(`[${SOCIALS_ROW_ATTR}]`)).filter((row) => socialsDisplayFor(row, editContentRef.current).icon).flatMap((row) => {
22662
23316
  const missing = socialsMissingIcons(row);
22663
23317
  listSocialItems(row).forEach((item) => ensureIconSlot(item));
@@ -22669,7 +23323,7 @@ function OhhwellsBridge() {
22669
23323
  }, []);
22670
23324
  requestMissingSocialIconsRef.current = requestMissingSocialIcons;
22671
23325
  isEditModeRef.current = isEditMode;
22672
- const changeSocialsDisplay = useCallback10(
23326
+ const changeSocialsDisplay = useCallback11(
22673
23327
  (row, next) => {
22674
23328
  if (next.icon) {
22675
23329
  const missing = socialsMissingIcons(row);
@@ -22693,19 +23347,19 @@ function OhhwellsBridge() {
22693
23347
  },
22694
23348
  []
22695
23349
  );
22696
- const closeFloatingPanelOnly = useCallback10(() => {
23350
+ const closeFloatingPanelOnly = useCallback11(() => {
22697
23351
  setFloatingPanel(null);
22698
23352
  setFloatingPanelPos(null);
22699
23353
  setLogoSizeDraft(null);
22700
23354
  }, []);
22701
23355
  closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
22702
- const closeFloatingPanelAndDeselect = useCallback10(() => {
23356
+ const closeFloatingPanelAndDeselect = useCallback11(() => {
22703
23357
  setFloatingPanel(null);
22704
23358
  setFloatingPanelPos(null);
22705
23359
  setLogoSizeDraft(null);
22706
23360
  deselectRef.current();
22707
23361
  }, []);
22708
- useEffect15(() => {
23362
+ useEffect16(() => {
22709
23363
  const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
22710
23364
  if (!session || !logoSizeDraft) {
22711
23365
  postToParentRef.current({ type: "ow:logo-size-panel", open: false });
@@ -22724,7 +23378,7 @@ function OhhwellsBridge() {
22724
23378
  max: LOGO_SIZE_MAX
22725
23379
  });
22726
23380
  }, [floatingPanel, logoSizeDraft, editorViewport]);
22727
- const persistLogoSizeDraft = useCallback10(
23381
+ const persistLogoSizeDraft = useCallback11(
22728
23382
  (placement, draft) => {
22729
23383
  const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
22730
23384
  const mobileKey = LOGO_SIZE_MOBILE_KEYS[placement];
@@ -22764,7 +23418,7 @@ function OhhwellsBridge() {
22764
23418
  },
22765
23419
  [postToParent2]
22766
23420
  );
22767
- const activate = useCallback10((el, options) => {
23421
+ const activate = useCallback11((el, options) => {
22768
23422
  if (activeElRef.current === el) return;
22769
23423
  document.querySelectorAll("[data-ohw-hovered]").forEach((hovered) => {
22770
23424
  hovered.removeAttribute("data-ohw-hovered");
@@ -22862,8 +23516,8 @@ function OhhwellsBridge() {
22862
23516
  openLogoSizePanelRef.current = openLogoSizePanel;
22863
23517
  deselectRef.current = deselect;
22864
23518
  closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
22865
- const lastSiteWideScopeRef = useRef12(null);
22866
- useEffect15(() => {
23519
+ const lastSiteWideScopeRef = useRef13(null);
23520
+ useEffect16(() => {
22867
23521
  if (!isEditMode) {
22868
23522
  if (lastSiteWideScopeRef.current !== false) {
22869
23523
  lastSiteWideScopeRef.current = false;
@@ -22910,6 +23564,7 @@ function OhhwellsBridge() {
22910
23564
  }
22911
23565
  if (typeof content[STYLE_STORE_KEY] === "string") {
22912
23566
  stylesRef.current = content[STYLE_STORE_KEY];
23567
+ document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
22913
23568
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
22914
23569
  }
22915
23570
  applyBrandChrome(content);
@@ -22918,12 +23573,12 @@ function OhhwellsBridge() {
22918
23573
  for (const [key, val] of Object.entries(content)) {
22919
23574
  if (key === "__ohw_sections") continue;
22920
23575
  if (key === AI_SECTIONS_KEY) continue;
23576
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
23577
+ if (LOGO_IMAGE_KEYS.includes(key)) continue;
22921
23578
  if (key === BRAND_KIT_KEY) continue;
22922
23579
  if (key === STYLE_STORE_KEY) continue;
22923
23580
  if (BRAND_CHROME_KEYS.has(key)) continue;
22924
- if (key === LOGO_PLACEHOLDER_KEY) continue;
22925
23581
  if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
22926
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
22927
23582
  if (applyVideoSettingNode(key, val)) continue;
22928
23583
  if (applyCarouselNode(key, val)) continue;
22929
23584
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -22995,7 +23650,9 @@ function OhhwellsBridge() {
22995
23650
  let cancelled = false;
22996
23651
  setFetchState("loading");
22997
23652
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
22998
- fetch(`${apiUrl}/api/public/sites/${subdomain}/content`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
23653
+ const initialPath = pathname;
23654
+ fetchedContentPaths.add(`${subdomain}::${initialPath}`);
23655
+ fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
22999
23656
  if (cancelled) return;
23000
23657
  const content = data?.content ?? {};
23001
23658
  const branding = Boolean(data?.showBranding);
@@ -23011,7 +23668,7 @@ function OhhwellsBridge() {
23011
23668
  cancelled = true;
23012
23669
  };
23013
23670
  }, [subdomain, isEditMode]);
23014
- useEffect15(() => {
23671
+ useEffect16(() => {
23015
23672
  if (!isEditMode) return;
23016
23673
  const resolveIndex = (form, clientY) => {
23017
23674
  const wrappers = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== fieldDragRef.current?.key);
@@ -23052,7 +23709,7 @@ function OhhwellsBridge() {
23052
23709
  window.removeEventListener("drop", onDrop, true);
23053
23710
  };
23054
23711
  }, [buildFieldDropSlots, isEditMode, persistFields, selectField]);
23055
- useEffect15(() => {
23712
+ useEffect16(() => {
23056
23713
  if (!isEditMode) return;
23057
23714
  const mark = () => document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
23058
23715
  markFormFields(form);
@@ -23064,7 +23721,7 @@ function OhhwellsBridge() {
23064
23721
  });
23065
23722
  return () => observer.disconnect();
23066
23723
  }, [isEditMode, fetchState, pathname]);
23067
- useEffect15(() => {
23724
+ useEffect16(() => {
23068
23725
  if (!isEditMode) return;
23069
23726
  let saveTimer = null;
23070
23727
  const onInput = (e) => {
@@ -23086,14 +23743,14 @@ function OhhwellsBridge() {
23086
23743
  document.addEventListener("input", onInput, true);
23087
23744
  return () => document.removeEventListener("input", onInput, true);
23088
23745
  }, [isEditMode, persistFields]);
23089
- useEffect15(() => {
23746
+ useEffect16(() => {
23090
23747
  if (isEditMode || fetchState !== "done") return;
23091
23748
  const content = contentCache.get(subdomain) ?? {};
23092
23749
  document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
23093
23750
  reconcileFieldsFromContent(form, content);
23094
23751
  });
23095
23752
  }, [isEditMode, fetchState, subdomain]);
23096
- useEffect15(() => {
23753
+ useEffect16(() => {
23097
23754
  if (!isEditMode) return;
23098
23755
  const swallow = (e) => {
23099
23756
  const target = e.target;
@@ -23102,14 +23759,14 @@ function OhhwellsBridge() {
23102
23759
  document.addEventListener("submit", swallow, true);
23103
23760
  return () => document.removeEventListener("submit", swallow, true);
23104
23761
  }, [isEditMode]);
23105
- useEffect15(() => {
23762
+ useEffect16(() => {
23106
23763
  if (isEditMode || fetchState !== "done") return;
23107
23764
  console.log("env", process.env.NEXT_PUBLIC_FLOWOPS_API_URL);
23108
23765
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
23109
23766
  console.log({ apiUrl, subdomain });
23110
23767
  bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
23111
23768
  }, [isEditMode, fetchState, subdomain]);
23112
- useEffect15(() => {
23769
+ useEffect16(() => {
23113
23770
  if (!subdomain || isEditMode) return;
23114
23771
  let debounceTimer = null;
23115
23772
  let observer = null;
@@ -23131,16 +23788,17 @@ function OhhwellsBridge() {
23131
23788
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
23132
23789
  }
23133
23790
  if (typeof content[STYLE_STORE_KEY] === "string") {
23791
+ document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
23134
23792
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
23135
23793
  }
23136
23794
  for (const [key, val] of Object.entries(content)) {
23137
23795
  if (key === "__ohw_sections") continue;
23138
23796
  if (key === AI_SECTIONS_KEY) continue;
23797
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
23798
+ if (LOGO_IMAGE_KEYS.includes(key)) continue;
23139
23799
  if (key === BRAND_KIT_KEY) continue;
23140
23800
  if (key === STYLE_STORE_KEY) continue;
23141
23801
  if (BRAND_CHROME_KEYS.has(key)) continue;
23142
- if (key === LOGO_PLACEHOLDER_KEY) continue;
23143
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
23144
23802
  if (applyVideoSettingNode(key, val)) continue;
23145
23803
  if (applyCarouselNode(key, val)) continue;
23146
23804
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -23192,6 +23850,17 @@ function OhhwellsBridge() {
23192
23850
  debounceTimer = setTimeout(applyFromCache, 150);
23193
23851
  };
23194
23852
  applyFromCache();
23853
+ const pathCacheKey = `${subdomain}::${pathname}`;
23854
+ if (!fetchedContentPaths.has(pathCacheKey)) {
23855
+ fetchedContentPaths.add(pathCacheKey);
23856
+ const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
23857
+ fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
23858
+ if (!data?.content) return;
23859
+ contentCache.set(subdomain, data.content);
23860
+ applyFromCache();
23861
+ }).catch(() => {
23862
+ });
23863
+ }
23195
23864
  observer = new MutationObserver(scheduleApply);
23196
23865
  observer.observe(document.body, { childList: true, subtree: true });
23197
23866
  return () => {
@@ -23205,10 +23874,10 @@ function OhhwellsBridge() {
23205
23874
  const visible = Boolean(subdomain) && fetchState !== "done";
23206
23875
  el.style.display = visible ? "flex" : "none";
23207
23876
  }, [subdomain, fetchState]);
23208
- useEffect15(() => {
23877
+ useEffect16(() => {
23209
23878
  postToParent2({ type: "ow:navigation", path: pathname });
23210
23879
  }, [pathname, postToParent2]);
23211
- useEffect15(() => {
23880
+ useEffect16(() => {
23212
23881
  if (!subdomain || isEditMode) return;
23213
23882
  const content = contentCache.get(subdomain);
23214
23883
  if (!content) return;
@@ -23224,7 +23893,7 @@ function OhhwellsBridge() {
23224
23893
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
23225
23894
  }
23226
23895
  }, [pathname, subdomain, isEditMode]);
23227
- useEffect15(() => {
23896
+ useEffect16(() => {
23228
23897
  if (!isEditMode) return;
23229
23898
  if (linkPopoverSessionRef.current?.intent === "add-nav") return;
23230
23899
  if (document.querySelector("[data-ohw-section-picker]")) return;
@@ -23232,11 +23901,11 @@ function OhhwellsBridge() {
23232
23901
  deselectRef.current();
23233
23902
  deactivateRef.current();
23234
23903
  }, [pathname, isEditMode]);
23235
- useEffect15(() => {
23904
+ useEffect16(() => {
23236
23905
  if (!isEditMode) return;
23237
23906
  initSectionInstancesFromContent(editContentRef.current, pathname);
23238
23907
  }, [pathname, isEditMode]);
23239
- useEffect15(() => {
23908
+ useEffect16(() => {
23240
23909
  if (!isEditMode) return;
23241
23910
  const observer = new MutationObserver(() => {
23242
23911
  const drawer = document.querySelector("[data-ohw-nav-drawer]");
@@ -23247,7 +23916,7 @@ function OhhwellsBridge() {
23247
23916
  observer.observe(document.body, { childList: true, subtree: true });
23248
23917
  return () => observer.disconnect();
23249
23918
  }, [isEditMode, pathname]);
23250
- useEffect15(() => {
23919
+ useEffect16(() => {
23251
23920
  const contentForNav = () => {
23252
23921
  if (isEditMode) return editContentRef.current;
23253
23922
  if (!subdomain) return {};
@@ -23320,7 +23989,7 @@ function OhhwellsBridge() {
23320
23989
  observer?.disconnect();
23321
23990
  };
23322
23991
  }, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
23323
- useEffect15(() => {
23992
+ useEffect16(() => {
23324
23993
  if (!isEditMode) return;
23325
23994
  let applying = false;
23326
23995
  let rafId = null;
@@ -23358,7 +24027,7 @@ function OhhwellsBridge() {
23358
24027
  observer.disconnect();
23359
24028
  };
23360
24029
  }, [isEditMode, pathname]);
23361
- useEffect15(() => {
24030
+ useEffect16(() => {
23362
24031
  if (!isEditMode) return;
23363
24032
  let lastPosted = 0;
23364
24033
  const measure = () => {
@@ -23380,29 +24049,14 @@ function OhhwellsBridge() {
23380
24049
  const t2 = setTimeout(measure, 500);
23381
24050
  const ro = new ResizeObserver(schedule);
23382
24051
  ro.observe(document.body);
23383
- let lastWidth = window.innerWidth;
23384
- let resizeTimers = [];
23385
- const clearResizeTimers = () => {
23386
- resizeTimers.forEach(clearTimeout);
23387
- resizeTimers = [];
23388
- };
23389
- const handleResize = () => {
23390
- if (window.innerWidth === lastWidth) return;
23391
- lastWidth = window.innerWidth;
23392
- clearResizeTimers();
23393
- resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
23394
- };
23395
- window.addEventListener("resize", handleResize);
23396
24052
  return () => {
23397
24053
  clearTimeout(t1);
23398
24054
  clearTimeout(t2);
23399
24055
  if (raf != null) cancelAnimationFrame(raf);
23400
24056
  ro.disconnect();
23401
- clearResizeTimers();
23402
- window.removeEventListener("resize", handleResize);
23403
24057
  };
23404
24058
  }, [pathname, isEditMode, postToParent2]);
23405
- useEffect15(() => {
24059
+ useEffect16(() => {
23406
24060
  if (!subdomainFromQuery || isEditMode) return;
23407
24061
  const handleClick = (e) => {
23408
24062
  const anchor = e.target.closest("a");
@@ -23418,7 +24072,7 @@ function OhhwellsBridge() {
23418
24072
  document.addEventListener("click", handleClick, true);
23419
24073
  return () => document.removeEventListener("click", handleClick, true);
23420
24074
  }, [subdomainFromQuery, isEditMode, router]);
23421
- useEffect15(() => {
24075
+ useEffect16(() => {
23422
24076
  if (!isEditMode) {
23423
24077
  editStylesRef.current?.base.remove();
23424
24078
  editStylesRef.current?.forceHover.remove();
@@ -23644,11 +24298,11 @@ function OhhwellsBridge() {
23644
24298
  footer [data-ohw-href-key] [data-ohw-editable][contenteditable],
23645
24299
  footer [data-ohw-href-key] [data-ohw-editable][contenteditable] * {
23646
24300
  outline: none !important;
23647
- caret-color: ${PRIMARY5} !important;
24301
+ caret-color: ${PRIMARY6} !important;
23648
24302
  cursor: text !important;
23649
24303
  }
23650
24304
  [data-ohw-editable][contenteditable]::selection,
23651
- [data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY5}59 !important; }
24305
+ [data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY6}59 !important; }
23652
24306
  [data-ohw-editable-state], [data-ohw-editable-state] * { pointer-events: none !important; }
23653
24307
  [data-ohw-editable-state][data-ohw-active-state] [data-ohw-editable] { pointer-events: auto !important; }
23654
24308
  [data-ohw-editable-state][data-ohw-active-state][data-ohw-editable] { pointer-events: auto !important; }
@@ -23694,6 +24348,13 @@ function OhhwellsBridge() {
23694
24348
  if (target.closest("[data-ohw-state-toggle]")) return;
23695
24349
  if (target.closest("[data-ohw-max-badge]")) return;
23696
24350
  if (isInsideLinkEditor(target)) return;
24351
+ if (isInsideFloatingPanel(target)) return;
24352
+ if (target.closest("[data-ohw-form-toolbar]")) return;
24353
+ if (target.closest(
24354
+ '[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
24355
+ )) {
24356
+ return;
24357
+ }
23697
24358
  if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
23698
24359
  clearMediaSelectionRef.current();
23699
24360
  }
@@ -23714,13 +24375,6 @@ function OhhwellsBridge() {
23714
24375
  return;
23715
24376
  }
23716
24377
  }
23717
- if (isInsideFloatingPanel(target)) return;
23718
- if (target.closest("[data-ohw-form-toolbar]")) return;
23719
- if (target.closest(
23720
- '[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
23721
- )) {
23722
- return;
23723
- }
23724
24378
  {
23725
24379
  const formEl = getFormElement(target);
23726
24380
  const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
@@ -24100,6 +24754,9 @@ function OhhwellsBridge() {
24100
24754
  setHoveredItemRect(null);
24101
24755
  hoveredNavContainerRef.current = null;
24102
24756
  setHoveredNavContainerRect(null);
24757
+ siblingHintElRef.current = null;
24758
+ setSiblingHintRect(null);
24759
+ setSiblingHintRects([]);
24103
24760
  return;
24104
24761
  }
24105
24762
  {
@@ -24220,7 +24877,6 @@ function OhhwellsBridge() {
24220
24877
  hoveredNavContainerRef.current = null;
24221
24878
  setHoveredNavContainerRect(null);
24222
24879
  hoveredItemElRef.current = editable;
24223
- setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
24224
24880
  }
24225
24881
  }
24226
24882
  }
@@ -24930,7 +25586,11 @@ function OhhwellsBridge() {
24930
25586
  };
24931
25587
  const handleMouseMove = (e) => {
24932
25588
  const { clientX, clientY } = e;
24933
- if (pointOwnedByFloatingPanel(clientX, clientY)) return;
25589
+ if (pointOwnedByFloatingPanel(clientX, clientY)) {
25590
+ dismissImageHover();
25591
+ clearImageHover();
25592
+ return;
25593
+ }
24934
25594
  if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
24935
25595
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
24936
25596
  formHoverElRef.current = null;
@@ -24959,7 +25619,12 @@ function OhhwellsBridge() {
24959
25619
  setHoveredItemRect(null);
24960
25620
  hoveredNavContainerRef.current = null;
24961
25621
  setHoveredNavContainerRect(null);
25622
+ siblingHintElRef.current = null;
25623
+ setSiblingHintRect(null);
25624
+ setSiblingHintRects([]);
24962
25625
  dismissImageHover();
25626
+ clearImageHover();
25627
+ setSectionGap(null);
24963
25628
  return;
24964
25629
  }
24965
25630
  if (probeSocialsRowAt(clientX, clientY)) return;
@@ -24971,7 +25636,11 @@ function OhhwellsBridge() {
24971
25636
  if (e.data?.type !== "ow:pointer-sync") return;
24972
25637
  const { clientX, clientY } = e.data;
24973
25638
  if (typeof clientX !== "number" || typeof clientY !== "number") return;
24974
- if (pointOwnedByFloatingPanel(clientX, clientY)) return;
25639
+ if (pointOwnedByFloatingPanel(clientX, clientY)) {
25640
+ dismissImageHover();
25641
+ clearImageHover();
25642
+ return;
25643
+ }
24975
25644
  if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
24976
25645
  if (probeSocialsRowAt(clientX, clientY)) return;
24977
25646
  probeSectionGapAt(clientX, clientY);
@@ -25317,6 +25986,7 @@ function OhhwellsBridge() {
25317
25986
  }
25318
25987
  if (typeof content[STYLE_STORE_KEY] === "string") {
25319
25988
  stylesRef.current = content[STYLE_STORE_KEY];
25989
+ document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
25320
25990
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
25321
25991
  }
25322
25992
  applyBrandChrome(content);
@@ -25329,12 +25999,12 @@ function OhhwellsBridge() {
25329
25999
  continue;
25330
26000
  }
25331
26001
  if (key === AI_SECTIONS_KEY) continue;
26002
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
26003
+ if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
25332
26004
  if (key === BRAND_KIT_KEY) continue;
25333
26005
  if (key === STYLE_STORE_KEY) continue;
25334
26006
  if (BRAND_CHROME_KEYS.has(key)) continue;
25335
- if (key === LOGO_PLACEHOLDER_KEY) continue;
25336
26007
  if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
25337
- if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
25338
26008
  if (applyVideoSettingNode(key, val)) continue;
25339
26009
  if (applyCarouselNode(key, val)) continue;
25340
26010
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -25780,6 +26450,12 @@ function OhhwellsBridge() {
25780
26450
  closeLinkPopoverRef.current();
25781
26451
  return;
25782
26452
  }
26453
+ if (floatingPanelOpenRef.current) {
26454
+ setFloatingPanelRef.current(null);
26455
+ deselectRef.current();
26456
+ deactivateRef.current();
26457
+ return;
26458
+ }
25783
26459
  deselectRef.current();
25784
26460
  deactivateRef.current();
25785
26461
  clearMediaSelectionRef.current();
@@ -26056,6 +26732,21 @@ function OhhwellsBridge() {
26056
26732
  type: "text",
26057
26733
  text: editContentRef.current[CUSTOM_CODE_AFTER_HEAD_KEY] ?? ""
26058
26734
  });
26735
+ nodes.push({
26736
+ key: BRAND_TITLE_KEY,
26737
+ type: "text",
26738
+ text: editContentRef.current[BRAND_TITLE_KEY] ?? ""
26739
+ });
26740
+ nodes.push({
26741
+ key: SITE_DESCRIPTION_KEY,
26742
+ type: "text",
26743
+ text: editContentRef.current[SITE_DESCRIPTION_KEY] ?? ""
26744
+ });
26745
+ nodes.push({
26746
+ key: SITE_OG_IMAGE_KEY,
26747
+ type: "text",
26748
+ text: editContentRef.current[SITE_OG_IMAGE_KEY] ?? ""
26749
+ });
26059
26750
  document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
26060
26751
  const formKey = formKeyOf(form);
26061
26752
  if (!formKey) return;
@@ -26078,8 +26769,12 @@ function OhhwellsBridge() {
26078
26769
  if (inserted) {
26079
26770
  const tracker = getSectionsTracker();
26080
26771
  postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
26081
- const h = document.body.scrollHeight;
26082
- if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
26772
+ const reportHeight = () => {
26773
+ const h = document.body.scrollHeight;
26774
+ if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
26775
+ };
26776
+ reportHeight();
26777
+ setTimeout(reportHeight, 500);
26083
26778
  }
26084
26779
  };
26085
26780
  const handleSwitchSchedule = (e) => {
@@ -26508,17 +27203,17 @@ function OhhwellsBridge() {
26508
27203
  window.removeEventListener("message", handleDeleteSection);
26509
27204
  window.removeEventListener("message", handleDuplicateSection);
26510
27205
  window.removeEventListener("message", handleDeactivate);
26511
- document.documentElement.removeAttribute("data-ohw-panel-dragging");
26512
27206
  window.removeEventListener("message", handleToastAction);
26513
27207
  window.removeEventListener("message", handleFormCount);
26514
27208
  window.removeEventListener("message", handleUiEscape);
27209
+ document.documentElement.removeAttribute("data-ohw-panel-dragging");
26515
27210
  autoSaveTimers.current.forEach(clearTimeout);
26516
27211
  autoSaveTimers.current.clear();
26517
27212
  if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
26518
27213
  if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
26519
27214
  };
26520
27215
  }, [isEditMode, refreshStateRules]);
26521
- useEffect15(() => {
27216
+ useEffect16(() => {
26522
27217
  if (!isEditMode) return;
26523
27218
  const THRESHOLD = 10;
26524
27219
  const resolveWasSelected = (el) => {
@@ -26674,7 +27369,7 @@ function OhhwellsBridge() {
26674
27369
  unlockFooterDragInteraction();
26675
27370
  };
26676
27371
  }, [isEditMode]);
26677
- useEffect15(() => {
27372
+ useEffect16(() => {
26678
27373
  if (!isEditMode) return;
26679
27374
  const THRESHOLD = 10;
26680
27375
  const onPointerDown = (e) => {
@@ -26765,7 +27460,7 @@ function OhhwellsBridge() {
26765
27460
  document.removeEventListener("selectstart", blockSelectStart, true);
26766
27461
  };
26767
27462
  }, [isEditMode, persistButtonCollectionDrag, refreshButtonDragVisuals]);
26768
- useEffect15(() => {
27463
+ useEffect16(() => {
26769
27464
  const handler = (e) => {
26770
27465
  if (e.data?.type !== "ow:request-schedule-config") return;
26771
27466
  const insertAfterVal = e.data.insertAfter;
@@ -26781,7 +27476,7 @@ function OhhwellsBridge() {
26781
27476
  window.addEventListener("message", handler);
26782
27477
  return () => window.removeEventListener("message", handler);
26783
27478
  }, [processConfigRequest]);
26784
- useEffect15(() => {
27479
+ useEffect16(() => {
26785
27480
  if (!isEditMode) return;
26786
27481
  document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
26787
27482
  el.removeAttribute("data-ohw-active-state");
@@ -26805,7 +27500,7 @@ function OhhwellsBridge() {
26805
27500
  postToParent2({
26806
27501
  type: "ow:ready",
26807
27502
  version: "1",
26808
- bridgeVersion: "0.1.123",
27503
+ bridgeVersion: "0.1.126",
26809
27504
  path: pathname,
26810
27505
  nodes: collectEditableNodes(editContentRef.current),
26811
27506
  sections
@@ -26817,13 +27512,13 @@ function OhhwellsBridge() {
26817
27512
  clearTimeout(timer);
26818
27513
  };
26819
27514
  }, [pathname, isEditMode, refreshStateRules, postToParent2]);
26820
- useEffect15(() => {
27515
+ useEffect16(() => {
26821
27516
  scrollToHashSectionWhenReady();
26822
27517
  const onHashChange = () => scrollToHashSectionWhenReady();
26823
27518
  window.addEventListener("hashchange", onHashChange);
26824
27519
  return () => window.removeEventListener("hashchange", onHashChange);
26825
27520
  }, [pathname]);
26826
- const handleCommand = useCallback10((cmd) => {
27521
+ const handleCommand = useCallback11((cmd) => {
26827
27522
  const el = activeElRef.current;
26828
27523
  const selBefore = window.getSelection();
26829
27524
  let savedOffsets = null;
@@ -26859,7 +27554,7 @@ function OhhwellsBridge() {
26859
27554
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
26860
27555
  refreshActiveCommandsRef.current();
26861
27556
  }, []);
26862
- useEffect15(() => {
27557
+ useEffect16(() => {
26863
27558
  const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
26864
27559
  if (!session || !logoSizeDraft) return;
26865
27560
  const onPanelAction = (e) => {
@@ -26897,7 +27592,7 @@ function OhhwellsBridge() {
26897
27592
  window.addEventListener("message", onPanelAction);
26898
27593
  return () => window.removeEventListener("message", onPanelAction);
26899
27594
  }, [floatingPanel, logoSizeDraft, editorViewport, persistLogoSizeDraft, closeFloatingPanelAndDeselect]);
26900
- const handleStateChange = useCallback10((state) => {
27595
+ const handleStateChange = useCallback11((state) => {
26901
27596
  if (!activeStateElRef.current) return;
26902
27597
  const el = activeStateElRef.current;
26903
27598
  if (state === "Default") {
@@ -26910,7 +27605,7 @@ function OhhwellsBridge() {
26910
27605
  }
26911
27606
  setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
26912
27607
  }, [deactivate]);
26913
- const reselectAfterLinkPopover = useCallback10(
27608
+ const reselectAfterLinkPopover = useCallback11(
26914
27609
  (hrefKey) => {
26915
27610
  requestAnimationFrame(() => {
26916
27611
  const el = resolveHrefKeyElement(hrefKey);
@@ -26919,7 +27614,7 @@ function OhhwellsBridge() {
26919
27614
  },
26920
27615
  [resolveHrefKeyElement]
26921
27616
  );
26922
- const closeLinkPopover = useCallback10(() => {
27617
+ const closeLinkPopover = useCallback11(() => {
26923
27618
  const session = linkPopoverSessionRef.current;
26924
27619
  addNavAfterAnchorRef.current = null;
26925
27620
  setLinkPopover(null);
@@ -26927,9 +27622,9 @@ function OhhwellsBridge() {
26927
27622
  reselectAfterLinkPopover(session.key);
26928
27623
  }
26929
27624
  }, [reselectAfterLinkPopover]);
26930
- const closeLinkPopoverRef = useRef12(closeLinkPopover);
27625
+ const closeLinkPopoverRef = useRef13(closeLinkPopover);
26931
27626
  closeLinkPopoverRef.current = closeLinkPopover;
26932
- const openLinkPopoverForActive = useCallback10(() => {
27627
+ const openLinkPopoverForActive = useCallback11(() => {
26933
27628
  const hrefCtx = getHrefKeyFromElement(activeElRef.current);
26934
27629
  if (!hrefCtx) return;
26935
27630
  bumpLinkPopoverGrace();
@@ -26940,7 +27635,7 @@ function OhhwellsBridge() {
26940
27635
  });
26941
27636
  deactivate();
26942
27637
  }, [deactivate]);
26943
- const openLinkPopoverForSelected = useCallback10(() => {
27638
+ const openLinkPopoverForSelected = useCallback11(() => {
26944
27639
  const anchor = selectedElRef.current;
26945
27640
  if (!anchor) return;
26946
27641
  const key = anchor.getAttribute("data-ohw-href-key");
@@ -26957,7 +27652,7 @@ function OhhwellsBridge() {
26957
27652
  });
26958
27653
  deselect();
26959
27654
  }, [deselect]);
26960
- const handleSelectParent = useCallback10(() => {
27655
+ const handleSelectParent = useCallback11(() => {
26961
27656
  const selected = selectedElRef.current;
26962
27657
  if (!selected) return;
26963
27658
  if (toolbarVariantRef.current === "select-frame") {
@@ -26984,7 +27679,7 @@ function OhhwellsBridge() {
26984
27679
  }
26985
27680
  deselectRef.current();
26986
27681
  }, []);
26987
- const handleDuplicateSelected = useCallback10(() => {
27682
+ const handleDuplicateSelected = useCallback11(() => {
26988
27683
  const selected = selectedElRef.current;
26989
27684
  if (!selected || !isNavigationItem2(selected)) return;
26990
27685
  if (isCtaButton(selected)) {
@@ -27147,7 +27842,7 @@ function OhhwellsBridge() {
27147
27842
  });
27148
27843
  }
27149
27844
  }, [postToParent2, tokensForButton]);
27150
- const runPendingDeleteUndo = useCallback10(() => {
27845
+ const runPendingDeleteUndo = useCallback11(() => {
27151
27846
  const pending = pendingDeleteUndoRef.current;
27152
27847
  if (!pending) return false;
27153
27848
  pendingDeleteUndoRef.current = null;
@@ -27155,7 +27850,7 @@ function OhhwellsBridge() {
27155
27850
  enforceLinkHrefs();
27156
27851
  return true;
27157
27852
  }, []);
27158
- const handleDeleteSelected = useCallback10(() => {
27853
+ const handleDeleteSelected = useCallback11(() => {
27159
27854
  const selected = selectedElRef.current;
27160
27855
  if (!selected) return false;
27161
27856
  if (isCtaButton(selected)) {
@@ -27208,7 +27903,7 @@ function OhhwellsBridge() {
27208
27903
  }, [postToParent2]);
27209
27904
  handleDeleteSelectedRef.current = handleDeleteSelected;
27210
27905
  runPendingDeleteUndoRef.current = runPendingDeleteUndo;
27211
- const handleLinkPopoverSubmit = useCallback10(
27906
+ const handleLinkPopoverSubmit = useCallback11(
27212
27907
  (target) => {
27213
27908
  const session = linkPopoverSessionRef.current;
27214
27909
  if (!session) return;
@@ -27274,14 +27969,14 @@ function OhhwellsBridge() {
27274
27969
  const showEditLink = toolbarShowEditLink;
27275
27970
  const currentSections = sectionsByPath[pathname] ?? [];
27276
27971
  linkPopoverOpenRef.current = linkPopover !== null;
27277
- const handleMediaSelect = useCallback10((key) => {
27972
+ const handleMediaSelect = useCallback11((key) => {
27278
27973
  const el = hoveredImageRef.current?.dataset.ohwKey === key ? hoveredImageRef.current : Array.from(document.querySelectorAll(MEDIA_SELECTOR)).find(
27279
27974
  (m) => (m.dataset.ohwKey ?? "") === key
27280
27975
  ) ?? null;
27281
27976
  if (!el) return;
27282
27977
  selectMediaElementRef.current(el);
27283
27978
  }, []);
27284
- const handleMediaReplace = useCallback10(
27979
+ const handleMediaReplace = useCallback11(
27285
27980
  (key) => {
27286
27981
  postToParent2({
27287
27982
  type: "ow:image-pick",
@@ -27291,13 +27986,13 @@ function OhhwellsBridge() {
27291
27986
  },
27292
27987
  [postToParent2, mediaHover?.elementType, selectedMedia?.elementType]
27293
27988
  );
27294
- const handleEditCarousel = useCallback10(
27989
+ const handleEditCarousel = useCallback11(
27295
27990
  (key) => {
27296
27991
  postToParent2({ type: "ow:carousel-open", key, images: readCarouselValue(key) });
27297
27992
  },
27298
27993
  [postToParent2]
27299
27994
  );
27300
- const handleMediaFadeOutComplete = useCallback10((key) => {
27995
+ const handleMediaFadeOutComplete = useCallback11((key) => {
27301
27996
  setUploadingRects((prev) => {
27302
27997
  if (!(key in prev)) return prev;
27303
27998
  const next = { ...prev };
@@ -27305,7 +28000,7 @@ function OhhwellsBridge() {
27305
28000
  return next;
27306
28001
  });
27307
28002
  }, []);
27308
- const handleVideoSettingsChange = useCallback10(
28003
+ const handleVideoSettingsChange = useCallback11(
27309
28004
  (key, settings) => {
27310
28005
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
27311
28006
  const video = getVideoEl2(el);
@@ -27327,14 +28022,14 @@ function OhhwellsBridge() {
27327
28022
  },
27328
28023
  [postToParent2]
27329
28024
  );
27330
- return /* @__PURE__ */ jsxs23(Fragment10, { children: [
27331
- /* @__PURE__ */ jsx36("div", { id: "ohw-loader", suppressHydrationWarning: true, style: { ...OHW_LOADER_STYLE, display: "none" }, children: /* @__PURE__ */ jsx36(OhwLoaderSpinner, {}) }),
27332
- /* @__PURE__ */ jsx36("script", { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: OHW_LOADER_PREHYDRATE_SCRIPT } }),
27333
- subdomain && !isEditMode && showBranding && /* @__PURE__ */ jsx36(MadeWithOhhWells, {}),
28025
+ return /* @__PURE__ */ jsxs24(Fragment11, { children: [
28026
+ /* @__PURE__ */ jsx37("div", { id: "ohw-loader", suppressHydrationWarning: true, style: { ...OHW_LOADER_STYLE, display: "none" }, children: /* @__PURE__ */ jsx37(OhwLoaderSpinner, {}) }),
28027
+ /* @__PURE__ */ jsx37("script", { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: OHW_LOADER_PREHYDRATE_SCRIPT } }),
28028
+ subdomain && !isEditMode && showBranding && /* @__PURE__ */ jsx37(MadeWithOhhWells, {}),
27334
28029
  bridgeRoot ? createPortal3(
27335
- /* @__PURE__ */ jsxs23(Fragment10, { children: [
27336
- /* @__PURE__ */ jsx36("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
27337
- isEditMode && /* @__PURE__ */ jsx36(
28030
+ /* @__PURE__ */ jsxs24(Fragment11, { children: [
28031
+ /* @__PURE__ */ jsx37("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
28032
+ isEditMode && /* @__PURE__ */ jsx37(
27338
28033
  AiSectionOverlay,
27339
28034
  {
27340
28035
  postToParent: postToParent2,
@@ -27342,7 +28037,7 @@ function OhhwellsBridge() {
27342
28037
  onSelectionChange: handleAiSectionSelectionChange
27343
28038
  }
27344
28039
  ),
27345
- isEditMode && /* @__PURE__ */ jsx36(
28040
+ isEditMode && /* @__PURE__ */ jsx37(
27346
28041
  AiMediaStripOverlay,
27347
28042
  {
27348
28043
  postToParent: postToParent2,
@@ -27351,7 +28046,7 @@ function OhhwellsBridge() {
27351
28046
  clearInteractionChromeRef
27352
28047
  }
27353
28048
  ),
27354
- isEditMode && /* @__PURE__ */ jsx36(
28049
+ isEditMode && /* @__PURE__ */ jsx37(
27355
28050
  AiPricingCardOverlay,
27356
28051
  {
27357
28052
  postToParent: postToParent2,
@@ -27359,12 +28054,21 @@ function OhhwellsBridge() {
27359
28054
  applyTreeLocalRef
27360
28055
  }
27361
28056
  ),
27362
- isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
28057
+ isEditMode && /* @__PURE__ */ jsx37(
28058
+ AiVideoOverlay,
28059
+ {
28060
+ postToParent: postToParent2,
28061
+ aiSectionsRef,
28062
+ applyTreeLocalRef,
28063
+ clearInteractionChromeRef
28064
+ }
28065
+ ),
28066
+ isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ jsx37(
27363
28067
  "div",
27364
28068
  {
27365
28069
  className: "pointer-events-none fixed z-2147483646",
27366
28070
  style: { left: slot.left, top: slot.y, width: slot.width, height: 3, transform: "translateY(-50%)" },
27367
- children: /* @__PURE__ */ jsx36(
28071
+ children: /* @__PURE__ */ jsx37(
27368
28072
  DropIndicator,
27369
28073
  {
27370
28074
  direction: "horizontal",
@@ -27375,7 +28079,7 @@ function OhhwellsBridge() {
27375
28079
  },
27376
28080
  `section-drop-${slot.insertIndex}-${i}`
27377
28081
  )),
27378
- Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx36(
28082
+ Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx37(
27379
28083
  MediaOverlay,
27380
28084
  {
27381
28085
  hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
@@ -27386,7 +28090,7 @@ function OhhwellsBridge() {
27386
28090
  },
27387
28091
  `uploading-${key}`
27388
28092
  )),
27389
- mediaHover && !(mediaHover.key in uploadingRects) && mediaHover.key !== selectedMedia?.key && /* @__PURE__ */ jsx36(
28093
+ mediaHover && !(mediaHover.key in uploadingRects) && mediaHover.key !== selectedMedia?.key && /* @__PURE__ */ jsx37(
27390
28094
  MediaOverlay,
27391
28095
  {
27392
28096
  hover: mediaHover,
@@ -27397,7 +28101,7 @@ function OhhwellsBridge() {
27397
28101
  onVideoSettingsChange: handleVideoSettingsChange
27398
28102
  }
27399
28103
  ),
27400
- selectedMedia && !(selectedMedia.key in uploadingRects) && !linkPopover && /* @__PURE__ */ jsx36(
28104
+ selectedMedia && !(selectedMedia.key in uploadingRects) && !linkPopover && /* @__PURE__ */ jsx37(
27401
28105
  MediaOverlay,
27402
28106
  {
27403
28107
  hover: selectedMedia,
@@ -27409,7 +28113,7 @@ function OhhwellsBridge() {
27409
28113
  onVideoSettingsChange: handleVideoSettingsChange
27410
28114
  }
27411
28115
  ),
27412
- carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx36(
28116
+ carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx37(
27413
28117
  CarouselOverlay,
27414
28118
  {
27415
28119
  hover: carouselHover,
@@ -27417,10 +28121,10 @@ function OhhwellsBridge() {
27417
28121
  cueOnly: !!carouselHover.fullBleedSectionId && carouselHover.fullBleedSectionId !== selectedAiSectionId
27418
28122
  }
27419
28123
  ),
27420
- siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
27421
- siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
27422
- isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && selectedElRef.current !== buttonCollectionDragRef.current && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
27423
- isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
28124
+ siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx37(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
28125
+ siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx37(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
28126
+ isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && selectedElRef.current !== buttonCollectionDragRef.current && /* @__PURE__ */ jsx37(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
28127
+ isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx37(
27424
28128
  "div",
27425
28129
  {
27426
28130
  className: "pointer-events-none fixed z-2147483646",
@@ -27430,7 +28134,7 @@ function OhhwellsBridge() {
27430
28134
  width: slot.width,
27431
28135
  height: slot.height
27432
28136
  },
27433
- children: /* @__PURE__ */ jsx36(
28137
+ children: /* @__PURE__ */ jsx37(
27434
28138
  DropIndicator,
27435
28139
  {
27436
28140
  direction: slot.direction,
@@ -27441,7 +28145,7 @@ function OhhwellsBridge() {
27441
28145
  },
27442
28146
  `footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
27443
28147
  )),
27444
- isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
28148
+ isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx37(
27445
28149
  "div",
27446
28150
  {
27447
28151
  className: "pointer-events-none fixed z-2147483646",
@@ -27451,7 +28155,7 @@ function OhhwellsBridge() {
27451
28155
  width: slot.width,
27452
28156
  height: slot.height
27453
28157
  },
27454
- children: /* @__PURE__ */ jsx36(
28158
+ children: /* @__PURE__ */ jsx37(
27455
28159
  DropIndicator,
27456
28160
  {
27457
28161
  direction: slot.direction,
@@ -27462,7 +28166,7 @@ function OhhwellsBridge() {
27462
28166
  },
27463
28167
  `nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
27464
28168
  )),
27465
- isItemDragging && buttonDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
28169
+ isItemDragging && buttonDropSlots.map((slot, i) => /* @__PURE__ */ jsx37(
27466
28170
  "div",
27467
28171
  {
27468
28172
  className: "pointer-events-none fixed z-2147483646",
@@ -27472,7 +28176,7 @@ function OhhwellsBridge() {
27472
28176
  width: slot.width,
27473
28177
  height: slot.height
27474
28178
  },
27475
- children: /* @__PURE__ */ jsx36(
28179
+ children: /* @__PURE__ */ jsx37(
27476
28180
  DropIndicator,
27477
28181
  {
27478
28182
  direction: slot.direction,
@@ -27483,10 +28187,10 @@ function OhhwellsBridge() {
27483
28187
  },
27484
28188
  `button-drop-${slot.direction}-${slot.insertIndex}-${i}`
27485
28189
  )),
27486
- hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
27487
- hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
27488
- hoveredTextRect && !hoveredNavContainerRect && !hoveredItemRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx36(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
27489
- formPickRect && !isItemDragging && /* @__PURE__ */ jsx36(
28190
+ hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx37(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
28191
+ hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx37(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
28192
+ hoveredTextRect && !hoveredNavContainerRect && !hoveredItemRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx37(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
28193
+ formPickRect && !isItemDragging && /* @__PURE__ */ jsx37(
27490
28194
  ItemInteractionLayer,
27491
28195
  {
27492
28196
  rect: formPickRect,
@@ -27494,13 +28198,13 @@ function OhhwellsBridge() {
27494
28198
  itemDragSurface: false,
27495
28199
  toolbarAlign: "left",
27496
28200
  chromeGap: 24,
27497
- toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ jsxs23(
28201
+ toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ jsxs24(
27498
28202
  "div",
27499
28203
  {
27500
28204
  "data-ohw-form-toolbar": "",
27501
28205
  className: "pointer-events-auto flex items-center gap-0.5 whitespace-nowrap rounded-lg border border-border bg-background p-1 shadow-md",
27502
28206
  children: [
27503
- /* @__PURE__ */ jsx36(
28207
+ /* @__PURE__ */ jsx37(
27504
28208
  "button",
27505
28209
  {
27506
28210
  type: "button",
@@ -27508,11 +28212,11 @@ function OhhwellsBridge() {
27508
28212
  className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
27509
28213
  onClick: () => setFieldTypePickerOpen((open) => !open),
27510
28214
  "data-ohw-add-field": "",
27511
- children: /* @__PURE__ */ jsx36(Plus4, { size: 15, "aria-hidden": true })
28215
+ children: /* @__PURE__ */ jsx37(Plus4, { size: 15, "aria-hidden": true })
27512
28216
  }
27513
28217
  ),
27514
- /* @__PURE__ */ jsx36("div", { className: "mx-0.5 h-5 w-px bg-border" }),
27515
- /* @__PURE__ */ jsxs23(
28218
+ /* @__PURE__ */ jsx37("div", { className: "mx-0.5 h-5 w-px bg-border" }),
28219
+ /* @__PURE__ */ jsxs24(
27516
28220
  "button",
27517
28221
  {
27518
28222
  type: "button",
@@ -27528,11 +28232,11 @@ function OhhwellsBridge() {
27528
28232
  });
27529
28233
  },
27530
28234
  children: [
27531
- /* @__PURE__ */ jsx36(Settings, { size: 14, "aria-hidden": true }),
28235
+ /* @__PURE__ */ jsx37(Settings, { size: 14, "aria-hidden": true }),
27532
28236
  "Form settings",
27533
28237
  formPickCount ? (
27534
28238
  // Counter pill, per the design — not a text suffix.
27535
- /* @__PURE__ */ jsx36(
28239
+ /* @__PURE__ */ jsx37(
27536
28240
  "span",
27537
28241
  {
27538
28242
  "data-ohw-form-count": "",
@@ -27544,8 +28248,8 @@ function OhhwellsBridge() {
27544
28248
  ]
27545
28249
  }
27546
28250
  ),
27547
- /* @__PURE__ */ jsx36("div", { className: "mx-0.5 h-5 w-px bg-border" }),
27548
- /* @__PURE__ */ jsx36("div", { className: "flex items-center rounded-md bg-muted/70 p-0.5", children: ["default", "success"].map((state) => /* @__PURE__ */ jsx36(
28251
+ /* @__PURE__ */ jsx37("div", { className: "mx-0.5 h-5 w-px bg-border" }),
28252
+ /* @__PURE__ */ jsx37("div", { className: "flex items-center rounded-md bg-muted/70 p-0.5", children: ["default", "success"].map((state) => /* @__PURE__ */ jsx37(
27549
28253
  "button",
27550
28254
  {
27551
28255
  type: "button",
@@ -27576,7 +28280,7 @@ function OhhwellsBridge() {
27576
28280
  )
27577
28281
  }
27578
28282
  ),
27579
- formHoverRect && !isItemDragging && /* @__PURE__ */ jsx36(
28283
+ formHoverRect && !isItemDragging && /* @__PURE__ */ jsx37(
27580
28284
  ItemInteractionLayer,
27581
28285
  {
27582
28286
  rect: formHoverRect,
@@ -27584,7 +28288,7 @@ function OhhwellsBridge() {
27584
28288
  chromeGap: formHoverElRef.current && getFieldWrapper(formHoverElRef.current) ? 8 : 24
27585
28289
  }
27586
28290
  ),
27587
- fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx36(
28291
+ fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx37(
27588
28292
  ItemInteractionLayer,
27589
28293
  {
27590
28294
  rect: fieldPickRect,
@@ -27596,7 +28300,7 @@ function OhhwellsBridge() {
27596
28300
  dragHandleLabel: "Reorder field",
27597
28301
  onDragHandleDragStart: handleFieldDragStart,
27598
28302
  onDragHandleDragEnd: handleFieldDragEnd,
27599
- toolbar: /* @__PURE__ */ jsx36(
28303
+ toolbar: /* @__PURE__ */ jsx37(
27600
28304
  FormFieldToolbar,
27601
28305
  {
27602
28306
  type: fieldPickState.type,
@@ -27609,12 +28313,12 @@ function OhhwellsBridge() {
27609
28313
  )
27610
28314
  }
27611
28315
  ),
27612
- fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */ jsx36(
28316
+ fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */ jsx37(
27613
28317
  "div",
27614
28318
  {
27615
28319
  className: "pointer-events-none fixed z-[2147483644]",
27616
28320
  style: { top: slot.top, left: slot.left, width: slot.width },
27617
- children: /* @__PURE__ */ jsx36(
28321
+ children: /* @__PURE__ */ jsx37(
27618
28322
  DropIndicator,
27619
28323
  {
27620
28324
  direction: "horizontal",
@@ -27627,7 +28331,7 @@ function OhhwellsBridge() {
27627
28331
  )) : null,
27628
28332
  fieldTypePickerOpen && formPickRect ? (() => {
27629
28333
  const toolbar = document.querySelector("[data-ohw-form-toolbar]")?.getBoundingClientRect();
27630
- return /* @__PURE__ */ jsx36(
28334
+ return /* @__PURE__ */ jsx37(
27631
28335
  "div",
27632
28336
  {
27633
28337
  className: "pointer-events-none fixed z-[2147483645]",
@@ -27635,12 +28339,12 @@ function OhhwellsBridge() {
27635
28339
  top: toolbar ? toolbar.bottom + 6 : formPickRect.top + 16,
27636
28340
  left: toolbar ? toolbar.left : formPickRect.left + 24
27637
28341
  },
27638
- children: /* @__PURE__ */ jsx36(FieldTypePicker, { onPick: handleAddField })
28342
+ children: /* @__PURE__ */ jsx37(FieldTypePicker, { onPick: handleAddField })
27639
28343
  }
27640
28344
  );
27641
28345
  })() : null,
27642
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx36(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
27643
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx36(
28346
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx37(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
28347
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx37(
27644
28348
  FooterContainerChrome,
27645
28349
  {
27646
28350
  rect: toolbarRect,
@@ -27648,7 +28352,7 @@ function OhhwellsBridge() {
27648
28352
  addDisabled: !canAddFooterColumn()
27649
28353
  }
27650
28354
  ),
27651
- toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ jsx36(
28355
+ toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ jsx37(
27652
28356
  ItemInteractionLayer,
27653
28357
  {
27654
28358
  rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected || selectedElRef.current === buttonCollectionDragRef.current) ? draggedItemRect : toolbarRect,
@@ -27668,7 +28372,7 @@ function OhhwellsBridge() {
27668
28372
  onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
27669
28373
  onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
27670
28374
  itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection && !selectedIsSocialsRow,
27671
- toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ jsx36(
28375
+ toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ jsx37(
27672
28376
  ItemActionToolbar,
27673
28377
  {
27674
28378
  onEditLink: openLinkPopoverForSelected,
@@ -27719,8 +28423,8 @@ function OhhwellsBridge() {
27719
28423
  ) : void 0
27720
28424
  }
27721
28425
  ),
27722
- toolbarRect && toolbarVariant === "rich-text" && !linkPopover && !isRectOutsideClip(toolbarRect, getIframeVisibleClip(parentScrollRef.current)) && /* @__PURE__ */ jsxs23(Fragment10, { children: [
27723
- /* @__PURE__ */ jsx36(
28426
+ toolbarRect && toolbarVariant === "rich-text" && !linkPopover && !isRectOutsideClip(toolbarRect, getIframeVisibleClip(parentScrollRef.current)) && /* @__PURE__ */ jsxs24(Fragment11, { children: [
28427
+ /* @__PURE__ */ jsx37(
27724
28428
  EditGlowChrome,
27725
28429
  {
27726
28430
  rect: toolbarRect,
@@ -27730,7 +28434,7 @@ function OhhwellsBridge() {
27730
28434
  hideHandle: isItemDragging
27731
28435
  }
27732
28436
  ),
27733
- /* @__PURE__ */ jsx36(
28437
+ /* @__PURE__ */ jsx37(
27734
28438
  FloatingToolbar,
27735
28439
  {
27736
28440
  rect: toolbarRect,
@@ -27743,7 +28447,7 @@ function OhhwellsBridge() {
27743
28447
  }
27744
28448
  )
27745
28449
  ] }),
27746
- maxBadge && /* @__PURE__ */ jsxs23(
28450
+ maxBadge && /* @__PURE__ */ jsxs24(
27747
28451
  "div",
27748
28452
  {
27749
28453
  "data-ohw-max-badge": "",
@@ -27769,7 +28473,7 @@ function OhhwellsBridge() {
27769
28473
  ]
27770
28474
  }
27771
28475
  ),
27772
- toggleState && !linkPopover && /* @__PURE__ */ jsx36(
28476
+ toggleState && !linkPopover && /* @__PURE__ */ jsx37(
27773
28477
  StateToggle,
27774
28478
  {
27775
28479
  rect: toggleState.rect,
@@ -27778,15 +28482,15 @@ function OhhwellsBridge() {
27778
28482
  onStateChange: handleStateChange
27779
28483
  }
27780
28484
  ),
27781
- sectionGap && !linkPopover && /* @__PURE__ */ jsxs23(
28485
+ sectionGap && !linkPopover && /* @__PURE__ */ jsxs24(
27782
28486
  "div",
27783
28487
  {
27784
28488
  "data-ohw-section-insert-line": "",
27785
28489
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
27786
28490
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
27787
28491
  children: [
27788
- /* @__PURE__ */ jsx36("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
27789
- /* @__PURE__ */ jsx36(
28492
+ /* @__PURE__ */ jsx37("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
28493
+ /* @__PURE__ */ jsx37(
27790
28494
  Badge,
27791
28495
  {
27792
28496
  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",
@@ -27803,11 +28507,11 @@ function OhhwellsBridge() {
27803
28507
  children: "Add Section"
27804
28508
  }
27805
28509
  ),
27806
- /* @__PURE__ */ jsx36("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
28510
+ /* @__PURE__ */ jsx37("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
27807
28511
  ]
27808
28512
  }
27809
28513
  ),
27810
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx36(
28514
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx37(
27811
28515
  LinkPopover,
27812
28516
  {
27813
28517
  panelRef: linkPopoverPanelRef,
@@ -27824,7 +28528,7 @@ function OhhwellsBridge() {
27824
28528
  },
27825
28529
  linkPopover.key
27826
28530
  ) : null,
27827
- floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx36(
28531
+ floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx37(
27828
28532
  FloatingPanel,
27829
28533
  {
27830
28534
  open: true,
@@ -27834,7 +28538,7 @@ function OhhwellsBridge() {
27834
28538
  onPositionChange: setFloatingPanelPos,
27835
28539
  parentScroll: parentScrollSnap ?? parentScrollRef.current,
27836
28540
  onClose: closeFloatingPanelOnly,
27837
- children: /* @__PURE__ */ jsx36(
28541
+ children: /* @__PURE__ */ jsx37(
27838
28542
  SocialsDisplayPanel,
27839
28543
  {
27840
28544
  display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
@@ -27855,19 +28559,19 @@ function OhhwellsBridge() {
27855
28559
  const tokens = tokensFromButton(button);
27856
28560
  const current = assignmentFor(button, editContentRef.current, tokens);
27857
28561
  void buttonStyleTick;
27858
- return /* @__PURE__ */ jsx36(
28562
+ return /* @__PURE__ */ jsx37(
27859
28563
  FloatingPanel,
27860
28564
  {
27861
28565
  open: true,
27862
28566
  title: floatingPanel.title,
27863
28567
  context: floatingPanel.context,
27864
- icon: /* @__PURE__ */ jsx36(Brush2, { className: "size-4 shrink-0", "aria-hidden": true }),
28568
+ icon: /* @__PURE__ */ jsx37(Brush2, { className: "size-4 shrink-0", "aria-hidden": true }),
27865
28569
  position: floatingPanelPos,
27866
28570
  onPositionChange: setFloatingPanelPos,
27867
28571
  parentScroll: parentScrollSnap ?? parentScrollRef.current,
27868
28572
  onClose: closeFloatingPanelOnly,
27869
28573
  bodyClassName: "gap-5",
27870
- children: /* @__PURE__ */ jsx36(
28574
+ children: /* @__PURE__ */ jsx37(
27871
28575
  ButtonStylePanel,
27872
28576
  {
27873
28577
  variants: tokens.variants,
@@ -27892,6 +28596,59 @@ function OhhwellsBridge() {
27892
28596
  ) : null
27893
28597
  ] });
27894
28598
  }
28599
+
28600
+ // src/ui/EmptySection.tsx
28601
+ import Link3 from "next/link";
28602
+ import { Fragment as Fragment12, jsx as jsx38, jsxs as jsxs25 } from "react/jsx-runtime";
28603
+ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
28604
+ return /* @__PURE__ */ jsxs25(Fragment12, { children: [
28605
+ /* @__PURE__ */ jsx38(
28606
+ "p",
28607
+ {
28608
+ style: {
28609
+ fontFamily: "var(--brand-font-body)",
28610
+ fontSize: "0.75rem",
28611
+ fontWeight: 500,
28612
+ letterSpacing: "0.15em",
28613
+ textTransform: "uppercase",
28614
+ color: "var(--brand-accent)",
28615
+ marginBottom: "1.5rem"
28616
+ },
28617
+ children: /* @__PURE__ */ jsx38(Link3, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ jsx38("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
28618
+ }
28619
+ ),
28620
+ /* @__PURE__ */ jsx38(
28621
+ "h1",
28622
+ {
28623
+ style: {
28624
+ fontFamily: "var(--brand-font-heading)",
28625
+ fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
28626
+ lineHeight: 1.1,
28627
+ letterSpacing: "-0.025em",
28628
+ color: "var(--brand-text)",
28629
+ marginBottom: "1rem"
28630
+ },
28631
+ ...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
28632
+ children: title
28633
+ }
28634
+ ),
28635
+ /* @__PURE__ */ jsx38(
28636
+ "p",
28637
+ {
28638
+ style: {
28639
+ fontFamily: "var(--brand-font-body)",
28640
+ fontSize: "1rem",
28641
+ lineHeight: 1.7,
28642
+ fontWeight: 300,
28643
+ color: "var(--brand-text-muted)",
28644
+ maxWidth: "340px"
28645
+ },
28646
+ ...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
28647
+ children: "This page doesn't have any content yet."
28648
+ }
28649
+ )
28650
+ ] });
28651
+ }
27895
28652
  export {
27896
28653
  AI_DEFAULT_BRAND,
27897
28654
  AI_TREE_SCHEMA_VERSIONS,
@@ -27908,6 +28665,7 @@ export {
27908
28665
  DropdownMenuItem,
27909
28666
  DropdownMenuSeparator,
27910
28667
  DropdownMenuTrigger,
28668
+ EmptySection,
27911
28669
  ItemActionToolbar,
27912
28670
  ItemInteractionLayer,
27913
28671
  LinkEditorPanel,