@ohhwells/bridge 0.1.55-next.158 → 0.1.56

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,7 +46,6 @@ __export(index_exports, {
46
46
  DropdownMenuItem: () => DropdownMenuItem,
47
47
  DropdownMenuSeparator: () => DropdownMenuSeparator,
48
48
  DropdownMenuTrigger: () => DropdownMenuTrigger,
49
- EmptySection: () => EmptySection,
50
49
  ItemActionToolbar: () => ItemActionToolbar,
51
50
  ItemInteractionLayer: () => ItemInteractionLayer,
52
51
  LinkEditorPanel: () => LinkEditorPanel,
@@ -192,129 +191,6 @@ function deleteSectionFromState(state, sectionId) {
192
191
  return { ...state, v: 1, sections: state.sections, removed: [...removed, sectionId] };
193
192
  }
194
193
 
195
- // src/lib/brand-chrome.ts
196
- var BRAND_NAME_KEY = "__ohw_brand_name";
197
- var BRAND_TITLE_KEY = "__ohw_site_title";
198
- var BRAND_FAVICON_LETTER_KEY = "__ohw_favicon_letter";
199
- var BRAND_CHROME_KEYS = /* @__PURE__ */ new Set([
200
- BRAND_NAME_KEY,
201
- BRAND_TITLE_KEY,
202
- BRAND_FAVICON_LETTER_KEY
203
- ]);
204
- function upsertMeta(selector, attr, token, value) {
205
- let el = document.head.querySelector(selector);
206
- if (!el) {
207
- el = document.createElement("meta");
208
- el.setAttribute(attr, token);
209
- document.head.appendChild(el);
210
- }
211
- if (el.getAttribute("content") !== value) el.setAttribute("content", value);
212
- }
213
- function escapeXml(value) {
214
- return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
215
- }
216
- function applyLetterFavicon(letter) {
217
- const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" rx="12" fill="#111827"/><text x="32" y="46" font-family="system-ui,-apple-system,Segoe UI,sans-serif" font-size="40" font-weight="700" text-anchor="middle" fill="#ffffff">${escapeXml(letter)}</text></svg>`;
218
- const href = `data:image/svg+xml,${encodeURIComponent(svg)}`;
219
- let link = document.head.querySelector('link[rel="icon"]');
220
- if (!link) {
221
- link = document.createElement("link");
222
- link.rel = "icon";
223
- document.head.appendChild(link);
224
- }
225
- link.type = "image/svg+xml";
226
- if (link.href !== href) link.href = href;
227
- }
228
- function applyBrandChrome(content) {
229
- const name = content[BRAND_NAME_KEY];
230
- if (typeof name === "string" && name.length > 0) {
231
- document.querySelectorAll("[data-ohw-wordmark]").forEach((el) => {
232
- if (el.textContent !== name) el.textContent = name;
233
- if (el.getAttribute("title") !== name) el.setAttribute("title", name);
234
- });
235
- }
236
- const title = content[BRAND_TITLE_KEY];
237
- if (typeof title === "string" && title.length > 0) {
238
- if (document.title !== title) document.title = title;
239
- upsertMeta('meta[property="og:title"]', "property", "og:title", title);
240
- upsertMeta('meta[name="twitter:title"]', "name", "twitter:title", title);
241
- }
242
- const letter = content[BRAND_FAVICON_LETTER_KEY];
243
- if (typeof letter === "string" && letter.length > 0) {
244
- applyLetterFavicon(letter);
245
- }
246
- }
247
-
248
- // src/lib/brand-kit.ts
249
- var BRAND_KIT_KEY = "__ohw_brand";
250
- var BRAND_VAR_PREFIX = "--ohw-brand-";
251
- var BRAND_VAR_NAMES = ["primary", "accent", "light", "dark", "surface", "border", "muted"].map(
252
- (role) => `${BRAND_VAR_PREFIX}${role}`
253
- );
254
- var FONT_VARS = { heading: ["--font-heading", "--font-display"], body: ["--font-body"] };
255
- var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
256
- function brandColorVars(kit) {
257
- const { dark, primary, accent, light } = kit.palette;
258
- const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
259
- return {
260
- [`${BRAND_VAR_PREFIX}primary`]: primary,
261
- [`${BRAND_VAR_PREFIX}accent`]: accent,
262
- [`${BRAND_VAR_PREFIX}light`]: light,
263
- [`${BRAND_VAR_PREFIX}dark`]: dark,
264
- [`${BRAND_VAR_PREFIX}surface`]: mix(light, 95, dark),
265
- [`${BRAND_VAR_PREFIX}border`]: mix(light, 85, dark),
266
- [`${BRAND_VAR_PREFIX}muted`]: mix(dark, 62, light)
267
- };
268
- }
269
- function parseBrandKit(raw) {
270
- if (!raw) return null;
271
- try {
272
- const parsed = JSON.parse(raw);
273
- const p = parsed?.palette;
274
- const f = parsed?.fonts;
275
- if (!p || !f || typeof p.dark !== "string" || typeof p.primary !== "string" || typeof p.accent !== "string" || typeof p.light !== "string" || typeof f.heading !== "string" || typeof f.body !== "string") {
276
- return null;
277
- }
278
- return {
279
- palette: { dark: p.dark, primary: p.primary, accent: p.accent, light: p.light },
280
- fonts: { heading: f.heading, body: f.body }
281
- };
282
- } catch {
283
- return null;
284
- }
285
- }
286
- function familyOf(stack) {
287
- const first = stack.split(",")[0]?.trim() ?? "";
288
- return first.replace(/^['"]|['"]$/g, "");
289
- }
290
- function loadBrandFonts(families) {
291
- const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
292
- if (unique.length === 0) return;
293
- const spec = unique.map((f) => `${f.replace(/ /g, "+")}:400,500,600,700`).join("|");
294
- const href = `https://fonts.googleapis.com/css?family=${spec}&display=swap`;
295
- let link = document.getElementById(BRAND_FONT_LINK_ID);
296
- if (!link) {
297
- link = document.createElement("link");
298
- link.id = BRAND_FONT_LINK_ID;
299
- link.rel = "stylesheet";
300
- document.head.appendChild(link);
301
- }
302
- if (link.href !== href) link.href = href;
303
- }
304
- function applyBrandToDom(kit) {
305
- const root = document.documentElement;
306
- if (!kit) {
307
- for (const name of BRAND_VAR_NAMES) root.style.removeProperty(name);
308
- for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
309
- document.getElementById(BRAND_FONT_LINK_ID)?.remove();
310
- return;
311
- }
312
- for (const [name, value] of Object.entries(brandColorVars(kit))) root.style.setProperty(name, value);
313
- for (const name of FONT_VARS.heading) root.style.setProperty(name, kit.fonts.heading);
314
- for (const name of FONT_VARS.body) root.style.setProperty(name, kit.fonts.body);
315
- loadBrandFonts([familyOf(kit.fonts.heading), familyOf(kit.fonts.body)]);
316
- }
317
-
318
194
  // src/ui/ai-tree/aiSectionsManager.tsx
319
195
  var import_react_dom = require("react-dom");
320
196
  var import_client = require("react-dom/client");
@@ -1401,34 +1277,17 @@ var import_jsx_runtime2 = require("react/jsx-runtime");
1401
1277
  var CONTAINER_ATTR = "data-ohw-ai-generated";
1402
1278
  var REPLACED_ATTR = "data-ohw-ai-replaced-by";
1403
1279
  var REMOVED_ATTR = "data-ohw-ai-removed";
1404
- function readRootVar(name) {
1405
- if (typeof document === "undefined") return "";
1406
- return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
1407
- }
1408
- function deriveBrandOverride() {
1409
- const dark = readRootVar("--ohw-brand-dark");
1410
- const primary = readRootVar("--ohw-brand-primary");
1411
- const light = readRootVar("--ohw-brand-light");
1412
- if (!dark || !primary || !light) return null;
1413
- const accent = readRootVar("--ohw-brand-accent");
1414
- const heading = readRootVar("--font-heading") || readRootVar("--font-display");
1415
- const body = readRootVar("--font-body");
1416
- return {
1417
- palette: { dark, primary, accent: accent || dark, light },
1418
- fonts: {
1419
- heading: heading || AI_DEFAULT_BRAND.fonts.heading,
1420
- body: body || AI_DEFAULT_BRAND.fonts.body
1421
- }
1422
- };
1423
- }
1424
1280
  function deriveTemplateBrand() {
1425
- const dark = readRootVar("--color-dark");
1426
- const primary = readRootVar("--color-primary");
1427
- const light = readRootVar("--color-light");
1281
+ if (typeof document === "undefined") return null;
1282
+ const cs = getComputedStyle(document.documentElement);
1283
+ const read = (name) => cs.getPropertyValue(name).trim();
1284
+ const dark = read("--color-dark");
1285
+ const primary = read("--color-primary");
1286
+ const light = read("--color-light");
1428
1287
  if (!dark || !primary || !light) return null;
1429
- const accent = readRootVar("--color-accent");
1430
- const heading = readRootVar("--font-heading") || readRootVar("--font-display");
1431
- const body = readRootVar("--font-body");
1288
+ const accent = read("--color-accent");
1289
+ const heading = read("--font-heading") || read("--font-display");
1290
+ const body = read("--font-body");
1432
1291
  return {
1433
1292
  palette: { dark, primary, accent: accent || dark, light },
1434
1293
  fonts: {
@@ -1520,9 +1379,7 @@ function syncReplacedOriginals(state) {
1520
1379
  }
1521
1380
  function applyAiSectionsToDom(state, options) {
1522
1381
  if (typeof document === "undefined") return;
1523
- const brandOverride = deriveBrandOverride();
1524
1382
  const templateBrand = deriveTemplateBrand();
1525
- const brandKey = brandOverride ? JSON.stringify(brandOverride) : "";
1526
1383
  const activeIds = new Set(state.sections.map((entry) => entry.id));
1527
1384
  for (const [id, section] of mounted) {
1528
1385
  if (!activeIds.has(id)) {
@@ -1532,7 +1389,7 @@ function applyAiSectionsToDom(state, options) {
1532
1389
  }
1533
1390
  }
1534
1391
  for (const entry of state.sections) {
1535
- const serialized = JSON.stringify(entry) + brandKey;
1392
+ const serialized = JSON.stringify(entry);
1536
1393
  const existing = mounted.get(entry.id);
1537
1394
  if (existing && existing.serialized === serialized && existing.container.isConnected) {
1538
1395
  continue;
@@ -1556,7 +1413,7 @@ function applyAiSectionsToDom(state, options) {
1556
1413
  AiTreeRenderer,
1557
1414
  {
1558
1415
  tree: entry.tree,
1559
- brand: brandOverride ?? entry.brand ?? options?.brand ?? templateBrand ?? void 0,
1416
+ brand: entry.brand ?? options?.brand ?? templateBrand ?? void 0,
1560
1417
  resolveMedia,
1561
1418
  editKeyPrefix: `ai.${entry.id}`
1562
1419
  }
@@ -2173,7 +2030,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
2173
2030
  const autoId = (0, import_react5.useId)();
2174
2031
  const insertAfter = insertAfterProp ?? autoId;
2175
2032
  const [schedule, setSchedule] = (0, import_react5.useState)(null);
2176
- const [loading, setLoading] = (0, import_react5.useState)(initialScheduleId !== null);
2033
+ const [loading, setLoading] = (0, import_react5.useState)(true);
2177
2034
  const [inEditor, setInEditor] = (0, import_react5.useState)(false);
2178
2035
  const [isHovered, setIsHovered] = (0, import_react5.useState)(false);
2179
2036
  const [modalState, setModalState] = (0, import_react5.useState)(null);
@@ -2347,10 +2204,8 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
2347
2204
  "*"
2348
2205
  );
2349
2206
  };
2207
+ if (!inEditor && !loading && !schedule) return null;
2350
2208
  const sectionId = `scheduling-${insertAfter}`;
2351
- if (!inEditor && !loading && !schedule) {
2352
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("section", { "data-ohw-section": sectionId, "data-ohw-scheduling-anchor": insertAfter, style: { display: "none" } });
2353
- }
2354
2209
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2355
2210
  "section",
2356
2211
  {
@@ -10980,329 +10835,6 @@ function deleteFooterColumn(column) {
10980
10835
  };
10981
10836
  }
10982
10837
 
10983
- // src/lib/logo-identity.ts
10984
- var LOGO_TEXT_KEYS = ["nav-logo-text", "footer-logo-text", "logo-text"];
10985
- var LOGO_IMAGE_KEYS = ["nav-logo-image", "footer-logo", "footer-logo-image"];
10986
- var LOGO_HREF_KEYS = ["nav-logo-href", "footer-logo-href", "logo-href"];
10987
- var LOGO_PLACEHOLDER_KEY = "logo-is-placeholder";
10988
- var LOGO_ALT_KEY = "logo-alt";
10989
- var LOGO_IMAGE_URL_KEY = "nav-logo-image";
10990
- var PLACEHOLDER_BUSINESS_NAME = "Business name";
10991
- function resolveLogoDisplayText(text) {
10992
- const trimmed = (text ?? "").trim();
10993
- return trimmed || PLACEHOLDER_BUSINESS_NAME;
10994
- }
10995
- function isFooterLogoRoot(root) {
10996
- return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
10997
- }
10998
- function imageKeyForRoot(root) {
10999
- return isFooterLogoRoot(root) ? "footer-logo" : "nav-logo-image";
11000
- }
11001
- function textKeyForRoot(root) {
11002
- return isFooterLogoRoot(root) ? "footer-logo-text" : "nav-logo-text";
11003
- }
11004
- function ensureLogoHrefKey(root) {
11005
- if (!(root instanceof HTMLAnchorElement)) return;
11006
- if (root.hasAttribute("data-ohw-href-key")) return;
11007
- root.setAttribute("data-ohw-href-key", isFooterLogoRoot(root) ? "footer-logo-href" : "nav-logo-href");
11008
- }
11009
- function applyLogoIdentity(text, isPlaceholder) {
11010
- const display = resolveLogoDisplayText(text);
11011
- const placeholder = isPlaceholder || !text.trim() || display === PLACEHOLDER_BUSINESS_NAME;
11012
- for (const key of LOGO_TEXT_KEYS) {
11013
- document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
11014
- if (el.textContent !== display) el.textContent = display;
11015
- });
11016
- }
11017
- for (const key of LOGO_IMAGE_KEYS) {
11018
- document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
11019
- const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
11020
- if (img) img.alt = display;
11021
- });
11022
- }
11023
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((el) => {
11024
- if (placeholder) el.setAttribute("data-ohw-placeholder", "");
11025
- else el.removeAttribute("data-ohw-placeholder");
11026
- });
11027
- return display;
11028
- }
11029
- function applyLogoImage(url, alt) {
11030
- const displayAlt = resolveLogoDisplayText(alt);
11031
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
11032
- ensureLogoHrefKey(root);
11033
- const imageKey = imageKeyForRoot(root);
11034
- const textKey = textKeyForRoot(root);
11035
- let img = root.querySelector(`img[data-ohw-key="${imageKey}"]`) ?? (root.querySelector(`[data-ohw-key="${imageKey}"]`) instanceof HTMLImageElement ? root.querySelector(`[data-ohw-key="${imageKey}"]`) : null) ?? root.querySelector("img");
11036
- let textEl = root.querySelector(`[data-ohw-key="${textKey}"]`) ?? root.querySelector('[data-ohw-key="logo-text"]');
11037
- if (url) {
11038
- if (!img) {
11039
- img = document.createElement("img");
11040
- img.setAttribute("data-ohw-editable", "image");
11041
- img.setAttribute("data-ohw-key", imageKey);
11042
- img.alt = displayAlt;
11043
- img.style.height = "";
11044
- img.style.maxHeight = "none";
11045
- img.style.width = "auto";
11046
- img.style.display = "block";
11047
- img.style.objectFit = "contain";
11048
- root.insertBefore(img, root.firstChild);
11049
- } else {
11050
- img.setAttribute("data-ohw-editable", "image");
11051
- img.setAttribute("data-ohw-key", imageKey);
11052
- }
11053
- img.removeAttribute("srcset");
11054
- img.removeAttribute("sizes");
11055
- img.src = url;
11056
- img.alt = displayAlt;
11057
- img.style.display = "block";
11058
- if (textEl) textEl.style.display = "none";
11059
- root.removeAttribute("data-ohw-placeholder");
11060
- return;
11061
- }
11062
- if (img) {
11063
- img.removeAttribute("src");
11064
- img.removeAttribute("srcset");
11065
- img.removeAttribute("sizes");
11066
- img.alt = displayAlt;
11067
- img.style.display = "none";
11068
- }
11069
- if (!textEl) {
11070
- textEl = document.createElement("span");
11071
- textEl.setAttribute("data-ohw-editable", "plain");
11072
- textEl.setAttribute("data-ohw-key", textKey);
11073
- root.appendChild(textEl);
11074
- }
11075
- textEl.style.display = "";
11076
- if (textEl.textContent !== displayAlt) textEl.textContent = displayAlt;
11077
- if (!displayAlt.trim() || displayAlt === PLACEHOLDER_BUSINESS_NAME) {
11078
- root.setAttribute("data-ohw-placeholder", "");
11079
- } else {
11080
- root.removeAttribute("data-ohw-placeholder");
11081
- }
11082
- });
11083
- }
11084
- function applyLogoHref(href) {
11085
- const target = href.trim() || "/";
11086
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
11087
- ensureLogoHrefKey(root);
11088
- if (root instanceof HTMLAnchorElement) {
11089
- root.setAttribute("href", target);
11090
- }
11091
- });
11092
- for (const key of LOGO_HREF_KEYS) setStoredLinkHref(key, target);
11093
- }
11094
- function readLogoIdentityFromDom() {
11095
- let imageUrl = null;
11096
- for (const key of LOGO_IMAGE_KEYS) {
11097
- const el = document.querySelector(`[data-ohw-key="${key}"]`);
11098
- const img = el instanceof HTMLImageElement ? el : el?.querySelector("img");
11099
- const attrSrc = img?.getAttribute("src")?.trim() ?? "";
11100
- if (attrSrc && !attrSrc.startsWith("data:") && img && img.style.display !== "none") {
11101
- imageUrl = img.currentSrc || img.src;
11102
- break;
11103
- }
11104
- }
11105
- let text = PLACEHOLDER_BUSINESS_NAME;
11106
- let isPlaceholder = true;
11107
- for (const key of LOGO_TEXT_KEYS) {
11108
- const el = document.querySelector(`[data-ohw-key="${key}"]`);
11109
- if (el?.textContent?.trim()) {
11110
- text = el.textContent.trim();
11111
- const logoRoot2 = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
11112
- isPlaceholder = logoRoot2?.hasAttribute("data-ohw-placeholder") === true || text === PLACEHOLDER_BUSINESS_NAME;
11113
- break;
11114
- }
11115
- }
11116
- if (imageUrl) {
11117
- const logoImg = document.querySelector(
11118
- '[data-ohw-key="nav-logo-image"], [data-ohw-key="footer-logo"]'
11119
- );
11120
- const alt = logoImg?.alt?.trim() || text;
11121
- isPlaceholder = false;
11122
- const hrefEl = document.querySelector(
11123
- 'a[data-ohw-role="logo"], a[data-ohw-logo], [data-ohw-role="logo"]'
11124
- );
11125
- const href2 = (hrefEl instanceof HTMLAnchorElement ? hrefEl.getAttribute("href") : null) || hrefEl?.closest("a")?.getAttribute("href") || "/";
11126
- return { text, isPlaceholder, imageUrl, href: href2, alt };
11127
- }
11128
- const logoRoot = document.querySelector('[data-ohw-role="logo"], [data-ohw-logo]');
11129
- const href = (logoRoot instanceof HTMLAnchorElement ? logoRoot.getAttribute("href") : null) || logoRoot?.closest("a")?.getAttribute("href") || "/";
11130
- return { text, isPlaceholder, imageUrl: null, href, alt: text };
11131
- }
11132
- function applyLogoFromContent(content) {
11133
- const hasLogoIdentity = LOGO_PLACEHOLDER_KEY in content || LOGO_TEXT_KEYS.some((key) => key in content) || LOGO_IMAGE_KEYS.some((key) => key in content) || LOGO_ALT_KEY in content || LOGO_HREF_KEYS.some((key) => key in content);
11134
- if (!hasLogoIdentity) return false;
11135
- const logoText = content[LOGO_TEXT_KEYS[0]] ?? content[LOGO_TEXT_KEYS[1]] ?? readLogoIdentityFromDom().text;
11136
- const logoAlt = content[LOGO_ALT_KEY] ?? logoText;
11137
- const rawLogoImage = content[LOGO_IMAGE_URL_KEY] ?? content["footer-logo"] ?? content["footer-logo-image"] ?? null;
11138
- const logoImageUrl = typeof rawLogoImage === "string" && rawLogoImage.trim() ? rawLogoImage.trim() : null;
11139
- const imageExplicitlyCleared = LOGO_IMAGE_KEYS.some((key) => key in content) && !logoImageUrl;
11140
- const logoIsPlaceholder = LOGO_PLACEHOLDER_KEY in content ? content[LOGO_PLACEHOLDER_KEY] !== "false" : !logoImageUrl && (!logoText.trim() || logoText === PLACEHOLDER_BUSINESS_NAME);
11141
- if (logoImageUrl) {
11142
- applyLogoImage(logoImageUrl, logoAlt);
11143
- } else {
11144
- if (imageExplicitlyCleared) applyLogoImage(null, logoAlt);
11145
- applyLogoIdentity(logoText, logoIsPlaceholder);
11146
- }
11147
- const logoHref = content["nav-logo-href"] ?? content["footer-logo-href"] ?? content["logo-href"];
11148
- if (typeof logoHref === "string" && logoHref.trim()) {
11149
- applyLogoHref(logoHref);
11150
- }
11151
- return true;
11152
- }
11153
-
11154
- // src/lib/logo-size.ts
11155
- var LOGO_SIZE_DEFAULTS = {
11156
- navbar: 28,
11157
- footer: 32
11158
- };
11159
- var LOGO_SIZE_MIN = 16;
11160
- var LOGO_SIZE_MAX = 80;
11161
- var LOGO_SIZE_DESKTOP_KEYS = {
11162
- navbar: "nav-logo-size",
11163
- footer: "footer-logo-size"
11164
- };
11165
- var LOGO_SIZE_MOBILE_KEYS = {
11166
- navbar: "nav-logo-size-mobile",
11167
- footer: "footer-logo-size-mobile"
11168
- };
11169
- var LOGO_SIZE_KEYS = [
11170
- LOGO_SIZE_DESKTOP_KEYS.navbar,
11171
- LOGO_SIZE_DESKTOP_KEYS.footer,
11172
- LOGO_SIZE_MOBILE_KEYS.navbar,
11173
- LOGO_SIZE_MOBILE_KEYS.footer
11174
- ];
11175
- function isFooterLogoRoot2(root) {
11176
- return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
11177
- }
11178
- function getLogoPlacement(root) {
11179
- return isFooterLogoRoot2(root) ? "footer" : "navbar";
11180
- }
11181
- function parseLogoSizePx(raw, fallback) {
11182
- if (raw == null || raw === "") return fallback;
11183
- const n = Number.parseFloat(raw);
11184
- if (!Number.isFinite(n)) return fallback;
11185
- return Math.min(LOGO_SIZE_MAX, Math.max(LOGO_SIZE_MIN, Math.round(n)));
11186
- }
11187
- function isMobileLogoSizeFollowing(content, placement) {
11188
- const raw = content[LOGO_SIZE_MOBILE_KEYS[placement]];
11189
- return raw == null || raw.trim() === "";
11190
- }
11191
- function resolveDesktopLogoSize(content, placement) {
11192
- return parseLogoSizePx(content[LOGO_SIZE_DESKTOP_KEYS[placement]], LOGO_SIZE_DEFAULTS[placement]);
11193
- }
11194
- function resolveMobileLogoSize(content, placement) {
11195
- if (isMobileLogoSizeFollowing(content, placement)) {
11196
- return resolveDesktopLogoSize(content, placement);
11197
- }
11198
- return parseLogoSizePx(
11199
- content[LOGO_SIZE_MOBILE_KEYS[placement]],
11200
- resolveDesktopLogoSize(content, placement)
11201
- );
11202
- }
11203
- function setRootSizeVars(root, desktopPx, mobilePx, following) {
11204
- root.style.setProperty("--ohw-logo-size", `${desktopPx}px`);
11205
- if (following) {
11206
- root.style.removeProperty("--ohw-logo-size-mobile");
11207
- } else {
11208
- root.style.setProperty("--ohw-logo-size-mobile", `${mobilePx}px`);
11209
- }
11210
- root.querySelectorAll("img").forEach((img) => {
11211
- img.style.height = "";
11212
- img.style.maxHeight = "none";
11213
- img.style.width = "auto";
11214
- img.style.objectFit = "contain";
11215
- });
11216
- }
11217
- function applyLogoSizes(content) {
11218
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
11219
- const placement = getLogoPlacement(root);
11220
- const desktop = resolveDesktopLogoSize(content, placement);
11221
- const following = isMobileLogoSizeFollowing(content, placement);
11222
- const mobile = following ? desktop : resolveMobileLogoSize(content, placement);
11223
- setRootSizeVars(root, desktop, mobile, following);
11224
- });
11225
- }
11226
- function applyLogoSizeToPlacement(placement, desktopPx, mobilePx, following) {
11227
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
11228
- if (getLogoPlacement(root) !== placement) return;
11229
- setRootSizeVars(root, desktopPx, mobilePx, following);
11230
- });
11231
- }
11232
- function logoHasUploadedImage(logoEl) {
11233
- if (logoEl.hasAttribute("data-ohw-placeholder")) return false;
11234
- const img = logoEl.querySelector('img[data-ohw-key="nav-logo-image"], img[data-ohw-key="footer-logo"], img[data-ohw-key="footer-logo-image"]') ?? logoEl.querySelector("img");
11235
- if (!img) return false;
11236
- const src = img.getAttribute("src")?.trim() ?? "";
11237
- if (!src || src.startsWith("data:")) return false;
11238
- if (img.style.display === "none") return false;
11239
- return true;
11240
- }
11241
- function getLogoInteractionRect(logoEl) {
11242
- if (logoHasUploadedImage(logoEl)) {
11243
- const img = logoEl.querySelector('img[data-ohw-key="nav-logo-image"], img[data-ohw-key="footer-logo"], img[data-ohw-key="footer-logo-image"]') ?? logoEl.querySelector("img");
11244
- if (img) {
11245
- const r2 = img.getBoundingClientRect();
11246
- if (r2.width > 0 && r2.height > 0) return r2;
11247
- }
11248
- }
11249
- const text = logoEl.querySelector(
11250
- '[data-ohw-key="nav-logo-text"], [data-ohw-key="footer-logo-text"]'
11251
- );
11252
- if (text) {
11253
- const style = window.getComputedStyle(text);
11254
- if (style.display !== "none" && style.visibility !== "hidden") {
11255
- const r2 = text.getBoundingClientRect();
11256
- if (r2.width > 0 && r2.height > 0) return r2;
11257
- }
11258
- }
11259
- return logoEl.getBoundingClientRect();
11260
- }
11261
- function readLogoSizeState(content, placement) {
11262
- const desktopPx = resolveDesktopLogoSize(content, placement);
11263
- const mobileFollowing = isMobileLogoSizeFollowing(content, placement);
11264
- const mobilePx = mobileFollowing ? desktopPx : resolveMobileLogoSize(content, placement);
11265
- return { desktopPx, mobilePx, mobileFollowing };
11266
- }
11267
-
11268
- // src/lib/site-wide-scope.ts
11269
- function getLogoElement(el) {
11270
- const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
11271
- if (marked) return marked;
11272
- if (el.closest('[data-ohw-editable="icon"]')) return null;
11273
- const root = el.closest("nav, [data-ohw-nav-root], footer");
11274
- if (!root) return null;
11275
- const anchor = el.closest("a");
11276
- if (anchor && root.contains(anchor) && !anchor.hasAttribute("data-ohw-href-key") && !anchor.closest("[data-ohw-nav-container]") && Boolean(anchor.querySelector("img") || anchor.matches("img"))) {
11277
- return anchor;
11278
- }
11279
- const img = el.matches("img") ? el : null;
11280
- if (img && !img.closest("[data-ohw-href-key]") && !img.closest("[data-ohw-nav-container]") && (img.closest("footer") || img.closest("nav, [data-ohw-nav-root]"))) {
11281
- return img;
11282
- }
11283
- return null;
11284
- }
11285
- function isInFooter(el) {
11286
- if (!el) return false;
11287
- return Boolean(el.closest("footer") || el.closest('[data-ohw-section="footer"]'));
11288
- }
11289
- function isSiteWideElement(el) {
11290
- if (!el) return false;
11291
- if (getLogoElement(el)) return true;
11292
- if (isInFooter(el)) return true;
11293
- if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-root")) {
11294
- return true;
11295
- }
11296
- if (el.hasAttribute("data-ohw-href-key") && el.closest("nav, [data-ohw-nav-root], [data-ohw-nav-drawer], aside")) {
11297
- return true;
11298
- }
11299
- if (el.closest('[data-ohw-role="navbar-button"]')) return true;
11300
- return false;
11301
- }
11302
- function isSiteWideScopeActive(args) {
11303
- return isSiteWideElement(args.selected) || isSiteWideElement(args.hoveredItem) || isSiteWideElement(args.hoveredNavContainer) || isSiteWideElement(args.active);
11304
- }
11305
-
11306
10838
  // src/lib/add-footer-column.ts
11307
10839
  function buildFooterColumnEditContentPatch(result) {
11308
10840
  return {
@@ -11511,127 +11043,16 @@ function FloatingPanel({
11511
11043
  );
11512
11044
  }
11513
11045
 
11514
- // src/ui/logo-size-panel.tsx
11515
- var import_lucide_react14 = require("lucide-react");
11516
- var import_jsx_runtime27 = require("react/jsx-runtime");
11517
- function SizeSlider({
11518
- value,
11519
- onChange
11520
- }) {
11521
- const pct = (value - LOGO_SIZE_MIN) / (LOGO_SIZE_MAX - LOGO_SIZE_MIN) * 100;
11522
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex w-full flex-col gap-3", children: [
11523
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex w-full items-center gap-2 text-sm font-medium leading-5", children: [
11524
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "min-w-0 flex-1 text-foreground", children: "Size" }),
11525
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "shrink-0 whitespace-nowrap text-muted-foreground", children: [
11526
- value,
11527
- " px"
11528
- ] })
11529
- ] }),
11530
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "relative h-2 w-full rounded-full bg-primary-50", children: [
11531
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
11532
- "div",
11533
- {
11534
- className: "absolute inset-y-0 left-0 rounded-full bg-primary",
11535
- style: { width: `${pct}%` }
11536
- }
11537
- ),
11538
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
11539
- "input",
11540
- {
11541
- type: "range",
11542
- min: LOGO_SIZE_MIN,
11543
- max: LOGO_SIZE_MAX,
11544
- step: 1,
11545
- value,
11546
- "aria-label": "Logo size",
11547
- className: cn(
11548
- "absolute inset-0 h-full w-full cursor-pointer appearance-none bg-transparent",
11549
- "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:size-5",
11550
- "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2",
11551
- "[&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-background",
11552
- "[&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full",
11553
- "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary",
11554
- "[&::-moz-range-thumb]:bg-background"
11555
- ),
11556
- onChange: (e) => onChange(Number(e.target.value))
11557
- }
11558
- )
11559
- ] })
11560
- ] });
11561
- }
11562
- function LogoSizePanel({
11563
- viewport,
11564
- sizePx,
11565
- mobileFollowing = true,
11566
- onSizeChange,
11567
- onCustomizeMobile,
11568
- onResetMobile,
11569
- onUpdateEverywhere,
11570
- className
11571
- }) {
11572
- const showFollowing = viewport === "mobile" && mobileFollowing;
11573
- const showMobileSlider = viewport === "mobile" && !mobileFollowing;
11574
- const showDesktopSlider = viewport === "desktop";
11575
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: cn("flex w-full flex-col gap-4", className), children: [
11576
- showFollowing ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
11577
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-start gap-1", children: [
11578
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Link, { size: 16, className: "mt-0.5 shrink-0 text-foreground", "aria-hidden": true }),
11579
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-sm font-semibold leading-5 text-foreground", children: "Following desktop size" })
11580
- ] }),
11581
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-sm leading-5 text-muted-foreground", children: "Mobile uses the desktop size until you customize it. Change the desktop size and it follows automatically." }),
11582
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
11583
- Button,
11584
- {
11585
- type: "button",
11586
- variant: "outline",
11587
- size: "sm",
11588
- className: "h-9 w-full min-w-0 cursor-pointer",
11589
- onClick: onCustomizeMobile,
11590
- children: "Customize for mobile"
11591
- }
11592
- )
11593
- ] }) : null,
11594
- showDesktopSlider || showMobileSlider ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SizeSlider, { value: sizePx, onChange: onSizeChange }) : null,
11595
- showMobileSlider ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
11596
- Button,
11597
- {
11598
- type: "button",
11599
- variant: "outline",
11600
- size: "sm",
11601
- className: "h-9 w-full min-w-0 cursor-pointer",
11602
- onClick: onResetMobile,
11603
- children: "Reset to desktop size"
11604
- }
11605
- ) : null,
11606
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-px w-full bg-border", role: "separator" }),
11607
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
11608
- Button,
11609
- {
11610
- type: "button",
11611
- variant: "outline",
11612
- size: "sm",
11613
- className: "h-9 w-full min-w-0 cursor-pointer gap-1",
11614
- onClick: onUpdateEverywhere,
11615
- children: [
11616
- "Update logo everywhere",
11617
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.ArrowUpRight, { size: 16, "aria-hidden": true })
11618
- ]
11619
- }
11620
- ),
11621
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-sm leading-5 text-muted-foreground", children: "Matches the right version to your background." })
11622
- ] });
11623
- }
11624
-
11625
11046
  // src/ui/socials-display-panel.tsx
11626
- var import_jsx_runtime28 = require("react/jsx-runtime");
11047
+ var import_jsx_runtime27 = require("react/jsx-runtime");
11627
11048
  function DisplaySwitch({
11628
11049
  label,
11629
11050
  checked,
11630
11051
  disabled,
11631
11052
  onChange
11632
11053
  }) {
11633
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex w-full items-center gap-2", children: [
11634
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
11054
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex w-full items-center gap-2", children: [
11055
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
11635
11056
  "span",
11636
11057
  {
11637
11058
  className: cn(
@@ -11641,7 +11062,7 @@ function DisplaySwitch({
11641
11062
  children: label
11642
11063
  }
11643
11064
  ),
11644
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
11065
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
11645
11066
  "button",
11646
11067
  {
11647
11068
  type: "button",
@@ -11655,7 +11076,7 @@ function DisplaySwitch({
11655
11076
  checked ? "bg-primary" : "bg-primary-50",
11656
11077
  disabled ? "cursor-default opacity-50" : "cursor-pointer"
11657
11078
  ),
11658
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
11079
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
11659
11080
  "span",
11660
11081
  {
11661
11082
  className: cn(
@@ -11669,8 +11090,8 @@ function DisplaySwitch({
11669
11090
  ] });
11670
11091
  }
11671
11092
  function SocialsDisplayPanel({ display, onChange, className }) {
11672
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn("flex w-full flex-col gap-3", className), children: [
11673
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
11093
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: cn("flex w-full flex-col gap-3", className), children: [
11094
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
11674
11095
  DisplaySwitch,
11675
11096
  {
11676
11097
  label: "Text",
@@ -11679,7 +11100,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
11679
11100
  onChange: (text) => onChange({ ...display, text })
11680
11101
  }
11681
11102
  ),
11682
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
11103
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
11683
11104
  DisplaySwitch,
11684
11105
  {
11685
11106
  label: "Icon",
@@ -12239,8 +11660,8 @@ function useNavItemDrag({
12239
11660
  }
12240
11661
 
12241
11662
  // src/ui/footer-container-chrome.tsx
12242
- var import_lucide_react15 = require("lucide-react");
12243
- var import_jsx_runtime29 = require("react/jsx-runtime");
11663
+ var import_lucide_react14 = require("lucide-react");
11664
+ var import_jsx_runtime28 = require("react/jsx-runtime");
12244
11665
  function FooterContainerChrome({
12245
11666
  rect,
12246
11667
  onAdd,
@@ -12248,7 +11669,7 @@ function FooterContainerChrome({
12248
11669
  }) {
12249
11670
  const chromeGap = 6;
12250
11671
  const buttonMargin = 7;
12251
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
11672
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12252
11673
  "div",
12253
11674
  {
12254
11675
  "data-ohw-footer-container-chrome": "",
@@ -12260,8 +11681,8 @@ function FooterContainerChrome({
12260
11681
  width: rect.width + chromeGap * 2,
12261
11682
  height: rect.height + chromeGap * 2
12262
11683
  },
12263
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Tooltip, { children: [
12264
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
11684
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Tooltip, { children: [
11685
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12265
11686
  "button",
12266
11687
  {
12267
11688
  type: "button",
@@ -12280,10 +11701,10 @@ function FooterContainerChrome({
12280
11701
  if (addDisabled) return;
12281
11702
  onAdd();
12282
11703
  },
12283
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react15.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
11704
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react14.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
12284
11705
  }
12285
11706
  ) }),
12286
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
11707
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
12287
11708
  ] })
12288
11709
  }
12289
11710
  ) });
@@ -12466,18 +11887,6 @@ function collectEditableNodes(extraContent, root = document) {
12466
11887
  }
12467
11888
  if (extraContent && !isScoped) {
12468
11889
  applyNavFooterDeleteOverrides(byKey, extraContent);
12469
- for (const key of LOGO_IMAGE_KEYS) {
12470
- if (!(key in extraContent)) continue;
12471
- byKey.set(key, { key, type: "image", text: extraContent[key] ?? "" });
12472
- }
12473
- for (const key of [LOGO_PLACEHOLDER_KEY, LOGO_ALT_KEY]) {
12474
- if (!(key in extraContent)) continue;
12475
- byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
12476
- }
12477
- for (const key of LOGO_SIZE_KEYS) {
12478
- if (!(key in extraContent)) continue;
12479
- byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
12480
- }
12481
11890
  }
12482
11891
  return Array.from(byKey.values());
12483
11892
  }
@@ -12743,14 +12152,14 @@ function deleteSelectedNavFooterItem(deps) {
12743
12152
  }
12744
12153
 
12745
12154
  // src/ui/navbar-container-chrome.tsx
12746
- var import_lucide_react16 = require("lucide-react");
12747
- var import_jsx_runtime30 = require("react/jsx-runtime");
12155
+ var import_lucide_react15 = require("lucide-react");
12156
+ var import_jsx_runtime29 = require("react/jsx-runtime");
12748
12157
  function NavbarContainerChrome({
12749
12158
  rect,
12750
12159
  onAdd
12751
12160
  }) {
12752
12161
  const chromeGap = 6;
12753
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
12162
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
12754
12163
  "div",
12755
12164
  {
12756
12165
  "data-ohw-navbar-container-chrome": "",
@@ -12762,7 +12171,7 @@ function NavbarContainerChrome({
12762
12171
  width: rect.width + chromeGap * 2,
12763
12172
  height: rect.height + chromeGap * 2
12764
12173
  },
12765
- children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
12174
+ children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
12766
12175
  "button",
12767
12176
  {
12768
12177
  type: "button",
@@ -12779,7 +12188,7 @@ function NavbarContainerChrome({
12779
12188
  e.stopPropagation();
12780
12189
  onAdd();
12781
12190
  },
12782
- children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react16.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
12191
+ children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react15.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
12783
12192
  }
12784
12193
  )
12785
12194
  }
@@ -12788,7 +12197,7 @@ function NavbarContainerChrome({
12788
12197
 
12789
12198
  // src/ui/drop-indicator.tsx
12790
12199
  var React10 = __toESM(require("react"), 1);
12791
- var import_jsx_runtime31 = require("react/jsx-runtime");
12200
+ var import_jsx_runtime30 = require("react/jsx-runtime");
12792
12201
  var dropIndicatorVariants = cva(
12793
12202
  "ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
12794
12203
  {
@@ -12812,7 +12221,7 @@ var dropIndicatorVariants = cva(
12812
12221
  );
12813
12222
  var DropIndicator = React10.forwardRef(
12814
12223
  ({ className, direction, state, ...props }, ref) => {
12815
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
12224
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
12816
12225
  "div",
12817
12226
  {
12818
12227
  ref,
@@ -12829,7 +12238,7 @@ var DropIndicator = React10.forwardRef(
12829
12238
  DropIndicator.displayName = "DropIndicator";
12830
12239
 
12831
12240
  // src/ui/badge.tsx
12832
- var import_jsx_runtime32 = require("react/jsx-runtime");
12241
+ var import_jsx_runtime31 = require("react/jsx-runtime");
12833
12242
  var badgeVariants = cva(
12834
12243
  "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",
12835
12244
  {
@@ -12847,12 +12256,12 @@ var badgeVariants = cva(
12847
12256
  }
12848
12257
  );
12849
12258
  function Badge({ className, variant, ...props }) {
12850
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
12259
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
12851
12260
  }
12852
12261
 
12853
12262
  // src/OhhwellsBridge.tsx
12854
- var import_lucide_react17 = require("lucide-react");
12855
- var import_jsx_runtime33 = require("react/jsx-runtime");
12263
+ var import_lucide_react16 = require("lucide-react");
12264
+ var import_jsx_runtime32 = require("react/jsx-runtime");
12856
12265
  var PRIMARY3 = "#0885FE";
12857
12266
  var IMAGE_FADE_MS = 300;
12858
12267
  function runOpacityFade(el, onDone) {
@@ -12946,10 +12355,21 @@ function parseSchedulingInsertAfter(insertAfter) {
12946
12355
  insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
12947
12356
  };
12948
12357
  }
12949
- function resolveEntryAnchor(entry) {
12950
- if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
12951
- const parsed = parseSchedulingInsertAfter(entry.insertAfter);
12952
- return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
12358
+ function resolveSchedulingInsert(insertAfter, explicitInsertBefore) {
12359
+ const parsed = parseSchedulingInsertAfter(insertAfter);
12360
+ const insertBefore = explicitInsertBefore ?? parsed.insertBefore;
12361
+ const effectiveInsertAfter = insertBefore && parsed.insertBefore === null ? `${insertAfter}${INSERT_BEFORE_MARKER}${insertBefore}` : insertAfter;
12362
+ return { effectiveInsertAfter, insertBefore };
12363
+ }
12364
+ function getSchedulingMountPoint(insertAfter) {
12365
+ const { anchor } = parseSchedulingInsertAfter(insertAfter);
12366
+ let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
12367
+ if (!anchorEl && anchor === "scheduling") {
12368
+ const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
12369
+ anchorEl = widgets.at(-1) ?? null;
12370
+ }
12371
+ if (!anchorEl) return null;
12372
+ return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
12953
12373
  }
12954
12374
  function schedulingMountDepth(insertAfter) {
12955
12375
  if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
@@ -12966,7 +12386,8 @@ function getPageSchedulingEntries(raw) {
12966
12386
  }
12967
12387
  }
12968
12388
  function isSchedulingWidgetMissing(entry) {
12969
- return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
12389
+ const { effectiveInsertAfter } = resolveSchedulingInsert(entry.insertAfter);
12390
+ return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
12970
12391
  }
12971
12392
  function hasMissingSchedulingWidgets(entries) {
12972
12393
  return entries.some(isSchedulingWidgetMissing);
@@ -12996,17 +12417,16 @@ function initSectionsFromContent(content, removeExisting = false) {
12996
12417
  } catch {
12997
12418
  }
12998
12419
  }
12999
- function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
13000
- const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
13001
- const sectionId = schedulingSectionId(widgetId);
12420
+ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId, explicitInsertBefore) {
12421
+ const { effectiveInsertAfter, insertBefore } = resolveSchedulingInsert(insertAfter, explicitInsertBefore);
12422
+ const sectionId = schedulingSectionId(effectiveInsertAfter);
13002
12423
  if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
13003
- const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
13004
- if (!anchorEl) return false;
13005
- const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
12424
+ const mountPoint = getSchedulingMountPoint(effectiveInsertAfter);
12425
+ if (!mountPoint) return false;
13006
12426
  const container = document.createElement("div");
13007
12427
  container.dataset.ohwSectionContainer = "scheduling";
13008
- if (beforeId) {
13009
- const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
12428
+ if (insertBefore) {
12429
+ const beforeAnchor = document.querySelector(`[data-ohw-section="${insertBefore}"]`);
13010
12430
  const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
13011
12431
  if (!beforePoint) return false;
13012
12432
  beforePoint.insertAdjacentElement("beforebegin", container);
@@ -13017,25 +12437,19 @@ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, be
13017
12437
  }
13018
12438
  tail.insertAdjacentElement("afterend", container);
13019
12439
  }
13020
- try {
13021
- const root = (0, import_client2.createRoot)(container);
13022
- (0, import_react_dom3.flushSync)(() => {
13023
- root.render(
13024
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
13025
- SchedulingWidget,
13026
- {
13027
- notifyOnConnect,
13028
- initialScheduleId: scheduleId,
13029
- insertAfter: widgetId
13030
- }
13031
- )
13032
- );
13033
- });
13034
- } catch (err) {
13035
- console.error("[ow:scheduling] render threw", err);
13036
- container.remove();
13037
- return false;
13038
- }
12440
+ const root = (0, import_client2.createRoot)(container);
12441
+ (0, import_react_dom3.flushSync)(() => {
12442
+ root.render(
12443
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
12444
+ SchedulingWidget,
12445
+ {
12446
+ notifyOnConnect,
12447
+ initialScheduleId: scheduleId,
12448
+ insertAfter: effectiveInsertAfter
12449
+ }
12450
+ )
12451
+ );
12452
+ });
13039
12453
  const tracker = getSectionsTracker();
13040
12454
  let sections = [];
13041
12455
  try {
@@ -13043,12 +12457,10 @@ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, be
13043
12457
  } catch {
13044
12458
  }
13045
12459
  const inEditor = typeof window !== "undefined" && window.self !== window.top;
13046
- if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
12460
+ if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === effectiveInsertAfter)) {
13047
12461
  sections.push({
13048
12462
  type: "scheduling",
13049
- insertAfter: widgetId,
13050
- anchorId,
13051
- beforeId: beforeId ?? null,
12463
+ insertAfter: effectiveInsertAfter,
13052
12464
  pagePath: window.location.pathname,
13053
12465
  ...scheduleId ? { scheduleId } : {}
13054
12466
  });
@@ -13062,8 +12474,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
13062
12474
  for (let i = pending.length - 1; i >= 0; i--) {
13063
12475
  const entry = pending[i];
13064
12476
  const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
13065
- const { anchorId, beforeId } = resolveEntryAnchor(entry);
13066
- if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
12477
+ if (mountSchedulingWidget(entry.insertAfter, shouldNotify, entry.scheduleId)) {
13067
12478
  pending.splice(i, 1);
13068
12479
  }
13069
12480
  }
@@ -13207,13 +12618,6 @@ function isInsideLinkEditor(target) {
13207
12618
  target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest("[data-ohw-footer-container-chrome]") || target.closest("[data-ohw-footer-add-button]") || target.closest("[data-ohw-more-menu]") || target.closest('[data-slot="dropdown-menu-content"]') || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
13208
12619
  );
13209
12620
  }
13210
- function isInsideFloatingPanel(target) {
13211
- return Boolean(target.closest("[data-ohw-floating-panel]"));
13212
- }
13213
- function isPointOverFloatingPanel(clientX, clientY) {
13214
- const el = document.elementFromPoint(clientX, clientY);
13215
- return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
13216
- }
13217
12621
  function getHrefKeyFromElement(el) {
13218
12622
  if (!el) return null;
13219
12623
  const anchor = el.closest("[data-ohw-href-key]");
@@ -13446,7 +12850,7 @@ function getNavigationSelectionParent(el) {
13446
12850
  if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
13447
12851
  return getFooterLinksContainer();
13448
12852
  }
13449
- 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)) {
12853
+ if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
13450
12854
  return getNavigationRoot(el);
13451
12855
  }
13452
12856
  return null;
@@ -13689,7 +13093,7 @@ function EditGlowChrome({
13689
13093
  hideHandle = false
13690
13094
  }) {
13691
13095
  const GAP = SELECTION_CHROME_GAP2;
13692
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
13096
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
13693
13097
  "div",
13694
13098
  {
13695
13099
  ref: elRef,
@@ -13704,7 +13108,7 @@ function EditGlowChrome({
13704
13108
  zIndex: 2147483646
13705
13109
  },
13706
13110
  children: [
13707
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
13111
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
13708
13112
  "div",
13709
13113
  {
13710
13114
  style: {
@@ -13717,7 +13121,7 @@ function EditGlowChrome({
13717
13121
  }
13718
13122
  }
13719
13123
  ),
13720
- reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
13124
+ reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
13721
13125
  "div",
13722
13126
  {
13723
13127
  "data-ohw-drag-handle-container": "",
@@ -13729,7 +13133,7 @@ function EditGlowChrome({
13729
13133
  transform: "translate(calc(-100% - 7px), -50%)",
13730
13134
  pointerEvents: dragDisabled ? "none" : "auto"
13731
13135
  },
13732
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
13136
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
13733
13137
  DragHandle,
13734
13138
  {
13735
13139
  "aria-label": `Reorder ${reorderHrefKey}`,
@@ -13939,7 +13343,7 @@ function FloatingToolbar({
13939
13343
  return () => ro.disconnect();
13940
13344
  }, [showEditLink, activeCommands]);
13941
13345
  const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
13942
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
13346
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
13943
13347
  "div",
13944
13348
  {
13945
13349
  ref: setRefs,
@@ -13951,12 +13355,12 @@ function FloatingToolbar({
13951
13355
  zIndex: 2147483647,
13952
13356
  pointerEvents: "auto"
13953
13357
  },
13954
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(CustomToolbar, { children: [
13955
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_react16.default.Fragment, { children: [
13956
- gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CustomToolbarDivider, {}),
13358
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(CustomToolbar, { children: [
13359
+ TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react16.default.Fragment, { children: [
13360
+ gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CustomToolbarDivider, {}),
13957
13361
  btns.map((btn) => {
13958
13362
  const isActive = activeCommands.has(btn.cmd);
13959
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
13363
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
13960
13364
  CustomToolbarButton,
13961
13365
  {
13962
13366
  title: btn.title,
@@ -13965,7 +13369,7 @@ function FloatingToolbar({
13965
13369
  e.preventDefault();
13966
13370
  onCommand(btn.cmd);
13967
13371
  },
13968
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
13372
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
13969
13373
  "svg",
13970
13374
  {
13971
13375
  width: "16",
@@ -13986,7 +13390,7 @@ function FloatingToolbar({
13986
13390
  );
13987
13391
  })
13988
13392
  ] }, gi)),
13989
- showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
13393
+ showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
13990
13394
  CustomToolbarButton,
13991
13395
  {
13992
13396
  type: "button",
@@ -14000,7 +13404,7 @@ function FloatingToolbar({
14000
13404
  e.preventDefault();
14001
13405
  e.stopPropagation();
14002
13406
  },
14003
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react17.Link, { className: "size-4 shrink-0", "aria-hidden": true })
13407
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react16.Link, { className: "size-4 shrink-0", "aria-hidden": true })
14004
13408
  }
14005
13409
  ) : null
14006
13410
  ] })
@@ -14017,7 +13421,7 @@ function StateToggle({
14017
13421
  states,
14018
13422
  onStateChange
14019
13423
  }) {
14020
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
13424
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
14021
13425
  ToggleGroup,
14022
13426
  {
14023
13427
  "data-ohw-state-toggle": "",
@@ -14031,12 +13435,11 @@ function StateToggle({
14031
13435
  left: rect.right - 8,
14032
13436
  transform: "translateX(-100%)"
14033
13437
  },
14034
- children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
13438
+ children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
14035
13439
  }
14036
13440
  );
14037
13441
  }
14038
13442
  var contentCache = /* @__PURE__ */ new Map();
14039
- var fetchedContentPaths = /* @__PURE__ */ new Set();
14040
13443
  function resolveSubdomain(subdomainFromQuery) {
14041
13444
  if (subdomainFromQuery) return subdomainFromQuery;
14042
13445
  if (typeof window !== "undefined") {
@@ -14131,14 +13534,8 @@ function OhhwellsBridge() {
14131
13534
  });
14132
13535
  const selectFrameRef = (0, import_react16.useRef)(() => {
14133
13536
  });
14134
- const selectLogoRef = (0, import_react16.useRef)(() => {
14135
- });
14136
- const openLogoSizePanelRef = (0, import_react16.useRef)(() => {
14137
- });
14138
13537
  const deselectRef = (0, import_react16.useRef)(() => {
14139
13538
  });
14140
- const closeFloatingPanelOnlyRef = (0, import_react16.useRef)(() => {
14141
- });
14142
13539
  const reselectNavigationItemRef = (0, import_react16.useRef)(() => {
14143
13540
  });
14144
13541
  const commitNavigationTextEditRef = (0, import_react16.useRef)(() => {
@@ -14177,6 +13574,9 @@ function OhhwellsBridge() {
14177
13574
  const [isItemDragging, setIsItemDragging] = (0, import_react16.useState)(false);
14178
13575
  const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react16.useState)(false);
14179
13576
  isFooterFrameSelectionRef.current = isFooterFrameSelection;
13577
+ const [floatingPanel, setFloatingPanel] = (0, import_react16.useState)(null);
13578
+ const [floatingPanelPos, setFloatingPanelPos] = (0, import_react16.useState)(null);
13579
+ const [parentScrollSnap, setParentScrollSnap] = (0, import_react16.useState)(null);
14180
13580
  const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react16.useState)(null);
14181
13581
  const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react16.useState)(null);
14182
13582
  const footerDragRef = (0, import_react16.useRef)(null);
@@ -14191,15 +13591,7 @@ function OhhwellsBridge() {
14191
13591
  const addNavAfterAnchorRef = (0, import_react16.useRef)(null);
14192
13592
  const editContentRef = (0, import_react16.useRef)({});
14193
13593
  const aiSectionsRef = (0, import_react16.useRef)("");
14194
- const brandKitRef = (0, import_react16.useRef)("");
14195
13594
  const pendingDeleteUndoRef = (0, import_react16.useRef)(null);
14196
- const [floatingPanel, setFloatingPanel] = (0, import_react16.useState)(null);
14197
- const floatingPanelOpenRef = (0, import_react16.useRef)(false);
14198
- const setFloatingPanelRef = (0, import_react16.useRef)(setFloatingPanel);
14199
- const [floatingPanelPos, setFloatingPanelPos] = (0, import_react16.useState)(null);
14200
- const [logoSizeDraft, setLogoSizeDraft] = (0, import_react16.useState)(null);
14201
- const [editorViewport, setEditorViewport] = (0, import_react16.useState)("desktop");
14202
- const [parentScrollSnap, setParentScrollSnap] = (0, import_react16.useState)(null);
14203
13595
  const [sitePages, setSitePages] = (0, import_react16.useState)([]);
14204
13596
  const [sectionsByPath, setSectionsByPath] = (0, import_react16.useState)({});
14205
13597
  const sectionsPrefetchGenRef = (0, import_react16.useRef)(0);
@@ -14208,18 +13600,7 @@ function OhhwellsBridge() {
14208
13600
  const linkPopoverOpenRef = (0, import_react16.useRef)(false);
14209
13601
  const linkPopoverGraceUntilRef = (0, import_react16.useRef)(0);
14210
13602
  setLinkPopoverRef.current = setLinkPopover;
14211
- setFloatingPanelRef.current = setFloatingPanel;
14212
13603
  linkPopoverSessionRef.current = linkPopover;
14213
- floatingPanelOpenRef.current = Boolean(floatingPanel);
14214
- (0, import_react16.useEffect)(() => {
14215
- const syncViewport = () => {
14216
- const next = window.innerWidth <= 480 ? "mobile" : "desktop";
14217
- setEditorViewport((prev) => prev === next ? prev : next);
14218
- };
14219
- syncViewport();
14220
- window.addEventListener("resize", syncViewport);
14221
- return () => window.removeEventListener("resize", syncViewport);
14222
- }, []);
14223
13604
  const {
14224
13605
  navDragRef,
14225
13606
  navDropSlots,
@@ -14442,10 +13823,6 @@ function OhhwellsBridge() {
14442
13823
  setIsItemDragging(false);
14443
13824
  hoveredNavContainerRef.current = null;
14444
13825
  setHoveredNavContainerRect(null);
14445
- hoveredItemElRef.current = null;
14446
- setHoveredItemRect(null);
14447
- setFloatingPanel(null);
14448
- setLogoSizeDraft(null);
14449
13826
  if (!activeElRef.current) {
14450
13827
  setNavGroupForceOpen(null, false);
14451
13828
  setToolbarRect(null);
@@ -15137,8 +14514,6 @@ function OhhwellsBridge() {
15137
14514
  setToolbarRect(anchor.getBoundingClientRect());
15138
14515
  setToolbarShowEditLink(false);
15139
14516
  setActiveCommands(/* @__PURE__ */ new Set());
15140
- setFloatingPanel(null);
15141
- setLogoSizeDraft(null);
15142
14517
  }, [deactivate, markSelected]);
15143
14518
  const selectFrame = (0, import_react16.useCallback)((el) => {
15144
14519
  if (!isNavigationContainer(el)) return;
@@ -15188,52 +14563,7 @@ function OhhwellsBridge() {
15188
14563
  setToolbarRect(el.getBoundingClientRect());
15189
14564
  setToolbarShowEditLink(false);
15190
14565
  setActiveCommands(/* @__PURE__ */ new Set());
15191
- setFloatingPanel(null);
15192
- setLogoSizeDraft(null);
15193
14566
  }, [deactivate, markSelected, postToParent2]);
15194
- const selectLogo = (0, import_react16.useCallback)(
15195
- (logoEl) => {
15196
- if (activeElRef.current) deactivate();
15197
- selectedElRef.current = logoEl;
15198
- selectedHrefKeyRef.current = null;
15199
- selectedFooterColAttrRef.current = null;
15200
- markSelected(logoEl);
15201
- setSelectedIsCta(false);
15202
- setSelectedIsSocial(false);
15203
- setSelectedIsSocialsRow(false);
15204
- setSelectedIsSocialsRow(false);
15205
- clearHrefKeyHover(logoEl);
15206
- hoveredNavContainerRef.current = null;
15207
- setHoveredNavContainerRect(null);
15208
- setHoveredItemRect(null);
15209
- hoveredItemElRef.current = null;
15210
- siblingHintElRef.current = null;
15211
- setSiblingHintRect(null);
15212
- setSiblingHintRects([]);
15213
- setIsItemDragging(false);
15214
- setReorderHrefKey(null);
15215
- setReorderDragDisabled(false);
15216
- setIsFooterFrameSelection(false);
15217
- setToolbarVariant("logo");
15218
- setToolbarRect(getLogoInteractionRect(logoEl));
15219
- setToolbarShowEditLink(false);
15220
- setActiveCommands(/* @__PURE__ */ new Set());
15221
- },
15222
- [deactivate, markSelected]
15223
- );
15224
- const openLogoSizePanel = (0, import_react16.useCallback)((logoEl) => {
15225
- const placement = getLogoPlacement(logoEl);
15226
- const draft = readLogoSizeState(editContentRef.current, placement);
15227
- setLogoSizeDraft(draft);
15228
- setParentScrollSnap(parentScrollRef.current);
15229
- setFloatingPanel({
15230
- key: `logo-size:${placement}`,
15231
- title: "Logo",
15232
- context: placement === "navbar" ? "Navbar" : "Footer",
15233
- kind: "logo-size",
15234
- placement
15235
- });
15236
- }, []);
15237
14567
  const openSocialsDisplayPanel = (0, import_react16.useCallback)((row) => {
15238
14568
  setParentScrollSnap(parentScrollRef.current);
15239
14569
  setFloatingPanel({
@@ -15269,53 +14599,11 @@ function OhhwellsBridge() {
15269
14599
  );
15270
14600
  const closeFloatingPanelOnly = (0, import_react16.useCallback)(() => {
15271
14601
  setFloatingPanel(null);
15272
- setLogoSizeDraft(null);
15273
14602
  }, []);
15274
14603
  const closeFloatingPanelAndDeselect = (0, import_react16.useCallback)(() => {
15275
14604
  setFloatingPanel(null);
15276
- setLogoSizeDraft(null);
15277
14605
  deselectRef.current();
15278
14606
  }, []);
15279
- const persistLogoSizeDraft = (0, import_react16.useCallback)(
15280
- (placement, draft) => {
15281
- const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
15282
- const mobileKey = LOGO_SIZE_MOBILE_KEYS[placement];
15283
- const nodes = [
15284
- { key: desktopKey, text: String(draft.desktopPx) }
15285
- ];
15286
- if (draft.mobileFollowing) {
15287
- nodes.push({ key: mobileKey, text: "" });
15288
- } else {
15289
- nodes.push({ key: mobileKey, text: String(draft.mobilePx) });
15290
- }
15291
- editContentRef.current = {
15292
- ...editContentRef.current,
15293
- [desktopKey]: String(draft.desktopPx),
15294
- [mobileKey]: draft.mobileFollowing ? "" : String(draft.mobilePx)
15295
- };
15296
- applyLogoSizeToPlacement(
15297
- placement,
15298
- draft.desktopPx,
15299
- draft.mobileFollowing ? draft.desktopPx : draft.mobilePx,
15300
- draft.mobileFollowing
15301
- );
15302
- postToParent2({ type: "ow:change", nodes });
15303
- requestAnimationFrame(() => {
15304
- const selected = selectedElRef.current;
15305
- if (!selected || toolbarVariantRef.current !== "logo") return;
15306
- const rect = getLogoInteractionRect(selected);
15307
- setToolbarRect(rect);
15308
- if (glowElRef.current) {
15309
- const GAP = SELECTION_CHROME_GAP2;
15310
- glowElRef.current.style.top = `${rect.top - GAP}px`;
15311
- glowElRef.current.style.left = `${rect.left - GAP}px`;
15312
- glowElRef.current.style.width = `${rect.width + GAP * 2}px`;
15313
- glowElRef.current.style.height = `${rect.height + GAP * 2}px`;
15314
- }
15315
- });
15316
- },
15317
- [postToParent2]
15318
- );
15319
14607
  const activate = (0, import_react16.useCallback)((el, options) => {
15320
14608
  if (activeElRef.current === el) return;
15321
14609
  if (isIconEditable(el)) return;
@@ -15396,37 +14684,7 @@ function OhhwellsBridge() {
15396
14684
  deactivateRef.current = deactivate;
15397
14685
  selectRef.current = select;
15398
14686
  selectFrameRef.current = selectFrame;
15399
- selectLogoRef.current = selectLogo;
15400
- openLogoSizePanelRef.current = openLogoSizePanel;
15401
14687
  deselectRef.current = deselect;
15402
- closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
15403
- const lastSiteWideScopeRef = (0, import_react16.useRef)(null);
15404
- (0, import_react16.useEffect)(() => {
15405
- if (!isEditMode) {
15406
- if (lastSiteWideScopeRef.current !== false) {
15407
- lastSiteWideScopeRef.current = false;
15408
- postToParent2({ type: "ow:site-wide-scope", active: false });
15409
- }
15410
- return;
15411
- }
15412
- const active = isSiteWideScopeActive({
15413
- selected: selectedElRef.current,
15414
- hoveredItem: hoveredItemElRef.current,
15415
- hoveredNavContainer: hoveredNavContainerRef.current,
15416
- active: activeElRef.current
15417
- });
15418
- if (lastSiteWideScopeRef.current === active) return;
15419
- lastSiteWideScopeRef.current = active;
15420
- postToParent2({ type: "ow:site-wide-scope", active });
15421
- }, [
15422
- isEditMode,
15423
- hoveredItemRect,
15424
- hoveredNavContainerRect,
15425
- toolbarVariant,
15426
- toolbarRect,
15427
- isFooterFrameSelection,
15428
- postToParent2
15429
- ]);
15430
14688
  (0, import_react16.useLayoutEffect)(() => {
15431
14689
  if (!subdomain || isEditMode) {
15432
14690
  setFetchState("done");
@@ -15438,18 +14696,9 @@ function OhhwellsBridge() {
15438
14696
  aiSectionsRef.current = content[AI_SECTIONS_KEY];
15439
14697
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
15440
14698
  }
15441
- if (typeof content[BRAND_KIT_KEY] === "string") {
15442
- brandKitRef.current = content[BRAND_KIT_KEY];
15443
- applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
15444
- }
15445
- applyBrandChrome(content);
15446
14699
  for (const [key, val] of Object.entries(content)) {
15447
14700
  if (key === "__ohw_sections") continue;
15448
14701
  if (key === AI_SECTIONS_KEY) continue;
15449
- if (key === LOGO_PLACEHOLDER_KEY) continue;
15450
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
15451
- if (key === BRAND_KIT_KEY) continue;
15452
- if (BRAND_CHROME_KEYS.has(key)) continue;
15453
14702
  if (applyVideoSettingNode(key, val)) continue;
15454
14703
  if (applyCarouselNode(key, val)) continue;
15455
14704
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -15484,8 +14733,6 @@ function OhhwellsBridge() {
15484
14733
  });
15485
14734
  applyLinkByKey(key, val);
15486
14735
  }
15487
- applyLogoFromContent(content);
15488
- applyLogoSizes(content);
15489
14736
  reconcileNavbarItemsFromContent(content);
15490
14737
  reconcileFooterOrderFromContent(content);
15491
14738
  reconcileSocialsFromContent(content);
@@ -15505,9 +14752,7 @@ function OhhwellsBridge() {
15505
14752
  let cancelled = false;
15506
14753
  setFetchState("loading");
15507
14754
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
15508
- const initialPath = pathname;
15509
- fetchedContentPaths.add(`${subdomain}::${initialPath}`);
15510
- fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
14755
+ fetch(`${apiUrl}/api/public/sites/${subdomain}/content`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
15511
14756
  if (cancelled) return;
15512
14757
  const content = data?.content ?? {};
15513
14758
  contentCache.set(subdomain, content);
@@ -15530,16 +14775,8 @@ function OhhwellsBridge() {
15530
14775
  retryMissingSchedulingMounts(getPageSchedulingEntries(content["__ohw_sections"]), false);
15531
14776
  observer?.disconnect();
15532
14777
  try {
15533
- applyBrandChrome(content);
15534
- if (typeof content[BRAND_KIT_KEY] === "string") {
15535
- applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
15536
- }
15537
14778
  for (const [key, val] of Object.entries(content)) {
15538
14779
  if (key === "__ohw_sections") continue;
15539
- if (key === LOGO_PLACEHOLDER_KEY) continue;
15540
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
15541
- if (key === BRAND_KIT_KEY) continue;
15542
- if (BRAND_CHROME_KEYS.has(key)) continue;
15543
14780
  if (applyVideoSettingNode(key, val)) continue;
15544
14781
  if (applyCarouselNode(key, val)) continue;
15545
14782
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -15560,7 +14797,6 @@ function OhhwellsBridge() {
15560
14797
  });
15561
14798
  applyLinkByKey(key, val);
15562
14799
  }
15563
- applyLogoFromContent(content);
15564
14800
  reconcileNavbarItemsFromContent(content);
15565
14801
  reconcileFooterOrderFromContent(content);
15566
14802
  reconcileSocialsFromContent(content);
@@ -15575,17 +14811,6 @@ function OhhwellsBridge() {
15575
14811
  debounceTimer = setTimeout(applyFromCache, 150);
15576
14812
  };
15577
14813
  applyFromCache();
15578
- const pathCacheKey = `${subdomain}::${pathname}`;
15579
- if (!fetchedContentPaths.has(pathCacheKey)) {
15580
- fetchedContentPaths.add(pathCacheKey);
15581
- const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
15582
- fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
15583
- if (!data?.content) return;
15584
- contentCache.set(subdomain, data.content);
15585
- applyFromCache();
15586
- }).catch(() => {
15587
- });
15588
- }
15589
14814
  observer = new MutationObserver(scheduleApply);
15590
14815
  observer.observe(document.body, { childList: true, subtree: true });
15591
14816
  return () => {
@@ -15645,7 +14870,7 @@ function OhhwellsBridge() {
15645
14870
  reconcileSocialsFromContent(content);
15646
14871
  applySocialsDisplayFromContent(content);
15647
14872
  document.querySelectorAll("footer [data-ohw-href-key]").forEach((el) => {
15648
- if (isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) {
14873
+ if (isFooterHrefKey(el.getAttribute("data-ohw-href-key")) || getSocialItem(el)) {
15649
14874
  disableNativeHrefDrag(el);
15650
14875
  }
15651
14876
  });
@@ -15679,31 +14904,26 @@ function OhhwellsBridge() {
15679
14904
  }, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
15680
14905
  (0, import_react16.useEffect)(() => {
15681
14906
  if (!isEditMode) return;
15682
- let lastPosted = 0;
15683
14907
  const measure = () => {
15684
14908
  const h = document.body.scrollHeight;
15685
- if (h > 50 && Math.abs(h - lastPosted) > 1) {
15686
- lastPosted = h;
15687
- postToParent2({ type: "ow:height", height: h });
15688
- }
15689
- };
15690
- let raf = null;
15691
- const schedule = () => {
15692
- if (raf != null) return;
15693
- raf = requestAnimationFrame(() => {
15694
- raf = null;
15695
- measure();
15696
- });
14909
+ if (h > 50) postToParent2({ type: "ow:height", height: h });
15697
14910
  };
15698
14911
  const t1 = setTimeout(measure, 50);
15699
14912
  const t2 = setTimeout(measure, 500);
15700
- const ro = new ResizeObserver(schedule);
15701
- ro.observe(document.body);
14913
+ let lastWidth = window.innerWidth;
14914
+ let resizeTimer = null;
14915
+ const handleResize = () => {
14916
+ if (window.innerWidth === lastWidth) return;
14917
+ lastWidth = window.innerWidth;
14918
+ if (resizeTimer) clearTimeout(resizeTimer);
14919
+ resizeTimer = setTimeout(measure, 150);
14920
+ };
14921
+ window.addEventListener("resize", handleResize);
15702
14922
  return () => {
15703
14923
  clearTimeout(t1);
15704
14924
  clearTimeout(t2);
15705
- if (raf != null) cancelAnimationFrame(raf);
15706
- ro.disconnect();
14925
+ if (resizeTimer) clearTimeout(resizeTimer);
14926
+ window.removeEventListener("resize", handleResize);
15707
14927
  };
15708
14928
  }, [pathname, isEditMode, postToParent2]);
15709
14929
  (0, import_react16.useEffect)(() => {
@@ -15851,7 +15071,6 @@ function OhhwellsBridge() {
15851
15071
  if (target.closest("[data-ohw-state-toggle]")) return;
15852
15072
  if (target.closest("[data-ohw-max-badge]")) return;
15853
15073
  if (isInsideLinkEditor(target)) return;
15854
- if (isInsideFloatingPanel(target)) return;
15855
15074
  if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
15856
15075
  const beneath = document.elementsFromPoint(e.clientX, e.clientY).find(
15857
15076
  (el) => el instanceof HTMLElement && !el.closest("[data-ohw-bridge-root]") && el.closest("[data-ohw-section]") != null
@@ -15915,21 +15134,6 @@ function OhhwellsBridge() {
15915
15134
  return;
15916
15135
  }
15917
15136
  }
15918
- const logoEl = getLogoElement(target);
15919
- if (logoEl) {
15920
- e.preventDefault();
15921
- e.stopPropagation();
15922
- if (!logoHasUploadedImage(logoEl)) {
15923
- deselectRef.current();
15924
- deactivateRef.current();
15925
- const identity = readLogoIdentityFromDom();
15926
- postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
15927
- return;
15928
- }
15929
- selectLogoRef.current(logoEl);
15930
- openLogoSizePanelRef.current(logoEl);
15931
- return;
15932
- }
15933
15137
  const editable = target.closest("[data-ohw-editable]");
15934
15138
  if (editable) {
15935
15139
  if (editable.dataset.ohwEditable === "link") {
@@ -16082,7 +15286,6 @@ function OhhwellsBridge() {
16082
15286
  if (target.closest("[data-ohw-state-toggle]")) return;
16083
15287
  if (target.closest("[data-ohw-max-badge]")) return;
16084
15288
  if (isInsideLinkEditor(target)) return;
16085
- if (isInsideFloatingPanel(target)) return;
16086
15289
  if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
16087
15290
  return;
16088
15291
  }
@@ -16110,16 +15313,6 @@ function OhhwellsBridge() {
16110
15313
  setHoveredNavContainerRect(null);
16111
15314
  return;
16112
15315
  }
16113
- if (isInsideFloatingPanel(target) || isPointOverFloatingPanel(e.clientX, e.clientY)) {
16114
- hoveredItemElRef.current = null;
16115
- setHoveredItemRect(null);
16116
- hoveredNavContainerRef.current = null;
16117
- setHoveredNavContainerRect(null);
16118
- siblingHintElRef.current = null;
16119
- setSiblingHintRect(null);
16120
- setSiblingHintRects([]);
16121
- return;
16122
- }
16123
15316
  {
16124
15317
  const selected2 = selectedElRef.current;
16125
15318
  const selectedIsFooterColumn = Boolean(selected2) && !isFooterLinksContainer(selected2) && (selected2.hasAttribute("data-ohw-footer-col") || selected2.hasAttribute("data-ohw-footer-column") || Boolean(selected2.closest("footer") && isInferredFooterGroup2(selected2)));
@@ -16127,7 +15320,7 @@ function OhhwellsBridge() {
16127
15320
  const allowFooterLinksHover = toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn;
16128
15321
  if (allowNavContainerHover) {
16129
15322
  const navContainer = target.closest("[data-ohw-nav-container]");
16130
- if (navContainer && !getNavigationItemAnchor(target) && !getLogoElement(target)) {
15323
+ if (navContainer && !getNavigationItemAnchor(target)) {
16131
15324
  hoveredNavContainerRef.current = navContainer;
16132
15325
  setHoveredNavContainerRect(navContainer.getBoundingClientRect());
16133
15326
  hoveredItemElRef.current = null;
@@ -16156,15 +15349,6 @@ function OhhwellsBridge() {
16156
15349
  setHoveredNavContainerRect(null);
16157
15350
  }
16158
15351
  }
16159
- const logoEl = getLogoElement(target);
16160
- if (logoEl) {
16161
- hoveredNavContainerRef.current = null;
16162
- setHoveredNavContainerRect(null);
16163
- if (selectedElRef.current === logoEl) return;
16164
- hoveredItemElRef.current = logoEl;
16165
- setHoveredItemRect(getLogoInteractionRect(logoEl));
16166
- return;
16167
- }
16168
15352
  const navAnchor = getNavigationItemAnchor(target);
16169
15353
  if (navAnchor) {
16170
15354
  hoveredNavContainerRef.current = null;
@@ -16202,12 +15386,6 @@ function OhhwellsBridge() {
16202
15386
  setHoveredItemRect(hoverTarget.getBoundingClientRect());
16203
15387
  } else if (!isInsideNavigationItem(editable)) {
16204
15388
  hoverTarget.setAttribute("data-ohw-hovered", "");
16205
- if (editable.closest("footer") || editable.closest('[data-ohw-section="footer"]')) {
16206
- hoveredNavContainerRef.current = null;
16207
- setHoveredNavContainerRect(null);
16208
- hoveredItemElRef.current = editable;
16209
- setHoveredItemRect(editable.getBoundingClientRect());
16210
- }
16211
15389
  }
16212
15390
  }
16213
15391
  };
@@ -16243,18 +15421,6 @@ function OhhwellsBridge() {
16243
15421
  }
16244
15422
  return;
16245
15423
  }
16246
- const logoEl = getLogoElement(target);
16247
- if (logoEl) {
16248
- const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
16249
- if (related2 && (logoEl === related2 || logoEl.contains(related2) || related2.closest?.('[data-ohw-role="logo"], [data-ohw-logo]'))) {
16250
- return;
16251
- }
16252
- if (hoveredItemElRef.current === logoEl) {
16253
- hoveredItemElRef.current = null;
16254
- setHoveredItemRect(null);
16255
- }
16256
- return;
16257
- }
16258
15424
  const editable = target.closest("[data-ohw-editable]");
16259
15425
  if (!editable) return;
16260
15426
  const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
@@ -16275,13 +15441,6 @@ function OhhwellsBridge() {
16275
15441
  }
16276
15442
  } else {
16277
15443
  hoverTarget.removeAttribute("data-ohw-hovered");
16278
- if (hoveredItemElRef.current === editable) {
16279
- const stillOnEditable = related instanceof Element && related.closest("[data-ohw-editable]") === editable;
16280
- if (!stillOnEditable) {
16281
- hoveredItemElRef.current = null;
16282
- setHoveredItemRect(null);
16283
- }
16284
- }
16285
15444
  }
16286
15445
  }
16287
15446
  };
@@ -16398,26 +15557,6 @@ function OhhwellsBridge() {
16398
15557
  hoveredNavContainerRef.current = null;
16399
15558
  setHoveredNavContainerRect(null);
16400
15559
  }
16401
- const logoCandidates = [
16402
- ...document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]'),
16403
- ...document.querySelectorAll("nav a:not([data-ohw-href-key]), [data-ohw-nav-root] a:not([data-ohw-href-key])"),
16404
- ...document.querySelectorAll("footer img")
16405
- ];
16406
- const seenLogos = /* @__PURE__ */ new Set();
16407
- for (const candidate of logoCandidates) {
16408
- const logo = getLogoElement(candidate);
16409
- if (!logo || seenLogos.has(logo)) continue;
16410
- seenLogos.add(logo);
16411
- const r2 = logo.getBoundingClientRect();
16412
- if (x < r2.left || x > r2.right || y < r2.top || y > r2.bottom) continue;
16413
- hoveredNavContainerRef.current = null;
16414
- setHoveredNavContainerRect(null);
16415
- if (selectedElRef.current !== logo) {
16416
- hoveredItemElRef.current = logo;
16417
- setHoveredItemRect(getLogoInteractionRect(logo));
16418
- }
16419
- return;
16420
- }
16421
15560
  const navContainers = Array.from(
16422
15561
  document.querySelectorAll("[data-ohw-nav-container]")
16423
15562
  );
@@ -16503,7 +15642,7 @@ function OhhwellsBridge() {
16503
15642
  }
16504
15643
  };
16505
15644
  const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
16506
- if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
15645
+ if (linkPopoverOpenRef.current) {
16507
15646
  if (hoveredImageRef.current) {
16508
15647
  hoveredImageRef.current = null;
16509
15648
  hoveredImageHasTextOverlapRef.current = false;
@@ -16757,7 +15896,7 @@ function OhhwellsBridge() {
16757
15896
  }
16758
15897
  };
16759
15898
  const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
16760
- if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY) || document.documentElement.hasAttribute("data-ohw-section-picking")) {
15899
+ if (linkPopoverOpenRef.current || document.documentElement.hasAttribute("data-ohw-section-picking")) {
16761
15900
  if (activeStateElRef.current) {
16762
15901
  activeStateElRef.current.removeAttribute("data-ohw-state-hovered");
16763
15902
  activeStateElRef.current = null;
@@ -16825,19 +15964,6 @@ function OhhwellsBridge() {
16825
15964
  };
16826
15965
  const handleMouseMove = (e) => {
16827
15966
  const { clientX, clientY } = e;
16828
- if (floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
16829
- hoveredItemElRef.current = null;
16830
- setHoveredItemRect(null);
16831
- hoveredNavContainerRef.current = null;
16832
- setHoveredNavContainerRect(null);
16833
- siblingHintElRef.current = null;
16834
- setSiblingHintRect(null);
16835
- setSiblingHintRects([]);
16836
- dismissImageHover();
16837
- clearImageHover();
16838
- setSectionGap(null);
16839
- return;
16840
- }
16841
15967
  probeSectionGapAt(clientX, clientY);
16842
15968
  probeImageAt(clientX, clientY);
16843
15969
  probeHoverCardsAt(clientX, clientY);
@@ -16846,11 +15972,6 @@ function OhhwellsBridge() {
16846
15972
  if (e.data?.type !== "ow:pointer-sync") return;
16847
15973
  const { clientX, clientY } = e.data;
16848
15974
  if (typeof clientX !== "number" || typeof clientY !== "number") return;
16849
- if (floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
16850
- dismissImageHover();
16851
- clearImageHover();
16852
- return;
16853
- }
16854
15975
  probeSectionGapAt(clientX, clientY);
16855
15976
  probeImageAt(clientX, clientY);
16856
15977
  probeHoverCardsAt(clientX, clientY);
@@ -17100,11 +16221,6 @@ function OhhwellsBridge() {
17100
16221
  aiSectionsRef.current = content[AI_SECTIONS_KEY];
17101
16222
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
17102
16223
  }
17103
- if (typeof content[BRAND_KIT_KEY] === "string") {
17104
- brandKitRef.current = content[BRAND_KIT_KEY];
17105
- applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
17106
- }
17107
- applyBrandChrome(content);
17108
16224
  let sectionsJson = null;
17109
16225
  for (const [key, val] of Object.entries(content)) {
17110
16226
  if (key === "__ohw_sections") {
@@ -17112,10 +16228,6 @@ function OhhwellsBridge() {
17112
16228
  continue;
17113
16229
  }
17114
16230
  if (key === AI_SECTIONS_KEY) continue;
17115
- if (key === LOGO_PLACEHOLDER_KEY) continue;
17116
- if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
17117
- if (key === BRAND_KIT_KEY) continue;
17118
- if (BRAND_CHROME_KEYS.has(key)) continue;
17119
16231
  if (applyVideoSettingNode(key, val)) continue;
17120
16232
  if (applyCarouselNode(key, val)) continue;
17121
16233
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -17135,8 +16247,6 @@ function OhhwellsBridge() {
17135
16247
  });
17136
16248
  applyLinkByKey(key, val);
17137
16249
  }
17138
- applyLogoFromContent(content);
17139
- applyLogoSizes(content);
17140
16250
  if (sectionsJson) {
17141
16251
  initSectionsFromContent({ __ohw_sections: sectionsJson }, true);
17142
16252
  sectionsLoadedRef.current = true;
@@ -17151,58 +16261,6 @@ function OhhwellsBridge() {
17151
16261
  if (hydratedHeight > 50) postToParentRef.current({ type: "ow:height", height: hydratedHeight });
17152
16262
  postToParentRef.current({ type: "ow:hydrate-done" });
17153
16263
  };
17154
- const handleUpdateLogoIdentity = (e) => {
17155
- if (e.data?.type !== "ow:update-logo-identity") return;
17156
- const rawText = typeof e.data.text === "string" ? e.data.text : "";
17157
- const alt = typeof e.data.alt === "string" ? e.data.alt : rawText;
17158
- const href = typeof e.data.href === "string" ? e.data.href : void 0;
17159
- const imageProvided = "image" in e.data;
17160
- const imageUrl = imageProvided && typeof e.data.image === "string" && e.data.image.trim() ? e.data.image.trim() : imageProvided ? null : void 0;
17161
- let isPlaceholder = e.data.isPlaceholder !== false;
17162
- if (imageUrl) isPlaceholder = false;
17163
- else if (imageProvided && imageUrl === null) {
17164
- isPlaceholder = e.data.isPlaceholder === true || !rawText.trim() || resolveLogoDisplayText(rawText) === PLACEHOLDER_BUSINESS_NAME;
17165
- }
17166
- const display = applyLogoIdentity(rawText, isPlaceholder);
17167
- const displayAlt = resolveLogoDisplayText(alt || display);
17168
- if (imageUrl !== void 0) {
17169
- applyLogoImage(imageUrl, displayAlt);
17170
- } else {
17171
- for (const key of LOGO_IMAGE_KEYS) {
17172
- document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
17173
- const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
17174
- if (img) img.alt = displayAlt;
17175
- });
17176
- }
17177
- }
17178
- if (href !== void 0) {
17179
- applyLogoHref(href);
17180
- applyLinkByKey("nav-logo-href", href);
17181
- applyLinkByKey("footer-logo-href", href);
17182
- applyLinkByKey("logo-href", href);
17183
- }
17184
- const nodes = [
17185
- ...LOGO_TEXT_KEYS.map((key) => ({ key, text: display })),
17186
- { key: LOGO_PLACEHOLDER_KEY, text: isPlaceholder ? "true" : "false" },
17187
- { key: LOGO_ALT_KEY, text: displayAlt }
17188
- ];
17189
- if (imageUrl !== void 0) {
17190
- if (imageUrl) {
17191
- for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: imageUrl });
17192
- } else {
17193
- for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: "" });
17194
- }
17195
- }
17196
- if (href !== void 0) {
17197
- for (const key of LOGO_HREF_KEYS) nodes.push({ key, text: href.trim() || "/" });
17198
- }
17199
- editContentRef.current = {
17200
- ...editContentRef.current,
17201
- ...Object.fromEntries(nodes.map(({ key, text }) => [key, text]))
17202
- };
17203
- applyLogoSizes(editContentRef.current);
17204
- postToParentRef.current({ type: "ow:change", nodes });
17205
- };
17206
16264
  window.addEventListener("message", handleHydrate);
17207
16265
  const postAiSectionsChanged = () => {
17208
16266
  postToParentRef.current({
@@ -17259,17 +16317,6 @@ function OhhwellsBridge() {
17259
16317
  postAiSectionsChanged();
17260
16318
  };
17261
16319
  window.addEventListener("message", handleAiSetSections);
17262
- const handleAiSetBrand = (e) => {
17263
- if (e.data?.type !== "ow:ai-set-brand") return;
17264
- const value = typeof e.data.value === "string" ? e.data.value : "";
17265
- const previous = brandKitRef.current;
17266
- brandKitRef.current = value;
17267
- applyBrandToDom(parseBrandKit(value));
17268
- if (aiSectionsRef.current) applyAiSectionsToDom(parseAiSectionsState(aiSectionsRef.current));
17269
- postToParentRef.current({ type: "ow:change", nodes: [{ key: BRAND_KIT_KEY, text: value }] });
17270
- postToParentRef.current({ type: "ow:ai-brand-applied", previous, value });
17271
- };
17272
- window.addEventListener("message", handleAiSetBrand);
17273
16320
  const handleDeactivate = (e) => {
17274
16321
  if (e.data?.type !== "ow:deactivate") return;
17275
16322
  if (Date.now() < linkPopoverGraceUntilRef.current) return;
@@ -17278,12 +16325,6 @@ function OhhwellsBridge() {
17278
16325
  closeLinkPopoverRef.current();
17279
16326
  return;
17280
16327
  }
17281
- if (floatingPanelOpenRef.current) {
17282
- setFloatingPanelRef.current(null);
17283
- deselectRef.current();
17284
- deactivateRef.current();
17285
- return;
17286
- }
17287
16328
  deselectRef.current();
17288
16329
  deactivateRef.current();
17289
16330
  };
@@ -17303,10 +16344,6 @@ function OhhwellsBridge() {
17303
16344
  closeLinkPopoverRef.current();
17304
16345
  return;
17305
16346
  }
17306
- if (floatingPanelOpenRef.current) {
17307
- closeFloatingPanelOnlyRef.current();
17308
- return;
17309
- }
17310
16347
  if (activeElRef.current) {
17311
16348
  const hrefCtx = getHrefKeyFromElement(activeElRef.current);
17312
16349
  const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
@@ -17337,10 +16374,6 @@ function OhhwellsBridge() {
17337
16374
  return;
17338
16375
  }
17339
16376
  if (selectedElRef.current) {
17340
- if (toolbarVariantRef.current === "logo") {
17341
- deselectRef.current();
17342
- return;
17343
- }
17344
16377
  if (toolbarVariantRef.current === "select-frame") {
17345
16378
  const parent2 = getNavigationSelectionParent(selectedElRef.current);
17346
16379
  if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
@@ -17374,16 +16407,7 @@ function OhhwellsBridge() {
17374
16407
  closeLinkPopoverRef.current();
17375
16408
  return;
17376
16409
  }
17377
- if (e.key === "Escape" && floatingPanelOpenRef.current) {
17378
- e.preventDefault();
17379
- closeFloatingPanelOnlyRef.current();
17380
- return;
17381
- }
17382
16410
  if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
17383
- if (toolbarVariantRef.current === "logo") {
17384
- deselectRef.current();
17385
- return;
17386
- }
17387
16411
  if (toolbarVariantRef.current === "select-frame") {
17388
16412
  const parent2 = getNavigationSelectionParent(selectedElRef.current);
17389
16413
  if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
@@ -17461,8 +16485,7 @@ function OhhwellsBridge() {
17461
16485
  const handleScroll = () => {
17462
16486
  const focusEl = activeElRef.current ?? selectedElRef.current;
17463
16487
  if (focusEl) {
17464
- const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
17465
- const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
16488
+ const r2 = activeElRef.current ? getEditMeasureEl(activeElRef.current).getBoundingClientRect() : focusEl.getBoundingClientRect();
17466
16489
  applyToolbarPos(r2);
17467
16490
  setToolbarRect(r2);
17468
16491
  setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
@@ -17472,9 +16495,7 @@ function OhhwellsBridge() {
17472
16495
  setToggleState((prev) => prev ? { ...prev, rect } : null);
17473
16496
  }
17474
16497
  if (hoveredItemElRef.current) {
17475
- const hoverEl = hoveredItemElRef.current;
17476
- const logo = getLogoElement(hoverEl);
17477
- setHoveredItemRect(logo ? getLogoInteractionRect(logo) : hoverEl.getBoundingClientRect());
16498
+ setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
17478
16499
  }
17479
16500
  if (hoveredNavContainerRef.current) {
17480
16501
  setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
@@ -17518,9 +16539,6 @@ function OhhwellsBridge() {
17518
16539
  if (aiSectionsRef.current) {
17519
16540
  nodes.push({ key: AI_SECTIONS_KEY, type: "sections", text: aiSectionsRef.current });
17520
16541
  }
17521
- if (brandKitRef.current) {
17522
- nodes.push({ key: BRAND_KIT_KEY, type: "brand", text: brandKitRef.current });
17523
- }
17524
16542
  postToParentRef.current({ type: "ow:save-result", nodes });
17525
16543
  };
17526
16544
  const handleInsertSection = (e) => {
@@ -17531,12 +16549,8 @@ function OhhwellsBridge() {
17531
16549
  if (inserted) {
17532
16550
  const tracker = getSectionsTracker();
17533
16551
  postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
17534
- const reportHeight = () => {
17535
- const h = document.body.scrollHeight;
17536
- if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
17537
- };
17538
- reportHeight();
17539
- setTimeout(reportHeight, 500);
16552
+ const h = document.documentElement.scrollHeight;
16553
+ if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
17540
16554
  }
17541
16555
  };
17542
16556
  const handleSwitchSchedule = (e) => {
@@ -17729,17 +16743,13 @@ function OhhwellsBridge() {
17729
16743
  if (e.data?.type !== "ow:parent-scroll") return;
17730
16744
  const { iframeOffsetTop, headerH, canvasH } = e.data;
17731
16745
  parentScrollRef.current = { iframeOffsetTop, headerH, canvasH };
17732
- if (floatingPanelOpenRef.current) {
17733
- setParentScrollSnap({ iframeOffsetTop, headerH, canvasH });
17734
- }
17735
16746
  if (visibleViewportRef.current) {
17736
16747
  applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
17737
16748
  }
17738
16749
  const focusEl = activeElRef.current ?? selectedElRef.current;
17739
16750
  if (focusEl) {
17740
- const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
17741
- const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
17742
- applyToolbarPos(r2);
16751
+ const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
16752
+ applyToolbarPos(measureEl.getBoundingClientRect());
17743
16753
  }
17744
16754
  };
17745
16755
  const handleClickAt = (e) => {
@@ -17764,25 +16774,6 @@ function OhhwellsBridge() {
17764
16774
  postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "", elementType: stateCardImage.dataset.ohwEditable ?? "image" });
17765
16775
  return;
17766
16776
  }
17767
- const logoAtPoint = Array.from(
17768
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]')
17769
- ).map((el) => getLogoElement(el)).find((logo) => {
17770
- if (!logo) return false;
17771
- const r2 = logo.getBoundingClientRect();
17772
- return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
17773
- });
17774
- if (logoAtPoint) {
17775
- if (!logoHasUploadedImage(logoAtPoint)) {
17776
- deselectRef.current();
17777
- deactivateRef.current();
17778
- const identity = readLogoIdentityFromDom();
17779
- postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
17780
- return;
17781
- }
17782
- selectLogoRef.current(logoAtPoint);
17783
- openLogoSizePanelRef.current(logoAtPoint);
17784
- return;
17785
- }
17786
16777
  const textEditable = Array.from(
17787
16778
  document.querySelectorAll(NON_MEDIA_SELECTOR)
17788
16779
  ).find((el) => {
@@ -17854,14 +16845,6 @@ function OhhwellsBridge() {
17854
16845
  window.addEventListener("message", handleParentScroll);
17855
16846
  window.addEventListener("message", handlePointerSync);
17856
16847
  window.addEventListener("message", handleClickAt);
17857
- window.addEventListener("message", handleUpdateLogoIdentity);
17858
- const handleViewMode = (e) => {
17859
- if (e.data?.type !== "ow:view-mode") return;
17860
- const mode = e.data.mode === "Mobile" || e.data.mode === "mobile" ? "mobile" : "desktop";
17861
- setEditorViewport(mode);
17862
- applyLogoSizes(editContentRef.current);
17863
- };
17864
- window.addEventListener("message", handleViewMode);
17865
16848
  const handleViewportResize = () => {
17866
16849
  if (visibleViewportRef.current) {
17867
16850
  applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
@@ -17917,13 +16900,10 @@ function OhhwellsBridge() {
17917
16900
  window.removeEventListener("resize", handleViewportResize);
17918
16901
  window.removeEventListener("message", handlePointerSync);
17919
16902
  window.removeEventListener("message", handleClickAt);
17920
- window.removeEventListener("message", handleUpdateLogoIdentity);
17921
- window.removeEventListener("message", handleViewMode);
17922
16903
  window.removeEventListener("message", handleHydrate);
17923
16904
  window.removeEventListener("message", handleAiApplyTree);
17924
16905
  window.removeEventListener("message", handleAiDeleteSection);
17925
16906
  window.removeEventListener("message", handleAiSetSections);
17926
- window.removeEventListener("message", handleAiSetBrand);
17927
16907
  window.removeEventListener("message", handleDeactivate);
17928
16908
  window.removeEventListener("message", handleToastAction);
17929
16909
  window.removeEventListener("message", handleUiEscape);
@@ -18522,10 +17502,10 @@ function OhhwellsBridge() {
18522
17502
  [postToParent2]
18523
17503
  );
18524
17504
  return bridgeRoot ? (0, import_react_dom4.createPortal)(
18525
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
18526
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
18527
- isEditMode && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
18528
- Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17505
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
17506
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
17507
+ isEditMode && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
17508
+ Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18529
17509
  MediaOverlay,
18530
17510
  {
18531
17511
  hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
@@ -18536,7 +17516,7 @@ function OhhwellsBridge() {
18536
17516
  },
18537
17517
  `uploading-${key}`
18538
17518
  )),
18539
- mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17519
+ mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18540
17520
  MediaOverlay,
18541
17521
  {
18542
17522
  hover: mediaHover,
@@ -18545,11 +17525,11 @@ function OhhwellsBridge() {
18545
17525
  onVideoSettingsChange: handleVideoSettingsChange
18546
17526
  }
18547
17527
  ),
18548
- carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
18549
- siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
18550
- siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
18551
- isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
18552
- isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17528
+ carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
17529
+ siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
17530
+ siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
17531
+ isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
17532
+ isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18553
17533
  "div",
18554
17534
  {
18555
17535
  className: "pointer-events-none fixed z-2147483646",
@@ -18559,7 +17539,7 @@ function OhhwellsBridge() {
18559
17539
  width: slot.width,
18560
17540
  height: slot.height
18561
17541
  },
18562
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17542
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18563
17543
  DropIndicator,
18564
17544
  {
18565
17545
  direction: slot.direction,
@@ -18570,7 +17550,7 @@ function OhhwellsBridge() {
18570
17550
  },
18571
17551
  `footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
18572
17552
  )),
18573
- isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17553
+ isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18574
17554
  "div",
18575
17555
  {
18576
17556
  className: "pointer-events-none fixed z-2147483646",
@@ -18580,7 +17560,7 @@ function OhhwellsBridge() {
18580
17560
  width: slot.width,
18581
17561
  height: slot.height
18582
17562
  },
18583
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17563
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18584
17564
  DropIndicator,
18585
17565
  {
18586
17566
  direction: slot.direction,
@@ -18591,10 +17571,10 @@ function OhhwellsBridge() {
18591
17571
  },
18592
17572
  `nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
18593
17573
  )),
18594
- hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
18595
- hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
18596
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
18597
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17574
+ hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
17575
+ hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
17576
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
17577
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18598
17578
  FooterContainerChrome,
18599
17579
  {
18600
17580
  rect: toolbarRect,
@@ -18602,7 +17582,7 @@ function OhhwellsBridge() {
18602
17582
  addDisabled: !canAddFooterColumn()
18603
17583
  }
18604
17584
  ),
18605
- toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17585
+ toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18606
17586
  ItemInteractionLayer,
18607
17587
  {
18608
17588
  rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
@@ -18614,10 +17594,10 @@ function OhhwellsBridge() {
18614
17594
  dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
18615
17595
  onDragHandleDragStart: handleItemDragStart,
18616
17596
  onDragHandleDragEnd: handleItemDragEnd,
18617
- onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
18618
- onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
18619
- itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection,
18620
- toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17597
+ onItemPointerDown: handleItemChromePointerDown,
17598
+ onItemClick: handleItemChromeClick,
17599
+ itemDragSurface: !isFooterFrameSelection,
17600
+ toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18621
17601
  ItemActionToolbar,
18622
17602
  {
18623
17603
  onEditLink: openLinkPopoverForSelected,
@@ -18650,8 +17630,8 @@ function OhhwellsBridge() {
18650
17630
  ) : void 0
18651
17631
  }
18652
17632
  ),
18653
- toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
18654
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17633
+ toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
17634
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18655
17635
  EditGlowChrome,
18656
17636
  {
18657
17637
  rect: toolbarRect,
@@ -18661,7 +17641,7 @@ function OhhwellsBridge() {
18661
17641
  hideHandle: isItemDragging
18662
17642
  }
18663
17643
  ),
18664
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17644
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18665
17645
  FloatingToolbar,
18666
17646
  {
18667
17647
  rect: toolbarRect,
@@ -18674,7 +17654,7 @@ function OhhwellsBridge() {
18674
17654
  }
18675
17655
  )
18676
17656
  ] }),
18677
- maxBadge && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
17657
+ maxBadge && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
18678
17658
  "div",
18679
17659
  {
18680
17660
  "data-ohw-max-badge": "",
@@ -18700,7 +17680,7 @@ function OhhwellsBridge() {
18700
17680
  ]
18701
17681
  }
18702
17682
  ),
18703
- toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17683
+ toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18704
17684
  StateToggle,
18705
17685
  {
18706
17686
  rect: toggleState.rect,
@@ -18709,15 +17689,15 @@ function OhhwellsBridge() {
18709
17689
  onStateChange: handleStateChange
18710
17690
  }
18711
17691
  ),
18712
- sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
17692
+ sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
18713
17693
  "div",
18714
17694
  {
18715
17695
  "data-ohw-section-insert-line": "",
18716
17696
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
18717
17697
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
18718
17698
  children: [
18719
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
18720
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17699
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
17700
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18721
17701
  Badge,
18722
17702
  {
18723
17703
  className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
@@ -18734,11 +17714,11 @@ function OhhwellsBridge() {
18734
17714
  children: "Add Section"
18735
17715
  }
18736
17716
  ),
18737
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
17717
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
18738
17718
  ]
18739
17719
  }
18740
17720
  ),
18741
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17721
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18742
17722
  LinkPopover,
18743
17723
  {
18744
17724
  panelRef: linkPopoverPanelRef,
@@ -18755,7 +17735,7 @@ function OhhwellsBridge() {
18755
17735
  },
18756
17736
  linkPopover.key
18757
17737
  ) : null,
18758
- floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17738
+ floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18759
17739
  FloatingPanel,
18760
17740
  {
18761
17741
  open: true,
@@ -18765,7 +17745,7 @@ function OhhwellsBridge() {
18765
17745
  onPositionChange: setFloatingPanelPos,
18766
17746
  parentScroll: parentScrollSnap ?? parentScrollRef.current,
18767
17747
  onClose: closeFloatingPanelOnly,
18768
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
17748
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
18769
17749
  SocialsDisplayPanel,
18770
17750
  {
18771
17751
  display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
@@ -18776,115 +17756,11 @@ function OhhwellsBridge() {
18776
17756
  }
18777
17757
  )
18778
17758
  }
18779
- ) : null,
18780
- floatingPanel && floatingPanel.kind === "logo-size" && logoSizeDraft ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
18781
- FloatingPanel,
18782
- {
18783
- open: true,
18784
- title: floatingPanel.title,
18785
- context: floatingPanel.context,
18786
- position: floatingPanelPos,
18787
- onPositionChange: setFloatingPanelPos,
18788
- parentScroll: parentScrollSnap ?? parentScrollRef.current,
18789
- onClose: closeFloatingPanelAndDeselect,
18790
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
18791
- LogoSizePanel,
18792
- {
18793
- viewport: editorViewport,
18794
- sizePx: editorViewport === "mobile" && !logoSizeDraft.mobileFollowing ? logoSizeDraft.mobilePx : logoSizeDraft.desktopPx,
18795
- mobileFollowing: logoSizeDraft.mobileFollowing,
18796
- onSizeChange: (px) => {
18797
- const next = editorViewport === "mobile" ? { ...logoSizeDraft, mobilePx: px, mobileFollowing: false } : {
18798
- ...logoSizeDraft,
18799
- desktopPx: px,
18800
- mobilePx: logoSizeDraft.mobileFollowing ? px : logoSizeDraft.mobilePx
18801
- };
18802
- setLogoSizeDraft(next);
18803
- persistLogoSizeDraft(floatingPanel.placement, next);
18804
- },
18805
- onCustomizeMobile: () => {
18806
- const next = {
18807
- ...logoSizeDraft,
18808
- mobileFollowing: false,
18809
- mobilePx: logoSizeDraft.desktopPx
18810
- };
18811
- setLogoSizeDraft(next);
18812
- persistLogoSizeDraft(floatingPanel.placement, next);
18813
- },
18814
- onResetMobile: () => {
18815
- const next = {
18816
- ...logoSizeDraft,
18817
- mobileFollowing: true,
18818
- mobilePx: logoSizeDraft.desktopPx
18819
- };
18820
- setLogoSizeDraft(next);
18821
- persistLogoSizeDraft(floatingPanel.placement, next);
18822
- },
18823
- onUpdateEverywhere: () => {
18824
- const identity = readLogoIdentityFromDom();
18825
- postToParent2({ type: "ow:open-logo-settings", ...identity });
18826
- }
18827
- }
18828
- )
18829
- }
18830
17759
  ) : null
18831
17760
  ] }),
18832
17761
  bridgeRoot
18833
17762
  ) : null;
18834
17763
  }
18835
-
18836
- // src/ui/EmptySection.tsx
18837
- var import_link = __toESM(require("next/link"), 1);
18838
- var import_jsx_runtime34 = require("react/jsx-runtime");
18839
- function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
18840
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
18841
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
18842
- "p",
18843
- {
18844
- style: {
18845
- fontFamily: "var(--brand-font-body)",
18846
- fontSize: "0.75rem",
18847
- fontWeight: 500,
18848
- letterSpacing: "0.15em",
18849
- textTransform: "uppercase",
18850
- color: "var(--brand-accent)",
18851
- marginBottom: "1.5rem"
18852
- },
18853
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_link.default, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
18854
- }
18855
- ),
18856
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
18857
- "h1",
18858
- {
18859
- style: {
18860
- fontFamily: "var(--brand-font-heading)",
18861
- fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
18862
- lineHeight: 1.1,
18863
- letterSpacing: "-0.025em",
18864
- color: "var(--brand-text)",
18865
- marginBottom: "1rem"
18866
- },
18867
- ...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
18868
- children: title
18869
- }
18870
- ),
18871
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
18872
- "p",
18873
- {
18874
- style: {
18875
- fontFamily: "var(--brand-font-body)",
18876
- fontSize: "1rem",
18877
- lineHeight: 1.7,
18878
- fontWeight: 300,
18879
- color: "var(--brand-text-muted)",
18880
- maxWidth: "340px"
18881
- },
18882
- ...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
18883
- children: "This page doesn't have any content yet."
18884
- }
18885
- )
18886
- ] });
18887
- }
18888
17764
  // Annotate the CommonJS export names for ESM import in node:
18889
17765
  0 && (module.exports = {
18890
17766
  AI_DEFAULT_BRAND,
@@ -18902,7 +17778,6 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
18902
17778
  DropdownMenuItem,
18903
17779
  DropdownMenuSeparator,
18904
17780
  DropdownMenuTrigger,
18905
- EmptySection,
18906
17781
  ItemActionToolbar,
18907
17782
  ItemInteractionLayer,
18908
17783
  LinkEditorPanel,