@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.cjs CHANGED
@@ -46,6 +46,7 @@ __export(index_exports, {
46
46
  DropdownMenuItem: () => DropdownMenuItem,
47
47
  DropdownMenuSeparator: () => DropdownMenuSeparator,
48
48
  DropdownMenuTrigger: () => DropdownMenuTrigger,
49
+ EmptySection: () => EmptySection,
49
50
  ItemActionToolbar: () => ItemActionToolbar,
50
51
  ItemInteractionLayer: () => ItemInteractionLayer,
51
52
  LinkEditorPanel: () => LinkEditorPanel,
@@ -74,7 +75,7 @@ __export(index_exports, {
74
75
  module.exports = __toCommonJS(index_exports);
75
76
 
76
77
  // src/OhhwellsBridge.tsx
77
- var import_react19 = __toESM(require("react"), 1);
78
+ var import_react20 = __toESM(require("react"), 1);
78
79
  var import_client2 = require("react-dom/client");
79
80
  var import_react_dom4 = require("react-dom");
80
81
 
@@ -295,10 +296,14 @@ function reapRemovedAiSections(state, store, removedIds, excludeIds = /* @__PURE
295
296
  var BRAND_NAME_KEY = "__ohw_brand_name";
296
297
  var BRAND_TITLE_KEY = "__ohw_site_title";
297
298
  var BRAND_FAVICON_LETTER_KEY = "__ohw_favicon_letter";
299
+ var SITE_DESCRIPTION_KEY = "__ohw_site_description";
300
+ var SITE_OG_IMAGE_KEY = "__ohw_og_image";
298
301
  var BRAND_CHROME_KEYS = /* @__PURE__ */ new Set([
299
302
  BRAND_NAME_KEY,
300
303
  BRAND_TITLE_KEY,
301
- BRAND_FAVICON_LETTER_KEY
304
+ BRAND_FAVICON_LETTER_KEY,
305
+ SITE_DESCRIPTION_KEY,
306
+ SITE_OG_IMAGE_KEY
302
307
  ]);
303
308
  function upsertMeta(selector, attr, token, value) {
304
309
  let el = document.head.querySelector(selector);
@@ -309,6 +314,9 @@ function upsertMeta(selector, attr, token, value) {
309
314
  }
310
315
  if (el.getAttribute("content") !== value) el.setAttribute("content", value);
311
316
  }
317
+ function removeMeta(selector) {
318
+ document.head.querySelector(selector)?.remove();
319
+ }
312
320
  function escapeXml(value) {
313
321
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
314
322
  }
@@ -324,6 +332,22 @@ function applyLetterFavicon(letter) {
324
332
  link.type = "image/svg+xml";
325
333
  if (link.href !== href) link.href = href;
326
334
  }
335
+ function applyDescription(description) {
336
+ if (!description) return;
337
+ upsertMeta('meta[name="description"]', "name", "description", description);
338
+ upsertMeta('meta[property="og:description"]', "property", "og:description", description);
339
+ upsertMeta('meta[name="twitter:description"]', "name", "twitter:description", description);
340
+ }
341
+ function applyOgImage(url) {
342
+ if (url) {
343
+ upsertMeta('meta[property="og:image"]', "property", "og:image", url);
344
+ upsertMeta('meta[name="twitter:image"]', "name", "twitter:image", url);
345
+ upsertMeta('meta[name="twitter:card"]', "name", "twitter:card", "summary_large_image");
346
+ return;
347
+ }
348
+ removeMeta('meta[property="og:image"]');
349
+ removeMeta('meta[name="twitter:image"]');
350
+ }
327
351
  function applyBrandChrome(content) {
328
352
  const name = content[BRAND_NAME_KEY];
329
353
  if (typeof name === "string" && name.length > 0) {
@@ -342,6 +366,13 @@ function applyBrandChrome(content) {
342
366
  if (typeof letter === "string" && letter.length > 0) {
343
367
  applyLetterFavicon(letter);
344
368
  }
369
+ const description = content[SITE_DESCRIPTION_KEY];
370
+ if (typeof description === "string" && description.length > 0) {
371
+ applyDescription(description);
372
+ }
373
+ if (Object.prototype.hasOwnProperty.call(content, SITE_OG_IMAGE_KEY)) {
374
+ applyOgImage(String(content[SITE_OG_IMAGE_KEY] ?? "").trim());
375
+ }
345
376
  }
346
377
 
347
378
  // src/lib/brand-kit.ts
@@ -1752,6 +1783,22 @@ function pricingCardEmphasis(featured, ctx, hasBg) {
1752
1783
  function textAttrs(ctx, path) {
1753
1784
  return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
1754
1785
  }
1786
+ var AI_RESPONSIVE_CSS = [
1787
+ "@media (max-width: 960px) {",
1788
+ " [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
1789
+ ' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
1790
+ "}",
1791
+ "@media (max-width: 640px) {",
1792
+ " [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
1793
+ " [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
1794
+ // Group containers flatten to a column on phones; span placements come along for free.
1795
+ " [data-ai-responsive] [data-ai-group] { display: flex !important; flex-direction: column !important; }",
1796
+ " [data-ai-responsive] [data-ai-group] > * { grid-column: auto !important; }",
1797
+ " [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
1798
+ " [data-ai-responsive] { overflow-x: hidden; }",
1799
+ " [data-ai-responsive] img { max-width: 100%; }",
1800
+ "}"
1801
+ ].join("\n");
1755
1802
  var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
1756
1803
  function MediaBox({
1757
1804
  refValue,
@@ -1769,9 +1816,9 @@ function MediaBox({
1769
1816
  const url = refValue ? ctx.resolveMedia(refValue) : null;
1770
1817
  const isIcon = /^(lucide|simple):/.test(refValue);
1771
1818
  const aspectRatio = aspect && /^\d+:\d+$/.test(aspect) ? aspect.replace(":", " / ") : void 0;
1772
- const editAttrs = ctx.keyFor && editPath && !isIcon ? {
1819
+ const editAttrs = ctx.keyFor && editPath ? {
1773
1820
  "data-ohw-key": ctx.keyFor(editPath),
1774
- ...genericImageEdit ? { "data-ohw-editable": "image" } : {}
1821
+ ...isIcon ? { "data-ohw-editable": "icon" } : genericImageEdit ? { "data-ohw-editable": "image" } : {}
1775
1822
  } : {};
1776
1823
  if (isIcon) {
1777
1824
  const Icon = refValue.startsWith("lucide:") ? lucideByName(refValue.slice(7)) : null;
@@ -1779,6 +1826,7 @@ function MediaBox({
1779
1826
  "span",
1780
1827
  {
1781
1828
  "data-ai-icon": refValue,
1829
+ ...editAttrs,
1782
1830
  style: {
1783
1831
  display: "inline-flex",
1784
1832
  width: 48,
@@ -1830,6 +1878,117 @@ function MediaBox({
1830
1878
  }
1831
1879
  );
1832
1880
  }
1881
+ function VideoEmbed({ slots, ctx, path }) {
1882
+ const [playing, setPlaying] = import_react.default.useState(false);
1883
+ const videoId = str(slots.videoId);
1884
+ const caption = str(slots.caption);
1885
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: AI_TREE_TOKENS.spacing3 }, children: [
1886
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1887
+ "div",
1888
+ {
1889
+ "data-ohw-video-block": "",
1890
+ "data-ohw-video-path": path,
1891
+ style: {
1892
+ position: "relative",
1893
+ width: "100%",
1894
+ aspectRatio: "16 / 9",
1895
+ // Floor so YouTube's own control chrome (volume tooltip, CC, related-videos
1896
+ // overlay) has enough room on narrow mobile widths — 16:9 alone can shrink
1897
+ // below what that fixed-size chrome needs and it starts clipping.
1898
+ minHeight: 250,
1899
+ borderRadius: AI_TREE_TOKENS.radiusCard,
1900
+ overflow: "hidden",
1901
+ background: "#DBEAFE"
1902
+ },
1903
+ children: !videoId ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1904
+ "div",
1905
+ {
1906
+ style: {
1907
+ position: "absolute",
1908
+ inset: 0,
1909
+ display: "flex",
1910
+ alignItems: "center",
1911
+ justifyContent: "center",
1912
+ color: "#93C5FD",
1913
+ fontSize: 13
1914
+ },
1915
+ children: "video"
1916
+ }
1917
+ ) : playing ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1918
+ "iframe",
1919
+ {
1920
+ src: `https://www.youtube-nocookie.com/embed/${videoId}?autoplay=1&mute=1&rel=0`,
1921
+ title: caption || "YouTube video",
1922
+ style: { position: "absolute", inset: 0, width: "100%", height: "100%", border: 0 },
1923
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture",
1924
+ allowFullScreen: true,
1925
+ sandbox: "allow-scripts allow-same-origin allow-presentation allow-popups allow-popups-to-escape-sandbox",
1926
+ loading: "lazy"
1927
+ }
1928
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1929
+ "button",
1930
+ {
1931
+ type: "button",
1932
+ onClick: () => setPlaying(true),
1933
+ "aria-label": "Play video",
1934
+ style: {
1935
+ position: "absolute",
1936
+ inset: 0,
1937
+ width: "100%",
1938
+ height: "100%",
1939
+ border: 0,
1940
+ padding: 0,
1941
+ margin: 0,
1942
+ cursor: "pointer",
1943
+ background: "none"
1944
+ },
1945
+ children: [
1946
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1947
+ "img",
1948
+ {
1949
+ src: `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`,
1950
+ alt: "",
1951
+ style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
1952
+ }
1953
+ ),
1954
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1955
+ "span",
1956
+ {
1957
+ style: {
1958
+ position: "absolute",
1959
+ top: "50%",
1960
+ left: "50%",
1961
+ transform: "translate(-50%, -50%)",
1962
+ width: 64,
1963
+ height: 64,
1964
+ borderRadius: "50%",
1965
+ background: "rgba(0,0,0,0.65)",
1966
+ display: "flex",
1967
+ alignItems: "center",
1968
+ justifyContent: "center"
1969
+ },
1970
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Play, { size: 28, color: "#fff", fill: "#fff" })
1971
+ }
1972
+ )
1973
+ ]
1974
+ }
1975
+ )
1976
+ }
1977
+ ),
1978
+ caption && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1979
+ "div",
1980
+ {
1981
+ ...textAttrs(ctx, `${path}.caption`),
1982
+ style: {
1983
+ ...typeStyle(AI_TREE_TOKENS.type.bodyM, ctx.brand.fonts.body),
1984
+ color: ctx.brand.palette.dark,
1985
+ textAlign: "center"
1986
+ },
1987
+ children: caption
1988
+ }
1989
+ )
1990
+ ] });
1991
+ }
1833
1992
  function ButtonEl({
1834
1993
  slots,
1835
1994
  ctx,
@@ -2837,7 +2996,7 @@ function CollectionBlock({ node, ctx, path }) {
2837
2996
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2838
2997
  "div",
2839
2998
  {
2840
- "data-ai-grid": "",
2999
+ "data-ai-grid": String(itemsPerRow),
2841
3000
  "data-ohw-pricing-collection": isPricing ? "" : void 0,
2842
3001
  style: {
2843
3002
  display: "grid",
@@ -2910,6 +3069,8 @@ function renderNode(node, ctx, path) {
2910
3069
  editPath: `${path}.source`
2911
3070
  }
2912
3071
  );
3072
+ case "video":
3073
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VideoEmbed, { slots, ctx, path });
2913
3074
  case "media-list": {
2914
3075
  const stacked = slots.layout === "stack";
2915
3076
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", gap: stacked ? 0 : AI_TREE_TOKENS.spacing3 }, children: (node.children ?? []).map((child, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -3196,6 +3357,7 @@ function AiTreeRenderer({
3196
3357
  {
3197
3358
  "data-ai-section": tree.tag ?? "",
3198
3359
  ...bgAttrs,
3360
+ "data-ai-responsive": "",
3199
3361
  style: {
3200
3362
  position: "relative",
3201
3363
  padding: `${pad}px 0`,
@@ -3206,12 +3368,13 @@ function AiTreeRenderer({
3206
3368
  color: settings.sectionBackground === "accent" ? blockBrand.palette.dark : void 0
3207
3369
  },
3208
3370
  children: [
3209
- isOverlay && backgroundUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
3371
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
3210
3372
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
3373
+ isOverlay && backgroundUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
3211
3374
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3212
3375
  "div",
3213
3376
  {
3214
- "data-ai-container": "",
3377
+ "data-ai-section-inner": "",
3215
3378
  style: {
3216
3379
  position: "relative",
3217
3380
  maxWidth: AI_TREE_TOKENS.sectionMaxWidth,
@@ -3222,7 +3385,7 @@ function AiTreeRenderer({
3222
3385
  children: tree.rows.map((row, r2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3223
3386
  "div",
3224
3387
  {
3225
- "data-ai-row": "",
3388
+ "data-ai-columns": "",
3226
3389
  style: {
3227
3390
  display: "grid",
3228
3391
  gridTemplateColumns: "repeat(12, 1fr)",
@@ -3626,9 +3789,10 @@ function applyAiSectionsToDom(state, options) {
3626
3789
  if (existing && existing.serialized === serialized && existing.container.isConnected) {
3627
3790
  continue;
3628
3791
  }
3629
- const isNewMount = !existing || !existing.container.isConnected;
3630
3792
  let container = existing?.container;
3793
+ let isNewMount = false;
3631
3794
  if (!container || !container.isConnected) {
3795
+ isNewMount = true;
3632
3796
  existing?.root.unmount();
3633
3797
  container?.remove();
3634
3798
  container = document.createElement("div");
@@ -9523,6 +9687,7 @@ function MediaOverlay({
9523
9687
  (prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
9524
9688
  );
9525
9689
  }, [isVideo]);
9690
+ const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
9526
9691
  const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
9527
9692
  const box = {
9528
9693
  position: "fixed",
@@ -9621,11 +9786,10 @@ function MediaOverlay({
9621
9786
  className: "flex items-center justify-center cursor-pointer",
9622
9787
  style: {
9623
9788
  ...box,
9624
- // When text overlays this media, let clicks fall THROUGH to the text underneath. In the
9625
- // parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
9626
- // in-document, pointer-events does it natively. The button below opts back in, so
9627
- // Replace still works.
9628
- pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
9789
+ // Visual only. `pointer-events: auto` on this full-bleed rect covered the navbar
9790
+ // (hero bg includes the absolute TopNav) and swallowed CTA press-drag. Text overlay
9791
+ // and cueOnly also need clicks to fall through — Replace / video controls opt back in.
9792
+ pointerEvents: "none",
9629
9793
  // Selected: a firm component ring with no wash, so the image reads as chosen rather
9630
9794
  // than hovered. Hover keeps the existing tinted preview.
9631
9795
  boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
@@ -9652,17 +9816,17 @@ function MediaOverlay({
9652
9816
  },
9653
9817
  children: [
9654
9818
  isVideo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
9655
- isVideo ? "Replace video" : "Replace image"
9819
+ replaceLabel
9656
9820
  ]
9657
9821
  }
9658
9822
  ),
9659
- replaceMode === "none" || cueOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9823
+ showChrome && replaceMode !== "none" && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9660
9824
  Button,
9661
9825
  {
9662
9826
  "data-ohw-media-overlay": "",
9663
9827
  variant: "outline",
9664
9828
  size: "sm",
9665
- "aria-label": isVideo ? "Replace video" : "Replace image",
9829
+ "aria-label": replaceLabel,
9666
9830
  className: "gap-1.5 cursor-pointer hover:bg-background",
9667
9831
  style: {
9668
9832
  ...OVERLAY_BUTTON_STYLE,
@@ -9685,7 +9849,7 @@ function MediaOverlay({
9685
9849
  },
9686
9850
  children: [
9687
9851
  isVideo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
9688
- replaceMode === "full" ? isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image" : null
9852
+ replaceMode === "full" ? replaceLabel : null
9689
9853
  ]
9690
9854
  }
9691
9855
  )
@@ -11459,6 +11623,486 @@ function AiPricingCardOverlay({
11459
11623
  ] });
11460
11624
  }
11461
11625
 
11626
+ // src/ui/ai-section/AiVideoOverlay.tsx
11627
+ var import_react11 = require("react");
11628
+ var import_lucide_react10 = require("lucide-react");
11629
+
11630
+ // src/lib/ai-video-tree.ts
11631
+ function resolveVideoBlock(tree, path) {
11632
+ const segments = path.split(".");
11633
+ const rowSeg = segments[0];
11634
+ const blockSeg = segments[1];
11635
+ if (!rowSeg?.startsWith("r") || !blockSeg?.startsWith("b")) return null;
11636
+ let node = tree.rows[Number(rowSeg.slice(1))]?.blocks[Number(blockSeg.slice(1))];
11637
+ for (const seg of segments.slice(2)) {
11638
+ if (!node || !seg.startsWith("c")) return null;
11639
+ node = node.children?.[Number(seg.slice(1))];
11640
+ }
11641
+ return node && node.type === "video" ? node : null;
11642
+ }
11643
+ function withVideo(tree, path, mutate) {
11644
+ const next = JSON.parse(JSON.stringify(tree));
11645
+ const block = resolveVideoBlock(next, path);
11646
+ if (!block) return null;
11647
+ block.slots = block.slots ?? {};
11648
+ return mutate(block) ? next : null;
11649
+ }
11650
+ function videoIdAt(tree, path) {
11651
+ const block = resolveVideoBlock(tree, path);
11652
+ const id = block?.slots?.videoId;
11653
+ return typeof id === "string" ? id : "";
11654
+ }
11655
+ function setVideoId(tree, path, videoId) {
11656
+ return withVideo(tree, path, (block) => {
11657
+ block.slots = { ...block.slots, videoId };
11658
+ return true;
11659
+ });
11660
+ }
11661
+ function clearVideo(tree, path) {
11662
+ return withVideo(tree, path, (block) => {
11663
+ const slots = { ...block.slots };
11664
+ delete slots.videoId;
11665
+ block.slots = slots;
11666
+ return true;
11667
+ });
11668
+ }
11669
+
11670
+ // src/lib/youtube.ts
11671
+ var YOUTUBE_ID_PATTERN = /^[A-Za-z0-9_-]{11}$/;
11672
+ function extractYouTubeId(input) {
11673
+ const trimmed = input.trim();
11674
+ if (!trimmed) return null;
11675
+ if (YOUTUBE_ID_PATTERN.test(trimmed)) return trimmed;
11676
+ let url;
11677
+ try {
11678
+ url = new URL(trimmed);
11679
+ } catch {
11680
+ return null;
11681
+ }
11682
+ const host = url.hostname.replace(/^www\./, "");
11683
+ if (host !== "youtube.com" && host !== "m.youtube.com" && host !== "youtu.be" && host !== "youtube-nocookie.com") {
11684
+ return null;
11685
+ }
11686
+ let candidate = null;
11687
+ if (host === "youtu.be") {
11688
+ candidate = url.pathname.slice(1).split("/")[0] ?? null;
11689
+ } else if (url.pathname === "/watch") {
11690
+ candidate = url.searchParams.get("v");
11691
+ } else {
11692
+ const match = url.pathname.match(/^\/(?:embed|shorts)\/([^/]+)/);
11693
+ candidate = match ? match[1] : null;
11694
+ }
11695
+ return candidate && YOUTUBE_ID_PATTERN.test(candidate) ? candidate : null;
11696
+ }
11697
+
11698
+ // src/ui/ai-section/AiVideoOverlay.tsx
11699
+ var import_jsx_runtime20 = require("react/jsx-runtime");
11700
+ var PRIMARY5 = "#0885FE";
11701
+ var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY5})`;
11702
+ var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
11703
+ function findVideoBlockElement(sectionId, path) {
11704
+ const sectionEl = findByInstanceId(sectionId);
11705
+ if (!sectionEl) return null;
11706
+ const items = sectionEl.querySelectorAll("[data-ohw-video-block]");
11707
+ for (const el of Array.from(items)) {
11708
+ if (el.dataset.ohwVideoPath === path) return el;
11709
+ }
11710
+ return null;
11711
+ }
11712
+ function readRect4(ref) {
11713
+ const el = ref && findVideoBlockElement(ref.sectionId, ref.path);
11714
+ if (!el) return null;
11715
+ const r2 = el.getBoundingClientRect();
11716
+ if (r2.width <= 0 || r2.height <= 0) return null;
11717
+ return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
11718
+ }
11719
+ function useLiveBlockRect(ref) {
11720
+ const [rect, setRect] = (0, import_react11.useState)(null);
11721
+ (0, import_react11.useEffect)(() => {
11722
+ if (!ref) {
11723
+ setRect(null);
11724
+ return;
11725
+ }
11726
+ const update = () => {
11727
+ const next = readRect4(ref);
11728
+ setRect(
11729
+ (prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
11730
+ );
11731
+ };
11732
+ update();
11733
+ const opts = { capture: true, passive: true };
11734
+ window.addEventListener("scroll", update, opts);
11735
+ window.addEventListener("resize", update);
11736
+ const interval = setInterval(update, 500);
11737
+ return () => {
11738
+ window.removeEventListener("scroll", update, opts);
11739
+ window.removeEventListener("resize", update);
11740
+ clearInterval(interval);
11741
+ };
11742
+ }, [ref?.sectionId, ref?.path]);
11743
+ return rect;
11744
+ }
11745
+ function requestValidateTree3(postToParent2, tree) {
11746
+ return new Promise((resolve) => {
11747
+ const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
11748
+ const timeout = window.setTimeout(() => {
11749
+ window.removeEventListener("message", onMessage);
11750
+ resolve({ ok: false, reasons: ["Validation request timed out."] });
11751
+ }, 8e3);
11752
+ function onMessage(e) {
11753
+ if (e.data?.type !== "ow:ai-validate-tree-result" || e.data.id !== id) return;
11754
+ window.clearTimeout(timeout);
11755
+ window.removeEventListener("message", onMessage);
11756
+ resolve({ ok: e.data.ok === true, reasons: Array.isArray(e.data.reasons) ? e.data.reasons : [] });
11757
+ }
11758
+ window.addEventListener("message", onMessage);
11759
+ postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
11760
+ });
11761
+ }
11762
+ function Pill3({
11763
+ label,
11764
+ onClick,
11765
+ disabled
11766
+ }) {
11767
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11768
+ "button",
11769
+ {
11770
+ type: "button",
11771
+ onClick,
11772
+ disabled,
11773
+ style: {
11774
+ height: 28,
11775
+ padding: "0 10px",
11776
+ display: "inline-flex",
11777
+ alignItems: "center",
11778
+ gap: 4,
11779
+ borderRadius: 999,
11780
+ border: "none",
11781
+ cursor: disabled ? "default" : "pointer",
11782
+ background: "#ffffff",
11783
+ color: OHW_BLUE_DARK3,
11784
+ opacity: disabled ? 0.4 : 1,
11785
+ fontSize: 12,
11786
+ lineHeight: "16px",
11787
+ fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
11788
+ whiteSpace: "nowrap",
11789
+ flex: "0 0 auto"
11790
+ },
11791
+ children: label
11792
+ }
11793
+ );
11794
+ }
11795
+ function watchUrl(id) {
11796
+ return `https://www.youtube.com/watch?v=${id}`;
11797
+ }
11798
+ function VideoUrlInput({ value, onCommit }) {
11799
+ const [draft, setDraft] = (0, import_react11.useState)(value ? watchUrl(value) : "");
11800
+ const [invalid, setInvalid] = (0, import_react11.useState)(false);
11801
+ (0, import_react11.useEffect)(() => {
11802
+ setDraft(value ? watchUrl(value) : "");
11803
+ setInvalid(false);
11804
+ }, [value]);
11805
+ const commit = () => {
11806
+ const next = draft.trim();
11807
+ if (!next) {
11808
+ setInvalid(false);
11809
+ if (value) onCommit(null);
11810
+ return;
11811
+ }
11812
+ const id = extractYouTubeId(next);
11813
+ if (!id) return setInvalid(true);
11814
+ setInvalid(false);
11815
+ setDraft(watchUrl(id));
11816
+ if (id !== value) onCommit(id);
11817
+ };
11818
+ const handleChange = (next) => {
11819
+ setDraft(next);
11820
+ const id = extractYouTubeId(next.trim());
11821
+ if (id && id !== value) {
11822
+ setInvalid(false);
11823
+ onCommit(id);
11824
+ }
11825
+ };
11826
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 4, width: "100%", maxWidth: 280 }, children: [
11827
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11828
+ "div",
11829
+ {
11830
+ style: {
11831
+ display: "flex",
11832
+ alignItems: "center",
11833
+ gap: 6,
11834
+ height: 28,
11835
+ padding: "0 12px",
11836
+ borderRadius: 999,
11837
+ background: "#ffffff",
11838
+ width: "100%",
11839
+ boxSizing: "border-box",
11840
+ boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
11841
+ },
11842
+ children: [
11843
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11844
+ "span",
11845
+ {
11846
+ style: {
11847
+ flex: "0 0 auto",
11848
+ color: OHW_BLUE_DARK3,
11849
+ fontSize: 10,
11850
+ lineHeight: "16px",
11851
+ fontWeight: 700,
11852
+ textTransform: "uppercase",
11853
+ letterSpacing: 0.4
11854
+ },
11855
+ children: "Video"
11856
+ }
11857
+ ),
11858
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11859
+ "input",
11860
+ {
11861
+ type: "text",
11862
+ inputMode: "url",
11863
+ value: draft,
11864
+ onChange: (e) => handleChange(e.target.value),
11865
+ onBlur: commit,
11866
+ onKeyDown: (e) => {
11867
+ if (e.key === "Enter") e.currentTarget.blur();
11868
+ if (e.key === "Escape") {
11869
+ setDraft(value ? watchUrl(value) : "");
11870
+ setInvalid(false);
11871
+ e.currentTarget.blur();
11872
+ }
11873
+ },
11874
+ placeholder: "Paste a YouTube URL",
11875
+ "aria-label": "YouTube video URL",
11876
+ "aria-invalid": invalid,
11877
+ style: {
11878
+ flex: 1,
11879
+ minWidth: 0,
11880
+ border: "none",
11881
+ outline: "none",
11882
+ background: "transparent",
11883
+ padding: 0,
11884
+ margin: 0,
11885
+ fontSize: 12,
11886
+ lineHeight: "16px",
11887
+ fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
11888
+ color: "#1f2937"
11889
+ }
11890
+ }
11891
+ )
11892
+ ]
11893
+ }
11894
+ ),
11895
+ invalid && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, textAlign: "center" }, children: "That doesn't look like a YouTube link \u2014 try pasting the video URL again." })
11896
+ ] });
11897
+ }
11898
+ function VideoToolbar({
11899
+ videoId,
11900
+ pending,
11901
+ error,
11902
+ onSetVideoId,
11903
+ onRemove
11904
+ }) {
11905
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11906
+ "div",
11907
+ {
11908
+ "data-ohw-bridge": "",
11909
+ "data-ohw-toolbar": "",
11910
+ onMouseDown: (e) => e.stopPropagation(),
11911
+ style: {
11912
+ display: "flex",
11913
+ flexDirection: "column",
11914
+ gap: 6,
11915
+ alignItems: "center",
11916
+ width: 280,
11917
+ background: OHW_BLUE3,
11918
+ padding: 8,
11919
+ borderRadius: 12,
11920
+ boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
11921
+ pointerEvents: pending ? "none" : "auto",
11922
+ opacity: pending ? 0.6 : 1
11923
+ },
11924
+ children: [
11925
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
11926
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill3, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
11927
+ error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
11928
+ ]
11929
+ }
11930
+ );
11931
+ }
11932
+ function AiVideoOverlay({
11933
+ postToParent: postToParent2,
11934
+ aiSectionsRef,
11935
+ applyTreeLocalRef,
11936
+ clearInteractionChromeRef
11937
+ }) {
11938
+ const [hover, setHover] = (0, import_react11.useState)(null);
11939
+ const [active, setActive] = (0, import_react11.useState)(null);
11940
+ const [pending, setPending] = (0, import_react11.useState)(false);
11941
+ const [error, setError] = (0, import_react11.useState)(null);
11942
+ const activeRef = (0, import_react11.useRef)(null);
11943
+ activeRef.current = active;
11944
+ (0, import_react11.useEffect)(() => {
11945
+ const onMove = (e) => {
11946
+ const t = e.target;
11947
+ if (!(t instanceof HTMLElement)) return;
11948
+ 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]")) {
11949
+ return;
11950
+ }
11951
+ const blockEl = t.closest("[data-ohw-video-block]");
11952
+ if (!blockEl) {
11953
+ setHover(null);
11954
+ return;
11955
+ }
11956
+ const sectionEl = blockEl.closest("[data-ohw-section]");
11957
+ const unit = sectionEl ? movableUnit(sectionEl) : null;
11958
+ const sectionId = unit ? instanceIdOf(unit) || null : null;
11959
+ const path = blockEl.dataset.ohwVideoPath;
11960
+ if (!sectionId || !path) {
11961
+ setHover(null);
11962
+ return;
11963
+ }
11964
+ setHover({ sectionId, path });
11965
+ };
11966
+ const onLeave = () => setHover(null);
11967
+ document.addEventListener("mousemove", onMove, { passive: true });
11968
+ document.documentElement.addEventListener("mouseleave", onLeave);
11969
+ return () => {
11970
+ document.removeEventListener("mousemove", onMove);
11971
+ document.documentElement.removeEventListener("mouseleave", onLeave);
11972
+ };
11973
+ }, []);
11974
+ (0, import_react11.useEffect)(() => {
11975
+ const onClick = (e) => {
11976
+ const current = activeRef.current;
11977
+ if (!current) return;
11978
+ const t = e.target;
11979
+ if (!(t instanceof HTMLElement)) return;
11980
+ if (t.closest("[data-ohw-item-interaction]")) return;
11981
+ const blockEl = findVideoBlockElement(current.sectionId, current.path);
11982
+ if (blockEl && blockEl.contains(t)) return;
11983
+ setActive(null);
11984
+ setError(null);
11985
+ };
11986
+ document.addEventListener("click", onClick, true);
11987
+ return () => document.removeEventListener("click", onClick, true);
11988
+ }, []);
11989
+ (0, import_react11.useEffect)(() => {
11990
+ const onBlur = () => {
11991
+ if (!activeRef.current) return;
11992
+ setActive(null);
11993
+ setError(null);
11994
+ };
11995
+ window.addEventListener("blur", onBlur);
11996
+ return () => window.removeEventListener("blur", onBlur);
11997
+ }, []);
11998
+ (0, import_react11.useEffect)(() => {
11999
+ const onKeyDown = (e) => {
12000
+ if (e.key !== "Escape") return;
12001
+ if (!activeRef.current) return;
12002
+ setActive(null);
12003
+ setError(null);
12004
+ };
12005
+ document.addEventListener("keydown", onKeyDown);
12006
+ return () => document.removeEventListener("keydown", onKeyDown);
12007
+ }, []);
12008
+ const findEntry = (0, import_react11.useCallback)(
12009
+ (sectionId) => {
12010
+ const state = parseAiSectionsState(aiSectionsRef.current);
12011
+ return state.sections.find((s) => s.id === sectionId) ?? null;
12012
+ },
12013
+ [aiSectionsRef]
12014
+ );
12015
+ const runMutation = (0, import_react11.useCallback)(
12016
+ async (sectionId, mutate) => {
12017
+ const entry = findEntry(sectionId);
12018
+ if (!entry) return false;
12019
+ const nextTree = mutate(entry.tree);
12020
+ if (!nextTree) return false;
12021
+ setPending(true);
12022
+ setError(null);
12023
+ const { ok, reasons } = await requestValidateTree3(postToParent2, nextTree);
12024
+ setPending(false);
12025
+ if (!ok) {
12026
+ setError(reasons[0] ?? "That change is not allowed.");
12027
+ return false;
12028
+ }
12029
+ applyTreeLocalRef.current?.({
12030
+ id: sectionId,
12031
+ mode: "replace",
12032
+ targetSectionId: sectionId,
12033
+ tree: nextTree,
12034
+ label: entry.label,
12035
+ media: entry.media,
12036
+ ...entry.brand ? { brand: entry.brand } : {}
12037
+ });
12038
+ return true;
12039
+ },
12040
+ [findEntry, postToParent2, applyTreeLocalRef]
12041
+ );
12042
+ const activeEntry = active ? findEntry(active.sectionId) : null;
12043
+ const hoverHandleRect = useLiveBlockRect(!active && hover ? hover : null);
12044
+ const activeBlockRect = useLiveBlockRect(active);
12045
+ const TOOLBAR_APPROX_H = 90;
12046
+ const toolbarState = activeBlockRect && activeBlockRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
12047
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
12048
+ hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12049
+ "button",
12050
+ {
12051
+ type: "button",
12052
+ "data-ohw-toolbar": "",
12053
+ onClick: () => {
12054
+ clearInteractionChromeRef.current();
12055
+ setActive(hover);
12056
+ },
12057
+ "aria-label": "Configure video",
12058
+ style: {
12059
+ position: "fixed",
12060
+ top: hoverHandleRect.top + 8,
12061
+ left: hoverHandleRect.left + hoverHandleRect.width - 36,
12062
+ width: 28,
12063
+ height: 28,
12064
+ borderRadius: 8,
12065
+ border: `1.5px dashed ${PRIMARY5}`,
12066
+ background: "#ffffff",
12067
+ color: PRIMARY5,
12068
+ display: "flex",
12069
+ alignItems: "center",
12070
+ justifyContent: "center",
12071
+ cursor: "pointer",
12072
+ zIndex: 2147483643,
12073
+ fontSize: 14,
12074
+ fontWeight: 700
12075
+ },
12076
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react10.Star, { size: 14, style: { pointerEvents: "none" } })
12077
+ }
12078
+ ),
12079
+ activeBlockRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12080
+ ItemInteractionLayer,
12081
+ {
12082
+ rect: activeBlockRect,
12083
+ state: toolbarState,
12084
+ toolbar: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12085
+ VideoToolbar,
12086
+ {
12087
+ videoId: videoIdAt(activeEntry.tree, active.path),
12088
+ pending,
12089
+ error,
12090
+ onSetVideoId: (videoId) => {
12091
+ void runMutation(
12092
+ active.sectionId,
12093
+ (tree) => videoId ? setVideoId(tree, active.path, videoId) : clearVideo(tree, active.path)
12094
+ );
12095
+ },
12096
+ onRemove: () => {
12097
+ void runMutation(active.sectionId, (tree) => clearVideo(tree, active.path));
12098
+ }
12099
+ }
12100
+ )
12101
+ }
12102
+ )
12103
+ ] });
12104
+ }
12105
+
11462
12106
  // src/OhhwellsBridge.tsx
11463
12107
  var import_react_dom5 = require("react-dom");
11464
12108
  var import_navigation3 = require("next/navigation");
@@ -11770,28 +12414,28 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
11770
12414
  }
11771
12415
 
11772
12416
  // src/ui/link-modal/LinkPopover.tsx
11773
- var import_react14 = require("react");
12417
+ var import_react15 = require("react");
11774
12418
 
11775
12419
  // src/ui/dialog.tsx
11776
12420
  var React9 = __toESM(require("react"), 1);
11777
12421
  var import_radix_ui6 = require("radix-ui");
11778
- var import_lucide_react10 = require("lucide-react");
11779
- var import_jsx_runtime20 = require("react/jsx-runtime");
12422
+ var import_lucide_react11 = require("lucide-react");
12423
+ var import_jsx_runtime21 = require("react/jsx-runtime");
11780
12424
  function Dialog2({
11781
12425
  ...props
11782
12426
  }) {
11783
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
12427
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
11784
12428
  }
11785
12429
  function DialogPortal({
11786
12430
  ...props
11787
12431
  }) {
11788
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
12432
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
11789
12433
  }
11790
12434
  function DialogOverlay({
11791
12435
  className,
11792
12436
  ...props
11793
12437
  }) {
11794
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12438
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11795
12439
  import_radix_ui6.Dialog.Overlay,
11796
12440
  {
11797
12441
  "data-slot": "dialog-overlay",
@@ -11804,9 +12448,9 @@ function DialogOverlay({
11804
12448
  var DialogContent = React9.forwardRef(
11805
12449
  ({ className, children, showCloseButton = true, container, ...props }, ref) => {
11806
12450
  const positionMode = container ? "absolute" : "fixed";
11807
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DialogPortal, { container: container ?? void 0, children: [
11808
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
11809
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
12451
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(DialogPortal, { container: container ?? void 0, children: [
12452
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
12453
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
11810
12454
  import_radix_ui6.Dialog.Content,
11811
12455
  {
11812
12456
  ref,
@@ -11822,13 +12466,13 @@ var DialogContent = React9.forwardRef(
11822
12466
  ...props,
11823
12467
  children: [
11824
12468
  children,
11825
- showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12469
+ showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11826
12470
  import_radix_ui6.Dialog.Close,
11827
12471
  {
11828
12472
  type: "button",
11829
12473
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
11830
12474
  "aria-label": "Close",
11831
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react10.X, { size: 16, "aria-hidden": true })
12475
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react11.X, { size: 16, "aria-hidden": true })
11832
12476
  }
11833
12477
  ) : null
11834
12478
  ]
@@ -11842,13 +12486,13 @@ function DialogHeader({
11842
12486
  className,
11843
12487
  ...props
11844
12488
  }) {
11845
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
12489
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
11846
12490
  }
11847
12491
  function DialogFooter({
11848
12492
  className,
11849
12493
  ...props
11850
12494
  }) {
11851
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12495
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11852
12496
  "div",
11853
12497
  {
11854
12498
  className: cn("flex items-center justify-end gap-2", className),
@@ -11856,7 +12500,7 @@ function DialogFooter({
11856
12500
  }
11857
12501
  );
11858
12502
  }
11859
- var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12503
+ var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11860
12504
  import_radix_ui6.Dialog.Title,
11861
12505
  {
11862
12506
  ref,
@@ -11868,7 +12512,7 @@ var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE
11868
12512
  }
11869
12513
  ));
11870
12514
  DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
11871
- var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12515
+ var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11872
12516
  import_radix_ui6.Dialog.Description,
11873
12517
  {
11874
12518
  ref,
@@ -11880,63 +12524,63 @@ DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
11880
12524
  var DialogClose = import_radix_ui6.Dialog.Close;
11881
12525
 
11882
12526
  // src/ui/link-modal/LinkEditorPanel.tsx
11883
- var import_lucide_react14 = require("lucide-react");
12527
+ var import_lucide_react15 = require("lucide-react");
11884
12528
 
11885
12529
  // src/ui/link-modal/DestinationBreadcrumb.tsx
11886
- var import_lucide_react11 = require("lucide-react");
11887
- var import_jsx_runtime21 = require("react/jsx-runtime");
12530
+ var import_lucide_react12 = require("lucide-react");
12531
+ var import_jsx_runtime22 = require("react/jsx-runtime");
11888
12532
  function DestinationBreadcrumb({
11889
12533
  pageTitle,
11890
12534
  sectionLabel
11891
12535
  }) {
11892
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
11893
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
11894
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-3", children: [
11895
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-2", children: [
11896
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react11.File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
11897
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
12536
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
12537
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
12538
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-3", children: [
12539
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2", children: [
12540
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
12541
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
11898
12542
  ] }),
11899
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11900
- import_lucide_react11.ArrowRight,
12543
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12544
+ import_lucide_react12.ArrowRight,
11901
12545
  {
11902
12546
  size: 16,
11903
12547
  className: "shrink-0 text-muted-foreground",
11904
12548
  "aria-hidden": true
11905
12549
  }
11906
12550
  ),
11907
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
11908
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11909
- import_lucide_react11.GalleryVertical,
12551
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
12552
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12553
+ import_lucide_react12.GalleryVertical,
11910
12554
  {
11911
12555
  size: 16,
11912
12556
  className: "shrink-0 text-foreground",
11913
12557
  "aria-hidden": true
11914
12558
  }
11915
12559
  ),
11916
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
12560
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
11917
12561
  ] })
11918
12562
  ] })
11919
12563
  ] });
11920
12564
  }
11921
12565
 
11922
12566
  // src/ui/link-modal/SectionTreeItem.tsx
11923
- var import_lucide_react12 = require("lucide-react");
11924
- var import_jsx_runtime22 = require("react/jsx-runtime");
12567
+ var import_lucide_react13 = require("lucide-react");
12568
+ var import_jsx_runtime23 = require("react/jsx-runtime");
11925
12569
  function SectionTreeItem({
11926
12570
  section,
11927
12571
  onSelect,
11928
12572
  selected
11929
12573
  }) {
11930
12574
  const interactive = Boolean(onSelect);
11931
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
11932
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12575
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
12576
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11933
12577
  "div",
11934
12578
  {
11935
12579
  className: "-mr-px h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
11936
12580
  "aria-hidden": true
11937
12581
  }
11938
12582
  ),
11939
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
12583
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
11940
12584
  "div",
11941
12585
  {
11942
12586
  role: interactive ? "button" : void 0,
@@ -11954,15 +12598,15 @@ function SectionTreeItem({
11954
12598
  interactive && selected && "border-bridge-primary"
11955
12599
  ),
11956
12600
  children: [
11957
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11958
- import_lucide_react12.GalleryVertical,
12601
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
12602
+ import_lucide_react13.GalleryVertical,
11959
12603
  {
11960
12604
  size: 16,
11961
12605
  className: "shrink-0 text-foreground",
11962
12606
  "aria-hidden": true
11963
12607
  }
11964
12608
  ),
11965
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
12609
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
11966
12610
  ]
11967
12611
  }
11968
12612
  )
@@ -11970,14 +12614,14 @@ function SectionTreeItem({
11970
12614
  }
11971
12615
 
11972
12616
  // src/ui/link-modal/UrlOrPageInput.tsx
11973
- var import_react11 = require("react");
12617
+ var import_react12 = require("react");
11974
12618
 
11975
12619
  // src/ui/input.tsx
11976
12620
  var React10 = __toESM(require("react"), 1);
11977
- var import_jsx_runtime23 = require("react/jsx-runtime");
12621
+ var import_jsx_runtime24 = require("react/jsx-runtime");
11978
12622
  var Input = React10.forwardRef(
11979
12623
  ({ className, type, ...props }, ref) => {
11980
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
12624
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
11981
12625
  "input",
11982
12626
  {
11983
12627
  type,
@@ -11996,9 +12640,9 @@ Input.displayName = "Input";
11996
12640
 
11997
12641
  // src/ui/label.tsx
11998
12642
  var import_radix_ui7 = require("radix-ui");
11999
- var import_jsx_runtime24 = require("react/jsx-runtime");
12643
+ var import_jsx_runtime25 = require("react/jsx-runtime");
12000
12644
  function Label({ className, ...props }) {
12001
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12645
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12002
12646
  import_radix_ui7.Label.Root,
12003
12647
  {
12004
12648
  "data-slot": "label",
@@ -12009,12 +12653,12 @@ function Label({ className, ...props }) {
12009
12653
  }
12010
12654
 
12011
12655
  // src/ui/link-modal/UrlOrPageInput.tsx
12012
- var import_lucide_react13 = require("lucide-react");
12013
- var import_jsx_runtime25 = require("react/jsx-runtime");
12656
+ var import_lucide_react14 = require("lucide-react");
12657
+ var import_jsx_runtime26 = require("react/jsx-runtime");
12014
12658
  function FieldChevron({
12015
12659
  onClick
12016
12660
  }) {
12017
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12661
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12018
12662
  "button",
12019
12663
  {
12020
12664
  type: "button",
@@ -12022,7 +12666,7 @@ function FieldChevron({
12022
12666
  onClick,
12023
12667
  "aria-label": "Open page list",
12024
12668
  tabIndex: -1,
12025
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react13.ChevronDown, { size: 16 })
12669
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react14.ChevronDown, { size: 16 })
12026
12670
  }
12027
12671
  );
12028
12672
  }
@@ -12038,11 +12682,11 @@ function UrlOrPageInput({
12038
12682
  readOnly = false,
12039
12683
  urlError
12040
12684
  }) {
12041
- const inputId = (0, import_react11.useId)();
12042
- const inputRef = (0, import_react11.useRef)(null);
12043
- const rootRef = (0, import_react11.useRef)(null);
12044
- const [isFocused, setIsFocused] = (0, import_react11.useState)(false);
12045
- (0, import_react11.useEffect)(() => {
12685
+ const inputId = (0, import_react12.useId)();
12686
+ const inputRef = (0, import_react12.useRef)(null);
12687
+ const rootRef = (0, import_react12.useRef)(null);
12688
+ const [isFocused, setIsFocused] = (0, import_react12.useState)(false);
12689
+ (0, import_react12.useEffect)(() => {
12046
12690
  if (!dropdownOpen) return;
12047
12691
  const isOutside = (e) => {
12048
12692
  const root = rootRef.current;
@@ -12083,19 +12727,19 @@ function UrlOrPageInput({
12083
12727
  "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]",
12084
12728
  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"
12085
12729
  );
12086
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
12087
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
12088
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { ref: rootRef, className: "relative w-full", children: [
12089
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
12090
- selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12091
- import_lucide_react13.File,
12730
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
12731
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
12732
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { ref: rootRef, className: "relative w-full", children: [
12733
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
12734
+ selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12735
+ import_lucide_react14.File,
12092
12736
  {
12093
12737
  size: 16,
12094
12738
  className: "shrink-0 text-foreground",
12095
12739
  "aria-hidden": true
12096
12740
  }
12097
12741
  ) }) : null,
12098
- readOnly ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12742
+ readOnly ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12099
12743
  Input,
12100
12744
  {
12101
12745
  ref: inputRef,
@@ -12121,7 +12765,7 @@ function UrlOrPageInput({
12121
12765
  )
12122
12766
  }
12123
12767
  ),
12124
- selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12768
+ selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12125
12769
  "button",
12126
12770
  {
12127
12771
  type: "button",
@@ -12129,26 +12773,26 @@ function UrlOrPageInput({
12129
12773
  onMouseDown: clearSelection,
12130
12774
  "aria-label": "Clear selected page",
12131
12775
  tabIndex: -1,
12132
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react13.X, { size: 16, "aria-hidden": true })
12776
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react14.X, { size: 16, "aria-hidden": true })
12133
12777
  }
12134
12778
  ) : null,
12135
- !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
12779
+ !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
12136
12780
  ] }),
12137
- dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12781
+ dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12138
12782
  "div",
12139
12783
  {
12140
12784
  "data-ohw-link-page-dropdown": "",
12141
12785
  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",
12142
12786
  onMouseDown: (e) => e.preventDefault(),
12143
- children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
12787
+ children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
12144
12788
  "button",
12145
12789
  {
12146
12790
  type: "button",
12147
12791
  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",
12148
12792
  onClick: () => onPageSelect(page),
12149
12793
  children: [
12150
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react13.File, { size: 16, className: "shrink-0", "aria-hidden": true }),
12151
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "truncate", children: page.title })
12794
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react14.File, { size: 16, className: "shrink-0", "aria-hidden": true }),
12795
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "truncate", children: page.title })
12152
12796
  ]
12153
12797
  },
12154
12798
  page.path
@@ -12156,34 +12800,34 @@ function UrlOrPageInput({
12156
12800
  }
12157
12801
  ) : null
12158
12802
  ] }),
12159
- urlError ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
12803
+ urlError ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
12160
12804
  ] });
12161
12805
  }
12162
12806
 
12163
12807
  // src/ui/link-modal/LinkEditorPanel.tsx
12164
- var import_jsx_runtime26 = require("react/jsx-runtime");
12808
+ var import_jsx_runtime27 = require("react/jsx-runtime");
12165
12809
  function LinkEditorPanel({ state, onClose }) {
12166
12810
  const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
12167
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
12168
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12811
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
12812
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12169
12813
  "button",
12170
12814
  {
12171
12815
  type: "button",
12172
12816
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
12173
12817
  "aria-label": "Close",
12174
12818
  onClick: onClose,
12175
- children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react14.X, { size: 16, "aria-hidden": true })
12819
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react15.X, { size: 16, "aria-hidden": true })
12176
12820
  }
12177
12821
  ) }),
12178
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
12179
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
12180
- state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12822
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
12823
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
12824
+ state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12181
12825
  DestinationBreadcrumb,
12182
12826
  {
12183
12827
  pageTitle: state.selectedPage.title,
12184
12828
  sectionLabel: state.selectedSection.label
12185
12829
  }
12186
- ) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12830
+ ) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12187
12831
  UrlOrPageInput,
12188
12832
  {
12189
12833
  value: state.searchValue,
@@ -12196,8 +12840,8 @@ function LinkEditorPanel({ state, onClose }) {
12196
12840
  urlError: state.urlError
12197
12841
  }
12198
12842
  ),
12199
- state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
12200
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12843
+ state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
12844
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12201
12845
  Button,
12202
12846
  {
12203
12847
  type: "button",
@@ -12208,15 +12852,15 @@ function LinkEditorPanel({ state, onClose }) {
12208
12852
  children: "Choose a section"
12209
12853
  }
12210
12854
  ),
12211
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
12212
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react14.Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
12213
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Pick a section this link should scroll to." })
12855
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
12856
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react15.Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
12857
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: "Pick a section this link should scroll to." })
12214
12858
  ] })
12215
12859
  ] }) : null,
12216
- state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
12860
+ state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
12217
12861
  ] }),
12218
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
12219
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12862
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
12863
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12220
12864
  Button,
12221
12865
  {
12222
12866
  type: "button",
@@ -12231,7 +12875,7 @@ function LinkEditorPanel({ state, onClose }) {
12231
12875
  children: state.secondaryLabel
12232
12876
  }
12233
12877
  ),
12234
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12878
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12235
12879
  Button,
12236
12880
  {
12237
12881
  type: "button",
@@ -12250,9 +12894,9 @@ function LinkEditorPanel({ state, onClose }) {
12250
12894
  }
12251
12895
 
12252
12896
  // src/ui/link-modal/SectionPickerOverlay.tsx
12253
- var import_react12 = require("react");
12897
+ var import_react13 = require("react");
12254
12898
  var import_react_dom3 = require("react-dom");
12255
- var import_lucide_react15 = require("lucide-react");
12899
+ var import_lucide_react16 = require("lucide-react");
12256
12900
  var import_navigation2 = require("next/navigation");
12257
12901
 
12258
12902
  // src/lib/parent-scroll.ts
@@ -12274,7 +12918,7 @@ function getIframeChromeClip(parentScroll) {
12274
12918
  }
12275
12919
 
12276
12920
  // src/ui/link-modal/SectionPickerOverlay.tsx
12277
- var import_jsx_runtime27 = require("react/jsx-runtime");
12921
+ var import_jsx_runtime28 = require("react/jsx-runtime");
12278
12922
  var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
12279
12923
  function rectsEqual(a, b) {
12280
12924
  if (a.size !== b.size) return false;
@@ -12307,12 +12951,12 @@ function hitTestSectionId(x, y, sectionIds, rects) {
12307
12951
  return null;
12308
12952
  }
12309
12953
  function useSectionRects(sectionIdsKey, enabled) {
12310
- const [rects, setRects] = (0, import_react12.useState)(/* @__PURE__ */ new Map());
12311
- const sectionIds = (0, import_react12.useMemo)(
12954
+ const [rects, setRects] = (0, import_react13.useState)(/* @__PURE__ */ new Map());
12955
+ const sectionIds = (0, import_react13.useMemo)(
12312
12956
  () => sectionIdsKey ? sectionIdsKey.split("\0") : [],
12313
12957
  [sectionIdsKey]
12314
12958
  );
12315
- (0, import_react12.useEffect)(() => {
12959
+ (0, import_react13.useEffect)(() => {
12316
12960
  if (!enabled || sectionIds.length === 0) {
12317
12961
  setRects((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
12318
12962
  return;
@@ -12353,13 +12997,13 @@ function SectionPickerOverlay({
12353
12997
  }) {
12354
12998
  const router = (0, import_navigation2.useRouter)();
12355
12999
  const pathname = (0, import_navigation2.usePathname)();
12356
- const [selectedId, setSelectedId] = (0, import_react12.useState)(null);
12357
- const [hoveredId, setHoveredId] = (0, import_react12.useState)(null);
12358
- const pointerRef = (0, import_react12.useRef)(null);
12359
- const pointerScreenRef = (0, import_react12.useRef)(null);
12360
- const iframeOffsetTopRef = (0, import_react12.useRef)(null);
12361
- const sectionIdsRef = (0, import_react12.useRef)([]);
12362
- const [chromeClip, setChromeClip] = (0, import_react12.useState)(
13000
+ const [selectedId, setSelectedId] = (0, import_react13.useState)(null);
13001
+ const [hoveredId, setHoveredId] = (0, import_react13.useState)(null);
13002
+ const pointerRef = (0, import_react13.useRef)(null);
13003
+ const pointerScreenRef = (0, import_react13.useRef)(null);
13004
+ const iframeOffsetTopRef = (0, import_react13.useRef)(null);
13005
+ const sectionIdsRef = (0, import_react13.useRef)([]);
13006
+ const [chromeClip, setChromeClip] = (0, import_react13.useState)(
12363
13007
  () => ({
12364
13008
  top: 0,
12365
13009
  bottom: typeof window !== "undefined" ? window.innerHeight : 0
@@ -12367,12 +13011,12 @@ function SectionPickerOverlay({
12367
13011
  );
12368
13012
  const normalizedTarget = normalizePath(pagePath);
12369
13013
  const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
12370
- (0, import_react12.useEffect)(() => {
13014
+ (0, import_react13.useEffect)(() => {
12371
13015
  if (isOnTargetPage) return;
12372
13016
  const search = readPreservedSearch();
12373
13017
  router.push(`${normalizedTarget}${search}`);
12374
13018
  }, [isOnTargetPage, normalizedTarget, router]);
12375
- (0, import_react12.useEffect)(() => {
13019
+ (0, import_react13.useEffect)(() => {
12376
13020
  document.documentElement.setAttribute("data-ohw-section-picking", "");
12377
13021
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
12378
13022
  el.removeAttribute("data-ohw-hovered");
@@ -12384,24 +13028,24 @@ function SectionPickerOverlay({
12384
13028
  document.documentElement.removeAttribute("data-ohw-section-picking");
12385
13029
  };
12386
13030
  }, []);
12387
- const liveSections = (0, import_react12.useMemo)(() => {
13031
+ const liveSections = (0, import_react13.useMemo)(() => {
12388
13032
  if (!isOnTargetPage) return sections;
12389
13033
  const live = collectSectionsFromDom();
12390
13034
  if (live.length === 0) return sections;
12391
13035
  const labels = new Map(sections.map((s) => [s.id, s.label]));
12392
13036
  return live.map((s) => ({ id: s.id, label: labels.get(s.id) ?? s.label }));
12393
13037
  }, [isOnTargetPage, sections, pathname]);
12394
- const sectionIdsKey = (0, import_react12.useMemo)(
13038
+ const sectionIdsKey = (0, import_react13.useMemo)(
12395
13039
  () => liveSections.map((s) => s.id).join("\0"),
12396
13040
  [liveSections]
12397
13041
  );
12398
- const sectionIds = (0, import_react12.useMemo)(
13042
+ const sectionIds = (0, import_react13.useMemo)(
12399
13043
  () => liveSections.map((s) => s.id),
12400
13044
  [liveSections]
12401
13045
  );
12402
13046
  sectionIdsRef.current = sectionIds;
12403
13047
  const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
12404
- const applyHoverAt = (0, import_react12.useCallback)(
13048
+ const applyHoverAt = (0, import_react13.useCallback)(
12405
13049
  (x, y, liveRects) => {
12406
13050
  const ids = sectionIdsRef.current;
12407
13051
  const map = liveRects ?? readSectionRects(ids);
@@ -12410,7 +13054,7 @@ function SectionPickerOverlay({
12410
13054
  },
12411
13055
  []
12412
13056
  );
12413
- (0, import_react12.useEffect)(() => {
13057
+ (0, import_react13.useEffect)(() => {
12414
13058
  const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH, promptBarH = 0) => {
12415
13059
  const next = getIframeVisibleClip({
12416
13060
  iframeOffsetTop,
@@ -12454,12 +13098,12 @@ function SectionPickerOverlay({
12454
13098
  window.removeEventListener("resize", onResize);
12455
13099
  };
12456
13100
  }, [applyHoverAt]);
12457
- (0, import_react12.useEffect)(() => {
13101
+ (0, import_react13.useEffect)(() => {
12458
13102
  const ptr = pointerRef.current;
12459
13103
  if (!ptr) return;
12460
13104
  applyHoverAt(ptr.x, ptr.y, rects);
12461
13105
  }, [rects, applyHoverAt]);
12462
- (0, import_react12.useEffect)(() => {
13106
+ (0, import_react13.useEffect)(() => {
12463
13107
  const rememberPointer = (clientX, clientY) => {
12464
13108
  pointerRef.current = { x: clientX, y: clientY };
12465
13109
  const top = iframeOffsetTopRef.current;
@@ -12483,7 +13127,7 @@ function SectionPickerOverlay({
12483
13127
  window.removeEventListener("message", onPointerSync);
12484
13128
  };
12485
13129
  }, [rects, applyHoverAt]);
12486
- const handleSelect = (0, import_react12.useCallback)(
13130
+ const handleSelect = (0, import_react13.useCallback)(
12487
13131
  (section) => {
12488
13132
  if (selectedId) return;
12489
13133
  setSelectedId(section.id);
@@ -12491,7 +13135,7 @@ function SectionPickerOverlay({
12491
13135
  },
12492
13136
  [selectedId, onSelect]
12493
13137
  );
12494
- (0, import_react12.useEffect)(() => {
13138
+ (0, import_react13.useEffect)(() => {
12495
13139
  const onKeyDown = (e) => {
12496
13140
  if (e.key === "Escape") {
12497
13141
  e.preventDefault();
@@ -12505,7 +13149,7 @@ function SectionPickerOverlay({
12505
13149
  const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
12506
13150
  if (!portalRoot) return null;
12507
13151
  return (0, import_react_dom3.createPortal)(
12508
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
13152
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
12509
13153
  "div",
12510
13154
  {
12511
13155
  "data-ohw-section-picker": "",
@@ -12515,12 +13159,12 @@ function SectionPickerOverlay({
12515
13159
  role: "dialog",
12516
13160
  "aria-label": "Choose a section",
12517
13161
  children: [
12518
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
13162
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12519
13163
  "div",
12520
13164
  {
12521
13165
  className: "pointer-events-auto fixed left-5 z-[2]",
12522
13166
  style: { top: chromeClip.top + 20 },
12523
- children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
13167
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
12524
13168
  Button,
12525
13169
  {
12526
13170
  type: "button",
@@ -12529,14 +13173,14 @@ function SectionPickerOverlay({
12529
13173
  className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
12530
13174
  onClick: onBack,
12531
13175
  children: [
12532
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react15.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
13176
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react16.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
12533
13177
  "Back"
12534
13178
  ]
12535
13179
  }
12536
13180
  )
12537
13181
  }
12538
13182
  ),
12539
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
13183
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12540
13184
  "div",
12541
13185
  {
12542
13186
  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",
@@ -12549,7 +13193,7 @@ function SectionPickerOverlay({
12549
13193
  children: "Click on section to select"
12550
13194
  }
12551
13195
  ),
12552
- !isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
13196
+ !isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12553
13197
  "div",
12554
13198
  {
12555
13199
  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",
@@ -12557,14 +13201,14 @@ function SectionPickerOverlay({
12557
13201
  children: "Loading page preview\u2026"
12558
13202
  }
12559
13203
  ) : null,
12560
- isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
13204
+ isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
12561
13205
  isOnTargetPage ? liveSections.map((section) => {
12562
13206
  const rect = rects.get(section.id);
12563
13207
  if (!rect || rect.width <= 0 || rect.height <= 0) return null;
12564
13208
  const isSelected = selectedId === section.id;
12565
13209
  const isHovered = hoveredId === section.id;
12566
13210
  const isLit = isSelected || isHovered;
12567
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
13211
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
12568
13212
  "button",
12569
13213
  {
12570
13214
  type: "button",
@@ -12579,7 +13223,7 @@ function SectionPickerOverlay({
12579
13223
  "aria-label": `Select section ${section.label}`,
12580
13224
  onClick: () => handleSelect(section),
12581
13225
  children: [
12582
- isLit ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
13226
+ isLit ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12583
13227
  "span",
12584
13228
  {
12585
13229
  className: "pointer-events-none absolute",
@@ -12592,13 +13236,13 @@ function SectionPickerOverlay({
12592
13236
  "aria-hidden": true
12593
13237
  }
12594
13238
  ) : null,
12595
- isSelected ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
13239
+ isSelected ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12596
13240
  "span",
12597
13241
  {
12598
13242
  className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
12599
13243
  style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
12600
13244
  "aria-hidden": true,
12601
- children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react15.Check, { className: "size-5" })
13245
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react16.Check, { className: "size-5" })
12602
13246
  }
12603
13247
  ) : null
12604
13248
  ]
@@ -12614,7 +13258,7 @@ function SectionPickerOverlay({
12614
13258
  }
12615
13259
 
12616
13260
  // src/ui/link-modal/useLinkModalState.ts
12617
- var import_react13 = require("react");
13261
+ var import_react14 = require("react");
12618
13262
  function useLinkModalState({
12619
13263
  open,
12620
13264
  mode,
@@ -12626,14 +13270,14 @@ function useLinkModalState({
12626
13270
  onClose,
12627
13271
  onSubmit
12628
13272
  }) {
12629
- const availablePages = (0, import_react13.useMemo)(() => pages, [pages]);
12630
- const [searchValue, setSearchValue] = (0, import_react13.useState)("");
12631
- const [selectedPage, setSelectedPage] = (0, import_react13.useState)(null);
12632
- const [selectedSection, setSelectedSection] = (0, import_react13.useState)(null);
12633
- const [step, setStep] = (0, import_react13.useState)("input");
12634
- const [dropdownOpen, setDropdownOpen] = (0, import_react13.useState)(false);
12635
- const [urlError, setUrlError] = (0, import_react13.useState)("");
12636
- const reset = (0, import_react13.useCallback)(() => {
13273
+ const availablePages = (0, import_react14.useMemo)(() => pages, [pages]);
13274
+ const [searchValue, setSearchValue] = (0, import_react14.useState)("");
13275
+ const [selectedPage, setSelectedPage] = (0, import_react14.useState)(null);
13276
+ const [selectedSection, setSelectedSection] = (0, import_react14.useState)(null);
13277
+ const [step, setStep] = (0, import_react14.useState)("input");
13278
+ const [dropdownOpen, setDropdownOpen] = (0, import_react14.useState)(false);
13279
+ const [urlError, setUrlError] = (0, import_react14.useState)("");
13280
+ const reset = (0, import_react14.useCallback)(() => {
12637
13281
  setSearchValue("");
12638
13282
  setSelectedPage(null);
12639
13283
  setSelectedSection(null);
@@ -12641,7 +13285,7 @@ function useLinkModalState({
12641
13285
  setDropdownOpen(false);
12642
13286
  setUrlError("");
12643
13287
  }, []);
12644
- (0, import_react13.useEffect)(() => {
13288
+ (0, import_react14.useEffect)(() => {
12645
13289
  if (!open) return;
12646
13290
  if (mode === "edit" && initialTarget) {
12647
13291
  const { pageRoute } = parseTarget(initialTarget);
@@ -12657,11 +13301,11 @@ function useLinkModalState({
12657
13301
  setDropdownOpen(false);
12658
13302
  setUrlError("");
12659
13303
  }, [open, mode, initialTarget, reset]);
12660
- const filteredPages = (0, import_react13.useMemo)(() => {
13304
+ const filteredPages = (0, import_react14.useMemo)(() => {
12661
13305
  if (!searchValue.trim()) return availablePages;
12662
13306
  return availablePages.filter((p) => p.title.toLowerCase().startsWith(searchValue.toLowerCase()));
12663
13307
  }, [availablePages, searchValue]);
12664
- const activeSections = (0, import_react13.useMemo)(() => {
13308
+ const activeSections = (0, import_react14.useMemo)(() => {
12665
13309
  if (!selectedPage) return [];
12666
13310
  return getSectionsForPath(sectionsByPath, selectedPage.path);
12667
13311
  }, [selectedPage, sectionsByPath]);
@@ -12710,7 +13354,7 @@ function useLinkModalState({
12710
13354
  reset();
12711
13355
  onClose();
12712
13356
  };
12713
- const isValid = (0, import_react13.useMemo)(() => {
13357
+ const isValid = (0, import_react14.useMemo)(() => {
12714
13358
  if (urlError) return false;
12715
13359
  if (showBreadcrumb) return true;
12716
13360
  if (selectedPage) return true;
@@ -12778,7 +13422,7 @@ function useLinkModalState({
12778
13422
  }
12779
13423
 
12780
13424
  // src/ui/link-modal/LinkPopover.tsx
12781
- var import_jsx_runtime28 = require("react/jsx-runtime");
13425
+ var import_jsx_runtime29 = require("react/jsx-runtime");
12782
13426
  function postToParent(data) {
12783
13427
  window.parent?.postMessage(data, "*");
12784
13428
  }
@@ -12807,7 +13451,7 @@ function LinkPopover({
12807
13451
  onSubmit
12808
13452
  });
12809
13453
  const sectionPickerActive = state.showSectionPicker && Boolean(state.selectedPage);
12810
- (0, import_react14.useEffect)(() => {
13454
+ (0, import_react15.useEffect)(() => {
12811
13455
  if (!open) return;
12812
13456
  if (sectionPickerActive) {
12813
13457
  postToParent({ type: "ui:unlock" });
@@ -12874,15 +13518,15 @@ function LinkPopover({
12874
13518
  );
12875
13519
  };
12876
13520
  }, [open, sectionPickerActive]);
12877
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
12878
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
13521
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
13522
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
12879
13523
  Dialog2,
12880
13524
  {
12881
13525
  open: open && !sectionPickerActive,
12882
13526
  onOpenChange: (next) => {
12883
13527
  if (!next) onClose?.();
12884
13528
  },
12885
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
13529
+ children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
12886
13530
  DialogContent,
12887
13531
  {
12888
13532
  ref: panelRef,
@@ -12892,12 +13536,12 @@ function LinkPopover({
12892
13536
  "data-ohw-bridge": "",
12893
13537
  showCloseButton: false,
12894
13538
  className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
12895
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(LinkEditorPanel, { state, onClose })
13539
+ children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(LinkEditorPanel, { state, onClose })
12896
13540
  }
12897
13541
  )
12898
13542
  }
12899
13543
  ),
12900
- sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
13544
+ sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
12901
13545
  SectionPickerOverlay,
12902
13546
  {
12903
13547
  pagePath: state.selectedPage.path,
@@ -16019,6 +16663,7 @@ function readLogoSizeState(content, placement) {
16019
16663
  function getLogoElement(el) {
16020
16664
  const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
16021
16665
  if (marked) return marked;
16666
+ if (el.closest('[data-ohw-editable="icon"]')) return null;
16022
16667
  const root = el.closest("nav, [data-ohw-nav-root], footer");
16023
16668
  if (!root) return null;
16024
16669
  const anchor = el.closest("a");
@@ -16085,9 +16730,9 @@ function addFooterColumnWithPersist({
16085
16730
  }
16086
16731
 
16087
16732
  // src/ui/FloatingPanel.tsx
16088
- var import_react15 = require("react");
16089
- var import_lucide_react16 = require("lucide-react");
16090
- var import_jsx_runtime29 = require("react/jsx-runtime");
16733
+ var import_react16 = require("react");
16734
+ var import_lucide_react17 = require("lucide-react");
16735
+ var import_jsx_runtime30 = require("react/jsx-runtime");
16091
16736
  var PANEL_WIDTH = 256;
16092
16737
  var EDGE_MARGIN = 16;
16093
16738
  var HEADER_MIN = 56;
@@ -16147,10 +16792,10 @@ function FloatingPanel({
16147
16792
  className,
16148
16793
  bodyClassName
16149
16794
  }) {
16150
- const panelRef = (0, import_react15.useRef)(null);
16151
- const [measured, setMeasured] = (0, import_react15.useState)({ w: PANEL_WIDTH, h: 280 });
16152
- const dragRef = (0, import_react15.useRef)(null);
16153
- const homeRef = (0, import_react15.useRef)(null);
16795
+ const panelRef = (0, import_react16.useRef)(null);
16796
+ const [measured, setMeasured] = (0, import_react16.useState)({ w: PANEL_WIDTH, h: 280 });
16797
+ const dragRef = (0, import_react16.useRef)(null);
16798
+ const homeRef = (0, import_react16.useRef)(null);
16154
16799
  if (!open) {
16155
16800
  homeRef.current = null;
16156
16801
  } else if (position) {
@@ -16158,17 +16803,17 @@ function FloatingPanel({
16158
16803
  } else if (homeRef.current == null) {
16159
16804
  homeRef.current = defaultFloatingPanelPosition(parentScroll);
16160
16805
  }
16161
- const [liveScroll, setLiveScroll] = (0, import_react15.useState)(parentScroll);
16806
+ const [liveScroll, setLiveScroll] = (0, import_react16.useState)(parentScroll);
16162
16807
  const home = position ?? homeRef.current ?? defaultFloatingPanelPosition(parentScroll);
16163
16808
  const { y: fittedY, maxHeight } = fitPanelInClip(home.y, liveScroll, measured.h);
16164
16809
  const clamped = {
16165
16810
  x: clampX(home.x, measured.w),
16166
16811
  y: fittedY
16167
16812
  };
16168
- (0, import_react15.useEffect)(() => {
16813
+ (0, import_react16.useEffect)(() => {
16169
16814
  setLiveScroll(parentScroll);
16170
16815
  }, [parentScroll]);
16171
- (0, import_react15.useEffect)(() => {
16816
+ (0, import_react16.useEffect)(() => {
16172
16817
  if (!open) return;
16173
16818
  const onParentScroll = (e) => {
16174
16819
  if (e.data?.type !== "ow:parent-scroll") return;
@@ -16178,8 +16823,8 @@ function FloatingPanel({
16178
16823
  window.addEventListener("message", onParentScroll);
16179
16824
  return () => window.removeEventListener("message", onParentScroll);
16180
16825
  }, [open]);
16181
- const positionRef = (0, import_react15.useRef)(position);
16182
- (0, import_react15.useLayoutEffect)(() => {
16826
+ const positionRef = (0, import_react16.useRef)(position);
16827
+ (0, import_react16.useLayoutEffect)(() => {
16183
16828
  if (!open) {
16184
16829
  positionRef.current = position;
16185
16830
  return;
@@ -16189,7 +16834,7 @@ function FloatingPanel({
16189
16834
  }
16190
16835
  positionRef.current = position;
16191
16836
  }, [open, position, liveScroll, parentScroll]);
16192
- (0, import_react15.useLayoutEffect)(() => {
16837
+ (0, import_react16.useLayoutEffect)(() => {
16193
16838
  if (!open || !panelRef.current) return;
16194
16839
  const el = panelRef.current;
16195
16840
  const header = el.querySelector("[data-ohw-floating-panel-header]");
@@ -16198,7 +16843,7 @@ function FloatingPanel({
16198
16843
  const next = { w: el.offsetWidth || PANEL_WIDTH, h: contentH };
16199
16844
  setMeasured((prev) => prev.w === next.w && prev.h === next.h ? prev : next);
16200
16845
  }, [open, children, title, context]);
16201
- const onHeaderPointerDown = (0, import_react15.useCallback)(
16846
+ const onHeaderPointerDown = (0, import_react16.useCallback)(
16202
16847
  (e) => {
16203
16848
  if (e.button !== 0) return;
16204
16849
  if (e.target.closest("[data-ohw-floating-panel-close]")) return;
@@ -16217,7 +16862,7 @@ function FloatingPanel({
16217
16862
  },
16218
16863
  [clamped.x, clamped.y]
16219
16864
  );
16220
- const onHeaderPointerMove = (0, import_react15.useCallback)(
16865
+ const onHeaderPointerMove = (0, import_react16.useCallback)(
16221
16866
  (e) => {
16222
16867
  const drag = dragRef.current;
16223
16868
  if (!drag || drag.pointerId !== e.pointerId) return;
@@ -16243,7 +16888,7 @@ function FloatingPanel({
16243
16888
  },
16244
16889
  [measured.w, onPositionChange, liveScroll]
16245
16890
  );
16246
- const endDrag = (0, import_react15.useCallback)((e) => {
16891
+ const endDrag = (0, import_react16.useCallback)((e) => {
16247
16892
  const drag = dragRef.current;
16248
16893
  if (!drag || drag.pointerId !== e.pointerId) return;
16249
16894
  dragRef.current = null;
@@ -16253,13 +16898,13 @@ function FloatingPanel({
16253
16898
  } catch {
16254
16899
  }
16255
16900
  }, []);
16256
- (0, import_react15.useEffect)(() => {
16901
+ (0, import_react16.useEffect)(() => {
16257
16902
  if (open) return;
16258
16903
  document.documentElement.removeAttribute("data-ohw-panel-dragging");
16259
16904
  }, [open]);
16260
- (0, import_react15.useEffect)(() => () => document.documentElement.removeAttribute("data-ohw-panel-dragging"), []);
16905
+ (0, import_react16.useEffect)(() => () => document.documentElement.removeAttribute("data-ohw-panel-dragging"), []);
16261
16906
  if (!open) return null;
16262
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
16907
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
16263
16908
  "div",
16264
16909
  {
16265
16910
  ref: panelRef,
@@ -16276,7 +16921,7 @@ function FloatingPanel({
16276
16921
  onPointerDown: (e) => e.stopPropagation(),
16277
16922
  onClick: (e) => e.stopPropagation(),
16278
16923
  children: [
16279
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
16924
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
16280
16925
  "div",
16281
16926
  {
16282
16927
  "data-ohw-floating-panel-header": "",
@@ -16286,14 +16931,14 @@ function FloatingPanel({
16286
16931
  onPointerUp: endDrag,
16287
16932
  onPointerCancel: endDrag,
16288
16933
  children: [
16289
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
16290
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-2", children: [
16291
- icon ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "shrink-0 text-foreground", children: icon }) : null,
16292
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "min-w-0 flex-1 text-lg font-semibold leading-7 text-foreground", children: title })
16934
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
16935
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-2", children: [
16936
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "shrink-0 text-foreground", children: icon }) : null,
16937
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "min-w-0 flex-1 text-lg font-semibold leading-7 text-foreground", children: title })
16293
16938
  ] }),
16294
- context ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "w-full text-sm leading-5 text-muted-foreground", children: context }) : null
16939
+ context ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "w-full text-sm leading-5 text-muted-foreground", children: context }) : null
16295
16940
  ] }),
16296
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
16941
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
16297
16942
  "button",
16298
16943
  {
16299
16944
  type: "button",
@@ -16305,13 +16950,13 @@ function FloatingPanel({
16305
16950
  onClose();
16306
16951
  },
16307
16952
  onPointerDown: (e) => e.stopPropagation(),
16308
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react16.X, { size: 16, "aria-hidden": true })
16953
+ children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react17.X, { size: 16, "aria-hidden": true })
16309
16954
  }
16310
16955
  )
16311
16956
  ]
16312
16957
  }
16313
16958
  ),
16314
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
16959
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
16315
16960
  "div",
16316
16961
  {
16317
16962
  "data-ohw-floating-panel-body": "",
@@ -16329,15 +16974,15 @@ function FloatingPanel({
16329
16974
  }
16330
16975
 
16331
16976
  // src/ui/socials-display-panel.tsx
16332
- var import_jsx_runtime30 = require("react/jsx-runtime");
16977
+ var import_jsx_runtime31 = require("react/jsx-runtime");
16333
16978
  function DisplaySwitch({
16334
16979
  label,
16335
16980
  checked,
16336
16981
  disabled,
16337
16982
  onChange
16338
16983
  }) {
16339
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex w-full items-center gap-2", children: [
16340
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
16984
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex w-full items-center gap-2", children: [
16985
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
16341
16986
  "span",
16342
16987
  {
16343
16988
  className: cn(
@@ -16347,7 +16992,7 @@ function DisplaySwitch({
16347
16992
  children: label
16348
16993
  }
16349
16994
  ),
16350
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
16995
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
16351
16996
  "button",
16352
16997
  {
16353
16998
  type: "button",
@@ -16361,7 +17006,7 @@ function DisplaySwitch({
16361
17006
  checked ? "bg-bridge-primary" : "bg-primary-50",
16362
17007
  disabled ? "cursor-default opacity-50" : "cursor-pointer"
16363
17008
  ),
16364
- children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
17009
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
16365
17010
  "span",
16366
17011
  {
16367
17012
  className: cn(
@@ -16375,8 +17020,8 @@ function DisplaySwitch({
16375
17020
  ] });
16376
17021
  }
16377
17022
  function SocialsDisplayPanel({ display, onChange, className }) {
16378
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: cn("flex w-full flex-col gap-3", className), children: [
16379
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
17023
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cn("flex w-full flex-col gap-3", className), children: [
17024
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
16380
17025
  DisplaySwitch,
16381
17026
  {
16382
17027
  label: "Text",
@@ -16385,7 +17030,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
16385
17030
  onChange: (text) => onChange({ ...display, text })
16386
17031
  }
16387
17032
  ),
16388
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
17033
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
16389
17034
  DisplaySwitch,
16390
17035
  {
16391
17036
  label: "Icon",
@@ -16398,7 +17043,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
16398
17043
  }
16399
17044
 
16400
17045
  // src/ui/button-style-panel.tsx
16401
- var import_lucide_react17 = require("lucide-react");
17046
+ var import_lucide_react18 = require("lucide-react");
16402
17047
 
16403
17048
  // src/lib/button-styles.ts
16404
17049
  var BUTTON_VARIANTS_KEY = "__ohw_button_variants";
@@ -17101,7 +17746,7 @@ function withAssignment(content, id, assignment) {
17101
17746
  }
17102
17747
 
17103
17748
  // src/ui/button-style-panel.tsx
17104
- var import_jsx_runtime31 = require("react/jsx-runtime");
17749
+ var import_jsx_runtime32 = require("react/jsx-runtime");
17105
17750
  var SIZE_LABEL = { s: "S", m: "M", l: "L" };
17106
17751
  function ButtonStylePanel({
17107
17752
  variants,
@@ -17115,15 +17760,15 @@ function ButtonStylePanel({
17115
17760
  }) {
17116
17761
  const preview = scaleGeometry(sizes.m, 0.75);
17117
17762
  const label = previewLabel.trim() || "Book Now";
17118
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex w-full flex-col gap-5", children: [
17119
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("section", { className: "flex w-full flex-col gap-2.5", children: [
17120
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("h3", { className: "text-xs font-semibold uppercase leading-4 tracking-[0.6px] text-stone-500 font-sans", children: "Variants" }),
17121
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex w-full flex-col gap-2.5", children: BUTTON_VARIANT_IDS.map((id) => {
17763
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex w-full flex-col gap-5", children: [
17764
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("section", { className: "flex w-full flex-col gap-2.5", children: [
17765
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("h3", { className: "text-xs font-semibold uppercase leading-4 tracking-[0.6px] text-stone-500 font-sans", children: "Variants" }),
17766
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex w-full flex-col gap-2.5", children: BUTTON_VARIANT_IDS.map((id) => {
17122
17767
  const chrome = variants[id];
17123
17768
  const selected = id === variant;
17124
17769
  const hasBorder = parseFloat(chrome.borderWidth) > 0;
17125
17770
  const cardSlot = previewSlotForChrome(chrome, slotBackground);
17126
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
17771
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
17127
17772
  "button",
17128
17773
  {
17129
17774
  type: "button",
@@ -17139,12 +17784,12 @@ function ButtonStylePanel({
17139
17784
  selected ? "border-2 border-primary" : "border border-border"
17140
17785
  ),
17141
17786
  children: [
17142
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
17787
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
17143
17788
  "div",
17144
17789
  {
17145
17790
  className: "flex w-full items-center justify-center py-4",
17146
17791
  style: { background: cardSlot },
17147
- children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
17792
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
17148
17793
  "span",
17149
17794
  {
17150
17795
  className: "inline-flex items-center justify-center whitespace-nowrap font-semibold uppercase leading-none",
@@ -17166,12 +17811,12 @@ function ButtonStylePanel({
17166
17811
  )
17167
17812
  }
17168
17813
  ),
17169
- selected ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
17814
+ selected ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
17170
17815
  "span",
17171
17816
  {
17172
17817
  className: "absolute right-0.5 top-0.5 flex size-5 items-center justify-center rounded-full bg-primary text-primary-foreground",
17173
17818
  "aria-hidden": true,
17174
- children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react17.Check, { className: "size-3", strokeWidth: 3 })
17819
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react18.Check, { className: "size-3", strokeWidth: 3 })
17175
17820
  }
17176
17821
  ) : null
17177
17822
  ]
@@ -17180,9 +17825,9 @@ function ButtonStylePanel({
17180
17825
  );
17181
17826
  }) })
17182
17827
  ] }),
17183
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("section", { className: "flex w-full flex-col gap-2.5", children: [
17184
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("h3", { className: "text-xs font-semibold uppercase leading-4 tracking-[0.6px] text-stone-500 font-sans", children: "Size" }),
17185
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
17828
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("section", { className: "flex w-full flex-col gap-2.5", children: [
17829
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("h3", { className: "text-xs font-semibold uppercase leading-4 tracking-[0.6px] text-stone-500 font-sans", children: "Size" }),
17830
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
17186
17831
  "div",
17187
17832
  {
17188
17833
  className: "flex w-full items-start rounded-lg bg-stone-100 p-1",
@@ -17190,7 +17835,7 @@ function ButtonStylePanel({
17190
17835
  "aria-label": "Size",
17191
17836
  children: BUTTON_SIZE_IDS.map((id) => {
17192
17837
  const selected = id === size;
17193
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
17838
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
17194
17839
  "button",
17195
17840
  {
17196
17841
  type: "button",
@@ -18094,7 +18739,7 @@ function hitTestNavDropSlot(clientX, clientY, draggedHrefKey, draggedEl) {
18094
18739
  }
18095
18740
 
18096
18741
  // src/useNavItemDrag.ts
18097
- var import_react16 = require("react");
18742
+ var import_react17 = require("react");
18098
18743
  function useNavItemDrag({
18099
18744
  isEditMode,
18100
18745
  editContentRef,
@@ -18118,11 +18763,11 @@ function useNavItemDrag({
18118
18763
  getNavigationItemAnchor: getNavigationItemAnchor2,
18119
18764
  isDragHandleDisabled: isDragHandleDisabled2
18120
18765
  }) {
18121
- const navDragRef = (0, import_react16.useRef)(null);
18122
- const [navDropSlots, setNavDropSlots] = (0, import_react16.useState)([]);
18123
- const [activeNavDropIndex, setActiveNavDropIndex] = (0, import_react16.useState)(null);
18124
- const navPointerDragRef = (0, import_react16.useRef)(null);
18125
- const clearNavDragVisuals = (0, import_react16.useCallback)(() => {
18766
+ const navDragRef = (0, import_react17.useRef)(null);
18767
+ const [navDropSlots, setNavDropSlots] = (0, import_react17.useState)([]);
18768
+ const [activeNavDropIndex, setActiveNavDropIndex] = (0, import_react17.useState)(null);
18769
+ const navPointerDragRef = (0, import_react17.useRef)(null);
18770
+ const clearNavDragVisuals = (0, import_react17.useCallback)(() => {
18126
18771
  const session = navDragRef.current;
18127
18772
  const nestedHrefKey = session?.draggedEl?.closest("[data-ohw-nav-children]") != null ? session.hrefKey : null;
18128
18773
  navDragRef.current = null;
@@ -18155,7 +18800,7 @@ function useNavItemDrag({
18155
18800
  document.documentElement.removeAttribute("data-ohw-nav-dragging-root");
18156
18801
  unlockItemDragInteraction();
18157
18802
  }, [setDraggedItemRect, setIsItemDragging, setSiblingHintRects]);
18158
- const refreshNavDragVisuals = (0, import_react16.useCallback)(
18803
+ const refreshNavDragVisuals = (0, import_react17.useCallback)(
18159
18804
  (session, activeSlot, clientX, clientY) => {
18160
18805
  setDraggedItemRect(session.draggedEl.getBoundingClientRect());
18161
18806
  if (typeof clientX === "number" && typeof clientY === "number") {
@@ -18173,13 +18818,13 @@ function useNavItemDrag({
18173
18818
  },
18174
18819
  [setDraggedItemRect, setSiblingHintRects]
18175
18820
  );
18176
- const refreshNavDragVisualsRef = (0, import_react16.useRef)(refreshNavDragVisuals);
18821
+ const refreshNavDragVisualsRef = (0, import_react17.useRef)(refreshNavDragVisuals);
18177
18822
  refreshNavDragVisualsRef.current = refreshNavDragVisuals;
18178
- const commitNavDragRef = (0, import_react16.useRef)(() => {
18823
+ const commitNavDragRef = (0, import_react17.useRef)(() => {
18179
18824
  });
18180
- const beginNavDragRef = (0, import_react16.useRef)(() => {
18825
+ const beginNavDragRef = (0, import_react17.useRef)(() => {
18181
18826
  });
18182
- const beginNavDrag = (0, import_react16.useCallback)(
18827
+ const beginNavDrag = (0, import_react17.useCallback)(
18183
18828
  (session) => {
18184
18829
  const rect = session.draggedEl.getBoundingClientRect();
18185
18830
  session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
@@ -18218,7 +18863,7 @@ function useNavItemDrag({
18218
18863
  ]
18219
18864
  );
18220
18865
  beginNavDragRef.current = beginNavDrag;
18221
- const commitNavDrag = (0, import_react16.useCallback)(
18866
+ const commitNavDrag = (0, import_react17.useCallback)(
18222
18867
  (clientX, clientY) => {
18223
18868
  const session = navDragRef.current;
18224
18869
  if (!session) {
@@ -18297,7 +18942,7 @@ function useNavItemDrag({
18297
18942
  [clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
18298
18943
  );
18299
18944
  commitNavDragRef.current = commitNavDrag;
18300
- const startNavLinkDrag = (0, import_react16.useCallback)(
18945
+ const startNavLinkDrag = (0, import_react17.useCallback)(
18301
18946
  (anchor, clientX, clientY, wasSelected) => {
18302
18947
  if (footerDragRef.current) return false;
18303
18948
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
@@ -18315,7 +18960,7 @@ function useNavItemDrag({
18315
18960
  },
18316
18961
  [beginNavDrag, footerDragRef, isDragHandleDisabled2, isCtaButton]
18317
18962
  );
18318
- const onNavDragOver = (0, import_react16.useCallback)(
18963
+ const onNavDragOver = (0, import_react17.useCallback)(
18319
18964
  (e) => {
18320
18965
  const session = navDragRef.current;
18321
18966
  if (!session) return false;
@@ -18327,7 +18972,7 @@ function useNavItemDrag({
18327
18972
  },
18328
18973
  []
18329
18974
  );
18330
- (0, import_react16.useEffect)(() => {
18975
+ (0, import_react17.useEffect)(() => {
18331
18976
  if (!isEditMode) return;
18332
18977
  const THRESHOLD = 10;
18333
18978
  const resolveWasSelected = (el) => {
@@ -18454,7 +19099,7 @@ function useNavItemDrag({
18454
19099
  setLinkPopover,
18455
19100
  suppressNextClickRef
18456
19101
  ]);
18457
- const armNavPressFromChrome = (0, import_react16.useCallback)(
19102
+ const armNavPressFromChrome = (0, import_react17.useCallback)(
18458
19103
  (selected, clientX, clientY, pointerId) => {
18459
19104
  const hrefKey = selected.getAttribute("data-ohw-href-key");
18460
19105
  if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
@@ -18486,7 +19131,7 @@ function useNavItemDrag({
18486
19131
  }
18487
19132
 
18488
19133
  // src/useSectionDrag.ts
18489
- var import_react17 = require("react");
19134
+ var import_react18 = require("react");
18490
19135
 
18491
19136
  // src/lib/section-dnd.ts
18492
19137
  function isFooterSection(el) {
@@ -18579,21 +19224,21 @@ function useSectionDrag({
18579
19224
  suppressNextClickRef,
18580
19225
  suppressClickUntilRef
18581
19226
  }) {
18582
- const sectionDragRef = (0, import_react17.useRef)(null);
18583
- const [sectionDropSlots, setSectionDropSlots] = (0, import_react17.useState)([]);
18584
- const [activeSectionDropIndex, setActiveSectionDropIndex] = (0, import_react17.useState)(null);
18585
- const [isSectionDragging, setIsSectionDragging] = (0, import_react17.useState)(false);
18586
- const sectionPointerDragRef = (0, import_react17.useRef)(null);
18587
- const autoScrollRafRef = (0, import_react17.useRef)(null);
18588
- const autoScrollDeltaRef = (0, import_react17.useRef)(0);
18589
- const stopAutoScroll = (0, import_react17.useCallback)(() => {
19227
+ const sectionDragRef = (0, import_react18.useRef)(null);
19228
+ const [sectionDropSlots, setSectionDropSlots] = (0, import_react18.useState)([]);
19229
+ const [activeSectionDropIndex, setActiveSectionDropIndex] = (0, import_react18.useState)(null);
19230
+ const [isSectionDragging, setIsSectionDragging] = (0, import_react18.useState)(false);
19231
+ const sectionPointerDragRef = (0, import_react18.useRef)(null);
19232
+ const autoScrollRafRef = (0, import_react18.useRef)(null);
19233
+ const autoScrollDeltaRef = (0, import_react18.useRef)(0);
19234
+ const stopAutoScroll = (0, import_react18.useCallback)(() => {
18590
19235
  if (autoScrollRafRef.current != null) {
18591
19236
  cancelAnimationFrame(autoScrollRafRef.current);
18592
19237
  autoScrollRafRef.current = null;
18593
19238
  }
18594
19239
  autoScrollDeltaRef.current = 0;
18595
19240
  }, []);
18596
- const tickAutoScroll = (0, import_react17.useCallback)(() => {
19241
+ const tickAutoScroll = (0, import_react18.useCallback)(() => {
18597
19242
  if (!sectionDragRef.current) {
18598
19243
  stopAutoScroll();
18599
19244
  return;
@@ -18603,7 +19248,7 @@ function useSectionDrag({
18603
19248
  }
18604
19249
  autoScrollRafRef.current = requestAnimationFrame(tickAutoScroll);
18605
19250
  }, [postToParentRef, stopAutoScroll]);
18606
- const updateAutoScroll = (0, import_react17.useCallback)(
19251
+ const updateAutoScroll = (0, import_react18.useCallback)(
18607
19252
  (clientY) => {
18608
19253
  const clip = getIframeChromeClip(parentScrollRef.current);
18609
19254
  let delta = 0;
@@ -18625,7 +19270,7 @@ function useSectionDrag({
18625
19270
  },
18626
19271
  [parentScrollRef, stopAutoScroll, tickAutoScroll]
18627
19272
  );
18628
- const clearSectionDragVisuals = (0, import_react17.useCallback)(() => {
19273
+ const clearSectionDragVisuals = (0, import_react18.useCallback)(() => {
18629
19274
  sectionDragRef.current?.draggedEl.removeAttribute("data-ohw-section-dragging");
18630
19275
  sectionDragRef.current = null;
18631
19276
  setSectionDropSlots([]);
@@ -18635,7 +19280,7 @@ function useSectionDrag({
18635
19280
  document.documentElement.removeAttribute("data-ohw-section-dragging-root");
18636
19281
  unlockItemDragInteraction();
18637
19282
  }, [stopAutoScroll]);
18638
- const refreshSectionDragVisuals = (0, import_react17.useCallback)(
19283
+ const refreshSectionDragVisuals = (0, import_react18.useCallback)(
18639
19284
  (session, clientX, clientY) => {
18640
19285
  session.lastClientX = clientX;
18641
19286
  session.lastClientY = clientY;
@@ -18649,7 +19294,7 @@ function useSectionDrag({
18649
19294
  },
18650
19295
  [updateAutoScroll]
18651
19296
  );
18652
- const beginSectionDrag = (0, import_react17.useCallback)(
19297
+ const beginSectionDrag = (0, import_react18.useCallback)(
18653
19298
  (session) => {
18654
19299
  sectionDragRef.current = session;
18655
19300
  setIsSectionDragging(true);
@@ -18660,7 +19305,7 @@ function useSectionDrag({
18660
19305
  },
18661
19306
  [refreshSectionDragVisuals]
18662
19307
  );
18663
- const commitSectionDrag = (0, import_react17.useCallback)(() => {
19308
+ const commitSectionDrag = (0, import_react18.useCallback)(() => {
18664
19309
  const session = sectionDragRef.current;
18665
19310
  if (!session) {
18666
19311
  clearSectionDragVisuals();
@@ -18689,7 +19334,7 @@ function useSectionDrag({
18689
19334
  });
18690
19335
  });
18691
19336
  }, [clearSectionDragVisuals, editContentRef, postToParentRef]);
18692
- const startSectionPressDrag = (0, import_react17.useCallback)(
19337
+ const startSectionPressDrag = (0, import_react18.useCallback)(
18693
19338
  (el, clientX, clientY, pointerId) => {
18694
19339
  if (navDragRef.current || footerDragRef.current || sectionDragRef.current) return false;
18695
19340
  const instanceId = instanceIdOf(el);
@@ -18706,7 +19351,7 @@ function useSectionDrag({
18706
19351
  },
18707
19352
  [footerDragRef, navDragRef]
18708
19353
  );
18709
- (0, import_react17.useEffect)(() => {
19354
+ (0, import_react18.useEffect)(() => {
18710
19355
  if (!isEditMode) return;
18711
19356
  const onPointerDown = (e) => {
18712
19357
  if (e.button !== 0) return;
@@ -18811,8 +19456,8 @@ function useSectionDrag({
18811
19456
  }
18812
19457
 
18813
19458
  // src/ui/footer-container-chrome.tsx
18814
- var import_lucide_react18 = require("lucide-react");
18815
- var import_jsx_runtime32 = require("react/jsx-runtime");
19459
+ var import_lucide_react19 = require("lucide-react");
19460
+ var import_jsx_runtime33 = require("react/jsx-runtime");
18816
19461
  function FooterContainerChrome({
18817
19462
  rect,
18818
19463
  onAdd,
@@ -18820,7 +19465,7 @@ function FooterContainerChrome({
18820
19465
  }) {
18821
19466
  const chromeGap = 6;
18822
19467
  const buttonMargin = 7;
18823
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
19468
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
18824
19469
  "div",
18825
19470
  {
18826
19471
  "data-ohw-footer-container-chrome": "",
@@ -18832,8 +19477,8 @@ function FooterContainerChrome({
18832
19477
  width: rect.width + chromeGap * 2,
18833
19478
  height: rect.height + chromeGap * 2
18834
19479
  },
18835
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Tooltip, { children: [
18836
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
19480
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Tooltip, { children: [
19481
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
18837
19482
  "button",
18838
19483
  {
18839
19484
  type: "button",
@@ -18852,17 +19497,17 @@ function FooterContainerChrome({
18852
19497
  if (addDisabled) return;
18853
19498
  onAdd();
18854
19499
  },
18855
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react18.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
19500
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react19.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
18856
19501
  }
18857
19502
  ) }),
18858
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
19503
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
18859
19504
  ] })
18860
19505
  }
18861
19506
  ) });
18862
19507
  }
18863
19508
 
18864
19509
  // src/lib/carousel.ts
18865
- var import_react18 = require("react");
19510
+ var import_react19 = require("react");
18866
19511
  var CAROUSEL_ATTR = "data-ohw-carousel";
18867
19512
  var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
18868
19513
  var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
@@ -18924,8 +19569,8 @@ function applyCarouselNode(key, val) {
18924
19569
  return true;
18925
19570
  }
18926
19571
  function useOhwCarousel(key, initial) {
18927
- const [images, setImages] = (0, import_react18.useState)(initial);
18928
- (0, import_react18.useEffect)(() => {
19572
+ const [images, setImages] = (0, import_react19.useState)(initial);
19573
+ (0, import_react19.useEffect)(() => {
18929
19574
  const el = document.querySelector(
18930
19575
  `[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
18931
19576
  );
@@ -19344,14 +19989,14 @@ function deleteSelectedNavFooterItem(deps) {
19344
19989
  }
19345
19990
 
19346
19991
  // src/ui/navbar-container-chrome.tsx
19347
- var import_lucide_react19 = require("lucide-react");
19348
- var import_jsx_runtime33 = require("react/jsx-runtime");
19992
+ var import_lucide_react20 = require("lucide-react");
19993
+ var import_jsx_runtime34 = require("react/jsx-runtime");
19349
19994
  function NavbarContainerChrome({
19350
19995
  rect,
19351
19996
  onAdd
19352
19997
  }) {
19353
19998
  const chromeGap = 6;
19354
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
19999
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19355
20000
  "div",
19356
20001
  {
19357
20002
  "data-ohw-navbar-container-chrome": "",
@@ -19363,7 +20008,7 @@ function NavbarContainerChrome({
19363
20008
  width: rect.width + chromeGap * 2,
19364
20009
  height: rect.height + chromeGap * 2
19365
20010
  },
19366
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20011
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19367
20012
  "button",
19368
20013
  {
19369
20014
  type: "button",
@@ -19380,7 +20025,7 @@ function NavbarContainerChrome({
19380
20025
  e.stopPropagation();
19381
20026
  onAdd();
19382
20027
  },
19383
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react19.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
20028
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react20.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
19384
20029
  }
19385
20030
  )
19386
20031
  }
@@ -19389,7 +20034,7 @@ function NavbarContainerChrome({
19389
20034
 
19390
20035
  // src/ui/drop-indicator.tsx
19391
20036
  var React11 = __toESM(require("react"), 1);
19392
- var import_jsx_runtime34 = require("react/jsx-runtime");
20037
+ var import_jsx_runtime35 = require("react/jsx-runtime");
19393
20038
  var dropIndicatorVariants = cva(
19394
20039
  "ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
19395
20040
  {
@@ -19413,7 +20058,7 @@ var dropIndicatorVariants = cva(
19413
20058
  );
19414
20059
  var DropIndicator = React11.forwardRef(
19415
20060
  ({ className, direction, state, ...props }, ref) => {
19416
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
20061
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
19417
20062
  "div",
19418
20063
  {
19419
20064
  ref,
@@ -19430,7 +20075,7 @@ var DropIndicator = React11.forwardRef(
19430
20075
  DropIndicator.displayName = "DropIndicator";
19431
20076
 
19432
20077
  // src/ui/badge.tsx
19433
- var import_jsx_runtime35 = require("react/jsx-runtime");
20078
+ var import_jsx_runtime36 = require("react/jsx-runtime");
19434
20079
  var badgeVariants = cva(
19435
20080
  "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",
19436
20081
  {
@@ -19448,13 +20093,13 @@ var badgeVariants = cva(
19448
20093
  }
19449
20094
  );
19450
20095
  function Badge({ className, variant, ...props }) {
19451
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
20096
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
19452
20097
  }
19453
20098
 
19454
20099
  // src/OhhwellsBridge.tsx
19455
- var import_lucide_react20 = require("lucide-react");
19456
- var import_jsx_runtime36 = require("react/jsx-runtime");
19457
- var PRIMARY5 = "#0885FE";
20100
+ var import_lucide_react21 = require("lucide-react");
20101
+ var import_jsx_runtime37 = require("react/jsx-runtime");
20102
+ var PRIMARY6 = "#0885FE";
19458
20103
  var IMAGE_FADE_MS = 300;
19459
20104
  var MEDIA_SETTLE_TIMEOUT_MS = 2500;
19460
20105
  function runOpacityFade(el, onDone) {
@@ -19575,7 +20220,7 @@ function duplicateSchedulingWidget(instanceId, scheduleId) {
19575
20220
  schedulingRoots.set(container, root);
19576
20221
  (0, import_react_dom4.flushSync)(() => {
19577
20222
  root.render(
19578
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
20223
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
19579
20224
  SchedulingWidget,
19580
20225
  {
19581
20226
  notifyOnConnect: false,
@@ -19618,21 +20263,10 @@ function parseSchedulingInsertAfter(insertAfter) {
19618
20263
  insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
19619
20264
  };
19620
20265
  }
19621
- function resolveSchedulingInsert(insertAfter, explicitInsertBefore) {
19622
- const parsed = parseSchedulingInsertAfter(insertAfter);
19623
- const insertBefore = explicitInsertBefore ?? parsed.insertBefore;
19624
- const effectiveInsertAfter = insertBefore && parsed.insertBefore === null ? `${insertAfter}${INSERT_BEFORE_MARKER}${insertBefore}` : insertAfter;
19625
- return { effectiveInsertAfter, insertBefore };
19626
- }
19627
- function getSchedulingMountPoint(insertAfter) {
19628
- const { anchor } = parseSchedulingInsertAfter(insertAfter);
19629
- let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
19630
- if (!anchorEl && anchor === "scheduling") {
19631
- const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
19632
- anchorEl = widgets.at(-1) ?? null;
19633
- }
19634
- if (!anchorEl) return null;
19635
- return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
20266
+ function resolveEntryAnchor(entry) {
20267
+ if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
20268
+ const parsed = parseSchedulingInsertAfter(entry.insertAfter);
20269
+ return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
19636
20270
  }
19637
20271
  function schedulingMountDepth(insertAfter) {
19638
20272
  if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
@@ -19649,8 +20283,7 @@ function getPageSchedulingEntries(raw) {
19649
20283
  }
19650
20284
  }
19651
20285
  function isSchedulingWidgetMissing(entry) {
19652
- const { effectiveInsertAfter } = resolveSchedulingInsert(entry.insertAfter);
19653
- return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
20286
+ return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
19654
20287
  }
19655
20288
  function hasMissingSchedulingWidgets(entries) {
19656
20289
  return entries.some(isSchedulingWidgetMissing);
@@ -19688,17 +20321,18 @@ function initSectionsFromContent(content, removeExisting = false, currentPath =
19688
20321
  } catch {
19689
20322
  }
19690
20323
  }
19691
- function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId, explicitInsertBefore) {
19692
- const { effectiveInsertAfter, insertBefore } = resolveSchedulingInsert(insertAfter, explicitInsertBefore);
19693
- const sectionId = schedulingSectionId(effectiveInsertAfter);
20324
+ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
20325
+ const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
20326
+ const sectionId = schedulingSectionId(widgetId);
19694
20327
  if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
19695
- const mountPoint = getSchedulingMountPoint(effectiveInsertAfter);
19696
- if (!mountPoint) return false;
20328
+ const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
20329
+ if (!anchorEl) return false;
20330
+ const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
19697
20331
  const container = document.createElement("div");
19698
20332
  container.dataset.ohwSectionContainer = "scheduling";
19699
20333
  container.dataset.ohwInstance = sectionId;
19700
- if (insertBefore) {
19701
- const beforeAnchor = document.querySelector(`[data-ohw-section="${insertBefore}"]`);
20334
+ if (beforeId) {
20335
+ const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
19702
20336
  const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
19703
20337
  if (!beforePoint) return false;
19704
20338
  beforePoint.insertAdjacentElement("beforebegin", container);
@@ -19709,20 +20343,26 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
19709
20343
  }
19710
20344
  tail.insertAdjacentElement("afterend", container);
19711
20345
  }
19712
- const root = (0, import_client2.createRoot)(container);
19713
- schedulingRoots.set(container, root);
19714
- (0, import_react_dom4.flushSync)(() => {
19715
- root.render(
19716
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
19717
- SchedulingWidget,
19718
- {
19719
- notifyOnConnect,
19720
- initialScheduleId: scheduleId,
19721
- insertAfter: effectiveInsertAfter
19722
- }
19723
- )
19724
- );
19725
- });
20346
+ try {
20347
+ const root = (0, import_client2.createRoot)(container);
20348
+ schedulingRoots.set(container, root);
20349
+ (0, import_react_dom4.flushSync)(() => {
20350
+ root.render(
20351
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20352
+ SchedulingWidget,
20353
+ {
20354
+ notifyOnConnect,
20355
+ initialScheduleId: scheduleId,
20356
+ insertAfter: widgetId
20357
+ }
20358
+ )
20359
+ );
20360
+ });
20361
+ } catch (err) {
20362
+ console.error("[ow:scheduling] render threw", err);
20363
+ container.remove();
20364
+ return false;
20365
+ }
19726
20366
  const tracker = getSectionsTracker();
19727
20367
  let sections = [];
19728
20368
  try {
@@ -19730,10 +20370,12 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
19730
20370
  } catch {
19731
20371
  }
19732
20372
  const inEditor = typeof window !== "undefined" && window.self !== window.top;
19733
- if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === effectiveInsertAfter)) {
20373
+ if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
19734
20374
  sections.push({
19735
20375
  type: "scheduling",
19736
- insertAfter: effectiveInsertAfter,
20376
+ insertAfter: widgetId,
20377
+ anchorId,
20378
+ beforeId: beforeId ?? null,
19737
20379
  pagePath: window.location.pathname,
19738
20380
  ...scheduleId ? { scheduleId } : {}
19739
20381
  });
@@ -19747,7 +20389,8 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
19747
20389
  for (let i = pending.length - 1; i >= 0; i--) {
19748
20390
  const entry = pending[i];
19749
20391
  const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
19750
- if (mountSchedulingWidget(entry.insertAfter, shouldNotify, entry.scheduleId ?? null)) {
20392
+ const { anchorId, beforeId } = resolveEntryAnchor(entry);
20393
+ if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
19751
20394
  pending.splice(i, 1);
19752
20395
  }
19753
20396
  }
@@ -20214,7 +20857,7 @@ function getNavigationSelectionParent(el) {
20214
20857
  if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
20215
20858
  return getFooterLinksContainer();
20216
20859
  }
20217
- if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
20860
+ 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)) {
20218
20861
  return getNavigationRoot(el);
20219
20862
  }
20220
20863
  return null;
@@ -20436,13 +21079,12 @@ var ICONS = {
20436
21079
  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"/>',
20437
21080
  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"/>'
20438
21081
  };
20439
- var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
20440
21082
  var SELECTION_CHROME_GAP2 = 4;
20441
21083
  var TOOLBAR_STROKE_GAP2 = 4;
20442
21084
  var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
20443
21085
  var HOVER_STROKE_WIDTH = 1.5;
20444
21086
  var TEXT_HOVER_SIDE_PAD = 4;
20445
- var CHROME_PRIMARY = `var(--ohw-primary, ${PRIMARY5})`;
21087
+ var CHROME_PRIMARY = `var(--ohw-primary, ${PRIMARY6})`;
20446
21088
  var TOOLBAR_GROUPS = [
20447
21089
  [
20448
21090
  { cmd: "bold", title: "Bold" },
@@ -20468,7 +21110,7 @@ function EditGlowChrome({
20468
21110
  hideHandle = false
20469
21111
  }) {
20470
21112
  const GAP = SELECTION_CHROME_GAP2;
20471
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
21113
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
20472
21114
  "div",
20473
21115
  {
20474
21116
  ref: elRef,
@@ -20483,7 +21125,7 @@ function EditGlowChrome({
20483
21125
  zIndex: 2147483646
20484
21126
  },
20485
21127
  children: [
20486
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21128
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20487
21129
  "div",
20488
21130
  {
20489
21131
  style: {
@@ -20497,7 +21139,7 @@ function EditGlowChrome({
20497
21139
  }
20498
21140
  }
20499
21141
  ),
20500
- reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21142
+ reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20501
21143
  "div",
20502
21144
  {
20503
21145
  "data-ohw-drag-handle-container": "",
@@ -20509,7 +21151,7 @@ function EditGlowChrome({
20509
21151
  transform: "translate(calc(-100% - 7px), -50%)",
20510
21152
  pointerEvents: dragDisabled ? "none" : "auto"
20511
21153
  },
20512
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21154
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20513
21155
  DragHandle,
20514
21156
  {
20515
21157
  "aria-label": `Reorder ${reorderHrefKey}`,
@@ -20686,9 +21328,9 @@ function FloatingToolbar({
20686
21328
  showEditLink,
20687
21329
  onEditLink
20688
21330
  }) {
20689
- const localRef = import_react19.default.useRef(null);
20690
- const [measuredW, setMeasuredW] = import_react19.default.useState(330);
20691
- const setRefs = import_react19.default.useCallback(
21331
+ const localRef = import_react20.default.useRef(null);
21332
+ const [measuredW, setMeasuredW] = import_react20.default.useState(330);
21333
+ const setRefs = import_react20.default.useCallback(
20692
21334
  (node) => {
20693
21335
  localRef.current = node;
20694
21336
  if (typeof elRef === "function") elRef(node);
@@ -20700,7 +21342,7 @@ function FloatingToolbar({
20700
21342
  },
20701
21343
  [elRef]
20702
21344
  );
20703
- import_react19.default.useLayoutEffect(() => {
21345
+ import_react20.default.useLayoutEffect(() => {
20704
21346
  const node = localRef.current;
20705
21347
  if (!node) return;
20706
21348
  const update = () => {
@@ -20713,7 +21355,7 @@ function FloatingToolbar({
20713
21355
  return () => ro.disconnect();
20714
21356
  }, [showEditLink, activeCommands]);
20715
21357
  const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
20716
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21358
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20717
21359
  "div",
20718
21360
  {
20719
21361
  ref: setRefs,
@@ -20725,12 +21367,12 @@ function FloatingToolbar({
20725
21367
  zIndex: 2147483647,
20726
21368
  pointerEvents: "auto"
20727
21369
  },
20728
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(CustomToolbar, { children: [
20729
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react19.default.Fragment, { children: [
20730
- gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CustomToolbarDivider, {}),
21370
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(CustomToolbar, { children: [
21371
+ TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_react20.default.Fragment, { children: [
21372
+ gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(CustomToolbarDivider, {}),
20731
21373
  btns.map((btn) => {
20732
21374
  const isActive = activeCommands.has(btn.cmd);
20733
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21375
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20734
21376
  CustomToolbarButton,
20735
21377
  {
20736
21378
  title: btn.title,
@@ -20739,7 +21381,7 @@ function FloatingToolbar({
20739
21381
  e.preventDefault();
20740
21382
  onCommand(btn.cmd);
20741
21383
  },
20742
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21384
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20743
21385
  "svg",
20744
21386
  {
20745
21387
  width: "16",
@@ -20760,7 +21402,7 @@ function FloatingToolbar({
20760
21402
  );
20761
21403
  })
20762
21404
  ] }, gi)),
20763
- showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21405
+ showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20764
21406
  CustomToolbarButton,
20765
21407
  {
20766
21408
  type: "button",
@@ -20774,7 +21416,7 @@ function FloatingToolbar({
20774
21416
  e.preventDefault();
20775
21417
  e.stopPropagation();
20776
21418
  },
20777
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Link, { className: "size-4 shrink-0", "aria-hidden": true })
21419
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react21.Link, { className: "size-4 shrink-0", "aria-hidden": true })
20778
21420
  }
20779
21421
  ) : null
20780
21422
  ] })
@@ -20791,7 +21433,7 @@ function StateToggle({
20791
21433
  states,
20792
21434
  onStateChange
20793
21435
  }) {
20794
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21436
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20795
21437
  ToggleGroup,
20796
21438
  {
20797
21439
  "data-ohw-state-toggle": "",
@@ -20805,11 +21447,12 @@ function StateToggle({
20805
21447
  left: rect.right - 8,
20806
21448
  transform: "translateX(-100%)"
20807
21449
  },
20808
- children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
21450
+ children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
20809
21451
  }
20810
21452
  );
20811
21453
  }
20812
21454
  var contentCache = /* @__PURE__ */ new Map();
21455
+ var fetchedContentPaths = /* @__PURE__ */ new Set();
20813
21456
  var brandingCache = /* @__PURE__ */ new Map();
20814
21457
  var OHW_LOADER_STYLE = {
20815
21458
  position: "fixed",
@@ -20821,9 +21464,9 @@ var OHW_LOADER_STYLE = {
20821
21464
  justifyContent: "center"
20822
21465
  };
20823
21466
  function OhwLoaderSpinner() {
20824
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", "aria-hidden": true, children: [
20825
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("circle", { cx: "14", cy: "14", r: "11", stroke: "#E7E5E4", strokeWidth: "3" }),
20826
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21467
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", "aria-hidden": true, children: [
21468
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("circle", { cx: "14", cy: "14", r: "11", stroke: "#E7E5E4", strokeWidth: "3" }),
21469
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20827
21470
  "circle",
20828
21471
  {
20829
21472
  cx: "14",
@@ -20833,7 +21476,7 @@ function OhwLoaderSpinner() {
20833
21476
  strokeWidth: "3",
20834
21477
  strokeDasharray: "17 52",
20835
21478
  strokeLinecap: "round",
20836
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21479
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20837
21480
  "animateTransform",
20838
21481
  {
20839
21482
  attributeName: "transform",
@@ -20849,7 +21492,7 @@ function OhwLoaderSpinner() {
20849
21492
  ] });
20850
21493
  }
20851
21494
  function OhwBrandMark() {
20852
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
21495
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
20853
21496
  "svg",
20854
21497
  {
20855
21498
  width: "16",
@@ -20860,7 +21503,7 @@ function OhwBrandMark() {
20860
21503
  style: { display: "block", flexShrink: 0 },
20861
21504
  xmlns: "http://www.w3.org/2000/svg",
20862
21505
  children: [
20863
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21506
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20864
21507
  "mask",
20865
21508
  {
20866
21509
  id: "ohw-badge-mark",
@@ -20870,15 +21513,15 @@ function OhwBrandMark() {
20870
21513
  y: "0",
20871
21514
  width: "48",
20872
21515
  height: "48",
20873
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("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" })
21516
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("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" })
20874
21517
  }
20875
21518
  ),
20876
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("g", { mask: "url(#ohw-badge-mark)", children: [
20877
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("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" }),
20878
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("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" }),
20879
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("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" }),
20880
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("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" }),
20881
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("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" })
21519
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("g", { mask: "url(#ohw-badge-mark)", children: [
21520
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("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" }),
21521
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("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" }),
21522
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("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" }),
21523
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("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" }),
21524
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("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" })
20882
21525
  ] })
20883
21526
  ]
20884
21527
  }
@@ -20915,7 +21558,7 @@ var OHW_BADGE_LABEL_STYLE = {
20915
21558
  whiteSpace: "nowrap"
20916
21559
  };
20917
21560
  function MadeWithOhhWells() {
20918
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
21561
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
20919
21562
  "a",
20920
21563
  {
20921
21564
  href: "https://ohhwells.com",
@@ -20925,8 +21568,8 @@ function MadeWithOhhWells() {
20925
21568
  "data-ohw-badge": "",
20926
21569
  style: OHW_BADGE_STYLE,
20927
21570
  children: [
20928
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(OhwBrandMark, {}),
20929
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { style: OHW_BADGE_LABEL_STYLE, children: "Made with OhhWells" })
21571
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(OhwBrandMark, {}),
21572
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { style: OHW_BADGE_LABEL_STYLE, children: "Made with OhhWells" })
20930
21573
  ]
20931
21574
  }
20932
21575
  );
@@ -20972,8 +21615,8 @@ function OhhwellsBridge() {
20972
21615
  const router = (0, import_navigation3.useRouter)();
20973
21616
  const searchParams = (0, import_navigation3.useSearchParams)();
20974
21617
  const isEditMode = isEditSessionActive();
20975
- const [bridgeRoot, setBridgeRoot] = (0, import_react19.useState)(null);
20976
- (0, import_react19.useEffect)(() => {
21618
+ const [bridgeRoot, setBridgeRoot] = (0, import_react20.useState)(null);
21619
+ (0, import_react20.useEffect)(() => {
20977
21620
  const figtreeFontId = "ohw-figtree-font";
20978
21621
  if (!document.getElementById(figtreeFontId)) {
20979
21622
  const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
@@ -20999,8 +21642,8 @@ function OhhwellsBridge() {
20999
21642
  };
21000
21643
  }, []);
21001
21644
  const subdomainFromQuery = searchParams.get("subdomain");
21002
- const [subdomain, setSubdomain] = (0, import_react19.useState)(() => resolveSubdomain(subdomainFromQuery));
21003
- (0, import_react19.useLayoutEffect)(() => {
21645
+ const [subdomain, setSubdomain] = (0, import_react20.useState)(() => resolveSubdomain(subdomainFromQuery));
21646
+ (0, import_react20.useLayoutEffect)(() => {
21004
21647
  const next = resolveSubdomain(subdomainFromQuery);
21005
21648
  if (next !== subdomain) setSubdomain(next);
21006
21649
  if (next) return;
@@ -21012,54 +21655,55 @@ function OhhwellsBridge() {
21012
21655
  }, 0);
21013
21656
  return () => window.clearTimeout(t);
21014
21657
  }, [subdomainFromQuery, subdomain]);
21015
- (0, import_react19.useEffect)(() => {
21658
+ (0, import_react20.useEffect)(() => {
21016
21659
  if (!subdomainFromQuery || typeof window === "undefined") return;
21017
21660
  const url = new URL(window.location.href);
21018
21661
  if (!url.searchParams.has("subdomain")) return;
21662
+ if (!resolveSubdomain(null)) return;
21019
21663
  url.searchParams.delete("subdomain");
21020
21664
  window.history.replaceState(null, "", url.pathname + url.search + url.hash);
21021
21665
  }, [subdomainFromQuery]);
21022
21666
  useLinkHrefGuardian(pathname, subdomain, isEditMode);
21023
21667
  useSavedLinkNavigation(isEditMode);
21024
- const postToParent2 = (0, import_react19.useCallback)((data) => {
21668
+ const postToParent2 = (0, import_react20.useCallback)((data) => {
21025
21669
  if (typeof window !== "undefined" && window.parent !== window) {
21026
21670
  window.parent.postMessage(data, "*");
21027
21671
  }
21028
21672
  }, []);
21029
- const [fetchState, setFetchState] = (0, import_react19.useState)("idle");
21030
- const [showBranding, setShowBranding] = (0, import_react19.useState)(false);
21031
- const autoSaveTimers = (0, import_react19.useRef)(/* @__PURE__ */ new Map());
21032
- const activeElRef = (0, import_react19.useRef)(null);
21033
- const pointerHeldRef = (0, import_react19.useRef)(false);
21034
- const selectedElRef = (0, import_react19.useRef)(null);
21035
- const selectedHrefKeyRef = (0, import_react19.useRef)(null);
21036
- const selectedFooterColAttrRef = (0, import_react19.useRef)(null);
21037
- const originalContentRef = (0, import_react19.useRef)(null);
21038
- const activeStateElRef = (0, import_react19.useRef)(null);
21039
- const parentScrollRef = (0, import_react19.useRef)(null);
21040
- const visibleViewportRef = (0, import_react19.useRef)(null);
21041
- const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react19.useState)(null);
21042
- const attachVisibleViewport = (0, import_react19.useCallback)((node) => {
21673
+ const [fetchState, setFetchState] = (0, import_react20.useState)("idle");
21674
+ const [showBranding, setShowBranding] = (0, import_react20.useState)(false);
21675
+ const autoSaveTimers = (0, import_react20.useRef)(/* @__PURE__ */ new Map());
21676
+ const activeElRef = (0, import_react20.useRef)(null);
21677
+ const pointerHeldRef = (0, import_react20.useRef)(false);
21678
+ const selectedElRef = (0, import_react20.useRef)(null);
21679
+ const selectedHrefKeyRef = (0, import_react20.useRef)(null);
21680
+ const selectedFooterColAttrRef = (0, import_react20.useRef)(null);
21681
+ const originalContentRef = (0, import_react20.useRef)(null);
21682
+ const activeStateElRef = (0, import_react20.useRef)(null);
21683
+ const parentScrollRef = (0, import_react20.useRef)(null);
21684
+ const visibleViewportRef = (0, import_react20.useRef)(null);
21685
+ const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react20.useState)(null);
21686
+ const attachVisibleViewport = (0, import_react20.useCallback)((node) => {
21043
21687
  visibleViewportRef.current = node;
21044
21688
  setDialogPortalContainer(node);
21045
21689
  if (node) applyVisibleViewport(node, parentScrollRef.current);
21046
21690
  }, []);
21047
- const toolbarElRef = (0, import_react19.useRef)(null);
21048
- const glowElRef = (0, import_react19.useRef)(null);
21049
- const hoveredImageRef = (0, import_react19.useRef)(null);
21050
- const hoveredImageHasTextOverlapRef = (0, import_react19.useRef)(false);
21051
- const dragOverElRef = (0, import_react19.useRef)(null);
21052
- const [mediaHover, setMediaHover] = (0, import_react19.useState)(null);
21053
- const [selectedAiSectionId, setSelectedAiSectionId] = (0, import_react19.useState)(null);
21054
- const selectedAiSectionIdRef = (0, import_react19.useRef)(null);
21055
- const handleAiSectionSelectionChange = (0, import_react19.useCallback)((id) => {
21691
+ const toolbarElRef = (0, import_react20.useRef)(null);
21692
+ const glowElRef = (0, import_react20.useRef)(null);
21693
+ const hoveredImageRef = (0, import_react20.useRef)(null);
21694
+ const hoveredImageHasTextOverlapRef = (0, import_react20.useRef)(false);
21695
+ const dragOverElRef = (0, import_react20.useRef)(null);
21696
+ const [mediaHover, setMediaHover] = (0, import_react20.useState)(null);
21697
+ const [selectedAiSectionId, setSelectedAiSectionId] = (0, import_react20.useState)(null);
21698
+ const selectedAiSectionIdRef = (0, import_react20.useRef)(null);
21699
+ const handleAiSectionSelectionChange = (0, import_react20.useCallback)((id) => {
21056
21700
  selectedAiSectionIdRef.current = id;
21057
21701
  setSelectedAiSectionId(id);
21058
21702
  }, []);
21059
- const [selectedMedia, setSelectedMedia] = (0, import_react19.useState)(null);
21060
- const selectedMediaElRef = (0, import_react19.useRef)(null);
21061
- const mediaKeyDropTokenRef = (0, import_react19.useRef)(0);
21062
- const clearMediaSelection = (0, import_react19.useCallback)(() => {
21703
+ const [selectedMedia, setSelectedMedia] = (0, import_react20.useState)(null);
21704
+ const selectedMediaElRef = (0, import_react20.useRef)(null);
21705
+ const mediaKeyDropTokenRef = (0, import_react20.useRef)(0);
21706
+ const clearMediaSelection = (0, import_react20.useCallback)(() => {
21063
21707
  const prev = selectedMediaElRef.current;
21064
21708
  selectedMediaElRef.current = null;
21065
21709
  setSelectedMedia(null);
@@ -21084,9 +21728,9 @@ function OhhwellsBridge() {
21084
21728
  window.postMessage({ type: "ow:media-key-drop", token }, "*");
21085
21729
  }
21086
21730
  }, []);
21087
- const clearMediaSelectionRef = (0, import_react19.useRef)(clearMediaSelection);
21731
+ const clearMediaSelectionRef = (0, import_react20.useRef)(clearMediaSelection);
21088
21732
  clearMediaSelectionRef.current = clearMediaSelection;
21089
- const selectMediaElement = (0, import_react19.useCallback)((el) => {
21733
+ const selectMediaElement = (0, import_react20.useCallback)((el) => {
21090
21734
  const r2 = el.getBoundingClientRect();
21091
21735
  const video = el.dataset.ohwEditable === "video" ? el.querySelector("video") : null;
21092
21736
  selectedMediaElRef.current = el;
@@ -21110,9 +21754,9 @@ function OhhwellsBridge() {
21110
21754
  keyLabel: el.dataset.ohwEditable === "video" ? "Video" : el.dataset.ohwEditable === "bg-image" ? "Background" : "Image"
21111
21755
  });
21112
21756
  }, []);
21113
- const selectMediaElementRef = (0, import_react19.useRef)(selectMediaElement);
21757
+ const selectMediaElementRef = (0, import_react20.useRef)(selectMediaElement);
21114
21758
  selectMediaElementRef.current = selectMediaElement;
21115
- (0, import_react19.useEffect)(() => {
21759
+ (0, import_react20.useEffect)(() => {
21116
21760
  if (!selectedMedia) return;
21117
21761
  const update = () => {
21118
21762
  const el = selectedMediaElRef.current;
@@ -21132,54 +21776,54 @@ function OhhwellsBridge() {
21132
21776
  window.removeEventListener("resize", update);
21133
21777
  };
21134
21778
  }, [selectedMedia !== null]);
21135
- const [carouselHover, setCarouselHover] = (0, import_react19.useState)(null);
21136
- const [uploadingRects, setUploadingRects] = (0, import_react19.useState)({});
21137
- const hoveredGapRef = (0, import_react19.useRef)(null);
21138
- const imageUnhoverTimerRef = (0, import_react19.useRef)(null);
21139
- const imageShowTimerRef = (0, import_react19.useRef)(null);
21140
- const editStylesRef = (0, import_react19.useRef)(null);
21141
- const activateRef = (0, import_react19.useRef)(() => {
21779
+ const [carouselHover, setCarouselHover] = (0, import_react20.useState)(null);
21780
+ const [uploadingRects, setUploadingRects] = (0, import_react20.useState)({});
21781
+ const hoveredGapRef = (0, import_react20.useRef)(null);
21782
+ const imageUnhoverTimerRef = (0, import_react20.useRef)(null);
21783
+ const imageShowTimerRef = (0, import_react20.useRef)(null);
21784
+ const editStylesRef = (0, import_react20.useRef)(null);
21785
+ const activateRef = (0, import_react20.useRef)(() => {
21142
21786
  });
21143
- const deactivateRef = (0, import_react19.useRef)(() => {
21787
+ const deactivateRef = (0, import_react20.useRef)(() => {
21144
21788
  });
21145
- const selectRef = (0, import_react19.useRef)(() => {
21789
+ const selectRef = (0, import_react20.useRef)(() => {
21146
21790
  });
21147
- const selectFrameRef = (0, import_react19.useRef)(() => {
21791
+ const selectFrameRef = (0, import_react20.useRef)(() => {
21148
21792
  });
21149
- const selectLogoRef = (0, import_react19.useRef)(() => {
21793
+ const selectLogoRef = (0, import_react20.useRef)(() => {
21150
21794
  });
21151
- const openLogoSizePanelRef = (0, import_react19.useRef)(() => {
21795
+ const openLogoSizePanelRef = (0, import_react20.useRef)(() => {
21152
21796
  });
21153
- const deselectRef = (0, import_react19.useRef)(() => {
21797
+ const deselectRef = (0, import_react20.useRef)(() => {
21154
21798
  });
21155
- const closeFloatingPanelOnlyRef = (0, import_react19.useRef)(() => {
21799
+ const closeFloatingPanelOnlyRef = (0, import_react20.useRef)(() => {
21156
21800
  });
21157
- const reselectNavigationItemRef = (0, import_react19.useRef)(() => {
21801
+ const reselectNavigationItemRef = (0, import_react20.useRef)(() => {
21158
21802
  });
21159
- const commitNavigationTextEditRef = (0, import_react19.useRef)(() => {
21803
+ const commitNavigationTextEditRef = (0, import_react20.useRef)(() => {
21160
21804
  });
21161
- const handleDeleteSelectedRef = (0, import_react19.useRef)(() => false);
21162
- const runPendingDeleteUndoRef = (0, import_react19.useRef)(() => false);
21163
- const isFooterFrameSelectionRef = (0, import_react19.useRef)(false);
21164
- const refreshActiveCommandsRef = (0, import_react19.useRef)(() => {
21805
+ const handleDeleteSelectedRef = (0, import_react20.useRef)(() => false);
21806
+ const runPendingDeleteUndoRef = (0, import_react20.useRef)(() => false);
21807
+ const isFooterFrameSelectionRef = (0, import_react20.useRef)(false);
21808
+ const refreshActiveCommandsRef = (0, import_react20.useRef)(() => {
21165
21809
  });
21166
- const postToParentRef = (0, import_react19.useRef)(postToParent2);
21810
+ const postToParentRef = (0, import_react20.useRef)(postToParent2);
21167
21811
  postToParentRef.current = postToParent2;
21168
- const aiSectionApiRef = (0, import_react19.useRef)(null);
21169
- const sectionsLoadedRef = (0, import_react19.useRef)(false);
21170
- const pendingScheduleConfigRequests = (0, import_react19.useRef)([]);
21171
- const [toolbarRect, setToolbarRect] = (0, import_react19.useState)(null);
21172
- const [formPickRect, setFormPickRect] = (0, import_react19.useState)(null);
21173
- const formPickElRef = (0, import_react19.useRef)(null);
21174
- const [formViewState, setFormViewStateUi] = (0, import_react19.useState)("default");
21175
- const [formPickCount, setFormPickCount] = (0, import_react19.useState)(null);
21176
- const [formHoverRect, setFormHoverRect] = (0, import_react19.useState)(null);
21177
- const formHoverElRef = (0, import_react19.useRef)(null);
21178
- const [fieldPickRect, setFieldPickRect] = (0, import_react19.useState)(null);
21179
- const fieldPickElRef = (0, import_react19.useRef)(null);
21180
- const [fieldPickState, setFieldPickState] = (0, import_react19.useState)(null);
21181
- const [fieldTypePickerOpen, setFieldTypePickerOpen] = (0, import_react19.useState)(false);
21182
- const clearFormPick = (0, import_react19.useCallback)(() => {
21812
+ const aiSectionApiRef = (0, import_react20.useRef)(null);
21813
+ const sectionsLoadedRef = (0, import_react20.useRef)(false);
21814
+ const pendingScheduleConfigRequests = (0, import_react20.useRef)([]);
21815
+ const [toolbarRect, setToolbarRect] = (0, import_react20.useState)(null);
21816
+ const [formPickRect, setFormPickRect] = (0, import_react20.useState)(null);
21817
+ const formPickElRef = (0, import_react20.useRef)(null);
21818
+ const [formViewState, setFormViewStateUi] = (0, import_react20.useState)("default");
21819
+ const [formPickCount, setFormPickCount] = (0, import_react20.useState)(null);
21820
+ const [formHoverRect, setFormHoverRect] = (0, import_react20.useState)(null);
21821
+ const formHoverElRef = (0, import_react20.useRef)(null);
21822
+ const [fieldPickRect, setFieldPickRect] = (0, import_react20.useState)(null);
21823
+ const fieldPickElRef = (0, import_react20.useRef)(null);
21824
+ const [fieldPickState, setFieldPickState] = (0, import_react20.useState)(null);
21825
+ const [fieldTypePickerOpen, setFieldTypePickerOpen] = (0, import_react20.useState)(false);
21826
+ const clearFormPick = (0, import_react20.useCallback)(() => {
21183
21827
  const form = formPickElRef.current;
21184
21828
  const editing = fieldPickElRef.current;
21185
21829
  if (commitPlaceholderEdit(editing) && editing) {
@@ -21199,7 +21843,7 @@ function OhhwellsBridge() {
21199
21843
  formPickElRef.current = null;
21200
21844
  setFormPickRect(null);
21201
21845
  }, []);
21202
- const clearFieldPick = (0, import_react19.useCallback)(() => {
21846
+ const clearFieldPick = (0, import_react20.useCallback)(() => {
21203
21847
  const wrapper = fieldPickElRef.current;
21204
21848
  if (commitPlaceholderEdit(wrapper) && wrapper) {
21205
21849
  const form = wrapper.closest('[data-ohw-editable="form"]');
@@ -21209,9 +21853,9 @@ function OhhwellsBridge() {
21209
21853
  setFieldPickRect(null);
21210
21854
  setFieldPickState(null);
21211
21855
  }, []);
21212
- const persistFieldsRef = (0, import_react19.useRef)(() => {
21856
+ const persistFieldsRef = (0, import_react20.useRef)(() => {
21213
21857
  });
21214
- const persistFields = (0, import_react19.useCallback)(
21858
+ const persistFields = (0, import_react20.useCallback)(
21215
21859
  (form) => {
21216
21860
  const key = formKeyOf(form);
21217
21861
  if (!key) return;
@@ -21222,7 +21866,7 @@ function OhhwellsBridge() {
21222
21866
  []
21223
21867
  );
21224
21868
  persistFieldsRef.current = persistFields;
21225
- const selectField = (0, import_react19.useCallback)((wrapper) => {
21869
+ const selectField = (0, import_react20.useCallback)((wrapper) => {
21226
21870
  if (fieldPickElRef.current && fieldPickElRef.current !== wrapper) {
21227
21871
  commitPlaceholderEdit(fieldPickElRef.current);
21228
21872
  }
@@ -21235,7 +21879,7 @@ function OhhwellsBridge() {
21235
21879
  setFieldPickState({ type: fieldTypeOf(wrapper), required: isFieldRequired(wrapper) });
21236
21880
  setFieldTypePickerOpen(false);
21237
21881
  }, []);
21238
- const withSelectedField = (0, import_react19.useCallback)(
21882
+ const withSelectedField = (0, import_react20.useCallback)(
21239
21883
  (run) => {
21240
21884
  const wrapper = fieldPickElRef.current;
21241
21885
  const form = formPickElRef.current;
@@ -21248,28 +21892,28 @@ function OhhwellsBridge() {
21248
21892
  },
21249
21893
  [persistFields]
21250
21894
  );
21251
- const handleFieldTypeChange = (0, import_react19.useCallback)(
21895
+ const handleFieldTypeChange = (0, import_react20.useCallback)(
21252
21896
  (type) => withSelectedField((_form, wrapper) => {
21253
21897
  applyFieldType(wrapper, type);
21254
21898
  selectField(wrapper);
21255
21899
  }),
21256
21900
  [selectField, withSelectedField]
21257
21901
  );
21258
- const handleFieldRequiredToggle = (0, import_react19.useCallback)(
21902
+ const handleFieldRequiredToggle = (0, import_react20.useCallback)(
21259
21903
  () => withSelectedField((_form, wrapper) => {
21260
21904
  setFieldRequired(wrapper, !isFieldRequired(wrapper));
21261
21905
  selectField(wrapper);
21262
21906
  }),
21263
21907
  [selectField, withSelectedField]
21264
21908
  );
21265
- const handleFieldDuplicate = (0, import_react19.useCallback)(
21909
+ const handleFieldDuplicate = (0, import_react20.useCallback)(
21266
21910
  () => withSelectedField((form, wrapper) => {
21267
21911
  const copy = duplicateField(form, wrapper);
21268
21912
  selectField(copy);
21269
21913
  }),
21270
21914
  [selectField, withSelectedField]
21271
21915
  );
21272
- const handleFieldDelete = (0, import_react19.useCallback)(
21916
+ const handleFieldDelete = (0, import_react20.useCallback)(
21273
21917
  () => withSelectedField((_form, wrapper) => {
21274
21918
  removeField(wrapper);
21275
21919
  clearFieldPick();
@@ -21277,7 +21921,7 @@ function OhhwellsBridge() {
21277
21921
  }),
21278
21922
  [clearFieldPick, withSelectedField]
21279
21923
  );
21280
- const handleAddField = (0, import_react19.useCallback)(
21924
+ const handleAddField = (0, import_react20.useCallback)(
21281
21925
  (type) => {
21282
21926
  const form = formPickElRef.current;
21283
21927
  if (!form) return;
@@ -21293,8 +21937,8 @@ function OhhwellsBridge() {
21293
21937
  },
21294
21938
  [persistFields, selectField]
21295
21939
  );
21296
- const fieldDragRef = (0, import_react19.useRef)(null);
21297
- const buildFieldDropSlots = (0, import_react19.useCallback)((form, draggedKey) => {
21940
+ const fieldDragRef = (0, import_react20.useRef)(null);
21941
+ const buildFieldDropSlots = (0, import_react20.useCallback)((form, draggedKey) => {
21298
21942
  const others = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== draggedKey);
21299
21943
  const slots = others.map((el) => {
21300
21944
  const rect = el.getBoundingClientRect();
@@ -21307,7 +21951,7 @@ function OhhwellsBridge() {
21307
21951
  }
21308
21952
  return slots;
21309
21953
  }, []);
21310
- const handleFieldDragStart = (0, import_react19.useCallback)(() => {
21954
+ const handleFieldDragStart = (0, import_react20.useCallback)(() => {
21311
21955
  const wrapper = fieldPickElRef.current;
21312
21956
  const form = formPickElRef.current;
21313
21957
  if (!wrapper || !form) return;
@@ -21316,18 +21960,18 @@ function OhhwellsBridge() {
21316
21960
  setFieldDragging(true);
21317
21961
  setFieldDropSlots(buildFieldDropSlots(form, key));
21318
21962
  }, [buildFieldDropSlots]);
21319
- const handleFieldDragEnd = (0, import_react19.useCallback)(() => {
21963
+ const handleFieldDragEnd = (0, import_react20.useCallback)(() => {
21320
21964
  fieldDragRef.current = null;
21321
21965
  setFieldDropIndex(null);
21322
21966
  setFieldDropSlots([]);
21323
21967
  setFieldDragging(false);
21324
21968
  }, []);
21325
- const [fieldDropIndex, setFieldDropIndex] = (0, import_react19.useState)(null);
21326
- const [fieldDropSlots, setFieldDropSlots] = (0, import_react19.useState)([]);
21327
- const [fieldDragging, setFieldDragging] = (0, import_react19.useState)(false);
21328
- const clearFormPickRef = (0, import_react19.useRef)(clearFormPick);
21969
+ const [fieldDropIndex, setFieldDropIndex] = (0, import_react20.useState)(null);
21970
+ const [fieldDropSlots, setFieldDropSlots] = (0, import_react20.useState)([]);
21971
+ const [fieldDragging, setFieldDragging] = (0, import_react20.useState)(false);
21972
+ const clearFormPickRef = (0, import_react20.useRef)(clearFormPick);
21329
21973
  clearFormPickRef.current = clearFormPick;
21330
- (0, import_react19.useEffect)(() => {
21974
+ (0, import_react20.useEffect)(() => {
21331
21975
  const el = fieldPickElRef.current;
21332
21976
  if (!el || fieldPickRect === null) return;
21333
21977
  const observer = new ResizeObserver(() => {
@@ -21336,7 +21980,7 @@ function OhhwellsBridge() {
21336
21980
  observer.observe(el);
21337
21981
  return () => observer.disconnect();
21338
21982
  }, [fieldPickRect !== null, fieldPickState]);
21339
- (0, import_react19.useEffect)(() => {
21983
+ (0, import_react20.useEffect)(() => {
21340
21984
  const el = formPickElRef.current;
21341
21985
  if (!el || formPickRect === null) return;
21342
21986
  const observer = new ResizeObserver(() => {
@@ -21345,25 +21989,25 @@ function OhhwellsBridge() {
21345
21989
  observer.observe(el);
21346
21990
  return () => observer.disconnect();
21347
21991
  }, [formPickRect !== null, formViewState]);
21348
- const [toolbarVariant, setToolbarVariant] = (0, import_react19.useState)("none");
21349
- const toolbarVariantRef = (0, import_react19.useRef)("none");
21992
+ const [toolbarVariant, setToolbarVariant] = (0, import_react20.useState)("none");
21993
+ const toolbarVariantRef = (0, import_react20.useRef)("none");
21350
21994
  toolbarVariantRef.current = toolbarVariant;
21351
- const [selectedIsCta, setSelectedIsCta] = (0, import_react19.useState)(false);
21352
- const [selectedIsSocial, setSelectedIsSocial] = (0, import_react19.useState)(false);
21353
- const [selectedIsSocialsRow, setSelectedIsSocialsRow] = (0, import_react19.useState)(false);
21354
- const [reorderHrefKey, setReorderHrefKey] = (0, import_react19.useState)(null);
21355
- const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react19.useState)(false);
21356
- const [toggleState, setToggleState] = (0, import_react19.useState)(null);
21357
- const [maxBadge, setMaxBadge] = (0, import_react19.useState)(null);
21358
- const [activeCommands, setActiveCommands] = (0, import_react19.useState)(/* @__PURE__ */ new Set());
21359
- const [sectionGap, setSectionGap] = (0, import_react19.useState)(null);
21360
- const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react19.useState)(false);
21361
- const hoveredNavContainerRef = (0, import_react19.useRef)(null);
21362
- const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react19.useState)(null);
21363
- const hoveredItemElRef = (0, import_react19.useRef)(null);
21364
- const [hoveredItemRect, setHoveredItemRect] = (0, import_react19.useState)(null);
21365
- const [hoveredTextRect, setHoveredTextRect] = (0, import_react19.useState)(null);
21366
- (0, import_react19.useEffect)(() => {
21995
+ const [selectedIsCta, setSelectedIsCta] = (0, import_react20.useState)(false);
21996
+ const [selectedIsSocial, setSelectedIsSocial] = (0, import_react20.useState)(false);
21997
+ const [selectedIsSocialsRow, setSelectedIsSocialsRow] = (0, import_react20.useState)(false);
21998
+ const [reorderHrefKey, setReorderHrefKey] = (0, import_react20.useState)(null);
21999
+ const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react20.useState)(false);
22000
+ const [toggleState, setToggleState] = (0, import_react20.useState)(null);
22001
+ const [maxBadge, setMaxBadge] = (0, import_react20.useState)(null);
22002
+ const [activeCommands, setActiveCommands] = (0, import_react20.useState)(/* @__PURE__ */ new Set());
22003
+ const [sectionGap, setSectionGap] = (0, import_react20.useState)(null);
22004
+ const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react20.useState)(false);
22005
+ const hoveredNavContainerRef = (0, import_react20.useRef)(null);
22006
+ const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react20.useState)(null);
22007
+ const hoveredItemElRef = (0, import_react20.useRef)(null);
22008
+ const [hoveredItemRect, setHoveredItemRect] = (0, import_react20.useState)(null);
22009
+ const [hoveredTextRect, setHoveredTextRect] = (0, import_react20.useState)(null);
22010
+ (0, import_react20.useEffect)(() => {
21367
22011
  const sync = () => {
21368
22012
  const el = document.querySelector(
21369
22013
  '[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]):not([data-ohw-editable="form"] *)'
@@ -21407,60 +22051,71 @@ function OhhwellsBridge() {
21407
22051
  });
21408
22052
  return () => observer.disconnect();
21409
22053
  }, []);
21410
- const siblingHintElRef = (0, import_react19.useRef)(null);
21411
- const [siblingHintRect, setSiblingHintRect] = (0, import_react19.useState)(null);
21412
- const [siblingHintRects, setSiblingHintRects] = (0, import_react19.useState)([]);
21413
- const [isItemDragging, setIsItemDragging] = (0, import_react19.useState)(false);
21414
- const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react19.useState)(false);
22054
+ const siblingHintElRef = (0, import_react20.useRef)(null);
22055
+ const [siblingHintRect, setSiblingHintRect] = (0, import_react20.useState)(null);
22056
+ const [siblingHintRects, setSiblingHintRects] = (0, import_react20.useState)([]);
22057
+ const [isItemDragging, setIsItemDragging] = (0, import_react20.useState)(false);
22058
+ const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react20.useState)(false);
21415
22059
  isFooterFrameSelectionRef.current = isFooterFrameSelection;
21416
- const [floatingPanel, setFloatingPanel] = (0, import_react19.useState)(null);
21417
- const floatingPanelOpenRef = (0, import_react19.useRef)(false);
21418
- floatingPanelOpenRef.current = floatingPanel !== null;
21419
- const floatingPanelRef = (0, import_react19.useRef)(null);
21420
- floatingPanelRef.current = floatingPanel;
21421
- const [floatingPanelPos, setFloatingPanelPos] = (0, import_react19.useState)(null);
21422
- const buttonCollectionDragRef = (0, import_react19.useRef)(null);
21423
- const buttonDropInsertIndexRef = (0, import_react19.useRef)(null);
21424
- const [buttonDropSlots, setButtonDropSlots] = (0, import_react19.useState)([]);
21425
- const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react19.useState)(null);
21426
- const buttonPointerDragRef = (0, import_react19.useRef)(null);
21427
- const [buttonStyleTick, setButtonStyleTick] = (0, import_react19.useState)(0);
21428
- const [logoSizeDraft, setLogoSizeDraft] = (0, import_react19.useState)(null);
21429
- const [editorViewport, setEditorViewport] = (0, import_react19.useState)("desktop");
21430
- const [parentScrollSnap, setParentScrollSnap] = (0, import_react19.useState)(null);
21431
- const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react19.useState)(null);
21432
- const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react19.useState)(null);
21433
- const footerDragRef = (0, import_react19.useRef)(null);
21434
- const [footerDropSlots, setFooterDropSlots] = (0, import_react19.useState)([]);
21435
- const [activeFooterDropIndex, setActiveFooterDropIndex] = (0, import_react19.useState)(null);
21436
- const [draggedItemRect, setDraggedItemRect] = (0, import_react19.useState)(null);
21437
- const footerPointerDragRef = (0, import_react19.useRef)(null);
21438
- const suppressNextClickRef = (0, import_react19.useRef)(false);
21439
- const suppressClickUntilRef = (0, import_react19.useRef)(0);
21440
- const [linkPopover, setLinkPopover] = (0, import_react19.useState)(null);
21441
- const linkPopoverSessionRef = (0, import_react19.useRef)(null);
21442
- const addNavAfterAnchorRef = (0, import_react19.useRef)(null);
21443
- const editContentRef = (0, import_react19.useRef)({});
21444
- const aiSectionsRef = (0, import_react19.useRef)("");
21445
- const applyTreeLocalRef = (0, import_react19.useRef)(
22060
+ const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react20.useState)(null);
22061
+ const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react20.useState)(null);
22062
+ const footerDragRef = (0, import_react20.useRef)(null);
22063
+ const [footerDropSlots, setFooterDropSlots] = (0, import_react20.useState)([]);
22064
+ const [activeFooterDropIndex, setActiveFooterDropIndex] = (0, import_react20.useState)(null);
22065
+ const [draggedItemRect, setDraggedItemRect] = (0, import_react20.useState)(null);
22066
+ const footerPointerDragRef = (0, import_react20.useRef)(null);
22067
+ const suppressNextClickRef = (0, import_react20.useRef)(false);
22068
+ const suppressClickUntilRef = (0, import_react20.useRef)(0);
22069
+ const [linkPopover, setLinkPopover] = (0, import_react20.useState)(null);
22070
+ const linkPopoverSessionRef = (0, import_react20.useRef)(null);
22071
+ const addNavAfterAnchorRef = (0, import_react20.useRef)(null);
22072
+ const editContentRef = (0, import_react20.useRef)({});
22073
+ const aiSectionsRef = (0, import_react20.useRef)("");
22074
+ const applyTreeLocalRef = (0, import_react20.useRef)(
21446
22075
  null
21447
22076
  );
21448
- const clearInteractionChromeRef = (0, import_react19.useRef)(() => {
22077
+ const clearInteractionChromeRef = (0, import_react20.useRef)(() => {
21449
22078
  });
21450
- const brandKitRef = (0, import_react19.useRef)("");
21451
- const stylesRef = (0, import_react19.useRef)("");
21452
- const appliedDrawerRef = (0, import_react19.useRef)(null);
21453
- const pendingDeleteUndoRef = (0, import_react19.useRef)(null);
21454
- const [sitePages, setSitePages] = (0, import_react19.useState)([]);
21455
- const [sectionsByPath, setSectionsByPath] = (0, import_react19.useState)({});
21456
- const sectionsPrefetchGenRef = (0, import_react19.useRef)(0);
21457
- const setLinkPopoverRef = (0, import_react19.useRef)(setLinkPopover);
21458
- const linkPopoverPanelRef = (0, import_react19.useRef)(null);
21459
- const linkPopoverOpenRef = (0, import_react19.useRef)(false);
21460
- const linkPopoverGraceUntilRef = (0, import_react19.useRef)(0);
22079
+ const brandKitRef = (0, import_react20.useRef)("");
22080
+ const stylesRef = (0, import_react20.useRef)("");
22081
+ const appliedDrawerRef = (0, import_react20.useRef)(null);
22082
+ const pendingDeleteUndoRef = (0, import_react20.useRef)(null);
22083
+ const [floatingPanel, setFloatingPanel] = (0, import_react20.useState)(null);
22084
+ const floatingPanelOpenRef = (0, import_react20.useRef)(false);
22085
+ const floatingPanelRef = (0, import_react20.useRef)(null);
22086
+ floatingPanelRef.current = floatingPanel;
22087
+ const setFloatingPanelRef = (0, import_react20.useRef)(setFloatingPanel);
22088
+ const [floatingPanelPos, setFloatingPanelPos] = (0, import_react20.useState)(null);
22089
+ const buttonCollectionDragRef = (0, import_react20.useRef)(null);
22090
+ const buttonDropInsertIndexRef = (0, import_react20.useRef)(null);
22091
+ const [buttonDropSlots, setButtonDropSlots] = (0, import_react20.useState)([]);
22092
+ const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react20.useState)(null);
22093
+ const buttonPointerDragRef = (0, import_react20.useRef)(null);
22094
+ const [buttonStyleTick, setButtonStyleTick] = (0, import_react20.useState)(0);
22095
+ const [logoSizeDraft, setLogoSizeDraft] = (0, import_react20.useState)(null);
22096
+ const [editorViewport, setEditorViewport] = (0, import_react20.useState)("desktop");
22097
+ const [parentScrollSnap, setParentScrollSnap] = (0, import_react20.useState)(null);
22098
+ const [sitePages, setSitePages] = (0, import_react20.useState)([]);
22099
+ const [sectionsByPath, setSectionsByPath] = (0, import_react20.useState)({});
22100
+ const sectionsPrefetchGenRef = (0, import_react20.useRef)(0);
22101
+ const setLinkPopoverRef = (0, import_react20.useRef)(setLinkPopover);
22102
+ const linkPopoverPanelRef = (0, import_react20.useRef)(null);
22103
+ const linkPopoverOpenRef = (0, import_react20.useRef)(false);
22104
+ const linkPopoverGraceUntilRef = (0, import_react20.useRef)(0);
21461
22105
  setLinkPopoverRef.current = setLinkPopover;
22106
+ setFloatingPanelRef.current = setFloatingPanel;
21462
22107
  linkPopoverSessionRef.current = linkPopover;
21463
- (0, import_react19.useEffect)(() => {
22108
+ floatingPanelOpenRef.current = Boolean(floatingPanel);
22109
+ (0, import_react20.useEffect)(() => {
22110
+ const syncViewport = () => {
22111
+ const next = window.innerWidth <= 480 ? "mobile" : "desktop";
22112
+ setEditorViewport((prev) => prev === next ? prev : next);
22113
+ };
22114
+ syncViewport();
22115
+ window.addEventListener("resize", syncViewport);
22116
+ return () => window.removeEventListener("resize", syncViewport);
22117
+ }, []);
22118
+ (0, import_react20.useEffect)(() => {
21464
22119
  setSectionOrderPersistHandler((entries) => {
21465
22120
  const currentPath = window.location.pathname;
21466
22121
  const merged = mergePageSectionOrder(editContentRef.current[SECTION_ORDER_KEY], currentPath, entries);
@@ -21516,7 +22171,7 @@ function OhhwellsBridge() {
21516
22171
  const bumpLinkPopoverGrace = () => {
21517
22172
  linkPopoverGraceUntilRef.current = Date.now() + 350;
21518
22173
  };
21519
- const runSectionsPrefetch = (0, import_react19.useCallback)((pages) => {
22174
+ const runSectionsPrefetch = (0, import_react20.useCallback)((pages) => {
21520
22175
  if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
21521
22176
  const gen = ++sectionsPrefetchGenRef.current;
21522
22177
  const paths = pages.map((p) => p.path);
@@ -21535,9 +22190,9 @@ function OhhwellsBridge() {
21535
22190
  );
21536
22191
  });
21537
22192
  }, [isEditMode, pathname]);
21538
- const runSectionsPrefetchRef = (0, import_react19.useRef)(runSectionsPrefetch);
22193
+ const runSectionsPrefetchRef = (0, import_react20.useRef)(runSectionsPrefetch);
21539
22194
  runSectionsPrefetchRef.current = runSectionsPrefetch;
21540
- (0, import_react19.useEffect)(() => {
22195
+ (0, import_react20.useEffect)(() => {
21541
22196
  if (!linkPopover) {
21542
22197
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
21543
22198
  return;
@@ -21565,7 +22220,7 @@ function OhhwellsBridge() {
21565
22220
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
21566
22221
  };
21567
22222
  }, [linkPopover, postToParent2]);
21568
- (0, import_react19.useEffect)(() => {
22223
+ (0, import_react20.useEffect)(() => {
21569
22224
  if (!isEditMode) return;
21570
22225
  const useFixtures = shouldUseDevFixtures();
21571
22226
  if (useFixtures) {
@@ -21589,14 +22244,14 @@ function OhhwellsBridge() {
21589
22244
  if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
21590
22245
  return () => window.removeEventListener("message", onSitePages);
21591
22246
  }, [isEditMode, postToParent2]);
21592
- (0, import_react19.useEffect)(() => {
22247
+ (0, import_react20.useEffect)(() => {
21593
22248
  if (!isEditMode || shouldUseDevFixtures()) return;
21594
22249
  void loadAllSectionsManifest().then((manifest) => {
21595
22250
  if (Object.keys(manifest).length === 0) return;
21596
22251
  setSectionsByPath((prev) => ({ ...manifest, ...prev }));
21597
22252
  });
21598
22253
  }, [isEditMode]);
21599
- (0, import_react19.useEffect)(() => {
22254
+ (0, import_react20.useEffect)(() => {
21600
22255
  const update = () => {
21601
22256
  const el = activeElRef.current ?? selectedElRef.current;
21602
22257
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
@@ -21620,10 +22275,10 @@ function OhhwellsBridge() {
21620
22275
  vvp.removeEventListener("resize", update);
21621
22276
  };
21622
22277
  }, []);
21623
- const refreshStateRules = (0, import_react19.useCallback)(() => {
22278
+ const refreshStateRules = (0, import_react20.useCallback)(() => {
21624
22279
  editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
21625
22280
  }, []);
21626
- const processConfigRequest = (0, import_react19.useCallback)((insertAfterVal) => {
22281
+ const processConfigRequest = (0, import_react20.useCallback)((insertAfterVal) => {
21627
22282
  const tracker = getSectionsTracker();
21628
22283
  let entries = [];
21629
22284
  try {
@@ -21646,7 +22301,7 @@ function OhhwellsBridge() {
21646
22301
  }
21647
22302
  window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
21648
22303
  }, [isEditMode]);
21649
- const deactivate = (0, import_react19.useCallback)(() => {
22304
+ const deactivate = (0, import_react20.useCallback)(() => {
21650
22305
  const el = activeElRef.current;
21651
22306
  if (!el) return;
21652
22307
  const isFormBlock = el.dataset.ohwEditable === "form";
@@ -21697,12 +22352,12 @@ function OhhwellsBridge() {
21697
22352
  setToolbarShowEditLink(false);
21698
22353
  postToParent2({ type: "ow:exit-edit" });
21699
22354
  }, [postToParent2]);
21700
- const clearSelectedAttr = (0, import_react19.useCallback)(() => {
22355
+ const clearSelectedAttr = (0, import_react20.useCallback)(() => {
21701
22356
  document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
21702
22357
  el.removeAttribute("data-ohw-selected");
21703
22358
  });
21704
22359
  }, []);
21705
- const deselect = (0, import_react19.useCallback)(() => {
22360
+ const deselect = (0, import_react20.useCallback)(() => {
21706
22361
  const nestedGroup = selectedElRef.current?.closest("[data-ohw-nav-children]") != null ? selectedElRef.current.closest("[data-ohw-nav-group]") : null;
21707
22362
  clearSelectedAttr();
21708
22363
  selectedElRef.current = null;
@@ -21737,20 +22392,20 @@ function OhhwellsBridge() {
21737
22392
  setToolbarVariant("none");
21738
22393
  }
21739
22394
  }, [clearSelectedAttr]);
21740
- const markSelected = (0, import_react19.useCallback)((el) => {
22395
+ const markSelected = (0, import_react20.useCallback)((el) => {
21741
22396
  clearSelectedAttr();
21742
22397
  el.removeAttribute("data-ohw-hovered");
21743
22398
  el.setAttribute("data-ohw-selected", "");
21744
22399
  }, [clearSelectedAttr]);
21745
- const isSelectedForHover = (0, import_react19.useCallback)((el) => {
22400
+ const isSelectedForHover = (0, import_react20.useCallback)((el) => {
21746
22401
  if (!el) return false;
21747
22402
  return [selectedElRef.current, activeElRef.current].some(
21748
22403
  (busy) => busy && (el === busy || busy.contains(el) || el.contains(busy))
21749
22404
  );
21750
22405
  }, []);
21751
- const isSelectedForHoverRef = (0, import_react19.useRef)(isSelectedForHover);
22406
+ const isSelectedForHoverRef = (0, import_react20.useRef)(isSelectedForHover);
21752
22407
  isSelectedForHoverRef.current = isSelectedForHover;
21753
- const resolveHrefKeyElement = (0, import_react19.useCallback)((hrefKey) => {
22408
+ const resolveHrefKeyElement = (0, import_react20.useCallback)((hrefKey) => {
21754
22409
  if (isFooterHrefKey(hrefKey)) {
21755
22410
  return document.querySelector(
21756
22411
  `footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
@@ -21765,7 +22420,7 @@ function OhhwellsBridge() {
21765
22420
  `[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
21766
22421
  );
21767
22422
  }, []);
21768
- const resyncSelectedNavigationItem = (0, import_react19.useCallback)(() => {
22423
+ const resyncSelectedNavigationItem = (0, import_react20.useCallback)(() => {
21769
22424
  const hrefKey = selectedHrefKeyRef.current;
21770
22425
  if (hrefKey) {
21771
22426
  const link = resolveHrefKeyElement(hrefKey);
@@ -21803,7 +22458,7 @@ function OhhwellsBridge() {
21803
22458
  );
21804
22459
  }
21805
22460
  }, [resolveHrefKeyElement]);
21806
- const reselectNavigationItem = (0, import_react19.useCallback)((navAnchor) => {
22461
+ const reselectNavigationItem = (0, import_react20.useCallback)((navAnchor) => {
21807
22462
  selectedElRef.current = navAnchor;
21808
22463
  selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
21809
22464
  selectedFooterColAttrRef.current = null;
@@ -21834,7 +22489,7 @@ function OhhwellsBridge() {
21834
22489
  setToolbarShowEditLink(false);
21835
22490
  setActiveCommands(/* @__PURE__ */ new Set());
21836
22491
  }, [markSelected]);
21837
- const commitNavigationTextEdit = (0, import_react19.useCallback)((navAnchor) => {
22492
+ const commitNavigationTextEdit = (0, import_react20.useCallback)((navAnchor) => {
21838
22493
  const el = activeElRef.current;
21839
22494
  if (!el) return;
21840
22495
  const key = el.dataset.ohwKey;
@@ -21867,7 +22522,7 @@ function OhhwellsBridge() {
21867
22522
  postToParent2({ type: "ow:exit-edit" });
21868
22523
  reselectNavigationItem(navAnchor);
21869
22524
  }, [postToParent2, reselectNavigationItem]);
21870
- const handleAddTopLevelNavItem = (0, import_react19.useCallback)(() => {
22525
+ const handleAddTopLevelNavItem = (0, import_react20.useCallback)(() => {
21871
22526
  const items = listNavbarRootItems();
21872
22527
  addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
21873
22528
  deselectRef.current();
@@ -21879,7 +22534,7 @@ function OhhwellsBridge() {
21879
22534
  intent: "add-nav"
21880
22535
  });
21881
22536
  }, []);
21882
- const maybeWarnNavLinkDropdownConflict = (0, import_react19.useCallback)(
22537
+ const maybeWarnNavLinkDropdownConflict = (0, import_react20.useCallback)(
21883
22538
  (anchor) => {
21884
22539
  if (!isNavbarHrefKey(anchor.getAttribute("data-ohw-href-key"))) return;
21885
22540
  if (!navDropdownsOpenOnClick()) return;
@@ -21892,7 +22547,7 @@ function OhhwellsBridge() {
21892
22547
  },
21893
22548
  [postToParent2]
21894
22549
  );
21895
- const handleNavDropdownOpenChange = (0, import_react19.useCallback)((open) => {
22550
+ const handleNavDropdownOpenChange = (0, import_react20.useCallback)((open) => {
21896
22551
  const selected = selectedElRef.current;
21897
22552
  if (!selected || !isNavigationItem2(selected)) return;
21898
22553
  if (isNestedNavChild(selected)) return;
@@ -21908,7 +22563,7 @@ function OhhwellsBridge() {
21908
22563
  }
21909
22564
  });
21910
22565
  }, []);
21911
- const handleFooterHeadingVisibleChange = (0, import_react19.useCallback)(
22566
+ const handleFooterHeadingVisibleChange = (0, import_react20.useCallback)(
21912
22567
  (visible) => {
21913
22568
  const selected = selectedElRef.current;
21914
22569
  if (!selected || !isFooterFrameSelectionRef.current) return;
@@ -21932,7 +22587,7 @@ function OhhwellsBridge() {
21932
22587
  },
21933
22588
  [postToParent2]
21934
22589
  );
21935
- const enterEditOnNewItem = (0, import_react19.useCallback)((anchor) => {
22590
+ const enterEditOnNewItem = (0, import_react20.useCallback)((anchor) => {
21936
22591
  const label = anchor.querySelector('[data-ohw-editable="text"]');
21937
22592
  if (!label) {
21938
22593
  selectRef.current(anchor);
@@ -21941,8 +22596,8 @@ function OhhwellsBridge() {
21941
22596
  setNavGroupForceOpen(anchor, true);
21942
22597
  activateRef.current(label);
21943
22598
  }, []);
21944
- const pendingSocialAddRef = (0, import_react19.useRef)(null);
21945
- const handleAddChildItem = (0, import_react19.useCallback)(() => {
22599
+ const pendingSocialAddRef = (0, import_react20.useRef)(null);
22600
+ const handleAddChildItem = (0, import_react20.useCallback)(() => {
21946
22601
  const selected = selectedElRef.current;
21947
22602
  if (!selected) return;
21948
22603
  const socialsRow = isSocialsRow(selected) ? selected : findSocialsRow(selected);
@@ -22053,7 +22708,7 @@ function OhhwellsBridge() {
22053
22708
  });
22054
22709
  });
22055
22710
  }, [enterEditOnNewItem, isFooterFrameSelection, maybeWarnNavLinkDropdownConflict, postToParent2]);
22056
- const handleAddFooterColumn = (0, import_react19.useCallback)(() => {
22711
+ const handleAddFooterColumn = (0, import_react20.useCallback)(() => {
22057
22712
  if (!canAddFooterColumn()) {
22058
22713
  postToParent2({
22059
22714
  type: "ow:toast",
@@ -22074,7 +22729,7 @@ function OhhwellsBridge() {
22074
22729
  selectRef.current(result.firstLink);
22075
22730
  });
22076
22731
  }, [postToParent2]);
22077
- const clearFooterDragVisuals = (0, import_react19.useCallback)(() => {
22732
+ const clearFooterDragVisuals = (0, import_react20.useCallback)(() => {
22078
22733
  footerDragRef.current = null;
22079
22734
  setSiblingHintRects([]);
22080
22735
  setFooterDropSlots([]);
@@ -22083,7 +22738,7 @@ function OhhwellsBridge() {
22083
22738
  setIsItemDragging(false);
22084
22739
  unlockFooterDragInteraction();
22085
22740
  }, []);
22086
- const refreshFooterDragVisuals = (0, import_react19.useCallback)((session, activeSlot, clientX, clientY) => {
22741
+ const refreshFooterDragVisuals = (0, import_react20.useCallback)((session, activeSlot, clientX, clientY) => {
22087
22742
  const dragged = session.draggedEl;
22088
22743
  setDraggedItemRect(dragged.getBoundingClientRect());
22089
22744
  if (typeof clientX === "number" && typeof clientY === "number") {
@@ -22115,13 +22770,13 @@ function OhhwellsBridge() {
22115
22770
  const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
22116
22771
  setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
22117
22772
  }, []);
22118
- const refreshFooterDragVisualsRef = (0, import_react19.useRef)(refreshFooterDragVisuals);
22773
+ const refreshFooterDragVisualsRef = (0, import_react20.useRef)(refreshFooterDragVisuals);
22119
22774
  refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
22120
- const commitFooterDragRef = (0, import_react19.useRef)(() => {
22775
+ const commitFooterDragRef = (0, import_react20.useRef)(() => {
22121
22776
  });
22122
- const beginFooterDragRef = (0, import_react19.useRef)(() => {
22777
+ const beginFooterDragRef = (0, import_react20.useRef)(() => {
22123
22778
  });
22124
- const beginFooterDrag = (0, import_react19.useCallback)(
22779
+ const beginFooterDrag = (0, import_react20.useCallback)(
22125
22780
  (session) => {
22126
22781
  const rect = session.draggedEl.getBoundingClientRect();
22127
22782
  session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
@@ -22141,7 +22796,7 @@ function OhhwellsBridge() {
22141
22796
  [refreshFooterDragVisuals]
22142
22797
  );
22143
22798
  beginFooterDragRef.current = beginFooterDrag;
22144
- const commitFooterDrag = (0, import_react19.useCallback)(
22799
+ const commitFooterDrag = (0, import_react20.useCallback)(
22145
22800
  (clientX, clientY) => {
22146
22801
  const session = footerDragRef.current;
22147
22802
  if (!session) {
@@ -22270,7 +22925,7 @@ function OhhwellsBridge() {
22270
22925
  [clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
22271
22926
  );
22272
22927
  commitFooterDragRef.current = commitFooterDrag;
22273
- const startFooterLinkDrag = (0, import_react19.useCallback)(
22928
+ const startFooterLinkDrag = (0, import_react20.useCallback)(
22274
22929
  (anchor, clientX, clientY, wasSelected) => {
22275
22930
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
22276
22931
  if (!hrefKey) return false;
@@ -22306,7 +22961,7 @@ function OhhwellsBridge() {
22306
22961
  },
22307
22962
  [beginFooterDrag]
22308
22963
  );
22309
- const startFooterColumnDrag = (0, import_react19.useCallback)(
22964
+ const startFooterColumnDrag = (0, import_react20.useCallback)(
22310
22965
  (columnEl, clientX, clientY, wasSelected) => {
22311
22966
  const columns = listFooterColumns();
22312
22967
  const idx = columns.indexOf(columnEl);
@@ -22326,7 +22981,7 @@ function OhhwellsBridge() {
22326
22981
  },
22327
22982
  [beginFooterDrag]
22328
22983
  );
22329
- const persistButtonCollectionDrag = (0, import_react19.useCallback)(
22984
+ const persistButtonCollectionDrag = (0, import_react20.useCallback)(
22330
22985
  (button, clientX) => {
22331
22986
  const insertIndex = buttonDropInsertIndexRef.current;
22332
22987
  if (insertIndex != null) insertButtonAtCollectionIndex(button, insertIndex);
@@ -22350,7 +23005,7 @@ function OhhwellsBridge() {
22350
23005
  },
22351
23006
  [postToParent2]
22352
23007
  );
22353
- const refreshButtonDragVisuals = (0, import_react19.useCallback)((button, clientX, clientY) => {
23008
+ const refreshButtonDragVisuals = (0, import_react20.useCallback)((button, clientX, clientY) => {
22354
23009
  const collection = buttonCollectionOf(button);
22355
23010
  if (!collection) {
22356
23011
  setButtonDropSlots([]);
@@ -22367,7 +23022,7 @@ function OhhwellsBridge() {
22367
23022
  setDraggedItemRect(button.getBoundingClientRect());
22368
23023
  if (selectedElRef.current === button) setToolbarRect(button.getBoundingClientRect());
22369
23024
  }, []);
22370
- const handleItemDragStart = (0, import_react19.useCallback)(
23025
+ const handleItemDragStart = (0, import_react20.useCallback)(
22371
23026
  (e) => {
22372
23027
  const selected = selectedElRef.current;
22373
23028
  if (!selected) {
@@ -22398,7 +23053,7 @@ function OhhwellsBridge() {
22398
23053
  },
22399
23054
  [startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag, refreshButtonDragVisuals]
22400
23055
  );
22401
- const handleItemDragEnd = (0, import_react19.useCallback)(
23056
+ const handleItemDragEnd = (0, import_react20.useCallback)(
22402
23057
  (e) => {
22403
23058
  const collectionButton = buttonCollectionDragRef.current;
22404
23059
  if (collectionButton) {
@@ -22429,7 +23084,7 @@ function OhhwellsBridge() {
22429
23084
  },
22430
23085
  [commitFooterDrag, commitNavDrag, navDragRef, persistButtonCollectionDrag]
22431
23086
  );
22432
- const handleItemChromePointerDown = (0, import_react19.useCallback)((e) => {
23087
+ const handleItemChromePointerDown = (0, import_react20.useCallback)((e) => {
22433
23088
  if (e.button !== 0) return;
22434
23089
  const selected = selectedElRef.current;
22435
23090
  if (!selected) return;
@@ -22470,7 +23125,7 @@ function OhhwellsBridge() {
22470
23125
  }
22471
23126
  if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
22472
23127
  }, [armNavPressFromChrome]);
22473
- const handleItemChromeClick = (0, import_react19.useCallback)((clientX, clientY) => {
23128
+ const handleItemChromeClick = (0, import_react20.useCallback)((clientX, clientY) => {
22474
23129
  if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
22475
23130
  suppressNextClickRef.current = false;
22476
23131
  return;
@@ -22483,7 +23138,7 @@ function OhhwellsBridge() {
22483
23138
  }, []);
22484
23139
  reselectNavigationItemRef.current = reselectNavigationItem;
22485
23140
  commitNavigationTextEditRef.current = commitNavigationTextEdit;
22486
- const select = (0, import_react19.useCallback)((anchor) => {
23141
+ const select = (0, import_react20.useCallback)((anchor) => {
22487
23142
  if (!isNavigationItem2(anchor)) return;
22488
23143
  if (activeElRef.current) deactivate();
22489
23144
  aiSectionApiRef.current?.selectFromElement(anchor);
@@ -22545,7 +23200,7 @@ function OhhwellsBridge() {
22545
23200
  setLogoSizeDraft(null);
22546
23201
  }
22547
23202
  }, [deactivate, markSelected]);
22548
- const selectFrame = (0, import_react19.useCallback)((el) => {
23203
+ const selectFrame = (0, import_react20.useCallback)((el) => {
22549
23204
  if (!isNavigationContainer(el)) return;
22550
23205
  if (activeElRef.current) deactivate();
22551
23206
  aiSectionApiRef.current?.selectFromElement(el);
@@ -22586,7 +23241,7 @@ function OhhwellsBridge() {
22586
23241
  setFloatingPanelPos(null);
22587
23242
  setLogoSizeDraft(null);
22588
23243
  }, [deactivate, markSelected, postToParent2]);
22589
- const selectLogo = (0, import_react19.useCallback)(
23244
+ const selectLogo = (0, import_react20.useCallback)(
22590
23245
  (logoEl) => {
22591
23246
  if (activeElRef.current) deactivate();
22592
23247
  selectedElRef.current = logoEl;
@@ -22615,7 +23270,7 @@ function OhhwellsBridge() {
22615
23270
  },
22616
23271
  [deactivate, markSelected]
22617
23272
  );
22618
- const openLogoSizePanel = (0, import_react19.useCallback)((logoEl) => {
23273
+ const openLogoSizePanel = (0, import_react20.useCallback)((logoEl) => {
22619
23274
  const placement = getLogoPlacement(logoEl);
22620
23275
  const draft = readLogoSizeState(editContentRef.current, placement);
22621
23276
  setLogoSizeDraft(draft);
@@ -22628,7 +23283,7 @@ function OhhwellsBridge() {
22628
23283
  placement
22629
23284
  });
22630
23285
  }, []);
22631
- const openSocialsDisplayPanel = (0, import_react19.useCallback)((row) => {
23286
+ const openSocialsDisplayPanel = (0, import_react20.useCallback)((row) => {
22632
23287
  setFloatingPanelPos(null);
22633
23288
  setParentScrollSnap(parentScrollRef.current);
22634
23289
  setFloatingPanel({
@@ -22639,7 +23294,7 @@ function OhhwellsBridge() {
22639
23294
  row
22640
23295
  });
22641
23296
  }, []);
22642
- const rememberButtonTokens = (0, import_react19.useCallback)(
23297
+ const rememberButtonTokens = (0, import_react20.useCallback)(
22643
23298
  (content, tokens, nodes) => {
22644
23299
  if (nodes.length === 0) return content;
22645
23300
  const next = { ...content };
@@ -22650,7 +23305,7 @@ function OhhwellsBridge() {
22650
23305
  },
22651
23306
  [postToParent2]
22652
23307
  );
22653
- const tokensForButton = (0, import_react19.useCallback)(
23308
+ const tokensForButton = (0, import_react20.useCallback)(
22654
23309
  (el, persistFallback = false) => {
22655
23310
  const stored = readStoredStyleTokens(editContentRef.current);
22656
23311
  if (stored) return stored;
@@ -22665,7 +23320,7 @@ function OhhwellsBridge() {
22665
23320
  },
22666
23321
  [rememberButtonTokens]
22667
23322
  );
22668
- const openButtonStylePanel = (0, import_react19.useCallback)(
23323
+ const openButtonStylePanel = (0, import_react20.useCallback)(
22669
23324
  (anchor) => {
22670
23325
  const id = buttonId(anchor);
22671
23326
  if (!id) return;
@@ -22683,7 +23338,7 @@ function OhhwellsBridge() {
22683
23338
  },
22684
23339
  [tokensForButton]
22685
23340
  );
22686
- const applySelectedButtonStyle = (0, import_react19.useCallback)(
23341
+ const applySelectedButtonStyle = (0, import_react20.useCallback)(
22687
23342
  (patch) => {
22688
23343
  const panel = floatingPanelRef.current;
22689
23344
  const id = panel?.kind === "button-style" ? panel.buttonId : null;
@@ -22701,7 +23356,7 @@ function OhhwellsBridge() {
22701
23356
  },
22702
23357
  [postToParent2]
22703
23358
  );
22704
- (0, import_react19.useEffect)(() => {
23359
+ (0, import_react20.useEffect)(() => {
22705
23360
  const onDragOver = (e) => {
22706
23361
  const dragged = buttonCollectionDragRef.current;
22707
23362
  if (!dragged) return;
@@ -22720,11 +23375,11 @@ function OhhwellsBridge() {
22720
23375
  document.removeEventListener("drop", onDrop);
22721
23376
  };
22722
23377
  }, [refreshButtonDragVisuals]);
22723
- const isEditModeRef = (0, import_react19.useRef)(false);
22724
- const requestMissingSocialIconsRef = (0, import_react19.useRef)(() => {
23378
+ const isEditModeRef = (0, import_react20.useRef)(false);
23379
+ const requestMissingSocialIconsRef = (0, import_react20.useRef)(() => {
22725
23380
  });
22726
- const askedSocialIconsRef = (0, import_react19.useRef)(/* @__PURE__ */ new Set());
22727
- const requestMissingSocialIcons = (0, import_react19.useCallback)(() => {
23381
+ const askedSocialIconsRef = (0, import_react20.useRef)(/* @__PURE__ */ new Set());
23382
+ const requestMissingSocialIcons = (0, import_react20.useCallback)(() => {
22728
23383
  const items = Array.from(document.querySelectorAll(`[${SOCIALS_ROW_ATTR}]`)).filter((row) => socialsDisplayFor(row, editContentRef.current).icon).flatMap((row) => {
22729
23384
  const missing = socialsMissingIcons(row);
22730
23385
  listSocialItems(row).forEach((item) => ensureIconSlot(item));
@@ -22736,7 +23391,7 @@ function OhhwellsBridge() {
22736
23391
  }, []);
22737
23392
  requestMissingSocialIconsRef.current = requestMissingSocialIcons;
22738
23393
  isEditModeRef.current = isEditMode;
22739
- const changeSocialsDisplay = (0, import_react19.useCallback)(
23394
+ const changeSocialsDisplay = (0, import_react20.useCallback)(
22740
23395
  (row, next) => {
22741
23396
  if (next.icon) {
22742
23397
  const missing = socialsMissingIcons(row);
@@ -22760,19 +23415,19 @@ function OhhwellsBridge() {
22760
23415
  },
22761
23416
  []
22762
23417
  );
22763
- const closeFloatingPanelOnly = (0, import_react19.useCallback)(() => {
23418
+ const closeFloatingPanelOnly = (0, import_react20.useCallback)(() => {
22764
23419
  setFloatingPanel(null);
22765
23420
  setFloatingPanelPos(null);
22766
23421
  setLogoSizeDraft(null);
22767
23422
  }, []);
22768
23423
  closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
22769
- const closeFloatingPanelAndDeselect = (0, import_react19.useCallback)(() => {
23424
+ const closeFloatingPanelAndDeselect = (0, import_react20.useCallback)(() => {
22770
23425
  setFloatingPanel(null);
22771
23426
  setFloatingPanelPos(null);
22772
23427
  setLogoSizeDraft(null);
22773
23428
  deselectRef.current();
22774
23429
  }, []);
22775
- (0, import_react19.useEffect)(() => {
23430
+ (0, import_react20.useEffect)(() => {
22776
23431
  const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
22777
23432
  if (!session || !logoSizeDraft) {
22778
23433
  postToParentRef.current({ type: "ow:logo-size-panel", open: false });
@@ -22791,7 +23446,7 @@ function OhhwellsBridge() {
22791
23446
  max: LOGO_SIZE_MAX
22792
23447
  });
22793
23448
  }, [floatingPanel, logoSizeDraft, editorViewport]);
22794
- const persistLogoSizeDraft = (0, import_react19.useCallback)(
23449
+ const persistLogoSizeDraft = (0, import_react20.useCallback)(
22795
23450
  (placement, draft) => {
22796
23451
  const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
22797
23452
  const mobileKey = LOGO_SIZE_MOBILE_KEYS[placement];
@@ -22831,7 +23486,7 @@ function OhhwellsBridge() {
22831
23486
  },
22832
23487
  [postToParent2]
22833
23488
  );
22834
- const activate = (0, import_react19.useCallback)((el, options) => {
23489
+ const activate = (0, import_react20.useCallback)((el, options) => {
22835
23490
  if (activeElRef.current === el) return;
22836
23491
  document.querySelectorAll("[data-ohw-hovered]").forEach((hovered) => {
22837
23492
  hovered.removeAttribute("data-ohw-hovered");
@@ -22929,8 +23584,8 @@ function OhhwellsBridge() {
22929
23584
  openLogoSizePanelRef.current = openLogoSizePanel;
22930
23585
  deselectRef.current = deselect;
22931
23586
  closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
22932
- const lastSiteWideScopeRef = (0, import_react19.useRef)(null);
22933
- (0, import_react19.useEffect)(() => {
23587
+ const lastSiteWideScopeRef = (0, import_react20.useRef)(null);
23588
+ (0, import_react20.useEffect)(() => {
22934
23589
  if (!isEditMode) {
22935
23590
  if (lastSiteWideScopeRef.current !== false) {
22936
23591
  lastSiteWideScopeRef.current = false;
@@ -22956,7 +23611,7 @@ function OhhwellsBridge() {
22956
23611
  isFooterFrameSelection,
22957
23612
  postToParent2
22958
23613
  ]);
22959
- (0, import_react19.useLayoutEffect)(() => {
23614
+ (0, import_react20.useLayoutEffect)(() => {
22960
23615
  if (!subdomain || isEditMode) {
22961
23616
  setFetchState("done");
22962
23617
  return;
@@ -22977,6 +23632,7 @@ function OhhwellsBridge() {
22977
23632
  }
22978
23633
  if (typeof content[STYLE_STORE_KEY] === "string") {
22979
23634
  stylesRef.current = content[STYLE_STORE_KEY];
23635
+ document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
22980
23636
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
22981
23637
  }
22982
23638
  applyBrandChrome(content);
@@ -22985,12 +23641,12 @@ function OhhwellsBridge() {
22985
23641
  for (const [key, val] of Object.entries(content)) {
22986
23642
  if (key === "__ohw_sections") continue;
22987
23643
  if (key === AI_SECTIONS_KEY) continue;
23644
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
23645
+ if (LOGO_IMAGE_KEYS.includes(key)) continue;
22988
23646
  if (key === BRAND_KIT_KEY) continue;
22989
23647
  if (key === STYLE_STORE_KEY) continue;
22990
23648
  if (BRAND_CHROME_KEYS.has(key)) continue;
22991
- if (key === LOGO_PLACEHOLDER_KEY) continue;
22992
23649
  if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
22993
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
22994
23650
  if (applyVideoSettingNode(key, val)) continue;
22995
23651
  if (applyCarouselNode(key, val)) continue;
22996
23652
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -23062,7 +23718,9 @@ function OhhwellsBridge() {
23062
23718
  let cancelled = false;
23063
23719
  setFetchState("loading");
23064
23720
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
23065
- fetch(`${apiUrl}/api/public/sites/${subdomain}/content`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
23721
+ const initialPath = pathname;
23722
+ fetchedContentPaths.add(`${subdomain}::${initialPath}`);
23723
+ fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
23066
23724
  if (cancelled) return;
23067
23725
  const content = data?.content ?? {};
23068
23726
  const branding = Boolean(data?.showBranding);
@@ -23078,7 +23736,7 @@ function OhhwellsBridge() {
23078
23736
  cancelled = true;
23079
23737
  };
23080
23738
  }, [subdomain, isEditMode]);
23081
- (0, import_react19.useEffect)(() => {
23739
+ (0, import_react20.useEffect)(() => {
23082
23740
  if (!isEditMode) return;
23083
23741
  const resolveIndex = (form, clientY) => {
23084
23742
  const wrappers = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== fieldDragRef.current?.key);
@@ -23119,7 +23777,7 @@ function OhhwellsBridge() {
23119
23777
  window.removeEventListener("drop", onDrop, true);
23120
23778
  };
23121
23779
  }, [buildFieldDropSlots, isEditMode, persistFields, selectField]);
23122
- (0, import_react19.useEffect)(() => {
23780
+ (0, import_react20.useEffect)(() => {
23123
23781
  if (!isEditMode) return;
23124
23782
  const mark = () => document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
23125
23783
  markFormFields(form);
@@ -23131,7 +23789,7 @@ function OhhwellsBridge() {
23131
23789
  });
23132
23790
  return () => observer.disconnect();
23133
23791
  }, [isEditMode, fetchState, pathname]);
23134
- (0, import_react19.useEffect)(() => {
23792
+ (0, import_react20.useEffect)(() => {
23135
23793
  if (!isEditMode) return;
23136
23794
  let saveTimer = null;
23137
23795
  const onInput = (e) => {
@@ -23153,14 +23811,14 @@ function OhhwellsBridge() {
23153
23811
  document.addEventListener("input", onInput, true);
23154
23812
  return () => document.removeEventListener("input", onInput, true);
23155
23813
  }, [isEditMode, persistFields]);
23156
- (0, import_react19.useEffect)(() => {
23814
+ (0, import_react20.useEffect)(() => {
23157
23815
  if (isEditMode || fetchState !== "done") return;
23158
23816
  const content = contentCache.get(subdomain) ?? {};
23159
23817
  document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
23160
23818
  reconcileFieldsFromContent(form, content);
23161
23819
  });
23162
23820
  }, [isEditMode, fetchState, subdomain]);
23163
- (0, import_react19.useEffect)(() => {
23821
+ (0, import_react20.useEffect)(() => {
23164
23822
  if (!isEditMode) return;
23165
23823
  const swallow = (e) => {
23166
23824
  const target = e.target;
@@ -23169,14 +23827,14 @@ function OhhwellsBridge() {
23169
23827
  document.addEventListener("submit", swallow, true);
23170
23828
  return () => document.removeEventListener("submit", swallow, true);
23171
23829
  }, [isEditMode]);
23172
- (0, import_react19.useEffect)(() => {
23830
+ (0, import_react20.useEffect)(() => {
23173
23831
  if (isEditMode || fetchState !== "done") return;
23174
23832
  console.log("env", process.env.NEXT_PUBLIC_FLOWOPS_API_URL);
23175
23833
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
23176
23834
  console.log({ apiUrl, subdomain });
23177
23835
  bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
23178
23836
  }, [isEditMode, fetchState, subdomain]);
23179
- (0, import_react19.useEffect)(() => {
23837
+ (0, import_react20.useEffect)(() => {
23180
23838
  if (!subdomain || isEditMode) return;
23181
23839
  let debounceTimer = null;
23182
23840
  let observer = null;
@@ -23198,16 +23856,17 @@ function OhhwellsBridge() {
23198
23856
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
23199
23857
  }
23200
23858
  if (typeof content[STYLE_STORE_KEY] === "string") {
23859
+ document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
23201
23860
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
23202
23861
  }
23203
23862
  for (const [key, val] of Object.entries(content)) {
23204
23863
  if (key === "__ohw_sections") continue;
23205
23864
  if (key === AI_SECTIONS_KEY) continue;
23865
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
23866
+ if (LOGO_IMAGE_KEYS.includes(key)) continue;
23206
23867
  if (key === BRAND_KIT_KEY) continue;
23207
23868
  if (key === STYLE_STORE_KEY) continue;
23208
23869
  if (BRAND_CHROME_KEYS.has(key)) continue;
23209
- if (key === LOGO_PLACEHOLDER_KEY) continue;
23210
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
23211
23870
  if (applyVideoSettingNode(key, val)) continue;
23212
23871
  if (applyCarouselNode(key, val)) continue;
23213
23872
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -23259,6 +23918,17 @@ function OhhwellsBridge() {
23259
23918
  debounceTimer = setTimeout(applyFromCache, 150);
23260
23919
  };
23261
23920
  applyFromCache();
23921
+ const pathCacheKey = `${subdomain}::${pathname}`;
23922
+ if (!fetchedContentPaths.has(pathCacheKey)) {
23923
+ fetchedContentPaths.add(pathCacheKey);
23924
+ const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
23925
+ fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
23926
+ if (!data?.content) return;
23927
+ contentCache.set(subdomain, data.content);
23928
+ applyFromCache();
23929
+ }).catch(() => {
23930
+ });
23931
+ }
23262
23932
  observer = new MutationObserver(scheduleApply);
23263
23933
  observer.observe(document.body, { childList: true, subtree: true });
23264
23934
  return () => {
@@ -23266,16 +23936,16 @@ function OhhwellsBridge() {
23266
23936
  if (debounceTimer) clearTimeout(debounceTimer);
23267
23937
  };
23268
23938
  }, [subdomain, isEditMode, pathname]);
23269
- (0, import_react19.useLayoutEffect)(() => {
23939
+ (0, import_react20.useLayoutEffect)(() => {
23270
23940
  const el = document.getElementById("ohw-loader");
23271
23941
  if (!el) return;
23272
23942
  const visible = Boolean(subdomain) && fetchState !== "done";
23273
23943
  el.style.display = visible ? "flex" : "none";
23274
23944
  }, [subdomain, fetchState]);
23275
- (0, import_react19.useEffect)(() => {
23945
+ (0, import_react20.useEffect)(() => {
23276
23946
  postToParent2({ type: "ow:navigation", path: pathname });
23277
23947
  }, [pathname, postToParent2]);
23278
- (0, import_react19.useEffect)(() => {
23948
+ (0, import_react20.useEffect)(() => {
23279
23949
  if (!subdomain || isEditMode) return;
23280
23950
  const content = contentCache.get(subdomain);
23281
23951
  if (!content) return;
@@ -23291,7 +23961,7 @@ function OhhwellsBridge() {
23291
23961
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
23292
23962
  }
23293
23963
  }, [pathname, subdomain, isEditMode]);
23294
- (0, import_react19.useEffect)(() => {
23964
+ (0, import_react20.useEffect)(() => {
23295
23965
  if (!isEditMode) return;
23296
23966
  if (linkPopoverSessionRef.current?.intent === "add-nav") return;
23297
23967
  if (document.querySelector("[data-ohw-section-picker]")) return;
@@ -23299,11 +23969,11 @@ function OhhwellsBridge() {
23299
23969
  deselectRef.current();
23300
23970
  deactivateRef.current();
23301
23971
  }, [pathname, isEditMode]);
23302
- (0, import_react19.useEffect)(() => {
23972
+ (0, import_react20.useEffect)(() => {
23303
23973
  if (!isEditMode) return;
23304
23974
  initSectionInstancesFromContent(editContentRef.current, pathname);
23305
23975
  }, [pathname, isEditMode]);
23306
- (0, import_react19.useEffect)(() => {
23976
+ (0, import_react20.useEffect)(() => {
23307
23977
  if (!isEditMode) return;
23308
23978
  const observer = new MutationObserver(() => {
23309
23979
  const drawer = document.querySelector("[data-ohw-nav-drawer]");
@@ -23314,7 +23984,7 @@ function OhhwellsBridge() {
23314
23984
  observer.observe(document.body, { childList: true, subtree: true });
23315
23985
  return () => observer.disconnect();
23316
23986
  }, [isEditMode, pathname]);
23317
- (0, import_react19.useEffect)(() => {
23987
+ (0, import_react20.useEffect)(() => {
23318
23988
  const contentForNav = () => {
23319
23989
  if (isEditMode) return editContentRef.current;
23320
23990
  if (!subdomain) return {};
@@ -23387,7 +24057,7 @@ function OhhwellsBridge() {
23387
24057
  observer?.disconnect();
23388
24058
  };
23389
24059
  }, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
23390
- (0, import_react19.useEffect)(() => {
24060
+ (0, import_react20.useEffect)(() => {
23391
24061
  if (!isEditMode) return;
23392
24062
  let applying = false;
23393
24063
  let rafId = null;
@@ -23425,7 +24095,7 @@ function OhhwellsBridge() {
23425
24095
  observer.disconnect();
23426
24096
  };
23427
24097
  }, [isEditMode, pathname]);
23428
- (0, import_react19.useEffect)(() => {
24098
+ (0, import_react20.useEffect)(() => {
23429
24099
  if (!isEditMode) return;
23430
24100
  let lastPosted = 0;
23431
24101
  const measure = () => {
@@ -23447,29 +24117,14 @@ function OhhwellsBridge() {
23447
24117
  const t2 = setTimeout(measure, 500);
23448
24118
  const ro = new ResizeObserver(schedule);
23449
24119
  ro.observe(document.body);
23450
- let lastWidth = window.innerWidth;
23451
- let resizeTimers = [];
23452
- const clearResizeTimers = () => {
23453
- resizeTimers.forEach(clearTimeout);
23454
- resizeTimers = [];
23455
- };
23456
- const handleResize = () => {
23457
- if (window.innerWidth === lastWidth) return;
23458
- lastWidth = window.innerWidth;
23459
- clearResizeTimers();
23460
- resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
23461
- };
23462
- window.addEventListener("resize", handleResize);
23463
24120
  return () => {
23464
24121
  clearTimeout(t1);
23465
24122
  clearTimeout(t2);
23466
24123
  if (raf != null) cancelAnimationFrame(raf);
23467
24124
  ro.disconnect();
23468
- clearResizeTimers();
23469
- window.removeEventListener("resize", handleResize);
23470
24125
  };
23471
24126
  }, [pathname, isEditMode, postToParent2]);
23472
- (0, import_react19.useEffect)(() => {
24127
+ (0, import_react20.useEffect)(() => {
23473
24128
  if (!subdomainFromQuery || isEditMode) return;
23474
24129
  const handleClick = (e) => {
23475
24130
  const anchor = e.target.closest("a");
@@ -23485,7 +24140,7 @@ function OhhwellsBridge() {
23485
24140
  document.addEventListener("click", handleClick, true);
23486
24141
  return () => document.removeEventListener("click", handleClick, true);
23487
24142
  }, [subdomainFromQuery, isEditMode, router]);
23488
- (0, import_react19.useEffect)(() => {
24143
+ (0, import_react20.useEffect)(() => {
23489
24144
  if (!isEditMode) {
23490
24145
  editStylesRef.current?.base.remove();
23491
24146
  editStylesRef.current?.forceHover.remove();
@@ -23711,11 +24366,11 @@ function OhhwellsBridge() {
23711
24366
  footer [data-ohw-href-key] [data-ohw-editable][contenteditable],
23712
24367
  footer [data-ohw-href-key] [data-ohw-editable][contenteditable] * {
23713
24368
  outline: none !important;
23714
- caret-color: ${PRIMARY5} !important;
24369
+ caret-color: ${PRIMARY6} !important;
23715
24370
  cursor: text !important;
23716
24371
  }
23717
24372
  [data-ohw-editable][contenteditable]::selection,
23718
- [data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY5}59 !important; }
24373
+ [data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY6}59 !important; }
23719
24374
  [data-ohw-editable-state], [data-ohw-editable-state] * { pointer-events: none !important; }
23720
24375
  [data-ohw-editable-state][data-ohw-active-state] [data-ohw-editable] { pointer-events: auto !important; }
23721
24376
  [data-ohw-editable-state][data-ohw-active-state][data-ohw-editable] { pointer-events: auto !important; }
@@ -23761,6 +24416,13 @@ function OhhwellsBridge() {
23761
24416
  if (target.closest("[data-ohw-state-toggle]")) return;
23762
24417
  if (target.closest("[data-ohw-max-badge]")) return;
23763
24418
  if (isInsideLinkEditor(target)) return;
24419
+ if (isInsideFloatingPanel(target)) return;
24420
+ if (target.closest("[data-ohw-form-toolbar]")) return;
24421
+ if (target.closest(
24422
+ '[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
24423
+ )) {
24424
+ return;
24425
+ }
23764
24426
  if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
23765
24427
  clearMediaSelectionRef.current();
23766
24428
  }
@@ -23781,13 +24443,6 @@ function OhhwellsBridge() {
23781
24443
  return;
23782
24444
  }
23783
24445
  }
23784
- if (isInsideFloatingPanel(target)) return;
23785
- if (target.closest("[data-ohw-form-toolbar]")) return;
23786
- if (target.closest(
23787
- '[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
23788
- )) {
23789
- return;
23790
- }
23791
24446
  {
23792
24447
  const formEl = getFormElement(target);
23793
24448
  const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
@@ -24167,6 +24822,9 @@ function OhhwellsBridge() {
24167
24822
  setHoveredItemRect(null);
24168
24823
  hoveredNavContainerRef.current = null;
24169
24824
  setHoveredNavContainerRect(null);
24825
+ siblingHintElRef.current = null;
24826
+ setSiblingHintRect(null);
24827
+ setSiblingHintRects([]);
24170
24828
  return;
24171
24829
  }
24172
24830
  {
@@ -24287,7 +24945,6 @@ function OhhwellsBridge() {
24287
24945
  hoveredNavContainerRef.current = null;
24288
24946
  setHoveredNavContainerRect(null);
24289
24947
  hoveredItemElRef.current = editable;
24290
- setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
24291
24948
  }
24292
24949
  }
24293
24950
  }
@@ -24997,7 +25654,11 @@ function OhhwellsBridge() {
24997
25654
  };
24998
25655
  const handleMouseMove = (e) => {
24999
25656
  const { clientX, clientY } = e;
25000
- if (pointOwnedByFloatingPanel(clientX, clientY)) return;
25657
+ if (pointOwnedByFloatingPanel(clientX, clientY)) {
25658
+ dismissImageHover();
25659
+ clearImageHover();
25660
+ return;
25661
+ }
25001
25662
  if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
25002
25663
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
25003
25664
  formHoverElRef.current = null;
@@ -25026,7 +25687,12 @@ function OhhwellsBridge() {
25026
25687
  setHoveredItemRect(null);
25027
25688
  hoveredNavContainerRef.current = null;
25028
25689
  setHoveredNavContainerRect(null);
25690
+ siblingHintElRef.current = null;
25691
+ setSiblingHintRect(null);
25692
+ setSiblingHintRects([]);
25029
25693
  dismissImageHover();
25694
+ clearImageHover();
25695
+ setSectionGap(null);
25030
25696
  return;
25031
25697
  }
25032
25698
  if (probeSocialsRowAt(clientX, clientY)) return;
@@ -25038,7 +25704,11 @@ function OhhwellsBridge() {
25038
25704
  if (e.data?.type !== "ow:pointer-sync") return;
25039
25705
  const { clientX, clientY } = e.data;
25040
25706
  if (typeof clientX !== "number" || typeof clientY !== "number") return;
25041
- if (pointOwnedByFloatingPanel(clientX, clientY)) return;
25707
+ if (pointOwnedByFloatingPanel(clientX, clientY)) {
25708
+ dismissImageHover();
25709
+ clearImageHover();
25710
+ return;
25711
+ }
25042
25712
  if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
25043
25713
  if (probeSocialsRowAt(clientX, clientY)) return;
25044
25714
  probeSectionGapAt(clientX, clientY);
@@ -25384,6 +26054,7 @@ function OhhwellsBridge() {
25384
26054
  }
25385
26055
  if (typeof content[STYLE_STORE_KEY] === "string") {
25386
26056
  stylesRef.current = content[STYLE_STORE_KEY];
26057
+ document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
25387
26058
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
25388
26059
  }
25389
26060
  applyBrandChrome(content);
@@ -25396,12 +26067,12 @@ function OhhwellsBridge() {
25396
26067
  continue;
25397
26068
  }
25398
26069
  if (key === AI_SECTIONS_KEY) continue;
26070
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
26071
+ if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
25399
26072
  if (key === BRAND_KIT_KEY) continue;
25400
26073
  if (key === STYLE_STORE_KEY) continue;
25401
26074
  if (BRAND_CHROME_KEYS.has(key)) continue;
25402
- if (key === LOGO_PLACEHOLDER_KEY) continue;
25403
26075
  if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
25404
- if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
25405
26076
  if (applyVideoSettingNode(key, val)) continue;
25406
26077
  if (applyCarouselNode(key, val)) continue;
25407
26078
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -25847,6 +26518,12 @@ function OhhwellsBridge() {
25847
26518
  closeLinkPopoverRef.current();
25848
26519
  return;
25849
26520
  }
26521
+ if (floatingPanelOpenRef.current) {
26522
+ setFloatingPanelRef.current(null);
26523
+ deselectRef.current();
26524
+ deactivateRef.current();
26525
+ return;
26526
+ }
25850
26527
  deselectRef.current();
25851
26528
  deactivateRef.current();
25852
26529
  clearMediaSelectionRef.current();
@@ -26123,6 +26800,21 @@ function OhhwellsBridge() {
26123
26800
  type: "text",
26124
26801
  text: editContentRef.current[CUSTOM_CODE_AFTER_HEAD_KEY] ?? ""
26125
26802
  });
26803
+ nodes.push({
26804
+ key: BRAND_TITLE_KEY,
26805
+ type: "text",
26806
+ text: editContentRef.current[BRAND_TITLE_KEY] ?? ""
26807
+ });
26808
+ nodes.push({
26809
+ key: SITE_DESCRIPTION_KEY,
26810
+ type: "text",
26811
+ text: editContentRef.current[SITE_DESCRIPTION_KEY] ?? ""
26812
+ });
26813
+ nodes.push({
26814
+ key: SITE_OG_IMAGE_KEY,
26815
+ type: "text",
26816
+ text: editContentRef.current[SITE_OG_IMAGE_KEY] ?? ""
26817
+ });
26126
26818
  document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
26127
26819
  const formKey = formKeyOf(form);
26128
26820
  if (!formKey) return;
@@ -26145,8 +26837,12 @@ function OhhwellsBridge() {
26145
26837
  if (inserted) {
26146
26838
  const tracker = getSectionsTracker();
26147
26839
  postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
26148
- const h = document.body.scrollHeight;
26149
- if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
26840
+ const reportHeight = () => {
26841
+ const h = document.body.scrollHeight;
26842
+ if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
26843
+ };
26844
+ reportHeight();
26845
+ setTimeout(reportHeight, 500);
26150
26846
  }
26151
26847
  };
26152
26848
  const handleSwitchSchedule = (e) => {
@@ -26575,17 +27271,17 @@ function OhhwellsBridge() {
26575
27271
  window.removeEventListener("message", handleDeleteSection);
26576
27272
  window.removeEventListener("message", handleDuplicateSection);
26577
27273
  window.removeEventListener("message", handleDeactivate);
26578
- document.documentElement.removeAttribute("data-ohw-panel-dragging");
26579
27274
  window.removeEventListener("message", handleToastAction);
26580
27275
  window.removeEventListener("message", handleFormCount);
26581
27276
  window.removeEventListener("message", handleUiEscape);
27277
+ document.documentElement.removeAttribute("data-ohw-panel-dragging");
26582
27278
  autoSaveTimers.current.forEach(clearTimeout);
26583
27279
  autoSaveTimers.current.clear();
26584
27280
  if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
26585
27281
  if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
26586
27282
  };
26587
27283
  }, [isEditMode, refreshStateRules]);
26588
- (0, import_react19.useEffect)(() => {
27284
+ (0, import_react20.useEffect)(() => {
26589
27285
  if (!isEditMode) return;
26590
27286
  const THRESHOLD = 10;
26591
27287
  const resolveWasSelected = (el) => {
@@ -26741,7 +27437,7 @@ function OhhwellsBridge() {
26741
27437
  unlockFooterDragInteraction();
26742
27438
  };
26743
27439
  }, [isEditMode]);
26744
- (0, import_react19.useEffect)(() => {
27440
+ (0, import_react20.useEffect)(() => {
26745
27441
  if (!isEditMode) return;
26746
27442
  const THRESHOLD = 10;
26747
27443
  const onPointerDown = (e) => {
@@ -26832,7 +27528,7 @@ function OhhwellsBridge() {
26832
27528
  document.removeEventListener("selectstart", blockSelectStart, true);
26833
27529
  };
26834
27530
  }, [isEditMode, persistButtonCollectionDrag, refreshButtonDragVisuals]);
26835
- (0, import_react19.useEffect)(() => {
27531
+ (0, import_react20.useEffect)(() => {
26836
27532
  const handler = (e) => {
26837
27533
  if (e.data?.type !== "ow:request-schedule-config") return;
26838
27534
  const insertAfterVal = e.data.insertAfter;
@@ -26848,7 +27544,7 @@ function OhhwellsBridge() {
26848
27544
  window.addEventListener("message", handler);
26849
27545
  return () => window.removeEventListener("message", handler);
26850
27546
  }, [processConfigRequest]);
26851
- (0, import_react19.useEffect)(() => {
27547
+ (0, import_react20.useEffect)(() => {
26852
27548
  if (!isEditMode) return;
26853
27549
  document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
26854
27550
  el.removeAttribute("data-ohw-active-state");
@@ -26872,7 +27568,7 @@ function OhhwellsBridge() {
26872
27568
  postToParent2({
26873
27569
  type: "ow:ready",
26874
27570
  version: "1",
26875
- bridgeVersion: "0.1.123",
27571
+ bridgeVersion: "0.1.126",
26876
27572
  path: pathname,
26877
27573
  nodes: collectEditableNodes(editContentRef.current),
26878
27574
  sections
@@ -26884,13 +27580,13 @@ function OhhwellsBridge() {
26884
27580
  clearTimeout(timer);
26885
27581
  };
26886
27582
  }, [pathname, isEditMode, refreshStateRules, postToParent2]);
26887
- (0, import_react19.useEffect)(() => {
27583
+ (0, import_react20.useEffect)(() => {
26888
27584
  scrollToHashSectionWhenReady();
26889
27585
  const onHashChange = () => scrollToHashSectionWhenReady();
26890
27586
  window.addEventListener("hashchange", onHashChange);
26891
27587
  return () => window.removeEventListener("hashchange", onHashChange);
26892
27588
  }, [pathname]);
26893
- const handleCommand = (0, import_react19.useCallback)((cmd) => {
27589
+ const handleCommand = (0, import_react20.useCallback)((cmd) => {
26894
27590
  const el = activeElRef.current;
26895
27591
  const selBefore = window.getSelection();
26896
27592
  let savedOffsets = null;
@@ -26926,7 +27622,7 @@ function OhhwellsBridge() {
26926
27622
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
26927
27623
  refreshActiveCommandsRef.current();
26928
27624
  }, []);
26929
- (0, import_react19.useEffect)(() => {
27625
+ (0, import_react20.useEffect)(() => {
26930
27626
  const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
26931
27627
  if (!session || !logoSizeDraft) return;
26932
27628
  const onPanelAction = (e) => {
@@ -26964,7 +27660,7 @@ function OhhwellsBridge() {
26964
27660
  window.addEventListener("message", onPanelAction);
26965
27661
  return () => window.removeEventListener("message", onPanelAction);
26966
27662
  }, [floatingPanel, logoSizeDraft, editorViewport, persistLogoSizeDraft, closeFloatingPanelAndDeselect]);
26967
- const handleStateChange = (0, import_react19.useCallback)((state) => {
27663
+ const handleStateChange = (0, import_react20.useCallback)((state) => {
26968
27664
  if (!activeStateElRef.current) return;
26969
27665
  const el = activeStateElRef.current;
26970
27666
  if (state === "Default") {
@@ -26977,7 +27673,7 @@ function OhhwellsBridge() {
26977
27673
  }
26978
27674
  setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
26979
27675
  }, [deactivate]);
26980
- const reselectAfterLinkPopover = (0, import_react19.useCallback)(
27676
+ const reselectAfterLinkPopover = (0, import_react20.useCallback)(
26981
27677
  (hrefKey) => {
26982
27678
  requestAnimationFrame(() => {
26983
27679
  const el = resolveHrefKeyElement(hrefKey);
@@ -26986,7 +27682,7 @@ function OhhwellsBridge() {
26986
27682
  },
26987
27683
  [resolveHrefKeyElement]
26988
27684
  );
26989
- const closeLinkPopover = (0, import_react19.useCallback)(() => {
27685
+ const closeLinkPopover = (0, import_react20.useCallback)(() => {
26990
27686
  const session = linkPopoverSessionRef.current;
26991
27687
  addNavAfterAnchorRef.current = null;
26992
27688
  setLinkPopover(null);
@@ -26994,9 +27690,9 @@ function OhhwellsBridge() {
26994
27690
  reselectAfterLinkPopover(session.key);
26995
27691
  }
26996
27692
  }, [reselectAfterLinkPopover]);
26997
- const closeLinkPopoverRef = (0, import_react19.useRef)(closeLinkPopover);
27693
+ const closeLinkPopoverRef = (0, import_react20.useRef)(closeLinkPopover);
26998
27694
  closeLinkPopoverRef.current = closeLinkPopover;
26999
- const openLinkPopoverForActive = (0, import_react19.useCallback)(() => {
27695
+ const openLinkPopoverForActive = (0, import_react20.useCallback)(() => {
27000
27696
  const hrefCtx = getHrefKeyFromElement(activeElRef.current);
27001
27697
  if (!hrefCtx) return;
27002
27698
  bumpLinkPopoverGrace();
@@ -27007,7 +27703,7 @@ function OhhwellsBridge() {
27007
27703
  });
27008
27704
  deactivate();
27009
27705
  }, [deactivate]);
27010
- const openLinkPopoverForSelected = (0, import_react19.useCallback)(() => {
27706
+ const openLinkPopoverForSelected = (0, import_react20.useCallback)(() => {
27011
27707
  const anchor = selectedElRef.current;
27012
27708
  if (!anchor) return;
27013
27709
  const key = anchor.getAttribute("data-ohw-href-key");
@@ -27024,7 +27720,7 @@ function OhhwellsBridge() {
27024
27720
  });
27025
27721
  deselect();
27026
27722
  }, [deselect]);
27027
- const handleSelectParent = (0, import_react19.useCallback)(() => {
27723
+ const handleSelectParent = (0, import_react20.useCallback)(() => {
27028
27724
  const selected = selectedElRef.current;
27029
27725
  if (!selected) return;
27030
27726
  if (toolbarVariantRef.current === "select-frame") {
@@ -27051,7 +27747,7 @@ function OhhwellsBridge() {
27051
27747
  }
27052
27748
  deselectRef.current();
27053
27749
  }, []);
27054
- const handleDuplicateSelected = (0, import_react19.useCallback)(() => {
27750
+ const handleDuplicateSelected = (0, import_react20.useCallback)(() => {
27055
27751
  const selected = selectedElRef.current;
27056
27752
  if (!selected || !isNavigationItem2(selected)) return;
27057
27753
  if (isCtaButton(selected)) {
@@ -27214,7 +27910,7 @@ function OhhwellsBridge() {
27214
27910
  });
27215
27911
  }
27216
27912
  }, [postToParent2, tokensForButton]);
27217
- const runPendingDeleteUndo = (0, import_react19.useCallback)(() => {
27913
+ const runPendingDeleteUndo = (0, import_react20.useCallback)(() => {
27218
27914
  const pending = pendingDeleteUndoRef.current;
27219
27915
  if (!pending) return false;
27220
27916
  pendingDeleteUndoRef.current = null;
@@ -27222,7 +27918,7 @@ function OhhwellsBridge() {
27222
27918
  enforceLinkHrefs();
27223
27919
  return true;
27224
27920
  }, []);
27225
- const handleDeleteSelected = (0, import_react19.useCallback)(() => {
27921
+ const handleDeleteSelected = (0, import_react20.useCallback)(() => {
27226
27922
  const selected = selectedElRef.current;
27227
27923
  if (!selected) return false;
27228
27924
  if (isCtaButton(selected)) {
@@ -27275,7 +27971,7 @@ function OhhwellsBridge() {
27275
27971
  }, [postToParent2]);
27276
27972
  handleDeleteSelectedRef.current = handleDeleteSelected;
27277
27973
  runPendingDeleteUndoRef.current = runPendingDeleteUndo;
27278
- const handleLinkPopoverSubmit = (0, import_react19.useCallback)(
27974
+ const handleLinkPopoverSubmit = (0, import_react20.useCallback)(
27279
27975
  (target) => {
27280
27976
  const session = linkPopoverSessionRef.current;
27281
27977
  if (!session) return;
@@ -27341,14 +28037,14 @@ function OhhwellsBridge() {
27341
28037
  const showEditLink = toolbarShowEditLink;
27342
28038
  const currentSections = sectionsByPath[pathname] ?? [];
27343
28039
  linkPopoverOpenRef.current = linkPopover !== null;
27344
- const handleMediaSelect = (0, import_react19.useCallback)((key) => {
28040
+ const handleMediaSelect = (0, import_react20.useCallback)((key) => {
27345
28041
  const el = hoveredImageRef.current?.dataset.ohwKey === key ? hoveredImageRef.current : Array.from(document.querySelectorAll(MEDIA_SELECTOR)).find(
27346
28042
  (m) => (m.dataset.ohwKey ?? "") === key
27347
28043
  ) ?? null;
27348
28044
  if (!el) return;
27349
28045
  selectMediaElementRef.current(el);
27350
28046
  }, []);
27351
- const handleMediaReplace = (0, import_react19.useCallback)(
28047
+ const handleMediaReplace = (0, import_react20.useCallback)(
27352
28048
  (key) => {
27353
28049
  postToParent2({
27354
28050
  type: "ow:image-pick",
@@ -27358,13 +28054,13 @@ function OhhwellsBridge() {
27358
28054
  },
27359
28055
  [postToParent2, mediaHover?.elementType, selectedMedia?.elementType]
27360
28056
  );
27361
- const handleEditCarousel = (0, import_react19.useCallback)(
28057
+ const handleEditCarousel = (0, import_react20.useCallback)(
27362
28058
  (key) => {
27363
28059
  postToParent2({ type: "ow:carousel-open", key, images: readCarouselValue(key) });
27364
28060
  },
27365
28061
  [postToParent2]
27366
28062
  );
27367
- const handleMediaFadeOutComplete = (0, import_react19.useCallback)((key) => {
28063
+ const handleMediaFadeOutComplete = (0, import_react20.useCallback)((key) => {
27368
28064
  setUploadingRects((prev) => {
27369
28065
  if (!(key in prev)) return prev;
27370
28066
  const next = { ...prev };
@@ -27372,7 +28068,7 @@ function OhhwellsBridge() {
27372
28068
  return next;
27373
28069
  });
27374
28070
  }, []);
27375
- const handleVideoSettingsChange = (0, import_react19.useCallback)(
28071
+ const handleVideoSettingsChange = (0, import_react20.useCallback)(
27376
28072
  (key, settings) => {
27377
28073
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
27378
28074
  const video = getVideoEl2(el);
@@ -27394,14 +28090,14 @@ function OhhwellsBridge() {
27394
28090
  },
27395
28091
  [postToParent2]
27396
28092
  );
27397
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
27398
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { id: "ohw-loader", suppressHydrationWarning: true, style: { ...OHW_LOADER_STYLE, display: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(OhwLoaderSpinner, {}) }),
27399
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("script", { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: OHW_LOADER_PREHYDRATE_SCRIPT } }),
27400
- subdomain && !isEditMode && showBranding && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(MadeWithOhhWells, {}),
28093
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
28094
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { id: "ohw-loader", suppressHydrationWarning: true, style: { ...OHW_LOADER_STYLE, display: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(OhwLoaderSpinner, {}) }),
28095
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("script", { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: OHW_LOADER_PREHYDRATE_SCRIPT } }),
28096
+ subdomain && !isEditMode && showBranding && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(MadeWithOhhWells, {}),
27401
28097
  bridgeRoot ? (0, import_react_dom5.createPortal)(
27402
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
27403
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
27404
- isEditMode && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28098
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
28099
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
28100
+ isEditMode && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27405
28101
  AiSectionOverlay,
27406
28102
  {
27407
28103
  postToParent: postToParent2,
@@ -27409,7 +28105,7 @@ function OhhwellsBridge() {
27409
28105
  onSelectionChange: handleAiSectionSelectionChange
27410
28106
  }
27411
28107
  ),
27412
- isEditMode && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28108
+ isEditMode && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27413
28109
  AiMediaStripOverlay,
27414
28110
  {
27415
28111
  postToParent: postToParent2,
@@ -27418,7 +28114,7 @@ function OhhwellsBridge() {
27418
28114
  clearInteractionChromeRef
27419
28115
  }
27420
28116
  ),
27421
- isEditMode && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28117
+ isEditMode && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27422
28118
  AiPricingCardOverlay,
27423
28119
  {
27424
28120
  postToParent: postToParent2,
@@ -27426,12 +28122,21 @@ function OhhwellsBridge() {
27426
28122
  applyTreeLocalRef
27427
28123
  }
27428
28124
  ),
27429
- isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28125
+ isEditMode && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
28126
+ AiVideoOverlay,
28127
+ {
28128
+ postToParent: postToParent2,
28129
+ aiSectionsRef,
28130
+ applyTreeLocalRef,
28131
+ clearInteractionChromeRef
28132
+ }
28133
+ ),
28134
+ isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27430
28135
  "div",
27431
28136
  {
27432
28137
  className: "pointer-events-none fixed z-2147483646",
27433
28138
  style: { left: slot.left, top: slot.y, width: slot.width, height: 3, transform: "translateY(-50%)" },
27434
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28139
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27435
28140
  DropIndicator,
27436
28141
  {
27437
28142
  direction: "horizontal",
@@ -27442,7 +28147,7 @@ function OhhwellsBridge() {
27442
28147
  },
27443
28148
  `section-drop-${slot.insertIndex}-${i}`
27444
28149
  )),
27445
- Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28150
+ Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27446
28151
  MediaOverlay,
27447
28152
  {
27448
28153
  hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
@@ -27453,7 +28158,7 @@ function OhhwellsBridge() {
27453
28158
  },
27454
28159
  `uploading-${key}`
27455
28160
  )),
27456
- mediaHover && !(mediaHover.key in uploadingRects) && mediaHover.key !== selectedMedia?.key && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28161
+ mediaHover && !(mediaHover.key in uploadingRects) && mediaHover.key !== selectedMedia?.key && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27457
28162
  MediaOverlay,
27458
28163
  {
27459
28164
  hover: mediaHover,
@@ -27464,7 +28169,7 @@ function OhhwellsBridge() {
27464
28169
  onVideoSettingsChange: handleVideoSettingsChange
27465
28170
  }
27466
28171
  ),
27467
- selectedMedia && !(selectedMedia.key in uploadingRects) && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28172
+ selectedMedia && !(selectedMedia.key in uploadingRects) && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27468
28173
  MediaOverlay,
27469
28174
  {
27470
28175
  hover: selectedMedia,
@@ -27476,7 +28181,7 @@ function OhhwellsBridge() {
27476
28181
  onVideoSettingsChange: handleVideoSettingsChange
27477
28182
  }
27478
28183
  ),
27479
- carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28184
+ carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27480
28185
  CarouselOverlay,
27481
28186
  {
27482
28187
  hover: carouselHover,
@@ -27484,10 +28189,10 @@ function OhhwellsBridge() {
27484
28189
  cueOnly: !!carouselHover.fullBleedSectionId && carouselHover.fullBleedSectionId !== selectedAiSectionId
27485
28190
  }
27486
28191
  ),
27487
- siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
27488
- siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
27489
- isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && selectedElRef.current !== buttonCollectionDragRef.current && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
27490
- isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28192
+ siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
28193
+ siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
28194
+ isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && selectedElRef.current !== buttonCollectionDragRef.current && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
28195
+ isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27491
28196
  "div",
27492
28197
  {
27493
28198
  className: "pointer-events-none fixed z-2147483646",
@@ -27497,7 +28202,7 @@ function OhhwellsBridge() {
27497
28202
  width: slot.width,
27498
28203
  height: slot.height
27499
28204
  },
27500
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28205
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27501
28206
  DropIndicator,
27502
28207
  {
27503
28208
  direction: slot.direction,
@@ -27508,7 +28213,7 @@ function OhhwellsBridge() {
27508
28213
  },
27509
28214
  `footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
27510
28215
  )),
27511
- isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28216
+ isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27512
28217
  "div",
27513
28218
  {
27514
28219
  className: "pointer-events-none fixed z-2147483646",
@@ -27518,7 +28223,7 @@ function OhhwellsBridge() {
27518
28223
  width: slot.width,
27519
28224
  height: slot.height
27520
28225
  },
27521
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28226
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27522
28227
  DropIndicator,
27523
28228
  {
27524
28229
  direction: slot.direction,
@@ -27529,7 +28234,7 @@ function OhhwellsBridge() {
27529
28234
  },
27530
28235
  `nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
27531
28236
  )),
27532
- isItemDragging && buttonDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28237
+ isItemDragging && buttonDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27533
28238
  "div",
27534
28239
  {
27535
28240
  className: "pointer-events-none fixed z-2147483646",
@@ -27539,7 +28244,7 @@ function OhhwellsBridge() {
27539
28244
  width: slot.width,
27540
28245
  height: slot.height
27541
28246
  },
27542
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28247
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27543
28248
  DropIndicator,
27544
28249
  {
27545
28250
  direction: slot.direction,
@@ -27550,10 +28255,10 @@ function OhhwellsBridge() {
27550
28255
  },
27551
28256
  `button-drop-${slot.direction}-${slot.insertIndex}-${i}`
27552
28257
  )),
27553
- hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
27554
- hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
27555
- hoveredTextRect && !hoveredNavContainerRect && !hoveredItemRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
27556
- formPickRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28258
+ hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
28259
+ hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
28260
+ hoveredTextRect && !hoveredNavContainerRect && !hoveredItemRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
28261
+ formPickRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27557
28262
  ItemInteractionLayer,
27558
28263
  {
27559
28264
  rect: formPickRect,
@@ -27561,13 +28266,13 @@ function OhhwellsBridge() {
27561
28266
  itemDragSurface: false,
27562
28267
  toolbarAlign: "left",
27563
28268
  chromeGap: 24,
27564
- toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
28269
+ toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
27565
28270
  "div",
27566
28271
  {
27567
28272
  "data-ohw-form-toolbar": "",
27568
28273
  className: "pointer-events-auto flex items-center gap-0.5 whitespace-nowrap rounded-lg border border-border bg-background p-1 shadow-md",
27569
28274
  children: [
27570
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28275
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27571
28276
  "button",
27572
28277
  {
27573
28278
  type: "button",
@@ -27575,11 +28280,11 @@ function OhhwellsBridge() {
27575
28280
  className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
27576
28281
  onClick: () => setFieldTypePickerOpen((open) => !open),
27577
28282
  "data-ohw-add-field": "",
27578
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Plus, { size: 15, "aria-hidden": true })
28283
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react21.Plus, { size: 15, "aria-hidden": true })
27579
28284
  }
27580
28285
  ),
27581
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
27582
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
28286
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
28287
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
27583
28288
  "button",
27584
28289
  {
27585
28290
  type: "button",
@@ -27595,11 +28300,11 @@ function OhhwellsBridge() {
27595
28300
  });
27596
28301
  },
27597
28302
  children: [
27598
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Settings, { size: 14, "aria-hidden": true }),
28303
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react21.Settings, { size: 14, "aria-hidden": true }),
27599
28304
  "Form settings",
27600
28305
  formPickCount ? (
27601
28306
  // Counter pill, per the design — not a text suffix.
27602
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28307
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27603
28308
  "span",
27604
28309
  {
27605
28310
  "data-ohw-form-count": "",
@@ -27611,8 +28316,8 @@ function OhhwellsBridge() {
27611
28316
  ]
27612
28317
  }
27613
28318
  ),
27614
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
27615
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex items-center rounded-md bg-muted/70 p-0.5", children: ["default", "success"].map((state) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28319
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
28320
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex items-center rounded-md bg-muted/70 p-0.5", children: ["default", "success"].map((state) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27616
28321
  "button",
27617
28322
  {
27618
28323
  type: "button",
@@ -27643,7 +28348,7 @@ function OhhwellsBridge() {
27643
28348
  )
27644
28349
  }
27645
28350
  ),
27646
- formHoverRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28351
+ formHoverRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27647
28352
  ItemInteractionLayer,
27648
28353
  {
27649
28354
  rect: formHoverRect,
@@ -27651,7 +28356,7 @@ function OhhwellsBridge() {
27651
28356
  chromeGap: formHoverElRef.current && getFieldWrapper(formHoverElRef.current) ? 8 : 24
27652
28357
  }
27653
28358
  ),
27654
- fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28359
+ fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27655
28360
  ItemInteractionLayer,
27656
28361
  {
27657
28362
  rect: fieldPickRect,
@@ -27663,7 +28368,7 @@ function OhhwellsBridge() {
27663
28368
  dragHandleLabel: "Reorder field",
27664
28369
  onDragHandleDragStart: handleFieldDragStart,
27665
28370
  onDragHandleDragEnd: handleFieldDragEnd,
27666
- toolbar: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28371
+ toolbar: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27667
28372
  FormFieldToolbar,
27668
28373
  {
27669
28374
  type: fieldPickState.type,
@@ -27676,12 +28381,12 @@ function OhhwellsBridge() {
27676
28381
  )
27677
28382
  }
27678
28383
  ),
27679
- fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28384
+ fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27680
28385
  "div",
27681
28386
  {
27682
28387
  className: "pointer-events-none fixed z-[2147483644]",
27683
28388
  style: { top: slot.top, left: slot.left, width: slot.width },
27684
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28389
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27685
28390
  DropIndicator,
27686
28391
  {
27687
28392
  direction: "horizontal",
@@ -27694,7 +28399,7 @@ function OhhwellsBridge() {
27694
28399
  )) : null,
27695
28400
  fieldTypePickerOpen && formPickRect ? (() => {
27696
28401
  const toolbar = document.querySelector("[data-ohw-form-toolbar]")?.getBoundingClientRect();
27697
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28402
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27698
28403
  "div",
27699
28404
  {
27700
28405
  className: "pointer-events-none fixed z-[2147483645]",
@@ -27702,12 +28407,12 @@ function OhhwellsBridge() {
27702
28407
  top: toolbar ? toolbar.bottom + 6 : formPickRect.top + 16,
27703
28408
  left: toolbar ? toolbar.left : formPickRect.left + 24
27704
28409
  },
27705
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(FieldTypePicker, { onPick: handleAddField })
28410
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(FieldTypePicker, { onPick: handleAddField })
27706
28411
  }
27707
28412
  );
27708
28413
  })() : null,
27709
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
27710
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28414
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
28415
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27711
28416
  FooterContainerChrome,
27712
28417
  {
27713
28418
  rect: toolbarRect,
@@ -27715,7 +28420,7 @@ function OhhwellsBridge() {
27715
28420
  addDisabled: !canAddFooterColumn()
27716
28421
  }
27717
28422
  ),
27718
- toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28423
+ toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27719
28424
  ItemInteractionLayer,
27720
28425
  {
27721
28426
  rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected || selectedElRef.current === buttonCollectionDragRef.current) ? draggedItemRect : toolbarRect,
@@ -27735,7 +28440,7 @@ function OhhwellsBridge() {
27735
28440
  onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
27736
28441
  onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
27737
28442
  itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection && !selectedIsSocialsRow,
27738
- toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28443
+ toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27739
28444
  ItemActionToolbar,
27740
28445
  {
27741
28446
  onEditLink: openLinkPopoverForSelected,
@@ -27786,8 +28491,8 @@ function OhhwellsBridge() {
27786
28491
  ) : void 0
27787
28492
  }
27788
28493
  ),
27789
- toolbarRect && toolbarVariant === "rich-text" && !linkPopover && !isRectOutsideClip(toolbarRect, getIframeVisibleClip(parentScrollRef.current)) && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
27790
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28494
+ toolbarRect && toolbarVariant === "rich-text" && !linkPopover && !isRectOutsideClip(toolbarRect, getIframeVisibleClip(parentScrollRef.current)) && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
28495
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27791
28496
  EditGlowChrome,
27792
28497
  {
27793
28498
  rect: toolbarRect,
@@ -27797,7 +28502,7 @@ function OhhwellsBridge() {
27797
28502
  hideHandle: isItemDragging
27798
28503
  }
27799
28504
  ),
27800
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28505
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27801
28506
  FloatingToolbar,
27802
28507
  {
27803
28508
  rect: toolbarRect,
@@ -27810,7 +28515,7 @@ function OhhwellsBridge() {
27810
28515
  }
27811
28516
  )
27812
28517
  ] }),
27813
- maxBadge && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
28518
+ maxBadge && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
27814
28519
  "div",
27815
28520
  {
27816
28521
  "data-ohw-max-badge": "",
@@ -27836,7 +28541,7 @@ function OhhwellsBridge() {
27836
28541
  ]
27837
28542
  }
27838
28543
  ),
27839
- toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28544
+ toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27840
28545
  StateToggle,
27841
28546
  {
27842
28547
  rect: toggleState.rect,
@@ -27845,15 +28550,15 @@ function OhhwellsBridge() {
27845
28550
  onStateChange: handleStateChange
27846
28551
  }
27847
28552
  ),
27848
- sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
28553
+ sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
27849
28554
  "div",
27850
28555
  {
27851
28556
  "data-ohw-section-insert-line": "",
27852
28557
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
27853
28558
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
27854
28559
  children: [
27855
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
27856
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28560
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
28561
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27857
28562
  Badge,
27858
28563
  {
27859
28564
  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",
@@ -27870,11 +28575,11 @@ function OhhwellsBridge() {
27870
28575
  children: "Add Section"
27871
28576
  }
27872
28577
  ),
27873
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
28578
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
27874
28579
  ]
27875
28580
  }
27876
28581
  ),
27877
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28582
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27878
28583
  LinkPopover,
27879
28584
  {
27880
28585
  panelRef: linkPopoverPanelRef,
@@ -27891,7 +28596,7 @@ function OhhwellsBridge() {
27891
28596
  },
27892
28597
  linkPopover.key
27893
28598
  ) : null,
27894
- floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28599
+ floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27895
28600
  FloatingPanel,
27896
28601
  {
27897
28602
  open: true,
@@ -27901,7 +28606,7 @@ function OhhwellsBridge() {
27901
28606
  onPositionChange: setFloatingPanelPos,
27902
28607
  parentScroll: parentScrollSnap ?? parentScrollRef.current,
27903
28608
  onClose: closeFloatingPanelOnly,
27904
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28609
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27905
28610
  SocialsDisplayPanel,
27906
28611
  {
27907
28612
  display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
@@ -27922,19 +28627,19 @@ function OhhwellsBridge() {
27922
28627
  const tokens = tokensFromButton(button);
27923
28628
  const current = assignmentFor(button, editContentRef.current, tokens);
27924
28629
  void buttonStyleTick;
27925
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28630
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27926
28631
  FloatingPanel,
27927
28632
  {
27928
28633
  open: true,
27929
28634
  title: floatingPanel.title,
27930
28635
  context: floatingPanel.context,
27931
- icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Brush, { className: "size-4 shrink-0", "aria-hidden": true }),
28636
+ icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react21.Brush, { className: "size-4 shrink-0", "aria-hidden": true }),
27932
28637
  position: floatingPanelPos,
27933
28638
  onPositionChange: setFloatingPanelPos,
27934
28639
  parentScroll: parentScrollSnap ?? parentScrollRef.current,
27935
28640
  onClose: closeFloatingPanelOnly,
27936
28641
  bodyClassName: "gap-5",
27937
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28642
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27938
28643
  ButtonStylePanel,
27939
28644
  {
27940
28645
  variants: tokens.variants,
@@ -27959,6 +28664,59 @@ function OhhwellsBridge() {
27959
28664
  ) : null
27960
28665
  ] });
27961
28666
  }
28667
+
28668
+ // src/ui/EmptySection.tsx
28669
+ var import_link = __toESM(require("next/link"), 1);
28670
+ var import_jsx_runtime38 = require("react/jsx-runtime");
28671
+ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
28672
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
28673
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
28674
+ "p",
28675
+ {
28676
+ style: {
28677
+ fontFamily: "var(--brand-font-body)",
28678
+ fontSize: "0.75rem",
28679
+ fontWeight: 500,
28680
+ letterSpacing: "0.15em",
28681
+ textTransform: "uppercase",
28682
+ color: "var(--brand-accent)",
28683
+ marginBottom: "1.5rem"
28684
+ },
28685
+ children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_link.default, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
28686
+ }
28687
+ ),
28688
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
28689
+ "h1",
28690
+ {
28691
+ style: {
28692
+ fontFamily: "var(--brand-font-heading)",
28693
+ fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
28694
+ lineHeight: 1.1,
28695
+ letterSpacing: "-0.025em",
28696
+ color: "var(--brand-text)",
28697
+ marginBottom: "1rem"
28698
+ },
28699
+ ...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
28700
+ children: title
28701
+ }
28702
+ ),
28703
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
28704
+ "p",
28705
+ {
28706
+ style: {
28707
+ fontFamily: "var(--brand-font-body)",
28708
+ fontSize: "1rem",
28709
+ lineHeight: 1.7,
28710
+ fontWeight: 300,
28711
+ color: "var(--brand-text-muted)",
28712
+ maxWidth: "340px"
28713
+ },
28714
+ ...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
28715
+ children: "This page doesn't have any content yet."
28716
+ }
28717
+ )
28718
+ ] });
28719
+ }
27962
28720
  // Annotate the CommonJS export names for ESM import in node:
27963
28721
  0 && (module.exports = {
27964
28722
  AI_DEFAULT_BRAND,
@@ -27976,6 +28734,7 @@ function OhhwellsBridge() {
27976
28734
  DropdownMenuItem,
27977
28735
  DropdownMenuSeparator,
27978
28736
  DropdownMenuTrigger,
28737
+ EmptySection,
27979
28738
  ItemActionToolbar,
27980
28739
  ItemInteractionLayer,
27981
28740
  LinkEditorPanel,