@ohhwells/bridge 0.1.62-next.174 → 0.1.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -96,7 +96,6 @@ function applyTreeToState(state, payload) {
96
96
  const entry = {
97
97
  id: payload.id,
98
98
  label: payload.label ?? "Generated section",
99
- ...typeof payload.path === "string" && payload.path ? { path: payload.path } : {},
100
99
  afterSection: payload.mode === "insert" && !insertBefore ? payload.targetSectionId ?? null : null,
101
100
  ...insertBefore && payload.targetSectionId ? { beforeSection: payload.targetSectionId } : {},
102
101
  ...payload.mode === "replace" && payload.targetSectionId ? { replaces: payload.targetSectionId } : {},
@@ -119,287 +118,6 @@ function deleteSectionFromState(state, sectionId) {
119
118
  return { ...state, v: 1, sections: state.sections, removed: [...removed, sectionId] };
120
119
  }
121
120
 
122
- // src/lib/brand-chrome.ts
123
- var BRAND_NAME_KEY = "__ohw_brand_name";
124
- var BRAND_TITLE_KEY = "__ohw_site_title";
125
- var BRAND_FAVICON_LETTER_KEY = "__ohw_favicon_letter";
126
- var BRAND_CHROME_KEYS = /* @__PURE__ */ new Set([
127
- BRAND_NAME_KEY,
128
- BRAND_TITLE_KEY,
129
- BRAND_FAVICON_LETTER_KEY
130
- ]);
131
- function upsertMeta(selector, attr, token, value) {
132
- let el = document.head.querySelector(selector);
133
- if (!el) {
134
- el = document.createElement("meta");
135
- el.setAttribute(attr, token);
136
- document.head.appendChild(el);
137
- }
138
- if (el.getAttribute("content") !== value) el.setAttribute("content", value);
139
- }
140
- function escapeXml(value) {
141
- return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
142
- }
143
- function applyLetterFavicon(letter) {
144
- 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>`;
145
- const href = `data:image/svg+xml,${encodeURIComponent(svg)}`;
146
- let link = document.head.querySelector('link[rel="icon"]');
147
- if (!link) {
148
- link = document.createElement("link");
149
- link.rel = "icon";
150
- document.head.appendChild(link);
151
- }
152
- link.type = "image/svg+xml";
153
- if (link.href !== href) link.href = href;
154
- }
155
- function applyBrandChrome(content) {
156
- const name = content[BRAND_NAME_KEY];
157
- if (typeof name === "string" && name.length > 0) {
158
- document.querySelectorAll("[data-ohw-wordmark]").forEach((el) => {
159
- if (el.textContent !== name) el.textContent = name;
160
- if (el.getAttribute("title") !== name) el.setAttribute("title", name);
161
- });
162
- }
163
- const title = content[BRAND_TITLE_KEY];
164
- if (typeof title === "string" && title.length > 0) {
165
- if (document.title !== title) document.title = title;
166
- upsertMeta('meta[property="og:title"]', "property", "og:title", title);
167
- upsertMeta('meta[name="twitter:title"]', "name", "twitter:title", title);
168
- }
169
- const letter = content[BRAND_FAVICON_LETTER_KEY];
170
- if (typeof letter === "string" && letter.length > 0) {
171
- applyLetterFavicon(letter);
172
- }
173
- }
174
-
175
- // src/lib/brand-kit.ts
176
- var BRAND_KIT_KEY = "__ohw_brand";
177
- var BRAND_VAR_PREFIX = "--ohw-brand-";
178
- var BRAND_VAR_NAMES = ["primary", "accent", "light", "dark", "surface", "border", "muted"].map(
179
- (role) => `${BRAND_VAR_PREFIX}${role}`
180
- );
181
- var FONT_VARS = { heading: ["--font-heading", "--font-display"], body: ["--font-body"] };
182
- var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
183
- function brandColorVars(kit) {
184
- const { dark, primary, accent, light } = kit.palette;
185
- const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
186
- return {
187
- [`${BRAND_VAR_PREFIX}primary`]: primary,
188
- [`${BRAND_VAR_PREFIX}accent`]: accent,
189
- [`${BRAND_VAR_PREFIX}light`]: light,
190
- [`${BRAND_VAR_PREFIX}dark`]: dark,
191
- [`${BRAND_VAR_PREFIX}surface`]: mix(light, 95, dark),
192
- [`${BRAND_VAR_PREFIX}border`]: mix(light, 85, dark),
193
- [`${BRAND_VAR_PREFIX}muted`]: mix(dark, 62, light)
194
- };
195
- }
196
- function parseBrandKit(raw) {
197
- if (!raw) return null;
198
- try {
199
- const parsed = JSON.parse(raw);
200
- const p = parsed?.palette;
201
- const f = parsed?.fonts;
202
- 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") {
203
- return null;
204
- }
205
- return {
206
- palette: { dark: p.dark, primary: p.primary, accent: p.accent, light: p.light },
207
- fonts: { heading: f.heading, body: f.body }
208
- };
209
- } catch {
210
- return null;
211
- }
212
- }
213
- function familyOf(stack) {
214
- const first = stack.split(",")[0]?.trim() ?? "";
215
- return first.replace(/^['"]|['"]$/g, "");
216
- }
217
- function loadBrandFonts(families) {
218
- const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
219
- if (unique.length === 0) return;
220
- const spec = unique.map((f) => `${f.replace(/ /g, "+")}:400,500,600,700`).join("|");
221
- const href = `https://fonts.googleapis.com/css?family=${spec}&display=swap`;
222
- let link = document.getElementById(BRAND_FONT_LINK_ID);
223
- if (!link) {
224
- link = document.createElement("link");
225
- link.id = BRAND_FONT_LINK_ID;
226
- link.rel = "stylesheet";
227
- document.head.appendChild(link);
228
- }
229
- if (link.href !== href) link.href = href;
230
- }
231
- function applyBrandToDom(kit) {
232
- const root = document.documentElement;
233
- if (!kit) {
234
- for (const name of BRAND_VAR_NAMES) root.style.removeProperty(name);
235
- for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
236
- document.getElementById(BRAND_FONT_LINK_ID)?.remove();
237
- return;
238
- }
239
- for (const [name, value] of Object.entries(brandColorVars(kit))) root.style.setProperty(name, value);
240
- for (const name of FONT_VARS.heading) root.style.setProperty(name, kit.fonts.heading);
241
- for (const name of FONT_VARS.body) root.style.setProperty(name, kit.fonts.body);
242
- loadBrandFonts([familyOf(kit.fonts.heading), familyOf(kit.fonts.body)]);
243
- }
244
-
245
- // src/lib/section-styles.ts
246
- var STYLE_STORE_KEY = "__ohw_styles";
247
- var STYLE_SHEET_ID = "ohw-section-styles";
248
- function parseStyleStore(raw) {
249
- if (!raw) return null;
250
- try {
251
- const parsed = JSON.parse(raw);
252
- if (parsed?.v !== 1) return null;
253
- return {
254
- v: 1,
255
- sections: typeof parsed.sections === "object" && parsed.sections ? parsed.sections : {},
256
- nodes: typeof parsed.nodes === "object" && parsed.nodes ? parsed.nodes : {}
257
- };
258
- } catch {
259
- return null;
260
- }
261
- }
262
- var BG_VALUES = {
263
- surface: "color-mix(in srgb, var(--ohw-brand-light, var(--color-light, #ECECEB)) 94%, var(--ohw-brand-dark, var(--color-dark, #0C0A09)))",
264
- accent: "var(--ohw-brand-primary, var(--color-primary, #0078E5))",
265
- "accent-soft": "color-mix(in srgb, var(--ohw-brand-primary, var(--color-primary, #0078E5)) 12%, var(--ohw-brand-light, var(--color-light, #FFFFFF)))"
266
- };
267
- var HEADLINE_SIZES = { md: 24, lg: 32, xl: 40, display: 56 };
268
- function styleSheetCss() {
269
- const rules = [];
270
- for (const [tone, value] of Object.entries(BG_VALUES)) {
271
- rules.push(`[data-ohw-style-bg="${tone}"] { background: ${value} !important; }`);
272
- }
273
- rules.push(
274
- `[data-ohw-style-bg="accent"] { color: var(--ohw-brand-light, var(--color-light, #FFFFFF)) !important; }`
275
- );
276
- rules.push(
277
- `[data-ohw-style-distribution="space-between"] { display: flex !important; flex-direction: column; justify-content: space-between; }`,
278
- `[data-ohw-style-distribution="center"] { display: flex !important; flex-direction: column; justify-content: center; }`
279
- );
280
- for (const [scale, size] of Object.entries(HEADLINE_SIZES)) {
281
- rules.push(
282
- `[data-ohw-style-headline="${scale}"] :is(h1, h2, h3) { font-size: ${size}px !important; line-height: 1.15 !important; }`
283
- );
284
- }
285
- rules.push(
286
- `[data-ohw-style-aspect="fill-height"] img { height: 100% !important; aspect-ratio: auto !important; object-fit: cover; }`
287
- );
288
- for (const aspect of ["1:1", "4:5", "3:4", "3:2", "16:9", "2:1", "3:1"]) {
289
- rules.push(
290
- `[data-ohw-style-aspect="${aspect.replace(":", "-")}"] img { aspect-ratio: ${aspect.replace(":", " / ")} !important; height: auto !important; object-fit: cover; }`
291
- );
292
- }
293
- const pad = { tight: 40, balanced: 64, airy: 96 };
294
- for (const [spacing, px] of Object.entries(pad)) {
295
- rules.push(
296
- `[data-ohw-style-spacing="${spacing}"] { padding-top: ${px}px !important; padding-bottom: ${px}px !important; }`
297
- );
298
- }
299
- return rules.join("\n");
300
- }
301
- var SECTION_ATTRS = {
302
- sectionBackground: "data-ohw-style-bg",
303
- textDistribution: "data-ohw-style-distribution",
304
- headlineScale: "data-ohw-style-headline",
305
- imageAspect: "data-ohw-style-aspect",
306
- spacing: "data-ohw-style-spacing"
307
- };
308
- var NODE_WROTE_ATTR = "data-ohw-style-node";
309
- var NODE_PROPS = ["color", "font-size", "background"];
310
- function saveInline(el, prop) {
311
- const attr = `data-ohw-style-prev-${prop}`;
312
- if (!el.hasAttribute(attr)) el.setAttribute(attr, el.style.getPropertyValue(prop));
313
- }
314
- function restoreInline(el, prop) {
315
- const attr = `data-ohw-style-prev-${prop}`;
316
- if (!el.hasAttribute(attr)) return;
317
- const prev = el.getAttribute(attr) ?? "";
318
- if (prev) el.style.setProperty(prop, prev);
319
- else el.style.removeProperty(prop);
320
- el.removeAttribute(attr);
321
- }
322
- function ensureStyleSheet() {
323
- let el = document.getElementById(STYLE_SHEET_ID);
324
- if (!el) {
325
- el = document.createElement("style");
326
- el.id = STYLE_SHEET_ID;
327
- document.head.appendChild(el);
328
- }
329
- const css = styleSheetCss();
330
- if (el.textContent !== css) el.textContent = css;
331
- }
332
- function clearSectionAttrs(root) {
333
- for (const attr of Object.values(SECTION_ATTRS)) {
334
- for (const el of Array.from(root.querySelectorAll(`[${attr}]`))) el.removeAttribute(attr);
335
- }
336
- for (const el of Array.from(root.querySelectorAll("[data-ohw-style-bgcolor]"))) {
337
- restoreInline(el, "background");
338
- el.removeAttribute("data-ohw-style-bgcolor");
339
- }
340
- }
341
- function clearNodeProps(root) {
342
- for (const el of Array.from(root.querySelectorAll(`[${NODE_WROTE_ATTR}]`))) {
343
- const h = el;
344
- for (const prop of NODE_PROPS) restoreInline(h, prop);
345
- h.removeAttribute(NODE_WROTE_ATTR);
346
- }
347
- }
348
- function buttonSurfaceOf(el) {
349
- return el.closest("a, button") ?? el;
350
- }
351
- function applyStylesToDom(store) {
352
- ensureStyleSheet();
353
- clearSectionAttrs(document);
354
- clearNodeProps(document);
355
- if (!store) return;
356
- for (const [sectionId, override] of Object.entries(store.sections)) {
357
- const sections = document.querySelectorAll(
358
- `[data-ohw-section="${CSS.escape(sectionId)}"]`
359
- );
360
- for (const section of Array.from(sections)) {
361
- for (const [prop, attr] of Object.entries(SECTION_ATTRS)) {
362
- const value = override[prop];
363
- if (value === void 0) continue;
364
- if (prop === "sectionBackground" && override.sectionBackgroundColor !== void 0) continue;
365
- section.setAttribute(attr, String(value).replace(":", "-"));
366
- }
367
- if (override.sectionBackgroundColor !== void 0) {
368
- saveInline(section, "background");
369
- section.style.setProperty("background", override.sectionBackgroundColor, "important");
370
- section.setAttribute("data-ohw-style-bgcolor", "");
371
- }
372
- }
373
- }
374
- for (const [key, override] of Object.entries(store.nodes)) {
375
- const nodes = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
376
- for (const el of Array.from(nodes)) {
377
- if (override.color !== void 0) {
378
- saveInline(el, "color");
379
- el.style.setProperty("color", override.color, "important");
380
- el.setAttribute(NODE_WROTE_ATTR, "");
381
- }
382
- if (override.fontSize !== void 0) {
383
- saveInline(el, "font-size");
384
- el.style.setProperty("font-size", `${override.fontSize}px`, "important");
385
- el.setAttribute(NODE_WROTE_ATTR, "");
386
- }
387
- if (override.buttonBackground !== void 0 || override.buttonText !== void 0) {
388
- const surface = buttonSurfaceOf(el);
389
- if (override.buttonBackground !== void 0) {
390
- saveInline(surface, "background");
391
- surface.style.setProperty("background", override.buttonBackground, "important");
392
- }
393
- if (override.buttonText !== void 0) {
394
- saveInline(surface, "color");
395
- surface.style.setProperty("color", override.buttonText, "important");
396
- }
397
- surface.setAttribute(NODE_WROTE_ATTR, "");
398
- }
399
- }
400
- }
401
- }
402
-
403
121
  // src/ui/ai-tree/aiSectionsManager.tsx
404
122
  import { flushSync } from "react-dom";
405
123
  import { createRoot } from "react-dom/client";
@@ -414,8 +132,7 @@ function lucideByName(name) {
414
132
  }
415
133
  var typeStyle = (spec, font) => ({
416
134
  fontFamily: font,
417
- // Headings shrink with the viewport (reaching full size around ~900px wide); body copy stays put.
418
- fontSize: spec.size >= 24 ? `clamp(${Math.max(18, Math.round(spec.size * 0.6))}px, ${(spec.size / 9).toFixed(2)}vw, ${spec.size}px)` : spec.size,
135
+ fontSize: spec.size,
419
136
  lineHeight: spec.line,
420
137
  fontWeight: spec.weight
421
138
  });
@@ -442,8 +159,6 @@ var AI_RESPONSIVE_CSS = [
442
159
  " [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
443
160
  " [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
444
161
  " [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
445
- " [data-ai-responsive] { overflow-x: hidden; }",
446
- " [data-ai-responsive] img { max-width: 100%; }",
447
162
  "}"
448
163
  ].join("\n");
449
164
  var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
@@ -1451,20 +1166,6 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
1451
1166
  const overlayAlpha = { low: 0.25, medium: 0.45, high: 0.65 }[settings.overlayIntensity ?? "medium"];
1452
1167
  const backgroundUrl = isOverlay && settings.backgroundMedia ? ctx.resolveMedia(settings.backgroundMedia) : null;
1453
1168
  const bgAttrs = ctx.keyFor && isOverlay && settings.backgroundMedia ? { "data-ohw-key": ctx.keyFor("settings.backgroundMedia"), "data-ohw-editable": "bg-image" } : {};
1454
- const toneBackground = (() => {
1455
- const { dark, primary, light } = resolvedBrand.palette;
1456
- switch (settings.sectionBackground) {
1457
- case "surface":
1458
- return `color-mix(in srgb, ${light} 94%, ${dark})`;
1459
- case "accent":
1460
- return primary;
1461
- case "accent-soft":
1462
- return `color-mix(in srgb, ${primary} 12%, ${light})`;
1463
- default:
1464
- return void 0;
1465
- }
1466
- })();
1467
- const distributed = !isOverlay && settings.textDistribution;
1468
1169
  return /* @__PURE__ */ jsxs(
1469
1170
  "section",
1470
1171
  {
@@ -1474,11 +1175,10 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
1474
1175
  style: {
1475
1176
  position: "relative",
1476
1177
  padding: `${pad}px 0`,
1477
- background: toneBackground ?? (isOverlay && !backgroundUrl ? "#DBEAFE" : void 0),
1178
+ background: isOverlay && !backgroundUrl ? "#DBEAFE" : void 0,
1478
1179
  backgroundImage: backgroundUrl ? `url(${backgroundUrl})` : void 0,
1479
1180
  backgroundSize: "cover",
1480
- backgroundPosition: "center",
1481
- color: settings.sectionBackground === "accent" ? resolvedBrand.palette.light : void 0
1181
+ backgroundPosition: "center"
1482
1182
  },
1483
1183
  children: [
1484
1184
  /* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
@@ -1502,24 +1202,10 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
1502
1202
  display: "grid",
1503
1203
  gridTemplateColumns: "repeat(12, 1fr)",
1504
1204
  gap: AI_TREE_TOKENS.spacing6,
1505
- alignItems: distributed === "space-between" ? "stretch" : (distributed ?? settings.verticalPosition) === "top" ? "start" : "center",
1205
+ alignItems: settings.verticalPosition === "top" ? "start" : "center",
1506
1206
  marginTop: r2 > 0 ? AI_TREE_TOKENS.spacing8 : 0
1507
1207
  },
1508
- children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ jsx(
1509
- "div",
1510
- {
1511
- "data-ai-cell": "",
1512
- style: {
1513
- gridColumn: `span ${Math.min(12, Math.max(1, block.span))}`,
1514
- minWidth: 0,
1515
- // space-between: each column becomes a flex column whose content spreads over
1516
- // the full row height instead of clumping at the top.
1517
- ...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
1518
- },
1519
- children: renderNode(block, ctx, `r${r2}.b${b}`)
1520
- },
1521
- b
1522
- ))
1208
+ children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ jsx("div", { style: { gridColumn: `span ${Math.min(12, Math.max(1, block.span))}`, minWidth: 0 }, children: renderNode(block, ctx, `r${r2}.b${b}`) }, b))
1523
1209
  },
1524
1210
  r2
1525
1211
  ))
@@ -1535,34 +1221,17 @@ import { jsx as jsx2 } from "react/jsx-runtime";
1535
1221
  var CONTAINER_ATTR = "data-ohw-ai-generated";
1536
1222
  var REPLACED_ATTR = "data-ohw-ai-replaced-by";
1537
1223
  var REMOVED_ATTR = "data-ohw-ai-removed";
1538
- function readRootVar(name) {
1539
- if (typeof document === "undefined") return "";
1540
- return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
1541
- }
1542
- function deriveBrandOverride() {
1543
- const dark = readRootVar("--ohw-brand-dark");
1544
- const primary = readRootVar("--ohw-brand-primary");
1545
- const light = readRootVar("--ohw-brand-light");
1546
- if (!dark || !primary || !light) return null;
1547
- const accent = readRootVar("--ohw-brand-accent");
1548
- const heading = readRootVar("--font-heading") || readRootVar("--font-display");
1549
- const body = readRootVar("--font-body");
1550
- return {
1551
- palette: { dark, primary, accent: accent || dark, light },
1552
- fonts: {
1553
- heading: heading || AI_DEFAULT_BRAND.fonts.heading,
1554
- body: body || AI_DEFAULT_BRAND.fonts.body
1555
- }
1556
- };
1557
- }
1558
1224
  function deriveTemplateBrand() {
1559
- const dark = readRootVar("--color-dark");
1560
- const primary = readRootVar("--color-primary");
1561
- const light = readRootVar("--color-light");
1225
+ if (typeof document === "undefined") return null;
1226
+ const cs = getComputedStyle(document.documentElement);
1227
+ const read = (name) => cs.getPropertyValue(name).trim();
1228
+ const dark = read("--color-dark");
1229
+ const primary = read("--color-primary");
1230
+ const light = read("--color-light");
1562
1231
  if (!dark || !primary || !light) return null;
1563
- const accent = readRootVar("--color-accent");
1564
- const heading = readRootVar("--font-heading") || readRootVar("--font-display");
1565
- const body = readRootVar("--font-body");
1232
+ const accent = read("--color-accent");
1233
+ const heading = read("--font-heading") || read("--font-display");
1234
+ const body = read("--font-body");
1566
1235
  return {
1567
1236
  palette: { dark, primary, accent: accent || dark, light },
1568
1237
  fonts: {
@@ -1654,12 +1323,8 @@ function syncReplacedOriginals(state) {
1654
1323
  }
1655
1324
  function applyAiSectionsToDom(state, options) {
1656
1325
  if (typeof document === "undefined") return;
1657
- const brandOverride = deriveBrandOverride();
1658
1326
  const templateBrand = deriveTemplateBrand();
1659
- const brandKey = brandOverride ? JSON.stringify(brandOverride) : "";
1660
- const pagePath = window.location.pathname;
1661
- const pageSections = state.sections.filter((entry) => !entry.path || entry.path === pagePath);
1662
- const activeIds = new Set(pageSections.map((entry) => entry.id));
1327
+ const activeIds = new Set(state.sections.map((entry) => entry.id));
1663
1328
  for (const [id, section] of mounted) {
1664
1329
  if (!activeIds.has(id)) {
1665
1330
  section.root.unmount();
@@ -1667,8 +1332,8 @@ function applyAiSectionsToDom(state, options) {
1667
1332
  mounted.delete(id);
1668
1333
  }
1669
1334
  }
1670
- for (const entry of pageSections) {
1671
- const serialized = JSON.stringify(entry) + brandKey;
1335
+ for (const entry of state.sections) {
1336
+ const serialized = JSON.stringify(entry);
1672
1337
  const existing = mounted.get(entry.id);
1673
1338
  if (existing && existing.serialized === serialized && existing.container.isConnected) {
1674
1339
  continue;
@@ -1682,7 +1347,6 @@ function applyAiSectionsToDom(state, options) {
1682
1347
  mounted.delete(entry.id);
1683
1348
  }
1684
1349
  container.setAttribute("data-ohw-section", entry.id);
1685
- container.setAttribute("data-ohw-instance", entry.id);
1686
1350
  container.setAttribute("data-ohw-section-label", entry.label);
1687
1351
  placeContainer(container, entry);
1688
1352
  const root = mounted.get(entry.id)?.root ?? createRoot(container);
@@ -1693,7 +1357,7 @@ function applyAiSectionsToDom(state, options) {
1693
1357
  AiTreeRenderer,
1694
1358
  {
1695
1359
  tree: entry.tree,
1696
- brand: brandOverride ?? entry.brand ?? options?.brand ?? templateBrand ?? void 0,
1360
+ brand: entry.brand ?? options?.brand ?? templateBrand ?? void 0,
1697
1361
  resolveMedia,
1698
1362
  editKeyPrefix: `ai.${entry.id}`
1699
1363
  }
@@ -2310,7 +1974,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
2310
1974
  const autoId = useId();
2311
1975
  const insertAfter = insertAfterProp ?? autoId;
2312
1976
  const [schedule, setSchedule] = useState2(null);
2313
- const [loading, setLoading] = useState2(initialScheduleId !== null);
1977
+ const [loading, setLoading] = useState2(true);
2314
1978
  const [inEditor, setInEditor] = useState2(false);
2315
1979
  const [isHovered, setIsHovered] = useState2(false);
2316
1980
  const [modalState, setModalState] = useState2(null);
@@ -2484,10 +2148,8 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
2484
2148
  "*"
2485
2149
  );
2486
2150
  };
2151
+ if (!inEditor && !loading && !schedule) return null;
2487
2152
  const sectionId = `scheduling-${insertAfter}`;
2488
- if (!inEditor && !loading && !schedule) {
2489
- return /* @__PURE__ */ jsx4("section", { "data-ohw-section": sectionId, "data-ohw-scheduling-anchor": insertAfter, style: { display: "none" } });
2490
- }
2491
2153
  return /* @__PURE__ */ jsxs3(
2492
2154
  "section",
2493
2155
  {
@@ -7006,12 +6668,8 @@ function parseSectionsFromHtml(html) {
7006
6668
 
7007
6669
  // src/ui/ai-section/AiSectionOverlay.tsx
7008
6670
  import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
7009
- function findSectionElement(instanceId) {
7010
- const escaped = CSS.escape(instanceId);
7011
- return document.querySelector(`[data-ohw-instance="${escaped}"]`) ?? document.querySelector(`[data-ohw-section="${escaped}"]:not([data-ohw-instance])`);
7012
- }
7013
- function readRect(instanceId) {
7014
- const el = findSectionElement(instanceId);
6671
+ function readRect(sectionId) {
6672
+ const el = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
7015
6673
  if (!el) return null;
7016
6674
  const r2 = el.getBoundingClientRect();
7017
6675
  if (r2.width <= 0 || r2.height <= 0) return null;
@@ -7034,7 +6692,7 @@ function useLiveSectionRect(sectionId) {
7034
6692
  const opts = { capture: true, passive: true };
7035
6693
  window.addEventListener("scroll", update, opts);
7036
6694
  window.addEventListener("resize", update);
7037
- const el = findSectionElement(sectionId);
6695
+ const el = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
7038
6696
  const ro = el ? new ResizeObserver(update) : null;
7039
6697
  if (el && ro) ro.observe(el);
7040
6698
  const interval = setInterval(update, 500);
@@ -7047,14 +6705,6 @@ function useLiveSectionRect(sectionId) {
7047
6705
  }, [sectionId]);
7048
6706
  return rect;
7049
6707
  }
7050
- function computeSectionBoundaryFlags(instanceId) {
7051
- const topLevel = Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
7052
- (el) => !el.parentElement?.closest("[data-ohw-section]")
7053
- );
7054
- const index = topLevel.findIndex((el) => (el.dataset.ohwInstance ?? el.dataset.ohwSection) === instanceId);
7055
- if (index === -1) return { isFirst: true, isLast: true };
7056
- return { isFirst: index === 0, isLast: index === topLevel.length - 1 };
7057
- }
7058
6708
  var PRIMARY2 = "#0885FE";
7059
6709
  function edgeAwareRadius(rect) {
7060
6710
  const container = window.innerWidth <= 480 ? 16 : 24;
@@ -7128,7 +6778,6 @@ function AiSectionOverlay({
7128
6778
  }) {
7129
6779
  const [selectedId, setSelectedId] = useState4(null);
7130
6780
  const [reviewId, setReviewId] = useState4(null);
7131
- const [reviewButtonsHidden, setReviewButtonsHidden] = useState4(false);
7132
6781
  const reviewIdRef = useRef4(null);
7133
6782
  reviewIdRef.current = reviewId;
7134
6783
  const selectedIdRef = useRef4(null);
@@ -7137,7 +6786,7 @@ function AiSectionOverlay({
7137
6786
  (el) => {
7138
6787
  postToParent2({
7139
6788
  type: "ow:section-selected",
7140
- sectionId: el ? el.dataset.ohwInstance ?? el.dataset.ohwSection ?? null : null,
6789
+ sectionId: el?.dataset.ohwSection ?? null,
7141
6790
  sectionLabel: el ? el.dataset.ohwSectionLabel ?? titleCaseSectionId(el.dataset.ohwSection ?? "") : null
7142
6791
  });
7143
6792
  },
@@ -7146,7 +6795,7 @@ function AiSectionOverlay({
7146
6795
  const selectFromElement = useCallback2(
7147
6796
  (el, options) => {
7148
6797
  const sectionEl = el?.closest("[data-ohw-section]") ?? null;
7149
- const id = sectionEl ? sectionEl.dataset.ohwInstance ?? sectionEl.dataset.ohwSection ?? null : null;
6798
+ const id = sectionEl?.dataset.ohwSection ?? null;
7150
6799
  if (id === selectedIdRef.current) return;
7151
6800
  setSelectedId(id);
7152
6801
  if (options?.report !== false) report(sectionEl);
@@ -7187,10 +6836,9 @@ function AiSectionOverlay({
7187
6836
  }
7188
6837
  const found = readRect(sectionId) != null;
7189
6838
  setReviewId(found ? sectionId : null);
7190
- setReviewButtonsHidden(e.data.hideButtons === true);
7191
6839
  postToParent2({ type: "ow:ai-review-started", sectionId, found });
7192
6840
  if (found) {
7193
- document.querySelector(`[data-ohw-instance="${CSS.escape(sectionId)}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
6841
+ document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
7194
6842
  }
7195
6843
  }
7196
6844
  };
@@ -7209,7 +6857,7 @@ function AiSectionOverlay({
7209
6857
  return;
7210
6858
  }
7211
6859
  const sec = t.closest("[data-ohw-section]");
7212
- setHoveredId(sec ? sec.dataset.ohwInstance ?? sec.dataset.ohwSection ?? null : null);
6860
+ setHoveredId(sec?.dataset.ohwSection ?? null);
7213
6861
  };
7214
6862
  const onLeave = () => setHoveredId(null);
7215
6863
  document.addEventListener("mousemove", onMove, { passive: true });
@@ -7241,29 +6889,9 @@ function AiSectionOverlay({
7241
6889
  },
7242
6890
  [postToParent2]
7243
6891
  );
7244
- const activeSelectionId = reviewId ? null : selectedId;
7245
- const selectionRect = useLiveSectionRect(activeSelectionId);
6892
+ const selectionRect = useLiveSectionRect(reviewId ? null : selectedId);
7246
6893
  const reviewRect = useLiveSectionRect(reviewId);
7247
6894
  const hoverRect = useLiveSectionRect(reviewId || hoveredId === selectedId ? null : hoveredId);
7248
- useEffect4(() => {
7249
- if (!activeSelectionId || !selectionRect) {
7250
- postToParent2({ type: "ow:section-rect", instanceId: null, rect: null });
7251
- return;
7252
- }
7253
- const { isFirst, isLast } = computeSectionBoundaryFlags(activeSelectionId);
7254
- postToParent2({
7255
- type: "ow:section-rect",
7256
- instanceId: activeSelectionId,
7257
- rect: {
7258
- top: selectionRect.top + window.scrollY,
7259
- left: selectionRect.left + window.scrollX,
7260
- width: selectionRect.width,
7261
- height: selectionRect.height
7262
- },
7263
- isFirst,
7264
- isLast
7265
- });
7266
- }, [activeSelectionId, selectionRect, postToParent2]);
7267
6895
  return /* @__PURE__ */ jsxs8(Fragment5, { children: [
7268
6896
  hoverRect && /* @__PURE__ */ jsx16(
7269
6897
  "div",
@@ -7314,16 +6942,13 @@ function AiSectionOverlay({
7314
6942
  border: `2px solid ${PRIMARY2}`,
7315
6943
  borderRadius: edgeAwareRadius(reviewRect),
7316
6944
  zIndex: 2147483200,
7317
- // The veil itself: swallows clicks so the section stays locked until decided. This
7318
- // stopPropagation only guards the bubble phase; the bridge's capture-phase click
7319
- // handlers additionally bail on `[data-ohw-ai-review]`, without which a click on
7320
- // Accept/Discard resolves to the media beneath and opens the file picker.
6945
+ // The veil itself: swallows clicks so the section stays locked until decided.
7321
6946
  background: "rgba(8, 133, 254, 0.04)",
7322
6947
  pointerEvents: "auto",
7323
6948
  cursor: "default"
7324
6949
  },
7325
6950
  onClick: (e) => e.stopPropagation(),
7326
- children: !reviewButtonsHidden && /* @__PURE__ */ jsxs8(
6951
+ children: /* @__PURE__ */ jsxs8(
7327
6952
  "div",
7328
6953
  {
7329
6954
  style: {
@@ -11223,329 +10848,6 @@ function deleteFooterColumn(column) {
11223
10848
  };
11224
10849
  }
11225
10850
 
11226
- // src/lib/logo-identity.ts
11227
- var LOGO_TEXT_KEYS = ["nav-logo-text", "footer-logo-text", "logo-text"];
11228
- var LOGO_IMAGE_KEYS = ["nav-logo-image", "footer-logo", "footer-logo-image"];
11229
- var LOGO_HREF_KEYS = ["nav-logo-href", "footer-logo-href", "logo-href"];
11230
- var LOGO_PLACEHOLDER_KEY = "logo-is-placeholder";
11231
- var LOGO_ALT_KEY = "logo-alt";
11232
- var LOGO_IMAGE_URL_KEY = "nav-logo-image";
11233
- var PLACEHOLDER_BUSINESS_NAME = "Business name";
11234
- function resolveLogoDisplayText(text) {
11235
- const trimmed = (text ?? "").trim();
11236
- return trimmed || PLACEHOLDER_BUSINESS_NAME;
11237
- }
11238
- function isFooterLogoRoot(root) {
11239
- return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
11240
- }
11241
- function imageKeyForRoot(root) {
11242
- return isFooterLogoRoot(root) ? "footer-logo" : "nav-logo-image";
11243
- }
11244
- function textKeyForRoot(root) {
11245
- return isFooterLogoRoot(root) ? "footer-logo-text" : "nav-logo-text";
11246
- }
11247
- function ensureLogoHrefKey(root) {
11248
- if (!(root instanceof HTMLAnchorElement)) return;
11249
- if (root.hasAttribute("data-ohw-href-key")) return;
11250
- root.setAttribute("data-ohw-href-key", isFooterLogoRoot(root) ? "footer-logo-href" : "nav-logo-href");
11251
- }
11252
- function applyLogoIdentity(text, isPlaceholder) {
11253
- const display = resolveLogoDisplayText(text);
11254
- const placeholder = isPlaceholder || !text.trim() || display === PLACEHOLDER_BUSINESS_NAME;
11255
- for (const key of LOGO_TEXT_KEYS) {
11256
- document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
11257
- if (el.textContent !== display) el.textContent = display;
11258
- });
11259
- }
11260
- for (const key of LOGO_IMAGE_KEYS) {
11261
- document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
11262
- const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
11263
- if (img) img.alt = display;
11264
- });
11265
- }
11266
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((el) => {
11267
- if (placeholder) el.setAttribute("data-ohw-placeholder", "");
11268
- else el.removeAttribute("data-ohw-placeholder");
11269
- });
11270
- return display;
11271
- }
11272
- function applyLogoImage(url, alt) {
11273
- const displayAlt = resolveLogoDisplayText(alt);
11274
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
11275
- ensureLogoHrefKey(root);
11276
- const imageKey = imageKeyForRoot(root);
11277
- const textKey = textKeyForRoot(root);
11278
- 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");
11279
- let textEl = root.querySelector(`[data-ohw-key="${textKey}"]`) ?? root.querySelector('[data-ohw-key="logo-text"]');
11280
- if (url) {
11281
- if (!img) {
11282
- img = document.createElement("img");
11283
- img.setAttribute("data-ohw-editable", "image");
11284
- img.setAttribute("data-ohw-key", imageKey);
11285
- img.alt = displayAlt;
11286
- img.style.height = "";
11287
- img.style.maxHeight = "none";
11288
- img.style.width = "auto";
11289
- img.style.display = "block";
11290
- img.style.objectFit = "contain";
11291
- root.insertBefore(img, root.firstChild);
11292
- } else {
11293
- img.setAttribute("data-ohw-editable", "image");
11294
- img.setAttribute("data-ohw-key", imageKey);
11295
- }
11296
- img.removeAttribute("srcset");
11297
- img.removeAttribute("sizes");
11298
- img.src = url;
11299
- img.alt = displayAlt;
11300
- img.style.display = "block";
11301
- if (textEl) textEl.style.display = "none";
11302
- root.removeAttribute("data-ohw-placeholder");
11303
- return;
11304
- }
11305
- if (img) {
11306
- img.removeAttribute("src");
11307
- img.removeAttribute("srcset");
11308
- img.removeAttribute("sizes");
11309
- img.alt = displayAlt;
11310
- img.style.display = "none";
11311
- }
11312
- if (!textEl) {
11313
- textEl = document.createElement("span");
11314
- textEl.setAttribute("data-ohw-editable", "plain");
11315
- textEl.setAttribute("data-ohw-key", textKey);
11316
- root.appendChild(textEl);
11317
- }
11318
- textEl.style.display = "";
11319
- if (textEl.textContent !== displayAlt) textEl.textContent = displayAlt;
11320
- if (!displayAlt.trim() || displayAlt === PLACEHOLDER_BUSINESS_NAME) {
11321
- root.setAttribute("data-ohw-placeholder", "");
11322
- } else {
11323
- root.removeAttribute("data-ohw-placeholder");
11324
- }
11325
- });
11326
- }
11327
- function applyLogoHref(href) {
11328
- const target = href.trim() || "/";
11329
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
11330
- ensureLogoHrefKey(root);
11331
- if (root instanceof HTMLAnchorElement) {
11332
- root.setAttribute("href", target);
11333
- }
11334
- });
11335
- for (const key of LOGO_HREF_KEYS) setStoredLinkHref(key, target);
11336
- }
11337
- function readLogoIdentityFromDom() {
11338
- let imageUrl = null;
11339
- for (const key of LOGO_IMAGE_KEYS) {
11340
- const el = document.querySelector(`[data-ohw-key="${key}"]`);
11341
- const img = el instanceof HTMLImageElement ? el : el?.querySelector("img");
11342
- const attrSrc = img?.getAttribute("src")?.trim() ?? "";
11343
- if (attrSrc && !attrSrc.startsWith("data:") && img && img.style.display !== "none") {
11344
- imageUrl = img.currentSrc || img.src;
11345
- break;
11346
- }
11347
- }
11348
- let text = PLACEHOLDER_BUSINESS_NAME;
11349
- let isPlaceholder = true;
11350
- for (const key of LOGO_TEXT_KEYS) {
11351
- const el = document.querySelector(`[data-ohw-key="${key}"]`);
11352
- if (el?.textContent?.trim()) {
11353
- text = el.textContent.trim();
11354
- const logoRoot2 = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
11355
- isPlaceholder = logoRoot2?.hasAttribute("data-ohw-placeholder") === true || text === PLACEHOLDER_BUSINESS_NAME;
11356
- break;
11357
- }
11358
- }
11359
- if (imageUrl) {
11360
- const logoImg = document.querySelector(
11361
- '[data-ohw-key="nav-logo-image"], [data-ohw-key="footer-logo"]'
11362
- );
11363
- const alt = logoImg?.alt?.trim() || text;
11364
- isPlaceholder = false;
11365
- const hrefEl = document.querySelector(
11366
- 'a[data-ohw-role="logo"], a[data-ohw-logo], [data-ohw-role="logo"]'
11367
- );
11368
- const href2 = (hrefEl instanceof HTMLAnchorElement ? hrefEl.getAttribute("href") : null) || hrefEl?.closest("a")?.getAttribute("href") || "/";
11369
- return { text, isPlaceholder, imageUrl, href: href2, alt };
11370
- }
11371
- const logoRoot = document.querySelector('[data-ohw-role="logo"], [data-ohw-logo]');
11372
- const href = (logoRoot instanceof HTMLAnchorElement ? logoRoot.getAttribute("href") : null) || logoRoot?.closest("a")?.getAttribute("href") || "/";
11373
- return { text, isPlaceholder, imageUrl: null, href, alt: text };
11374
- }
11375
- function applyLogoFromContent(content) {
11376
- 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);
11377
- if (!hasLogoIdentity) return false;
11378
- const logoText = content[LOGO_TEXT_KEYS[0]] ?? content[LOGO_TEXT_KEYS[1]] ?? readLogoIdentityFromDom().text;
11379
- const logoAlt = content[LOGO_ALT_KEY] ?? logoText;
11380
- const rawLogoImage = content[LOGO_IMAGE_URL_KEY] ?? content["footer-logo"] ?? content["footer-logo-image"] ?? null;
11381
- const logoImageUrl = typeof rawLogoImage === "string" && rawLogoImage.trim() ? rawLogoImage.trim() : null;
11382
- const imageExplicitlyCleared = LOGO_IMAGE_KEYS.some((key) => key in content) && !logoImageUrl;
11383
- const logoIsPlaceholder = LOGO_PLACEHOLDER_KEY in content ? content[LOGO_PLACEHOLDER_KEY] !== "false" : !logoImageUrl && (!logoText.trim() || logoText === PLACEHOLDER_BUSINESS_NAME);
11384
- if (logoImageUrl) {
11385
- applyLogoImage(logoImageUrl, logoAlt);
11386
- } else {
11387
- if (imageExplicitlyCleared) applyLogoImage(null, logoAlt);
11388
- applyLogoIdentity(logoText, logoIsPlaceholder);
11389
- }
11390
- const logoHref = content["nav-logo-href"] ?? content["footer-logo-href"] ?? content["logo-href"];
11391
- if (typeof logoHref === "string" && logoHref.trim()) {
11392
- applyLogoHref(logoHref);
11393
- }
11394
- return true;
11395
- }
11396
-
11397
- // src/lib/logo-size.ts
11398
- var LOGO_SIZE_DEFAULTS = {
11399
- navbar: 28,
11400
- footer: 32
11401
- };
11402
- var LOGO_SIZE_MIN = 16;
11403
- var LOGO_SIZE_MAX = 80;
11404
- var LOGO_SIZE_DESKTOP_KEYS = {
11405
- navbar: "nav-logo-size",
11406
- footer: "footer-logo-size"
11407
- };
11408
- var LOGO_SIZE_MOBILE_KEYS = {
11409
- navbar: "nav-logo-size-mobile",
11410
- footer: "footer-logo-size-mobile"
11411
- };
11412
- var LOGO_SIZE_KEYS = [
11413
- LOGO_SIZE_DESKTOP_KEYS.navbar,
11414
- LOGO_SIZE_DESKTOP_KEYS.footer,
11415
- LOGO_SIZE_MOBILE_KEYS.navbar,
11416
- LOGO_SIZE_MOBILE_KEYS.footer
11417
- ];
11418
- function isFooterLogoRoot2(root) {
11419
- return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
11420
- }
11421
- function getLogoPlacement(root) {
11422
- return isFooterLogoRoot2(root) ? "footer" : "navbar";
11423
- }
11424
- function parseLogoSizePx(raw, fallback) {
11425
- if (raw == null || raw === "") return fallback;
11426
- const n = Number.parseFloat(raw);
11427
- if (!Number.isFinite(n)) return fallback;
11428
- return Math.min(LOGO_SIZE_MAX, Math.max(LOGO_SIZE_MIN, Math.round(n)));
11429
- }
11430
- function isMobileLogoSizeFollowing(content, placement) {
11431
- const raw = content[LOGO_SIZE_MOBILE_KEYS[placement]];
11432
- return raw == null || raw.trim() === "";
11433
- }
11434
- function resolveDesktopLogoSize(content, placement) {
11435
- return parseLogoSizePx(content[LOGO_SIZE_DESKTOP_KEYS[placement]], LOGO_SIZE_DEFAULTS[placement]);
11436
- }
11437
- function resolveMobileLogoSize(content, placement) {
11438
- if (isMobileLogoSizeFollowing(content, placement)) {
11439
- return resolveDesktopLogoSize(content, placement);
11440
- }
11441
- return parseLogoSizePx(
11442
- content[LOGO_SIZE_MOBILE_KEYS[placement]],
11443
- resolveDesktopLogoSize(content, placement)
11444
- );
11445
- }
11446
- function setRootSizeVars(root, desktopPx, mobilePx, following) {
11447
- root.style.setProperty("--ohw-logo-size", `${desktopPx}px`);
11448
- if (following) {
11449
- root.style.removeProperty("--ohw-logo-size-mobile");
11450
- } else {
11451
- root.style.setProperty("--ohw-logo-size-mobile", `${mobilePx}px`);
11452
- }
11453
- root.querySelectorAll("img").forEach((img) => {
11454
- img.style.height = "";
11455
- img.style.maxHeight = "none";
11456
- img.style.width = "auto";
11457
- img.style.objectFit = "contain";
11458
- });
11459
- }
11460
- function applyLogoSizes(content) {
11461
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
11462
- const placement = getLogoPlacement(root);
11463
- const desktop = resolveDesktopLogoSize(content, placement);
11464
- const following = isMobileLogoSizeFollowing(content, placement);
11465
- const mobile = following ? desktop : resolveMobileLogoSize(content, placement);
11466
- setRootSizeVars(root, desktop, mobile, following);
11467
- });
11468
- }
11469
- function applyLogoSizeToPlacement(placement, desktopPx, mobilePx, following) {
11470
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
11471
- if (getLogoPlacement(root) !== placement) return;
11472
- setRootSizeVars(root, desktopPx, mobilePx, following);
11473
- });
11474
- }
11475
- function logoHasUploadedImage(logoEl) {
11476
- if (logoEl.hasAttribute("data-ohw-placeholder")) return false;
11477
- 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");
11478
- if (!img) return false;
11479
- const src = img.getAttribute("src")?.trim() ?? "";
11480
- if (!src || src.startsWith("data:")) return false;
11481
- if (img.style.display === "none") return false;
11482
- return true;
11483
- }
11484
- function getLogoInteractionRect(logoEl) {
11485
- if (logoHasUploadedImage(logoEl)) {
11486
- 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");
11487
- if (img) {
11488
- const r2 = img.getBoundingClientRect();
11489
- if (r2.width > 0 && r2.height > 0) return r2;
11490
- }
11491
- }
11492
- const text = logoEl.querySelector(
11493
- '[data-ohw-key="nav-logo-text"], [data-ohw-key="footer-logo-text"]'
11494
- );
11495
- if (text) {
11496
- const style = window.getComputedStyle(text);
11497
- if (style.display !== "none" && style.visibility !== "hidden") {
11498
- const r2 = text.getBoundingClientRect();
11499
- if (r2.width > 0 && r2.height > 0) return r2;
11500
- }
11501
- }
11502
- return logoEl.getBoundingClientRect();
11503
- }
11504
- function readLogoSizeState(content, placement) {
11505
- const desktopPx = resolveDesktopLogoSize(content, placement);
11506
- const mobileFollowing = isMobileLogoSizeFollowing(content, placement);
11507
- const mobilePx = mobileFollowing ? desktopPx : resolveMobileLogoSize(content, placement);
11508
- return { desktopPx, mobilePx, mobileFollowing };
11509
- }
11510
-
11511
- // src/lib/site-wide-scope.ts
11512
- function getLogoElement(el) {
11513
- const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
11514
- if (marked) return marked;
11515
- if (el.closest('[data-ohw-editable="icon"]')) return null;
11516
- const root = el.closest("nav, [data-ohw-nav-root], footer");
11517
- if (!root) return null;
11518
- const anchor = el.closest("a");
11519
- if (anchor && root.contains(anchor) && !anchor.hasAttribute("data-ohw-href-key") && !anchor.closest("[data-ohw-nav-container]") && Boolean(anchor.querySelector("img") || anchor.matches("img"))) {
11520
- return anchor;
11521
- }
11522
- const img = el.matches("img") ? el : null;
11523
- if (img && !img.closest("[data-ohw-href-key]") && !img.closest("[data-ohw-nav-container]") && (img.closest("footer") || img.closest("nav, [data-ohw-nav-root]"))) {
11524
- return img;
11525
- }
11526
- return null;
11527
- }
11528
- function isInFooter(el) {
11529
- if (!el) return false;
11530
- return Boolean(el.closest("footer") || el.closest('[data-ohw-section="footer"]'));
11531
- }
11532
- function isSiteWideElement(el) {
11533
- if (!el) return false;
11534
- if (getLogoElement(el)) return true;
11535
- if (isInFooter(el)) return true;
11536
- if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-root")) {
11537
- return true;
11538
- }
11539
- if (el.hasAttribute("data-ohw-href-key") && el.closest("nav, [data-ohw-nav-root], [data-ohw-nav-drawer], aside")) {
11540
- return true;
11541
- }
11542
- if (el.closest('[data-ohw-role="navbar-button"]')) return true;
11543
- return false;
11544
- }
11545
- function isSiteWideScopeActive(args) {
11546
- return isSiteWideElement(args.selected) || isSiteWideElement(args.hoveredItem) || isSiteWideElement(args.hoveredNavContainer) || isSiteWideElement(args.active);
11547
- }
11548
-
11549
10851
  // src/lib/add-footer-column.ts
11550
10852
  function buildFooterColumnEditContentPatch(result) {
11551
10853
  return {
@@ -11767,127 +11069,16 @@ function FloatingPanel({
11767
11069
  );
11768
11070
  }
11769
11071
 
11770
- // src/ui/logo-size-panel.tsx
11771
- import { ArrowUpRight, Link as Link2 } from "lucide-react";
11772
- import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
11773
- function SizeSlider({
11774
- value,
11775
- onChange
11776
- }) {
11777
- const pct = (value - LOGO_SIZE_MIN) / (LOGO_SIZE_MAX - LOGO_SIZE_MIN) * 100;
11778
- return /* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-3", children: [
11779
- /* @__PURE__ */ jsxs17("div", { className: "flex w-full items-center gap-2 text-sm font-medium leading-5", children: [
11780
- /* @__PURE__ */ jsx27("span", { className: "min-w-0 flex-1 text-foreground", children: "Size" }),
11781
- /* @__PURE__ */ jsxs17("span", { className: "shrink-0 whitespace-nowrap text-muted-foreground", children: [
11782
- value,
11783
- " px"
11784
- ] })
11785
- ] }),
11786
- /* @__PURE__ */ jsxs17("div", { className: "relative h-2 w-full rounded-full bg-primary-50", children: [
11787
- /* @__PURE__ */ jsx27(
11788
- "div",
11789
- {
11790
- className: "absolute inset-y-0 left-0 rounded-full bg-primary",
11791
- style: { width: `${pct}%` }
11792
- }
11793
- ),
11794
- /* @__PURE__ */ jsx27(
11795
- "input",
11796
- {
11797
- type: "range",
11798
- min: LOGO_SIZE_MIN,
11799
- max: LOGO_SIZE_MAX,
11800
- step: 1,
11801
- value,
11802
- "aria-label": "Logo size",
11803
- className: cn(
11804
- "absolute inset-0 h-full w-full cursor-pointer appearance-none bg-transparent",
11805
- "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:size-5",
11806
- "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2",
11807
- "[&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-background",
11808
- "[&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full",
11809
- "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary",
11810
- "[&::-moz-range-thumb]:bg-background"
11811
- ),
11812
- onChange: (e) => onChange(Number(e.target.value))
11813
- }
11814
- )
11815
- ] })
11816
- ] });
11817
- }
11818
- function LogoSizePanel({
11819
- viewport,
11820
- sizePx,
11821
- mobileFollowing = true,
11822
- onSizeChange,
11823
- onCustomizeMobile,
11824
- onResetMobile,
11825
- onUpdateEverywhere,
11826
- className
11827
- }) {
11828
- const showFollowing = viewport === "mobile" && mobileFollowing;
11829
- const showMobileSlider = viewport === "mobile" && !mobileFollowing;
11830
- const showDesktopSlider = viewport === "desktop";
11831
- return /* @__PURE__ */ jsxs17("div", { className: cn("flex w-full flex-col gap-4", className), children: [
11832
- showFollowing ? /* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-2", children: [
11833
- /* @__PURE__ */ jsxs17("div", { className: "flex items-start gap-1", children: [
11834
- /* @__PURE__ */ jsx27(Link2, { size: 16, className: "mt-0.5 shrink-0 text-foreground", "aria-hidden": true }),
11835
- /* @__PURE__ */ jsx27("p", { className: "text-sm font-semibold leading-5 text-foreground", children: "Following desktop size" })
11836
- ] }),
11837
- /* @__PURE__ */ jsx27("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." }),
11838
- /* @__PURE__ */ jsx27(
11839
- Button,
11840
- {
11841
- type: "button",
11842
- variant: "outline",
11843
- size: "sm",
11844
- className: "h-9 w-full min-w-0 cursor-pointer",
11845
- onClick: onCustomizeMobile,
11846
- children: "Customize for mobile"
11847
- }
11848
- )
11849
- ] }) : null,
11850
- showDesktopSlider || showMobileSlider ? /* @__PURE__ */ jsx27(SizeSlider, { value: sizePx, onChange: onSizeChange }) : null,
11851
- showMobileSlider ? /* @__PURE__ */ jsx27(
11852
- Button,
11853
- {
11854
- type: "button",
11855
- variant: "outline",
11856
- size: "sm",
11857
- className: "h-9 w-full min-w-0 cursor-pointer",
11858
- onClick: onResetMobile,
11859
- children: "Reset to desktop size"
11860
- }
11861
- ) : null,
11862
- /* @__PURE__ */ jsx27("div", { className: "h-px w-full bg-border", role: "separator" }),
11863
- /* @__PURE__ */ jsxs17(
11864
- Button,
11865
- {
11866
- type: "button",
11867
- variant: "outline",
11868
- size: "sm",
11869
- className: "h-9 w-full min-w-0 cursor-pointer gap-1",
11870
- onClick: onUpdateEverywhere,
11871
- children: [
11872
- "Update logo everywhere",
11873
- /* @__PURE__ */ jsx27(ArrowUpRight, { size: 16, "aria-hidden": true })
11874
- ]
11875
- }
11876
- ),
11877
- /* @__PURE__ */ jsx27("p", { className: "text-sm leading-5 text-muted-foreground", children: "Matches the right version to your background." })
11878
- ] });
11879
- }
11880
-
11881
11072
  // src/ui/socials-display-panel.tsx
11882
- import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
11073
+ import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
11883
11074
  function DisplaySwitch({
11884
11075
  label,
11885
11076
  checked,
11886
11077
  disabled,
11887
11078
  onChange
11888
11079
  }) {
11889
- return /* @__PURE__ */ jsxs18("div", { className: "flex w-full items-center gap-2", children: [
11890
- /* @__PURE__ */ jsx28(
11080
+ return /* @__PURE__ */ jsxs17("div", { className: "flex w-full items-center gap-2", children: [
11081
+ /* @__PURE__ */ jsx27(
11891
11082
  "span",
11892
11083
  {
11893
11084
  className: cn(
@@ -11897,7 +11088,7 @@ function DisplaySwitch({
11897
11088
  children: label
11898
11089
  }
11899
11090
  ),
11900
- /* @__PURE__ */ jsx28(
11091
+ /* @__PURE__ */ jsx27(
11901
11092
  "button",
11902
11093
  {
11903
11094
  type: "button",
@@ -11911,7 +11102,7 @@ function DisplaySwitch({
11911
11102
  checked ? "bg-primary" : "bg-primary-50",
11912
11103
  disabled ? "cursor-default opacity-50" : "cursor-pointer"
11913
11104
  ),
11914
- children: /* @__PURE__ */ jsx28(
11105
+ children: /* @__PURE__ */ jsx27(
11915
11106
  "span",
11916
11107
  {
11917
11108
  className: cn(
@@ -11925,8 +11116,8 @@ function DisplaySwitch({
11925
11116
  ] });
11926
11117
  }
11927
11118
  function SocialsDisplayPanel({ display, onChange, className }) {
11928
- return /* @__PURE__ */ jsxs18("div", { className: cn("flex w-full flex-col gap-3", className), children: [
11929
- /* @__PURE__ */ jsx28(
11119
+ return /* @__PURE__ */ jsxs17("div", { className: cn("flex w-full flex-col gap-3", className), children: [
11120
+ /* @__PURE__ */ jsx27(
11930
11121
  DisplaySwitch,
11931
11122
  {
11932
11123
  label: "Text",
@@ -11935,7 +11126,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
11935
11126
  onChange: (text) => onChange({ ...display, text })
11936
11127
  }
11937
11128
  ),
11938
- /* @__PURE__ */ jsx28(
11129
+ /* @__PURE__ */ jsx27(
11939
11130
  DisplaySwitch,
11940
11131
  {
11941
11132
  label: "Icon",
@@ -12496,7 +11687,7 @@ function useNavItemDrag({
12496
11687
 
12497
11688
  // src/ui/footer-container-chrome.tsx
12498
11689
  import { Plus as Plus2 } from "lucide-react";
12499
- import { jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
11690
+ import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
12500
11691
  function FooterContainerChrome({
12501
11692
  rect,
12502
11693
  onAdd,
@@ -12504,7 +11695,7 @@ function FooterContainerChrome({
12504
11695
  }) {
12505
11696
  const chromeGap = 6;
12506
11697
  const buttonMargin = 7;
12507
- return /* @__PURE__ */ jsx29(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx29(
11698
+ return /* @__PURE__ */ jsx28(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx28(
12508
11699
  "div",
12509
11700
  {
12510
11701
  "data-ohw-footer-container-chrome": "",
@@ -12516,8 +11707,8 @@ function FooterContainerChrome({
12516
11707
  width: rect.width + chromeGap * 2,
12517
11708
  height: rect.height + chromeGap * 2
12518
11709
  },
12519
- children: /* @__PURE__ */ jsxs19(Tooltip, { children: [
12520
- /* @__PURE__ */ jsx29(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx29(
11710
+ children: /* @__PURE__ */ jsxs18(Tooltip, { children: [
11711
+ /* @__PURE__ */ jsx28(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx28(
12521
11712
  "button",
12522
11713
  {
12523
11714
  type: "button",
@@ -12536,10 +11727,10 @@ function FooterContainerChrome({
12536
11727
  if (addDisabled) return;
12537
11728
  onAdd();
12538
11729
  },
12539
- children: /* @__PURE__ */ jsx29(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
11730
+ children: /* @__PURE__ */ jsx28(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
12540
11731
  }
12541
11732
  ) }),
12542
- /* @__PURE__ */ jsx29(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
11733
+ /* @__PURE__ */ jsx28(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
12543
11734
  ] })
12544
11735
  }
12545
11736
  ) });
@@ -12722,18 +11913,6 @@ function collectEditableNodes(extraContent, root = document) {
12722
11913
  }
12723
11914
  if (extraContent && !isScoped) {
12724
11915
  applyNavFooterDeleteOverrides(byKey, extraContent);
12725
- for (const key of LOGO_IMAGE_KEYS) {
12726
- if (!(key in extraContent)) continue;
12727
- byKey.set(key, { key, type: "image", text: extraContent[key] ?? "" });
12728
- }
12729
- for (const key of [LOGO_PLACEHOLDER_KEY, LOGO_ALT_KEY]) {
12730
- if (!(key in extraContent)) continue;
12731
- byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
12732
- }
12733
- for (const key of LOGO_SIZE_KEYS) {
12734
- if (!(key in extraContent)) continue;
12735
- byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
12736
- }
12737
11916
  }
12738
11917
  return Array.from(byKey.values());
12739
11918
  }
@@ -13000,13 +12179,13 @@ function deleteSelectedNavFooterItem(deps) {
13000
12179
 
13001
12180
  // src/ui/navbar-container-chrome.tsx
13002
12181
  import { Plus as Plus3 } from "lucide-react";
13003
- import { jsx as jsx30 } from "react/jsx-runtime";
12182
+ import { jsx as jsx29 } from "react/jsx-runtime";
13004
12183
  function NavbarContainerChrome({
13005
12184
  rect,
13006
12185
  onAdd
13007
12186
  }) {
13008
12187
  const chromeGap = 6;
13009
- return /* @__PURE__ */ jsx30(
12188
+ return /* @__PURE__ */ jsx29(
13010
12189
  "div",
13011
12190
  {
13012
12191
  "data-ohw-navbar-container-chrome": "",
@@ -13018,7 +12197,7 @@ function NavbarContainerChrome({
13018
12197
  width: rect.width + chromeGap * 2,
13019
12198
  height: rect.height + chromeGap * 2
13020
12199
  },
13021
- children: /* @__PURE__ */ jsx30(
12200
+ children: /* @__PURE__ */ jsx29(
13022
12201
  "button",
13023
12202
  {
13024
12203
  type: "button",
@@ -13035,7 +12214,7 @@ function NavbarContainerChrome({
13035
12214
  e.stopPropagation();
13036
12215
  onAdd();
13037
12216
  },
13038
- children: /* @__PURE__ */ jsx30(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
12217
+ children: /* @__PURE__ */ jsx29(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
13039
12218
  }
13040
12219
  )
13041
12220
  }
@@ -13044,7 +12223,7 @@ function NavbarContainerChrome({
13044
12223
 
13045
12224
  // src/ui/drop-indicator.tsx
13046
12225
  import * as React10 from "react";
13047
- import { jsx as jsx31 } from "react/jsx-runtime";
12226
+ import { jsx as jsx30 } from "react/jsx-runtime";
13048
12227
  var dropIndicatorVariants = cva(
13049
12228
  "ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
13050
12229
  {
@@ -13068,7 +12247,7 @@ var dropIndicatorVariants = cva(
13068
12247
  );
13069
12248
  var DropIndicator = React10.forwardRef(
13070
12249
  ({ className, direction, state, ...props }, ref) => {
13071
- return /* @__PURE__ */ jsx31(
12250
+ return /* @__PURE__ */ jsx30(
13072
12251
  "div",
13073
12252
  {
13074
12253
  ref,
@@ -13085,7 +12264,7 @@ var DropIndicator = React10.forwardRef(
13085
12264
  DropIndicator.displayName = "DropIndicator";
13086
12265
 
13087
12266
  // src/ui/badge.tsx
13088
- import { jsx as jsx32 } from "react/jsx-runtime";
12267
+ import { jsx as jsx31 } from "react/jsx-runtime";
13089
12268
  var badgeVariants = cva(
13090
12269
  "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",
13091
12270
  {
@@ -13103,12 +12282,12 @@ var badgeVariants = cva(
13103
12282
  }
13104
12283
  );
13105
12284
  function Badge({ className, variant, ...props }) {
13106
- return /* @__PURE__ */ jsx32("div", { className: cn(badgeVariants({ variant }), className), ...props });
12285
+ return /* @__PURE__ */ jsx31("div", { className: cn(badgeVariants({ variant }), className), ...props });
13107
12286
  }
13108
12287
 
13109
12288
  // src/OhhwellsBridge.tsx
13110
- import { Link as Link3 } from "lucide-react";
13111
- import { Fragment as Fragment8, jsx as jsx33, jsxs as jsxs20 } from "react/jsx-runtime";
12289
+ import { Link as Link2 } from "lucide-react";
12290
+ import { Fragment as Fragment8, jsx as jsx32, jsxs as jsxs19 } from "react/jsx-runtime";
13112
12291
  var PRIMARY3 = "#0885FE";
13113
12292
  var IMAGE_FADE_MS = 300;
13114
12293
  function runOpacityFade(el, onDone) {
@@ -13202,10 +12381,21 @@ function parseSchedulingInsertAfter(insertAfter) {
13202
12381
  insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
13203
12382
  };
13204
12383
  }
13205
- function resolveEntryAnchor(entry) {
13206
- if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
13207
- const parsed = parseSchedulingInsertAfter(entry.insertAfter);
13208
- return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
12384
+ function resolveSchedulingInsert(insertAfter, explicitInsertBefore) {
12385
+ const parsed = parseSchedulingInsertAfter(insertAfter);
12386
+ const insertBefore = explicitInsertBefore ?? parsed.insertBefore;
12387
+ const effectiveInsertAfter = insertBefore && parsed.insertBefore === null ? `${insertAfter}${INSERT_BEFORE_MARKER}${insertBefore}` : insertAfter;
12388
+ return { effectiveInsertAfter, insertBefore };
12389
+ }
12390
+ function getSchedulingMountPoint(insertAfter) {
12391
+ const { anchor } = parseSchedulingInsertAfter(insertAfter);
12392
+ let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
12393
+ if (!anchorEl && anchor === "scheduling") {
12394
+ const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
12395
+ anchorEl = widgets.at(-1) ?? null;
12396
+ }
12397
+ if (!anchorEl) return null;
12398
+ return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
13209
12399
  }
13210
12400
  function schedulingMountDepth(insertAfter) {
13211
12401
  if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
@@ -13222,7 +12412,8 @@ function getPageSchedulingEntries(raw) {
13222
12412
  }
13223
12413
  }
13224
12414
  function isSchedulingWidgetMissing(entry) {
13225
- return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
12415
+ const { effectiveInsertAfter } = resolveSchedulingInsert(entry.insertAfter);
12416
+ return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
13226
12417
  }
13227
12418
  function hasMissingSchedulingWidgets(entries) {
13228
12419
  return entries.some(isSchedulingWidgetMissing);
@@ -13252,17 +12443,16 @@ function initSectionsFromContent(content, removeExisting = false) {
13252
12443
  } catch {
13253
12444
  }
13254
12445
  }
13255
- function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
13256
- const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
13257
- const sectionId = schedulingSectionId(widgetId);
12446
+ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId, explicitInsertBefore) {
12447
+ const { effectiveInsertAfter, insertBefore } = resolveSchedulingInsert(insertAfter, explicitInsertBefore);
12448
+ const sectionId = schedulingSectionId(effectiveInsertAfter);
13258
12449
  if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
13259
- const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
13260
- if (!anchorEl) return false;
13261
- const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
12450
+ const mountPoint = getSchedulingMountPoint(effectiveInsertAfter);
12451
+ if (!mountPoint) return false;
13262
12452
  const container = document.createElement("div");
13263
12453
  container.dataset.ohwSectionContainer = "scheduling";
13264
- if (beforeId) {
13265
- const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
12454
+ if (insertBefore) {
12455
+ const beforeAnchor = document.querySelector(`[data-ohw-section="${insertBefore}"]`);
13266
12456
  const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
13267
12457
  if (!beforePoint) return false;
13268
12458
  beforePoint.insertAdjacentElement("beforebegin", container);
@@ -13273,25 +12463,19 @@ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, be
13273
12463
  }
13274
12464
  tail.insertAdjacentElement("afterend", container);
13275
12465
  }
13276
- try {
13277
- const root = createRoot2(container);
13278
- flushSync2(() => {
13279
- root.render(
13280
- /* @__PURE__ */ jsx33(
13281
- SchedulingWidget,
13282
- {
13283
- notifyOnConnect,
13284
- initialScheduleId: scheduleId,
13285
- insertAfter: widgetId
13286
- }
13287
- )
13288
- );
13289
- });
13290
- } catch (err) {
13291
- console.error("[ow:scheduling] render threw", err);
13292
- container.remove();
13293
- return false;
13294
- }
12466
+ const root = createRoot2(container);
12467
+ flushSync2(() => {
12468
+ root.render(
12469
+ /* @__PURE__ */ jsx32(
12470
+ SchedulingWidget,
12471
+ {
12472
+ notifyOnConnect,
12473
+ initialScheduleId: scheduleId,
12474
+ insertAfter: effectiveInsertAfter
12475
+ }
12476
+ )
12477
+ );
12478
+ });
13295
12479
  const tracker = getSectionsTracker();
13296
12480
  let sections = [];
13297
12481
  try {
@@ -13299,12 +12483,10 @@ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, be
13299
12483
  } catch {
13300
12484
  }
13301
12485
  const inEditor = typeof window !== "undefined" && window.self !== window.top;
13302
- if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
12486
+ if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === effectiveInsertAfter)) {
13303
12487
  sections.push({
13304
12488
  type: "scheduling",
13305
- insertAfter: widgetId,
13306
- anchorId,
13307
- beforeId: beforeId ?? null,
12489
+ insertAfter: effectiveInsertAfter,
13308
12490
  pagePath: window.location.pathname,
13309
12491
  ...scheduleId ? { scheduleId } : {}
13310
12492
  });
@@ -13318,8 +12500,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
13318
12500
  for (let i = pending.length - 1; i >= 0; i--) {
13319
12501
  const entry = pending[i];
13320
12502
  const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
13321
- const { anchorId, beforeId } = resolveEntryAnchor(entry);
13322
- if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
12503
+ if (mountSchedulingWidget(entry.insertAfter, shouldNotify, entry.scheduleId)) {
13323
12504
  pending.splice(i, 1);
13324
12505
  }
13325
12506
  }
@@ -13463,13 +12644,6 @@ function isInsideLinkEditor(target) {
13463
12644
  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"]')
13464
12645
  );
13465
12646
  }
13466
- function isInsideFloatingPanel(target) {
13467
- return Boolean(target.closest("[data-ohw-floating-panel]"));
13468
- }
13469
- function isPointOverFloatingPanel(clientX, clientY) {
13470
- const el = document.elementFromPoint(clientX, clientY);
13471
- return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
13472
- }
13473
12647
  function getHrefKeyFromElement(el) {
13474
12648
  if (!el) return null;
13475
12649
  const anchor = el.closest("[data-ohw-href-key]");
@@ -13517,7 +12691,8 @@ function isNavItemPointerTarget(el) {
13517
12691
  function getNavigationItemAnchor(el) {
13518
12692
  const anchor = el.matches("[data-ohw-href-key]") ? el : el.closest("[data-ohw-href-key]");
13519
12693
  if (!anchor) return null;
13520
- if (!anchor.querySelector('[data-ohw-editable="text"]') && !getSocialItem(anchor)) return null;
12694
+ if (!anchor.matches('[data-ohw-editable="text"], [data-ohw-editable="plain"]') && !anchor.querySelector('[data-ohw-editable="text"], [data-ohw-editable="plain"]') && !getSocialItem(anchor))
12695
+ return null;
13521
12696
  if (!isNavItemPointerTarget(anchor)) return null;
13522
12697
  return anchor;
13523
12698
  }
@@ -13707,7 +12882,7 @@ function getNavigationSelectionParent(el) {
13707
12882
  if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
13708
12883
  return getFooterLinksContainer();
13709
12884
  }
13710
- 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)) {
12885
+ if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
13711
12886
  return getNavigationRoot(el);
13712
12887
  }
13713
12888
  return null;
@@ -13953,7 +13128,7 @@ function EditGlowChrome({
13953
13128
  hideHandle = false
13954
13129
  }) {
13955
13130
  const GAP = SELECTION_CHROME_GAP2;
13956
- return /* @__PURE__ */ jsxs20(
13131
+ return /* @__PURE__ */ jsxs19(
13957
13132
  "div",
13958
13133
  {
13959
13134
  ref: elRef,
@@ -13968,7 +13143,7 @@ function EditGlowChrome({
13968
13143
  zIndex: 2147483646
13969
13144
  },
13970
13145
  children: [
13971
- /* @__PURE__ */ jsx33(
13146
+ /* @__PURE__ */ jsx32(
13972
13147
  "div",
13973
13148
  {
13974
13149
  style: {
@@ -13981,7 +13156,7 @@ function EditGlowChrome({
13981
13156
  }
13982
13157
  }
13983
13158
  ),
13984
- reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx33(
13159
+ reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx32(
13985
13160
  "div",
13986
13161
  {
13987
13162
  "data-ohw-drag-handle-container": "",
@@ -13993,7 +13168,7 @@ function EditGlowChrome({
13993
13168
  transform: "translate(calc(-100% - 7px), -50%)",
13994
13169
  pointerEvents: dragDisabled ? "none" : "auto"
13995
13170
  },
13996
- children: /* @__PURE__ */ jsx33(
13171
+ children: /* @__PURE__ */ jsx32(
13997
13172
  DragHandle,
13998
13173
  {
13999
13174
  "aria-label": `Reorder ${reorderHrefKey}`,
@@ -14203,7 +13378,7 @@ function FloatingToolbar({
14203
13378
  return () => ro.disconnect();
14204
13379
  }, [showEditLink, activeCommands]);
14205
13380
  const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
14206
- return /* @__PURE__ */ jsx33(
13381
+ return /* @__PURE__ */ jsx32(
14207
13382
  "div",
14208
13383
  {
14209
13384
  ref: setRefs,
@@ -14215,12 +13390,12 @@ function FloatingToolbar({
14215
13390
  zIndex: 2147483647,
14216
13391
  pointerEvents: "auto"
14217
13392
  },
14218
- children: /* @__PURE__ */ jsxs20(CustomToolbar, { children: [
14219
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs20(React11.Fragment, { children: [
14220
- gi > 0 && /* @__PURE__ */ jsx33(CustomToolbarDivider, {}),
13393
+ children: /* @__PURE__ */ jsxs19(CustomToolbar, { children: [
13394
+ TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs19(React11.Fragment, { children: [
13395
+ gi > 0 && /* @__PURE__ */ jsx32(CustomToolbarDivider, {}),
14221
13396
  btns.map((btn) => {
14222
13397
  const isActive = activeCommands.has(btn.cmd);
14223
- return /* @__PURE__ */ jsx33(
13398
+ return /* @__PURE__ */ jsx32(
14224
13399
  CustomToolbarButton,
14225
13400
  {
14226
13401
  title: btn.title,
@@ -14229,7 +13404,7 @@ function FloatingToolbar({
14229
13404
  e.preventDefault();
14230
13405
  onCommand(btn.cmd);
14231
13406
  },
14232
- children: /* @__PURE__ */ jsx33(
13407
+ children: /* @__PURE__ */ jsx32(
14233
13408
  "svg",
14234
13409
  {
14235
13410
  width: "16",
@@ -14250,7 +13425,7 @@ function FloatingToolbar({
14250
13425
  );
14251
13426
  })
14252
13427
  ] }, gi)),
14253
- showEditLink ? /* @__PURE__ */ jsx33(
13428
+ showEditLink ? /* @__PURE__ */ jsx32(
14254
13429
  CustomToolbarButton,
14255
13430
  {
14256
13431
  type: "button",
@@ -14264,7 +13439,7 @@ function FloatingToolbar({
14264
13439
  e.preventDefault();
14265
13440
  e.stopPropagation();
14266
13441
  },
14267
- children: /* @__PURE__ */ jsx33(Link3, { className: "size-4 shrink-0", "aria-hidden": true })
13442
+ children: /* @__PURE__ */ jsx32(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
14268
13443
  }
14269
13444
  ) : null
14270
13445
  ] })
@@ -14281,7 +13456,7 @@ function StateToggle({
14281
13456
  states,
14282
13457
  onStateChange
14283
13458
  }) {
14284
- return /* @__PURE__ */ jsx33(
13459
+ return /* @__PURE__ */ jsx32(
14285
13460
  ToggleGroup,
14286
13461
  {
14287
13462
  "data-ohw-state-toggle": "",
@@ -14295,12 +13470,11 @@ function StateToggle({
14295
13470
  left: rect.right - 8,
14296
13471
  transform: "translateX(-100%)"
14297
13472
  },
14298
- children: states.map((state) => /* @__PURE__ */ jsx33(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
13473
+ children: states.map((state) => /* @__PURE__ */ jsx32(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
14299
13474
  }
14300
13475
  );
14301
13476
  }
14302
13477
  var contentCache = /* @__PURE__ */ new Map();
14303
- var fetchedContentPaths = /* @__PURE__ */ new Set();
14304
13478
  function resolveSubdomain(subdomainFromQuery) {
14305
13479
  if (subdomainFromQuery) return subdomainFromQuery;
14306
13480
  if (typeof window !== "undefined") {
@@ -14395,14 +13569,8 @@ function OhhwellsBridge() {
14395
13569
  });
14396
13570
  const selectFrameRef = useRef9(() => {
14397
13571
  });
14398
- const selectLogoRef = useRef9(() => {
14399
- });
14400
- const openLogoSizePanelRef = useRef9(() => {
14401
- });
14402
13572
  const deselectRef = useRef9(() => {
14403
13573
  });
14404
- const closeFloatingPanelOnlyRef = useRef9(() => {
14405
- });
14406
13574
  const reselectNavigationItemRef = useRef9(() => {
14407
13575
  });
14408
13576
  const commitNavigationTextEditRef = useRef9(() => {
@@ -14463,6 +13631,11 @@ function OhhwellsBridge() {
14463
13631
  const [isItemDragging, setIsItemDragging] = useState11(false);
14464
13632
  const [isFooterFrameSelection, setIsFooterFrameSelection] = useState11(false);
14465
13633
  isFooterFrameSelectionRef.current = isFooterFrameSelection;
13634
+ const [floatingPanel, setFloatingPanel] = useState11(null);
13635
+ const floatingPanelOpenRef = useRef9(false);
13636
+ floatingPanelOpenRef.current = floatingPanel !== null;
13637
+ const [floatingPanelPos, setFloatingPanelPos] = useState11(null);
13638
+ const [parentScrollSnap, setParentScrollSnap] = useState11(null);
14466
13639
  const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState11(null);
14467
13640
  const [footerHeadingVisible, setFooterHeadingVisible] = useState11(null);
14468
13641
  const footerDragRef = useRef9(null);
@@ -14477,16 +13650,7 @@ function OhhwellsBridge() {
14477
13650
  const addNavAfterAnchorRef = useRef9(null);
14478
13651
  const editContentRef = useRef9({});
14479
13652
  const aiSectionsRef = useRef9("");
14480
- const brandKitRef = useRef9("");
14481
- const stylesRef = useRef9("");
14482
13653
  const pendingDeleteUndoRef = useRef9(null);
14483
- const [floatingPanel, setFloatingPanel] = useState11(null);
14484
- const floatingPanelOpenRef = useRef9(false);
14485
- const setFloatingPanelRef = useRef9(setFloatingPanel);
14486
- const [floatingPanelPos, setFloatingPanelPos] = useState11(null);
14487
- const [logoSizeDraft, setLogoSizeDraft] = useState11(null);
14488
- const [editorViewport, setEditorViewport] = useState11("desktop");
14489
- const [parentScrollSnap, setParentScrollSnap] = useState11(null);
14490
13654
  const [sitePages, setSitePages] = useState11([]);
14491
13655
  const [sectionsByPath, setSectionsByPath] = useState11({});
14492
13656
  const sectionsPrefetchGenRef = useRef9(0);
@@ -14495,18 +13659,7 @@ function OhhwellsBridge() {
14495
13659
  const linkPopoverOpenRef = useRef9(false);
14496
13660
  const linkPopoverGraceUntilRef = useRef9(0);
14497
13661
  setLinkPopoverRef.current = setLinkPopover;
14498
- setFloatingPanelRef.current = setFloatingPanel;
14499
13662
  linkPopoverSessionRef.current = linkPopover;
14500
- floatingPanelOpenRef.current = Boolean(floatingPanel);
14501
- useEffect12(() => {
14502
- const syncViewport = () => {
14503
- const next = window.innerWidth <= 480 ? "mobile" : "desktop";
14504
- setEditorViewport((prev) => prev === next ? prev : next);
14505
- };
14506
- syncViewport();
14507
- window.addEventListener("resize", syncViewport);
14508
- return () => window.removeEventListener("resize", syncViewport);
14509
- }, []);
14510
13663
  const {
14511
13664
  navDragRef,
14512
13665
  navDropSlots,
@@ -14729,10 +13882,6 @@ function OhhwellsBridge() {
14729
13882
  setIsItemDragging(false);
14730
13883
  hoveredNavContainerRef.current = null;
14731
13884
  setHoveredNavContainerRect(null);
14732
- hoveredItemElRef.current = null;
14733
- setHoveredItemRect(null);
14734
- setFloatingPanel(null);
14735
- setLogoSizeDraft(null);
14736
13885
  if (!activeElRef.current) {
14737
13886
  setNavGroupForceOpen(null, false);
14738
13887
  setToolbarRect(null);
@@ -15438,8 +14587,6 @@ function OhhwellsBridge() {
15438
14587
  setToolbarRect(anchor.getBoundingClientRect());
15439
14588
  setToolbarShowEditLink(false);
15440
14589
  setActiveCommands(/* @__PURE__ */ new Set());
15441
- setFloatingPanel(null);
15442
- setLogoSizeDraft(null);
15443
14590
  }, [deactivate, markSelected]);
15444
14591
  const selectFrame = useCallback7((el) => {
15445
14592
  if (!isNavigationContainer(el)) return;
@@ -15489,51 +14636,7 @@ function OhhwellsBridge() {
15489
14636
  setToolbarRect(el.getBoundingClientRect());
15490
14637
  setToolbarShowEditLink(false);
15491
14638
  setActiveCommands(/* @__PURE__ */ new Set());
15492
- setFloatingPanel(null);
15493
- setLogoSizeDraft(null);
15494
14639
  }, [deactivate, markSelected, postToParent2]);
15495
- const selectLogo = useCallback7(
15496
- (logoEl) => {
15497
- if (activeElRef.current) deactivate();
15498
- selectedElRef.current = logoEl;
15499
- selectedHrefKeyRef.current = null;
15500
- selectedFooterColAttrRef.current = null;
15501
- markSelected(logoEl);
15502
- setSelectedIsCta(false);
15503
- setSelectedIsSocial(false);
15504
- setSelectedIsSocialsRow(false);
15505
- clearHrefKeyHover(logoEl);
15506
- hoveredNavContainerRef.current = null;
15507
- setHoveredNavContainerRect(null);
15508
- setHoveredItemRect(null);
15509
- hoveredItemElRef.current = null;
15510
- siblingHintElRef.current = null;
15511
- setSiblingHintRect(null);
15512
- setSiblingHintRects([]);
15513
- setIsItemDragging(false);
15514
- setReorderHrefKey(null);
15515
- setReorderDragDisabled(false);
15516
- setIsFooterFrameSelection(false);
15517
- setToolbarVariant("logo");
15518
- setToolbarRect(getLogoInteractionRect(logoEl));
15519
- setToolbarShowEditLink(false);
15520
- setActiveCommands(/* @__PURE__ */ new Set());
15521
- },
15522
- [deactivate, markSelected]
15523
- );
15524
- const openLogoSizePanel = useCallback7((logoEl) => {
15525
- const placement = getLogoPlacement(logoEl);
15526
- const draft = readLogoSizeState(editContentRef.current, placement);
15527
- setLogoSizeDraft(draft);
15528
- setParentScrollSnap(parentScrollRef.current);
15529
- setFloatingPanel({
15530
- key: `logo-size:${placement}`,
15531
- title: "Logo",
15532
- context: placement === "navbar" ? "Navbar" : "Footer",
15533
- kind: "logo-size",
15534
- placement
15535
- });
15536
- }, []);
15537
14640
  const openSocialsDisplayPanel = useCallback7((row) => {
15538
14641
  setParentScrollSnap(parentScrollRef.current);
15539
14642
  setFloatingPanel({
@@ -15569,53 +14672,13 @@ function OhhwellsBridge() {
15569
14672
  );
15570
14673
  const closeFloatingPanelOnly = useCallback7(() => {
15571
14674
  setFloatingPanel(null);
15572
- setLogoSizeDraft(null);
15573
14675
  }, []);
14676
+ const closeFloatingPanelOnlyRef = useRef9(closeFloatingPanelOnly);
14677
+ closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
15574
14678
  const closeFloatingPanelAndDeselect = useCallback7(() => {
15575
14679
  setFloatingPanel(null);
15576
- setLogoSizeDraft(null);
15577
14680
  deselectRef.current();
15578
14681
  }, []);
15579
- const persistLogoSizeDraft = useCallback7(
15580
- (placement, draft) => {
15581
- const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
15582
- const mobileKey = LOGO_SIZE_MOBILE_KEYS[placement];
15583
- const nodes = [
15584
- { key: desktopKey, text: String(draft.desktopPx) }
15585
- ];
15586
- if (draft.mobileFollowing) {
15587
- nodes.push({ key: mobileKey, text: "" });
15588
- } else {
15589
- nodes.push({ key: mobileKey, text: String(draft.mobilePx) });
15590
- }
15591
- editContentRef.current = {
15592
- ...editContentRef.current,
15593
- [desktopKey]: String(draft.desktopPx),
15594
- [mobileKey]: draft.mobileFollowing ? "" : String(draft.mobilePx)
15595
- };
15596
- applyLogoSizeToPlacement(
15597
- placement,
15598
- draft.desktopPx,
15599
- draft.mobileFollowing ? draft.desktopPx : draft.mobilePx,
15600
- draft.mobileFollowing
15601
- );
15602
- postToParent2({ type: "ow:change", nodes });
15603
- requestAnimationFrame(() => {
15604
- const selected = selectedElRef.current;
15605
- if (!selected || toolbarVariantRef.current !== "logo") return;
15606
- const rect = getLogoInteractionRect(selected);
15607
- setToolbarRect(rect);
15608
- if (glowElRef.current) {
15609
- const GAP = SELECTION_CHROME_GAP2;
15610
- glowElRef.current.style.top = `${rect.top - GAP}px`;
15611
- glowElRef.current.style.left = `${rect.left - GAP}px`;
15612
- glowElRef.current.style.width = `${rect.width + GAP * 2}px`;
15613
- glowElRef.current.style.height = `${rect.height + GAP * 2}px`;
15614
- }
15615
- });
15616
- },
15617
- [postToParent2]
15618
- );
15619
14682
  const activate = useCallback7((el, options) => {
15620
14683
  if (activeElRef.current === el) return;
15621
14684
  if (isIconEditable(el)) return;
@@ -15696,37 +14759,7 @@ function OhhwellsBridge() {
15696
14759
  deactivateRef.current = deactivate;
15697
14760
  selectRef.current = select;
15698
14761
  selectFrameRef.current = selectFrame;
15699
- selectLogoRef.current = selectLogo;
15700
- openLogoSizePanelRef.current = openLogoSizePanel;
15701
14762
  deselectRef.current = deselect;
15702
- closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
15703
- const lastSiteWideScopeRef = useRef9(null);
15704
- useEffect12(() => {
15705
- if (!isEditMode) {
15706
- if (lastSiteWideScopeRef.current !== false) {
15707
- lastSiteWideScopeRef.current = false;
15708
- postToParent2({ type: "ow:site-wide-scope", active: false });
15709
- }
15710
- return;
15711
- }
15712
- const active = isSiteWideScopeActive({
15713
- selected: selectedElRef.current,
15714
- hoveredItem: hoveredItemElRef.current,
15715
- hoveredNavContainer: hoveredNavContainerRef.current,
15716
- active: activeElRef.current
15717
- });
15718
- if (lastSiteWideScopeRef.current === active) return;
15719
- lastSiteWideScopeRef.current = active;
15720
- postToParent2({ type: "ow:site-wide-scope", active });
15721
- }, [
15722
- isEditMode,
15723
- hoveredItemRect,
15724
- hoveredNavContainerRect,
15725
- toolbarVariant,
15726
- toolbarRect,
15727
- isFooterFrameSelection,
15728
- postToParent2
15729
- ]);
15730
14763
  useLayoutEffect4(() => {
15731
14764
  if (!subdomain || isEditMode) {
15732
14765
  setFetchState("done");
@@ -15738,23 +14771,9 @@ function OhhwellsBridge() {
15738
14771
  aiSectionsRef.current = content[AI_SECTIONS_KEY];
15739
14772
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
15740
14773
  }
15741
- if (typeof content[BRAND_KIT_KEY] === "string") {
15742
- brandKitRef.current = content[BRAND_KIT_KEY];
15743
- applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
15744
- }
15745
- if (typeof content[STYLE_STORE_KEY] === "string") {
15746
- stylesRef.current = content[STYLE_STORE_KEY];
15747
- applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
15748
- }
15749
- applyBrandChrome(content);
15750
14774
  for (const [key, val] of Object.entries(content)) {
15751
14775
  if (key === "__ohw_sections") continue;
15752
14776
  if (key === AI_SECTIONS_KEY) continue;
15753
- if (key === LOGO_PLACEHOLDER_KEY) continue;
15754
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
15755
- if (key === BRAND_KIT_KEY) continue;
15756
- if (key === STYLE_STORE_KEY) continue;
15757
- if (BRAND_CHROME_KEYS.has(key)) continue;
15758
14777
  if (applyVideoSettingNode(key, val)) continue;
15759
14778
  if (applyCarouselNode(key, val)) continue;
15760
14779
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -15789,8 +14808,6 @@ function OhhwellsBridge() {
15789
14808
  });
15790
14809
  applyLinkByKey(key, val);
15791
14810
  }
15792
- applyLogoFromContent(content);
15793
- applyLogoSizes(content);
15794
14811
  reconcileNavbarItemsFromContent(content);
15795
14812
  reconcileFooterOrderFromContent(content);
15796
14813
  reconcileSocialsFromContent(content);
@@ -15811,9 +14828,7 @@ function OhhwellsBridge() {
15811
14828
  let cancelled = false;
15812
14829
  setFetchState("loading");
15813
14830
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
15814
- const initialPath = pathname;
15815
- fetchedContentPaths.add(`${subdomain}::${initialPath}`);
15816
- fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
14831
+ fetch(`${apiUrl}/api/public/sites/${subdomain}/content`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
15817
14832
  if (cancelled) return;
15818
14833
  const content = data?.content ?? {};
15819
14834
  contentCache.set(subdomain, content);
@@ -15837,21 +14852,8 @@ function OhhwellsBridge() {
15837
14852
  initSectionInstancesFromContent(content, window.location.pathname);
15838
14853
  observer?.disconnect();
15839
14854
  try {
15840
- applyBrandChrome(content);
15841
- if (typeof content[BRAND_KIT_KEY] === "string") {
15842
- applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
15843
- }
15844
- if (typeof content[STYLE_STORE_KEY] === "string") {
15845
- applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
15846
- }
15847
14855
  for (const [key, val] of Object.entries(content)) {
15848
14856
  if (key === "__ohw_sections") continue;
15849
- if (key === LOGO_PLACEHOLDER_KEY) continue;
15850
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
15851
- if (key === BRAND_KIT_KEY) continue;
15852
- if (key === STYLE_STORE_KEY) continue;
15853
- if (key === STYLE_STORE_KEY) continue;
15854
- if (BRAND_CHROME_KEYS.has(key)) continue;
15855
14857
  if (applyVideoSettingNode(key, val)) continue;
15856
14858
  if (applyCarouselNode(key, val)) continue;
15857
14859
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -15872,7 +14874,6 @@ function OhhwellsBridge() {
15872
14874
  });
15873
14875
  applyLinkByKey(key, val);
15874
14876
  }
15875
- applyLogoFromContent(content);
15876
14877
  reconcileNavbarItemsFromContent(content);
15877
14878
  reconcileFooterOrderFromContent(content);
15878
14879
  reconcileSocialsFromContent(content);
@@ -15887,17 +14888,6 @@ function OhhwellsBridge() {
15887
14888
  debounceTimer = setTimeout(applyFromCache, 150);
15888
14889
  };
15889
14890
  applyFromCache();
15890
- const pathCacheKey = `${subdomain}::${pathname}`;
15891
- if (!fetchedContentPaths.has(pathCacheKey)) {
15892
- fetchedContentPaths.add(pathCacheKey);
15893
- const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
15894
- fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
15895
- if (!data?.content) return;
15896
- contentCache.set(subdomain, data.content);
15897
- applyFromCache();
15898
- }).catch(() => {
15899
- });
15900
- }
15901
14891
  observer = new MutationObserver(scheduleApply);
15902
14892
  observer.observe(document.body, { childList: true, subtree: true });
15903
14893
  return () => {
@@ -15991,31 +14981,26 @@ function OhhwellsBridge() {
15991
14981
  }, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
15992
14982
  useEffect12(() => {
15993
14983
  if (!isEditMode) return;
15994
- let lastPosted = 0;
15995
14984
  const measure = () => {
15996
14985
  const h = document.body.scrollHeight;
15997
- if (h > 50 && Math.abs(h - lastPosted) > 1) {
15998
- lastPosted = h;
15999
- postToParent2({ type: "ow:height", height: h });
16000
- }
16001
- };
16002
- let raf = null;
16003
- const schedule = () => {
16004
- if (raf != null) return;
16005
- raf = requestAnimationFrame(() => {
16006
- raf = null;
16007
- measure();
16008
- });
14986
+ if (h > 50) postToParent2({ type: "ow:height", height: h });
16009
14987
  };
16010
14988
  const t1 = setTimeout(measure, 50);
16011
14989
  const t2 = setTimeout(measure, 500);
16012
- const ro = new ResizeObserver(schedule);
16013
- ro.observe(document.body);
14990
+ let lastWidth = window.innerWidth;
14991
+ let resizeTimer = null;
14992
+ const handleResize = () => {
14993
+ if (window.innerWidth === lastWidth) return;
14994
+ lastWidth = window.innerWidth;
14995
+ if (resizeTimer) clearTimeout(resizeTimer);
14996
+ resizeTimer = setTimeout(measure, 150);
14997
+ };
14998
+ window.addEventListener("resize", handleResize);
16014
14999
  return () => {
16015
15000
  clearTimeout(t1);
16016
15001
  clearTimeout(t2);
16017
- if (raf != null) cancelAnimationFrame(raf);
16018
- ro.disconnect();
15002
+ if (resizeTimer) clearTimeout(resizeTimer);
15003
+ window.removeEventListener("resize", handleResize);
16019
15004
  };
16020
15005
  }, [pathname, isEditMode, postToParent2]);
16021
15006
  useEffect12(() => {
@@ -16165,12 +15150,10 @@ function OhhwellsBridge() {
16165
15150
  return;
16166
15151
  }
16167
15152
  const target = e.target;
16168
- if (target.closest("[data-ohw-ai-review]")) return;
16169
15153
  if (target.closest("[data-ohw-toolbar]")) return;
16170
15154
  if (target.closest("[data-ohw-state-toggle]")) return;
16171
15155
  if (target.closest("[data-ohw-max-badge]")) return;
16172
15156
  if (isInsideLinkEditor(target)) return;
16173
- if (isInsideFloatingPanel(target)) return;
16174
15157
  if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
16175
15158
  const beneath = document.elementsFromPoint(e.clientX, e.clientY).find(
16176
15159
  (el) => el instanceof HTMLElement && !el.closest("[data-ohw-bridge-root]") && el.closest("[data-ohw-section]") != null
@@ -16234,21 +15217,6 @@ function OhhwellsBridge() {
16234
15217
  return;
16235
15218
  }
16236
15219
  }
16237
- const logoEl = getLogoElement(target);
16238
- if (logoEl) {
16239
- e.preventDefault();
16240
- e.stopPropagation();
16241
- if (!logoHasUploadedImage(logoEl)) {
16242
- deselectRef.current();
16243
- deactivateRef.current();
16244
- const identity = readLogoIdentityFromDom();
16245
- postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
16246
- return;
16247
- }
16248
- selectLogoRef.current(logoEl);
16249
- openLogoSizePanelRef.current(logoEl);
16250
- return;
16251
- }
16252
15220
  const editable = target.closest("[data-ohw-editable]");
16253
15221
  if (editable) {
16254
15222
  if (editable.dataset.ohwEditable === "link") {
@@ -16401,12 +15369,10 @@ function OhhwellsBridge() {
16401
15369
  };
16402
15370
  const handleDblClick = (e) => {
16403
15371
  const target = e.target;
16404
- if (target.closest("[data-ohw-ai-review]")) return;
16405
15372
  if (target.closest("[data-ohw-toolbar]")) return;
16406
15373
  if (target.closest("[data-ohw-state-toggle]")) return;
16407
15374
  if (target.closest("[data-ohw-max-badge]")) return;
16408
15375
  if (isInsideLinkEditor(target)) return;
16409
- if (isInsideFloatingPanel(target)) return;
16410
15376
  if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
16411
15377
  return;
16412
15378
  }
@@ -16434,14 +15400,11 @@ function OhhwellsBridge() {
16434
15400
  setHoveredNavContainerRect(null);
16435
15401
  return;
16436
15402
  }
16437
- if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || isInsideFloatingPanel(target) || isPointOverFloatingPanel(e.clientX, e.clientY)) {
15403
+ if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || target.closest("[data-ohw-floating-panel]")) {
16438
15404
  hoveredItemElRef.current = null;
16439
15405
  setHoveredItemRect(null);
16440
15406
  hoveredNavContainerRef.current = null;
16441
15407
  setHoveredNavContainerRect(null);
16442
- siblingHintElRef.current = null;
16443
- setSiblingHintRect(null);
16444
- setSiblingHintRects([]);
16445
15408
  return;
16446
15409
  }
16447
15410
  {
@@ -16451,7 +15414,7 @@ function OhhwellsBridge() {
16451
15414
  const allowFooterLinksHover = toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn;
16452
15415
  if (allowNavContainerHover) {
16453
15416
  const navContainer = target.closest("[data-ohw-nav-container]");
16454
- if (navContainer && !getNavigationItemAnchor(target) && !getLogoElement(target)) {
15417
+ if (navContainer && !getNavigationItemAnchor(target)) {
16455
15418
  hoveredNavContainerRef.current = navContainer;
16456
15419
  setHoveredNavContainerRect(navContainer.getBoundingClientRect());
16457
15420
  hoveredItemElRef.current = null;
@@ -16480,15 +15443,6 @@ function OhhwellsBridge() {
16480
15443
  setHoveredNavContainerRect(null);
16481
15444
  }
16482
15445
  }
16483
- const logoEl = getLogoElement(target);
16484
- if (logoEl) {
16485
- hoveredNavContainerRef.current = null;
16486
- setHoveredNavContainerRect(null);
16487
- if (selectedElRef.current === logoEl) return;
16488
- hoveredItemElRef.current = logoEl;
16489
- setHoveredItemRect(getLogoInteractionRect(logoEl));
16490
- return;
16491
- }
16492
15446
  const navAnchor = getNavigationItemAnchor(target);
16493
15447
  if (navAnchor) {
16494
15448
  hoveredNavContainerRef.current = null;
@@ -16526,11 +15480,6 @@ function OhhwellsBridge() {
16526
15480
  setHoveredItemRect(hoverTarget.getBoundingClientRect());
16527
15481
  } else if (!isInsideNavigationItem(editable)) {
16528
15482
  hoverTarget.setAttribute("data-ohw-hovered", "");
16529
- if (editable.closest("footer") || editable.closest('[data-ohw-section="footer"]')) {
16530
- hoveredNavContainerRef.current = null;
16531
- setHoveredNavContainerRect(null);
16532
- hoveredItemElRef.current = editable;
16533
- }
16534
15483
  }
16535
15484
  }
16536
15485
  };
@@ -16566,18 +15515,6 @@ function OhhwellsBridge() {
16566
15515
  }
16567
15516
  return;
16568
15517
  }
16569
- const logoEl = getLogoElement(target);
16570
- if (logoEl) {
16571
- const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
16572
- if (related2 && (logoEl === related2 || logoEl.contains(related2) || related2.closest?.('[data-ohw-role="logo"], [data-ohw-logo]'))) {
16573
- return;
16574
- }
16575
- if (hoveredItemElRef.current === logoEl) {
16576
- hoveredItemElRef.current = null;
16577
- setHoveredItemRect(null);
16578
- }
16579
- return;
16580
- }
16581
15518
  const editable = target.closest("[data-ohw-editable]");
16582
15519
  if (!editable) return;
16583
15520
  const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
@@ -16598,13 +15535,6 @@ function OhhwellsBridge() {
16598
15535
  }
16599
15536
  } else {
16600
15537
  hoverTarget.removeAttribute("data-ohw-hovered");
16601
- if (hoveredItemElRef.current === editable) {
16602
- const stillOnEditable = related instanceof Element && related.closest("[data-ohw-editable]") === editable;
16603
- if (!stillOnEditable) {
16604
- hoveredItemElRef.current = null;
16605
- setHoveredItemRect(null);
16606
- }
16607
- }
16608
15538
  }
16609
15539
  }
16610
15540
  };
@@ -16721,26 +15651,6 @@ function OhhwellsBridge() {
16721
15651
  hoveredNavContainerRef.current = null;
16722
15652
  setHoveredNavContainerRect(null);
16723
15653
  }
16724
- const logoCandidates = [
16725
- ...document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]'),
16726
- ...document.querySelectorAll("nav a:not([data-ohw-href-key]), [data-ohw-nav-root] a:not([data-ohw-href-key])"),
16727
- ...document.querySelectorAll("footer img")
16728
- ];
16729
- const seenLogos = /* @__PURE__ */ new Set();
16730
- for (const candidate of logoCandidates) {
16731
- const logo = getLogoElement(candidate);
16732
- if (!logo || seenLogos.has(logo)) continue;
16733
- seenLogos.add(logo);
16734
- const r2 = logo.getBoundingClientRect();
16735
- if (x < r2.left || x > r2.right || y < r2.top || y > r2.bottom) continue;
16736
- hoveredNavContainerRef.current = null;
16737
- setHoveredNavContainerRect(null);
16738
- if (selectedElRef.current !== logo) {
16739
- hoveredItemElRef.current = logo;
16740
- setHoveredItemRect(getLogoInteractionRect(logo));
16741
- }
16742
- return;
16743
- }
16744
15654
  const navContainers = Array.from(
16745
15655
  document.querySelectorAll("[data-ohw-nav-container]")
16746
15656
  );
@@ -16826,7 +15736,7 @@ function OhhwellsBridge() {
16826
15736
  }
16827
15737
  };
16828
15738
  const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
16829
- if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
15739
+ if (linkPopoverOpenRef.current) {
16830
15740
  if (hoveredImageRef.current) {
16831
15741
  hoveredImageRef.current = null;
16832
15742
  hoveredImageHasTextOverlapRef.current = false;
@@ -17080,7 +15990,7 @@ function OhhwellsBridge() {
17080
15990
  }
17081
15991
  };
17082
15992
  const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
17083
- if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY) || document.documentElement.hasAttribute("data-ohw-section-picking")) {
15993
+ if (linkPopoverOpenRef.current || document.documentElement.hasAttribute("data-ohw-section-picking")) {
17084
15994
  if (activeStateElRef.current) {
17085
15995
  activeStateElRef.current.removeAttribute("data-ohw-state-hovered");
17086
15996
  activeStateElRef.current = null;
@@ -17146,21 +16056,16 @@ function OhhwellsBridge() {
17146
16056
  setSectionGap(null);
17147
16057
  }
17148
16058
  };
16059
+ const pointOwnedByFloatingPanel = (clientX, clientY) => {
16060
+ if (document.documentElement.hasAttribute("data-ohw-panel-dragging")) return true;
16061
+ const panel = document.querySelector("[data-ohw-floating-panel]");
16062
+ if (!panel) return false;
16063
+ const rect = panel.getBoundingClientRect();
16064
+ return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
16065
+ };
17149
16066
  const handleMouseMove = (e) => {
17150
16067
  const { clientX, clientY } = e;
17151
- if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
17152
- hoveredItemElRef.current = null;
17153
- setHoveredItemRect(null);
17154
- hoveredNavContainerRef.current = null;
17155
- setHoveredNavContainerRect(null);
17156
- siblingHintElRef.current = null;
17157
- setSiblingHintRect(null);
17158
- setSiblingHintRects([]);
17159
- dismissImageHover();
17160
- clearImageHover();
17161
- setSectionGap(null);
17162
- return;
17163
- }
16068
+ if (pointOwnedByFloatingPanel(clientX, clientY)) return;
17164
16069
  probeSectionGapAt(clientX, clientY);
17165
16070
  probeImageAt(clientX, clientY);
17166
16071
  probeHoverCardsAt(clientX, clientY);
@@ -17169,11 +16074,7 @@ function OhhwellsBridge() {
17169
16074
  if (e.data?.type !== "ow:pointer-sync") return;
17170
16075
  const { clientX, clientY } = e.data;
17171
16076
  if (typeof clientX !== "number" || typeof clientY !== "number") return;
17172
- if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
17173
- dismissImageHover();
17174
- clearImageHover();
17175
- return;
17176
- }
16077
+ if (pointOwnedByFloatingPanel(clientX, clientY)) return;
17177
16078
  probeSectionGapAt(clientX, clientY);
17178
16079
  probeImageAt(clientX, clientY);
17179
16080
  probeHoverCardsAt(clientX, clientY);
@@ -17423,15 +16324,6 @@ function OhhwellsBridge() {
17423
16324
  aiSectionsRef.current = content[AI_SECTIONS_KEY];
17424
16325
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
17425
16326
  }
17426
- if (typeof content[BRAND_KIT_KEY] === "string") {
17427
- brandKitRef.current = content[BRAND_KIT_KEY];
17428
- applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
17429
- }
17430
- if (typeof content[STYLE_STORE_KEY] === "string") {
17431
- stylesRef.current = content[STYLE_STORE_KEY];
17432
- applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
17433
- }
17434
- applyBrandChrome(content);
17435
16327
  let sectionsJson = null;
17436
16328
  for (const [key, val] of Object.entries(content)) {
17437
16329
  if (key === "__ohw_sections") {
@@ -17439,11 +16331,6 @@ function OhhwellsBridge() {
17439
16331
  continue;
17440
16332
  }
17441
16333
  if (key === AI_SECTIONS_KEY) continue;
17442
- if (key === LOGO_PLACEHOLDER_KEY) continue;
17443
- if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
17444
- if (key === BRAND_KIT_KEY) continue;
17445
- if (key === STYLE_STORE_KEY) continue;
17446
- if (BRAND_CHROME_KEYS.has(key)) continue;
17447
16334
  if (applyVideoSettingNode(key, val)) continue;
17448
16335
  if (applyCarouselNode(key, val)) continue;
17449
16336
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -17463,8 +16350,6 @@ function OhhwellsBridge() {
17463
16350
  });
17464
16351
  applyLinkByKey(key, val);
17465
16352
  }
17466
- applyLogoFromContent(content);
17467
- applyLogoSizes(content);
17468
16353
  if (sectionsJson) {
17469
16354
  initSectionsFromContent({ __ohw_sections: sectionsJson }, true);
17470
16355
  sectionsLoadedRef.current = true;
@@ -17480,58 +16365,6 @@ function OhhwellsBridge() {
17480
16365
  if (hydratedHeight > 50) postToParentRef.current({ type: "ow:height", height: hydratedHeight });
17481
16366
  postToParentRef.current({ type: "ow:hydrate-done" });
17482
16367
  };
17483
- const handleUpdateLogoIdentity = (e) => {
17484
- if (e.data?.type !== "ow:update-logo-identity") return;
17485
- const rawText = typeof e.data.text === "string" ? e.data.text : "";
17486
- const alt = typeof e.data.alt === "string" ? e.data.alt : rawText;
17487
- const href = typeof e.data.href === "string" ? e.data.href : void 0;
17488
- const imageProvided = "image" in e.data;
17489
- const imageUrl = imageProvided && typeof e.data.image === "string" && e.data.image.trim() ? e.data.image.trim() : imageProvided ? null : void 0;
17490
- let isPlaceholder = e.data.isPlaceholder !== false;
17491
- if (imageUrl) isPlaceholder = false;
17492
- else if (imageProvided && imageUrl === null) {
17493
- isPlaceholder = e.data.isPlaceholder === true || !rawText.trim() || resolveLogoDisplayText(rawText) === PLACEHOLDER_BUSINESS_NAME;
17494
- }
17495
- const display = applyLogoIdentity(rawText, isPlaceholder);
17496
- const displayAlt = resolveLogoDisplayText(alt || display);
17497
- if (imageUrl !== void 0) {
17498
- applyLogoImage(imageUrl, displayAlt);
17499
- } else {
17500
- for (const key of LOGO_IMAGE_KEYS) {
17501
- document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
17502
- const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
17503
- if (img) img.alt = displayAlt;
17504
- });
17505
- }
17506
- }
17507
- if (href !== void 0) {
17508
- applyLogoHref(href);
17509
- applyLinkByKey("nav-logo-href", href);
17510
- applyLinkByKey("footer-logo-href", href);
17511
- applyLinkByKey("logo-href", href);
17512
- }
17513
- const nodes = [
17514
- ...LOGO_TEXT_KEYS.map((key) => ({ key, text: display })),
17515
- { key: LOGO_PLACEHOLDER_KEY, text: isPlaceholder ? "true" : "false" },
17516
- { key: LOGO_ALT_KEY, text: displayAlt }
17517
- ];
17518
- if (imageUrl !== void 0) {
17519
- if (imageUrl) {
17520
- for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: imageUrl });
17521
- } else {
17522
- for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: "" });
17523
- }
17524
- }
17525
- if (href !== void 0) {
17526
- for (const key of LOGO_HREF_KEYS) nodes.push({ key, text: href.trim() || "/" });
17527
- }
17528
- editContentRef.current = {
17529
- ...editContentRef.current,
17530
- ...Object.fromEntries(nodes.map(({ key, text }) => [key, text]))
17531
- };
17532
- applyLogoSizes(editContentRef.current);
17533
- postToParentRef.current({ type: "ow:change", nodes });
17534
- };
17535
16368
  window.addEventListener("message", handleHydrate);
17536
16369
  const postAiSectionsChanged = () => {
17537
16370
  postToParentRef.current({
@@ -17545,10 +16378,7 @@ function OhhwellsBridge() {
17545
16378
  const payload = e.data.payload;
17546
16379
  if (!payload || typeof payload.id !== "string" || !isRenderableTree(payload.tree)) return;
17547
16380
  const previous = aiSectionsRef.current;
17548
- const nextState = applyTreeToState(parseAiSectionsState(previous), {
17549
- ...payload,
17550
- path: payload.path ?? window.location.pathname
17551
- });
16381
+ const nextState = applyTreeToState(parseAiSectionsState(previous), payload);
17552
16382
  const nextValue = serializeAiSectionsState(nextState);
17553
16383
  aiSectionsRef.current = nextValue;
17554
16384
  applyAiSectionsToDom(nextState);
@@ -17585,42 +16415,12 @@ function OhhwellsBridge() {
17585
16415
  const value = typeof e.data.value === "string" ? e.data.value : "";
17586
16416
  aiSectionsRef.current = value;
17587
16417
  applyAiSectionsToDom(parseAiSectionsState(value));
17588
- applyStylesToDom(parseStyleStore(stylesRef.current));
17589
16418
  const restoredHeight = document.documentElement.scrollHeight;
17590
16419
  if (restoredHeight > 50) postToParentRef.current({ type: "ow:height", height: restoredHeight });
17591
16420
  postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: value }] });
17592
16421
  postAiSectionsChanged();
17593
16422
  };
17594
16423
  window.addEventListener("message", handleAiSetSections);
17595
- const handleAiSetBrand = (e) => {
17596
- if (e.data?.type !== "ow:ai-set-brand") return;
17597
- const value = typeof e.data.value === "string" ? e.data.value : "";
17598
- const previous = brandKitRef.current;
17599
- brandKitRef.current = value;
17600
- applyBrandToDom(parseBrandKit(value));
17601
- if (aiSectionsRef.current) applyAiSectionsToDom(parseAiSectionsState(aiSectionsRef.current));
17602
- applyStylesToDom(parseStyleStore(stylesRef.current));
17603
- postToParentRef.current({ type: "ow:change", nodes: [{ key: BRAND_KIT_KEY, text: value }] });
17604
- postToParentRef.current({ type: "ow:ai-brand-applied", previous, value });
17605
- };
17606
- window.addEventListener("message", handleAiSetBrand);
17607
- const handleAiSetStyles = (e) => {
17608
- if (e.data?.type !== "ow:ai-set-styles") return;
17609
- const value = typeof e.data.value === "string" ? e.data.value : "";
17610
- const previous = stylesRef.current;
17611
- stylesRef.current = value;
17612
- applyStylesToDom(parseStyleStore(value));
17613
- postToParentRef.current({ type: "ow:change", nodes: [{ key: STYLE_STORE_KEY, text: value }] });
17614
- postToParentRef.current({ type: "ow:ai-styles-applied", previous, value });
17615
- };
17616
- window.addEventListener("message", handleAiSetStyles);
17617
- const handleGetBrand = (e) => {
17618
- if (e.data?.type !== "ow:get-brand") return;
17619
- const template = deriveTemplateBrand();
17620
- const value = brandKitRef.current || (template ? JSON.stringify(template) : "");
17621
- postToParentRef.current({ type: "ow:brand-value", value });
17622
- };
17623
- window.addEventListener("message", handleGetBrand);
17624
16424
  const handleDeactivate = (e) => {
17625
16425
  if (e.data?.type !== "ow:deactivate") return;
17626
16426
  if (Date.now() < linkPopoverGraceUntilRef.current) return;
@@ -17629,12 +16429,6 @@ function OhhwellsBridge() {
17629
16429
  closeLinkPopoverRef.current();
17630
16430
  return;
17631
16431
  }
17632
- if (floatingPanelOpenRef.current) {
17633
- setFloatingPanelRef.current(null);
17634
- deselectRef.current();
17635
- deactivateRef.current();
17636
- return;
17637
- }
17638
16432
  deselectRef.current();
17639
16433
  deactivateRef.current();
17640
16434
  };
@@ -17688,10 +16482,6 @@ function OhhwellsBridge() {
17688
16482
  return;
17689
16483
  }
17690
16484
  if (selectedElRef.current) {
17691
- if (toolbarVariantRef.current === "logo") {
17692
- deselectRef.current();
17693
- return;
17694
- }
17695
16485
  if (toolbarVariantRef.current === "select-frame") {
17696
16486
  const parent2 = getNavigationSelectionParent(selectedElRef.current);
17697
16487
  if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
@@ -17731,10 +16521,6 @@ function OhhwellsBridge() {
17731
16521
  return;
17732
16522
  }
17733
16523
  if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
17734
- if (toolbarVariantRef.current === "logo") {
17735
- deselectRef.current();
17736
- return;
17737
- }
17738
16524
  if (toolbarVariantRef.current === "select-frame") {
17739
16525
  const parent2 = getNavigationSelectionParent(selectedElRef.current);
17740
16526
  if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
@@ -17812,8 +16598,7 @@ function OhhwellsBridge() {
17812
16598
  const handleScroll = () => {
17813
16599
  const focusEl = activeElRef.current ?? selectedElRef.current;
17814
16600
  if (focusEl) {
17815
- const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
17816
- const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
16601
+ const r2 = activeElRef.current ? getEditMeasureEl(activeElRef.current).getBoundingClientRect() : focusEl.getBoundingClientRect();
17817
16602
  applyToolbarPos(r2);
17818
16603
  setToolbarRect(r2);
17819
16604
  setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
@@ -17823,9 +16608,7 @@ function OhhwellsBridge() {
17823
16608
  setToggleState((prev) => prev ? { ...prev, rect } : null);
17824
16609
  }
17825
16610
  if (hoveredItemElRef.current) {
17826
- const hoverEl = hoveredItemElRef.current;
17827
- const logo = getLogoElement(hoverEl);
17828
- setHoveredItemRect(logo ? getLogoInteractionRect(logo) : hoverEl.getBoundingClientRect());
16611
+ setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
17829
16612
  }
17830
16613
  if (hoveredNavContainerRef.current) {
17831
16614
  setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
@@ -17869,12 +16652,6 @@ function OhhwellsBridge() {
17869
16652
  if (aiSectionsRef.current) {
17870
16653
  nodes.push({ key: AI_SECTIONS_KEY, type: "sections", text: aiSectionsRef.current });
17871
16654
  }
17872
- if (stylesRef.current) {
17873
- nodes.push({ key: STYLE_STORE_KEY, type: "styles", text: stylesRef.current });
17874
- }
17875
- if (brandKitRef.current) {
17876
- nodes.push({ key: BRAND_KIT_KEY, type: "brand", text: brandKitRef.current });
17877
- }
17878
16655
  postToParentRef.current({ type: "ow:save-result", nodes });
17879
16656
  };
17880
16657
  const handleInsertSection = (e) => {
@@ -17885,12 +16662,8 @@ function OhhwellsBridge() {
17885
16662
  if (inserted) {
17886
16663
  const tracker = getSectionsTracker();
17887
16664
  postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
17888
- const reportHeight = () => {
17889
- const h = document.body.scrollHeight;
17890
- if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
17891
- };
17892
- reportHeight();
17893
- setTimeout(reportHeight, 500);
16665
+ const h = document.documentElement.scrollHeight;
16666
+ if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
17894
16667
  }
17895
16668
  };
17896
16669
  const handleSwitchSchedule = (e) => {
@@ -18083,17 +16856,13 @@ function OhhwellsBridge() {
18083
16856
  if (e.data?.type !== "ow:parent-scroll") return;
18084
16857
  const { iframeOffsetTop, headerH, canvasH } = e.data;
18085
16858
  parentScrollRef.current = { iframeOffsetTop, headerH, canvasH };
18086
- if (floatingPanelOpenRef.current) {
18087
- setParentScrollSnap({ iframeOffsetTop, headerH, canvasH });
18088
- }
18089
16859
  if (visibleViewportRef.current) {
18090
16860
  applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
18091
16861
  }
18092
16862
  const focusEl = activeElRef.current ?? selectedElRef.current;
18093
16863
  if (focusEl) {
18094
- const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
18095
- const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
18096
- applyToolbarPos(r2);
16864
+ const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
16865
+ applyToolbarPos(measureEl.getBoundingClientRect());
18097
16866
  }
18098
16867
  };
18099
16868
  const handleClickAt = (e) => {
@@ -18118,25 +16887,6 @@ function OhhwellsBridge() {
18118
16887
  postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "", elementType: stateCardImage.dataset.ohwEditable ?? "image" });
18119
16888
  return;
18120
16889
  }
18121
- const logoAtPoint = Array.from(
18122
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]')
18123
- ).map((el) => getLogoElement(el)).find((logo) => {
18124
- if (!logo) return false;
18125
- const r2 = logo.getBoundingClientRect();
18126
- return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
18127
- });
18128
- if (logoAtPoint) {
18129
- if (!logoHasUploadedImage(logoAtPoint)) {
18130
- deselectRef.current();
18131
- deactivateRef.current();
18132
- const identity = readLogoIdentityFromDom();
18133
- postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
18134
- return;
18135
- }
18136
- selectLogoRef.current(logoAtPoint);
18137
- openLogoSizePanelRef.current(logoAtPoint);
18138
- return;
18139
- }
18140
16890
  const textEditable = Array.from(
18141
16891
  document.querySelectorAll(NON_MEDIA_SELECTOR)
18142
16892
  ).find((el) => {
@@ -18208,14 +16958,6 @@ function OhhwellsBridge() {
18208
16958
  window.addEventListener("message", handleParentScroll);
18209
16959
  window.addEventListener("message", handlePointerSync);
18210
16960
  window.addEventListener("message", handleClickAt);
18211
- window.addEventListener("message", handleUpdateLogoIdentity);
18212
- const handleViewMode = (e) => {
18213
- if (e.data?.type !== "ow:view-mode") return;
18214
- const mode = e.data.mode === "Mobile" || e.data.mode === "mobile" ? "mobile" : "desktop";
18215
- setEditorViewport(mode);
18216
- applyLogoSizes(editContentRef.current);
18217
- };
18218
- window.addEventListener("message", handleViewMode);
18219
16961
  const handleViewportResize = () => {
18220
16962
  if (visibleViewportRef.current) {
18221
16963
  applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
@@ -18271,15 +17013,10 @@ function OhhwellsBridge() {
18271
17013
  window.removeEventListener("resize", handleViewportResize);
18272
17014
  window.removeEventListener("message", handlePointerSync);
18273
17015
  window.removeEventListener("message", handleClickAt);
18274
- window.removeEventListener("message", handleUpdateLogoIdentity);
18275
- window.removeEventListener("message", handleViewMode);
18276
17016
  window.removeEventListener("message", handleHydrate);
18277
17017
  window.removeEventListener("message", handleAiApplyTree);
18278
17018
  window.removeEventListener("message", handleAiDeleteSection);
18279
17019
  window.removeEventListener("message", handleAiSetSections);
18280
- window.removeEventListener("message", handleAiSetBrand);
18281
- window.removeEventListener("message", handleAiSetStyles);
18282
- window.removeEventListener("message", handleGetBrand);
18283
17020
  window.removeEventListener("message", handleDeactivate);
18284
17021
  window.removeEventListener("message", handleToastAction);
18285
17022
  window.removeEventListener("message", handleUiEscape);
@@ -18483,7 +17220,7 @@ function OhhwellsBridge() {
18483
17220
  postToParent2({
18484
17221
  type: "ow:ready",
18485
17222
  version: "1",
18486
- bridgeVersion: "0.1.62",
17223
+ bridgeVersion: "0.1.61",
18487
17224
  path: pathname,
18488
17225
  nodes: collectEditableNodes(editContentRef.current),
18489
17226
  sections
@@ -18878,10 +17615,10 @@ function OhhwellsBridge() {
18878
17615
  [postToParent2]
18879
17616
  );
18880
17617
  return bridgeRoot ? createPortal2(
18881
- /* @__PURE__ */ jsxs20(Fragment8, { children: [
18882
- /* @__PURE__ */ jsx33("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
18883
- isEditMode && /* @__PURE__ */ jsx33(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
18884
- Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx33(
17618
+ /* @__PURE__ */ jsxs19(Fragment8, { children: [
17619
+ /* @__PURE__ */ jsx32("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
17620
+ isEditMode && /* @__PURE__ */ jsx32(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
17621
+ Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx32(
18885
17622
  MediaOverlay,
18886
17623
  {
18887
17624
  hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
@@ -18892,7 +17629,7 @@ function OhhwellsBridge() {
18892
17629
  },
18893
17630
  `uploading-${key}`
18894
17631
  )),
18895
- mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx33(
17632
+ mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx32(
18896
17633
  MediaOverlay,
18897
17634
  {
18898
17635
  hover: mediaHover,
@@ -18901,11 +17638,11 @@ function OhhwellsBridge() {
18901
17638
  onVideoSettingsChange: handleVideoSettingsChange
18902
17639
  }
18903
17640
  ),
18904
- carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
18905
- siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
18906
- siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
18907
- isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
18908
- isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
17641
+ carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx32(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
17642
+ siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx32(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
17643
+ siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx32(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
17644
+ isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ jsx32(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
17645
+ isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx32(
18909
17646
  "div",
18910
17647
  {
18911
17648
  className: "pointer-events-none fixed z-2147483646",
@@ -18915,7 +17652,7 @@ function OhhwellsBridge() {
18915
17652
  width: slot.width,
18916
17653
  height: slot.height
18917
17654
  },
18918
- children: /* @__PURE__ */ jsx33(
17655
+ children: /* @__PURE__ */ jsx32(
18919
17656
  DropIndicator,
18920
17657
  {
18921
17658
  direction: slot.direction,
@@ -18926,7 +17663,7 @@ function OhhwellsBridge() {
18926
17663
  },
18927
17664
  `footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
18928
17665
  )),
18929
- isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
17666
+ isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx32(
18930
17667
  "div",
18931
17668
  {
18932
17669
  className: "pointer-events-none fixed z-2147483646",
@@ -18936,7 +17673,7 @@ function OhhwellsBridge() {
18936
17673
  width: slot.width,
18937
17674
  height: slot.height
18938
17675
  },
18939
- children: /* @__PURE__ */ jsx33(
17676
+ children: /* @__PURE__ */ jsx32(
18940
17677
  DropIndicator,
18941
17678
  {
18942
17679
  direction: slot.direction,
@@ -18947,11 +17684,11 @@ function OhhwellsBridge() {
18947
17684
  },
18948
17685
  `nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
18949
17686
  )),
18950
- hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
18951
- hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
18952
- hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
18953
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx33(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
18954
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx33(
17687
+ hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx32(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
17688
+ hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx32(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
17689
+ hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx32(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
17690
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx32(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
17691
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx32(
18955
17692
  FooterContainerChrome,
18956
17693
  {
18957
17694
  rect: toolbarRect,
@@ -18959,7 +17696,7 @@ function OhhwellsBridge() {
18959
17696
  addDisabled: !canAddFooterColumn()
18960
17697
  }
18961
17698
  ),
18962
- toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ jsx33(
17699
+ toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ jsx32(
18963
17700
  ItemInteractionLayer,
18964
17701
  {
18965
17702
  rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
@@ -18971,10 +17708,10 @@ function OhhwellsBridge() {
18971
17708
  dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
18972
17709
  onDragHandleDragStart: handleItemDragStart,
18973
17710
  onDragHandleDragEnd: handleItemDragEnd,
18974
- onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
18975
- onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
18976
- itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection,
18977
- toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ jsx33(
17711
+ onItemPointerDown: handleItemChromePointerDown,
17712
+ onItemClick: handleItemChromeClick,
17713
+ itemDragSurface: !isFooterFrameSelection,
17714
+ toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ jsx32(
18978
17715
  ItemActionToolbar,
18979
17716
  {
18980
17717
  onEditLink: openLinkPopoverForSelected,
@@ -19010,8 +17747,8 @@ function OhhwellsBridge() {
19010
17747
  ) : void 0
19011
17748
  }
19012
17749
  ),
19013
- toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ jsxs20(Fragment8, { children: [
19014
- /* @__PURE__ */ jsx33(
17750
+ toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ jsxs19(Fragment8, { children: [
17751
+ /* @__PURE__ */ jsx32(
19015
17752
  EditGlowChrome,
19016
17753
  {
19017
17754
  rect: toolbarRect,
@@ -19021,7 +17758,7 @@ function OhhwellsBridge() {
19021
17758
  hideHandle: isItemDragging
19022
17759
  }
19023
17760
  ),
19024
- /* @__PURE__ */ jsx33(
17761
+ /* @__PURE__ */ jsx32(
19025
17762
  FloatingToolbar,
19026
17763
  {
19027
17764
  rect: toolbarRect,
@@ -19034,7 +17771,7 @@ function OhhwellsBridge() {
19034
17771
  }
19035
17772
  )
19036
17773
  ] }),
19037
- maxBadge && /* @__PURE__ */ jsxs20(
17774
+ maxBadge && /* @__PURE__ */ jsxs19(
19038
17775
  "div",
19039
17776
  {
19040
17777
  "data-ohw-max-badge": "",
@@ -19060,7 +17797,7 @@ function OhhwellsBridge() {
19060
17797
  ]
19061
17798
  }
19062
17799
  ),
19063
- toggleState && !linkPopover && /* @__PURE__ */ jsx33(
17800
+ toggleState && !linkPopover && /* @__PURE__ */ jsx32(
19064
17801
  StateToggle,
19065
17802
  {
19066
17803
  rect: toggleState.rect,
@@ -19069,15 +17806,15 @@ function OhhwellsBridge() {
19069
17806
  onStateChange: handleStateChange
19070
17807
  }
19071
17808
  ),
19072
- sectionGap && !linkPopover && /* @__PURE__ */ jsxs20(
17809
+ sectionGap && !linkPopover && /* @__PURE__ */ jsxs19(
19073
17810
  "div",
19074
17811
  {
19075
17812
  "data-ohw-section-insert-line": "",
19076
17813
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
19077
17814
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
19078
17815
  children: [
19079
- /* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
19080
- /* @__PURE__ */ jsx33(
17816
+ /* @__PURE__ */ jsx32("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
17817
+ /* @__PURE__ */ jsx32(
19081
17818
  Badge,
19082
17819
  {
19083
17820
  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",
@@ -19094,11 +17831,11 @@ function OhhwellsBridge() {
19094
17831
  children: "Add Section"
19095
17832
  }
19096
17833
  ),
19097
- /* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } })
17834
+ /* @__PURE__ */ jsx32("div", { className: "flex-1 bg-primary", style: { height: 3 } })
19098
17835
  ]
19099
17836
  }
19100
17837
  ),
19101
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx33(
17838
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx32(
19102
17839
  LinkPopover,
19103
17840
  {
19104
17841
  panelRef: linkPopoverPanelRef,
@@ -19115,7 +17852,7 @@ function OhhwellsBridge() {
19115
17852
  },
19116
17853
  linkPopover.key
19117
17854
  ) : null,
19118
- floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx33(
17855
+ floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx32(
19119
17856
  FloatingPanel,
19120
17857
  {
19121
17858
  open: true,
@@ -19125,7 +17862,7 @@ function OhhwellsBridge() {
19125
17862
  onPositionChange: setFloatingPanelPos,
19126
17863
  parentScroll: parentScrollSnap ?? parentScrollRef.current,
19127
17864
  onClose: closeFloatingPanelOnly,
19128
- children: /* @__PURE__ */ jsx33(
17865
+ children: /* @__PURE__ */ jsx32(
19129
17866
  SocialsDisplayPanel,
19130
17867
  {
19131
17868
  display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
@@ -19136,115 +17873,11 @@ function OhhwellsBridge() {
19136
17873
  }
19137
17874
  )
19138
17875
  }
19139
- ) : null,
19140
- floatingPanel && floatingPanel.kind === "logo-size" && logoSizeDraft ? /* @__PURE__ */ jsx33(
19141
- FloatingPanel,
19142
- {
19143
- open: true,
19144
- title: floatingPanel.title,
19145
- context: floatingPanel.context,
19146
- position: floatingPanelPos,
19147
- onPositionChange: setFloatingPanelPos,
19148
- parentScroll: parentScrollSnap ?? parentScrollRef.current,
19149
- onClose: closeFloatingPanelAndDeselect,
19150
- children: /* @__PURE__ */ jsx33(
19151
- LogoSizePanel,
19152
- {
19153
- viewport: editorViewport,
19154
- sizePx: editorViewport === "mobile" && !logoSizeDraft.mobileFollowing ? logoSizeDraft.mobilePx : logoSizeDraft.desktopPx,
19155
- mobileFollowing: logoSizeDraft.mobileFollowing,
19156
- onSizeChange: (px) => {
19157
- const next = editorViewport === "mobile" ? { ...logoSizeDraft, mobilePx: px, mobileFollowing: false } : {
19158
- ...logoSizeDraft,
19159
- desktopPx: px,
19160
- mobilePx: logoSizeDraft.mobileFollowing ? px : logoSizeDraft.mobilePx
19161
- };
19162
- setLogoSizeDraft(next);
19163
- persistLogoSizeDraft(floatingPanel.placement, next);
19164
- },
19165
- onCustomizeMobile: () => {
19166
- const next = {
19167
- ...logoSizeDraft,
19168
- mobileFollowing: false,
19169
- mobilePx: logoSizeDraft.desktopPx
19170
- };
19171
- setLogoSizeDraft(next);
19172
- persistLogoSizeDraft(floatingPanel.placement, next);
19173
- },
19174
- onResetMobile: () => {
19175
- const next = {
19176
- ...logoSizeDraft,
19177
- mobileFollowing: true,
19178
- mobilePx: logoSizeDraft.desktopPx
19179
- };
19180
- setLogoSizeDraft(next);
19181
- persistLogoSizeDraft(floatingPanel.placement, next);
19182
- },
19183
- onUpdateEverywhere: () => {
19184
- const identity = readLogoIdentityFromDom();
19185
- postToParent2({ type: "ow:open-logo-settings", ...identity });
19186
- }
19187
- }
19188
- )
19189
- }
19190
17876
  ) : null
19191
17877
  ] }),
19192
17878
  bridgeRoot
19193
17879
  ) : null;
19194
17880
  }
19195
-
19196
- // src/ui/EmptySection.tsx
19197
- import Link4 from "next/link";
19198
- import { Fragment as Fragment9, jsx as jsx34, jsxs as jsxs21 } from "react/jsx-runtime";
19199
- function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
19200
- return /* @__PURE__ */ jsxs21(Fragment9, { children: [
19201
- /* @__PURE__ */ jsx34(
19202
- "p",
19203
- {
19204
- style: {
19205
- fontFamily: "var(--brand-font-body)",
19206
- fontSize: "0.75rem",
19207
- fontWeight: 500,
19208
- letterSpacing: "0.15em",
19209
- textTransform: "uppercase",
19210
- color: "var(--brand-accent)",
19211
- marginBottom: "1.5rem"
19212
- },
19213
- children: /* @__PURE__ */ jsx34(Link4, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ jsx34("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
19214
- }
19215
- ),
19216
- /* @__PURE__ */ jsx34(
19217
- "h1",
19218
- {
19219
- style: {
19220
- fontFamily: "var(--brand-font-heading)",
19221
- fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
19222
- lineHeight: 1.1,
19223
- letterSpacing: "-0.025em",
19224
- color: "var(--brand-text)",
19225
- marginBottom: "1rem"
19226
- },
19227
- ...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
19228
- children: title
19229
- }
19230
- ),
19231
- /* @__PURE__ */ jsx34(
19232
- "p",
19233
- {
19234
- style: {
19235
- fontFamily: "var(--brand-font-body)",
19236
- fontSize: "1rem",
19237
- lineHeight: 1.7,
19238
- fontWeight: 300,
19239
- color: "var(--brand-text-muted)",
19240
- maxWidth: "340px"
19241
- },
19242
- ...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
19243
- children: "This page doesn't have any content yet."
19244
- }
19245
- )
19246
- ] });
19247
- }
19248
17881
  export {
19249
17882
  AI_DEFAULT_BRAND,
19250
17883
  AI_TREE_SCHEMA_VERSIONS,
@@ -19261,7 +17894,6 @@ export {
19261
17894
  DropdownMenuItem,
19262
17895
  DropdownMenuSeparator,
19263
17896
  DropdownMenuTrigger,
19264
- EmptySection,
19265
17897
  ItemActionToolbar,
19266
17898
  ItemInteractionLayer,
19267
17899
  LinkEditorPanel,