@ohhwells/bridge 0.1.123 → 0.1.124-next.344

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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,112 @@ 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
+ borderRadius: AI_TREE_TOKENS.radiusCard,
1896
+ overflow: "hidden",
1897
+ background: "#DBEAFE"
1898
+ },
1899
+ children: !videoId ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1900
+ "div",
1901
+ {
1902
+ style: {
1903
+ position: "absolute",
1904
+ inset: 0,
1905
+ display: "flex",
1906
+ alignItems: "center",
1907
+ justifyContent: "center",
1908
+ color: "#93C5FD",
1909
+ fontSize: 13
1910
+ },
1911
+ children: "video"
1912
+ }
1913
+ ) : playing ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1914
+ "iframe",
1915
+ {
1916
+ src: `https://www.youtube-nocookie.com/embed/${videoId}?autoplay=1&mute=1`,
1917
+ title: caption || "YouTube video",
1918
+ style: { position: "absolute", inset: 0, width: "100%", height: "100%", border: 0 },
1919
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
1920
+ sandbox: "allow-scripts allow-same-origin allow-presentation allow-popups allow-popups-to-escape-sandbox",
1921
+ loading: "lazy"
1922
+ }
1923
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1924
+ "button",
1925
+ {
1926
+ type: "button",
1927
+ onClick: () => setPlaying(true),
1928
+ "aria-label": "Play video",
1929
+ style: {
1930
+ position: "absolute",
1931
+ inset: 0,
1932
+ width: "100%",
1933
+ height: "100%",
1934
+ border: 0,
1935
+ padding: 0,
1936
+ margin: 0,
1937
+ cursor: "pointer",
1938
+ background: "none"
1939
+ },
1940
+ children: [
1941
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1942
+ "img",
1943
+ {
1944
+ src: `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`,
1945
+ alt: "",
1946
+ style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
1947
+ }
1948
+ ),
1949
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1950
+ "span",
1951
+ {
1952
+ style: {
1953
+ position: "absolute",
1954
+ top: "50%",
1955
+ left: "50%",
1956
+ transform: "translate(-50%, -50%)",
1957
+ width: 64,
1958
+ height: 64,
1959
+ borderRadius: "50%",
1960
+ background: "rgba(0,0,0,0.65)",
1961
+ display: "flex",
1962
+ alignItems: "center",
1963
+ justifyContent: "center"
1964
+ },
1965
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Play, { size: 28, color: "#fff", fill: "#fff" })
1966
+ }
1967
+ )
1968
+ ]
1969
+ }
1970
+ )
1971
+ }
1972
+ ),
1973
+ caption && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1974
+ "div",
1975
+ {
1976
+ ...textAttrs(ctx, `${path}.caption`),
1977
+ style: {
1978
+ ...typeStyle(AI_TREE_TOKENS.type.bodyM, ctx.brand.fonts.body),
1979
+ color: ctx.brand.palette.dark,
1980
+ textAlign: "center"
1981
+ },
1982
+ children: caption
1983
+ }
1984
+ )
1985
+ ] });
1986
+ }
1833
1987
  function ButtonEl({
1834
1988
  slots,
1835
1989
  ctx,
@@ -2837,7 +2991,7 @@ function CollectionBlock({ node, ctx, path }) {
2837
2991
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2838
2992
  "div",
2839
2993
  {
2840
- "data-ai-grid": "",
2994
+ "data-ai-grid": String(itemsPerRow),
2841
2995
  "data-ohw-pricing-collection": isPricing ? "" : void 0,
2842
2996
  style: {
2843
2997
  display: "grid",
@@ -2910,6 +3064,8 @@ function renderNode(node, ctx, path) {
2910
3064
  editPath: `${path}.source`
2911
3065
  }
2912
3066
  );
3067
+ case "video":
3068
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VideoEmbed, { slots, ctx, path });
2913
3069
  case "media-list": {
2914
3070
  const stacked = slots.layout === "stack";
2915
3071
  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 +3352,7 @@ function AiTreeRenderer({
3196
3352
  {
3197
3353
  "data-ai-section": tree.tag ?? "",
3198
3354
  ...bgAttrs,
3355
+ "data-ai-responsive": "",
3199
3356
  style: {
3200
3357
  position: "relative",
3201
3358
  padding: `${pad}px 0`,
@@ -3206,12 +3363,13 @@ function AiTreeRenderer({
3206
3363
  color: settings.sectionBackground === "accent" ? blockBrand.palette.dark : void 0
3207
3364
  },
3208
3365
  children: [
3209
- isOverlay && backgroundUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
3366
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
3210
3367
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
3368
+ isOverlay && backgroundUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
3211
3369
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3212
3370
  "div",
3213
3371
  {
3214
- "data-ai-container": "",
3372
+ "data-ai-section-inner": "",
3215
3373
  style: {
3216
3374
  position: "relative",
3217
3375
  maxWidth: AI_TREE_TOKENS.sectionMaxWidth,
@@ -3222,7 +3380,7 @@ function AiTreeRenderer({
3222
3380
  children: tree.rows.map((row, r2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3223
3381
  "div",
3224
3382
  {
3225
- "data-ai-row": "",
3383
+ "data-ai-columns": "",
3226
3384
  style: {
3227
3385
  display: "grid",
3228
3386
  gridTemplateColumns: "repeat(12, 1fr)",
@@ -3626,9 +3784,10 @@ function applyAiSectionsToDom(state, options) {
3626
3784
  if (existing && existing.serialized === serialized && existing.container.isConnected) {
3627
3785
  continue;
3628
3786
  }
3629
- const isNewMount = !existing || !existing.container.isConnected;
3630
3787
  let container = existing?.container;
3788
+ let isNewMount = false;
3631
3789
  if (!container || !container.isConnected) {
3790
+ isNewMount = true;
3632
3791
  existing?.root.unmount();
3633
3792
  container?.remove();
3634
3793
  container = document.createElement("div");
@@ -4017,6 +4176,7 @@ function EmptyState({ inEditor, insertAfter }) {
4017
4176
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4018
4177
  "button",
4019
4178
  {
4179
+ "data-ohw-bridge": true,
4020
4180
  onClick: handleAddSchedule,
4021
4181
  className: "h-9 px-2 py-1.5 flex items-center justify-center bg-white border border-[#E7E5E4] rounded-md font-body text-sm font-medium text-(--color-dark,#200C02) cursor-pointer",
4022
4182
  children: "Add Schedule"
@@ -4434,7 +4594,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
4434
4594
  const timer = setTimeout(() => {
4435
4595
  if (!done) {
4436
4596
  done = true;
4437
- setLoading(false);
4597
+ innerCleanup = loadWithId(null);
4438
4598
  }
4439
4599
  }, 2e3);
4440
4600
  const configHandler = (e) => {
@@ -9522,6 +9682,7 @@ function MediaOverlay({
9522
9682
  (prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
9523
9683
  );
9524
9684
  }, [isVideo]);
9685
+ const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
9525
9686
  const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
9526
9687
  const box = {
9527
9688
  position: "fixed",
@@ -9620,11 +9781,10 @@ function MediaOverlay({
9620
9781
  className: "flex items-center justify-center cursor-pointer",
9621
9782
  style: {
9622
9783
  ...box,
9623
- // When text overlays this media, let clicks fall THROUGH to the text underneath. In the
9624
- // parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
9625
- // in-document, pointer-events does it natively. The button below opts back in, so
9626
- // Replace still works.
9627
- pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
9784
+ // Visual only. `pointer-events: auto` on this full-bleed rect covered the navbar
9785
+ // (hero bg includes the absolute TopNav) and swallowed CTA press-drag. Text overlay
9786
+ // and cueOnly also need clicks to fall through — Replace / video controls opt back in.
9787
+ pointerEvents: "none",
9628
9788
  // Selected: a firm component ring with no wash, so the image reads as chosen rather
9629
9789
  // than hovered. Hover keeps the existing tinted preview.
9630
9790
  boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
@@ -9651,17 +9811,17 @@ function MediaOverlay({
9651
9811
  },
9652
9812
  children: [
9653
9813
  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 }),
9654
- isVideo ? "Replace video" : "Replace image"
9814
+ replaceLabel
9655
9815
  ]
9656
9816
  }
9657
9817
  ),
9658
- replaceMode === "none" || cueOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9818
+ showChrome && replaceMode !== "none" && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9659
9819
  Button,
9660
9820
  {
9661
9821
  "data-ohw-media-overlay": "",
9662
9822
  variant: "outline",
9663
9823
  size: "sm",
9664
- "aria-label": isVideo ? "Replace video" : "Replace image",
9824
+ "aria-label": replaceLabel,
9665
9825
  className: "gap-1.5 cursor-pointer hover:bg-background",
9666
9826
  style: {
9667
9827
  ...OVERLAY_BUTTON_STYLE,
@@ -9684,7 +9844,7 @@ function MediaOverlay({
9684
9844
  },
9685
9845
  children: [
9686
9846
  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 }),
9687
- replaceMode === "full" ? isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image" : null
9847
+ replaceMode === "full" ? replaceLabel : null
9688
9848
  ]
9689
9849
  }
9690
9850
  )
@@ -11458,6 +11618,486 @@ function AiPricingCardOverlay({
11458
11618
  ] });
11459
11619
  }
11460
11620
 
11621
+ // src/ui/ai-section/AiVideoOverlay.tsx
11622
+ var import_react11 = require("react");
11623
+ var import_lucide_react10 = require("lucide-react");
11624
+
11625
+ // src/lib/ai-video-tree.ts
11626
+ function resolveVideoBlock(tree, path) {
11627
+ const segments = path.split(".");
11628
+ const rowSeg = segments[0];
11629
+ const blockSeg = segments[1];
11630
+ if (!rowSeg?.startsWith("r") || !blockSeg?.startsWith("b")) return null;
11631
+ let node = tree.rows[Number(rowSeg.slice(1))]?.blocks[Number(blockSeg.slice(1))];
11632
+ for (const seg of segments.slice(2)) {
11633
+ if (!node || !seg.startsWith("c")) return null;
11634
+ node = node.children?.[Number(seg.slice(1))];
11635
+ }
11636
+ return node && node.type === "video" ? node : null;
11637
+ }
11638
+ function withVideo(tree, path, mutate) {
11639
+ const next = JSON.parse(JSON.stringify(tree));
11640
+ const block = resolveVideoBlock(next, path);
11641
+ if (!block) return null;
11642
+ block.slots = block.slots ?? {};
11643
+ return mutate(block) ? next : null;
11644
+ }
11645
+ function videoIdAt(tree, path) {
11646
+ const block = resolveVideoBlock(tree, path);
11647
+ const id = block?.slots?.videoId;
11648
+ return typeof id === "string" ? id : "";
11649
+ }
11650
+ function setVideoId(tree, path, videoId) {
11651
+ return withVideo(tree, path, (block) => {
11652
+ block.slots = { ...block.slots, videoId };
11653
+ return true;
11654
+ });
11655
+ }
11656
+ function clearVideo(tree, path) {
11657
+ return withVideo(tree, path, (block) => {
11658
+ const slots = { ...block.slots };
11659
+ delete slots.videoId;
11660
+ block.slots = slots;
11661
+ return true;
11662
+ });
11663
+ }
11664
+
11665
+ // src/lib/youtube.ts
11666
+ var YOUTUBE_ID_PATTERN = /^[A-Za-z0-9_-]{11}$/;
11667
+ function extractYouTubeId(input) {
11668
+ const trimmed = input.trim();
11669
+ if (!trimmed) return null;
11670
+ if (YOUTUBE_ID_PATTERN.test(trimmed)) return trimmed;
11671
+ let url;
11672
+ try {
11673
+ url = new URL(trimmed);
11674
+ } catch {
11675
+ return null;
11676
+ }
11677
+ const host = url.hostname.replace(/^www\./, "");
11678
+ if (host !== "youtube.com" && host !== "m.youtube.com" && host !== "youtu.be" && host !== "youtube-nocookie.com") {
11679
+ return null;
11680
+ }
11681
+ let candidate = null;
11682
+ if (host === "youtu.be") {
11683
+ candidate = url.pathname.slice(1).split("/")[0] ?? null;
11684
+ } else if (url.pathname === "/watch") {
11685
+ candidate = url.searchParams.get("v");
11686
+ } else {
11687
+ const match = url.pathname.match(/^\/(?:embed|shorts)\/([^/]+)/);
11688
+ candidate = match ? match[1] : null;
11689
+ }
11690
+ return candidate && YOUTUBE_ID_PATTERN.test(candidate) ? candidate : null;
11691
+ }
11692
+
11693
+ // src/ui/ai-section/AiVideoOverlay.tsx
11694
+ var import_jsx_runtime20 = require("react/jsx-runtime");
11695
+ var PRIMARY5 = "#0885FE";
11696
+ var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY5})`;
11697
+ var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
11698
+ function findVideoBlockElement(sectionId, path) {
11699
+ const sectionEl = findByInstanceId(sectionId);
11700
+ if (!sectionEl) return null;
11701
+ const items = sectionEl.querySelectorAll("[data-ohw-video-block]");
11702
+ for (const el of Array.from(items)) {
11703
+ if (el.dataset.ohwVideoPath === path) return el;
11704
+ }
11705
+ return null;
11706
+ }
11707
+ function readRect4(ref) {
11708
+ const el = ref && findVideoBlockElement(ref.sectionId, ref.path);
11709
+ if (!el) return null;
11710
+ const r2 = el.getBoundingClientRect();
11711
+ if (r2.width <= 0 || r2.height <= 0) return null;
11712
+ return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
11713
+ }
11714
+ function useLiveBlockRect(ref) {
11715
+ const [rect, setRect] = (0, import_react11.useState)(null);
11716
+ (0, import_react11.useEffect)(() => {
11717
+ if (!ref) {
11718
+ setRect(null);
11719
+ return;
11720
+ }
11721
+ const update = () => {
11722
+ const next = readRect4(ref);
11723
+ setRect(
11724
+ (prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
11725
+ );
11726
+ };
11727
+ update();
11728
+ const opts = { capture: true, passive: true };
11729
+ window.addEventListener("scroll", update, opts);
11730
+ window.addEventListener("resize", update);
11731
+ const interval = setInterval(update, 500);
11732
+ return () => {
11733
+ window.removeEventListener("scroll", update, opts);
11734
+ window.removeEventListener("resize", update);
11735
+ clearInterval(interval);
11736
+ };
11737
+ }, [ref?.sectionId, ref?.path]);
11738
+ return rect;
11739
+ }
11740
+ function requestValidateTree3(postToParent2, tree) {
11741
+ return new Promise((resolve) => {
11742
+ const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
11743
+ const timeout = window.setTimeout(() => {
11744
+ window.removeEventListener("message", onMessage);
11745
+ resolve({ ok: false, reasons: ["Validation request timed out."] });
11746
+ }, 8e3);
11747
+ function onMessage(e) {
11748
+ if (e.data?.type !== "ow:ai-validate-tree-result" || e.data.id !== id) return;
11749
+ window.clearTimeout(timeout);
11750
+ window.removeEventListener("message", onMessage);
11751
+ resolve({ ok: e.data.ok === true, reasons: Array.isArray(e.data.reasons) ? e.data.reasons : [] });
11752
+ }
11753
+ window.addEventListener("message", onMessage);
11754
+ postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
11755
+ });
11756
+ }
11757
+ function Pill3({
11758
+ label,
11759
+ onClick,
11760
+ disabled
11761
+ }) {
11762
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11763
+ "button",
11764
+ {
11765
+ type: "button",
11766
+ onClick,
11767
+ disabled,
11768
+ style: {
11769
+ height: 28,
11770
+ padding: "0 10px",
11771
+ display: "inline-flex",
11772
+ alignItems: "center",
11773
+ gap: 4,
11774
+ borderRadius: 999,
11775
+ border: "none",
11776
+ cursor: disabled ? "default" : "pointer",
11777
+ background: "#ffffff",
11778
+ color: OHW_BLUE_DARK3,
11779
+ opacity: disabled ? 0.4 : 1,
11780
+ fontSize: 12,
11781
+ lineHeight: "16px",
11782
+ fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
11783
+ whiteSpace: "nowrap",
11784
+ flex: "0 0 auto"
11785
+ },
11786
+ children: label
11787
+ }
11788
+ );
11789
+ }
11790
+ function watchUrl(id) {
11791
+ return `https://www.youtube.com/watch?v=${id}`;
11792
+ }
11793
+ function VideoUrlInput({ value, onCommit }) {
11794
+ const [draft, setDraft] = (0, import_react11.useState)(value ? watchUrl(value) : "");
11795
+ const [invalid, setInvalid] = (0, import_react11.useState)(false);
11796
+ (0, import_react11.useEffect)(() => {
11797
+ setDraft(value ? watchUrl(value) : "");
11798
+ setInvalid(false);
11799
+ }, [value]);
11800
+ const commit = () => {
11801
+ const next = draft.trim();
11802
+ if (!next) {
11803
+ setInvalid(false);
11804
+ if (value) onCommit(null);
11805
+ return;
11806
+ }
11807
+ const id = extractYouTubeId(next);
11808
+ if (!id) return setInvalid(true);
11809
+ setInvalid(false);
11810
+ setDraft(watchUrl(id));
11811
+ if (id !== value) onCommit(id);
11812
+ };
11813
+ const handleChange = (next) => {
11814
+ setDraft(next);
11815
+ const id = extractYouTubeId(next.trim());
11816
+ if (id && id !== value) {
11817
+ setInvalid(false);
11818
+ onCommit(id);
11819
+ }
11820
+ };
11821
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 4, width: "100%", maxWidth: 280 }, children: [
11822
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11823
+ "div",
11824
+ {
11825
+ style: {
11826
+ display: "flex",
11827
+ alignItems: "center",
11828
+ gap: 6,
11829
+ height: 28,
11830
+ padding: "0 12px",
11831
+ borderRadius: 999,
11832
+ background: "#ffffff",
11833
+ width: "100%",
11834
+ boxSizing: "border-box",
11835
+ boxShadow: invalid ? "inset 0 0 0 1.5px #EF4444" : "none"
11836
+ },
11837
+ children: [
11838
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11839
+ "span",
11840
+ {
11841
+ style: {
11842
+ flex: "0 0 auto",
11843
+ color: OHW_BLUE_DARK3,
11844
+ fontSize: 10,
11845
+ lineHeight: "16px",
11846
+ fontWeight: 700,
11847
+ textTransform: "uppercase",
11848
+ letterSpacing: 0.4
11849
+ },
11850
+ children: "Video"
11851
+ }
11852
+ ),
11853
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11854
+ "input",
11855
+ {
11856
+ type: "text",
11857
+ inputMode: "url",
11858
+ value: draft,
11859
+ onChange: (e) => handleChange(e.target.value),
11860
+ onBlur: commit,
11861
+ onKeyDown: (e) => {
11862
+ if (e.key === "Enter") e.currentTarget.blur();
11863
+ if (e.key === "Escape") {
11864
+ setDraft(value ? watchUrl(value) : "");
11865
+ setInvalid(false);
11866
+ e.currentTarget.blur();
11867
+ }
11868
+ },
11869
+ placeholder: "Paste a YouTube URL",
11870
+ "aria-label": "YouTube video URL",
11871
+ "aria-invalid": invalid,
11872
+ style: {
11873
+ flex: 1,
11874
+ minWidth: 0,
11875
+ border: "none",
11876
+ outline: "none",
11877
+ background: "transparent",
11878
+ padding: 0,
11879
+ margin: 0,
11880
+ fontSize: 12,
11881
+ lineHeight: "16px",
11882
+ fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
11883
+ color: "#1f2937"
11884
+ }
11885
+ }
11886
+ )
11887
+ ]
11888
+ }
11889
+ ),
11890
+ 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." })
11891
+ ] });
11892
+ }
11893
+ function VideoToolbar({
11894
+ videoId,
11895
+ pending,
11896
+ error,
11897
+ onSetVideoId,
11898
+ onRemove
11899
+ }) {
11900
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11901
+ "div",
11902
+ {
11903
+ "data-ohw-bridge": "",
11904
+ "data-ohw-toolbar": "",
11905
+ onMouseDown: (e) => e.stopPropagation(),
11906
+ style: {
11907
+ display: "flex",
11908
+ flexDirection: "column",
11909
+ gap: 6,
11910
+ alignItems: "center",
11911
+ width: 280,
11912
+ background: OHW_BLUE3,
11913
+ padding: 8,
11914
+ borderRadius: 12,
11915
+ boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
11916
+ pointerEvents: pending ? "none" : "auto",
11917
+ opacity: pending ? 0.6 : 1
11918
+ },
11919
+ children: [
11920
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
11921
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill3, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
11922
+ error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
11923
+ ]
11924
+ }
11925
+ );
11926
+ }
11927
+ function AiVideoOverlay({
11928
+ postToParent: postToParent2,
11929
+ aiSectionsRef,
11930
+ applyTreeLocalRef,
11931
+ clearInteractionChromeRef
11932
+ }) {
11933
+ const [hover, setHover] = (0, import_react11.useState)(null);
11934
+ const [active, setActive] = (0, import_react11.useState)(null);
11935
+ const [pending, setPending] = (0, import_react11.useState)(false);
11936
+ const [error, setError] = (0, import_react11.useState)(null);
11937
+ const activeRef = (0, import_react11.useRef)(null);
11938
+ activeRef.current = active;
11939
+ (0, import_react11.useEffect)(() => {
11940
+ const onMove = (e) => {
11941
+ const t = e.target;
11942
+ if (!(t instanceof HTMLElement)) return;
11943
+ 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]")) {
11944
+ return;
11945
+ }
11946
+ const blockEl = t.closest("[data-ohw-video-block]");
11947
+ if (!blockEl) {
11948
+ setHover(null);
11949
+ return;
11950
+ }
11951
+ const sectionEl = blockEl.closest("[data-ohw-section]");
11952
+ const unit = sectionEl ? movableUnit(sectionEl) : null;
11953
+ const sectionId = unit ? instanceIdOf(unit) || null : null;
11954
+ const path = blockEl.dataset.ohwVideoPath;
11955
+ if (!sectionId || !path) {
11956
+ setHover(null);
11957
+ return;
11958
+ }
11959
+ setHover({ sectionId, path });
11960
+ };
11961
+ const onLeave = () => setHover(null);
11962
+ document.addEventListener("mousemove", onMove, { passive: true });
11963
+ document.documentElement.addEventListener("mouseleave", onLeave);
11964
+ return () => {
11965
+ document.removeEventListener("mousemove", onMove);
11966
+ document.documentElement.removeEventListener("mouseleave", onLeave);
11967
+ };
11968
+ }, []);
11969
+ (0, import_react11.useEffect)(() => {
11970
+ const onClick = (e) => {
11971
+ const current = activeRef.current;
11972
+ if (!current) return;
11973
+ const t = e.target;
11974
+ if (!(t instanceof HTMLElement)) return;
11975
+ if (t.closest("[data-ohw-item-interaction]")) return;
11976
+ const blockEl = findVideoBlockElement(current.sectionId, current.path);
11977
+ if (blockEl && blockEl.contains(t)) return;
11978
+ setActive(null);
11979
+ setError(null);
11980
+ };
11981
+ document.addEventListener("click", onClick, true);
11982
+ return () => document.removeEventListener("click", onClick, true);
11983
+ }, []);
11984
+ (0, import_react11.useEffect)(() => {
11985
+ const onBlur = () => {
11986
+ if (!activeRef.current) return;
11987
+ setActive(null);
11988
+ setError(null);
11989
+ };
11990
+ window.addEventListener("blur", onBlur);
11991
+ return () => window.removeEventListener("blur", onBlur);
11992
+ }, []);
11993
+ (0, import_react11.useEffect)(() => {
11994
+ const onKeyDown = (e) => {
11995
+ if (e.key !== "Escape") return;
11996
+ if (!activeRef.current) return;
11997
+ setActive(null);
11998
+ setError(null);
11999
+ };
12000
+ document.addEventListener("keydown", onKeyDown);
12001
+ return () => document.removeEventListener("keydown", onKeyDown);
12002
+ }, []);
12003
+ const findEntry = (0, import_react11.useCallback)(
12004
+ (sectionId) => {
12005
+ const state = parseAiSectionsState(aiSectionsRef.current);
12006
+ return state.sections.find((s) => s.id === sectionId) ?? null;
12007
+ },
12008
+ [aiSectionsRef]
12009
+ );
12010
+ const runMutation = (0, import_react11.useCallback)(
12011
+ async (sectionId, mutate) => {
12012
+ const entry = findEntry(sectionId);
12013
+ if (!entry) return false;
12014
+ const nextTree = mutate(entry.tree);
12015
+ if (!nextTree) return false;
12016
+ setPending(true);
12017
+ setError(null);
12018
+ const { ok, reasons } = await requestValidateTree3(postToParent2, nextTree);
12019
+ setPending(false);
12020
+ if (!ok) {
12021
+ setError(reasons[0] ?? "That change is not allowed.");
12022
+ return false;
12023
+ }
12024
+ applyTreeLocalRef.current?.({
12025
+ id: sectionId,
12026
+ mode: "replace",
12027
+ targetSectionId: sectionId,
12028
+ tree: nextTree,
12029
+ label: entry.label,
12030
+ media: entry.media,
12031
+ ...entry.brand ? { brand: entry.brand } : {}
12032
+ });
12033
+ return true;
12034
+ },
12035
+ [findEntry, postToParent2, applyTreeLocalRef]
12036
+ );
12037
+ const activeEntry = active ? findEntry(active.sectionId) : null;
12038
+ const hoverHandleRect = useLiveBlockRect(!active && hover ? hover : null);
12039
+ const activeBlockRect = useLiveBlockRect(active);
12040
+ const TOOLBAR_APPROX_H = 90;
12041
+ const toolbarState = activeBlockRect && activeBlockRect.top < TOOLBAR_APPROX_H ? "active-bottom" : "active-top";
12042
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
12043
+ hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12044
+ "button",
12045
+ {
12046
+ type: "button",
12047
+ "data-ohw-toolbar": "",
12048
+ onClick: () => {
12049
+ clearInteractionChromeRef.current();
12050
+ setActive(hover);
12051
+ },
12052
+ "aria-label": "Configure video",
12053
+ style: {
12054
+ position: "fixed",
12055
+ top: hoverHandleRect.top + 8,
12056
+ left: hoverHandleRect.left + hoverHandleRect.width - 36,
12057
+ width: 28,
12058
+ height: 28,
12059
+ borderRadius: 8,
12060
+ border: `1.5px dashed ${PRIMARY5}`,
12061
+ background: "#ffffff",
12062
+ color: PRIMARY5,
12063
+ display: "flex",
12064
+ alignItems: "center",
12065
+ justifyContent: "center",
12066
+ cursor: "pointer",
12067
+ zIndex: 2147483643,
12068
+ fontSize: 14,
12069
+ fontWeight: 700
12070
+ },
12071
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react10.Star, { size: 14, style: { pointerEvents: "none" } })
12072
+ }
12073
+ ),
12074
+ activeBlockRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12075
+ ItemInteractionLayer,
12076
+ {
12077
+ rect: activeBlockRect,
12078
+ state: toolbarState,
12079
+ toolbar: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12080
+ VideoToolbar,
12081
+ {
12082
+ videoId: videoIdAt(activeEntry.tree, active.path),
12083
+ pending,
12084
+ error,
12085
+ onSetVideoId: (videoId) => {
12086
+ void runMutation(
12087
+ active.sectionId,
12088
+ (tree) => videoId ? setVideoId(tree, active.path, videoId) : clearVideo(tree, active.path)
12089
+ );
12090
+ },
12091
+ onRemove: () => {
12092
+ void runMutation(active.sectionId, (tree) => clearVideo(tree, active.path));
12093
+ }
12094
+ }
12095
+ )
12096
+ }
12097
+ )
12098
+ ] });
12099
+ }
12100
+
11461
12101
  // src/OhhwellsBridge.tsx
11462
12102
  var import_react_dom5 = require("react-dom");
11463
12103
  var import_navigation3 = require("next/navigation");
@@ -11769,28 +12409,28 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
11769
12409
  }
11770
12410
 
11771
12411
  // src/ui/link-modal/LinkPopover.tsx
11772
- var import_react14 = require("react");
12412
+ var import_react15 = require("react");
11773
12413
 
11774
12414
  // src/ui/dialog.tsx
11775
12415
  var React9 = __toESM(require("react"), 1);
11776
12416
  var import_radix_ui6 = require("radix-ui");
11777
- var import_lucide_react10 = require("lucide-react");
11778
- var import_jsx_runtime20 = require("react/jsx-runtime");
12417
+ var import_lucide_react11 = require("lucide-react");
12418
+ var import_jsx_runtime21 = require("react/jsx-runtime");
11779
12419
  function Dialog2({
11780
12420
  ...props
11781
12421
  }) {
11782
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
12422
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
11783
12423
  }
11784
12424
  function DialogPortal({
11785
12425
  ...props
11786
12426
  }) {
11787
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
12427
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
11788
12428
  }
11789
12429
  function DialogOverlay({
11790
12430
  className,
11791
12431
  ...props
11792
12432
  }) {
11793
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12433
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11794
12434
  import_radix_ui6.Dialog.Overlay,
11795
12435
  {
11796
12436
  "data-slot": "dialog-overlay",
@@ -11803,9 +12443,9 @@ function DialogOverlay({
11803
12443
  var DialogContent = React9.forwardRef(
11804
12444
  ({ className, children, showCloseButton = true, container, ...props }, ref) => {
11805
12445
  const positionMode = container ? "absolute" : "fixed";
11806
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DialogPortal, { container: container ?? void 0, children: [
11807
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
11808
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
12446
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(DialogPortal, { container: container ?? void 0, children: [
12447
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
12448
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
11809
12449
  import_radix_ui6.Dialog.Content,
11810
12450
  {
11811
12451
  ref,
@@ -11821,13 +12461,13 @@ var DialogContent = React9.forwardRef(
11821
12461
  ...props,
11822
12462
  children: [
11823
12463
  children,
11824
- showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12464
+ showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11825
12465
  import_radix_ui6.Dialog.Close,
11826
12466
  {
11827
12467
  type: "button",
11828
12468
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
11829
12469
  "aria-label": "Close",
11830
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react10.X, { size: 16, "aria-hidden": true })
12470
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react11.X, { size: 16, "aria-hidden": true })
11831
12471
  }
11832
12472
  ) : null
11833
12473
  ]
@@ -11841,13 +12481,13 @@ function DialogHeader({
11841
12481
  className,
11842
12482
  ...props
11843
12483
  }) {
11844
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
12484
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
11845
12485
  }
11846
12486
  function DialogFooter({
11847
12487
  className,
11848
12488
  ...props
11849
12489
  }) {
11850
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12490
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11851
12491
  "div",
11852
12492
  {
11853
12493
  className: cn("flex items-center justify-end gap-2", className),
@@ -11855,7 +12495,7 @@ function DialogFooter({
11855
12495
  }
11856
12496
  );
11857
12497
  }
11858
- var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12498
+ var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11859
12499
  import_radix_ui6.Dialog.Title,
11860
12500
  {
11861
12501
  ref,
@@ -11867,7 +12507,7 @@ var DialogTitle = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE
11867
12507
  }
11868
12508
  ));
11869
12509
  DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
11870
- var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
12510
+ var DialogDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11871
12511
  import_radix_ui6.Dialog.Description,
11872
12512
  {
11873
12513
  ref,
@@ -11879,63 +12519,63 @@ DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
11879
12519
  var DialogClose = import_radix_ui6.Dialog.Close;
11880
12520
 
11881
12521
  // src/ui/link-modal/LinkEditorPanel.tsx
11882
- var import_lucide_react14 = require("lucide-react");
12522
+ var import_lucide_react15 = require("lucide-react");
11883
12523
 
11884
12524
  // src/ui/link-modal/DestinationBreadcrumb.tsx
11885
- var import_lucide_react11 = require("lucide-react");
11886
- var import_jsx_runtime21 = require("react/jsx-runtime");
12525
+ var import_lucide_react12 = require("lucide-react");
12526
+ var import_jsx_runtime22 = require("react/jsx-runtime");
11887
12527
  function DestinationBreadcrumb({
11888
12528
  pageTitle,
11889
12529
  sectionLabel
11890
12530
  }) {
11891
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
11892
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
11893
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-3", children: [
11894
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-2", children: [
11895
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react11.File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
11896
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
12531
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
12532
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
12533
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-3", children: [
12534
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2", children: [
12535
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
12536
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
11897
12537
  ] }),
11898
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11899
- import_lucide_react11.ArrowRight,
12538
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12539
+ import_lucide_react12.ArrowRight,
11900
12540
  {
11901
12541
  size: 16,
11902
12542
  className: "shrink-0 text-muted-foreground",
11903
12543
  "aria-hidden": true
11904
12544
  }
11905
12545
  ),
11906
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
11907
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11908
- import_lucide_react11.GalleryVertical,
12546
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
12547
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12548
+ import_lucide_react12.GalleryVertical,
11909
12549
  {
11910
12550
  size: 16,
11911
12551
  className: "shrink-0 text-foreground",
11912
12552
  "aria-hidden": true
11913
12553
  }
11914
12554
  ),
11915
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
12555
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
11916
12556
  ] })
11917
12557
  ] })
11918
12558
  ] });
11919
12559
  }
11920
12560
 
11921
12561
  // src/ui/link-modal/SectionTreeItem.tsx
11922
- var import_lucide_react12 = require("lucide-react");
11923
- var import_jsx_runtime22 = require("react/jsx-runtime");
12562
+ var import_lucide_react13 = require("lucide-react");
12563
+ var import_jsx_runtime23 = require("react/jsx-runtime");
11924
12564
  function SectionTreeItem({
11925
12565
  section,
11926
12566
  onSelect,
11927
12567
  selected
11928
12568
  }) {
11929
12569
  const interactive = Boolean(onSelect);
11930
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
11931
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
12570
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
12571
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
11932
12572
  "div",
11933
12573
  {
11934
12574
  className: "-mr-px h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
11935
12575
  "aria-hidden": true
11936
12576
  }
11937
12577
  ),
11938
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
12578
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
11939
12579
  "div",
11940
12580
  {
11941
12581
  role: interactive ? "button" : void 0,
@@ -11953,15 +12593,15 @@ function SectionTreeItem({
11953
12593
  interactive && selected && "border-bridge-primary"
11954
12594
  ),
11955
12595
  children: [
11956
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
11957
- import_lucide_react12.GalleryVertical,
12596
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
12597
+ import_lucide_react13.GalleryVertical,
11958
12598
  {
11959
12599
  size: 16,
11960
12600
  className: "shrink-0 text-foreground",
11961
12601
  "aria-hidden": true
11962
12602
  }
11963
12603
  ),
11964
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
12604
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
11965
12605
  ]
11966
12606
  }
11967
12607
  )
@@ -11969,14 +12609,14 @@ function SectionTreeItem({
11969
12609
  }
11970
12610
 
11971
12611
  // src/ui/link-modal/UrlOrPageInput.tsx
11972
- var import_react11 = require("react");
12612
+ var import_react12 = require("react");
11973
12613
 
11974
12614
  // src/ui/input.tsx
11975
12615
  var React10 = __toESM(require("react"), 1);
11976
- var import_jsx_runtime23 = require("react/jsx-runtime");
12616
+ var import_jsx_runtime24 = require("react/jsx-runtime");
11977
12617
  var Input = React10.forwardRef(
11978
12618
  ({ className, type, ...props }, ref) => {
11979
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
12619
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
11980
12620
  "input",
11981
12621
  {
11982
12622
  type,
@@ -11995,9 +12635,9 @@ Input.displayName = "Input";
11995
12635
 
11996
12636
  // src/ui/label.tsx
11997
12637
  var import_radix_ui7 = require("radix-ui");
11998
- var import_jsx_runtime24 = require("react/jsx-runtime");
12638
+ var import_jsx_runtime25 = require("react/jsx-runtime");
11999
12639
  function Label({ className, ...props }) {
12000
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
12640
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12001
12641
  import_radix_ui7.Label.Root,
12002
12642
  {
12003
12643
  "data-slot": "label",
@@ -12008,12 +12648,12 @@ function Label({ className, ...props }) {
12008
12648
  }
12009
12649
 
12010
12650
  // src/ui/link-modal/UrlOrPageInput.tsx
12011
- var import_lucide_react13 = require("lucide-react");
12012
- var import_jsx_runtime25 = require("react/jsx-runtime");
12651
+ var import_lucide_react14 = require("lucide-react");
12652
+ var import_jsx_runtime26 = require("react/jsx-runtime");
12013
12653
  function FieldChevron({
12014
12654
  onClick
12015
12655
  }) {
12016
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12656
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12017
12657
  "button",
12018
12658
  {
12019
12659
  type: "button",
@@ -12021,7 +12661,7 @@ function FieldChevron({
12021
12661
  onClick,
12022
12662
  "aria-label": "Open page list",
12023
12663
  tabIndex: -1,
12024
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react13.ChevronDown, { size: 16 })
12664
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react14.ChevronDown, { size: 16 })
12025
12665
  }
12026
12666
  );
12027
12667
  }
@@ -12037,11 +12677,11 @@ function UrlOrPageInput({
12037
12677
  readOnly = false,
12038
12678
  urlError
12039
12679
  }) {
12040
- const inputId = (0, import_react11.useId)();
12041
- const inputRef = (0, import_react11.useRef)(null);
12042
- const rootRef = (0, import_react11.useRef)(null);
12043
- const [isFocused, setIsFocused] = (0, import_react11.useState)(false);
12044
- (0, import_react11.useEffect)(() => {
12680
+ const inputId = (0, import_react12.useId)();
12681
+ const inputRef = (0, import_react12.useRef)(null);
12682
+ const rootRef = (0, import_react12.useRef)(null);
12683
+ const [isFocused, setIsFocused] = (0, import_react12.useState)(false);
12684
+ (0, import_react12.useEffect)(() => {
12045
12685
  if (!dropdownOpen) return;
12046
12686
  const isOutside = (e) => {
12047
12687
  const root = rootRef.current;
@@ -12082,19 +12722,19 @@ function UrlOrPageInput({
12082
12722
  "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]",
12083
12723
  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"
12084
12724
  );
12085
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
12086
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
12087
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { ref: rootRef, className: "relative w-full", children: [
12088
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
12089
- selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12090
- import_lucide_react13.File,
12725
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
12726
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
12727
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { ref: rootRef, className: "relative w-full", children: [
12728
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
12729
+ selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12730
+ import_lucide_react14.File,
12091
12731
  {
12092
12732
  size: 16,
12093
12733
  className: "shrink-0 text-foreground",
12094
12734
  "aria-hidden": true
12095
12735
  }
12096
12736
  ) }) : null,
12097
- 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)(
12737
+ 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)(
12098
12738
  Input,
12099
12739
  {
12100
12740
  ref: inputRef,
@@ -12120,7 +12760,7 @@ function UrlOrPageInput({
12120
12760
  )
12121
12761
  }
12122
12762
  ),
12123
- selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12763
+ selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12124
12764
  "button",
12125
12765
  {
12126
12766
  type: "button",
@@ -12128,26 +12768,26 @@ function UrlOrPageInput({
12128
12768
  onMouseDown: clearSelection,
12129
12769
  "aria-label": "Clear selected page",
12130
12770
  tabIndex: -1,
12131
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react13.X, { size: 16, "aria-hidden": true })
12771
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react14.X, { size: 16, "aria-hidden": true })
12132
12772
  }
12133
12773
  ) : null,
12134
- !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
12774
+ !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
12135
12775
  ] }),
12136
- dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
12776
+ dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12137
12777
  "div",
12138
12778
  {
12139
12779
  "data-ohw-link-page-dropdown": "",
12140
12780
  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",
12141
12781
  onMouseDown: (e) => e.preventDefault(),
12142
- children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
12782
+ children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
12143
12783
  "button",
12144
12784
  {
12145
12785
  type: "button",
12146
12786
  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",
12147
12787
  onClick: () => onPageSelect(page),
12148
12788
  children: [
12149
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react13.File, { size: 16, className: "shrink-0", "aria-hidden": true }),
12150
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "truncate", children: page.title })
12789
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react14.File, { size: 16, className: "shrink-0", "aria-hidden": true }),
12790
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "truncate", children: page.title })
12151
12791
  ]
12152
12792
  },
12153
12793
  page.path
@@ -12155,34 +12795,34 @@ function UrlOrPageInput({
12155
12795
  }
12156
12796
  ) : null
12157
12797
  ] }),
12158
- urlError ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
12798
+ urlError ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
12159
12799
  ] });
12160
12800
  }
12161
12801
 
12162
12802
  // src/ui/link-modal/LinkEditorPanel.tsx
12163
- var import_jsx_runtime26 = require("react/jsx-runtime");
12803
+ var import_jsx_runtime27 = require("react/jsx-runtime");
12164
12804
  function LinkEditorPanel({ state, onClose }) {
12165
12805
  const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
12166
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
12167
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12806
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
12807
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12168
12808
  "button",
12169
12809
  {
12170
12810
  type: "button",
12171
12811
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
12172
12812
  "aria-label": "Close",
12173
12813
  onClick: onClose,
12174
- children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react14.X, { size: 16, "aria-hidden": true })
12814
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react15.X, { size: 16, "aria-hidden": true })
12175
12815
  }
12176
12816
  ) }),
12177
- /* @__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 }) }),
12178
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
12179
- state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12817
+ /* @__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 }) }),
12818
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
12819
+ state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12180
12820
  DestinationBreadcrumb,
12181
12821
  {
12182
12822
  pageTitle: state.selectedPage.title,
12183
12823
  sectionLabel: state.selectedSection.label
12184
12824
  }
12185
- ) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12825
+ ) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12186
12826
  UrlOrPageInput,
12187
12827
  {
12188
12828
  value: state.searchValue,
@@ -12195,8 +12835,8 @@ function LinkEditorPanel({ state, onClose }) {
12195
12835
  urlError: state.urlError
12196
12836
  }
12197
12837
  ),
12198
- state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
12199
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12838
+ state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
12839
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12200
12840
  Button,
12201
12841
  {
12202
12842
  type: "button",
@@ -12207,15 +12847,15 @@ function LinkEditorPanel({ state, onClose }) {
12207
12847
  children: "Choose a section"
12208
12848
  }
12209
12849
  ),
12210
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
12211
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react14.Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
12212
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: "Pick a section this link should scroll to." })
12850
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
12851
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react15.Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
12852
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { children: "Pick a section this link should scroll to." })
12213
12853
  ] })
12214
12854
  ] }) : null,
12215
- state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
12855
+ state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
12216
12856
  ] }),
12217
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
12218
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12857
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
12858
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12219
12859
  Button,
12220
12860
  {
12221
12861
  type: "button",
@@ -12230,7 +12870,7 @@ function LinkEditorPanel({ state, onClose }) {
12230
12870
  children: state.secondaryLabel
12231
12871
  }
12232
12872
  ),
12233
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
12873
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12234
12874
  Button,
12235
12875
  {
12236
12876
  type: "button",
@@ -12249,9 +12889,9 @@ function LinkEditorPanel({ state, onClose }) {
12249
12889
  }
12250
12890
 
12251
12891
  // src/ui/link-modal/SectionPickerOverlay.tsx
12252
- var import_react12 = require("react");
12892
+ var import_react13 = require("react");
12253
12893
  var import_react_dom3 = require("react-dom");
12254
- var import_lucide_react15 = require("lucide-react");
12894
+ var import_lucide_react16 = require("lucide-react");
12255
12895
  var import_navigation2 = require("next/navigation");
12256
12896
 
12257
12897
  // src/lib/parent-scroll.ts
@@ -12273,7 +12913,7 @@ function getIframeChromeClip(parentScroll) {
12273
12913
  }
12274
12914
 
12275
12915
  // src/ui/link-modal/SectionPickerOverlay.tsx
12276
- var import_jsx_runtime27 = require("react/jsx-runtime");
12916
+ var import_jsx_runtime28 = require("react/jsx-runtime");
12277
12917
  var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
12278
12918
  function rectsEqual(a, b) {
12279
12919
  if (a.size !== b.size) return false;
@@ -12306,12 +12946,12 @@ function hitTestSectionId(x, y, sectionIds, rects) {
12306
12946
  return null;
12307
12947
  }
12308
12948
  function useSectionRects(sectionIdsKey, enabled) {
12309
- const [rects, setRects] = (0, import_react12.useState)(/* @__PURE__ */ new Map());
12310
- const sectionIds = (0, import_react12.useMemo)(
12949
+ const [rects, setRects] = (0, import_react13.useState)(/* @__PURE__ */ new Map());
12950
+ const sectionIds = (0, import_react13.useMemo)(
12311
12951
  () => sectionIdsKey ? sectionIdsKey.split("\0") : [],
12312
12952
  [sectionIdsKey]
12313
12953
  );
12314
- (0, import_react12.useEffect)(() => {
12954
+ (0, import_react13.useEffect)(() => {
12315
12955
  if (!enabled || sectionIds.length === 0) {
12316
12956
  setRects((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
12317
12957
  return;
@@ -12352,13 +12992,13 @@ function SectionPickerOverlay({
12352
12992
  }) {
12353
12993
  const router = (0, import_navigation2.useRouter)();
12354
12994
  const pathname = (0, import_navigation2.usePathname)();
12355
- const [selectedId, setSelectedId] = (0, import_react12.useState)(null);
12356
- const [hoveredId, setHoveredId] = (0, import_react12.useState)(null);
12357
- const pointerRef = (0, import_react12.useRef)(null);
12358
- const pointerScreenRef = (0, import_react12.useRef)(null);
12359
- const iframeOffsetTopRef = (0, import_react12.useRef)(null);
12360
- const sectionIdsRef = (0, import_react12.useRef)([]);
12361
- const [chromeClip, setChromeClip] = (0, import_react12.useState)(
12995
+ const [selectedId, setSelectedId] = (0, import_react13.useState)(null);
12996
+ const [hoveredId, setHoveredId] = (0, import_react13.useState)(null);
12997
+ const pointerRef = (0, import_react13.useRef)(null);
12998
+ const pointerScreenRef = (0, import_react13.useRef)(null);
12999
+ const iframeOffsetTopRef = (0, import_react13.useRef)(null);
13000
+ const sectionIdsRef = (0, import_react13.useRef)([]);
13001
+ const [chromeClip, setChromeClip] = (0, import_react13.useState)(
12362
13002
  () => ({
12363
13003
  top: 0,
12364
13004
  bottom: typeof window !== "undefined" ? window.innerHeight : 0
@@ -12366,12 +13006,12 @@ function SectionPickerOverlay({
12366
13006
  );
12367
13007
  const normalizedTarget = normalizePath(pagePath);
12368
13008
  const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
12369
- (0, import_react12.useEffect)(() => {
13009
+ (0, import_react13.useEffect)(() => {
12370
13010
  if (isOnTargetPage) return;
12371
13011
  const search = readPreservedSearch();
12372
13012
  router.push(`${normalizedTarget}${search}`);
12373
13013
  }, [isOnTargetPage, normalizedTarget, router]);
12374
- (0, import_react12.useEffect)(() => {
13014
+ (0, import_react13.useEffect)(() => {
12375
13015
  document.documentElement.setAttribute("data-ohw-section-picking", "");
12376
13016
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
12377
13017
  el.removeAttribute("data-ohw-hovered");
@@ -12383,24 +13023,24 @@ function SectionPickerOverlay({
12383
13023
  document.documentElement.removeAttribute("data-ohw-section-picking");
12384
13024
  };
12385
13025
  }, []);
12386
- const liveSections = (0, import_react12.useMemo)(() => {
13026
+ const liveSections = (0, import_react13.useMemo)(() => {
12387
13027
  if (!isOnTargetPage) return sections;
12388
13028
  const live = collectSectionsFromDom();
12389
13029
  if (live.length === 0) return sections;
12390
13030
  const labels = new Map(sections.map((s) => [s.id, s.label]));
12391
13031
  return live.map((s) => ({ id: s.id, label: labels.get(s.id) ?? s.label }));
12392
13032
  }, [isOnTargetPage, sections, pathname]);
12393
- const sectionIdsKey = (0, import_react12.useMemo)(
13033
+ const sectionIdsKey = (0, import_react13.useMemo)(
12394
13034
  () => liveSections.map((s) => s.id).join("\0"),
12395
13035
  [liveSections]
12396
13036
  );
12397
- const sectionIds = (0, import_react12.useMemo)(
13037
+ const sectionIds = (0, import_react13.useMemo)(
12398
13038
  () => liveSections.map((s) => s.id),
12399
13039
  [liveSections]
12400
13040
  );
12401
13041
  sectionIdsRef.current = sectionIds;
12402
13042
  const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
12403
- const applyHoverAt = (0, import_react12.useCallback)(
13043
+ const applyHoverAt = (0, import_react13.useCallback)(
12404
13044
  (x, y, liveRects) => {
12405
13045
  const ids = sectionIdsRef.current;
12406
13046
  const map = liveRects ?? readSectionRects(ids);
@@ -12409,7 +13049,7 @@ function SectionPickerOverlay({
12409
13049
  },
12410
13050
  []
12411
13051
  );
12412
- (0, import_react12.useEffect)(() => {
13052
+ (0, import_react13.useEffect)(() => {
12413
13053
  const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH, promptBarH = 0) => {
12414
13054
  const next = getIframeVisibleClip({
12415
13055
  iframeOffsetTop,
@@ -12453,12 +13093,12 @@ function SectionPickerOverlay({
12453
13093
  window.removeEventListener("resize", onResize);
12454
13094
  };
12455
13095
  }, [applyHoverAt]);
12456
- (0, import_react12.useEffect)(() => {
13096
+ (0, import_react13.useEffect)(() => {
12457
13097
  const ptr = pointerRef.current;
12458
13098
  if (!ptr) return;
12459
13099
  applyHoverAt(ptr.x, ptr.y, rects);
12460
13100
  }, [rects, applyHoverAt]);
12461
- (0, import_react12.useEffect)(() => {
13101
+ (0, import_react13.useEffect)(() => {
12462
13102
  const rememberPointer = (clientX, clientY) => {
12463
13103
  pointerRef.current = { x: clientX, y: clientY };
12464
13104
  const top = iframeOffsetTopRef.current;
@@ -12482,7 +13122,7 @@ function SectionPickerOverlay({
12482
13122
  window.removeEventListener("message", onPointerSync);
12483
13123
  };
12484
13124
  }, [rects, applyHoverAt]);
12485
- const handleSelect = (0, import_react12.useCallback)(
13125
+ const handleSelect = (0, import_react13.useCallback)(
12486
13126
  (section) => {
12487
13127
  if (selectedId) return;
12488
13128
  setSelectedId(section.id);
@@ -12490,7 +13130,7 @@ function SectionPickerOverlay({
12490
13130
  },
12491
13131
  [selectedId, onSelect]
12492
13132
  );
12493
- (0, import_react12.useEffect)(() => {
13133
+ (0, import_react13.useEffect)(() => {
12494
13134
  const onKeyDown = (e) => {
12495
13135
  if (e.key === "Escape") {
12496
13136
  e.preventDefault();
@@ -12504,7 +13144,7 @@ function SectionPickerOverlay({
12504
13144
  const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
12505
13145
  if (!portalRoot) return null;
12506
13146
  return (0, import_react_dom3.createPortal)(
12507
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
13147
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
12508
13148
  "div",
12509
13149
  {
12510
13150
  "data-ohw-section-picker": "",
@@ -12514,12 +13154,12 @@ function SectionPickerOverlay({
12514
13154
  role: "dialog",
12515
13155
  "aria-label": "Choose a section",
12516
13156
  children: [
12517
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
13157
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12518
13158
  "div",
12519
13159
  {
12520
13160
  className: "pointer-events-auto fixed left-5 z-[2]",
12521
13161
  style: { top: chromeClip.top + 20 },
12522
- children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
13162
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
12523
13163
  Button,
12524
13164
  {
12525
13165
  type: "button",
@@ -12528,14 +13168,14 @@ function SectionPickerOverlay({
12528
13168
  className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
12529
13169
  onClick: onBack,
12530
13170
  children: [
12531
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react15.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
13171
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react16.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
12532
13172
  "Back"
12533
13173
  ]
12534
13174
  }
12535
13175
  )
12536
13176
  }
12537
13177
  ),
12538
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
13178
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12539
13179
  "div",
12540
13180
  {
12541
13181
  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",
@@ -12548,7 +13188,7 @@ function SectionPickerOverlay({
12548
13188
  children: "Click on section to select"
12549
13189
  }
12550
13190
  ),
12551
- !isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
13191
+ !isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12552
13192
  "div",
12553
13193
  {
12554
13194
  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",
@@ -12556,14 +13196,14 @@ function SectionPickerOverlay({
12556
13196
  children: "Loading page preview\u2026"
12557
13197
  }
12558
13198
  ) : null,
12559
- 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,
13199
+ 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,
12560
13200
  isOnTargetPage ? liveSections.map((section) => {
12561
13201
  const rect = rects.get(section.id);
12562
13202
  if (!rect || rect.width <= 0 || rect.height <= 0) return null;
12563
13203
  const isSelected = selectedId === section.id;
12564
13204
  const isHovered = hoveredId === section.id;
12565
13205
  const isLit = isSelected || isHovered;
12566
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
13206
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
12567
13207
  "button",
12568
13208
  {
12569
13209
  type: "button",
@@ -12578,7 +13218,7 @@ function SectionPickerOverlay({
12578
13218
  "aria-label": `Select section ${section.label}`,
12579
13219
  onClick: () => handleSelect(section),
12580
13220
  children: [
12581
- isLit ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
13221
+ isLit ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12582
13222
  "span",
12583
13223
  {
12584
13224
  className: "pointer-events-none absolute",
@@ -12591,13 +13231,13 @@ function SectionPickerOverlay({
12591
13231
  "aria-hidden": true
12592
13232
  }
12593
13233
  ) : null,
12594
- isSelected ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
13234
+ isSelected ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12595
13235
  "span",
12596
13236
  {
12597
13237
  className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
12598
13238
  style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
12599
13239
  "aria-hidden": true,
12600
- children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react15.Check, { className: "size-5" })
13240
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react16.Check, { className: "size-5" })
12601
13241
  }
12602
13242
  ) : null
12603
13243
  ]
@@ -12613,7 +13253,7 @@ function SectionPickerOverlay({
12613
13253
  }
12614
13254
 
12615
13255
  // src/ui/link-modal/useLinkModalState.ts
12616
- var import_react13 = require("react");
13256
+ var import_react14 = require("react");
12617
13257
  function useLinkModalState({
12618
13258
  open,
12619
13259
  mode,
@@ -12625,14 +13265,14 @@ function useLinkModalState({
12625
13265
  onClose,
12626
13266
  onSubmit
12627
13267
  }) {
12628
- const availablePages = (0, import_react13.useMemo)(() => pages, [pages]);
12629
- const [searchValue, setSearchValue] = (0, import_react13.useState)("");
12630
- const [selectedPage, setSelectedPage] = (0, import_react13.useState)(null);
12631
- const [selectedSection, setSelectedSection] = (0, import_react13.useState)(null);
12632
- const [step, setStep] = (0, import_react13.useState)("input");
12633
- const [dropdownOpen, setDropdownOpen] = (0, import_react13.useState)(false);
12634
- const [urlError, setUrlError] = (0, import_react13.useState)("");
12635
- const reset = (0, import_react13.useCallback)(() => {
13268
+ const availablePages = (0, import_react14.useMemo)(() => pages, [pages]);
13269
+ const [searchValue, setSearchValue] = (0, import_react14.useState)("");
13270
+ const [selectedPage, setSelectedPage] = (0, import_react14.useState)(null);
13271
+ const [selectedSection, setSelectedSection] = (0, import_react14.useState)(null);
13272
+ const [step, setStep] = (0, import_react14.useState)("input");
13273
+ const [dropdownOpen, setDropdownOpen] = (0, import_react14.useState)(false);
13274
+ const [urlError, setUrlError] = (0, import_react14.useState)("");
13275
+ const reset = (0, import_react14.useCallback)(() => {
12636
13276
  setSearchValue("");
12637
13277
  setSelectedPage(null);
12638
13278
  setSelectedSection(null);
@@ -12640,7 +13280,7 @@ function useLinkModalState({
12640
13280
  setDropdownOpen(false);
12641
13281
  setUrlError("");
12642
13282
  }, []);
12643
- (0, import_react13.useEffect)(() => {
13283
+ (0, import_react14.useEffect)(() => {
12644
13284
  if (!open) return;
12645
13285
  if (mode === "edit" && initialTarget) {
12646
13286
  const { pageRoute } = parseTarget(initialTarget);
@@ -12656,11 +13296,11 @@ function useLinkModalState({
12656
13296
  setDropdownOpen(false);
12657
13297
  setUrlError("");
12658
13298
  }, [open, mode, initialTarget, reset]);
12659
- const filteredPages = (0, import_react13.useMemo)(() => {
13299
+ const filteredPages = (0, import_react14.useMemo)(() => {
12660
13300
  if (!searchValue.trim()) return availablePages;
12661
13301
  return availablePages.filter((p) => p.title.toLowerCase().startsWith(searchValue.toLowerCase()));
12662
13302
  }, [availablePages, searchValue]);
12663
- const activeSections = (0, import_react13.useMemo)(() => {
13303
+ const activeSections = (0, import_react14.useMemo)(() => {
12664
13304
  if (!selectedPage) return [];
12665
13305
  return getSectionsForPath(sectionsByPath, selectedPage.path);
12666
13306
  }, [selectedPage, sectionsByPath]);
@@ -12709,7 +13349,7 @@ function useLinkModalState({
12709
13349
  reset();
12710
13350
  onClose();
12711
13351
  };
12712
- const isValid = (0, import_react13.useMemo)(() => {
13352
+ const isValid = (0, import_react14.useMemo)(() => {
12713
13353
  if (urlError) return false;
12714
13354
  if (showBreadcrumb) return true;
12715
13355
  if (selectedPage) return true;
@@ -12777,7 +13417,7 @@ function useLinkModalState({
12777
13417
  }
12778
13418
 
12779
13419
  // src/ui/link-modal/LinkPopover.tsx
12780
- var import_jsx_runtime28 = require("react/jsx-runtime");
13420
+ var import_jsx_runtime29 = require("react/jsx-runtime");
12781
13421
  function postToParent(data) {
12782
13422
  window.parent?.postMessage(data, "*");
12783
13423
  }
@@ -12806,7 +13446,7 @@ function LinkPopover({
12806
13446
  onSubmit
12807
13447
  });
12808
13448
  const sectionPickerActive = state.showSectionPicker && Boolean(state.selectedPage);
12809
- (0, import_react14.useEffect)(() => {
13449
+ (0, import_react15.useEffect)(() => {
12810
13450
  if (!open) return;
12811
13451
  if (sectionPickerActive) {
12812
13452
  postToParent({ type: "ui:unlock" });
@@ -12873,15 +13513,15 @@ function LinkPopover({
12873
13513
  );
12874
13514
  };
12875
13515
  }, [open, sectionPickerActive]);
12876
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
12877
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
13516
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
13517
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
12878
13518
  Dialog2,
12879
13519
  {
12880
13520
  open: open && !sectionPickerActive,
12881
13521
  onOpenChange: (next) => {
12882
13522
  if (!next) onClose?.();
12883
13523
  },
12884
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
13524
+ children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
12885
13525
  DialogContent,
12886
13526
  {
12887
13527
  ref: panelRef,
@@ -12891,12 +13531,12 @@ function LinkPopover({
12891
13531
  "data-ohw-bridge": "",
12892
13532
  showCloseButton: false,
12893
13533
  className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
12894
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(LinkEditorPanel, { state, onClose })
13534
+ children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(LinkEditorPanel, { state, onClose })
12895
13535
  }
12896
13536
  )
12897
13537
  }
12898
13538
  ),
12899
- sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
13539
+ sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
12900
13540
  SectionPickerOverlay,
12901
13541
  {
12902
13542
  pagePath: state.selectedPage.path,
@@ -16018,6 +16658,7 @@ function readLogoSizeState(content, placement) {
16018
16658
  function getLogoElement(el) {
16019
16659
  const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
16020
16660
  if (marked) return marked;
16661
+ if (el.closest('[data-ohw-editable="icon"]')) return null;
16021
16662
  const root = el.closest("nav, [data-ohw-nav-root], footer");
16022
16663
  if (!root) return null;
16023
16664
  const anchor = el.closest("a");
@@ -16084,9 +16725,9 @@ function addFooterColumnWithPersist({
16084
16725
  }
16085
16726
 
16086
16727
  // src/ui/FloatingPanel.tsx
16087
- var import_react15 = require("react");
16088
- var import_lucide_react16 = require("lucide-react");
16089
- var import_jsx_runtime29 = require("react/jsx-runtime");
16728
+ var import_react16 = require("react");
16729
+ var import_lucide_react17 = require("lucide-react");
16730
+ var import_jsx_runtime30 = require("react/jsx-runtime");
16090
16731
  var PANEL_WIDTH = 256;
16091
16732
  var EDGE_MARGIN = 16;
16092
16733
  var HEADER_MIN = 56;
@@ -16146,10 +16787,10 @@ function FloatingPanel({
16146
16787
  className,
16147
16788
  bodyClassName
16148
16789
  }) {
16149
- const panelRef = (0, import_react15.useRef)(null);
16150
- const [measured, setMeasured] = (0, import_react15.useState)({ w: PANEL_WIDTH, h: 280 });
16151
- const dragRef = (0, import_react15.useRef)(null);
16152
- const homeRef = (0, import_react15.useRef)(null);
16790
+ const panelRef = (0, import_react16.useRef)(null);
16791
+ const [measured, setMeasured] = (0, import_react16.useState)({ w: PANEL_WIDTH, h: 280 });
16792
+ const dragRef = (0, import_react16.useRef)(null);
16793
+ const homeRef = (0, import_react16.useRef)(null);
16153
16794
  if (!open) {
16154
16795
  homeRef.current = null;
16155
16796
  } else if (position) {
@@ -16157,17 +16798,17 @@ function FloatingPanel({
16157
16798
  } else if (homeRef.current == null) {
16158
16799
  homeRef.current = defaultFloatingPanelPosition(parentScroll);
16159
16800
  }
16160
- const [liveScroll, setLiveScroll] = (0, import_react15.useState)(parentScroll);
16801
+ const [liveScroll, setLiveScroll] = (0, import_react16.useState)(parentScroll);
16161
16802
  const home = position ?? homeRef.current ?? defaultFloatingPanelPosition(parentScroll);
16162
16803
  const { y: fittedY, maxHeight } = fitPanelInClip(home.y, liveScroll, measured.h);
16163
16804
  const clamped = {
16164
16805
  x: clampX(home.x, measured.w),
16165
16806
  y: fittedY
16166
16807
  };
16167
- (0, import_react15.useEffect)(() => {
16808
+ (0, import_react16.useEffect)(() => {
16168
16809
  setLiveScroll(parentScroll);
16169
16810
  }, [parentScroll]);
16170
- (0, import_react15.useEffect)(() => {
16811
+ (0, import_react16.useEffect)(() => {
16171
16812
  if (!open) return;
16172
16813
  const onParentScroll = (e) => {
16173
16814
  if (e.data?.type !== "ow:parent-scroll") return;
@@ -16177,8 +16818,8 @@ function FloatingPanel({
16177
16818
  window.addEventListener("message", onParentScroll);
16178
16819
  return () => window.removeEventListener("message", onParentScroll);
16179
16820
  }, [open]);
16180
- const positionRef = (0, import_react15.useRef)(position);
16181
- (0, import_react15.useLayoutEffect)(() => {
16821
+ const positionRef = (0, import_react16.useRef)(position);
16822
+ (0, import_react16.useLayoutEffect)(() => {
16182
16823
  if (!open) {
16183
16824
  positionRef.current = position;
16184
16825
  return;
@@ -16188,7 +16829,7 @@ function FloatingPanel({
16188
16829
  }
16189
16830
  positionRef.current = position;
16190
16831
  }, [open, position, liveScroll, parentScroll]);
16191
- (0, import_react15.useLayoutEffect)(() => {
16832
+ (0, import_react16.useLayoutEffect)(() => {
16192
16833
  if (!open || !panelRef.current) return;
16193
16834
  const el = panelRef.current;
16194
16835
  const header = el.querySelector("[data-ohw-floating-panel-header]");
@@ -16197,7 +16838,7 @@ function FloatingPanel({
16197
16838
  const next = { w: el.offsetWidth || PANEL_WIDTH, h: contentH };
16198
16839
  setMeasured((prev) => prev.w === next.w && prev.h === next.h ? prev : next);
16199
16840
  }, [open, children, title, context]);
16200
- const onHeaderPointerDown = (0, import_react15.useCallback)(
16841
+ const onHeaderPointerDown = (0, import_react16.useCallback)(
16201
16842
  (e) => {
16202
16843
  if (e.button !== 0) return;
16203
16844
  if (e.target.closest("[data-ohw-floating-panel-close]")) return;
@@ -16216,7 +16857,7 @@ function FloatingPanel({
16216
16857
  },
16217
16858
  [clamped.x, clamped.y]
16218
16859
  );
16219
- const onHeaderPointerMove = (0, import_react15.useCallback)(
16860
+ const onHeaderPointerMove = (0, import_react16.useCallback)(
16220
16861
  (e) => {
16221
16862
  const drag = dragRef.current;
16222
16863
  if (!drag || drag.pointerId !== e.pointerId) return;
@@ -16242,7 +16883,7 @@ function FloatingPanel({
16242
16883
  },
16243
16884
  [measured.w, onPositionChange, liveScroll]
16244
16885
  );
16245
- const endDrag = (0, import_react15.useCallback)((e) => {
16886
+ const endDrag = (0, import_react16.useCallback)((e) => {
16246
16887
  const drag = dragRef.current;
16247
16888
  if (!drag || drag.pointerId !== e.pointerId) return;
16248
16889
  dragRef.current = null;
@@ -16252,13 +16893,13 @@ function FloatingPanel({
16252
16893
  } catch {
16253
16894
  }
16254
16895
  }, []);
16255
- (0, import_react15.useEffect)(() => {
16896
+ (0, import_react16.useEffect)(() => {
16256
16897
  if (open) return;
16257
16898
  document.documentElement.removeAttribute("data-ohw-panel-dragging");
16258
16899
  }, [open]);
16259
- (0, import_react15.useEffect)(() => () => document.documentElement.removeAttribute("data-ohw-panel-dragging"), []);
16900
+ (0, import_react16.useEffect)(() => () => document.documentElement.removeAttribute("data-ohw-panel-dragging"), []);
16260
16901
  if (!open) return null;
16261
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
16902
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
16262
16903
  "div",
16263
16904
  {
16264
16905
  ref: panelRef,
@@ -16275,7 +16916,7 @@ function FloatingPanel({
16275
16916
  onPointerDown: (e) => e.stopPropagation(),
16276
16917
  onClick: (e) => e.stopPropagation(),
16277
16918
  children: [
16278
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
16919
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
16279
16920
  "div",
16280
16921
  {
16281
16922
  "data-ohw-floating-panel-header": "",
@@ -16285,14 +16926,14 @@ function FloatingPanel({
16285
16926
  onPointerUp: endDrag,
16286
16927
  onPointerCancel: endDrag,
16287
16928
  children: [
16288
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
16289
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-2", children: [
16290
- icon ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "shrink-0 text-foreground", children: icon }) : null,
16291
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "min-w-0 flex-1 text-lg font-semibold leading-7 text-foreground", children: title })
16929
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [
16930
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-2", children: [
16931
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "shrink-0 text-foreground", children: icon }) : null,
16932
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "min-w-0 flex-1 text-lg font-semibold leading-7 text-foreground", children: title })
16292
16933
  ] }),
16293
- context ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "w-full text-sm leading-5 text-muted-foreground", children: context }) : null
16934
+ context ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "w-full text-sm leading-5 text-muted-foreground", children: context }) : null
16294
16935
  ] }),
16295
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
16936
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
16296
16937
  "button",
16297
16938
  {
16298
16939
  type: "button",
@@ -16304,13 +16945,13 @@ function FloatingPanel({
16304
16945
  onClose();
16305
16946
  },
16306
16947
  onPointerDown: (e) => e.stopPropagation(),
16307
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react16.X, { size: 16, "aria-hidden": true })
16948
+ children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react17.X, { size: 16, "aria-hidden": true })
16308
16949
  }
16309
16950
  )
16310
16951
  ]
16311
16952
  }
16312
16953
  ),
16313
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
16954
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
16314
16955
  "div",
16315
16956
  {
16316
16957
  "data-ohw-floating-panel-body": "",
@@ -16328,15 +16969,15 @@ function FloatingPanel({
16328
16969
  }
16329
16970
 
16330
16971
  // src/ui/socials-display-panel.tsx
16331
- var import_jsx_runtime30 = require("react/jsx-runtime");
16972
+ var import_jsx_runtime31 = require("react/jsx-runtime");
16332
16973
  function DisplaySwitch({
16333
16974
  label,
16334
16975
  checked,
16335
16976
  disabled,
16336
16977
  onChange
16337
16978
  }) {
16338
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex w-full items-center gap-2", children: [
16339
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
16979
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex w-full items-center gap-2", children: [
16980
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
16340
16981
  "span",
16341
16982
  {
16342
16983
  className: cn(
@@ -16346,7 +16987,7 @@ function DisplaySwitch({
16346
16987
  children: label
16347
16988
  }
16348
16989
  ),
16349
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
16990
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
16350
16991
  "button",
16351
16992
  {
16352
16993
  type: "button",
@@ -16360,7 +17001,7 @@ function DisplaySwitch({
16360
17001
  checked ? "bg-bridge-primary" : "bg-primary-50",
16361
17002
  disabled ? "cursor-default opacity-50" : "cursor-pointer"
16362
17003
  ),
16363
- children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
17004
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
16364
17005
  "span",
16365
17006
  {
16366
17007
  className: cn(
@@ -16374,8 +17015,8 @@ function DisplaySwitch({
16374
17015
  ] });
16375
17016
  }
16376
17017
  function SocialsDisplayPanel({ display, onChange, className }) {
16377
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: cn("flex w-full flex-col gap-3", className), children: [
16378
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
17018
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cn("flex w-full flex-col gap-3", className), children: [
17019
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
16379
17020
  DisplaySwitch,
16380
17021
  {
16381
17022
  label: "Text",
@@ -16384,7 +17025,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
16384
17025
  onChange: (text) => onChange({ ...display, text })
16385
17026
  }
16386
17027
  ),
16387
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
17028
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
16388
17029
  DisplaySwitch,
16389
17030
  {
16390
17031
  label: "Icon",
@@ -16397,7 +17038,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
16397
17038
  }
16398
17039
 
16399
17040
  // src/ui/button-style-panel.tsx
16400
- var import_lucide_react17 = require("lucide-react");
17041
+ var import_lucide_react18 = require("lucide-react");
16401
17042
 
16402
17043
  // src/lib/button-styles.ts
16403
17044
  var BUTTON_VARIANTS_KEY = "__ohw_button_variants";
@@ -17100,7 +17741,7 @@ function withAssignment(content, id, assignment) {
17100
17741
  }
17101
17742
 
17102
17743
  // src/ui/button-style-panel.tsx
17103
- var import_jsx_runtime31 = require("react/jsx-runtime");
17744
+ var import_jsx_runtime32 = require("react/jsx-runtime");
17104
17745
  var SIZE_LABEL = { s: "S", m: "M", l: "L" };
17105
17746
  function ButtonStylePanel({
17106
17747
  variants,
@@ -17114,15 +17755,15 @@ function ButtonStylePanel({
17114
17755
  }) {
17115
17756
  const preview = scaleGeometry(sizes.m, 0.75);
17116
17757
  const label = previewLabel.trim() || "Book Now";
17117
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "flex w-full flex-col gap-5", children: [
17118
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("section", { className: "flex w-full flex-col gap-2.5", children: [
17119
- /* @__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" }),
17120
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "flex w-full flex-col gap-2.5", children: BUTTON_VARIANT_IDS.map((id) => {
17758
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex w-full flex-col gap-5", children: [
17759
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("section", { className: "flex w-full flex-col gap-2.5", children: [
17760
+ /* @__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" }),
17761
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex w-full flex-col gap-2.5", children: BUTTON_VARIANT_IDS.map((id) => {
17121
17762
  const chrome = variants[id];
17122
17763
  const selected = id === variant;
17123
17764
  const hasBorder = parseFloat(chrome.borderWidth) > 0;
17124
17765
  const cardSlot = previewSlotForChrome(chrome, slotBackground);
17125
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
17766
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
17126
17767
  "button",
17127
17768
  {
17128
17769
  type: "button",
@@ -17138,12 +17779,12 @@ function ButtonStylePanel({
17138
17779
  selected ? "border-2 border-primary" : "border border-border"
17139
17780
  ),
17140
17781
  children: [
17141
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
17782
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
17142
17783
  "div",
17143
17784
  {
17144
17785
  className: "flex w-full items-center justify-center py-4",
17145
17786
  style: { background: cardSlot },
17146
- children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
17787
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
17147
17788
  "span",
17148
17789
  {
17149
17790
  className: "inline-flex items-center justify-center whitespace-nowrap font-semibold uppercase leading-none",
@@ -17165,12 +17806,12 @@ function ButtonStylePanel({
17165
17806
  )
17166
17807
  }
17167
17808
  ),
17168
- selected ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
17809
+ selected ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
17169
17810
  "span",
17170
17811
  {
17171
17812
  className: "absolute right-0.5 top-0.5 flex size-5 items-center justify-center rounded-full bg-primary text-primary-foreground",
17172
17813
  "aria-hidden": true,
17173
- children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react17.Check, { className: "size-3", strokeWidth: 3 })
17814
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react18.Check, { className: "size-3", strokeWidth: 3 })
17174
17815
  }
17175
17816
  ) : null
17176
17817
  ]
@@ -17179,9 +17820,9 @@ function ButtonStylePanel({
17179
17820
  );
17180
17821
  }) })
17181
17822
  ] }),
17182
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("section", { className: "flex w-full flex-col gap-2.5", children: [
17183
- /* @__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" }),
17184
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
17823
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("section", { className: "flex w-full flex-col gap-2.5", children: [
17824
+ /* @__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" }),
17825
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
17185
17826
  "div",
17186
17827
  {
17187
17828
  className: "flex w-full items-start rounded-lg bg-stone-100 p-1",
@@ -17189,7 +17830,7 @@ function ButtonStylePanel({
17189
17830
  "aria-label": "Size",
17190
17831
  children: BUTTON_SIZE_IDS.map((id) => {
17191
17832
  const selected = id === size;
17192
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
17833
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
17193
17834
  "button",
17194
17835
  {
17195
17836
  type: "button",
@@ -18093,7 +18734,7 @@ function hitTestNavDropSlot(clientX, clientY, draggedHrefKey, draggedEl) {
18093
18734
  }
18094
18735
 
18095
18736
  // src/useNavItemDrag.ts
18096
- var import_react16 = require("react");
18737
+ var import_react17 = require("react");
18097
18738
  function useNavItemDrag({
18098
18739
  isEditMode,
18099
18740
  editContentRef,
@@ -18117,11 +18758,11 @@ function useNavItemDrag({
18117
18758
  getNavigationItemAnchor: getNavigationItemAnchor2,
18118
18759
  isDragHandleDisabled: isDragHandleDisabled2
18119
18760
  }) {
18120
- const navDragRef = (0, import_react16.useRef)(null);
18121
- const [navDropSlots, setNavDropSlots] = (0, import_react16.useState)([]);
18122
- const [activeNavDropIndex, setActiveNavDropIndex] = (0, import_react16.useState)(null);
18123
- const navPointerDragRef = (0, import_react16.useRef)(null);
18124
- const clearNavDragVisuals = (0, import_react16.useCallback)(() => {
18761
+ const navDragRef = (0, import_react17.useRef)(null);
18762
+ const [navDropSlots, setNavDropSlots] = (0, import_react17.useState)([]);
18763
+ const [activeNavDropIndex, setActiveNavDropIndex] = (0, import_react17.useState)(null);
18764
+ const navPointerDragRef = (0, import_react17.useRef)(null);
18765
+ const clearNavDragVisuals = (0, import_react17.useCallback)(() => {
18125
18766
  const session = navDragRef.current;
18126
18767
  const nestedHrefKey = session?.draggedEl?.closest("[data-ohw-nav-children]") != null ? session.hrefKey : null;
18127
18768
  navDragRef.current = null;
@@ -18154,7 +18795,7 @@ function useNavItemDrag({
18154
18795
  document.documentElement.removeAttribute("data-ohw-nav-dragging-root");
18155
18796
  unlockItemDragInteraction();
18156
18797
  }, [setDraggedItemRect, setIsItemDragging, setSiblingHintRects]);
18157
- const refreshNavDragVisuals = (0, import_react16.useCallback)(
18798
+ const refreshNavDragVisuals = (0, import_react17.useCallback)(
18158
18799
  (session, activeSlot, clientX, clientY) => {
18159
18800
  setDraggedItemRect(session.draggedEl.getBoundingClientRect());
18160
18801
  if (typeof clientX === "number" && typeof clientY === "number") {
@@ -18172,13 +18813,13 @@ function useNavItemDrag({
18172
18813
  },
18173
18814
  [setDraggedItemRect, setSiblingHintRects]
18174
18815
  );
18175
- const refreshNavDragVisualsRef = (0, import_react16.useRef)(refreshNavDragVisuals);
18816
+ const refreshNavDragVisualsRef = (0, import_react17.useRef)(refreshNavDragVisuals);
18176
18817
  refreshNavDragVisualsRef.current = refreshNavDragVisuals;
18177
- const commitNavDragRef = (0, import_react16.useRef)(() => {
18818
+ const commitNavDragRef = (0, import_react17.useRef)(() => {
18178
18819
  });
18179
- const beginNavDragRef = (0, import_react16.useRef)(() => {
18820
+ const beginNavDragRef = (0, import_react17.useRef)(() => {
18180
18821
  });
18181
- const beginNavDrag = (0, import_react16.useCallback)(
18822
+ const beginNavDrag = (0, import_react17.useCallback)(
18182
18823
  (session) => {
18183
18824
  const rect = session.draggedEl.getBoundingClientRect();
18184
18825
  session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
@@ -18217,7 +18858,7 @@ function useNavItemDrag({
18217
18858
  ]
18218
18859
  );
18219
18860
  beginNavDragRef.current = beginNavDrag;
18220
- const commitNavDrag = (0, import_react16.useCallback)(
18861
+ const commitNavDrag = (0, import_react17.useCallback)(
18221
18862
  (clientX, clientY) => {
18222
18863
  const session = navDragRef.current;
18223
18864
  if (!session) {
@@ -18296,7 +18937,7 @@ function useNavItemDrag({
18296
18937
  [clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
18297
18938
  );
18298
18939
  commitNavDragRef.current = commitNavDrag;
18299
- const startNavLinkDrag = (0, import_react16.useCallback)(
18940
+ const startNavLinkDrag = (0, import_react17.useCallback)(
18300
18941
  (anchor, clientX, clientY, wasSelected) => {
18301
18942
  if (footerDragRef.current) return false;
18302
18943
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
@@ -18314,7 +18955,7 @@ function useNavItemDrag({
18314
18955
  },
18315
18956
  [beginNavDrag, footerDragRef, isDragHandleDisabled2, isCtaButton]
18316
18957
  );
18317
- const onNavDragOver = (0, import_react16.useCallback)(
18958
+ const onNavDragOver = (0, import_react17.useCallback)(
18318
18959
  (e) => {
18319
18960
  const session = navDragRef.current;
18320
18961
  if (!session) return false;
@@ -18326,7 +18967,7 @@ function useNavItemDrag({
18326
18967
  },
18327
18968
  []
18328
18969
  );
18329
- (0, import_react16.useEffect)(() => {
18970
+ (0, import_react17.useEffect)(() => {
18330
18971
  if (!isEditMode) return;
18331
18972
  const THRESHOLD = 10;
18332
18973
  const resolveWasSelected = (el) => {
@@ -18453,7 +19094,7 @@ function useNavItemDrag({
18453
19094
  setLinkPopover,
18454
19095
  suppressNextClickRef
18455
19096
  ]);
18456
- const armNavPressFromChrome = (0, import_react16.useCallback)(
19097
+ const armNavPressFromChrome = (0, import_react17.useCallback)(
18457
19098
  (selected, clientX, clientY, pointerId) => {
18458
19099
  const hrefKey = selected.getAttribute("data-ohw-href-key");
18459
19100
  if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
@@ -18485,7 +19126,7 @@ function useNavItemDrag({
18485
19126
  }
18486
19127
 
18487
19128
  // src/useSectionDrag.ts
18488
- var import_react17 = require("react");
19129
+ var import_react18 = require("react");
18489
19130
 
18490
19131
  // src/lib/section-dnd.ts
18491
19132
  function isFooterSection(el) {
@@ -18578,21 +19219,21 @@ function useSectionDrag({
18578
19219
  suppressNextClickRef,
18579
19220
  suppressClickUntilRef
18580
19221
  }) {
18581
- const sectionDragRef = (0, import_react17.useRef)(null);
18582
- const [sectionDropSlots, setSectionDropSlots] = (0, import_react17.useState)([]);
18583
- const [activeSectionDropIndex, setActiveSectionDropIndex] = (0, import_react17.useState)(null);
18584
- const [isSectionDragging, setIsSectionDragging] = (0, import_react17.useState)(false);
18585
- const sectionPointerDragRef = (0, import_react17.useRef)(null);
18586
- const autoScrollRafRef = (0, import_react17.useRef)(null);
18587
- const autoScrollDeltaRef = (0, import_react17.useRef)(0);
18588
- const stopAutoScroll = (0, import_react17.useCallback)(() => {
19222
+ const sectionDragRef = (0, import_react18.useRef)(null);
19223
+ const [sectionDropSlots, setSectionDropSlots] = (0, import_react18.useState)([]);
19224
+ const [activeSectionDropIndex, setActiveSectionDropIndex] = (0, import_react18.useState)(null);
19225
+ const [isSectionDragging, setIsSectionDragging] = (0, import_react18.useState)(false);
19226
+ const sectionPointerDragRef = (0, import_react18.useRef)(null);
19227
+ const autoScrollRafRef = (0, import_react18.useRef)(null);
19228
+ const autoScrollDeltaRef = (0, import_react18.useRef)(0);
19229
+ const stopAutoScroll = (0, import_react18.useCallback)(() => {
18589
19230
  if (autoScrollRafRef.current != null) {
18590
19231
  cancelAnimationFrame(autoScrollRafRef.current);
18591
19232
  autoScrollRafRef.current = null;
18592
19233
  }
18593
19234
  autoScrollDeltaRef.current = 0;
18594
19235
  }, []);
18595
- const tickAutoScroll = (0, import_react17.useCallback)(() => {
19236
+ const tickAutoScroll = (0, import_react18.useCallback)(() => {
18596
19237
  if (!sectionDragRef.current) {
18597
19238
  stopAutoScroll();
18598
19239
  return;
@@ -18602,7 +19243,7 @@ function useSectionDrag({
18602
19243
  }
18603
19244
  autoScrollRafRef.current = requestAnimationFrame(tickAutoScroll);
18604
19245
  }, [postToParentRef, stopAutoScroll]);
18605
- const updateAutoScroll = (0, import_react17.useCallback)(
19246
+ const updateAutoScroll = (0, import_react18.useCallback)(
18606
19247
  (clientY) => {
18607
19248
  const clip = getIframeChromeClip(parentScrollRef.current);
18608
19249
  let delta = 0;
@@ -18624,7 +19265,7 @@ function useSectionDrag({
18624
19265
  },
18625
19266
  [parentScrollRef, stopAutoScroll, tickAutoScroll]
18626
19267
  );
18627
- const clearSectionDragVisuals = (0, import_react17.useCallback)(() => {
19268
+ const clearSectionDragVisuals = (0, import_react18.useCallback)(() => {
18628
19269
  sectionDragRef.current?.draggedEl.removeAttribute("data-ohw-section-dragging");
18629
19270
  sectionDragRef.current = null;
18630
19271
  setSectionDropSlots([]);
@@ -18634,7 +19275,7 @@ function useSectionDrag({
18634
19275
  document.documentElement.removeAttribute("data-ohw-section-dragging-root");
18635
19276
  unlockItemDragInteraction();
18636
19277
  }, [stopAutoScroll]);
18637
- const refreshSectionDragVisuals = (0, import_react17.useCallback)(
19278
+ const refreshSectionDragVisuals = (0, import_react18.useCallback)(
18638
19279
  (session, clientX, clientY) => {
18639
19280
  session.lastClientX = clientX;
18640
19281
  session.lastClientY = clientY;
@@ -18648,7 +19289,7 @@ function useSectionDrag({
18648
19289
  },
18649
19290
  [updateAutoScroll]
18650
19291
  );
18651
- const beginSectionDrag = (0, import_react17.useCallback)(
19292
+ const beginSectionDrag = (0, import_react18.useCallback)(
18652
19293
  (session) => {
18653
19294
  sectionDragRef.current = session;
18654
19295
  setIsSectionDragging(true);
@@ -18659,7 +19300,7 @@ function useSectionDrag({
18659
19300
  },
18660
19301
  [refreshSectionDragVisuals]
18661
19302
  );
18662
- const commitSectionDrag = (0, import_react17.useCallback)(() => {
19303
+ const commitSectionDrag = (0, import_react18.useCallback)(() => {
18663
19304
  const session = sectionDragRef.current;
18664
19305
  if (!session) {
18665
19306
  clearSectionDragVisuals();
@@ -18688,7 +19329,7 @@ function useSectionDrag({
18688
19329
  });
18689
19330
  });
18690
19331
  }, [clearSectionDragVisuals, editContentRef, postToParentRef]);
18691
- const startSectionPressDrag = (0, import_react17.useCallback)(
19332
+ const startSectionPressDrag = (0, import_react18.useCallback)(
18692
19333
  (el, clientX, clientY, pointerId) => {
18693
19334
  if (navDragRef.current || footerDragRef.current || sectionDragRef.current) return false;
18694
19335
  const instanceId = instanceIdOf(el);
@@ -18705,7 +19346,7 @@ function useSectionDrag({
18705
19346
  },
18706
19347
  [footerDragRef, navDragRef]
18707
19348
  );
18708
- (0, import_react17.useEffect)(() => {
19349
+ (0, import_react18.useEffect)(() => {
18709
19350
  if (!isEditMode) return;
18710
19351
  const onPointerDown = (e) => {
18711
19352
  if (e.button !== 0) return;
@@ -18810,8 +19451,8 @@ function useSectionDrag({
18810
19451
  }
18811
19452
 
18812
19453
  // src/ui/footer-container-chrome.tsx
18813
- var import_lucide_react18 = require("lucide-react");
18814
- var import_jsx_runtime32 = require("react/jsx-runtime");
19454
+ var import_lucide_react19 = require("lucide-react");
19455
+ var import_jsx_runtime33 = require("react/jsx-runtime");
18815
19456
  function FooterContainerChrome({
18816
19457
  rect,
18817
19458
  onAdd,
@@ -18819,7 +19460,7 @@ function FooterContainerChrome({
18819
19460
  }) {
18820
19461
  const chromeGap = 6;
18821
19462
  const buttonMargin = 7;
18822
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
19463
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
18823
19464
  "div",
18824
19465
  {
18825
19466
  "data-ohw-footer-container-chrome": "",
@@ -18831,8 +19472,8 @@ function FooterContainerChrome({
18831
19472
  width: rect.width + chromeGap * 2,
18832
19473
  height: rect.height + chromeGap * 2
18833
19474
  },
18834
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Tooltip, { children: [
18835
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
19475
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Tooltip, { children: [
19476
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
18836
19477
  "button",
18837
19478
  {
18838
19479
  type: "button",
@@ -18851,17 +19492,17 @@ function FooterContainerChrome({
18851
19492
  if (addDisabled) return;
18852
19493
  onAdd();
18853
19494
  },
18854
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react18.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
19495
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react19.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
18855
19496
  }
18856
19497
  ) }),
18857
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
19498
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
18858
19499
  ] })
18859
19500
  }
18860
19501
  ) });
18861
19502
  }
18862
19503
 
18863
19504
  // src/lib/carousel.ts
18864
- var import_react18 = require("react");
19505
+ var import_react19 = require("react");
18865
19506
  var CAROUSEL_ATTR = "data-ohw-carousel";
18866
19507
  var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
18867
19508
  var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
@@ -18923,8 +19564,8 @@ function applyCarouselNode(key, val) {
18923
19564
  return true;
18924
19565
  }
18925
19566
  function useOhwCarousel(key, initial) {
18926
- const [images, setImages] = (0, import_react18.useState)(initial);
18927
- (0, import_react18.useEffect)(() => {
19567
+ const [images, setImages] = (0, import_react19.useState)(initial);
19568
+ (0, import_react19.useEffect)(() => {
18928
19569
  const el = document.querySelector(
18929
19570
  `[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
18930
19571
  );
@@ -19343,14 +19984,14 @@ function deleteSelectedNavFooterItem(deps) {
19343
19984
  }
19344
19985
 
19345
19986
  // src/ui/navbar-container-chrome.tsx
19346
- var import_lucide_react19 = require("lucide-react");
19347
- var import_jsx_runtime33 = require("react/jsx-runtime");
19987
+ var import_lucide_react20 = require("lucide-react");
19988
+ var import_jsx_runtime34 = require("react/jsx-runtime");
19348
19989
  function NavbarContainerChrome({
19349
19990
  rect,
19350
19991
  onAdd
19351
19992
  }) {
19352
19993
  const chromeGap = 6;
19353
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
19994
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19354
19995
  "div",
19355
19996
  {
19356
19997
  "data-ohw-navbar-container-chrome": "",
@@ -19362,7 +20003,7 @@ function NavbarContainerChrome({
19362
20003
  width: rect.width + chromeGap * 2,
19363
20004
  height: rect.height + chromeGap * 2
19364
20005
  },
19365
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20006
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19366
20007
  "button",
19367
20008
  {
19368
20009
  type: "button",
@@ -19379,7 +20020,7 @@ function NavbarContainerChrome({
19379
20020
  e.stopPropagation();
19380
20021
  onAdd();
19381
20022
  },
19382
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react19.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
20023
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react20.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
19383
20024
  }
19384
20025
  )
19385
20026
  }
@@ -19388,7 +20029,7 @@ function NavbarContainerChrome({
19388
20029
 
19389
20030
  // src/ui/drop-indicator.tsx
19390
20031
  var React11 = __toESM(require("react"), 1);
19391
- var import_jsx_runtime34 = require("react/jsx-runtime");
20032
+ var import_jsx_runtime35 = require("react/jsx-runtime");
19392
20033
  var dropIndicatorVariants = cva(
19393
20034
  "ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
19394
20035
  {
@@ -19412,7 +20053,7 @@ var dropIndicatorVariants = cva(
19412
20053
  );
19413
20054
  var DropIndicator = React11.forwardRef(
19414
20055
  ({ className, direction, state, ...props }, ref) => {
19415
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
20056
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
19416
20057
  "div",
19417
20058
  {
19418
20059
  ref,
@@ -19429,7 +20070,7 @@ var DropIndicator = React11.forwardRef(
19429
20070
  DropIndicator.displayName = "DropIndicator";
19430
20071
 
19431
20072
  // src/ui/badge.tsx
19432
- var import_jsx_runtime35 = require("react/jsx-runtime");
20073
+ var import_jsx_runtime36 = require("react/jsx-runtime");
19433
20074
  var badgeVariants = cva(
19434
20075
  "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",
19435
20076
  {
@@ -19447,13 +20088,13 @@ var badgeVariants = cva(
19447
20088
  }
19448
20089
  );
19449
20090
  function Badge({ className, variant, ...props }) {
19450
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
20091
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
19451
20092
  }
19452
20093
 
19453
20094
  // src/OhhwellsBridge.tsx
19454
- var import_lucide_react20 = require("lucide-react");
19455
- var import_jsx_runtime36 = require("react/jsx-runtime");
19456
- var PRIMARY5 = "#0885FE";
20095
+ var import_lucide_react21 = require("lucide-react");
20096
+ var import_jsx_runtime37 = require("react/jsx-runtime");
20097
+ var PRIMARY6 = "#0885FE";
19457
20098
  var IMAGE_FADE_MS = 300;
19458
20099
  var MEDIA_SETTLE_TIMEOUT_MS = 2500;
19459
20100
  function runOpacityFade(el, onDone) {
@@ -19574,7 +20215,7 @@ function duplicateSchedulingWidget(instanceId, scheduleId) {
19574
20215
  schedulingRoots.set(container, root);
19575
20216
  (0, import_react_dom4.flushSync)(() => {
19576
20217
  root.render(
19577
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
20218
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
19578
20219
  SchedulingWidget,
19579
20220
  {
19580
20221
  notifyOnConnect: false,
@@ -19617,21 +20258,10 @@ function parseSchedulingInsertAfter(insertAfter) {
19617
20258
  insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
19618
20259
  };
19619
20260
  }
19620
- function resolveSchedulingInsert(insertAfter, explicitInsertBefore) {
19621
- const parsed = parseSchedulingInsertAfter(insertAfter);
19622
- const insertBefore = explicitInsertBefore ?? parsed.insertBefore;
19623
- const effectiveInsertAfter = insertBefore && parsed.insertBefore === null ? `${insertAfter}${INSERT_BEFORE_MARKER}${insertBefore}` : insertAfter;
19624
- return { effectiveInsertAfter, insertBefore };
19625
- }
19626
- function getSchedulingMountPoint(insertAfter) {
19627
- const { anchor } = parseSchedulingInsertAfter(insertAfter);
19628
- let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
19629
- if (!anchorEl && anchor === "scheduling") {
19630
- const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
19631
- anchorEl = widgets.at(-1) ?? null;
19632
- }
19633
- if (!anchorEl) return null;
19634
- return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
20261
+ function resolveEntryAnchor(entry) {
20262
+ if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
20263
+ const parsed = parseSchedulingInsertAfter(entry.insertAfter);
20264
+ return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
19635
20265
  }
19636
20266
  function schedulingMountDepth(insertAfter) {
19637
20267
  if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
@@ -19648,8 +20278,7 @@ function getPageSchedulingEntries(raw) {
19648
20278
  }
19649
20279
  }
19650
20280
  function isSchedulingWidgetMissing(entry) {
19651
- const { effectiveInsertAfter } = resolveSchedulingInsert(entry.insertAfter);
19652
- return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
20281
+ return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
19653
20282
  }
19654
20283
  function hasMissingSchedulingWidgets(entries) {
19655
20284
  return entries.some(isSchedulingWidgetMissing);
@@ -19687,17 +20316,18 @@ function initSectionsFromContent(content, removeExisting = false, currentPath =
19687
20316
  } catch {
19688
20317
  }
19689
20318
  }
19690
- function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId, explicitInsertBefore) {
19691
- const { effectiveInsertAfter, insertBefore } = resolveSchedulingInsert(insertAfter, explicitInsertBefore);
19692
- const sectionId = schedulingSectionId(effectiveInsertAfter);
20319
+ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
20320
+ const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
20321
+ const sectionId = schedulingSectionId(widgetId);
19693
20322
  if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
19694
- const mountPoint = getSchedulingMountPoint(effectiveInsertAfter);
19695
- if (!mountPoint) return false;
20323
+ const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
20324
+ if (!anchorEl) return false;
20325
+ const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
19696
20326
  const container = document.createElement("div");
19697
20327
  container.dataset.ohwSectionContainer = "scheduling";
19698
20328
  container.dataset.ohwInstance = sectionId;
19699
- if (insertBefore) {
19700
- const beforeAnchor = document.querySelector(`[data-ohw-section="${insertBefore}"]`);
20329
+ if (beforeId) {
20330
+ const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
19701
20331
  const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
19702
20332
  if (!beforePoint) return false;
19703
20333
  beforePoint.insertAdjacentElement("beforebegin", container);
@@ -19708,20 +20338,26 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
19708
20338
  }
19709
20339
  tail.insertAdjacentElement("afterend", container);
19710
20340
  }
19711
- const root = (0, import_client2.createRoot)(container);
19712
- schedulingRoots.set(container, root);
19713
- (0, import_react_dom4.flushSync)(() => {
19714
- root.render(
19715
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
19716
- SchedulingWidget,
19717
- {
19718
- notifyOnConnect,
19719
- initialScheduleId: scheduleId,
19720
- insertAfter: effectiveInsertAfter
19721
- }
19722
- )
19723
- );
19724
- });
20341
+ try {
20342
+ const root = (0, import_client2.createRoot)(container);
20343
+ schedulingRoots.set(container, root);
20344
+ (0, import_react_dom4.flushSync)(() => {
20345
+ root.render(
20346
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20347
+ SchedulingWidget,
20348
+ {
20349
+ notifyOnConnect,
20350
+ initialScheduleId: scheduleId,
20351
+ insertAfter: widgetId
20352
+ }
20353
+ )
20354
+ );
20355
+ });
20356
+ } catch (err) {
20357
+ console.error("[ow:scheduling] render threw", err);
20358
+ container.remove();
20359
+ return false;
20360
+ }
19725
20361
  const tracker = getSectionsTracker();
19726
20362
  let sections = [];
19727
20363
  try {
@@ -19729,10 +20365,12 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
19729
20365
  } catch {
19730
20366
  }
19731
20367
  const inEditor = typeof window !== "undefined" && window.self !== window.top;
19732
- if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === effectiveInsertAfter)) {
20368
+ if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
19733
20369
  sections.push({
19734
20370
  type: "scheduling",
19735
- insertAfter: effectiveInsertAfter,
20371
+ insertAfter: widgetId,
20372
+ anchorId,
20373
+ beforeId: beforeId ?? null,
19736
20374
  pagePath: window.location.pathname,
19737
20375
  ...scheduleId ? { scheduleId } : {}
19738
20376
  });
@@ -19746,7 +20384,8 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
19746
20384
  for (let i = pending.length - 1; i >= 0; i--) {
19747
20385
  const entry = pending[i];
19748
20386
  const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
19749
- if (mountSchedulingWidget(entry.insertAfter, shouldNotify, entry.scheduleId ?? null)) {
20387
+ const { anchorId, beforeId } = resolveEntryAnchor(entry);
20388
+ if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
19750
20389
  pending.splice(i, 1);
19751
20390
  }
19752
20391
  }
@@ -20213,7 +20852,7 @@ function getNavigationSelectionParent(el) {
20213
20852
  if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
20214
20853
  return getFooterLinksContainer();
20215
20854
  }
20216
- if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
20855
+ 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)) {
20217
20856
  return getNavigationRoot(el);
20218
20857
  }
20219
20858
  return null;
@@ -20435,13 +21074,12 @@ var ICONS = {
20435
21074
  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"/>',
20436
21075
  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"/>'
20437
21076
  };
20438
- var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
20439
21077
  var SELECTION_CHROME_GAP2 = 4;
20440
21078
  var TOOLBAR_STROKE_GAP2 = 4;
20441
21079
  var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
20442
21080
  var HOVER_STROKE_WIDTH = 1.5;
20443
21081
  var TEXT_HOVER_SIDE_PAD = 4;
20444
- var CHROME_PRIMARY = `var(--ohw-primary, ${PRIMARY5})`;
21082
+ var CHROME_PRIMARY = `var(--ohw-primary, ${PRIMARY6})`;
20445
21083
  var TOOLBAR_GROUPS = [
20446
21084
  [
20447
21085
  { cmd: "bold", title: "Bold" },
@@ -20467,7 +21105,7 @@ function EditGlowChrome({
20467
21105
  hideHandle = false
20468
21106
  }) {
20469
21107
  const GAP = SELECTION_CHROME_GAP2;
20470
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
21108
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
20471
21109
  "div",
20472
21110
  {
20473
21111
  ref: elRef,
@@ -20482,7 +21120,7 @@ function EditGlowChrome({
20482
21120
  zIndex: 2147483646
20483
21121
  },
20484
21122
  children: [
20485
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21123
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20486
21124
  "div",
20487
21125
  {
20488
21126
  style: {
@@ -20496,7 +21134,7 @@ function EditGlowChrome({
20496
21134
  }
20497
21135
  }
20498
21136
  ),
20499
- reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21137
+ reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20500
21138
  "div",
20501
21139
  {
20502
21140
  "data-ohw-drag-handle-container": "",
@@ -20508,7 +21146,7 @@ function EditGlowChrome({
20508
21146
  transform: "translate(calc(-100% - 7px), -50%)",
20509
21147
  pointerEvents: dragDisabled ? "none" : "auto"
20510
21148
  },
20511
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21149
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20512
21150
  DragHandle,
20513
21151
  {
20514
21152
  "aria-label": `Reorder ${reorderHrefKey}`,
@@ -20685,9 +21323,9 @@ function FloatingToolbar({
20685
21323
  showEditLink,
20686
21324
  onEditLink
20687
21325
  }) {
20688
- const localRef = import_react19.default.useRef(null);
20689
- const [measuredW, setMeasuredW] = import_react19.default.useState(330);
20690
- const setRefs = import_react19.default.useCallback(
21326
+ const localRef = import_react20.default.useRef(null);
21327
+ const [measuredW, setMeasuredW] = import_react20.default.useState(330);
21328
+ const setRefs = import_react20.default.useCallback(
20691
21329
  (node) => {
20692
21330
  localRef.current = node;
20693
21331
  if (typeof elRef === "function") elRef(node);
@@ -20699,7 +21337,7 @@ function FloatingToolbar({
20699
21337
  },
20700
21338
  [elRef]
20701
21339
  );
20702
- import_react19.default.useLayoutEffect(() => {
21340
+ import_react20.default.useLayoutEffect(() => {
20703
21341
  const node = localRef.current;
20704
21342
  if (!node) return;
20705
21343
  const update = () => {
@@ -20712,7 +21350,7 @@ function FloatingToolbar({
20712
21350
  return () => ro.disconnect();
20713
21351
  }, [showEditLink, activeCommands]);
20714
21352
  const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
20715
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21353
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20716
21354
  "div",
20717
21355
  {
20718
21356
  ref: setRefs,
@@ -20724,12 +21362,12 @@ function FloatingToolbar({
20724
21362
  zIndex: 2147483647,
20725
21363
  pointerEvents: "auto"
20726
21364
  },
20727
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(CustomToolbar, { children: [
20728
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react19.default.Fragment, { children: [
20729
- gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CustomToolbarDivider, {}),
21365
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(CustomToolbar, { children: [
21366
+ TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_react20.default.Fragment, { children: [
21367
+ gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(CustomToolbarDivider, {}),
20730
21368
  btns.map((btn) => {
20731
21369
  const isActive = activeCommands.has(btn.cmd);
20732
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21370
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20733
21371
  CustomToolbarButton,
20734
21372
  {
20735
21373
  title: btn.title,
@@ -20738,7 +21376,7 @@ function FloatingToolbar({
20738
21376
  e.preventDefault();
20739
21377
  onCommand(btn.cmd);
20740
21378
  },
20741
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21379
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20742
21380
  "svg",
20743
21381
  {
20744
21382
  width: "16",
@@ -20759,7 +21397,7 @@ function FloatingToolbar({
20759
21397
  );
20760
21398
  })
20761
21399
  ] }, gi)),
20762
- showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21400
+ showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20763
21401
  CustomToolbarButton,
20764
21402
  {
20765
21403
  type: "button",
@@ -20773,7 +21411,7 @@ function FloatingToolbar({
20773
21411
  e.preventDefault();
20774
21412
  e.stopPropagation();
20775
21413
  },
20776
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Link, { className: "size-4 shrink-0", "aria-hidden": true })
21414
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react21.Link, { className: "size-4 shrink-0", "aria-hidden": true })
20777
21415
  }
20778
21416
  ) : null
20779
21417
  ] })
@@ -20790,7 +21428,7 @@ function StateToggle({
20790
21428
  states,
20791
21429
  onStateChange
20792
21430
  }) {
20793
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21431
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20794
21432
  ToggleGroup,
20795
21433
  {
20796
21434
  "data-ohw-state-toggle": "",
@@ -20804,11 +21442,12 @@ function StateToggle({
20804
21442
  left: rect.right - 8,
20805
21443
  transform: "translateX(-100%)"
20806
21444
  },
20807
- children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
21445
+ children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
20808
21446
  }
20809
21447
  );
20810
21448
  }
20811
21449
  var contentCache = /* @__PURE__ */ new Map();
21450
+ var fetchedContentPaths = /* @__PURE__ */ new Set();
20812
21451
  var brandingCache = /* @__PURE__ */ new Map();
20813
21452
  var OHW_LOADER_STYLE = {
20814
21453
  position: "fixed",
@@ -20820,9 +21459,9 @@ var OHW_LOADER_STYLE = {
20820
21459
  justifyContent: "center"
20821
21460
  };
20822
21461
  function OhwLoaderSpinner() {
20823
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", "aria-hidden": true, children: [
20824
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("circle", { cx: "14", cy: "14", r: "11", stroke: "#E7E5E4", strokeWidth: "3" }),
20825
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21462
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", "aria-hidden": true, children: [
21463
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("circle", { cx: "14", cy: "14", r: "11", stroke: "#E7E5E4", strokeWidth: "3" }),
21464
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20826
21465
  "circle",
20827
21466
  {
20828
21467
  cx: "14",
@@ -20832,7 +21471,7 @@ function OhwLoaderSpinner() {
20832
21471
  strokeWidth: "3",
20833
21472
  strokeDasharray: "17 52",
20834
21473
  strokeLinecap: "round",
20835
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21474
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20836
21475
  "animateTransform",
20837
21476
  {
20838
21477
  attributeName: "transform",
@@ -20848,7 +21487,7 @@ function OhwLoaderSpinner() {
20848
21487
  ] });
20849
21488
  }
20850
21489
  function OhwBrandMark() {
20851
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
21490
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
20852
21491
  "svg",
20853
21492
  {
20854
21493
  width: "16",
@@ -20859,7 +21498,7 @@ function OhwBrandMark() {
20859
21498
  style: { display: "block", flexShrink: 0 },
20860
21499
  xmlns: "http://www.w3.org/2000/svg",
20861
21500
  children: [
20862
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
21501
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
20863
21502
  "mask",
20864
21503
  {
20865
21504
  id: "ohw-badge-mark",
@@ -20869,15 +21508,15 @@ function OhwBrandMark() {
20869
21508
  y: "0",
20870
21509
  width: "48",
20871
21510
  height: "48",
20872
- 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" })
21511
+ 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" })
20873
21512
  }
20874
21513
  ),
20875
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("g", { mask: "url(#ohw-badge-mark)", children: [
20876
- /* @__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" }),
20877
- /* @__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" }),
20878
- /* @__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" }),
20879
- /* @__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" }),
20880
- /* @__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" })
21514
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("g", { mask: "url(#ohw-badge-mark)", children: [
21515
+ /* @__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" }),
21516
+ /* @__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" }),
21517
+ /* @__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" }),
21518
+ /* @__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" }),
21519
+ /* @__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" })
20881
21520
  ] })
20882
21521
  ]
20883
21522
  }
@@ -20914,7 +21553,7 @@ var OHW_BADGE_LABEL_STYLE = {
20914
21553
  whiteSpace: "nowrap"
20915
21554
  };
20916
21555
  function MadeWithOhhWells() {
20917
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
21556
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
20918
21557
  "a",
20919
21558
  {
20920
21559
  href: "https://ohhwells.com",
@@ -20924,8 +21563,8 @@ function MadeWithOhhWells() {
20924
21563
  "data-ohw-badge": "",
20925
21564
  style: OHW_BADGE_STYLE,
20926
21565
  children: [
20927
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(OhwBrandMark, {}),
20928
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { style: OHW_BADGE_LABEL_STYLE, children: "Made with OhhWells" })
21566
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(OhwBrandMark, {}),
21567
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { style: OHW_BADGE_LABEL_STYLE, children: "Made with OhhWells" })
20929
21568
  ]
20930
21569
  }
20931
21570
  );
@@ -20971,8 +21610,8 @@ function OhhwellsBridge() {
20971
21610
  const router = (0, import_navigation3.useRouter)();
20972
21611
  const searchParams = (0, import_navigation3.useSearchParams)();
20973
21612
  const isEditMode = isEditSessionActive();
20974
- const [bridgeRoot, setBridgeRoot] = (0, import_react19.useState)(null);
20975
- (0, import_react19.useEffect)(() => {
21613
+ const [bridgeRoot, setBridgeRoot] = (0, import_react20.useState)(null);
21614
+ (0, import_react20.useEffect)(() => {
20976
21615
  const figtreeFontId = "ohw-figtree-font";
20977
21616
  if (!document.getElementById(figtreeFontId)) {
20978
21617
  const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
@@ -20998,8 +21637,8 @@ function OhhwellsBridge() {
20998
21637
  };
20999
21638
  }, []);
21000
21639
  const subdomainFromQuery = searchParams.get("subdomain");
21001
- const [subdomain, setSubdomain] = (0, import_react19.useState)(() => resolveSubdomain(subdomainFromQuery));
21002
- (0, import_react19.useLayoutEffect)(() => {
21640
+ const [subdomain, setSubdomain] = (0, import_react20.useState)(() => resolveSubdomain(subdomainFromQuery));
21641
+ (0, import_react20.useLayoutEffect)(() => {
21003
21642
  const next = resolveSubdomain(subdomainFromQuery);
21004
21643
  if (next !== subdomain) setSubdomain(next);
21005
21644
  if (next) return;
@@ -21011,54 +21650,55 @@ function OhhwellsBridge() {
21011
21650
  }, 0);
21012
21651
  return () => window.clearTimeout(t);
21013
21652
  }, [subdomainFromQuery, subdomain]);
21014
- (0, import_react19.useEffect)(() => {
21653
+ (0, import_react20.useEffect)(() => {
21015
21654
  if (!subdomainFromQuery || typeof window === "undefined") return;
21016
21655
  const url = new URL(window.location.href);
21017
21656
  if (!url.searchParams.has("subdomain")) return;
21657
+ if (!resolveSubdomain(null)) return;
21018
21658
  url.searchParams.delete("subdomain");
21019
21659
  window.history.replaceState(null, "", url.pathname + url.search + url.hash);
21020
21660
  }, [subdomainFromQuery]);
21021
21661
  useLinkHrefGuardian(pathname, subdomain, isEditMode);
21022
21662
  useSavedLinkNavigation(isEditMode);
21023
- const postToParent2 = (0, import_react19.useCallback)((data) => {
21663
+ const postToParent2 = (0, import_react20.useCallback)((data) => {
21024
21664
  if (typeof window !== "undefined" && window.parent !== window) {
21025
21665
  window.parent.postMessage(data, "*");
21026
21666
  }
21027
21667
  }, []);
21028
- const [fetchState, setFetchState] = (0, import_react19.useState)("idle");
21029
- const [showBranding, setShowBranding] = (0, import_react19.useState)(false);
21030
- const autoSaveTimers = (0, import_react19.useRef)(/* @__PURE__ */ new Map());
21031
- const activeElRef = (0, import_react19.useRef)(null);
21032
- const pointerHeldRef = (0, import_react19.useRef)(false);
21033
- const selectedElRef = (0, import_react19.useRef)(null);
21034
- const selectedHrefKeyRef = (0, import_react19.useRef)(null);
21035
- const selectedFooterColAttrRef = (0, import_react19.useRef)(null);
21036
- const originalContentRef = (0, import_react19.useRef)(null);
21037
- const activeStateElRef = (0, import_react19.useRef)(null);
21038
- const parentScrollRef = (0, import_react19.useRef)(null);
21039
- const visibleViewportRef = (0, import_react19.useRef)(null);
21040
- const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react19.useState)(null);
21041
- const attachVisibleViewport = (0, import_react19.useCallback)((node) => {
21668
+ const [fetchState, setFetchState] = (0, import_react20.useState)("idle");
21669
+ const [showBranding, setShowBranding] = (0, import_react20.useState)(false);
21670
+ const autoSaveTimers = (0, import_react20.useRef)(/* @__PURE__ */ new Map());
21671
+ const activeElRef = (0, import_react20.useRef)(null);
21672
+ const pointerHeldRef = (0, import_react20.useRef)(false);
21673
+ const selectedElRef = (0, import_react20.useRef)(null);
21674
+ const selectedHrefKeyRef = (0, import_react20.useRef)(null);
21675
+ const selectedFooterColAttrRef = (0, import_react20.useRef)(null);
21676
+ const originalContentRef = (0, import_react20.useRef)(null);
21677
+ const activeStateElRef = (0, import_react20.useRef)(null);
21678
+ const parentScrollRef = (0, import_react20.useRef)(null);
21679
+ const visibleViewportRef = (0, import_react20.useRef)(null);
21680
+ const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react20.useState)(null);
21681
+ const attachVisibleViewport = (0, import_react20.useCallback)((node) => {
21042
21682
  visibleViewportRef.current = node;
21043
21683
  setDialogPortalContainer(node);
21044
21684
  if (node) applyVisibleViewport(node, parentScrollRef.current);
21045
21685
  }, []);
21046
- const toolbarElRef = (0, import_react19.useRef)(null);
21047
- const glowElRef = (0, import_react19.useRef)(null);
21048
- const hoveredImageRef = (0, import_react19.useRef)(null);
21049
- const hoveredImageHasTextOverlapRef = (0, import_react19.useRef)(false);
21050
- const dragOverElRef = (0, import_react19.useRef)(null);
21051
- const [mediaHover, setMediaHover] = (0, import_react19.useState)(null);
21052
- const [selectedAiSectionId, setSelectedAiSectionId] = (0, import_react19.useState)(null);
21053
- const selectedAiSectionIdRef = (0, import_react19.useRef)(null);
21054
- const handleAiSectionSelectionChange = (0, import_react19.useCallback)((id) => {
21686
+ const toolbarElRef = (0, import_react20.useRef)(null);
21687
+ const glowElRef = (0, import_react20.useRef)(null);
21688
+ const hoveredImageRef = (0, import_react20.useRef)(null);
21689
+ const hoveredImageHasTextOverlapRef = (0, import_react20.useRef)(false);
21690
+ const dragOverElRef = (0, import_react20.useRef)(null);
21691
+ const [mediaHover, setMediaHover] = (0, import_react20.useState)(null);
21692
+ const [selectedAiSectionId, setSelectedAiSectionId] = (0, import_react20.useState)(null);
21693
+ const selectedAiSectionIdRef = (0, import_react20.useRef)(null);
21694
+ const handleAiSectionSelectionChange = (0, import_react20.useCallback)((id) => {
21055
21695
  selectedAiSectionIdRef.current = id;
21056
21696
  setSelectedAiSectionId(id);
21057
21697
  }, []);
21058
- const [selectedMedia, setSelectedMedia] = (0, import_react19.useState)(null);
21059
- const selectedMediaElRef = (0, import_react19.useRef)(null);
21060
- const mediaKeyDropTokenRef = (0, import_react19.useRef)(0);
21061
- const clearMediaSelection = (0, import_react19.useCallback)(() => {
21698
+ const [selectedMedia, setSelectedMedia] = (0, import_react20.useState)(null);
21699
+ const selectedMediaElRef = (0, import_react20.useRef)(null);
21700
+ const mediaKeyDropTokenRef = (0, import_react20.useRef)(0);
21701
+ const clearMediaSelection = (0, import_react20.useCallback)(() => {
21062
21702
  const prev = selectedMediaElRef.current;
21063
21703
  selectedMediaElRef.current = null;
21064
21704
  setSelectedMedia(null);
@@ -21083,9 +21723,9 @@ function OhhwellsBridge() {
21083
21723
  window.postMessage({ type: "ow:media-key-drop", token }, "*");
21084
21724
  }
21085
21725
  }, []);
21086
- const clearMediaSelectionRef = (0, import_react19.useRef)(clearMediaSelection);
21726
+ const clearMediaSelectionRef = (0, import_react20.useRef)(clearMediaSelection);
21087
21727
  clearMediaSelectionRef.current = clearMediaSelection;
21088
- const selectMediaElement = (0, import_react19.useCallback)((el) => {
21728
+ const selectMediaElement = (0, import_react20.useCallback)((el) => {
21089
21729
  const r2 = el.getBoundingClientRect();
21090
21730
  const video = el.dataset.ohwEditable === "video" ? el.querySelector("video") : null;
21091
21731
  selectedMediaElRef.current = el;
@@ -21109,9 +21749,9 @@ function OhhwellsBridge() {
21109
21749
  keyLabel: el.dataset.ohwEditable === "video" ? "Video" : el.dataset.ohwEditable === "bg-image" ? "Background" : "Image"
21110
21750
  });
21111
21751
  }, []);
21112
- const selectMediaElementRef = (0, import_react19.useRef)(selectMediaElement);
21752
+ const selectMediaElementRef = (0, import_react20.useRef)(selectMediaElement);
21113
21753
  selectMediaElementRef.current = selectMediaElement;
21114
- (0, import_react19.useEffect)(() => {
21754
+ (0, import_react20.useEffect)(() => {
21115
21755
  if (!selectedMedia) return;
21116
21756
  const update = () => {
21117
21757
  const el = selectedMediaElRef.current;
@@ -21131,54 +21771,54 @@ function OhhwellsBridge() {
21131
21771
  window.removeEventListener("resize", update);
21132
21772
  };
21133
21773
  }, [selectedMedia !== null]);
21134
- const [carouselHover, setCarouselHover] = (0, import_react19.useState)(null);
21135
- const [uploadingRects, setUploadingRects] = (0, import_react19.useState)({});
21136
- const hoveredGapRef = (0, import_react19.useRef)(null);
21137
- const imageUnhoverTimerRef = (0, import_react19.useRef)(null);
21138
- const imageShowTimerRef = (0, import_react19.useRef)(null);
21139
- const editStylesRef = (0, import_react19.useRef)(null);
21140
- const activateRef = (0, import_react19.useRef)(() => {
21774
+ const [carouselHover, setCarouselHover] = (0, import_react20.useState)(null);
21775
+ const [uploadingRects, setUploadingRects] = (0, import_react20.useState)({});
21776
+ const hoveredGapRef = (0, import_react20.useRef)(null);
21777
+ const imageUnhoverTimerRef = (0, import_react20.useRef)(null);
21778
+ const imageShowTimerRef = (0, import_react20.useRef)(null);
21779
+ const editStylesRef = (0, import_react20.useRef)(null);
21780
+ const activateRef = (0, import_react20.useRef)(() => {
21141
21781
  });
21142
- const deactivateRef = (0, import_react19.useRef)(() => {
21782
+ const deactivateRef = (0, import_react20.useRef)(() => {
21143
21783
  });
21144
- const selectRef = (0, import_react19.useRef)(() => {
21784
+ const selectRef = (0, import_react20.useRef)(() => {
21145
21785
  });
21146
- const selectFrameRef = (0, import_react19.useRef)(() => {
21786
+ const selectFrameRef = (0, import_react20.useRef)(() => {
21147
21787
  });
21148
- const selectLogoRef = (0, import_react19.useRef)(() => {
21788
+ const selectLogoRef = (0, import_react20.useRef)(() => {
21149
21789
  });
21150
- const openLogoSizePanelRef = (0, import_react19.useRef)(() => {
21790
+ const openLogoSizePanelRef = (0, import_react20.useRef)(() => {
21151
21791
  });
21152
- const deselectRef = (0, import_react19.useRef)(() => {
21792
+ const deselectRef = (0, import_react20.useRef)(() => {
21153
21793
  });
21154
- const closeFloatingPanelOnlyRef = (0, import_react19.useRef)(() => {
21794
+ const closeFloatingPanelOnlyRef = (0, import_react20.useRef)(() => {
21155
21795
  });
21156
- const reselectNavigationItemRef = (0, import_react19.useRef)(() => {
21796
+ const reselectNavigationItemRef = (0, import_react20.useRef)(() => {
21157
21797
  });
21158
- const commitNavigationTextEditRef = (0, import_react19.useRef)(() => {
21798
+ const commitNavigationTextEditRef = (0, import_react20.useRef)(() => {
21159
21799
  });
21160
- const handleDeleteSelectedRef = (0, import_react19.useRef)(() => false);
21161
- const runPendingDeleteUndoRef = (0, import_react19.useRef)(() => false);
21162
- const isFooterFrameSelectionRef = (0, import_react19.useRef)(false);
21163
- const refreshActiveCommandsRef = (0, import_react19.useRef)(() => {
21800
+ const handleDeleteSelectedRef = (0, import_react20.useRef)(() => false);
21801
+ const runPendingDeleteUndoRef = (0, import_react20.useRef)(() => false);
21802
+ const isFooterFrameSelectionRef = (0, import_react20.useRef)(false);
21803
+ const refreshActiveCommandsRef = (0, import_react20.useRef)(() => {
21164
21804
  });
21165
- const postToParentRef = (0, import_react19.useRef)(postToParent2);
21805
+ const postToParentRef = (0, import_react20.useRef)(postToParent2);
21166
21806
  postToParentRef.current = postToParent2;
21167
- const aiSectionApiRef = (0, import_react19.useRef)(null);
21168
- const sectionsLoadedRef = (0, import_react19.useRef)(false);
21169
- const pendingScheduleConfigRequests = (0, import_react19.useRef)([]);
21170
- const [toolbarRect, setToolbarRect] = (0, import_react19.useState)(null);
21171
- const [formPickRect, setFormPickRect] = (0, import_react19.useState)(null);
21172
- const formPickElRef = (0, import_react19.useRef)(null);
21173
- const [formViewState, setFormViewStateUi] = (0, import_react19.useState)("default");
21174
- const [formPickCount, setFormPickCount] = (0, import_react19.useState)(null);
21175
- const [formHoverRect, setFormHoverRect] = (0, import_react19.useState)(null);
21176
- const formHoverElRef = (0, import_react19.useRef)(null);
21177
- const [fieldPickRect, setFieldPickRect] = (0, import_react19.useState)(null);
21178
- const fieldPickElRef = (0, import_react19.useRef)(null);
21179
- const [fieldPickState, setFieldPickState] = (0, import_react19.useState)(null);
21180
- const [fieldTypePickerOpen, setFieldTypePickerOpen] = (0, import_react19.useState)(false);
21181
- const clearFormPick = (0, import_react19.useCallback)(() => {
21807
+ const aiSectionApiRef = (0, import_react20.useRef)(null);
21808
+ const sectionsLoadedRef = (0, import_react20.useRef)(false);
21809
+ const pendingScheduleConfigRequests = (0, import_react20.useRef)([]);
21810
+ const [toolbarRect, setToolbarRect] = (0, import_react20.useState)(null);
21811
+ const [formPickRect, setFormPickRect] = (0, import_react20.useState)(null);
21812
+ const formPickElRef = (0, import_react20.useRef)(null);
21813
+ const [formViewState, setFormViewStateUi] = (0, import_react20.useState)("default");
21814
+ const [formPickCount, setFormPickCount] = (0, import_react20.useState)(null);
21815
+ const [formHoverRect, setFormHoverRect] = (0, import_react20.useState)(null);
21816
+ const formHoverElRef = (0, import_react20.useRef)(null);
21817
+ const [fieldPickRect, setFieldPickRect] = (0, import_react20.useState)(null);
21818
+ const fieldPickElRef = (0, import_react20.useRef)(null);
21819
+ const [fieldPickState, setFieldPickState] = (0, import_react20.useState)(null);
21820
+ const [fieldTypePickerOpen, setFieldTypePickerOpen] = (0, import_react20.useState)(false);
21821
+ const clearFormPick = (0, import_react20.useCallback)(() => {
21182
21822
  const form = formPickElRef.current;
21183
21823
  const editing = fieldPickElRef.current;
21184
21824
  if (commitPlaceholderEdit(editing) && editing) {
@@ -21198,7 +21838,7 @@ function OhhwellsBridge() {
21198
21838
  formPickElRef.current = null;
21199
21839
  setFormPickRect(null);
21200
21840
  }, []);
21201
- const clearFieldPick = (0, import_react19.useCallback)(() => {
21841
+ const clearFieldPick = (0, import_react20.useCallback)(() => {
21202
21842
  const wrapper = fieldPickElRef.current;
21203
21843
  if (commitPlaceholderEdit(wrapper) && wrapper) {
21204
21844
  const form = wrapper.closest('[data-ohw-editable="form"]');
@@ -21208,9 +21848,9 @@ function OhhwellsBridge() {
21208
21848
  setFieldPickRect(null);
21209
21849
  setFieldPickState(null);
21210
21850
  }, []);
21211
- const persistFieldsRef = (0, import_react19.useRef)(() => {
21851
+ const persistFieldsRef = (0, import_react20.useRef)(() => {
21212
21852
  });
21213
- const persistFields = (0, import_react19.useCallback)(
21853
+ const persistFields = (0, import_react20.useCallback)(
21214
21854
  (form) => {
21215
21855
  const key = formKeyOf(form);
21216
21856
  if (!key) return;
@@ -21221,7 +21861,7 @@ function OhhwellsBridge() {
21221
21861
  []
21222
21862
  );
21223
21863
  persistFieldsRef.current = persistFields;
21224
- const selectField = (0, import_react19.useCallback)((wrapper) => {
21864
+ const selectField = (0, import_react20.useCallback)((wrapper) => {
21225
21865
  if (fieldPickElRef.current && fieldPickElRef.current !== wrapper) {
21226
21866
  commitPlaceholderEdit(fieldPickElRef.current);
21227
21867
  }
@@ -21234,7 +21874,7 @@ function OhhwellsBridge() {
21234
21874
  setFieldPickState({ type: fieldTypeOf(wrapper), required: isFieldRequired(wrapper) });
21235
21875
  setFieldTypePickerOpen(false);
21236
21876
  }, []);
21237
- const withSelectedField = (0, import_react19.useCallback)(
21877
+ const withSelectedField = (0, import_react20.useCallback)(
21238
21878
  (run) => {
21239
21879
  const wrapper = fieldPickElRef.current;
21240
21880
  const form = formPickElRef.current;
@@ -21247,28 +21887,28 @@ function OhhwellsBridge() {
21247
21887
  },
21248
21888
  [persistFields]
21249
21889
  );
21250
- const handleFieldTypeChange = (0, import_react19.useCallback)(
21890
+ const handleFieldTypeChange = (0, import_react20.useCallback)(
21251
21891
  (type) => withSelectedField((_form, wrapper) => {
21252
21892
  applyFieldType(wrapper, type);
21253
21893
  selectField(wrapper);
21254
21894
  }),
21255
21895
  [selectField, withSelectedField]
21256
21896
  );
21257
- const handleFieldRequiredToggle = (0, import_react19.useCallback)(
21897
+ const handleFieldRequiredToggle = (0, import_react20.useCallback)(
21258
21898
  () => withSelectedField((_form, wrapper) => {
21259
21899
  setFieldRequired(wrapper, !isFieldRequired(wrapper));
21260
21900
  selectField(wrapper);
21261
21901
  }),
21262
21902
  [selectField, withSelectedField]
21263
21903
  );
21264
- const handleFieldDuplicate = (0, import_react19.useCallback)(
21904
+ const handleFieldDuplicate = (0, import_react20.useCallback)(
21265
21905
  () => withSelectedField((form, wrapper) => {
21266
21906
  const copy = duplicateField(form, wrapper);
21267
21907
  selectField(copy);
21268
21908
  }),
21269
21909
  [selectField, withSelectedField]
21270
21910
  );
21271
- const handleFieldDelete = (0, import_react19.useCallback)(
21911
+ const handleFieldDelete = (0, import_react20.useCallback)(
21272
21912
  () => withSelectedField((_form, wrapper) => {
21273
21913
  removeField(wrapper);
21274
21914
  clearFieldPick();
@@ -21276,7 +21916,7 @@ function OhhwellsBridge() {
21276
21916
  }),
21277
21917
  [clearFieldPick, withSelectedField]
21278
21918
  );
21279
- const handleAddField = (0, import_react19.useCallback)(
21919
+ const handleAddField = (0, import_react20.useCallback)(
21280
21920
  (type) => {
21281
21921
  const form = formPickElRef.current;
21282
21922
  if (!form) return;
@@ -21292,8 +21932,8 @@ function OhhwellsBridge() {
21292
21932
  },
21293
21933
  [persistFields, selectField]
21294
21934
  );
21295
- const fieldDragRef = (0, import_react19.useRef)(null);
21296
- const buildFieldDropSlots = (0, import_react19.useCallback)((form, draggedKey) => {
21935
+ const fieldDragRef = (0, import_react20.useRef)(null);
21936
+ const buildFieldDropSlots = (0, import_react20.useCallback)((form, draggedKey) => {
21297
21937
  const others = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== draggedKey);
21298
21938
  const slots = others.map((el) => {
21299
21939
  const rect = el.getBoundingClientRect();
@@ -21306,7 +21946,7 @@ function OhhwellsBridge() {
21306
21946
  }
21307
21947
  return slots;
21308
21948
  }, []);
21309
- const handleFieldDragStart = (0, import_react19.useCallback)(() => {
21949
+ const handleFieldDragStart = (0, import_react20.useCallback)(() => {
21310
21950
  const wrapper = fieldPickElRef.current;
21311
21951
  const form = formPickElRef.current;
21312
21952
  if (!wrapper || !form) return;
@@ -21315,18 +21955,18 @@ function OhhwellsBridge() {
21315
21955
  setFieldDragging(true);
21316
21956
  setFieldDropSlots(buildFieldDropSlots(form, key));
21317
21957
  }, [buildFieldDropSlots]);
21318
- const handleFieldDragEnd = (0, import_react19.useCallback)(() => {
21958
+ const handleFieldDragEnd = (0, import_react20.useCallback)(() => {
21319
21959
  fieldDragRef.current = null;
21320
21960
  setFieldDropIndex(null);
21321
21961
  setFieldDropSlots([]);
21322
21962
  setFieldDragging(false);
21323
21963
  }, []);
21324
- const [fieldDropIndex, setFieldDropIndex] = (0, import_react19.useState)(null);
21325
- const [fieldDropSlots, setFieldDropSlots] = (0, import_react19.useState)([]);
21326
- const [fieldDragging, setFieldDragging] = (0, import_react19.useState)(false);
21327
- const clearFormPickRef = (0, import_react19.useRef)(clearFormPick);
21964
+ const [fieldDropIndex, setFieldDropIndex] = (0, import_react20.useState)(null);
21965
+ const [fieldDropSlots, setFieldDropSlots] = (0, import_react20.useState)([]);
21966
+ const [fieldDragging, setFieldDragging] = (0, import_react20.useState)(false);
21967
+ const clearFormPickRef = (0, import_react20.useRef)(clearFormPick);
21328
21968
  clearFormPickRef.current = clearFormPick;
21329
- (0, import_react19.useEffect)(() => {
21969
+ (0, import_react20.useEffect)(() => {
21330
21970
  const el = fieldPickElRef.current;
21331
21971
  if (!el || fieldPickRect === null) return;
21332
21972
  const observer = new ResizeObserver(() => {
@@ -21335,7 +21975,7 @@ function OhhwellsBridge() {
21335
21975
  observer.observe(el);
21336
21976
  return () => observer.disconnect();
21337
21977
  }, [fieldPickRect !== null, fieldPickState]);
21338
- (0, import_react19.useEffect)(() => {
21978
+ (0, import_react20.useEffect)(() => {
21339
21979
  const el = formPickElRef.current;
21340
21980
  if (!el || formPickRect === null) return;
21341
21981
  const observer = new ResizeObserver(() => {
@@ -21344,25 +21984,25 @@ function OhhwellsBridge() {
21344
21984
  observer.observe(el);
21345
21985
  return () => observer.disconnect();
21346
21986
  }, [formPickRect !== null, formViewState]);
21347
- const [toolbarVariant, setToolbarVariant] = (0, import_react19.useState)("none");
21348
- const toolbarVariantRef = (0, import_react19.useRef)("none");
21987
+ const [toolbarVariant, setToolbarVariant] = (0, import_react20.useState)("none");
21988
+ const toolbarVariantRef = (0, import_react20.useRef)("none");
21349
21989
  toolbarVariantRef.current = toolbarVariant;
21350
- const [selectedIsCta, setSelectedIsCta] = (0, import_react19.useState)(false);
21351
- const [selectedIsSocial, setSelectedIsSocial] = (0, import_react19.useState)(false);
21352
- const [selectedIsSocialsRow, setSelectedIsSocialsRow] = (0, import_react19.useState)(false);
21353
- const [reorderHrefKey, setReorderHrefKey] = (0, import_react19.useState)(null);
21354
- const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react19.useState)(false);
21355
- const [toggleState, setToggleState] = (0, import_react19.useState)(null);
21356
- const [maxBadge, setMaxBadge] = (0, import_react19.useState)(null);
21357
- const [activeCommands, setActiveCommands] = (0, import_react19.useState)(/* @__PURE__ */ new Set());
21358
- const [sectionGap, setSectionGap] = (0, import_react19.useState)(null);
21359
- const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react19.useState)(false);
21360
- const hoveredNavContainerRef = (0, import_react19.useRef)(null);
21361
- const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react19.useState)(null);
21362
- const hoveredItemElRef = (0, import_react19.useRef)(null);
21363
- const [hoveredItemRect, setHoveredItemRect] = (0, import_react19.useState)(null);
21364
- const [hoveredTextRect, setHoveredTextRect] = (0, import_react19.useState)(null);
21365
- (0, import_react19.useEffect)(() => {
21990
+ const [selectedIsCta, setSelectedIsCta] = (0, import_react20.useState)(false);
21991
+ const [selectedIsSocial, setSelectedIsSocial] = (0, import_react20.useState)(false);
21992
+ const [selectedIsSocialsRow, setSelectedIsSocialsRow] = (0, import_react20.useState)(false);
21993
+ const [reorderHrefKey, setReorderHrefKey] = (0, import_react20.useState)(null);
21994
+ const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react20.useState)(false);
21995
+ const [toggleState, setToggleState] = (0, import_react20.useState)(null);
21996
+ const [maxBadge, setMaxBadge] = (0, import_react20.useState)(null);
21997
+ const [activeCommands, setActiveCommands] = (0, import_react20.useState)(/* @__PURE__ */ new Set());
21998
+ const [sectionGap, setSectionGap] = (0, import_react20.useState)(null);
21999
+ const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react20.useState)(false);
22000
+ const hoveredNavContainerRef = (0, import_react20.useRef)(null);
22001
+ const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react20.useState)(null);
22002
+ const hoveredItemElRef = (0, import_react20.useRef)(null);
22003
+ const [hoveredItemRect, setHoveredItemRect] = (0, import_react20.useState)(null);
22004
+ const [hoveredTextRect, setHoveredTextRect] = (0, import_react20.useState)(null);
22005
+ (0, import_react20.useEffect)(() => {
21366
22006
  const sync = () => {
21367
22007
  const el = document.querySelector(
21368
22008
  '[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]):not([data-ohw-editable="form"] *)'
@@ -21406,60 +22046,71 @@ function OhhwellsBridge() {
21406
22046
  });
21407
22047
  return () => observer.disconnect();
21408
22048
  }, []);
21409
- const siblingHintElRef = (0, import_react19.useRef)(null);
21410
- const [siblingHintRect, setSiblingHintRect] = (0, import_react19.useState)(null);
21411
- const [siblingHintRects, setSiblingHintRects] = (0, import_react19.useState)([]);
21412
- const [isItemDragging, setIsItemDragging] = (0, import_react19.useState)(false);
21413
- const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react19.useState)(false);
22049
+ const siblingHintElRef = (0, import_react20.useRef)(null);
22050
+ const [siblingHintRect, setSiblingHintRect] = (0, import_react20.useState)(null);
22051
+ const [siblingHintRects, setSiblingHintRects] = (0, import_react20.useState)([]);
22052
+ const [isItemDragging, setIsItemDragging] = (0, import_react20.useState)(false);
22053
+ const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react20.useState)(false);
21414
22054
  isFooterFrameSelectionRef.current = isFooterFrameSelection;
21415
- const [floatingPanel, setFloatingPanel] = (0, import_react19.useState)(null);
21416
- const floatingPanelOpenRef = (0, import_react19.useRef)(false);
21417
- floatingPanelOpenRef.current = floatingPanel !== null;
21418
- const floatingPanelRef = (0, import_react19.useRef)(null);
21419
- floatingPanelRef.current = floatingPanel;
21420
- const [floatingPanelPos, setFloatingPanelPos] = (0, import_react19.useState)(null);
21421
- const buttonCollectionDragRef = (0, import_react19.useRef)(null);
21422
- const buttonDropInsertIndexRef = (0, import_react19.useRef)(null);
21423
- const [buttonDropSlots, setButtonDropSlots] = (0, import_react19.useState)([]);
21424
- const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react19.useState)(null);
21425
- const buttonPointerDragRef = (0, import_react19.useRef)(null);
21426
- const [buttonStyleTick, setButtonStyleTick] = (0, import_react19.useState)(0);
21427
- const [logoSizeDraft, setLogoSizeDraft] = (0, import_react19.useState)(null);
21428
- const [editorViewport, setEditorViewport] = (0, import_react19.useState)("desktop");
21429
- const [parentScrollSnap, setParentScrollSnap] = (0, import_react19.useState)(null);
21430
- const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react19.useState)(null);
21431
- const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react19.useState)(null);
21432
- const footerDragRef = (0, import_react19.useRef)(null);
21433
- const [footerDropSlots, setFooterDropSlots] = (0, import_react19.useState)([]);
21434
- const [activeFooterDropIndex, setActiveFooterDropIndex] = (0, import_react19.useState)(null);
21435
- const [draggedItemRect, setDraggedItemRect] = (0, import_react19.useState)(null);
21436
- const footerPointerDragRef = (0, import_react19.useRef)(null);
21437
- const suppressNextClickRef = (0, import_react19.useRef)(false);
21438
- const suppressClickUntilRef = (0, import_react19.useRef)(0);
21439
- const [linkPopover, setLinkPopover] = (0, import_react19.useState)(null);
21440
- const linkPopoverSessionRef = (0, import_react19.useRef)(null);
21441
- const addNavAfterAnchorRef = (0, import_react19.useRef)(null);
21442
- const editContentRef = (0, import_react19.useRef)({});
21443
- const aiSectionsRef = (0, import_react19.useRef)("");
21444
- const applyTreeLocalRef = (0, import_react19.useRef)(
22055
+ const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react20.useState)(null);
22056
+ const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react20.useState)(null);
22057
+ const footerDragRef = (0, import_react20.useRef)(null);
22058
+ const [footerDropSlots, setFooterDropSlots] = (0, import_react20.useState)([]);
22059
+ const [activeFooterDropIndex, setActiveFooterDropIndex] = (0, import_react20.useState)(null);
22060
+ const [draggedItemRect, setDraggedItemRect] = (0, import_react20.useState)(null);
22061
+ const footerPointerDragRef = (0, import_react20.useRef)(null);
22062
+ const suppressNextClickRef = (0, import_react20.useRef)(false);
22063
+ const suppressClickUntilRef = (0, import_react20.useRef)(0);
22064
+ const [linkPopover, setLinkPopover] = (0, import_react20.useState)(null);
22065
+ const linkPopoverSessionRef = (0, import_react20.useRef)(null);
22066
+ const addNavAfterAnchorRef = (0, import_react20.useRef)(null);
22067
+ const editContentRef = (0, import_react20.useRef)({});
22068
+ const aiSectionsRef = (0, import_react20.useRef)("");
22069
+ const applyTreeLocalRef = (0, import_react20.useRef)(
21445
22070
  null
21446
22071
  );
21447
- const clearInteractionChromeRef = (0, import_react19.useRef)(() => {
22072
+ const clearInteractionChromeRef = (0, import_react20.useRef)(() => {
21448
22073
  });
21449
- const brandKitRef = (0, import_react19.useRef)("");
21450
- const stylesRef = (0, import_react19.useRef)("");
21451
- const appliedDrawerRef = (0, import_react19.useRef)(null);
21452
- const pendingDeleteUndoRef = (0, import_react19.useRef)(null);
21453
- const [sitePages, setSitePages] = (0, import_react19.useState)([]);
21454
- const [sectionsByPath, setSectionsByPath] = (0, import_react19.useState)({});
21455
- const sectionsPrefetchGenRef = (0, import_react19.useRef)(0);
21456
- const setLinkPopoverRef = (0, import_react19.useRef)(setLinkPopover);
21457
- const linkPopoverPanelRef = (0, import_react19.useRef)(null);
21458
- const linkPopoverOpenRef = (0, import_react19.useRef)(false);
21459
- const linkPopoverGraceUntilRef = (0, import_react19.useRef)(0);
22074
+ const brandKitRef = (0, import_react20.useRef)("");
22075
+ const stylesRef = (0, import_react20.useRef)("");
22076
+ const appliedDrawerRef = (0, import_react20.useRef)(null);
22077
+ const pendingDeleteUndoRef = (0, import_react20.useRef)(null);
22078
+ const [floatingPanel, setFloatingPanel] = (0, import_react20.useState)(null);
22079
+ const floatingPanelOpenRef = (0, import_react20.useRef)(false);
22080
+ const floatingPanelRef = (0, import_react20.useRef)(null);
22081
+ floatingPanelRef.current = floatingPanel;
22082
+ const setFloatingPanelRef = (0, import_react20.useRef)(setFloatingPanel);
22083
+ const [floatingPanelPos, setFloatingPanelPos] = (0, import_react20.useState)(null);
22084
+ const buttonCollectionDragRef = (0, import_react20.useRef)(null);
22085
+ const buttonDropInsertIndexRef = (0, import_react20.useRef)(null);
22086
+ const [buttonDropSlots, setButtonDropSlots] = (0, import_react20.useState)([]);
22087
+ const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react20.useState)(null);
22088
+ const buttonPointerDragRef = (0, import_react20.useRef)(null);
22089
+ const [buttonStyleTick, setButtonStyleTick] = (0, import_react20.useState)(0);
22090
+ const [logoSizeDraft, setLogoSizeDraft] = (0, import_react20.useState)(null);
22091
+ const [editorViewport, setEditorViewport] = (0, import_react20.useState)("desktop");
22092
+ const [parentScrollSnap, setParentScrollSnap] = (0, import_react20.useState)(null);
22093
+ const [sitePages, setSitePages] = (0, import_react20.useState)([]);
22094
+ const [sectionsByPath, setSectionsByPath] = (0, import_react20.useState)({});
22095
+ const sectionsPrefetchGenRef = (0, import_react20.useRef)(0);
22096
+ const setLinkPopoverRef = (0, import_react20.useRef)(setLinkPopover);
22097
+ const linkPopoverPanelRef = (0, import_react20.useRef)(null);
22098
+ const linkPopoverOpenRef = (0, import_react20.useRef)(false);
22099
+ const linkPopoverGraceUntilRef = (0, import_react20.useRef)(0);
21460
22100
  setLinkPopoverRef.current = setLinkPopover;
22101
+ setFloatingPanelRef.current = setFloatingPanel;
21461
22102
  linkPopoverSessionRef.current = linkPopover;
21462
- (0, import_react19.useEffect)(() => {
22103
+ floatingPanelOpenRef.current = Boolean(floatingPanel);
22104
+ (0, import_react20.useEffect)(() => {
22105
+ const syncViewport = () => {
22106
+ const next = window.innerWidth <= 480 ? "mobile" : "desktop";
22107
+ setEditorViewport((prev) => prev === next ? prev : next);
22108
+ };
22109
+ syncViewport();
22110
+ window.addEventListener("resize", syncViewport);
22111
+ return () => window.removeEventListener("resize", syncViewport);
22112
+ }, []);
22113
+ (0, import_react20.useEffect)(() => {
21463
22114
  setSectionOrderPersistHandler((entries) => {
21464
22115
  const currentPath = window.location.pathname;
21465
22116
  const merged = mergePageSectionOrder(editContentRef.current[SECTION_ORDER_KEY], currentPath, entries);
@@ -21515,7 +22166,7 @@ function OhhwellsBridge() {
21515
22166
  const bumpLinkPopoverGrace = () => {
21516
22167
  linkPopoverGraceUntilRef.current = Date.now() + 350;
21517
22168
  };
21518
- const runSectionsPrefetch = (0, import_react19.useCallback)((pages) => {
22169
+ const runSectionsPrefetch = (0, import_react20.useCallback)((pages) => {
21519
22170
  if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
21520
22171
  const gen = ++sectionsPrefetchGenRef.current;
21521
22172
  const paths = pages.map((p) => p.path);
@@ -21534,9 +22185,9 @@ function OhhwellsBridge() {
21534
22185
  );
21535
22186
  });
21536
22187
  }, [isEditMode, pathname]);
21537
- const runSectionsPrefetchRef = (0, import_react19.useRef)(runSectionsPrefetch);
22188
+ const runSectionsPrefetchRef = (0, import_react20.useRef)(runSectionsPrefetch);
21538
22189
  runSectionsPrefetchRef.current = runSectionsPrefetch;
21539
- (0, import_react19.useEffect)(() => {
22190
+ (0, import_react20.useEffect)(() => {
21540
22191
  if (!linkPopover) {
21541
22192
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
21542
22193
  return;
@@ -21564,7 +22215,7 @@ function OhhwellsBridge() {
21564
22215
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
21565
22216
  };
21566
22217
  }, [linkPopover, postToParent2]);
21567
- (0, import_react19.useEffect)(() => {
22218
+ (0, import_react20.useEffect)(() => {
21568
22219
  if (!isEditMode) return;
21569
22220
  const useFixtures = shouldUseDevFixtures();
21570
22221
  if (useFixtures) {
@@ -21588,14 +22239,14 @@ function OhhwellsBridge() {
21588
22239
  if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
21589
22240
  return () => window.removeEventListener("message", onSitePages);
21590
22241
  }, [isEditMode, postToParent2]);
21591
- (0, import_react19.useEffect)(() => {
22242
+ (0, import_react20.useEffect)(() => {
21592
22243
  if (!isEditMode || shouldUseDevFixtures()) return;
21593
22244
  void loadAllSectionsManifest().then((manifest) => {
21594
22245
  if (Object.keys(manifest).length === 0) return;
21595
22246
  setSectionsByPath((prev) => ({ ...manifest, ...prev }));
21596
22247
  });
21597
22248
  }, [isEditMode]);
21598
- (0, import_react19.useEffect)(() => {
22249
+ (0, import_react20.useEffect)(() => {
21599
22250
  const update = () => {
21600
22251
  const el = activeElRef.current ?? selectedElRef.current;
21601
22252
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
@@ -21619,10 +22270,10 @@ function OhhwellsBridge() {
21619
22270
  vvp.removeEventListener("resize", update);
21620
22271
  };
21621
22272
  }, []);
21622
- const refreshStateRules = (0, import_react19.useCallback)(() => {
22273
+ const refreshStateRules = (0, import_react20.useCallback)(() => {
21623
22274
  editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
21624
22275
  }, []);
21625
- const processConfigRequest = (0, import_react19.useCallback)((insertAfterVal) => {
22276
+ const processConfigRequest = (0, import_react20.useCallback)((insertAfterVal) => {
21626
22277
  const tracker = getSectionsTracker();
21627
22278
  let entries = [];
21628
22279
  try {
@@ -21645,7 +22296,7 @@ function OhhwellsBridge() {
21645
22296
  }
21646
22297
  window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
21647
22298
  }, [isEditMode]);
21648
- const deactivate = (0, import_react19.useCallback)(() => {
22299
+ const deactivate = (0, import_react20.useCallback)(() => {
21649
22300
  const el = activeElRef.current;
21650
22301
  if (!el) return;
21651
22302
  const isFormBlock = el.dataset.ohwEditable === "form";
@@ -21696,12 +22347,12 @@ function OhhwellsBridge() {
21696
22347
  setToolbarShowEditLink(false);
21697
22348
  postToParent2({ type: "ow:exit-edit" });
21698
22349
  }, [postToParent2]);
21699
- const clearSelectedAttr = (0, import_react19.useCallback)(() => {
22350
+ const clearSelectedAttr = (0, import_react20.useCallback)(() => {
21700
22351
  document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
21701
22352
  el.removeAttribute("data-ohw-selected");
21702
22353
  });
21703
22354
  }, []);
21704
- const deselect = (0, import_react19.useCallback)(() => {
22355
+ const deselect = (0, import_react20.useCallback)(() => {
21705
22356
  const nestedGroup = selectedElRef.current?.closest("[data-ohw-nav-children]") != null ? selectedElRef.current.closest("[data-ohw-nav-group]") : null;
21706
22357
  clearSelectedAttr();
21707
22358
  selectedElRef.current = null;
@@ -21736,20 +22387,20 @@ function OhhwellsBridge() {
21736
22387
  setToolbarVariant("none");
21737
22388
  }
21738
22389
  }, [clearSelectedAttr]);
21739
- const markSelected = (0, import_react19.useCallback)((el) => {
22390
+ const markSelected = (0, import_react20.useCallback)((el) => {
21740
22391
  clearSelectedAttr();
21741
22392
  el.removeAttribute("data-ohw-hovered");
21742
22393
  el.setAttribute("data-ohw-selected", "");
21743
22394
  }, [clearSelectedAttr]);
21744
- const isSelectedForHover = (0, import_react19.useCallback)((el) => {
22395
+ const isSelectedForHover = (0, import_react20.useCallback)((el) => {
21745
22396
  if (!el) return false;
21746
22397
  return [selectedElRef.current, activeElRef.current].some(
21747
22398
  (busy) => busy && (el === busy || busy.contains(el) || el.contains(busy))
21748
22399
  );
21749
22400
  }, []);
21750
- const isSelectedForHoverRef = (0, import_react19.useRef)(isSelectedForHover);
22401
+ const isSelectedForHoverRef = (0, import_react20.useRef)(isSelectedForHover);
21751
22402
  isSelectedForHoverRef.current = isSelectedForHover;
21752
- const resolveHrefKeyElement = (0, import_react19.useCallback)((hrefKey) => {
22403
+ const resolveHrefKeyElement = (0, import_react20.useCallback)((hrefKey) => {
21753
22404
  if (isFooterHrefKey(hrefKey)) {
21754
22405
  return document.querySelector(
21755
22406
  `footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
@@ -21764,7 +22415,7 @@ function OhhwellsBridge() {
21764
22415
  `[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
21765
22416
  );
21766
22417
  }, []);
21767
- const resyncSelectedNavigationItem = (0, import_react19.useCallback)(() => {
22418
+ const resyncSelectedNavigationItem = (0, import_react20.useCallback)(() => {
21768
22419
  const hrefKey = selectedHrefKeyRef.current;
21769
22420
  if (hrefKey) {
21770
22421
  const link = resolveHrefKeyElement(hrefKey);
@@ -21802,7 +22453,7 @@ function OhhwellsBridge() {
21802
22453
  );
21803
22454
  }
21804
22455
  }, [resolveHrefKeyElement]);
21805
- const reselectNavigationItem = (0, import_react19.useCallback)((navAnchor) => {
22456
+ const reselectNavigationItem = (0, import_react20.useCallback)((navAnchor) => {
21806
22457
  selectedElRef.current = navAnchor;
21807
22458
  selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
21808
22459
  selectedFooterColAttrRef.current = null;
@@ -21833,7 +22484,7 @@ function OhhwellsBridge() {
21833
22484
  setToolbarShowEditLink(false);
21834
22485
  setActiveCommands(/* @__PURE__ */ new Set());
21835
22486
  }, [markSelected]);
21836
- const commitNavigationTextEdit = (0, import_react19.useCallback)((navAnchor) => {
22487
+ const commitNavigationTextEdit = (0, import_react20.useCallback)((navAnchor) => {
21837
22488
  const el = activeElRef.current;
21838
22489
  if (!el) return;
21839
22490
  const key = el.dataset.ohwKey;
@@ -21866,7 +22517,7 @@ function OhhwellsBridge() {
21866
22517
  postToParent2({ type: "ow:exit-edit" });
21867
22518
  reselectNavigationItem(navAnchor);
21868
22519
  }, [postToParent2, reselectNavigationItem]);
21869
- const handleAddTopLevelNavItem = (0, import_react19.useCallback)(() => {
22520
+ const handleAddTopLevelNavItem = (0, import_react20.useCallback)(() => {
21870
22521
  const items = listNavbarRootItems();
21871
22522
  addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
21872
22523
  deselectRef.current();
@@ -21878,7 +22529,7 @@ function OhhwellsBridge() {
21878
22529
  intent: "add-nav"
21879
22530
  });
21880
22531
  }, []);
21881
- const maybeWarnNavLinkDropdownConflict = (0, import_react19.useCallback)(
22532
+ const maybeWarnNavLinkDropdownConflict = (0, import_react20.useCallback)(
21882
22533
  (anchor) => {
21883
22534
  if (!isNavbarHrefKey(anchor.getAttribute("data-ohw-href-key"))) return;
21884
22535
  if (!navDropdownsOpenOnClick()) return;
@@ -21891,7 +22542,7 @@ function OhhwellsBridge() {
21891
22542
  },
21892
22543
  [postToParent2]
21893
22544
  );
21894
- const handleNavDropdownOpenChange = (0, import_react19.useCallback)((open) => {
22545
+ const handleNavDropdownOpenChange = (0, import_react20.useCallback)((open) => {
21895
22546
  const selected = selectedElRef.current;
21896
22547
  if (!selected || !isNavigationItem2(selected)) return;
21897
22548
  if (isNestedNavChild(selected)) return;
@@ -21907,7 +22558,7 @@ function OhhwellsBridge() {
21907
22558
  }
21908
22559
  });
21909
22560
  }, []);
21910
- const handleFooterHeadingVisibleChange = (0, import_react19.useCallback)(
22561
+ const handleFooterHeadingVisibleChange = (0, import_react20.useCallback)(
21911
22562
  (visible) => {
21912
22563
  const selected = selectedElRef.current;
21913
22564
  if (!selected || !isFooterFrameSelectionRef.current) return;
@@ -21931,7 +22582,7 @@ function OhhwellsBridge() {
21931
22582
  },
21932
22583
  [postToParent2]
21933
22584
  );
21934
- const enterEditOnNewItem = (0, import_react19.useCallback)((anchor) => {
22585
+ const enterEditOnNewItem = (0, import_react20.useCallback)((anchor) => {
21935
22586
  const label = anchor.querySelector('[data-ohw-editable="text"]');
21936
22587
  if (!label) {
21937
22588
  selectRef.current(anchor);
@@ -21940,8 +22591,8 @@ function OhhwellsBridge() {
21940
22591
  setNavGroupForceOpen(anchor, true);
21941
22592
  activateRef.current(label);
21942
22593
  }, []);
21943
- const pendingSocialAddRef = (0, import_react19.useRef)(null);
21944
- const handleAddChildItem = (0, import_react19.useCallback)(() => {
22594
+ const pendingSocialAddRef = (0, import_react20.useRef)(null);
22595
+ const handleAddChildItem = (0, import_react20.useCallback)(() => {
21945
22596
  const selected = selectedElRef.current;
21946
22597
  if (!selected) return;
21947
22598
  const socialsRow = isSocialsRow(selected) ? selected : findSocialsRow(selected);
@@ -22052,7 +22703,7 @@ function OhhwellsBridge() {
22052
22703
  });
22053
22704
  });
22054
22705
  }, [enterEditOnNewItem, isFooterFrameSelection, maybeWarnNavLinkDropdownConflict, postToParent2]);
22055
- const handleAddFooterColumn = (0, import_react19.useCallback)(() => {
22706
+ const handleAddFooterColumn = (0, import_react20.useCallback)(() => {
22056
22707
  if (!canAddFooterColumn()) {
22057
22708
  postToParent2({
22058
22709
  type: "ow:toast",
@@ -22073,7 +22724,7 @@ function OhhwellsBridge() {
22073
22724
  selectRef.current(result.firstLink);
22074
22725
  });
22075
22726
  }, [postToParent2]);
22076
- const clearFooterDragVisuals = (0, import_react19.useCallback)(() => {
22727
+ const clearFooterDragVisuals = (0, import_react20.useCallback)(() => {
22077
22728
  footerDragRef.current = null;
22078
22729
  setSiblingHintRects([]);
22079
22730
  setFooterDropSlots([]);
@@ -22082,7 +22733,7 @@ function OhhwellsBridge() {
22082
22733
  setIsItemDragging(false);
22083
22734
  unlockFooterDragInteraction();
22084
22735
  }, []);
22085
- const refreshFooterDragVisuals = (0, import_react19.useCallback)((session, activeSlot, clientX, clientY) => {
22736
+ const refreshFooterDragVisuals = (0, import_react20.useCallback)((session, activeSlot, clientX, clientY) => {
22086
22737
  const dragged = session.draggedEl;
22087
22738
  setDraggedItemRect(dragged.getBoundingClientRect());
22088
22739
  if (typeof clientX === "number" && typeof clientY === "number") {
@@ -22114,13 +22765,13 @@ function OhhwellsBridge() {
22114
22765
  const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
22115
22766
  setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
22116
22767
  }, []);
22117
- const refreshFooterDragVisualsRef = (0, import_react19.useRef)(refreshFooterDragVisuals);
22768
+ const refreshFooterDragVisualsRef = (0, import_react20.useRef)(refreshFooterDragVisuals);
22118
22769
  refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
22119
- const commitFooterDragRef = (0, import_react19.useRef)(() => {
22770
+ const commitFooterDragRef = (0, import_react20.useRef)(() => {
22120
22771
  });
22121
- const beginFooterDragRef = (0, import_react19.useRef)(() => {
22772
+ const beginFooterDragRef = (0, import_react20.useRef)(() => {
22122
22773
  });
22123
- const beginFooterDrag = (0, import_react19.useCallback)(
22774
+ const beginFooterDrag = (0, import_react20.useCallback)(
22124
22775
  (session) => {
22125
22776
  const rect = session.draggedEl.getBoundingClientRect();
22126
22777
  session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
@@ -22140,7 +22791,7 @@ function OhhwellsBridge() {
22140
22791
  [refreshFooterDragVisuals]
22141
22792
  );
22142
22793
  beginFooterDragRef.current = beginFooterDrag;
22143
- const commitFooterDrag = (0, import_react19.useCallback)(
22794
+ const commitFooterDrag = (0, import_react20.useCallback)(
22144
22795
  (clientX, clientY) => {
22145
22796
  const session = footerDragRef.current;
22146
22797
  if (!session) {
@@ -22269,7 +22920,7 @@ function OhhwellsBridge() {
22269
22920
  [clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
22270
22921
  );
22271
22922
  commitFooterDragRef.current = commitFooterDrag;
22272
- const startFooterLinkDrag = (0, import_react19.useCallback)(
22923
+ const startFooterLinkDrag = (0, import_react20.useCallback)(
22273
22924
  (anchor, clientX, clientY, wasSelected) => {
22274
22925
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
22275
22926
  if (!hrefKey) return false;
@@ -22305,7 +22956,7 @@ function OhhwellsBridge() {
22305
22956
  },
22306
22957
  [beginFooterDrag]
22307
22958
  );
22308
- const startFooterColumnDrag = (0, import_react19.useCallback)(
22959
+ const startFooterColumnDrag = (0, import_react20.useCallback)(
22309
22960
  (columnEl, clientX, clientY, wasSelected) => {
22310
22961
  const columns = listFooterColumns();
22311
22962
  const idx = columns.indexOf(columnEl);
@@ -22325,7 +22976,7 @@ function OhhwellsBridge() {
22325
22976
  },
22326
22977
  [beginFooterDrag]
22327
22978
  );
22328
- const persistButtonCollectionDrag = (0, import_react19.useCallback)(
22979
+ const persistButtonCollectionDrag = (0, import_react20.useCallback)(
22329
22980
  (button, clientX) => {
22330
22981
  const insertIndex = buttonDropInsertIndexRef.current;
22331
22982
  if (insertIndex != null) insertButtonAtCollectionIndex(button, insertIndex);
@@ -22349,7 +23000,7 @@ function OhhwellsBridge() {
22349
23000
  },
22350
23001
  [postToParent2]
22351
23002
  );
22352
- const refreshButtonDragVisuals = (0, import_react19.useCallback)((button, clientX, clientY) => {
23003
+ const refreshButtonDragVisuals = (0, import_react20.useCallback)((button, clientX, clientY) => {
22353
23004
  const collection = buttonCollectionOf(button);
22354
23005
  if (!collection) {
22355
23006
  setButtonDropSlots([]);
@@ -22366,7 +23017,7 @@ function OhhwellsBridge() {
22366
23017
  setDraggedItemRect(button.getBoundingClientRect());
22367
23018
  if (selectedElRef.current === button) setToolbarRect(button.getBoundingClientRect());
22368
23019
  }, []);
22369
- const handleItemDragStart = (0, import_react19.useCallback)(
23020
+ const handleItemDragStart = (0, import_react20.useCallback)(
22370
23021
  (e) => {
22371
23022
  const selected = selectedElRef.current;
22372
23023
  if (!selected) {
@@ -22397,7 +23048,7 @@ function OhhwellsBridge() {
22397
23048
  },
22398
23049
  [startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag, refreshButtonDragVisuals]
22399
23050
  );
22400
- const handleItemDragEnd = (0, import_react19.useCallback)(
23051
+ const handleItemDragEnd = (0, import_react20.useCallback)(
22401
23052
  (e) => {
22402
23053
  const collectionButton = buttonCollectionDragRef.current;
22403
23054
  if (collectionButton) {
@@ -22428,7 +23079,7 @@ function OhhwellsBridge() {
22428
23079
  },
22429
23080
  [commitFooterDrag, commitNavDrag, navDragRef, persistButtonCollectionDrag]
22430
23081
  );
22431
- const handleItemChromePointerDown = (0, import_react19.useCallback)((e) => {
23082
+ const handleItemChromePointerDown = (0, import_react20.useCallback)((e) => {
22432
23083
  if (e.button !== 0) return;
22433
23084
  const selected = selectedElRef.current;
22434
23085
  if (!selected) return;
@@ -22469,7 +23120,7 @@ function OhhwellsBridge() {
22469
23120
  }
22470
23121
  if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
22471
23122
  }, [armNavPressFromChrome]);
22472
- const handleItemChromeClick = (0, import_react19.useCallback)((clientX, clientY) => {
23123
+ const handleItemChromeClick = (0, import_react20.useCallback)((clientX, clientY) => {
22473
23124
  if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
22474
23125
  suppressNextClickRef.current = false;
22475
23126
  return;
@@ -22482,7 +23133,7 @@ function OhhwellsBridge() {
22482
23133
  }, []);
22483
23134
  reselectNavigationItemRef.current = reselectNavigationItem;
22484
23135
  commitNavigationTextEditRef.current = commitNavigationTextEdit;
22485
- const select = (0, import_react19.useCallback)((anchor) => {
23136
+ const select = (0, import_react20.useCallback)((anchor) => {
22486
23137
  if (!isNavigationItem2(anchor)) return;
22487
23138
  if (activeElRef.current) deactivate();
22488
23139
  aiSectionApiRef.current?.selectFromElement(anchor);
@@ -22544,7 +23195,7 @@ function OhhwellsBridge() {
22544
23195
  setLogoSizeDraft(null);
22545
23196
  }
22546
23197
  }, [deactivate, markSelected]);
22547
- const selectFrame = (0, import_react19.useCallback)((el) => {
23198
+ const selectFrame = (0, import_react20.useCallback)((el) => {
22548
23199
  if (!isNavigationContainer(el)) return;
22549
23200
  if (activeElRef.current) deactivate();
22550
23201
  aiSectionApiRef.current?.selectFromElement(el);
@@ -22585,7 +23236,7 @@ function OhhwellsBridge() {
22585
23236
  setFloatingPanelPos(null);
22586
23237
  setLogoSizeDraft(null);
22587
23238
  }, [deactivate, markSelected, postToParent2]);
22588
- const selectLogo = (0, import_react19.useCallback)(
23239
+ const selectLogo = (0, import_react20.useCallback)(
22589
23240
  (logoEl) => {
22590
23241
  if (activeElRef.current) deactivate();
22591
23242
  selectedElRef.current = logoEl;
@@ -22614,7 +23265,7 @@ function OhhwellsBridge() {
22614
23265
  },
22615
23266
  [deactivate, markSelected]
22616
23267
  );
22617
- const openLogoSizePanel = (0, import_react19.useCallback)((logoEl) => {
23268
+ const openLogoSizePanel = (0, import_react20.useCallback)((logoEl) => {
22618
23269
  const placement = getLogoPlacement(logoEl);
22619
23270
  const draft = readLogoSizeState(editContentRef.current, placement);
22620
23271
  setLogoSizeDraft(draft);
@@ -22627,7 +23278,7 @@ function OhhwellsBridge() {
22627
23278
  placement
22628
23279
  });
22629
23280
  }, []);
22630
- const openSocialsDisplayPanel = (0, import_react19.useCallback)((row) => {
23281
+ const openSocialsDisplayPanel = (0, import_react20.useCallback)((row) => {
22631
23282
  setFloatingPanelPos(null);
22632
23283
  setParentScrollSnap(parentScrollRef.current);
22633
23284
  setFloatingPanel({
@@ -22638,7 +23289,7 @@ function OhhwellsBridge() {
22638
23289
  row
22639
23290
  });
22640
23291
  }, []);
22641
- const rememberButtonTokens = (0, import_react19.useCallback)(
23292
+ const rememberButtonTokens = (0, import_react20.useCallback)(
22642
23293
  (content, tokens, nodes) => {
22643
23294
  if (nodes.length === 0) return content;
22644
23295
  const next = { ...content };
@@ -22649,7 +23300,7 @@ function OhhwellsBridge() {
22649
23300
  },
22650
23301
  [postToParent2]
22651
23302
  );
22652
- const tokensForButton = (0, import_react19.useCallback)(
23303
+ const tokensForButton = (0, import_react20.useCallback)(
22653
23304
  (el, persistFallback = false) => {
22654
23305
  const stored = readStoredStyleTokens(editContentRef.current);
22655
23306
  if (stored) return stored;
@@ -22664,7 +23315,7 @@ function OhhwellsBridge() {
22664
23315
  },
22665
23316
  [rememberButtonTokens]
22666
23317
  );
22667
- const openButtonStylePanel = (0, import_react19.useCallback)(
23318
+ const openButtonStylePanel = (0, import_react20.useCallback)(
22668
23319
  (anchor) => {
22669
23320
  const id = buttonId(anchor);
22670
23321
  if (!id) return;
@@ -22682,7 +23333,7 @@ function OhhwellsBridge() {
22682
23333
  },
22683
23334
  [tokensForButton]
22684
23335
  );
22685
- const applySelectedButtonStyle = (0, import_react19.useCallback)(
23336
+ const applySelectedButtonStyle = (0, import_react20.useCallback)(
22686
23337
  (patch) => {
22687
23338
  const panel = floatingPanelRef.current;
22688
23339
  const id = panel?.kind === "button-style" ? panel.buttonId : null;
@@ -22700,7 +23351,7 @@ function OhhwellsBridge() {
22700
23351
  },
22701
23352
  [postToParent2]
22702
23353
  );
22703
- (0, import_react19.useEffect)(() => {
23354
+ (0, import_react20.useEffect)(() => {
22704
23355
  const onDragOver = (e) => {
22705
23356
  const dragged = buttonCollectionDragRef.current;
22706
23357
  if (!dragged) return;
@@ -22719,11 +23370,11 @@ function OhhwellsBridge() {
22719
23370
  document.removeEventListener("drop", onDrop);
22720
23371
  };
22721
23372
  }, [refreshButtonDragVisuals]);
22722
- const isEditModeRef = (0, import_react19.useRef)(false);
22723
- const requestMissingSocialIconsRef = (0, import_react19.useRef)(() => {
23373
+ const isEditModeRef = (0, import_react20.useRef)(false);
23374
+ const requestMissingSocialIconsRef = (0, import_react20.useRef)(() => {
22724
23375
  });
22725
- const askedSocialIconsRef = (0, import_react19.useRef)(/* @__PURE__ */ new Set());
22726
- const requestMissingSocialIcons = (0, import_react19.useCallback)(() => {
23376
+ const askedSocialIconsRef = (0, import_react20.useRef)(/* @__PURE__ */ new Set());
23377
+ const requestMissingSocialIcons = (0, import_react20.useCallback)(() => {
22727
23378
  const items = Array.from(document.querySelectorAll(`[${SOCIALS_ROW_ATTR}]`)).filter((row) => socialsDisplayFor(row, editContentRef.current).icon).flatMap((row) => {
22728
23379
  const missing = socialsMissingIcons(row);
22729
23380
  listSocialItems(row).forEach((item) => ensureIconSlot(item));
@@ -22735,7 +23386,7 @@ function OhhwellsBridge() {
22735
23386
  }, []);
22736
23387
  requestMissingSocialIconsRef.current = requestMissingSocialIcons;
22737
23388
  isEditModeRef.current = isEditMode;
22738
- const changeSocialsDisplay = (0, import_react19.useCallback)(
23389
+ const changeSocialsDisplay = (0, import_react20.useCallback)(
22739
23390
  (row, next) => {
22740
23391
  if (next.icon) {
22741
23392
  const missing = socialsMissingIcons(row);
@@ -22759,19 +23410,19 @@ function OhhwellsBridge() {
22759
23410
  },
22760
23411
  []
22761
23412
  );
22762
- const closeFloatingPanelOnly = (0, import_react19.useCallback)(() => {
23413
+ const closeFloatingPanelOnly = (0, import_react20.useCallback)(() => {
22763
23414
  setFloatingPanel(null);
22764
23415
  setFloatingPanelPos(null);
22765
23416
  setLogoSizeDraft(null);
22766
23417
  }, []);
22767
23418
  closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
22768
- const closeFloatingPanelAndDeselect = (0, import_react19.useCallback)(() => {
23419
+ const closeFloatingPanelAndDeselect = (0, import_react20.useCallback)(() => {
22769
23420
  setFloatingPanel(null);
22770
23421
  setFloatingPanelPos(null);
22771
23422
  setLogoSizeDraft(null);
22772
23423
  deselectRef.current();
22773
23424
  }, []);
22774
- (0, import_react19.useEffect)(() => {
23425
+ (0, import_react20.useEffect)(() => {
22775
23426
  const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
22776
23427
  if (!session || !logoSizeDraft) {
22777
23428
  postToParentRef.current({ type: "ow:logo-size-panel", open: false });
@@ -22790,7 +23441,7 @@ function OhhwellsBridge() {
22790
23441
  max: LOGO_SIZE_MAX
22791
23442
  });
22792
23443
  }, [floatingPanel, logoSizeDraft, editorViewport]);
22793
- const persistLogoSizeDraft = (0, import_react19.useCallback)(
23444
+ const persistLogoSizeDraft = (0, import_react20.useCallback)(
22794
23445
  (placement, draft) => {
22795
23446
  const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
22796
23447
  const mobileKey = LOGO_SIZE_MOBILE_KEYS[placement];
@@ -22830,7 +23481,7 @@ function OhhwellsBridge() {
22830
23481
  },
22831
23482
  [postToParent2]
22832
23483
  );
22833
- const activate = (0, import_react19.useCallback)((el, options) => {
23484
+ const activate = (0, import_react20.useCallback)((el, options) => {
22834
23485
  if (activeElRef.current === el) return;
22835
23486
  document.querySelectorAll("[data-ohw-hovered]").forEach((hovered) => {
22836
23487
  hovered.removeAttribute("data-ohw-hovered");
@@ -22928,8 +23579,8 @@ function OhhwellsBridge() {
22928
23579
  openLogoSizePanelRef.current = openLogoSizePanel;
22929
23580
  deselectRef.current = deselect;
22930
23581
  closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
22931
- const lastSiteWideScopeRef = (0, import_react19.useRef)(null);
22932
- (0, import_react19.useEffect)(() => {
23582
+ const lastSiteWideScopeRef = (0, import_react20.useRef)(null);
23583
+ (0, import_react20.useEffect)(() => {
22933
23584
  if (!isEditMode) {
22934
23585
  if (lastSiteWideScopeRef.current !== false) {
22935
23586
  lastSiteWideScopeRef.current = false;
@@ -22955,7 +23606,7 @@ function OhhwellsBridge() {
22955
23606
  isFooterFrameSelection,
22956
23607
  postToParent2
22957
23608
  ]);
22958
- (0, import_react19.useLayoutEffect)(() => {
23609
+ (0, import_react20.useLayoutEffect)(() => {
22959
23610
  if (!subdomain || isEditMode) {
22960
23611
  setFetchState("done");
22961
23612
  return;
@@ -22976,6 +23627,7 @@ function OhhwellsBridge() {
22976
23627
  }
22977
23628
  if (typeof content[STYLE_STORE_KEY] === "string") {
22978
23629
  stylesRef.current = content[STYLE_STORE_KEY];
23630
+ document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
22979
23631
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
22980
23632
  }
22981
23633
  applyBrandChrome(content);
@@ -22984,12 +23636,12 @@ function OhhwellsBridge() {
22984
23636
  for (const [key, val] of Object.entries(content)) {
22985
23637
  if (key === "__ohw_sections") continue;
22986
23638
  if (key === AI_SECTIONS_KEY) continue;
23639
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
23640
+ if (LOGO_IMAGE_KEYS.includes(key)) continue;
22987
23641
  if (key === BRAND_KIT_KEY) continue;
22988
23642
  if (key === STYLE_STORE_KEY) continue;
22989
23643
  if (BRAND_CHROME_KEYS.has(key)) continue;
22990
- if (key === LOGO_PLACEHOLDER_KEY) continue;
22991
23644
  if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
22992
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
22993
23645
  if (applyVideoSettingNode(key, val)) continue;
22994
23646
  if (applyCarouselNode(key, val)) continue;
22995
23647
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -23061,7 +23713,9 @@ function OhhwellsBridge() {
23061
23713
  let cancelled = false;
23062
23714
  setFetchState("loading");
23063
23715
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
23064
- fetch(`${apiUrl}/api/public/sites/${subdomain}/content`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
23716
+ const initialPath = pathname;
23717
+ fetchedContentPaths.add(`${subdomain}::${initialPath}`);
23718
+ fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
23065
23719
  if (cancelled) return;
23066
23720
  const content = data?.content ?? {};
23067
23721
  const branding = Boolean(data?.showBranding);
@@ -23077,7 +23731,7 @@ function OhhwellsBridge() {
23077
23731
  cancelled = true;
23078
23732
  };
23079
23733
  }, [subdomain, isEditMode]);
23080
- (0, import_react19.useEffect)(() => {
23734
+ (0, import_react20.useEffect)(() => {
23081
23735
  if (!isEditMode) return;
23082
23736
  const resolveIndex = (form, clientY) => {
23083
23737
  const wrappers = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== fieldDragRef.current?.key);
@@ -23118,7 +23772,7 @@ function OhhwellsBridge() {
23118
23772
  window.removeEventListener("drop", onDrop, true);
23119
23773
  };
23120
23774
  }, [buildFieldDropSlots, isEditMode, persistFields, selectField]);
23121
- (0, import_react19.useEffect)(() => {
23775
+ (0, import_react20.useEffect)(() => {
23122
23776
  if (!isEditMode) return;
23123
23777
  const mark = () => document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
23124
23778
  markFormFields(form);
@@ -23130,7 +23784,7 @@ function OhhwellsBridge() {
23130
23784
  });
23131
23785
  return () => observer.disconnect();
23132
23786
  }, [isEditMode, fetchState, pathname]);
23133
- (0, import_react19.useEffect)(() => {
23787
+ (0, import_react20.useEffect)(() => {
23134
23788
  if (!isEditMode) return;
23135
23789
  let saveTimer = null;
23136
23790
  const onInput = (e) => {
@@ -23152,14 +23806,14 @@ function OhhwellsBridge() {
23152
23806
  document.addEventListener("input", onInput, true);
23153
23807
  return () => document.removeEventListener("input", onInput, true);
23154
23808
  }, [isEditMode, persistFields]);
23155
- (0, import_react19.useEffect)(() => {
23809
+ (0, import_react20.useEffect)(() => {
23156
23810
  if (isEditMode || fetchState !== "done") return;
23157
23811
  const content = contentCache.get(subdomain) ?? {};
23158
23812
  document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
23159
23813
  reconcileFieldsFromContent(form, content);
23160
23814
  });
23161
23815
  }, [isEditMode, fetchState, subdomain]);
23162
- (0, import_react19.useEffect)(() => {
23816
+ (0, import_react20.useEffect)(() => {
23163
23817
  if (!isEditMode) return;
23164
23818
  const swallow = (e) => {
23165
23819
  const target = e.target;
@@ -23168,14 +23822,14 @@ function OhhwellsBridge() {
23168
23822
  document.addEventListener("submit", swallow, true);
23169
23823
  return () => document.removeEventListener("submit", swallow, true);
23170
23824
  }, [isEditMode]);
23171
- (0, import_react19.useEffect)(() => {
23825
+ (0, import_react20.useEffect)(() => {
23172
23826
  if (isEditMode || fetchState !== "done") return;
23173
23827
  console.log("env", process.env.NEXT_PUBLIC_FLOWOPS_API_URL);
23174
23828
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
23175
23829
  console.log({ apiUrl, subdomain });
23176
23830
  bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
23177
23831
  }, [isEditMode, fetchState, subdomain]);
23178
- (0, import_react19.useEffect)(() => {
23832
+ (0, import_react20.useEffect)(() => {
23179
23833
  if (!subdomain || isEditMode) return;
23180
23834
  let debounceTimer = null;
23181
23835
  let observer = null;
@@ -23197,16 +23851,17 @@ function OhhwellsBridge() {
23197
23851
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
23198
23852
  }
23199
23853
  if (typeof content[STYLE_STORE_KEY] === "string") {
23854
+ document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
23200
23855
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
23201
23856
  }
23202
23857
  for (const [key, val] of Object.entries(content)) {
23203
23858
  if (key === "__ohw_sections") continue;
23204
23859
  if (key === AI_SECTIONS_KEY) continue;
23860
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
23861
+ if (LOGO_IMAGE_KEYS.includes(key)) continue;
23205
23862
  if (key === BRAND_KIT_KEY) continue;
23206
23863
  if (key === STYLE_STORE_KEY) continue;
23207
23864
  if (BRAND_CHROME_KEYS.has(key)) continue;
23208
- if (key === LOGO_PLACEHOLDER_KEY) continue;
23209
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
23210
23865
  if (applyVideoSettingNode(key, val)) continue;
23211
23866
  if (applyCarouselNode(key, val)) continue;
23212
23867
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -23258,6 +23913,17 @@ function OhhwellsBridge() {
23258
23913
  debounceTimer = setTimeout(applyFromCache, 150);
23259
23914
  };
23260
23915
  applyFromCache();
23916
+ const pathCacheKey = `${subdomain}::${pathname}`;
23917
+ if (!fetchedContentPaths.has(pathCacheKey)) {
23918
+ fetchedContentPaths.add(pathCacheKey);
23919
+ const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
23920
+ fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
23921
+ if (!data?.content) return;
23922
+ contentCache.set(subdomain, data.content);
23923
+ applyFromCache();
23924
+ }).catch(() => {
23925
+ });
23926
+ }
23261
23927
  observer = new MutationObserver(scheduleApply);
23262
23928
  observer.observe(document.body, { childList: true, subtree: true });
23263
23929
  return () => {
@@ -23265,16 +23931,16 @@ function OhhwellsBridge() {
23265
23931
  if (debounceTimer) clearTimeout(debounceTimer);
23266
23932
  };
23267
23933
  }, [subdomain, isEditMode, pathname]);
23268
- (0, import_react19.useLayoutEffect)(() => {
23934
+ (0, import_react20.useLayoutEffect)(() => {
23269
23935
  const el = document.getElementById("ohw-loader");
23270
23936
  if (!el) return;
23271
23937
  const visible = Boolean(subdomain) && fetchState !== "done";
23272
23938
  el.style.display = visible ? "flex" : "none";
23273
23939
  }, [subdomain, fetchState]);
23274
- (0, import_react19.useEffect)(() => {
23940
+ (0, import_react20.useEffect)(() => {
23275
23941
  postToParent2({ type: "ow:navigation", path: pathname });
23276
23942
  }, [pathname, postToParent2]);
23277
- (0, import_react19.useEffect)(() => {
23943
+ (0, import_react20.useEffect)(() => {
23278
23944
  if (!subdomain || isEditMode) return;
23279
23945
  const content = contentCache.get(subdomain);
23280
23946
  if (!content) return;
@@ -23290,7 +23956,7 @@ function OhhwellsBridge() {
23290
23956
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
23291
23957
  }
23292
23958
  }, [pathname, subdomain, isEditMode]);
23293
- (0, import_react19.useEffect)(() => {
23959
+ (0, import_react20.useEffect)(() => {
23294
23960
  if (!isEditMode) return;
23295
23961
  if (linkPopoverSessionRef.current?.intent === "add-nav") return;
23296
23962
  if (document.querySelector("[data-ohw-section-picker]")) return;
@@ -23298,11 +23964,11 @@ function OhhwellsBridge() {
23298
23964
  deselectRef.current();
23299
23965
  deactivateRef.current();
23300
23966
  }, [pathname, isEditMode]);
23301
- (0, import_react19.useEffect)(() => {
23967
+ (0, import_react20.useEffect)(() => {
23302
23968
  if (!isEditMode) return;
23303
23969
  initSectionInstancesFromContent(editContentRef.current, pathname);
23304
23970
  }, [pathname, isEditMode]);
23305
- (0, import_react19.useEffect)(() => {
23971
+ (0, import_react20.useEffect)(() => {
23306
23972
  if (!isEditMode) return;
23307
23973
  const observer = new MutationObserver(() => {
23308
23974
  const drawer = document.querySelector("[data-ohw-nav-drawer]");
@@ -23313,7 +23979,7 @@ function OhhwellsBridge() {
23313
23979
  observer.observe(document.body, { childList: true, subtree: true });
23314
23980
  return () => observer.disconnect();
23315
23981
  }, [isEditMode, pathname]);
23316
- (0, import_react19.useEffect)(() => {
23982
+ (0, import_react20.useEffect)(() => {
23317
23983
  const contentForNav = () => {
23318
23984
  if (isEditMode) return editContentRef.current;
23319
23985
  if (!subdomain) return {};
@@ -23386,7 +24052,7 @@ function OhhwellsBridge() {
23386
24052
  observer?.disconnect();
23387
24053
  };
23388
24054
  }, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
23389
- (0, import_react19.useEffect)(() => {
24055
+ (0, import_react20.useEffect)(() => {
23390
24056
  if (!isEditMode) return;
23391
24057
  let applying = false;
23392
24058
  let rafId = null;
@@ -23424,7 +24090,7 @@ function OhhwellsBridge() {
23424
24090
  observer.disconnect();
23425
24091
  };
23426
24092
  }, [isEditMode, pathname]);
23427
- (0, import_react19.useEffect)(() => {
24093
+ (0, import_react20.useEffect)(() => {
23428
24094
  if (!isEditMode) return;
23429
24095
  let lastPosted = 0;
23430
24096
  const measure = () => {
@@ -23446,29 +24112,14 @@ function OhhwellsBridge() {
23446
24112
  const t2 = setTimeout(measure, 500);
23447
24113
  const ro = new ResizeObserver(schedule);
23448
24114
  ro.observe(document.body);
23449
- let lastWidth = window.innerWidth;
23450
- let resizeTimers = [];
23451
- const clearResizeTimers = () => {
23452
- resizeTimers.forEach(clearTimeout);
23453
- resizeTimers = [];
23454
- };
23455
- const handleResize = () => {
23456
- if (window.innerWidth === lastWidth) return;
23457
- lastWidth = window.innerWidth;
23458
- clearResizeTimers();
23459
- resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
23460
- };
23461
- window.addEventListener("resize", handleResize);
23462
24115
  return () => {
23463
24116
  clearTimeout(t1);
23464
24117
  clearTimeout(t2);
23465
24118
  if (raf != null) cancelAnimationFrame(raf);
23466
24119
  ro.disconnect();
23467
- clearResizeTimers();
23468
- window.removeEventListener("resize", handleResize);
23469
24120
  };
23470
24121
  }, [pathname, isEditMode, postToParent2]);
23471
- (0, import_react19.useEffect)(() => {
24122
+ (0, import_react20.useEffect)(() => {
23472
24123
  if (!subdomainFromQuery || isEditMode) return;
23473
24124
  const handleClick = (e) => {
23474
24125
  const anchor = e.target.closest("a");
@@ -23484,7 +24135,7 @@ function OhhwellsBridge() {
23484
24135
  document.addEventListener("click", handleClick, true);
23485
24136
  return () => document.removeEventListener("click", handleClick, true);
23486
24137
  }, [subdomainFromQuery, isEditMode, router]);
23487
- (0, import_react19.useEffect)(() => {
24138
+ (0, import_react20.useEffect)(() => {
23488
24139
  if (!isEditMode) {
23489
24140
  editStylesRef.current?.base.remove();
23490
24141
  editStylesRef.current?.forceHover.remove();
@@ -23710,11 +24361,11 @@ function OhhwellsBridge() {
23710
24361
  footer [data-ohw-href-key] [data-ohw-editable][contenteditable],
23711
24362
  footer [data-ohw-href-key] [data-ohw-editable][contenteditable] * {
23712
24363
  outline: none !important;
23713
- caret-color: ${PRIMARY5} !important;
24364
+ caret-color: ${PRIMARY6} !important;
23714
24365
  cursor: text !important;
23715
24366
  }
23716
24367
  [data-ohw-editable][contenteditable]::selection,
23717
- [data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY5}59 !important; }
24368
+ [data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY6}59 !important; }
23718
24369
  [data-ohw-editable-state], [data-ohw-editable-state] * { pointer-events: none !important; }
23719
24370
  [data-ohw-editable-state][data-ohw-active-state] [data-ohw-editable] { pointer-events: auto !important; }
23720
24371
  [data-ohw-editable-state][data-ohw-active-state][data-ohw-editable] { pointer-events: auto !important; }
@@ -23760,6 +24411,13 @@ function OhhwellsBridge() {
23760
24411
  if (target.closest("[data-ohw-state-toggle]")) return;
23761
24412
  if (target.closest("[data-ohw-max-badge]")) return;
23762
24413
  if (isInsideLinkEditor(target)) return;
24414
+ if (isInsideFloatingPanel(target)) return;
24415
+ if (target.closest("[data-ohw-form-toolbar]")) return;
24416
+ if (target.closest(
24417
+ '[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
24418
+ )) {
24419
+ return;
24420
+ }
23763
24421
  if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
23764
24422
  clearMediaSelectionRef.current();
23765
24423
  }
@@ -23780,13 +24438,6 @@ function OhhwellsBridge() {
23780
24438
  return;
23781
24439
  }
23782
24440
  }
23783
- if (isInsideFloatingPanel(target)) return;
23784
- if (target.closest("[data-ohw-form-toolbar]")) return;
23785
- if (target.closest(
23786
- '[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
23787
- )) {
23788
- return;
23789
- }
23790
24441
  {
23791
24442
  const formEl = getFormElement(target);
23792
24443
  const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
@@ -24166,6 +24817,9 @@ function OhhwellsBridge() {
24166
24817
  setHoveredItemRect(null);
24167
24818
  hoveredNavContainerRef.current = null;
24168
24819
  setHoveredNavContainerRect(null);
24820
+ siblingHintElRef.current = null;
24821
+ setSiblingHintRect(null);
24822
+ setSiblingHintRects([]);
24169
24823
  return;
24170
24824
  }
24171
24825
  {
@@ -24286,7 +24940,6 @@ function OhhwellsBridge() {
24286
24940
  hoveredNavContainerRef.current = null;
24287
24941
  setHoveredNavContainerRect(null);
24288
24942
  hoveredItemElRef.current = editable;
24289
- setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
24290
24943
  }
24291
24944
  }
24292
24945
  }
@@ -24996,7 +25649,11 @@ function OhhwellsBridge() {
24996
25649
  };
24997
25650
  const handleMouseMove = (e) => {
24998
25651
  const { clientX, clientY } = e;
24999
- if (pointOwnedByFloatingPanel(clientX, clientY)) return;
25652
+ if (pointOwnedByFloatingPanel(clientX, clientY)) {
25653
+ dismissImageHover();
25654
+ clearImageHover();
25655
+ return;
25656
+ }
25000
25657
  if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
25001
25658
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
25002
25659
  formHoverElRef.current = null;
@@ -25025,7 +25682,12 @@ function OhhwellsBridge() {
25025
25682
  setHoveredItemRect(null);
25026
25683
  hoveredNavContainerRef.current = null;
25027
25684
  setHoveredNavContainerRect(null);
25685
+ siblingHintElRef.current = null;
25686
+ setSiblingHintRect(null);
25687
+ setSiblingHintRects([]);
25028
25688
  dismissImageHover();
25689
+ clearImageHover();
25690
+ setSectionGap(null);
25029
25691
  return;
25030
25692
  }
25031
25693
  if (probeSocialsRowAt(clientX, clientY)) return;
@@ -25037,7 +25699,11 @@ function OhhwellsBridge() {
25037
25699
  if (e.data?.type !== "ow:pointer-sync") return;
25038
25700
  const { clientX, clientY } = e.data;
25039
25701
  if (typeof clientX !== "number" || typeof clientY !== "number") return;
25040
- if (pointOwnedByFloatingPanel(clientX, clientY)) return;
25702
+ if (pointOwnedByFloatingPanel(clientX, clientY)) {
25703
+ dismissImageHover();
25704
+ clearImageHover();
25705
+ return;
25706
+ }
25041
25707
  if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
25042
25708
  if (probeSocialsRowAt(clientX, clientY)) return;
25043
25709
  probeSectionGapAt(clientX, clientY);
@@ -25383,6 +26049,7 @@ function OhhwellsBridge() {
25383
26049
  }
25384
26050
  if (typeof content[STYLE_STORE_KEY] === "string") {
25385
26051
  stylesRef.current = content[STYLE_STORE_KEY];
26052
+ document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
25386
26053
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
25387
26054
  }
25388
26055
  applyBrandChrome(content);
@@ -25395,12 +26062,12 @@ function OhhwellsBridge() {
25395
26062
  continue;
25396
26063
  }
25397
26064
  if (key === AI_SECTIONS_KEY) continue;
26065
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
26066
+ if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
25398
26067
  if (key === BRAND_KIT_KEY) continue;
25399
26068
  if (key === STYLE_STORE_KEY) continue;
25400
26069
  if (BRAND_CHROME_KEYS.has(key)) continue;
25401
- if (key === LOGO_PLACEHOLDER_KEY) continue;
25402
26070
  if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
25403
- if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
25404
26071
  if (applyVideoSettingNode(key, val)) continue;
25405
26072
  if (applyCarouselNode(key, val)) continue;
25406
26073
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -25846,6 +26513,12 @@ function OhhwellsBridge() {
25846
26513
  closeLinkPopoverRef.current();
25847
26514
  return;
25848
26515
  }
26516
+ if (floatingPanelOpenRef.current) {
26517
+ setFloatingPanelRef.current(null);
26518
+ deselectRef.current();
26519
+ deactivateRef.current();
26520
+ return;
26521
+ }
25849
26522
  deselectRef.current();
25850
26523
  deactivateRef.current();
25851
26524
  clearMediaSelectionRef.current();
@@ -26122,6 +26795,21 @@ function OhhwellsBridge() {
26122
26795
  type: "text",
26123
26796
  text: editContentRef.current[CUSTOM_CODE_AFTER_HEAD_KEY] ?? ""
26124
26797
  });
26798
+ nodes.push({
26799
+ key: BRAND_TITLE_KEY,
26800
+ type: "text",
26801
+ text: editContentRef.current[BRAND_TITLE_KEY] ?? ""
26802
+ });
26803
+ nodes.push({
26804
+ key: SITE_DESCRIPTION_KEY,
26805
+ type: "text",
26806
+ text: editContentRef.current[SITE_DESCRIPTION_KEY] ?? ""
26807
+ });
26808
+ nodes.push({
26809
+ key: SITE_OG_IMAGE_KEY,
26810
+ type: "text",
26811
+ text: editContentRef.current[SITE_OG_IMAGE_KEY] ?? ""
26812
+ });
26125
26813
  document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
26126
26814
  const formKey = formKeyOf(form);
26127
26815
  if (!formKey) return;
@@ -26144,8 +26832,12 @@ function OhhwellsBridge() {
26144
26832
  if (inserted) {
26145
26833
  const tracker = getSectionsTracker();
26146
26834
  postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
26147
- const h = document.body.scrollHeight;
26148
- if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
26835
+ const reportHeight = () => {
26836
+ const h = document.body.scrollHeight;
26837
+ if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
26838
+ };
26839
+ reportHeight();
26840
+ setTimeout(reportHeight, 500);
26149
26841
  }
26150
26842
  };
26151
26843
  const handleSwitchSchedule = (e) => {
@@ -26574,17 +27266,17 @@ function OhhwellsBridge() {
26574
27266
  window.removeEventListener("message", handleDeleteSection);
26575
27267
  window.removeEventListener("message", handleDuplicateSection);
26576
27268
  window.removeEventListener("message", handleDeactivate);
26577
- document.documentElement.removeAttribute("data-ohw-panel-dragging");
26578
27269
  window.removeEventListener("message", handleToastAction);
26579
27270
  window.removeEventListener("message", handleFormCount);
26580
27271
  window.removeEventListener("message", handleUiEscape);
27272
+ document.documentElement.removeAttribute("data-ohw-panel-dragging");
26581
27273
  autoSaveTimers.current.forEach(clearTimeout);
26582
27274
  autoSaveTimers.current.clear();
26583
27275
  if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
26584
27276
  if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
26585
27277
  };
26586
27278
  }, [isEditMode, refreshStateRules]);
26587
- (0, import_react19.useEffect)(() => {
27279
+ (0, import_react20.useEffect)(() => {
26588
27280
  if (!isEditMode) return;
26589
27281
  const THRESHOLD = 10;
26590
27282
  const resolveWasSelected = (el) => {
@@ -26740,7 +27432,7 @@ function OhhwellsBridge() {
26740
27432
  unlockFooterDragInteraction();
26741
27433
  };
26742
27434
  }, [isEditMode]);
26743
- (0, import_react19.useEffect)(() => {
27435
+ (0, import_react20.useEffect)(() => {
26744
27436
  if (!isEditMode) return;
26745
27437
  const THRESHOLD = 10;
26746
27438
  const onPointerDown = (e) => {
@@ -26831,7 +27523,7 @@ function OhhwellsBridge() {
26831
27523
  document.removeEventListener("selectstart", blockSelectStart, true);
26832
27524
  };
26833
27525
  }, [isEditMode, persistButtonCollectionDrag, refreshButtonDragVisuals]);
26834
- (0, import_react19.useEffect)(() => {
27526
+ (0, import_react20.useEffect)(() => {
26835
27527
  const handler = (e) => {
26836
27528
  if (e.data?.type !== "ow:request-schedule-config") return;
26837
27529
  const insertAfterVal = e.data.insertAfter;
@@ -26847,7 +27539,7 @@ function OhhwellsBridge() {
26847
27539
  window.addEventListener("message", handler);
26848
27540
  return () => window.removeEventListener("message", handler);
26849
27541
  }, [processConfigRequest]);
26850
- (0, import_react19.useEffect)(() => {
27542
+ (0, import_react20.useEffect)(() => {
26851
27543
  if (!isEditMode) return;
26852
27544
  document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
26853
27545
  el.removeAttribute("data-ohw-active-state");
@@ -26871,7 +27563,7 @@ function OhhwellsBridge() {
26871
27563
  postToParent2({
26872
27564
  type: "ow:ready",
26873
27565
  version: "1",
26874
- bridgeVersion: "0.1.122",
27566
+ bridgeVersion: "0.1.124",
26875
27567
  path: pathname,
26876
27568
  nodes: collectEditableNodes(editContentRef.current),
26877
27569
  sections
@@ -26883,13 +27575,13 @@ function OhhwellsBridge() {
26883
27575
  clearTimeout(timer);
26884
27576
  };
26885
27577
  }, [pathname, isEditMode, refreshStateRules, postToParent2]);
26886
- (0, import_react19.useEffect)(() => {
27578
+ (0, import_react20.useEffect)(() => {
26887
27579
  scrollToHashSectionWhenReady();
26888
27580
  const onHashChange = () => scrollToHashSectionWhenReady();
26889
27581
  window.addEventListener("hashchange", onHashChange);
26890
27582
  return () => window.removeEventListener("hashchange", onHashChange);
26891
27583
  }, [pathname]);
26892
- const handleCommand = (0, import_react19.useCallback)((cmd) => {
27584
+ const handleCommand = (0, import_react20.useCallback)((cmd) => {
26893
27585
  const el = activeElRef.current;
26894
27586
  const selBefore = window.getSelection();
26895
27587
  let savedOffsets = null;
@@ -26925,7 +27617,7 @@ function OhhwellsBridge() {
26925
27617
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
26926
27618
  refreshActiveCommandsRef.current();
26927
27619
  }, []);
26928
- (0, import_react19.useEffect)(() => {
27620
+ (0, import_react20.useEffect)(() => {
26929
27621
  const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
26930
27622
  if (!session || !logoSizeDraft) return;
26931
27623
  const onPanelAction = (e) => {
@@ -26963,7 +27655,7 @@ function OhhwellsBridge() {
26963
27655
  window.addEventListener("message", onPanelAction);
26964
27656
  return () => window.removeEventListener("message", onPanelAction);
26965
27657
  }, [floatingPanel, logoSizeDraft, editorViewport, persistLogoSizeDraft, closeFloatingPanelAndDeselect]);
26966
- const handleStateChange = (0, import_react19.useCallback)((state) => {
27658
+ const handleStateChange = (0, import_react20.useCallback)((state) => {
26967
27659
  if (!activeStateElRef.current) return;
26968
27660
  const el = activeStateElRef.current;
26969
27661
  if (state === "Default") {
@@ -26976,7 +27668,7 @@ function OhhwellsBridge() {
26976
27668
  }
26977
27669
  setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
26978
27670
  }, [deactivate]);
26979
- const reselectAfterLinkPopover = (0, import_react19.useCallback)(
27671
+ const reselectAfterLinkPopover = (0, import_react20.useCallback)(
26980
27672
  (hrefKey) => {
26981
27673
  requestAnimationFrame(() => {
26982
27674
  const el = resolveHrefKeyElement(hrefKey);
@@ -26985,7 +27677,7 @@ function OhhwellsBridge() {
26985
27677
  },
26986
27678
  [resolveHrefKeyElement]
26987
27679
  );
26988
- const closeLinkPopover = (0, import_react19.useCallback)(() => {
27680
+ const closeLinkPopover = (0, import_react20.useCallback)(() => {
26989
27681
  const session = linkPopoverSessionRef.current;
26990
27682
  addNavAfterAnchorRef.current = null;
26991
27683
  setLinkPopover(null);
@@ -26993,9 +27685,9 @@ function OhhwellsBridge() {
26993
27685
  reselectAfterLinkPopover(session.key);
26994
27686
  }
26995
27687
  }, [reselectAfterLinkPopover]);
26996
- const closeLinkPopoverRef = (0, import_react19.useRef)(closeLinkPopover);
27688
+ const closeLinkPopoverRef = (0, import_react20.useRef)(closeLinkPopover);
26997
27689
  closeLinkPopoverRef.current = closeLinkPopover;
26998
- const openLinkPopoverForActive = (0, import_react19.useCallback)(() => {
27690
+ const openLinkPopoverForActive = (0, import_react20.useCallback)(() => {
26999
27691
  const hrefCtx = getHrefKeyFromElement(activeElRef.current);
27000
27692
  if (!hrefCtx) return;
27001
27693
  bumpLinkPopoverGrace();
@@ -27006,7 +27698,7 @@ function OhhwellsBridge() {
27006
27698
  });
27007
27699
  deactivate();
27008
27700
  }, [deactivate]);
27009
- const openLinkPopoverForSelected = (0, import_react19.useCallback)(() => {
27701
+ const openLinkPopoverForSelected = (0, import_react20.useCallback)(() => {
27010
27702
  const anchor = selectedElRef.current;
27011
27703
  if (!anchor) return;
27012
27704
  const key = anchor.getAttribute("data-ohw-href-key");
@@ -27023,7 +27715,7 @@ function OhhwellsBridge() {
27023
27715
  });
27024
27716
  deselect();
27025
27717
  }, [deselect]);
27026
- const handleSelectParent = (0, import_react19.useCallback)(() => {
27718
+ const handleSelectParent = (0, import_react20.useCallback)(() => {
27027
27719
  const selected = selectedElRef.current;
27028
27720
  if (!selected) return;
27029
27721
  if (toolbarVariantRef.current === "select-frame") {
@@ -27050,7 +27742,7 @@ function OhhwellsBridge() {
27050
27742
  }
27051
27743
  deselectRef.current();
27052
27744
  }, []);
27053
- const handleDuplicateSelected = (0, import_react19.useCallback)(() => {
27745
+ const handleDuplicateSelected = (0, import_react20.useCallback)(() => {
27054
27746
  const selected = selectedElRef.current;
27055
27747
  if (!selected || !isNavigationItem2(selected)) return;
27056
27748
  if (isCtaButton(selected)) {
@@ -27213,7 +27905,7 @@ function OhhwellsBridge() {
27213
27905
  });
27214
27906
  }
27215
27907
  }, [postToParent2, tokensForButton]);
27216
- const runPendingDeleteUndo = (0, import_react19.useCallback)(() => {
27908
+ const runPendingDeleteUndo = (0, import_react20.useCallback)(() => {
27217
27909
  const pending = pendingDeleteUndoRef.current;
27218
27910
  if (!pending) return false;
27219
27911
  pendingDeleteUndoRef.current = null;
@@ -27221,7 +27913,7 @@ function OhhwellsBridge() {
27221
27913
  enforceLinkHrefs();
27222
27914
  return true;
27223
27915
  }, []);
27224
- const handleDeleteSelected = (0, import_react19.useCallback)(() => {
27916
+ const handleDeleteSelected = (0, import_react20.useCallback)(() => {
27225
27917
  const selected = selectedElRef.current;
27226
27918
  if (!selected) return false;
27227
27919
  if (isCtaButton(selected)) {
@@ -27274,7 +27966,7 @@ function OhhwellsBridge() {
27274
27966
  }, [postToParent2]);
27275
27967
  handleDeleteSelectedRef.current = handleDeleteSelected;
27276
27968
  runPendingDeleteUndoRef.current = runPendingDeleteUndo;
27277
- const handleLinkPopoverSubmit = (0, import_react19.useCallback)(
27969
+ const handleLinkPopoverSubmit = (0, import_react20.useCallback)(
27278
27970
  (target) => {
27279
27971
  const session = linkPopoverSessionRef.current;
27280
27972
  if (!session) return;
@@ -27340,14 +28032,14 @@ function OhhwellsBridge() {
27340
28032
  const showEditLink = toolbarShowEditLink;
27341
28033
  const currentSections = sectionsByPath[pathname] ?? [];
27342
28034
  linkPopoverOpenRef.current = linkPopover !== null;
27343
- const handleMediaSelect = (0, import_react19.useCallback)((key) => {
28035
+ const handleMediaSelect = (0, import_react20.useCallback)((key) => {
27344
28036
  const el = hoveredImageRef.current?.dataset.ohwKey === key ? hoveredImageRef.current : Array.from(document.querySelectorAll(MEDIA_SELECTOR)).find(
27345
28037
  (m) => (m.dataset.ohwKey ?? "") === key
27346
28038
  ) ?? null;
27347
28039
  if (!el) return;
27348
28040
  selectMediaElementRef.current(el);
27349
28041
  }, []);
27350
- const handleMediaReplace = (0, import_react19.useCallback)(
28042
+ const handleMediaReplace = (0, import_react20.useCallback)(
27351
28043
  (key) => {
27352
28044
  postToParent2({
27353
28045
  type: "ow:image-pick",
@@ -27357,13 +28049,13 @@ function OhhwellsBridge() {
27357
28049
  },
27358
28050
  [postToParent2, mediaHover?.elementType, selectedMedia?.elementType]
27359
28051
  );
27360
- const handleEditCarousel = (0, import_react19.useCallback)(
28052
+ const handleEditCarousel = (0, import_react20.useCallback)(
27361
28053
  (key) => {
27362
28054
  postToParent2({ type: "ow:carousel-open", key, images: readCarouselValue(key) });
27363
28055
  },
27364
28056
  [postToParent2]
27365
28057
  );
27366
- const handleMediaFadeOutComplete = (0, import_react19.useCallback)((key) => {
28058
+ const handleMediaFadeOutComplete = (0, import_react20.useCallback)((key) => {
27367
28059
  setUploadingRects((prev) => {
27368
28060
  if (!(key in prev)) return prev;
27369
28061
  const next = { ...prev };
@@ -27371,7 +28063,7 @@ function OhhwellsBridge() {
27371
28063
  return next;
27372
28064
  });
27373
28065
  }, []);
27374
- const handleVideoSettingsChange = (0, import_react19.useCallback)(
28066
+ const handleVideoSettingsChange = (0, import_react20.useCallback)(
27375
28067
  (key, settings) => {
27376
28068
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
27377
28069
  const video = getVideoEl2(el);
@@ -27393,14 +28085,14 @@ function OhhwellsBridge() {
27393
28085
  },
27394
28086
  [postToParent2]
27395
28087
  );
27396
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
27397
- /* @__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, {}) }),
27398
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("script", { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: OHW_LOADER_PREHYDRATE_SCRIPT } }),
27399
- subdomain && !isEditMode && showBranding && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(MadeWithOhhWells, {}),
28088
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
28089
+ /* @__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, {}) }),
28090
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("script", { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: OHW_LOADER_PREHYDRATE_SCRIPT } }),
28091
+ subdomain && !isEditMode && showBranding && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(MadeWithOhhWells, {}),
27400
28092
  bridgeRoot ? (0, import_react_dom5.createPortal)(
27401
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
27402
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
27403
- isEditMode && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28093
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
28094
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
28095
+ isEditMode && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27404
28096
  AiSectionOverlay,
27405
28097
  {
27406
28098
  postToParent: postToParent2,
@@ -27408,7 +28100,7 @@ function OhhwellsBridge() {
27408
28100
  onSelectionChange: handleAiSectionSelectionChange
27409
28101
  }
27410
28102
  ),
27411
- isEditMode && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28103
+ isEditMode && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27412
28104
  AiMediaStripOverlay,
27413
28105
  {
27414
28106
  postToParent: postToParent2,
@@ -27417,7 +28109,7 @@ function OhhwellsBridge() {
27417
28109
  clearInteractionChromeRef
27418
28110
  }
27419
28111
  ),
27420
- isEditMode && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28112
+ isEditMode && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27421
28113
  AiPricingCardOverlay,
27422
28114
  {
27423
28115
  postToParent: postToParent2,
@@ -27425,12 +28117,21 @@ function OhhwellsBridge() {
27425
28117
  applyTreeLocalRef
27426
28118
  }
27427
28119
  ),
27428
- isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28120
+ isEditMode && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
28121
+ AiVideoOverlay,
28122
+ {
28123
+ postToParent: postToParent2,
28124
+ aiSectionsRef,
28125
+ applyTreeLocalRef,
28126
+ clearInteractionChromeRef
28127
+ }
28128
+ ),
28129
+ isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27429
28130
  "div",
27430
28131
  {
27431
28132
  className: "pointer-events-none fixed z-2147483646",
27432
28133
  style: { left: slot.left, top: slot.y, width: slot.width, height: 3, transform: "translateY(-50%)" },
27433
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28134
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27434
28135
  DropIndicator,
27435
28136
  {
27436
28137
  direction: "horizontal",
@@ -27441,7 +28142,7 @@ function OhhwellsBridge() {
27441
28142
  },
27442
28143
  `section-drop-${slot.insertIndex}-${i}`
27443
28144
  )),
27444
- Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28145
+ Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27445
28146
  MediaOverlay,
27446
28147
  {
27447
28148
  hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
@@ -27452,7 +28153,7 @@ function OhhwellsBridge() {
27452
28153
  },
27453
28154
  `uploading-${key}`
27454
28155
  )),
27455
- mediaHover && !(mediaHover.key in uploadingRects) && mediaHover.key !== selectedMedia?.key && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28156
+ mediaHover && !(mediaHover.key in uploadingRects) && mediaHover.key !== selectedMedia?.key && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27456
28157
  MediaOverlay,
27457
28158
  {
27458
28159
  hover: mediaHover,
@@ -27463,7 +28164,7 @@ function OhhwellsBridge() {
27463
28164
  onVideoSettingsChange: handleVideoSettingsChange
27464
28165
  }
27465
28166
  ),
27466
- selectedMedia && !(selectedMedia.key in uploadingRects) && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28167
+ selectedMedia && !(selectedMedia.key in uploadingRects) && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27467
28168
  MediaOverlay,
27468
28169
  {
27469
28170
  hover: selectedMedia,
@@ -27475,7 +28176,7 @@ function OhhwellsBridge() {
27475
28176
  onVideoSettingsChange: handleVideoSettingsChange
27476
28177
  }
27477
28178
  ),
27478
- carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28179
+ carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27479
28180
  CarouselOverlay,
27480
28181
  {
27481
28182
  hover: carouselHover,
@@ -27483,10 +28184,10 @@ function OhhwellsBridge() {
27483
28184
  cueOnly: !!carouselHover.fullBleedSectionId && carouselHover.fullBleedSectionId !== selectedAiSectionId
27484
28185
  }
27485
28186
  ),
27486
- siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
27487
- siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
27488
- 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" }),
27489
- isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28187
+ siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
28188
+ siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
28189
+ 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" }),
28190
+ isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27490
28191
  "div",
27491
28192
  {
27492
28193
  className: "pointer-events-none fixed z-2147483646",
@@ -27496,7 +28197,7 @@ function OhhwellsBridge() {
27496
28197
  width: slot.width,
27497
28198
  height: slot.height
27498
28199
  },
27499
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28200
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27500
28201
  DropIndicator,
27501
28202
  {
27502
28203
  direction: slot.direction,
@@ -27507,7 +28208,7 @@ function OhhwellsBridge() {
27507
28208
  },
27508
28209
  `footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
27509
28210
  )),
27510
- isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28211
+ isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27511
28212
  "div",
27512
28213
  {
27513
28214
  className: "pointer-events-none fixed z-2147483646",
@@ -27517,7 +28218,7 @@ function OhhwellsBridge() {
27517
28218
  width: slot.width,
27518
28219
  height: slot.height
27519
28220
  },
27520
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28221
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27521
28222
  DropIndicator,
27522
28223
  {
27523
28224
  direction: slot.direction,
@@ -27528,7 +28229,7 @@ function OhhwellsBridge() {
27528
28229
  },
27529
28230
  `nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
27530
28231
  )),
27531
- isItemDragging && buttonDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28232
+ isItemDragging && buttonDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27532
28233
  "div",
27533
28234
  {
27534
28235
  className: "pointer-events-none fixed z-2147483646",
@@ -27538,7 +28239,7 @@ function OhhwellsBridge() {
27538
28239
  width: slot.width,
27539
28240
  height: slot.height
27540
28241
  },
27541
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28242
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27542
28243
  DropIndicator,
27543
28244
  {
27544
28245
  direction: slot.direction,
@@ -27549,10 +28250,10 @@ function OhhwellsBridge() {
27549
28250
  },
27550
28251
  `button-drop-${slot.direction}-${slot.insertIndex}-${i}`
27551
28252
  )),
27552
- hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
27553
- hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
27554
- hoveredTextRect && !hoveredNavContainerRect && !hoveredItemRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
27555
- formPickRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28253
+ hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
28254
+ hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
28255
+ hoveredTextRect && !hoveredNavContainerRect && !hoveredItemRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
28256
+ formPickRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27556
28257
  ItemInteractionLayer,
27557
28258
  {
27558
28259
  rect: formPickRect,
@@ -27560,13 +28261,13 @@ function OhhwellsBridge() {
27560
28261
  itemDragSurface: false,
27561
28262
  toolbarAlign: "left",
27562
28263
  chromeGap: 24,
27563
- toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
28264
+ toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
27564
28265
  "div",
27565
28266
  {
27566
28267
  "data-ohw-form-toolbar": "",
27567
28268
  className: "pointer-events-auto flex items-center gap-0.5 whitespace-nowrap rounded-lg border border-border bg-background p-1 shadow-md",
27568
28269
  children: [
27569
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28270
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27570
28271
  "button",
27571
28272
  {
27572
28273
  type: "button",
@@ -27574,11 +28275,11 @@ function OhhwellsBridge() {
27574
28275
  className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
27575
28276
  onClick: () => setFieldTypePickerOpen((open) => !open),
27576
28277
  "data-ohw-add-field": "",
27577
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Plus, { size: 15, "aria-hidden": true })
28278
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react21.Plus, { size: 15, "aria-hidden": true })
27578
28279
  }
27579
28280
  ),
27580
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
27581
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
28281
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
28282
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
27582
28283
  "button",
27583
28284
  {
27584
28285
  type: "button",
@@ -27594,11 +28295,11 @@ function OhhwellsBridge() {
27594
28295
  });
27595
28296
  },
27596
28297
  children: [
27597
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Settings, { size: 14, "aria-hidden": true }),
28298
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react21.Settings, { size: 14, "aria-hidden": true }),
27598
28299
  "Form settings",
27599
28300
  formPickCount ? (
27600
28301
  // Counter pill, per the design — not a text suffix.
27601
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28302
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27602
28303
  "span",
27603
28304
  {
27604
28305
  "data-ohw-form-count": "",
@@ -27610,8 +28311,8 @@ function OhhwellsBridge() {
27610
28311
  ]
27611
28312
  }
27612
28313
  ),
27613
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
27614
- /* @__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)(
28314
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
28315
+ /* @__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)(
27615
28316
  "button",
27616
28317
  {
27617
28318
  type: "button",
@@ -27642,7 +28343,7 @@ function OhhwellsBridge() {
27642
28343
  )
27643
28344
  }
27644
28345
  ),
27645
- formHoverRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28346
+ formHoverRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27646
28347
  ItemInteractionLayer,
27647
28348
  {
27648
28349
  rect: formHoverRect,
@@ -27650,7 +28351,7 @@ function OhhwellsBridge() {
27650
28351
  chromeGap: formHoverElRef.current && getFieldWrapper(formHoverElRef.current) ? 8 : 24
27651
28352
  }
27652
28353
  ),
27653
- fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28354
+ fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27654
28355
  ItemInteractionLayer,
27655
28356
  {
27656
28357
  rect: fieldPickRect,
@@ -27662,7 +28363,7 @@ function OhhwellsBridge() {
27662
28363
  dragHandleLabel: "Reorder field",
27663
28364
  onDragHandleDragStart: handleFieldDragStart,
27664
28365
  onDragHandleDragEnd: handleFieldDragEnd,
27665
- toolbar: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28366
+ toolbar: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27666
28367
  FormFieldToolbar,
27667
28368
  {
27668
28369
  type: fieldPickState.type,
@@ -27675,12 +28376,12 @@ function OhhwellsBridge() {
27675
28376
  )
27676
28377
  }
27677
28378
  ),
27678
- fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28379
+ fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27679
28380
  "div",
27680
28381
  {
27681
28382
  className: "pointer-events-none fixed z-[2147483644]",
27682
28383
  style: { top: slot.top, left: slot.left, width: slot.width },
27683
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28384
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27684
28385
  DropIndicator,
27685
28386
  {
27686
28387
  direction: "horizontal",
@@ -27693,7 +28394,7 @@ function OhhwellsBridge() {
27693
28394
  )) : null,
27694
28395
  fieldTypePickerOpen && formPickRect ? (() => {
27695
28396
  const toolbar = document.querySelector("[data-ohw-form-toolbar]")?.getBoundingClientRect();
27696
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28397
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27697
28398
  "div",
27698
28399
  {
27699
28400
  className: "pointer-events-none fixed z-[2147483645]",
@@ -27701,12 +28402,12 @@ function OhhwellsBridge() {
27701
28402
  top: toolbar ? toolbar.bottom + 6 : formPickRect.top + 16,
27702
28403
  left: toolbar ? toolbar.left : formPickRect.left + 24
27703
28404
  },
27704
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(FieldTypePicker, { onPick: handleAddField })
28405
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(FieldTypePicker, { onPick: handleAddField })
27705
28406
  }
27706
28407
  );
27707
28408
  })() : null,
27708
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
27709
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28409
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
28410
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27710
28411
  FooterContainerChrome,
27711
28412
  {
27712
28413
  rect: toolbarRect,
@@ -27714,7 +28415,7 @@ function OhhwellsBridge() {
27714
28415
  addDisabled: !canAddFooterColumn()
27715
28416
  }
27716
28417
  ),
27717
- toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28418
+ toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27718
28419
  ItemInteractionLayer,
27719
28420
  {
27720
28421
  rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected || selectedElRef.current === buttonCollectionDragRef.current) ? draggedItemRect : toolbarRect,
@@ -27734,7 +28435,7 @@ function OhhwellsBridge() {
27734
28435
  onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
27735
28436
  onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
27736
28437
  itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection && !selectedIsSocialsRow,
27737
- toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28438
+ toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27738
28439
  ItemActionToolbar,
27739
28440
  {
27740
28441
  onEditLink: openLinkPopoverForSelected,
@@ -27785,8 +28486,8 @@ function OhhwellsBridge() {
27785
28486
  ) : void 0
27786
28487
  }
27787
28488
  ),
27788
- toolbarRect && toolbarVariant === "rich-text" && !linkPopover && !isRectOutsideClip(toolbarRect, getIframeVisibleClip(parentScrollRef.current)) && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
27789
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28489
+ toolbarRect && toolbarVariant === "rich-text" && !linkPopover && !isRectOutsideClip(toolbarRect, getIframeVisibleClip(parentScrollRef.current)) && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
28490
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27790
28491
  EditGlowChrome,
27791
28492
  {
27792
28493
  rect: toolbarRect,
@@ -27796,7 +28497,7 @@ function OhhwellsBridge() {
27796
28497
  hideHandle: isItemDragging
27797
28498
  }
27798
28499
  ),
27799
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28500
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27800
28501
  FloatingToolbar,
27801
28502
  {
27802
28503
  rect: toolbarRect,
@@ -27809,7 +28510,7 @@ function OhhwellsBridge() {
27809
28510
  }
27810
28511
  )
27811
28512
  ] }),
27812
- maxBadge && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
28513
+ maxBadge && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
27813
28514
  "div",
27814
28515
  {
27815
28516
  "data-ohw-max-badge": "",
@@ -27835,7 +28536,7 @@ function OhhwellsBridge() {
27835
28536
  ]
27836
28537
  }
27837
28538
  ),
27838
- toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28539
+ toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27839
28540
  StateToggle,
27840
28541
  {
27841
28542
  rect: toggleState.rect,
@@ -27844,15 +28545,15 @@ function OhhwellsBridge() {
27844
28545
  onStateChange: handleStateChange
27845
28546
  }
27846
28547
  ),
27847
- sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
28548
+ sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
27848
28549
  "div",
27849
28550
  {
27850
28551
  "data-ohw-section-insert-line": "",
27851
28552
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
27852
28553
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
27853
28554
  children: [
27854
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
27855
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28555
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
28556
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27856
28557
  Badge,
27857
28558
  {
27858
28559
  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",
@@ -27869,11 +28570,11 @@ function OhhwellsBridge() {
27869
28570
  children: "Add Section"
27870
28571
  }
27871
28572
  ),
27872
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
28573
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
27873
28574
  ]
27874
28575
  }
27875
28576
  ),
27876
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28577
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27877
28578
  LinkPopover,
27878
28579
  {
27879
28580
  panelRef: linkPopoverPanelRef,
@@ -27890,7 +28591,7 @@ function OhhwellsBridge() {
27890
28591
  },
27891
28592
  linkPopover.key
27892
28593
  ) : null,
27893
- floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28594
+ floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27894
28595
  FloatingPanel,
27895
28596
  {
27896
28597
  open: true,
@@ -27900,7 +28601,7 @@ function OhhwellsBridge() {
27900
28601
  onPositionChange: setFloatingPanelPos,
27901
28602
  parentScroll: parentScrollSnap ?? parentScrollRef.current,
27902
28603
  onClose: closeFloatingPanelOnly,
27903
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28604
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27904
28605
  SocialsDisplayPanel,
27905
28606
  {
27906
28607
  display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
@@ -27921,19 +28622,19 @@ function OhhwellsBridge() {
27921
28622
  const tokens = tokensFromButton(button);
27922
28623
  const current = assignmentFor(button, editContentRef.current, tokens);
27923
28624
  void buttonStyleTick;
27924
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28625
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27925
28626
  FloatingPanel,
27926
28627
  {
27927
28628
  open: true,
27928
28629
  title: floatingPanel.title,
27929
28630
  context: floatingPanel.context,
27930
- icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Brush, { className: "size-4 shrink-0", "aria-hidden": true }),
28631
+ icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react21.Brush, { className: "size-4 shrink-0", "aria-hidden": true }),
27931
28632
  position: floatingPanelPos,
27932
28633
  onPositionChange: setFloatingPanelPos,
27933
28634
  parentScroll: parentScrollSnap ?? parentScrollRef.current,
27934
28635
  onClose: closeFloatingPanelOnly,
27935
28636
  bodyClassName: "gap-5",
27936
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
28637
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
27937
28638
  ButtonStylePanel,
27938
28639
  {
27939
28640
  variants: tokens.variants,
@@ -27958,6 +28659,59 @@ function OhhwellsBridge() {
27958
28659
  ) : null
27959
28660
  ] });
27960
28661
  }
28662
+
28663
+ // src/ui/EmptySection.tsx
28664
+ var import_link = __toESM(require("next/link"), 1);
28665
+ var import_jsx_runtime38 = require("react/jsx-runtime");
28666
+ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
28667
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
28668
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
28669
+ "p",
28670
+ {
28671
+ style: {
28672
+ fontFamily: "var(--brand-font-body)",
28673
+ fontSize: "0.75rem",
28674
+ fontWeight: 500,
28675
+ letterSpacing: "0.15em",
28676
+ textTransform: "uppercase",
28677
+ color: "var(--brand-accent)",
28678
+ marginBottom: "1.5rem"
28679
+ },
28680
+ 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" }) })
28681
+ }
28682
+ ),
28683
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
28684
+ "h1",
28685
+ {
28686
+ style: {
28687
+ fontFamily: "var(--brand-font-heading)",
28688
+ fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
28689
+ lineHeight: 1.1,
28690
+ letterSpacing: "-0.025em",
28691
+ color: "var(--brand-text)",
28692
+ marginBottom: "1rem"
28693
+ },
28694
+ ...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
28695
+ children: title
28696
+ }
28697
+ ),
28698
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
28699
+ "p",
28700
+ {
28701
+ style: {
28702
+ fontFamily: "var(--brand-font-body)",
28703
+ fontSize: "1rem",
28704
+ lineHeight: 1.7,
28705
+ fontWeight: 300,
28706
+ color: "var(--brand-text-muted)",
28707
+ maxWidth: "340px"
28708
+ },
28709
+ ...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
28710
+ children: "This page doesn't have any content yet."
28711
+ }
28712
+ )
28713
+ ] });
28714
+ }
27961
28715
  // Annotate the CommonJS export names for ESM import in node:
27962
28716
  0 && (module.exports = {
27963
28717
  AI_DEFAULT_BRAND,
@@ -27975,6 +28729,7 @@ function OhhwellsBridge() {
27975
28729
  DropdownMenuItem,
27976
28730
  DropdownMenuSeparator,
27977
28731
  DropdownMenuTrigger,
28732
+ EmptySection,
27978
28733
  ItemActionToolbar,
27979
28734
  ItemInteractionLayer,
27980
28735
  LinkEditorPanel,