@ohhwells/bridge 0.1.61-next.172 → 0.1.61

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,272 +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
- function ensureStyleSheet() {
310
- let el = document.getElementById(STYLE_SHEET_ID);
311
- if (!el) {
312
- el = document.createElement("style");
313
- el.id = STYLE_SHEET_ID;
314
- document.head.appendChild(el);
315
- }
316
- const css = styleSheetCss();
317
- if (el.textContent !== css) el.textContent = css;
318
- }
319
- function clearSectionAttrs(root) {
320
- for (const attr of Object.values(SECTION_ATTRS)) {
321
- for (const el of Array.from(root.querySelectorAll(`[${attr}]`))) el.removeAttribute(attr);
322
- }
323
- for (const el of Array.from(root.querySelectorAll("[data-ohw-style-bgcolor]"))) {
324
- ;
325
- el.style.removeProperty("background");
326
- el.removeAttribute("data-ohw-style-bgcolor");
327
- }
328
- }
329
- function clearNodeProps(root) {
330
- for (const el of Array.from(root.querySelectorAll(`[${NODE_WROTE_ATTR}]`))) {
331
- const h = el;
332
- h.style.removeProperty("color");
333
- h.style.removeProperty("font-size");
334
- h.style.removeProperty("background");
335
- h.removeAttribute(NODE_WROTE_ATTR);
336
- }
337
- }
338
- function buttonSurfaceOf(el) {
339
- return el.closest("a, button") ?? el;
340
- }
341
- function applyStylesToDom(store) {
342
- ensureStyleSheet();
343
- clearSectionAttrs(document);
344
- clearNodeProps(document);
345
- if (!store) return;
346
- for (const [sectionId, override] of Object.entries(store.sections)) {
347
- const sections = document.querySelectorAll(
348
- `[data-ohw-section="${CSS.escape(sectionId)}"]`
349
- );
350
- for (const section of Array.from(sections)) {
351
- for (const [prop, attr] of Object.entries(SECTION_ATTRS)) {
352
- const value = override[prop];
353
- if (value === void 0) continue;
354
- if (prop === "sectionBackground" && override.sectionBackgroundColor !== void 0) continue;
355
- section.setAttribute(attr, String(value).replace(":", "-"));
356
- }
357
- if (override.sectionBackgroundColor !== void 0) {
358
- section.style.setProperty("background", override.sectionBackgroundColor, "important");
359
- section.setAttribute("data-ohw-style-bgcolor", "");
360
- }
361
- }
362
- }
363
- for (const [key, override] of Object.entries(store.nodes)) {
364
- const nodes = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
365
- for (const el of Array.from(nodes)) {
366
- if (override.color !== void 0) {
367
- el.style.setProperty("color", override.color, "important");
368
- el.setAttribute(NODE_WROTE_ATTR, "");
369
- }
370
- if (override.fontSize !== void 0) {
371
- el.style.setProperty("font-size", `${override.fontSize}px`, "important");
372
- el.setAttribute(NODE_WROTE_ATTR, "");
373
- }
374
- if (override.buttonBackground !== void 0 || override.buttonText !== void 0) {
375
- const surface = buttonSurfaceOf(el);
376
- if (override.buttonBackground !== void 0) {
377
- surface.style.setProperty("background", override.buttonBackground, "important");
378
- }
379
- if (override.buttonText !== void 0) {
380
- surface.style.setProperty("color", override.buttonText, "important");
381
- }
382
- surface.setAttribute(NODE_WROTE_ATTR, "");
383
- }
384
- }
385
- }
386
- }
387
-
388
121
  // src/ui/ai-tree/aiSectionsManager.tsx
389
122
  import { flushSync } from "react-dom";
390
123
  import { createRoot } from "react-dom/client";
@@ -399,8 +132,7 @@ function lucideByName(name) {
399
132
  }
400
133
  var typeStyle = (spec, font) => ({
401
134
  fontFamily: font,
402
- // Headings shrink with the viewport (reaching full size around ~900px wide); body copy stays put.
403
- 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,
404
136
  lineHeight: spec.line,
405
137
  fontWeight: spec.weight
406
138
  });
@@ -427,8 +159,6 @@ var AI_RESPONSIVE_CSS = [
427
159
  " [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
428
160
  " [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
429
161
  " [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
430
- " [data-ai-responsive] { overflow-x: hidden; }",
431
- " [data-ai-responsive] img { max-width: 100%; }",
432
162
  "}"
433
163
  ].join("\n");
434
164
  var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
@@ -1436,20 +1166,6 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
1436
1166
  const overlayAlpha = { low: 0.25, medium: 0.45, high: 0.65 }[settings.overlayIntensity ?? "medium"];
1437
1167
  const backgroundUrl = isOverlay && settings.backgroundMedia ? ctx.resolveMedia(settings.backgroundMedia) : null;
1438
1168
  const bgAttrs = ctx.keyFor && isOverlay && settings.backgroundMedia ? { "data-ohw-key": ctx.keyFor("settings.backgroundMedia"), "data-ohw-editable": "bg-image" } : {};
1439
- const toneBackground = (() => {
1440
- const { dark, primary, light } = resolvedBrand.palette;
1441
- switch (settings.sectionBackground) {
1442
- case "surface":
1443
- return `color-mix(in srgb, ${light} 94%, ${dark})`;
1444
- case "accent":
1445
- return primary;
1446
- case "accent-soft":
1447
- return `color-mix(in srgb, ${primary} 12%, ${light})`;
1448
- default:
1449
- return void 0;
1450
- }
1451
- })();
1452
- const distributed = !isOverlay && settings.textDistribution;
1453
1169
  return /* @__PURE__ */ jsxs(
1454
1170
  "section",
1455
1171
  {
@@ -1459,11 +1175,10 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
1459
1175
  style: {
1460
1176
  position: "relative",
1461
1177
  padding: `${pad}px 0`,
1462
- background: toneBackground ?? (isOverlay && !backgroundUrl ? "#DBEAFE" : void 0),
1178
+ background: isOverlay && !backgroundUrl ? "#DBEAFE" : void 0,
1463
1179
  backgroundImage: backgroundUrl ? `url(${backgroundUrl})` : void 0,
1464
1180
  backgroundSize: "cover",
1465
- backgroundPosition: "center",
1466
- color: settings.sectionBackground === "accent" ? resolvedBrand.palette.light : void 0
1181
+ backgroundPosition: "center"
1467
1182
  },
1468
1183
  children: [
1469
1184
  /* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
@@ -1487,24 +1202,10 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
1487
1202
  display: "grid",
1488
1203
  gridTemplateColumns: "repeat(12, 1fr)",
1489
1204
  gap: AI_TREE_TOKENS.spacing6,
1490
- alignItems: distributed === "space-between" ? "stretch" : (distributed ?? settings.verticalPosition) === "top" ? "start" : "center",
1205
+ alignItems: settings.verticalPosition === "top" ? "start" : "center",
1491
1206
  marginTop: r2 > 0 ? AI_TREE_TOKENS.spacing8 : 0
1492
1207
  },
1493
- children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ jsx(
1494
- "div",
1495
- {
1496
- "data-ai-cell": "",
1497
- style: {
1498
- gridColumn: `span ${Math.min(12, Math.max(1, block.span))}`,
1499
- minWidth: 0,
1500
- // space-between: each column becomes a flex column whose content spreads over
1501
- // the full row height instead of clumping at the top.
1502
- ...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
1503
- },
1504
- children: renderNode(block, ctx, `r${r2}.b${b}`)
1505
- },
1506
- b
1507
- ))
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))
1508
1209
  },
1509
1210
  r2
1510
1211
  ))
@@ -1520,34 +1221,17 @@ import { jsx as jsx2 } from "react/jsx-runtime";
1520
1221
  var CONTAINER_ATTR = "data-ohw-ai-generated";
1521
1222
  var REPLACED_ATTR = "data-ohw-ai-replaced-by";
1522
1223
  var REMOVED_ATTR = "data-ohw-ai-removed";
1523
- function readRootVar(name) {
1524
- if (typeof document === "undefined") return "";
1525
- return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
1526
- }
1527
- function deriveBrandOverride() {
1528
- const dark = readRootVar("--ohw-brand-dark");
1529
- const primary = readRootVar("--ohw-brand-primary");
1530
- const light = readRootVar("--ohw-brand-light");
1531
- if (!dark || !primary || !light) return null;
1532
- const accent = readRootVar("--ohw-brand-accent");
1533
- const heading = readRootVar("--font-heading") || readRootVar("--font-display");
1534
- const body = readRootVar("--font-body");
1535
- return {
1536
- palette: { dark, primary, accent: accent || dark, light },
1537
- fonts: {
1538
- heading: heading || AI_DEFAULT_BRAND.fonts.heading,
1539
- body: body || AI_DEFAULT_BRAND.fonts.body
1540
- }
1541
- };
1542
- }
1543
1224
  function deriveTemplateBrand() {
1544
- const dark = readRootVar("--color-dark");
1545
- const primary = readRootVar("--color-primary");
1546
- 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");
1547
1231
  if (!dark || !primary || !light) return null;
1548
- const accent = readRootVar("--color-accent");
1549
- const heading = readRootVar("--font-heading") || readRootVar("--font-display");
1550
- 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");
1551
1235
  return {
1552
1236
  palette: { dark, primary, accent: accent || dark, light },
1553
1237
  fonts: {
@@ -1639,12 +1323,8 @@ function syncReplacedOriginals(state) {
1639
1323
  }
1640
1324
  function applyAiSectionsToDom(state, options) {
1641
1325
  if (typeof document === "undefined") return;
1642
- const brandOverride = deriveBrandOverride();
1643
1326
  const templateBrand = deriveTemplateBrand();
1644
- const brandKey = brandOverride ? JSON.stringify(brandOverride) : "";
1645
- const pagePath = window.location.pathname;
1646
- const pageSections = state.sections.filter((entry) => !entry.path || entry.path === pagePath);
1647
- const activeIds = new Set(pageSections.map((entry) => entry.id));
1327
+ const activeIds = new Set(state.sections.map((entry) => entry.id));
1648
1328
  for (const [id, section] of mounted) {
1649
1329
  if (!activeIds.has(id)) {
1650
1330
  section.root.unmount();
@@ -1652,8 +1332,8 @@ function applyAiSectionsToDom(state, options) {
1652
1332
  mounted.delete(id);
1653
1333
  }
1654
1334
  }
1655
- for (const entry of pageSections) {
1656
- const serialized = JSON.stringify(entry) + brandKey;
1335
+ for (const entry of state.sections) {
1336
+ const serialized = JSON.stringify(entry);
1657
1337
  const existing = mounted.get(entry.id);
1658
1338
  if (existing && existing.serialized === serialized && existing.container.isConnected) {
1659
1339
  continue;
@@ -1667,7 +1347,6 @@ function applyAiSectionsToDom(state, options) {
1667
1347
  mounted.delete(entry.id);
1668
1348
  }
1669
1349
  container.setAttribute("data-ohw-section", entry.id);
1670
- container.setAttribute("data-ohw-instance", entry.id);
1671
1350
  container.setAttribute("data-ohw-section-label", entry.label);
1672
1351
  placeContainer(container, entry);
1673
1352
  const root = mounted.get(entry.id)?.root ?? createRoot(container);
@@ -1678,7 +1357,7 @@ function applyAiSectionsToDom(state, options) {
1678
1357
  AiTreeRenderer,
1679
1358
  {
1680
1359
  tree: entry.tree,
1681
- brand: brandOverride ?? entry.brand ?? options?.brand ?? templateBrand ?? void 0,
1360
+ brand: entry.brand ?? options?.brand ?? templateBrand ?? void 0,
1682
1361
  resolveMedia,
1683
1362
  editKeyPrefix: `ai.${entry.id}`
1684
1363
  }
@@ -2295,7 +1974,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
2295
1974
  const autoId = useId();
2296
1975
  const insertAfter = insertAfterProp ?? autoId;
2297
1976
  const [schedule, setSchedule] = useState2(null);
2298
- const [loading, setLoading] = useState2(initialScheduleId !== null);
1977
+ const [loading, setLoading] = useState2(true);
2299
1978
  const [inEditor, setInEditor] = useState2(false);
2300
1979
  const [isHovered, setIsHovered] = useState2(false);
2301
1980
  const [modalState, setModalState] = useState2(null);
@@ -2469,10 +2148,8 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
2469
2148
  "*"
2470
2149
  );
2471
2150
  };
2151
+ if (!inEditor && !loading && !schedule) return null;
2472
2152
  const sectionId = `scheduling-${insertAfter}`;
2473
- if (!inEditor && !loading && !schedule) {
2474
- return /* @__PURE__ */ jsx4("section", { "data-ohw-section": sectionId, "data-ohw-scheduling-anchor": insertAfter, style: { display: "none" } });
2475
- }
2476
2153
  return /* @__PURE__ */ jsxs3(
2477
2154
  "section",
2478
2155
  {
@@ -6991,12 +6668,8 @@ function parseSectionsFromHtml(html) {
6991
6668
 
6992
6669
  // src/ui/ai-section/AiSectionOverlay.tsx
6993
6670
  import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
6994
- function findSectionElement(instanceId) {
6995
- const escaped = CSS.escape(instanceId);
6996
- return document.querySelector(`[data-ohw-instance="${escaped}"]`) ?? document.querySelector(`[data-ohw-section="${escaped}"]:not([data-ohw-instance])`);
6997
- }
6998
- function readRect(instanceId) {
6999
- const el = findSectionElement(instanceId);
6671
+ function readRect(sectionId) {
6672
+ const el = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
7000
6673
  if (!el) return null;
7001
6674
  const r2 = el.getBoundingClientRect();
7002
6675
  if (r2.width <= 0 || r2.height <= 0) return null;
@@ -7019,7 +6692,7 @@ function useLiveSectionRect(sectionId) {
7019
6692
  const opts = { capture: true, passive: true };
7020
6693
  window.addEventListener("scroll", update, opts);
7021
6694
  window.addEventListener("resize", update);
7022
- const el = findSectionElement(sectionId);
6695
+ const el = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
7023
6696
  const ro = el ? new ResizeObserver(update) : null;
7024
6697
  if (el && ro) ro.observe(el);
7025
6698
  const interval = setInterval(update, 500);
@@ -7032,14 +6705,6 @@ function useLiveSectionRect(sectionId) {
7032
6705
  }, [sectionId]);
7033
6706
  return rect;
7034
6707
  }
7035
- function computeSectionBoundaryFlags(instanceId) {
7036
- const topLevel = Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
7037
- (el) => !el.parentElement?.closest("[data-ohw-section]")
7038
- );
7039
- const index = topLevel.findIndex((el) => (el.dataset.ohwInstance ?? el.dataset.ohwSection) === instanceId);
7040
- if (index === -1) return { isFirst: true, isLast: true };
7041
- return { isFirst: index === 0, isLast: index === topLevel.length - 1 };
7042
- }
7043
6708
  var PRIMARY2 = "#0885FE";
7044
6709
  function edgeAwareRadius(rect) {
7045
6710
  const container = window.innerWidth <= 480 ? 16 : 24;
@@ -7113,7 +6778,6 @@ function AiSectionOverlay({
7113
6778
  }) {
7114
6779
  const [selectedId, setSelectedId] = useState4(null);
7115
6780
  const [reviewId, setReviewId] = useState4(null);
7116
- const [reviewButtonsHidden, setReviewButtonsHidden] = useState4(false);
7117
6781
  const reviewIdRef = useRef4(null);
7118
6782
  reviewIdRef.current = reviewId;
7119
6783
  const selectedIdRef = useRef4(null);
@@ -7122,7 +6786,7 @@ function AiSectionOverlay({
7122
6786
  (el) => {
7123
6787
  postToParent2({
7124
6788
  type: "ow:section-selected",
7125
- sectionId: el ? el.dataset.ohwInstance ?? el.dataset.ohwSection ?? null : null,
6789
+ sectionId: el?.dataset.ohwSection ?? null,
7126
6790
  sectionLabel: el ? el.dataset.ohwSectionLabel ?? titleCaseSectionId(el.dataset.ohwSection ?? "") : null
7127
6791
  });
7128
6792
  },
@@ -7131,7 +6795,7 @@ function AiSectionOverlay({
7131
6795
  const selectFromElement = useCallback2(
7132
6796
  (el, options) => {
7133
6797
  const sectionEl = el?.closest("[data-ohw-section]") ?? null;
7134
- const id = sectionEl ? sectionEl.dataset.ohwInstance ?? sectionEl.dataset.ohwSection ?? null : null;
6798
+ const id = sectionEl?.dataset.ohwSection ?? null;
7135
6799
  if (id === selectedIdRef.current) return;
7136
6800
  setSelectedId(id);
7137
6801
  if (options?.report !== false) report(sectionEl);
@@ -7172,10 +6836,9 @@ function AiSectionOverlay({
7172
6836
  }
7173
6837
  const found = readRect(sectionId) != null;
7174
6838
  setReviewId(found ? sectionId : null);
7175
- setReviewButtonsHidden(e.data.hideButtons === true);
7176
6839
  postToParent2({ type: "ow:ai-review-started", sectionId, found });
7177
6840
  if (found) {
7178
- 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" });
7179
6842
  }
7180
6843
  }
7181
6844
  };
@@ -7194,7 +6857,7 @@ function AiSectionOverlay({
7194
6857
  return;
7195
6858
  }
7196
6859
  const sec = t.closest("[data-ohw-section]");
7197
- setHoveredId(sec ? sec.dataset.ohwInstance ?? sec.dataset.ohwSection ?? null : null);
6860
+ setHoveredId(sec?.dataset.ohwSection ?? null);
7198
6861
  };
7199
6862
  const onLeave = () => setHoveredId(null);
7200
6863
  document.addEventListener("mousemove", onMove, { passive: true });
@@ -7226,29 +6889,9 @@ function AiSectionOverlay({
7226
6889
  },
7227
6890
  [postToParent2]
7228
6891
  );
7229
- const activeSelectionId = reviewId ? null : selectedId;
7230
- const selectionRect = useLiveSectionRect(activeSelectionId);
6892
+ const selectionRect = useLiveSectionRect(reviewId ? null : selectedId);
7231
6893
  const reviewRect = useLiveSectionRect(reviewId);
7232
6894
  const hoverRect = useLiveSectionRect(reviewId || hoveredId === selectedId ? null : hoveredId);
7233
- useEffect4(() => {
7234
- if (!activeSelectionId || !selectionRect) {
7235
- postToParent2({ type: "ow:section-rect", instanceId: null, rect: null });
7236
- return;
7237
- }
7238
- const { isFirst, isLast } = computeSectionBoundaryFlags(activeSelectionId);
7239
- postToParent2({
7240
- type: "ow:section-rect",
7241
- instanceId: activeSelectionId,
7242
- rect: {
7243
- top: selectionRect.top + window.scrollY,
7244
- left: selectionRect.left + window.scrollX,
7245
- width: selectionRect.width,
7246
- height: selectionRect.height
7247
- },
7248
- isFirst,
7249
- isLast
7250
- });
7251
- }, [activeSelectionId, selectionRect, postToParent2]);
7252
6895
  return /* @__PURE__ */ jsxs8(Fragment5, { children: [
7253
6896
  hoverRect && /* @__PURE__ */ jsx16(
7254
6897
  "div",
@@ -7299,16 +6942,13 @@ function AiSectionOverlay({
7299
6942
  border: `2px solid ${PRIMARY2}`,
7300
6943
  borderRadius: edgeAwareRadius(reviewRect),
7301
6944
  zIndex: 2147483200,
7302
- // The veil itself: swallows clicks so the section stays locked until decided. This
7303
- // stopPropagation only guards the bubble phase; the bridge's capture-phase click
7304
- // handlers additionally bail on `[data-ohw-ai-review]`, without which a click on
7305
- // 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.
7306
6946
  background: "rgba(8, 133, 254, 0.04)",
7307
6947
  pointerEvents: "auto",
7308
6948
  cursor: "default"
7309
6949
  },
7310
6950
  onClick: (e) => e.stopPropagation(),
7311
- children: !reviewButtonsHidden && /* @__PURE__ */ jsxs8(
6951
+ children: /* @__PURE__ */ jsxs8(
7312
6952
  "div",
7313
6953
  {
7314
6954
  style: {
@@ -11208,329 +10848,6 @@ function deleteFooterColumn(column) {
11208
10848
  };
11209
10849
  }
11210
10850
 
11211
- // src/lib/logo-identity.ts
11212
- var LOGO_TEXT_KEYS = ["nav-logo-text", "footer-logo-text", "logo-text"];
11213
- var LOGO_IMAGE_KEYS = ["nav-logo-image", "footer-logo", "footer-logo-image"];
11214
- var LOGO_HREF_KEYS = ["nav-logo-href", "footer-logo-href", "logo-href"];
11215
- var LOGO_PLACEHOLDER_KEY = "logo-is-placeholder";
11216
- var LOGO_ALT_KEY = "logo-alt";
11217
- var LOGO_IMAGE_URL_KEY = "nav-logo-image";
11218
- var PLACEHOLDER_BUSINESS_NAME = "Business name";
11219
- function resolveLogoDisplayText(text) {
11220
- const trimmed = (text ?? "").trim();
11221
- return trimmed || PLACEHOLDER_BUSINESS_NAME;
11222
- }
11223
- function isFooterLogoRoot(root) {
11224
- return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
11225
- }
11226
- function imageKeyForRoot(root) {
11227
- return isFooterLogoRoot(root) ? "footer-logo" : "nav-logo-image";
11228
- }
11229
- function textKeyForRoot(root) {
11230
- return isFooterLogoRoot(root) ? "footer-logo-text" : "nav-logo-text";
11231
- }
11232
- function ensureLogoHrefKey(root) {
11233
- if (!(root instanceof HTMLAnchorElement)) return;
11234
- if (root.hasAttribute("data-ohw-href-key")) return;
11235
- root.setAttribute("data-ohw-href-key", isFooterLogoRoot(root) ? "footer-logo-href" : "nav-logo-href");
11236
- }
11237
- function applyLogoIdentity(text, isPlaceholder) {
11238
- const display = resolveLogoDisplayText(text);
11239
- const placeholder = isPlaceholder || !text.trim() || display === PLACEHOLDER_BUSINESS_NAME;
11240
- for (const key of LOGO_TEXT_KEYS) {
11241
- document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
11242
- if (el.textContent !== display) el.textContent = display;
11243
- });
11244
- }
11245
- for (const key of LOGO_IMAGE_KEYS) {
11246
- document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
11247
- const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
11248
- if (img) img.alt = display;
11249
- });
11250
- }
11251
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((el) => {
11252
- if (placeholder) el.setAttribute("data-ohw-placeholder", "");
11253
- else el.removeAttribute("data-ohw-placeholder");
11254
- });
11255
- return display;
11256
- }
11257
- function applyLogoImage(url, alt) {
11258
- const displayAlt = resolveLogoDisplayText(alt);
11259
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
11260
- ensureLogoHrefKey(root);
11261
- const imageKey = imageKeyForRoot(root);
11262
- const textKey = textKeyForRoot(root);
11263
- 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");
11264
- let textEl = root.querySelector(`[data-ohw-key="${textKey}"]`) ?? root.querySelector('[data-ohw-key="logo-text"]');
11265
- if (url) {
11266
- if (!img) {
11267
- img = document.createElement("img");
11268
- img.setAttribute("data-ohw-editable", "image");
11269
- img.setAttribute("data-ohw-key", imageKey);
11270
- img.alt = displayAlt;
11271
- img.style.height = "";
11272
- img.style.maxHeight = "none";
11273
- img.style.width = "auto";
11274
- img.style.display = "block";
11275
- img.style.objectFit = "contain";
11276
- root.insertBefore(img, root.firstChild);
11277
- } else {
11278
- img.setAttribute("data-ohw-editable", "image");
11279
- img.setAttribute("data-ohw-key", imageKey);
11280
- }
11281
- img.removeAttribute("srcset");
11282
- img.removeAttribute("sizes");
11283
- img.src = url;
11284
- img.alt = displayAlt;
11285
- img.style.display = "block";
11286
- if (textEl) textEl.style.display = "none";
11287
- root.removeAttribute("data-ohw-placeholder");
11288
- return;
11289
- }
11290
- if (img) {
11291
- img.removeAttribute("src");
11292
- img.removeAttribute("srcset");
11293
- img.removeAttribute("sizes");
11294
- img.alt = displayAlt;
11295
- img.style.display = "none";
11296
- }
11297
- if (!textEl) {
11298
- textEl = document.createElement("span");
11299
- textEl.setAttribute("data-ohw-editable", "plain");
11300
- textEl.setAttribute("data-ohw-key", textKey);
11301
- root.appendChild(textEl);
11302
- }
11303
- textEl.style.display = "";
11304
- if (textEl.textContent !== displayAlt) textEl.textContent = displayAlt;
11305
- if (!displayAlt.trim() || displayAlt === PLACEHOLDER_BUSINESS_NAME) {
11306
- root.setAttribute("data-ohw-placeholder", "");
11307
- } else {
11308
- root.removeAttribute("data-ohw-placeholder");
11309
- }
11310
- });
11311
- }
11312
- function applyLogoHref(href) {
11313
- const target = href.trim() || "/";
11314
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
11315
- ensureLogoHrefKey(root);
11316
- if (root instanceof HTMLAnchorElement) {
11317
- root.setAttribute("href", target);
11318
- }
11319
- });
11320
- for (const key of LOGO_HREF_KEYS) setStoredLinkHref(key, target);
11321
- }
11322
- function readLogoIdentityFromDom() {
11323
- let imageUrl = null;
11324
- for (const key of LOGO_IMAGE_KEYS) {
11325
- const el = document.querySelector(`[data-ohw-key="${key}"]`);
11326
- const img = el instanceof HTMLImageElement ? el : el?.querySelector("img");
11327
- const attrSrc = img?.getAttribute("src")?.trim() ?? "";
11328
- if (attrSrc && !attrSrc.startsWith("data:") && img && img.style.display !== "none") {
11329
- imageUrl = img.currentSrc || img.src;
11330
- break;
11331
- }
11332
- }
11333
- let text = PLACEHOLDER_BUSINESS_NAME;
11334
- let isPlaceholder = true;
11335
- for (const key of LOGO_TEXT_KEYS) {
11336
- const el = document.querySelector(`[data-ohw-key="${key}"]`);
11337
- if (el?.textContent?.trim()) {
11338
- text = el.textContent.trim();
11339
- const logoRoot2 = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
11340
- isPlaceholder = logoRoot2?.hasAttribute("data-ohw-placeholder") === true || text === PLACEHOLDER_BUSINESS_NAME;
11341
- break;
11342
- }
11343
- }
11344
- if (imageUrl) {
11345
- const logoImg = document.querySelector(
11346
- '[data-ohw-key="nav-logo-image"], [data-ohw-key="footer-logo"]'
11347
- );
11348
- const alt = logoImg?.alt?.trim() || text;
11349
- isPlaceholder = false;
11350
- const hrefEl = document.querySelector(
11351
- 'a[data-ohw-role="logo"], a[data-ohw-logo], [data-ohw-role="logo"]'
11352
- );
11353
- const href2 = (hrefEl instanceof HTMLAnchorElement ? hrefEl.getAttribute("href") : null) || hrefEl?.closest("a")?.getAttribute("href") || "/";
11354
- return { text, isPlaceholder, imageUrl, href: href2, alt };
11355
- }
11356
- const logoRoot = document.querySelector('[data-ohw-role="logo"], [data-ohw-logo]');
11357
- const href = (logoRoot instanceof HTMLAnchorElement ? logoRoot.getAttribute("href") : null) || logoRoot?.closest("a")?.getAttribute("href") || "/";
11358
- return { text, isPlaceholder, imageUrl: null, href, alt: text };
11359
- }
11360
- function applyLogoFromContent(content) {
11361
- 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);
11362
- if (!hasLogoIdentity) return false;
11363
- const logoText = content[LOGO_TEXT_KEYS[0]] ?? content[LOGO_TEXT_KEYS[1]] ?? readLogoIdentityFromDom().text;
11364
- const logoAlt = content[LOGO_ALT_KEY] ?? logoText;
11365
- const rawLogoImage = content[LOGO_IMAGE_URL_KEY] ?? content["footer-logo"] ?? content["footer-logo-image"] ?? null;
11366
- const logoImageUrl = typeof rawLogoImage === "string" && rawLogoImage.trim() ? rawLogoImage.trim() : null;
11367
- const imageExplicitlyCleared = LOGO_IMAGE_KEYS.some((key) => key in content) && !logoImageUrl;
11368
- const logoIsPlaceholder = LOGO_PLACEHOLDER_KEY in content ? content[LOGO_PLACEHOLDER_KEY] !== "false" : !logoImageUrl && (!logoText.trim() || logoText === PLACEHOLDER_BUSINESS_NAME);
11369
- if (logoImageUrl) {
11370
- applyLogoImage(logoImageUrl, logoAlt);
11371
- } else {
11372
- if (imageExplicitlyCleared) applyLogoImage(null, logoAlt);
11373
- applyLogoIdentity(logoText, logoIsPlaceholder);
11374
- }
11375
- const logoHref = content["nav-logo-href"] ?? content["footer-logo-href"] ?? content["logo-href"];
11376
- if (typeof logoHref === "string" && logoHref.trim()) {
11377
- applyLogoHref(logoHref);
11378
- }
11379
- return true;
11380
- }
11381
-
11382
- // src/lib/logo-size.ts
11383
- var LOGO_SIZE_DEFAULTS = {
11384
- navbar: 28,
11385
- footer: 32
11386
- };
11387
- var LOGO_SIZE_MIN = 16;
11388
- var LOGO_SIZE_MAX = 80;
11389
- var LOGO_SIZE_DESKTOP_KEYS = {
11390
- navbar: "nav-logo-size",
11391
- footer: "footer-logo-size"
11392
- };
11393
- var LOGO_SIZE_MOBILE_KEYS = {
11394
- navbar: "nav-logo-size-mobile",
11395
- footer: "footer-logo-size-mobile"
11396
- };
11397
- var LOGO_SIZE_KEYS = [
11398
- LOGO_SIZE_DESKTOP_KEYS.navbar,
11399
- LOGO_SIZE_DESKTOP_KEYS.footer,
11400
- LOGO_SIZE_MOBILE_KEYS.navbar,
11401
- LOGO_SIZE_MOBILE_KEYS.footer
11402
- ];
11403
- function isFooterLogoRoot2(root) {
11404
- return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
11405
- }
11406
- function getLogoPlacement(root) {
11407
- return isFooterLogoRoot2(root) ? "footer" : "navbar";
11408
- }
11409
- function parseLogoSizePx(raw, fallback) {
11410
- if (raw == null || raw === "") return fallback;
11411
- const n = Number.parseFloat(raw);
11412
- if (!Number.isFinite(n)) return fallback;
11413
- return Math.min(LOGO_SIZE_MAX, Math.max(LOGO_SIZE_MIN, Math.round(n)));
11414
- }
11415
- function isMobileLogoSizeFollowing(content, placement) {
11416
- const raw = content[LOGO_SIZE_MOBILE_KEYS[placement]];
11417
- return raw == null || raw.trim() === "";
11418
- }
11419
- function resolveDesktopLogoSize(content, placement) {
11420
- return parseLogoSizePx(content[LOGO_SIZE_DESKTOP_KEYS[placement]], LOGO_SIZE_DEFAULTS[placement]);
11421
- }
11422
- function resolveMobileLogoSize(content, placement) {
11423
- if (isMobileLogoSizeFollowing(content, placement)) {
11424
- return resolveDesktopLogoSize(content, placement);
11425
- }
11426
- return parseLogoSizePx(
11427
- content[LOGO_SIZE_MOBILE_KEYS[placement]],
11428
- resolveDesktopLogoSize(content, placement)
11429
- );
11430
- }
11431
- function setRootSizeVars(root, desktopPx, mobilePx, following) {
11432
- root.style.setProperty("--ohw-logo-size", `${desktopPx}px`);
11433
- if (following) {
11434
- root.style.removeProperty("--ohw-logo-size-mobile");
11435
- } else {
11436
- root.style.setProperty("--ohw-logo-size-mobile", `${mobilePx}px`);
11437
- }
11438
- root.querySelectorAll("img").forEach((img) => {
11439
- img.style.height = "";
11440
- img.style.maxHeight = "none";
11441
- img.style.width = "auto";
11442
- img.style.objectFit = "contain";
11443
- });
11444
- }
11445
- function applyLogoSizes(content) {
11446
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
11447
- const placement = getLogoPlacement(root);
11448
- const desktop = resolveDesktopLogoSize(content, placement);
11449
- const following = isMobileLogoSizeFollowing(content, placement);
11450
- const mobile = following ? desktop : resolveMobileLogoSize(content, placement);
11451
- setRootSizeVars(root, desktop, mobile, following);
11452
- });
11453
- }
11454
- function applyLogoSizeToPlacement(placement, desktopPx, mobilePx, following) {
11455
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
11456
- if (getLogoPlacement(root) !== placement) return;
11457
- setRootSizeVars(root, desktopPx, mobilePx, following);
11458
- });
11459
- }
11460
- function logoHasUploadedImage(logoEl) {
11461
- if (logoEl.hasAttribute("data-ohw-placeholder")) return false;
11462
- 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");
11463
- if (!img) return false;
11464
- const src = img.getAttribute("src")?.trim() ?? "";
11465
- if (!src || src.startsWith("data:")) return false;
11466
- if (img.style.display === "none") return false;
11467
- return true;
11468
- }
11469
- function getLogoInteractionRect(logoEl) {
11470
- if (logoHasUploadedImage(logoEl)) {
11471
- 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");
11472
- if (img) {
11473
- const r2 = img.getBoundingClientRect();
11474
- if (r2.width > 0 && r2.height > 0) return r2;
11475
- }
11476
- }
11477
- const text = logoEl.querySelector(
11478
- '[data-ohw-key="nav-logo-text"], [data-ohw-key="footer-logo-text"]'
11479
- );
11480
- if (text) {
11481
- const style = window.getComputedStyle(text);
11482
- if (style.display !== "none" && style.visibility !== "hidden") {
11483
- const r2 = text.getBoundingClientRect();
11484
- if (r2.width > 0 && r2.height > 0) return r2;
11485
- }
11486
- }
11487
- return logoEl.getBoundingClientRect();
11488
- }
11489
- function readLogoSizeState(content, placement) {
11490
- const desktopPx = resolveDesktopLogoSize(content, placement);
11491
- const mobileFollowing = isMobileLogoSizeFollowing(content, placement);
11492
- const mobilePx = mobileFollowing ? desktopPx : resolveMobileLogoSize(content, placement);
11493
- return { desktopPx, mobilePx, mobileFollowing };
11494
- }
11495
-
11496
- // src/lib/site-wide-scope.ts
11497
- function getLogoElement(el) {
11498
- const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
11499
- if (marked) return marked;
11500
- if (el.closest('[data-ohw-editable="icon"]')) return null;
11501
- const root = el.closest("nav, [data-ohw-nav-root], footer");
11502
- if (!root) return null;
11503
- const anchor = el.closest("a");
11504
- if (anchor && root.contains(anchor) && !anchor.hasAttribute("data-ohw-href-key") && !anchor.closest("[data-ohw-nav-container]") && Boolean(anchor.querySelector("img") || anchor.matches("img"))) {
11505
- return anchor;
11506
- }
11507
- const img = el.matches("img") ? el : null;
11508
- if (img && !img.closest("[data-ohw-href-key]") && !img.closest("[data-ohw-nav-container]") && (img.closest("footer") || img.closest("nav, [data-ohw-nav-root]"))) {
11509
- return img;
11510
- }
11511
- return null;
11512
- }
11513
- function isInFooter(el) {
11514
- if (!el) return false;
11515
- return Boolean(el.closest("footer") || el.closest('[data-ohw-section="footer"]'));
11516
- }
11517
- function isSiteWideElement(el) {
11518
- if (!el) return false;
11519
- if (getLogoElement(el)) return true;
11520
- if (isInFooter(el)) return true;
11521
- if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-root")) {
11522
- return true;
11523
- }
11524
- if (el.hasAttribute("data-ohw-href-key") && el.closest("nav, [data-ohw-nav-root], [data-ohw-nav-drawer], aside")) {
11525
- return true;
11526
- }
11527
- if (el.closest('[data-ohw-role="navbar-button"]')) return true;
11528
- return false;
11529
- }
11530
- function isSiteWideScopeActive(args) {
11531
- return isSiteWideElement(args.selected) || isSiteWideElement(args.hoveredItem) || isSiteWideElement(args.hoveredNavContainer) || isSiteWideElement(args.active);
11532
- }
11533
-
11534
10851
  // src/lib/add-footer-column.ts
11535
10852
  function buildFooterColumnEditContentPatch(result) {
11536
10853
  return {
@@ -11752,127 +11069,16 @@ function FloatingPanel({
11752
11069
  );
11753
11070
  }
11754
11071
 
11755
- // src/ui/logo-size-panel.tsx
11756
- import { ArrowUpRight, Link as Link2 } from "lucide-react";
11757
- import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
11758
- function SizeSlider({
11759
- value,
11760
- onChange
11761
- }) {
11762
- const pct = (value - LOGO_SIZE_MIN) / (LOGO_SIZE_MAX - LOGO_SIZE_MIN) * 100;
11763
- return /* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-3", children: [
11764
- /* @__PURE__ */ jsxs17("div", { className: "flex w-full items-center gap-2 text-sm font-medium leading-5", children: [
11765
- /* @__PURE__ */ jsx27("span", { className: "min-w-0 flex-1 text-foreground", children: "Size" }),
11766
- /* @__PURE__ */ jsxs17("span", { className: "shrink-0 whitespace-nowrap text-muted-foreground", children: [
11767
- value,
11768
- " px"
11769
- ] })
11770
- ] }),
11771
- /* @__PURE__ */ jsxs17("div", { className: "relative h-2 w-full rounded-full bg-primary-50", children: [
11772
- /* @__PURE__ */ jsx27(
11773
- "div",
11774
- {
11775
- className: "absolute inset-y-0 left-0 rounded-full bg-primary",
11776
- style: { width: `${pct}%` }
11777
- }
11778
- ),
11779
- /* @__PURE__ */ jsx27(
11780
- "input",
11781
- {
11782
- type: "range",
11783
- min: LOGO_SIZE_MIN,
11784
- max: LOGO_SIZE_MAX,
11785
- step: 1,
11786
- value,
11787
- "aria-label": "Logo size",
11788
- className: cn(
11789
- "absolute inset-0 h-full w-full cursor-pointer appearance-none bg-transparent",
11790
- "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:size-5",
11791
- "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2",
11792
- "[&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-background",
11793
- "[&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full",
11794
- "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary",
11795
- "[&::-moz-range-thumb]:bg-background"
11796
- ),
11797
- onChange: (e) => onChange(Number(e.target.value))
11798
- }
11799
- )
11800
- ] })
11801
- ] });
11802
- }
11803
- function LogoSizePanel({
11804
- viewport,
11805
- sizePx,
11806
- mobileFollowing = true,
11807
- onSizeChange,
11808
- onCustomizeMobile,
11809
- onResetMobile,
11810
- onUpdateEverywhere,
11811
- className
11812
- }) {
11813
- const showFollowing = viewport === "mobile" && mobileFollowing;
11814
- const showMobileSlider = viewport === "mobile" && !mobileFollowing;
11815
- const showDesktopSlider = viewport === "desktop";
11816
- return /* @__PURE__ */ jsxs17("div", { className: cn("flex w-full flex-col gap-4", className), children: [
11817
- showFollowing ? /* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-2", children: [
11818
- /* @__PURE__ */ jsxs17("div", { className: "flex items-start gap-1", children: [
11819
- /* @__PURE__ */ jsx27(Link2, { size: 16, className: "mt-0.5 shrink-0 text-foreground", "aria-hidden": true }),
11820
- /* @__PURE__ */ jsx27("p", { className: "text-sm font-semibold leading-5 text-foreground", children: "Following desktop size" })
11821
- ] }),
11822
- /* @__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." }),
11823
- /* @__PURE__ */ jsx27(
11824
- Button,
11825
- {
11826
- type: "button",
11827
- variant: "outline",
11828
- size: "sm",
11829
- className: "h-9 w-full min-w-0 cursor-pointer",
11830
- onClick: onCustomizeMobile,
11831
- children: "Customize for mobile"
11832
- }
11833
- )
11834
- ] }) : null,
11835
- showDesktopSlider || showMobileSlider ? /* @__PURE__ */ jsx27(SizeSlider, { value: sizePx, onChange: onSizeChange }) : null,
11836
- showMobileSlider ? /* @__PURE__ */ jsx27(
11837
- Button,
11838
- {
11839
- type: "button",
11840
- variant: "outline",
11841
- size: "sm",
11842
- className: "h-9 w-full min-w-0 cursor-pointer",
11843
- onClick: onResetMobile,
11844
- children: "Reset to desktop size"
11845
- }
11846
- ) : null,
11847
- /* @__PURE__ */ jsx27("div", { className: "h-px w-full bg-border", role: "separator" }),
11848
- /* @__PURE__ */ jsxs17(
11849
- Button,
11850
- {
11851
- type: "button",
11852
- variant: "outline",
11853
- size: "sm",
11854
- className: "h-9 w-full min-w-0 cursor-pointer gap-1",
11855
- onClick: onUpdateEverywhere,
11856
- children: [
11857
- "Update logo everywhere",
11858
- /* @__PURE__ */ jsx27(ArrowUpRight, { size: 16, "aria-hidden": true })
11859
- ]
11860
- }
11861
- ),
11862
- /* @__PURE__ */ jsx27("p", { className: "text-sm leading-5 text-muted-foreground", children: "Matches the right version to your background." })
11863
- ] });
11864
- }
11865
-
11866
11072
  // src/ui/socials-display-panel.tsx
11867
- import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
11073
+ import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
11868
11074
  function DisplaySwitch({
11869
11075
  label,
11870
11076
  checked,
11871
11077
  disabled,
11872
11078
  onChange
11873
11079
  }) {
11874
- return /* @__PURE__ */ jsxs18("div", { className: "flex w-full items-center gap-2", children: [
11875
- /* @__PURE__ */ jsx28(
11080
+ return /* @__PURE__ */ jsxs17("div", { className: "flex w-full items-center gap-2", children: [
11081
+ /* @__PURE__ */ jsx27(
11876
11082
  "span",
11877
11083
  {
11878
11084
  className: cn(
@@ -11882,7 +11088,7 @@ function DisplaySwitch({
11882
11088
  children: label
11883
11089
  }
11884
11090
  ),
11885
- /* @__PURE__ */ jsx28(
11091
+ /* @__PURE__ */ jsx27(
11886
11092
  "button",
11887
11093
  {
11888
11094
  type: "button",
@@ -11896,7 +11102,7 @@ function DisplaySwitch({
11896
11102
  checked ? "bg-primary" : "bg-primary-50",
11897
11103
  disabled ? "cursor-default opacity-50" : "cursor-pointer"
11898
11104
  ),
11899
- children: /* @__PURE__ */ jsx28(
11105
+ children: /* @__PURE__ */ jsx27(
11900
11106
  "span",
11901
11107
  {
11902
11108
  className: cn(
@@ -11910,8 +11116,8 @@ function DisplaySwitch({
11910
11116
  ] });
11911
11117
  }
11912
11118
  function SocialsDisplayPanel({ display, onChange, className }) {
11913
- return /* @__PURE__ */ jsxs18("div", { className: cn("flex w-full flex-col gap-3", className), children: [
11914
- /* @__PURE__ */ jsx28(
11119
+ return /* @__PURE__ */ jsxs17("div", { className: cn("flex w-full flex-col gap-3", className), children: [
11120
+ /* @__PURE__ */ jsx27(
11915
11121
  DisplaySwitch,
11916
11122
  {
11917
11123
  label: "Text",
@@ -11920,7 +11126,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
11920
11126
  onChange: (text) => onChange({ ...display, text })
11921
11127
  }
11922
11128
  ),
11923
- /* @__PURE__ */ jsx28(
11129
+ /* @__PURE__ */ jsx27(
11924
11130
  DisplaySwitch,
11925
11131
  {
11926
11132
  label: "Icon",
@@ -12481,7 +11687,7 @@ function useNavItemDrag({
12481
11687
 
12482
11688
  // src/ui/footer-container-chrome.tsx
12483
11689
  import { Plus as Plus2 } from "lucide-react";
12484
- import { jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
11690
+ import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
12485
11691
  function FooterContainerChrome({
12486
11692
  rect,
12487
11693
  onAdd,
@@ -12489,7 +11695,7 @@ function FooterContainerChrome({
12489
11695
  }) {
12490
11696
  const chromeGap = 6;
12491
11697
  const buttonMargin = 7;
12492
- return /* @__PURE__ */ jsx29(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx29(
11698
+ return /* @__PURE__ */ jsx28(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx28(
12493
11699
  "div",
12494
11700
  {
12495
11701
  "data-ohw-footer-container-chrome": "",
@@ -12501,8 +11707,8 @@ function FooterContainerChrome({
12501
11707
  width: rect.width + chromeGap * 2,
12502
11708
  height: rect.height + chromeGap * 2
12503
11709
  },
12504
- children: /* @__PURE__ */ jsxs19(Tooltip, { children: [
12505
- /* @__PURE__ */ jsx29(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx29(
11710
+ children: /* @__PURE__ */ jsxs18(Tooltip, { children: [
11711
+ /* @__PURE__ */ jsx28(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx28(
12506
11712
  "button",
12507
11713
  {
12508
11714
  type: "button",
@@ -12521,10 +11727,10 @@ function FooterContainerChrome({
12521
11727
  if (addDisabled) return;
12522
11728
  onAdd();
12523
11729
  },
12524
- 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 })
12525
11731
  }
12526
11732
  ) }),
12527
- /* @__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" })
12528
11734
  ] })
12529
11735
  }
12530
11736
  ) });
@@ -12707,18 +11913,6 @@ function collectEditableNodes(extraContent, root = document) {
12707
11913
  }
12708
11914
  if (extraContent && !isScoped) {
12709
11915
  applyNavFooterDeleteOverrides(byKey, extraContent);
12710
- for (const key of LOGO_IMAGE_KEYS) {
12711
- if (!(key in extraContent)) continue;
12712
- byKey.set(key, { key, type: "image", text: extraContent[key] ?? "" });
12713
- }
12714
- for (const key of [LOGO_PLACEHOLDER_KEY, LOGO_ALT_KEY]) {
12715
- if (!(key in extraContent)) continue;
12716
- byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
12717
- }
12718
- for (const key of LOGO_SIZE_KEYS) {
12719
- if (!(key in extraContent)) continue;
12720
- byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
12721
- }
12722
11916
  }
12723
11917
  return Array.from(byKey.values());
12724
11918
  }
@@ -12985,13 +12179,13 @@ function deleteSelectedNavFooterItem(deps) {
12985
12179
 
12986
12180
  // src/ui/navbar-container-chrome.tsx
12987
12181
  import { Plus as Plus3 } from "lucide-react";
12988
- import { jsx as jsx30 } from "react/jsx-runtime";
12182
+ import { jsx as jsx29 } from "react/jsx-runtime";
12989
12183
  function NavbarContainerChrome({
12990
12184
  rect,
12991
12185
  onAdd
12992
12186
  }) {
12993
12187
  const chromeGap = 6;
12994
- return /* @__PURE__ */ jsx30(
12188
+ return /* @__PURE__ */ jsx29(
12995
12189
  "div",
12996
12190
  {
12997
12191
  "data-ohw-navbar-container-chrome": "",
@@ -13003,7 +12197,7 @@ function NavbarContainerChrome({
13003
12197
  width: rect.width + chromeGap * 2,
13004
12198
  height: rect.height + chromeGap * 2
13005
12199
  },
13006
- children: /* @__PURE__ */ jsx30(
12200
+ children: /* @__PURE__ */ jsx29(
13007
12201
  "button",
13008
12202
  {
13009
12203
  type: "button",
@@ -13020,7 +12214,7 @@ function NavbarContainerChrome({
13020
12214
  e.stopPropagation();
13021
12215
  onAdd();
13022
12216
  },
13023
- 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 })
13024
12218
  }
13025
12219
  )
13026
12220
  }
@@ -13029,7 +12223,7 @@ function NavbarContainerChrome({
13029
12223
 
13030
12224
  // src/ui/drop-indicator.tsx
13031
12225
  import * as React10 from "react";
13032
- import { jsx as jsx31 } from "react/jsx-runtime";
12226
+ import { jsx as jsx30 } from "react/jsx-runtime";
13033
12227
  var dropIndicatorVariants = cva(
13034
12228
  "ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
13035
12229
  {
@@ -13053,7 +12247,7 @@ var dropIndicatorVariants = cva(
13053
12247
  );
13054
12248
  var DropIndicator = React10.forwardRef(
13055
12249
  ({ className, direction, state, ...props }, ref) => {
13056
- return /* @__PURE__ */ jsx31(
12250
+ return /* @__PURE__ */ jsx30(
13057
12251
  "div",
13058
12252
  {
13059
12253
  ref,
@@ -13070,7 +12264,7 @@ var DropIndicator = React10.forwardRef(
13070
12264
  DropIndicator.displayName = "DropIndicator";
13071
12265
 
13072
12266
  // src/ui/badge.tsx
13073
- import { jsx as jsx32 } from "react/jsx-runtime";
12267
+ import { jsx as jsx31 } from "react/jsx-runtime";
13074
12268
  var badgeVariants = cva(
13075
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",
13076
12270
  {
@@ -13088,12 +12282,12 @@ var badgeVariants = cva(
13088
12282
  }
13089
12283
  );
13090
12284
  function Badge({ className, variant, ...props }) {
13091
- return /* @__PURE__ */ jsx32("div", { className: cn(badgeVariants({ variant }), className), ...props });
12285
+ return /* @__PURE__ */ jsx31("div", { className: cn(badgeVariants({ variant }), className), ...props });
13092
12286
  }
13093
12287
 
13094
12288
  // src/OhhwellsBridge.tsx
13095
- import { Link as Link3 } from "lucide-react";
13096
- 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";
13097
12291
  var PRIMARY3 = "#0885FE";
13098
12292
  var IMAGE_FADE_MS = 300;
13099
12293
  function runOpacityFade(el, onDone) {
@@ -13187,10 +12381,21 @@ function parseSchedulingInsertAfter(insertAfter) {
13187
12381
  insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
13188
12382
  };
13189
12383
  }
13190
- function resolveEntryAnchor(entry) {
13191
- if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
13192
- const parsed = parseSchedulingInsertAfter(entry.insertAfter);
13193
- 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;
13194
12399
  }
13195
12400
  function schedulingMountDepth(insertAfter) {
13196
12401
  if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
@@ -13207,7 +12412,8 @@ function getPageSchedulingEntries(raw) {
13207
12412
  }
13208
12413
  }
13209
12414
  function isSchedulingWidgetMissing(entry) {
13210
- return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
12415
+ const { effectiveInsertAfter } = resolveSchedulingInsert(entry.insertAfter);
12416
+ return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
13211
12417
  }
13212
12418
  function hasMissingSchedulingWidgets(entries) {
13213
12419
  return entries.some(isSchedulingWidgetMissing);
@@ -13237,17 +12443,16 @@ function initSectionsFromContent(content, removeExisting = false) {
13237
12443
  } catch {
13238
12444
  }
13239
12445
  }
13240
- function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
13241
- const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
13242
- const sectionId = schedulingSectionId(widgetId);
12446
+ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId, explicitInsertBefore) {
12447
+ const { effectiveInsertAfter, insertBefore } = resolveSchedulingInsert(insertAfter, explicitInsertBefore);
12448
+ const sectionId = schedulingSectionId(effectiveInsertAfter);
13243
12449
  if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
13244
- const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
13245
- if (!anchorEl) return false;
13246
- const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
12450
+ const mountPoint = getSchedulingMountPoint(effectiveInsertAfter);
12451
+ if (!mountPoint) return false;
13247
12452
  const container = document.createElement("div");
13248
12453
  container.dataset.ohwSectionContainer = "scheduling";
13249
- if (beforeId) {
13250
- const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
12454
+ if (insertBefore) {
12455
+ const beforeAnchor = document.querySelector(`[data-ohw-section="${insertBefore}"]`);
13251
12456
  const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
13252
12457
  if (!beforePoint) return false;
13253
12458
  beforePoint.insertAdjacentElement("beforebegin", container);
@@ -13258,25 +12463,19 @@ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, be
13258
12463
  }
13259
12464
  tail.insertAdjacentElement("afterend", container);
13260
12465
  }
13261
- try {
13262
- const root = createRoot2(container);
13263
- flushSync2(() => {
13264
- root.render(
13265
- /* @__PURE__ */ jsx33(
13266
- SchedulingWidget,
13267
- {
13268
- notifyOnConnect,
13269
- initialScheduleId: scheduleId,
13270
- insertAfter: widgetId
13271
- }
13272
- )
13273
- );
13274
- });
13275
- } catch (err) {
13276
- console.error("[ow:scheduling] render threw", err);
13277
- container.remove();
13278
- return false;
13279
- }
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
+ });
13280
12479
  const tracker = getSectionsTracker();
13281
12480
  let sections = [];
13282
12481
  try {
@@ -13284,12 +12483,10 @@ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, be
13284
12483
  } catch {
13285
12484
  }
13286
12485
  const inEditor = typeof window !== "undefined" && window.self !== window.top;
13287
- if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
12486
+ if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === effectiveInsertAfter)) {
13288
12487
  sections.push({
13289
12488
  type: "scheduling",
13290
- insertAfter: widgetId,
13291
- anchorId,
13292
- beforeId: beforeId ?? null,
12489
+ insertAfter: effectiveInsertAfter,
13293
12490
  pagePath: window.location.pathname,
13294
12491
  ...scheduleId ? { scheduleId } : {}
13295
12492
  });
@@ -13303,8 +12500,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
13303
12500
  for (let i = pending.length - 1; i >= 0; i--) {
13304
12501
  const entry = pending[i];
13305
12502
  const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
13306
- const { anchorId, beforeId } = resolveEntryAnchor(entry);
13307
- if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
12503
+ if (mountSchedulingWidget(entry.insertAfter, shouldNotify, entry.scheduleId)) {
13308
12504
  pending.splice(i, 1);
13309
12505
  }
13310
12506
  }
@@ -13448,13 +12644,6 @@ function isInsideLinkEditor(target) {
13448
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"]')
13449
12645
  );
13450
12646
  }
13451
- function isInsideFloatingPanel(target) {
13452
- return Boolean(target.closest("[data-ohw-floating-panel]"));
13453
- }
13454
- function isPointOverFloatingPanel(clientX, clientY) {
13455
- const el = document.elementFromPoint(clientX, clientY);
13456
- return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
13457
- }
13458
12647
  function getHrefKeyFromElement(el) {
13459
12648
  if (!el) return null;
13460
12649
  const anchor = el.closest("[data-ohw-href-key]");
@@ -13502,7 +12691,8 @@ function isNavItemPointerTarget(el) {
13502
12691
  function getNavigationItemAnchor(el) {
13503
12692
  const anchor = el.matches("[data-ohw-href-key]") ? el : el.closest("[data-ohw-href-key]");
13504
12693
  if (!anchor) return null;
13505
- if (!anchor.querySelector('[data-ohw-editable="text"]') && !getSocialItem(anchor)) return null;
12694
+ if (!anchor.querySelector('[data-ohw-editable="text"], [data-ohw-editable="plain"]') && !getSocialItem(anchor))
12695
+ return null;
13506
12696
  if (!isNavItemPointerTarget(anchor)) return null;
13507
12697
  return anchor;
13508
12698
  }
@@ -13692,7 +12882,7 @@ function getNavigationSelectionParent(el) {
13692
12882
  if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
13693
12883
  return getFooterLinksContainer();
13694
12884
  }
13695
- 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)) {
13696
12886
  return getNavigationRoot(el);
13697
12887
  }
13698
12888
  return null;
@@ -13938,7 +13128,7 @@ function EditGlowChrome({
13938
13128
  hideHandle = false
13939
13129
  }) {
13940
13130
  const GAP = SELECTION_CHROME_GAP2;
13941
- return /* @__PURE__ */ jsxs20(
13131
+ return /* @__PURE__ */ jsxs19(
13942
13132
  "div",
13943
13133
  {
13944
13134
  ref: elRef,
@@ -13953,7 +13143,7 @@ function EditGlowChrome({
13953
13143
  zIndex: 2147483646
13954
13144
  },
13955
13145
  children: [
13956
- /* @__PURE__ */ jsx33(
13146
+ /* @__PURE__ */ jsx32(
13957
13147
  "div",
13958
13148
  {
13959
13149
  style: {
@@ -13966,7 +13156,7 @@ function EditGlowChrome({
13966
13156
  }
13967
13157
  }
13968
13158
  ),
13969
- reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx33(
13159
+ reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx32(
13970
13160
  "div",
13971
13161
  {
13972
13162
  "data-ohw-drag-handle-container": "",
@@ -13978,7 +13168,7 @@ function EditGlowChrome({
13978
13168
  transform: "translate(calc(-100% - 7px), -50%)",
13979
13169
  pointerEvents: dragDisabled ? "none" : "auto"
13980
13170
  },
13981
- children: /* @__PURE__ */ jsx33(
13171
+ children: /* @__PURE__ */ jsx32(
13982
13172
  DragHandle,
13983
13173
  {
13984
13174
  "aria-label": `Reorder ${reorderHrefKey}`,
@@ -14188,7 +13378,7 @@ function FloatingToolbar({
14188
13378
  return () => ro.disconnect();
14189
13379
  }, [showEditLink, activeCommands]);
14190
13380
  const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
14191
- return /* @__PURE__ */ jsx33(
13381
+ return /* @__PURE__ */ jsx32(
14192
13382
  "div",
14193
13383
  {
14194
13384
  ref: setRefs,
@@ -14200,12 +13390,12 @@ function FloatingToolbar({
14200
13390
  zIndex: 2147483647,
14201
13391
  pointerEvents: "auto"
14202
13392
  },
14203
- children: /* @__PURE__ */ jsxs20(CustomToolbar, { children: [
14204
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs20(React11.Fragment, { children: [
14205
- 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, {}),
14206
13396
  btns.map((btn) => {
14207
13397
  const isActive = activeCommands.has(btn.cmd);
14208
- return /* @__PURE__ */ jsx33(
13398
+ return /* @__PURE__ */ jsx32(
14209
13399
  CustomToolbarButton,
14210
13400
  {
14211
13401
  title: btn.title,
@@ -14214,7 +13404,7 @@ function FloatingToolbar({
14214
13404
  e.preventDefault();
14215
13405
  onCommand(btn.cmd);
14216
13406
  },
14217
- children: /* @__PURE__ */ jsx33(
13407
+ children: /* @__PURE__ */ jsx32(
14218
13408
  "svg",
14219
13409
  {
14220
13410
  width: "16",
@@ -14235,7 +13425,7 @@ function FloatingToolbar({
14235
13425
  );
14236
13426
  })
14237
13427
  ] }, gi)),
14238
- showEditLink ? /* @__PURE__ */ jsx33(
13428
+ showEditLink ? /* @__PURE__ */ jsx32(
14239
13429
  CustomToolbarButton,
14240
13430
  {
14241
13431
  type: "button",
@@ -14249,7 +13439,7 @@ function FloatingToolbar({
14249
13439
  e.preventDefault();
14250
13440
  e.stopPropagation();
14251
13441
  },
14252
- 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 })
14253
13443
  }
14254
13444
  ) : null
14255
13445
  ] })
@@ -14266,7 +13456,7 @@ function StateToggle({
14266
13456
  states,
14267
13457
  onStateChange
14268
13458
  }) {
14269
- return /* @__PURE__ */ jsx33(
13459
+ return /* @__PURE__ */ jsx32(
14270
13460
  ToggleGroup,
14271
13461
  {
14272
13462
  "data-ohw-state-toggle": "",
@@ -14280,12 +13470,11 @@ function StateToggle({
14280
13470
  left: rect.right - 8,
14281
13471
  transform: "translateX(-100%)"
14282
13472
  },
14283
- 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))
14284
13474
  }
14285
13475
  );
14286
13476
  }
14287
13477
  var contentCache = /* @__PURE__ */ new Map();
14288
- var fetchedContentPaths = /* @__PURE__ */ new Set();
14289
13478
  function resolveSubdomain(subdomainFromQuery) {
14290
13479
  if (subdomainFromQuery) return subdomainFromQuery;
14291
13480
  if (typeof window !== "undefined") {
@@ -14380,14 +13569,8 @@ function OhhwellsBridge() {
14380
13569
  });
14381
13570
  const selectFrameRef = useRef9(() => {
14382
13571
  });
14383
- const selectLogoRef = useRef9(() => {
14384
- });
14385
- const openLogoSizePanelRef = useRef9(() => {
14386
- });
14387
13572
  const deselectRef = useRef9(() => {
14388
13573
  });
14389
- const closeFloatingPanelOnlyRef = useRef9(() => {
14390
- });
14391
13574
  const reselectNavigationItemRef = useRef9(() => {
14392
13575
  });
14393
13576
  const commitNavigationTextEditRef = useRef9(() => {
@@ -14448,6 +13631,11 @@ function OhhwellsBridge() {
14448
13631
  const [isItemDragging, setIsItemDragging] = useState11(false);
14449
13632
  const [isFooterFrameSelection, setIsFooterFrameSelection] = useState11(false);
14450
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);
14451
13639
  const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState11(null);
14452
13640
  const [footerHeadingVisible, setFooterHeadingVisible] = useState11(null);
14453
13641
  const footerDragRef = useRef9(null);
@@ -14462,16 +13650,7 @@ function OhhwellsBridge() {
14462
13650
  const addNavAfterAnchorRef = useRef9(null);
14463
13651
  const editContentRef = useRef9({});
14464
13652
  const aiSectionsRef = useRef9("");
14465
- const brandKitRef = useRef9("");
14466
- const stylesRef = useRef9("");
14467
13653
  const pendingDeleteUndoRef = useRef9(null);
14468
- const [floatingPanel, setFloatingPanel] = useState11(null);
14469
- const floatingPanelOpenRef = useRef9(false);
14470
- const setFloatingPanelRef = useRef9(setFloatingPanel);
14471
- const [floatingPanelPos, setFloatingPanelPos] = useState11(null);
14472
- const [logoSizeDraft, setLogoSizeDraft] = useState11(null);
14473
- const [editorViewport, setEditorViewport] = useState11("desktop");
14474
- const [parentScrollSnap, setParentScrollSnap] = useState11(null);
14475
13654
  const [sitePages, setSitePages] = useState11([]);
14476
13655
  const [sectionsByPath, setSectionsByPath] = useState11({});
14477
13656
  const sectionsPrefetchGenRef = useRef9(0);
@@ -14480,18 +13659,7 @@ function OhhwellsBridge() {
14480
13659
  const linkPopoverOpenRef = useRef9(false);
14481
13660
  const linkPopoverGraceUntilRef = useRef9(0);
14482
13661
  setLinkPopoverRef.current = setLinkPopover;
14483
- setFloatingPanelRef.current = setFloatingPanel;
14484
13662
  linkPopoverSessionRef.current = linkPopover;
14485
- floatingPanelOpenRef.current = Boolean(floatingPanel);
14486
- useEffect12(() => {
14487
- const syncViewport = () => {
14488
- const next = window.innerWidth <= 480 ? "mobile" : "desktop";
14489
- setEditorViewport((prev) => prev === next ? prev : next);
14490
- };
14491
- syncViewport();
14492
- window.addEventListener("resize", syncViewport);
14493
- return () => window.removeEventListener("resize", syncViewport);
14494
- }, []);
14495
13663
  const {
14496
13664
  navDragRef,
14497
13665
  navDropSlots,
@@ -14714,10 +13882,6 @@ function OhhwellsBridge() {
14714
13882
  setIsItemDragging(false);
14715
13883
  hoveredNavContainerRef.current = null;
14716
13884
  setHoveredNavContainerRect(null);
14717
- hoveredItemElRef.current = null;
14718
- setHoveredItemRect(null);
14719
- setFloatingPanel(null);
14720
- setLogoSizeDraft(null);
14721
13885
  if (!activeElRef.current) {
14722
13886
  setNavGroupForceOpen(null, false);
14723
13887
  setToolbarRect(null);
@@ -15423,8 +14587,6 @@ function OhhwellsBridge() {
15423
14587
  setToolbarRect(anchor.getBoundingClientRect());
15424
14588
  setToolbarShowEditLink(false);
15425
14589
  setActiveCommands(/* @__PURE__ */ new Set());
15426
- setFloatingPanel(null);
15427
- setLogoSizeDraft(null);
15428
14590
  }, [deactivate, markSelected]);
15429
14591
  const selectFrame = useCallback7((el) => {
15430
14592
  if (!isNavigationContainer(el)) return;
@@ -15474,51 +14636,7 @@ function OhhwellsBridge() {
15474
14636
  setToolbarRect(el.getBoundingClientRect());
15475
14637
  setToolbarShowEditLink(false);
15476
14638
  setActiveCommands(/* @__PURE__ */ new Set());
15477
- setFloatingPanel(null);
15478
- setLogoSizeDraft(null);
15479
14639
  }, [deactivate, markSelected, postToParent2]);
15480
- const selectLogo = useCallback7(
15481
- (logoEl) => {
15482
- if (activeElRef.current) deactivate();
15483
- selectedElRef.current = logoEl;
15484
- selectedHrefKeyRef.current = null;
15485
- selectedFooterColAttrRef.current = null;
15486
- markSelected(logoEl);
15487
- setSelectedIsCta(false);
15488
- setSelectedIsSocial(false);
15489
- setSelectedIsSocialsRow(false);
15490
- clearHrefKeyHover(logoEl);
15491
- hoveredNavContainerRef.current = null;
15492
- setHoveredNavContainerRect(null);
15493
- setHoveredItemRect(null);
15494
- hoveredItemElRef.current = null;
15495
- siblingHintElRef.current = null;
15496
- setSiblingHintRect(null);
15497
- setSiblingHintRects([]);
15498
- setIsItemDragging(false);
15499
- setReorderHrefKey(null);
15500
- setReorderDragDisabled(false);
15501
- setIsFooterFrameSelection(false);
15502
- setToolbarVariant("logo");
15503
- setToolbarRect(getLogoInteractionRect(logoEl));
15504
- setToolbarShowEditLink(false);
15505
- setActiveCommands(/* @__PURE__ */ new Set());
15506
- },
15507
- [deactivate, markSelected]
15508
- );
15509
- const openLogoSizePanel = useCallback7((logoEl) => {
15510
- const placement = getLogoPlacement(logoEl);
15511
- const draft = readLogoSizeState(editContentRef.current, placement);
15512
- setLogoSizeDraft(draft);
15513
- setParentScrollSnap(parentScrollRef.current);
15514
- setFloatingPanel({
15515
- key: `logo-size:${placement}`,
15516
- title: "Logo",
15517
- context: placement === "navbar" ? "Navbar" : "Footer",
15518
- kind: "logo-size",
15519
- placement
15520
- });
15521
- }, []);
15522
14640
  const openSocialsDisplayPanel = useCallback7((row) => {
15523
14641
  setParentScrollSnap(parentScrollRef.current);
15524
14642
  setFloatingPanel({
@@ -15554,53 +14672,13 @@ function OhhwellsBridge() {
15554
14672
  );
15555
14673
  const closeFloatingPanelOnly = useCallback7(() => {
15556
14674
  setFloatingPanel(null);
15557
- setLogoSizeDraft(null);
15558
14675
  }, []);
14676
+ const closeFloatingPanelOnlyRef = useRef9(closeFloatingPanelOnly);
14677
+ closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
15559
14678
  const closeFloatingPanelAndDeselect = useCallback7(() => {
15560
14679
  setFloatingPanel(null);
15561
- setLogoSizeDraft(null);
15562
14680
  deselectRef.current();
15563
14681
  }, []);
15564
- const persistLogoSizeDraft = useCallback7(
15565
- (placement, draft) => {
15566
- const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
15567
- const mobileKey = LOGO_SIZE_MOBILE_KEYS[placement];
15568
- const nodes = [
15569
- { key: desktopKey, text: String(draft.desktopPx) }
15570
- ];
15571
- if (draft.mobileFollowing) {
15572
- nodes.push({ key: mobileKey, text: "" });
15573
- } else {
15574
- nodes.push({ key: mobileKey, text: String(draft.mobilePx) });
15575
- }
15576
- editContentRef.current = {
15577
- ...editContentRef.current,
15578
- [desktopKey]: String(draft.desktopPx),
15579
- [mobileKey]: draft.mobileFollowing ? "" : String(draft.mobilePx)
15580
- };
15581
- applyLogoSizeToPlacement(
15582
- placement,
15583
- draft.desktopPx,
15584
- draft.mobileFollowing ? draft.desktopPx : draft.mobilePx,
15585
- draft.mobileFollowing
15586
- );
15587
- postToParent2({ type: "ow:change", nodes });
15588
- requestAnimationFrame(() => {
15589
- const selected = selectedElRef.current;
15590
- if (!selected || toolbarVariantRef.current !== "logo") return;
15591
- const rect = getLogoInteractionRect(selected);
15592
- setToolbarRect(rect);
15593
- if (glowElRef.current) {
15594
- const GAP = SELECTION_CHROME_GAP2;
15595
- glowElRef.current.style.top = `${rect.top - GAP}px`;
15596
- glowElRef.current.style.left = `${rect.left - GAP}px`;
15597
- glowElRef.current.style.width = `${rect.width + GAP * 2}px`;
15598
- glowElRef.current.style.height = `${rect.height + GAP * 2}px`;
15599
- }
15600
- });
15601
- },
15602
- [postToParent2]
15603
- );
15604
14682
  const activate = useCallback7((el, options) => {
15605
14683
  if (activeElRef.current === el) return;
15606
14684
  if (isIconEditable(el)) return;
@@ -15681,37 +14759,7 @@ function OhhwellsBridge() {
15681
14759
  deactivateRef.current = deactivate;
15682
14760
  selectRef.current = select;
15683
14761
  selectFrameRef.current = selectFrame;
15684
- selectLogoRef.current = selectLogo;
15685
- openLogoSizePanelRef.current = openLogoSizePanel;
15686
14762
  deselectRef.current = deselect;
15687
- closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
15688
- const lastSiteWideScopeRef = useRef9(null);
15689
- useEffect12(() => {
15690
- if (!isEditMode) {
15691
- if (lastSiteWideScopeRef.current !== false) {
15692
- lastSiteWideScopeRef.current = false;
15693
- postToParent2({ type: "ow:site-wide-scope", active: false });
15694
- }
15695
- return;
15696
- }
15697
- const active = isSiteWideScopeActive({
15698
- selected: selectedElRef.current,
15699
- hoveredItem: hoveredItemElRef.current,
15700
- hoveredNavContainer: hoveredNavContainerRef.current,
15701
- active: activeElRef.current
15702
- });
15703
- if (lastSiteWideScopeRef.current === active) return;
15704
- lastSiteWideScopeRef.current = active;
15705
- postToParent2({ type: "ow:site-wide-scope", active });
15706
- }, [
15707
- isEditMode,
15708
- hoveredItemRect,
15709
- hoveredNavContainerRect,
15710
- toolbarVariant,
15711
- toolbarRect,
15712
- isFooterFrameSelection,
15713
- postToParent2
15714
- ]);
15715
14763
  useLayoutEffect4(() => {
15716
14764
  if (!subdomain || isEditMode) {
15717
14765
  setFetchState("done");
@@ -15723,23 +14771,9 @@ function OhhwellsBridge() {
15723
14771
  aiSectionsRef.current = content[AI_SECTIONS_KEY];
15724
14772
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
15725
14773
  }
15726
- if (typeof content[BRAND_KIT_KEY] === "string") {
15727
- brandKitRef.current = content[BRAND_KIT_KEY];
15728
- applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
15729
- }
15730
- if (typeof content[STYLE_STORE_KEY] === "string") {
15731
- stylesRef.current = content[STYLE_STORE_KEY];
15732
- applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
15733
- }
15734
- applyBrandChrome(content);
15735
14774
  for (const [key, val] of Object.entries(content)) {
15736
14775
  if (key === "__ohw_sections") continue;
15737
14776
  if (key === AI_SECTIONS_KEY) continue;
15738
- if (key === LOGO_PLACEHOLDER_KEY) continue;
15739
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
15740
- if (key === BRAND_KIT_KEY) continue;
15741
- if (key === STYLE_STORE_KEY) continue;
15742
- if (BRAND_CHROME_KEYS.has(key)) continue;
15743
14777
  if (applyVideoSettingNode(key, val)) continue;
15744
14778
  if (applyCarouselNode(key, val)) continue;
15745
14779
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -15774,8 +14808,6 @@ function OhhwellsBridge() {
15774
14808
  });
15775
14809
  applyLinkByKey(key, val);
15776
14810
  }
15777
- applyLogoFromContent(content);
15778
- applyLogoSizes(content);
15779
14811
  reconcileNavbarItemsFromContent(content);
15780
14812
  reconcileFooterOrderFromContent(content);
15781
14813
  reconcileSocialsFromContent(content);
@@ -15796,9 +14828,7 @@ function OhhwellsBridge() {
15796
14828
  let cancelled = false;
15797
14829
  setFetchState("loading");
15798
14830
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
15799
- const initialPath = pathname;
15800
- fetchedContentPaths.add(`${subdomain}::${initialPath}`);
15801
- 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) => {
15802
14832
  if (cancelled) return;
15803
14833
  const content = data?.content ?? {};
15804
14834
  contentCache.set(subdomain, content);
@@ -15822,21 +14852,8 @@ function OhhwellsBridge() {
15822
14852
  initSectionInstancesFromContent(content, window.location.pathname);
15823
14853
  observer?.disconnect();
15824
14854
  try {
15825
- applyBrandChrome(content);
15826
- if (typeof content[BRAND_KIT_KEY] === "string") {
15827
- applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
15828
- }
15829
- if (typeof content[STYLE_STORE_KEY] === "string") {
15830
- applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
15831
- }
15832
14855
  for (const [key, val] of Object.entries(content)) {
15833
14856
  if (key === "__ohw_sections") continue;
15834
- if (key === LOGO_PLACEHOLDER_KEY) continue;
15835
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
15836
- if (key === BRAND_KIT_KEY) continue;
15837
- if (key === STYLE_STORE_KEY) continue;
15838
- if (key === STYLE_STORE_KEY) continue;
15839
- if (BRAND_CHROME_KEYS.has(key)) continue;
15840
14857
  if (applyVideoSettingNode(key, val)) continue;
15841
14858
  if (applyCarouselNode(key, val)) continue;
15842
14859
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -15857,7 +14874,6 @@ function OhhwellsBridge() {
15857
14874
  });
15858
14875
  applyLinkByKey(key, val);
15859
14876
  }
15860
- applyLogoFromContent(content);
15861
14877
  reconcileNavbarItemsFromContent(content);
15862
14878
  reconcileFooterOrderFromContent(content);
15863
14879
  reconcileSocialsFromContent(content);
@@ -15872,17 +14888,6 @@ function OhhwellsBridge() {
15872
14888
  debounceTimer = setTimeout(applyFromCache, 150);
15873
14889
  };
15874
14890
  applyFromCache();
15875
- const pathCacheKey = `${subdomain}::${pathname}`;
15876
- if (!fetchedContentPaths.has(pathCacheKey)) {
15877
- fetchedContentPaths.add(pathCacheKey);
15878
- const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
15879
- fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
15880
- if (!data?.content) return;
15881
- contentCache.set(subdomain, data.content);
15882
- applyFromCache();
15883
- }).catch(() => {
15884
- });
15885
- }
15886
14891
  observer = new MutationObserver(scheduleApply);
15887
14892
  observer.observe(document.body, { childList: true, subtree: true });
15888
14893
  return () => {
@@ -15976,31 +14981,26 @@ function OhhwellsBridge() {
15976
14981
  }, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
15977
14982
  useEffect12(() => {
15978
14983
  if (!isEditMode) return;
15979
- let lastPosted = 0;
15980
14984
  const measure = () => {
15981
14985
  const h = document.body.scrollHeight;
15982
- if (h > 50 && Math.abs(h - lastPosted) > 1) {
15983
- lastPosted = h;
15984
- postToParent2({ type: "ow:height", height: h });
15985
- }
15986
- };
15987
- let raf = null;
15988
- const schedule = () => {
15989
- if (raf != null) return;
15990
- raf = requestAnimationFrame(() => {
15991
- raf = null;
15992
- measure();
15993
- });
14986
+ if (h > 50) postToParent2({ type: "ow:height", height: h });
15994
14987
  };
15995
14988
  const t1 = setTimeout(measure, 50);
15996
14989
  const t2 = setTimeout(measure, 500);
15997
- const ro = new ResizeObserver(schedule);
15998
- 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);
15999
14999
  return () => {
16000
15000
  clearTimeout(t1);
16001
15001
  clearTimeout(t2);
16002
- if (raf != null) cancelAnimationFrame(raf);
16003
- ro.disconnect();
15002
+ if (resizeTimer) clearTimeout(resizeTimer);
15003
+ window.removeEventListener("resize", handleResize);
16004
15004
  };
16005
15005
  }, [pathname, isEditMode, postToParent2]);
16006
15006
  useEffect12(() => {
@@ -16150,12 +15150,10 @@ function OhhwellsBridge() {
16150
15150
  return;
16151
15151
  }
16152
15152
  const target = e.target;
16153
- if (target.closest("[data-ohw-ai-review]")) return;
16154
15153
  if (target.closest("[data-ohw-toolbar]")) return;
16155
15154
  if (target.closest("[data-ohw-state-toggle]")) return;
16156
15155
  if (target.closest("[data-ohw-max-badge]")) return;
16157
15156
  if (isInsideLinkEditor(target)) return;
16158
- if (isInsideFloatingPanel(target)) return;
16159
15157
  if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
16160
15158
  const beneath = document.elementsFromPoint(e.clientX, e.clientY).find(
16161
15159
  (el) => el instanceof HTMLElement && !el.closest("[data-ohw-bridge-root]") && el.closest("[data-ohw-section]") != null
@@ -16219,21 +15217,6 @@ function OhhwellsBridge() {
16219
15217
  return;
16220
15218
  }
16221
15219
  }
16222
- const logoEl = getLogoElement(target);
16223
- if (logoEl) {
16224
- e.preventDefault();
16225
- e.stopPropagation();
16226
- if (!logoHasUploadedImage(logoEl)) {
16227
- deselectRef.current();
16228
- deactivateRef.current();
16229
- const identity = readLogoIdentityFromDom();
16230
- postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
16231
- return;
16232
- }
16233
- selectLogoRef.current(logoEl);
16234
- openLogoSizePanelRef.current(logoEl);
16235
- return;
16236
- }
16237
15220
  const editable = target.closest("[data-ohw-editable]");
16238
15221
  if (editable) {
16239
15222
  if (editable.dataset.ohwEditable === "link") {
@@ -16386,12 +15369,10 @@ function OhhwellsBridge() {
16386
15369
  };
16387
15370
  const handleDblClick = (e) => {
16388
15371
  const target = e.target;
16389
- if (target.closest("[data-ohw-ai-review]")) return;
16390
15372
  if (target.closest("[data-ohw-toolbar]")) return;
16391
15373
  if (target.closest("[data-ohw-state-toggle]")) return;
16392
15374
  if (target.closest("[data-ohw-max-badge]")) return;
16393
15375
  if (isInsideLinkEditor(target)) return;
16394
- if (isInsideFloatingPanel(target)) return;
16395
15376
  if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
16396
15377
  return;
16397
15378
  }
@@ -16419,14 +15400,11 @@ function OhhwellsBridge() {
16419
15400
  setHoveredNavContainerRect(null);
16420
15401
  return;
16421
15402
  }
16422
- 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]")) {
16423
15404
  hoveredItemElRef.current = null;
16424
15405
  setHoveredItemRect(null);
16425
15406
  hoveredNavContainerRef.current = null;
16426
15407
  setHoveredNavContainerRect(null);
16427
- siblingHintElRef.current = null;
16428
- setSiblingHintRect(null);
16429
- setSiblingHintRects([]);
16430
15408
  return;
16431
15409
  }
16432
15410
  {
@@ -16436,7 +15414,7 @@ function OhhwellsBridge() {
16436
15414
  const allowFooterLinksHover = toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn;
16437
15415
  if (allowNavContainerHover) {
16438
15416
  const navContainer = target.closest("[data-ohw-nav-container]");
16439
- if (navContainer && !getNavigationItemAnchor(target) && !getLogoElement(target)) {
15417
+ if (navContainer && !getNavigationItemAnchor(target)) {
16440
15418
  hoveredNavContainerRef.current = navContainer;
16441
15419
  setHoveredNavContainerRect(navContainer.getBoundingClientRect());
16442
15420
  hoveredItemElRef.current = null;
@@ -16465,15 +15443,6 @@ function OhhwellsBridge() {
16465
15443
  setHoveredNavContainerRect(null);
16466
15444
  }
16467
15445
  }
16468
- const logoEl = getLogoElement(target);
16469
- if (logoEl) {
16470
- hoveredNavContainerRef.current = null;
16471
- setHoveredNavContainerRect(null);
16472
- if (selectedElRef.current === logoEl) return;
16473
- hoveredItemElRef.current = logoEl;
16474
- setHoveredItemRect(getLogoInteractionRect(logoEl));
16475
- return;
16476
- }
16477
15446
  const navAnchor = getNavigationItemAnchor(target);
16478
15447
  if (navAnchor) {
16479
15448
  hoveredNavContainerRef.current = null;
@@ -16511,11 +15480,6 @@ function OhhwellsBridge() {
16511
15480
  setHoveredItemRect(hoverTarget.getBoundingClientRect());
16512
15481
  } else if (!isInsideNavigationItem(editable)) {
16513
15482
  hoverTarget.setAttribute("data-ohw-hovered", "");
16514
- if (editable.closest("footer") || editable.closest('[data-ohw-section="footer"]')) {
16515
- hoveredNavContainerRef.current = null;
16516
- setHoveredNavContainerRect(null);
16517
- hoveredItemElRef.current = editable;
16518
- }
16519
15483
  }
16520
15484
  }
16521
15485
  };
@@ -16551,18 +15515,6 @@ function OhhwellsBridge() {
16551
15515
  }
16552
15516
  return;
16553
15517
  }
16554
- const logoEl = getLogoElement(target);
16555
- if (logoEl) {
16556
- const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
16557
- if (related2 && (logoEl === related2 || logoEl.contains(related2) || related2.closest?.('[data-ohw-role="logo"], [data-ohw-logo]'))) {
16558
- return;
16559
- }
16560
- if (hoveredItemElRef.current === logoEl) {
16561
- hoveredItemElRef.current = null;
16562
- setHoveredItemRect(null);
16563
- }
16564
- return;
16565
- }
16566
15518
  const editable = target.closest("[data-ohw-editable]");
16567
15519
  if (!editable) return;
16568
15520
  const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
@@ -16583,13 +15535,6 @@ function OhhwellsBridge() {
16583
15535
  }
16584
15536
  } else {
16585
15537
  hoverTarget.removeAttribute("data-ohw-hovered");
16586
- if (hoveredItemElRef.current === editable) {
16587
- const stillOnEditable = related instanceof Element && related.closest("[data-ohw-editable]") === editable;
16588
- if (!stillOnEditable) {
16589
- hoveredItemElRef.current = null;
16590
- setHoveredItemRect(null);
16591
- }
16592
- }
16593
15538
  }
16594
15539
  }
16595
15540
  };
@@ -16706,26 +15651,6 @@ function OhhwellsBridge() {
16706
15651
  hoveredNavContainerRef.current = null;
16707
15652
  setHoveredNavContainerRect(null);
16708
15653
  }
16709
- const logoCandidates = [
16710
- ...document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]'),
16711
- ...document.querySelectorAll("nav a:not([data-ohw-href-key]), [data-ohw-nav-root] a:not([data-ohw-href-key])"),
16712
- ...document.querySelectorAll("footer img")
16713
- ];
16714
- const seenLogos = /* @__PURE__ */ new Set();
16715
- for (const candidate of logoCandidates) {
16716
- const logo = getLogoElement(candidate);
16717
- if (!logo || seenLogos.has(logo)) continue;
16718
- seenLogos.add(logo);
16719
- const r2 = logo.getBoundingClientRect();
16720
- if (x < r2.left || x > r2.right || y < r2.top || y > r2.bottom) continue;
16721
- hoveredNavContainerRef.current = null;
16722
- setHoveredNavContainerRect(null);
16723
- if (selectedElRef.current !== logo) {
16724
- hoveredItemElRef.current = logo;
16725
- setHoveredItemRect(getLogoInteractionRect(logo));
16726
- }
16727
- return;
16728
- }
16729
15654
  const navContainers = Array.from(
16730
15655
  document.querySelectorAll("[data-ohw-nav-container]")
16731
15656
  );
@@ -16811,7 +15736,7 @@ function OhhwellsBridge() {
16811
15736
  }
16812
15737
  };
16813
15738
  const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
16814
- if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
15739
+ if (linkPopoverOpenRef.current) {
16815
15740
  if (hoveredImageRef.current) {
16816
15741
  hoveredImageRef.current = null;
16817
15742
  hoveredImageHasTextOverlapRef.current = false;
@@ -17065,7 +15990,7 @@ function OhhwellsBridge() {
17065
15990
  }
17066
15991
  };
17067
15992
  const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
17068
- 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")) {
17069
15994
  if (activeStateElRef.current) {
17070
15995
  activeStateElRef.current.removeAttribute("data-ohw-state-hovered");
17071
15996
  activeStateElRef.current = null;
@@ -17131,21 +16056,16 @@ function OhhwellsBridge() {
17131
16056
  setSectionGap(null);
17132
16057
  }
17133
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
+ };
17134
16066
  const handleMouseMove = (e) => {
17135
16067
  const { clientX, clientY } = e;
17136
- if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
17137
- hoveredItemElRef.current = null;
17138
- setHoveredItemRect(null);
17139
- hoveredNavContainerRef.current = null;
17140
- setHoveredNavContainerRect(null);
17141
- siblingHintElRef.current = null;
17142
- setSiblingHintRect(null);
17143
- setSiblingHintRects([]);
17144
- dismissImageHover();
17145
- clearImageHover();
17146
- setSectionGap(null);
17147
- return;
17148
- }
16068
+ if (pointOwnedByFloatingPanel(clientX, clientY)) return;
17149
16069
  probeSectionGapAt(clientX, clientY);
17150
16070
  probeImageAt(clientX, clientY);
17151
16071
  probeHoverCardsAt(clientX, clientY);
@@ -17154,11 +16074,7 @@ function OhhwellsBridge() {
17154
16074
  if (e.data?.type !== "ow:pointer-sync") return;
17155
16075
  const { clientX, clientY } = e.data;
17156
16076
  if (typeof clientX !== "number" || typeof clientY !== "number") return;
17157
- if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
17158
- dismissImageHover();
17159
- clearImageHover();
17160
- return;
17161
- }
16077
+ if (pointOwnedByFloatingPanel(clientX, clientY)) return;
17162
16078
  probeSectionGapAt(clientX, clientY);
17163
16079
  probeImageAt(clientX, clientY);
17164
16080
  probeHoverCardsAt(clientX, clientY);
@@ -17408,15 +16324,6 @@ function OhhwellsBridge() {
17408
16324
  aiSectionsRef.current = content[AI_SECTIONS_KEY];
17409
16325
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
17410
16326
  }
17411
- if (typeof content[BRAND_KIT_KEY] === "string") {
17412
- brandKitRef.current = content[BRAND_KIT_KEY];
17413
- applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
17414
- }
17415
- if (typeof content[STYLE_STORE_KEY] === "string") {
17416
- stylesRef.current = content[STYLE_STORE_KEY];
17417
- applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
17418
- }
17419
- applyBrandChrome(content);
17420
16327
  let sectionsJson = null;
17421
16328
  for (const [key, val] of Object.entries(content)) {
17422
16329
  if (key === "__ohw_sections") {
@@ -17424,11 +16331,6 @@ function OhhwellsBridge() {
17424
16331
  continue;
17425
16332
  }
17426
16333
  if (key === AI_SECTIONS_KEY) continue;
17427
- if (key === LOGO_PLACEHOLDER_KEY) continue;
17428
- if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
17429
- if (key === BRAND_KIT_KEY) continue;
17430
- if (key === STYLE_STORE_KEY) continue;
17431
- if (BRAND_CHROME_KEYS.has(key)) continue;
17432
16334
  if (applyVideoSettingNode(key, val)) continue;
17433
16335
  if (applyCarouselNode(key, val)) continue;
17434
16336
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -17448,8 +16350,6 @@ function OhhwellsBridge() {
17448
16350
  });
17449
16351
  applyLinkByKey(key, val);
17450
16352
  }
17451
- applyLogoFromContent(content);
17452
- applyLogoSizes(content);
17453
16353
  if (sectionsJson) {
17454
16354
  initSectionsFromContent({ __ohw_sections: sectionsJson }, true);
17455
16355
  sectionsLoadedRef.current = true;
@@ -17465,58 +16365,6 @@ function OhhwellsBridge() {
17465
16365
  if (hydratedHeight > 50) postToParentRef.current({ type: "ow:height", height: hydratedHeight });
17466
16366
  postToParentRef.current({ type: "ow:hydrate-done" });
17467
16367
  };
17468
- const handleUpdateLogoIdentity = (e) => {
17469
- if (e.data?.type !== "ow:update-logo-identity") return;
17470
- const rawText = typeof e.data.text === "string" ? e.data.text : "";
17471
- const alt = typeof e.data.alt === "string" ? e.data.alt : rawText;
17472
- const href = typeof e.data.href === "string" ? e.data.href : void 0;
17473
- const imageProvided = "image" in e.data;
17474
- const imageUrl = imageProvided && typeof e.data.image === "string" && e.data.image.trim() ? e.data.image.trim() : imageProvided ? null : void 0;
17475
- let isPlaceholder = e.data.isPlaceholder !== false;
17476
- if (imageUrl) isPlaceholder = false;
17477
- else if (imageProvided && imageUrl === null) {
17478
- isPlaceholder = e.data.isPlaceholder === true || !rawText.trim() || resolveLogoDisplayText(rawText) === PLACEHOLDER_BUSINESS_NAME;
17479
- }
17480
- const display = applyLogoIdentity(rawText, isPlaceholder);
17481
- const displayAlt = resolveLogoDisplayText(alt || display);
17482
- if (imageUrl !== void 0) {
17483
- applyLogoImage(imageUrl, displayAlt);
17484
- } else {
17485
- for (const key of LOGO_IMAGE_KEYS) {
17486
- document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
17487
- const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
17488
- if (img) img.alt = displayAlt;
17489
- });
17490
- }
17491
- }
17492
- if (href !== void 0) {
17493
- applyLogoHref(href);
17494
- applyLinkByKey("nav-logo-href", href);
17495
- applyLinkByKey("footer-logo-href", href);
17496
- applyLinkByKey("logo-href", href);
17497
- }
17498
- const nodes = [
17499
- ...LOGO_TEXT_KEYS.map((key) => ({ key, text: display })),
17500
- { key: LOGO_PLACEHOLDER_KEY, text: isPlaceholder ? "true" : "false" },
17501
- { key: LOGO_ALT_KEY, text: displayAlt }
17502
- ];
17503
- if (imageUrl !== void 0) {
17504
- if (imageUrl) {
17505
- for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: imageUrl });
17506
- } else {
17507
- for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: "" });
17508
- }
17509
- }
17510
- if (href !== void 0) {
17511
- for (const key of LOGO_HREF_KEYS) nodes.push({ key, text: href.trim() || "/" });
17512
- }
17513
- editContentRef.current = {
17514
- ...editContentRef.current,
17515
- ...Object.fromEntries(nodes.map(({ key, text }) => [key, text]))
17516
- };
17517
- applyLogoSizes(editContentRef.current);
17518
- postToParentRef.current({ type: "ow:change", nodes });
17519
- };
17520
16368
  window.addEventListener("message", handleHydrate);
17521
16369
  const postAiSectionsChanged = () => {
17522
16370
  postToParentRef.current({
@@ -17530,10 +16378,7 @@ function OhhwellsBridge() {
17530
16378
  const payload = e.data.payload;
17531
16379
  if (!payload || typeof payload.id !== "string" || !isRenderableTree(payload.tree)) return;
17532
16380
  const previous = aiSectionsRef.current;
17533
- const nextState = applyTreeToState(parseAiSectionsState(previous), {
17534
- ...payload,
17535
- path: payload.path ?? window.location.pathname
17536
- });
16381
+ const nextState = applyTreeToState(parseAiSectionsState(previous), payload);
17537
16382
  const nextValue = serializeAiSectionsState(nextState);
17538
16383
  aiSectionsRef.current = nextValue;
17539
16384
  applyAiSectionsToDom(nextState);
@@ -17570,42 +16415,12 @@ function OhhwellsBridge() {
17570
16415
  const value = typeof e.data.value === "string" ? e.data.value : "";
17571
16416
  aiSectionsRef.current = value;
17572
16417
  applyAiSectionsToDom(parseAiSectionsState(value));
17573
- applyStylesToDom(parseStyleStore(stylesRef.current));
17574
16418
  const restoredHeight = document.documentElement.scrollHeight;
17575
16419
  if (restoredHeight > 50) postToParentRef.current({ type: "ow:height", height: restoredHeight });
17576
16420
  postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: value }] });
17577
16421
  postAiSectionsChanged();
17578
16422
  };
17579
16423
  window.addEventListener("message", handleAiSetSections);
17580
- const handleAiSetBrand = (e) => {
17581
- if (e.data?.type !== "ow:ai-set-brand") return;
17582
- const value = typeof e.data.value === "string" ? e.data.value : "";
17583
- const previous = brandKitRef.current;
17584
- brandKitRef.current = value;
17585
- applyBrandToDom(parseBrandKit(value));
17586
- if (aiSectionsRef.current) applyAiSectionsToDom(parseAiSectionsState(aiSectionsRef.current));
17587
- applyStylesToDom(parseStyleStore(stylesRef.current));
17588
- postToParentRef.current({ type: "ow:change", nodes: [{ key: BRAND_KIT_KEY, text: value }] });
17589
- postToParentRef.current({ type: "ow:ai-brand-applied", previous, value });
17590
- };
17591
- window.addEventListener("message", handleAiSetBrand);
17592
- const handleAiSetStyles = (e) => {
17593
- if (e.data?.type !== "ow:ai-set-styles") return;
17594
- const value = typeof e.data.value === "string" ? e.data.value : "";
17595
- const previous = stylesRef.current;
17596
- stylesRef.current = value;
17597
- applyStylesToDom(parseStyleStore(value));
17598
- postToParentRef.current({ type: "ow:change", nodes: [{ key: STYLE_STORE_KEY, text: value }] });
17599
- postToParentRef.current({ type: "ow:ai-styles-applied", previous, value });
17600
- };
17601
- window.addEventListener("message", handleAiSetStyles);
17602
- const handleGetBrand = (e) => {
17603
- if (e.data?.type !== "ow:get-brand") return;
17604
- const template = deriveTemplateBrand();
17605
- const value = brandKitRef.current || (template ? JSON.stringify(template) : "");
17606
- postToParentRef.current({ type: "ow:brand-value", value });
17607
- };
17608
- window.addEventListener("message", handleGetBrand);
17609
16424
  const handleDeactivate = (e) => {
17610
16425
  if (e.data?.type !== "ow:deactivate") return;
17611
16426
  if (Date.now() < linkPopoverGraceUntilRef.current) return;
@@ -17614,12 +16429,6 @@ function OhhwellsBridge() {
17614
16429
  closeLinkPopoverRef.current();
17615
16430
  return;
17616
16431
  }
17617
- if (floatingPanelOpenRef.current) {
17618
- setFloatingPanelRef.current(null);
17619
- deselectRef.current();
17620
- deactivateRef.current();
17621
- return;
17622
- }
17623
16432
  deselectRef.current();
17624
16433
  deactivateRef.current();
17625
16434
  };
@@ -17673,10 +16482,6 @@ function OhhwellsBridge() {
17673
16482
  return;
17674
16483
  }
17675
16484
  if (selectedElRef.current) {
17676
- if (toolbarVariantRef.current === "logo") {
17677
- deselectRef.current();
17678
- return;
17679
- }
17680
16485
  if (toolbarVariantRef.current === "select-frame") {
17681
16486
  const parent2 = getNavigationSelectionParent(selectedElRef.current);
17682
16487
  if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
@@ -17716,10 +16521,6 @@ function OhhwellsBridge() {
17716
16521
  return;
17717
16522
  }
17718
16523
  if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
17719
- if (toolbarVariantRef.current === "logo") {
17720
- deselectRef.current();
17721
- return;
17722
- }
17723
16524
  if (toolbarVariantRef.current === "select-frame") {
17724
16525
  const parent2 = getNavigationSelectionParent(selectedElRef.current);
17725
16526
  if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
@@ -17797,8 +16598,7 @@ function OhhwellsBridge() {
17797
16598
  const handleScroll = () => {
17798
16599
  const focusEl = activeElRef.current ?? selectedElRef.current;
17799
16600
  if (focusEl) {
17800
- const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
17801
- const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
16601
+ const r2 = activeElRef.current ? getEditMeasureEl(activeElRef.current).getBoundingClientRect() : focusEl.getBoundingClientRect();
17802
16602
  applyToolbarPos(r2);
17803
16603
  setToolbarRect(r2);
17804
16604
  setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
@@ -17808,9 +16608,7 @@ function OhhwellsBridge() {
17808
16608
  setToggleState((prev) => prev ? { ...prev, rect } : null);
17809
16609
  }
17810
16610
  if (hoveredItemElRef.current) {
17811
- const hoverEl = hoveredItemElRef.current;
17812
- const logo = getLogoElement(hoverEl);
17813
- setHoveredItemRect(logo ? getLogoInteractionRect(logo) : hoverEl.getBoundingClientRect());
16611
+ setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
17814
16612
  }
17815
16613
  if (hoveredNavContainerRef.current) {
17816
16614
  setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
@@ -17854,12 +16652,6 @@ function OhhwellsBridge() {
17854
16652
  if (aiSectionsRef.current) {
17855
16653
  nodes.push({ key: AI_SECTIONS_KEY, type: "sections", text: aiSectionsRef.current });
17856
16654
  }
17857
- if (stylesRef.current) {
17858
- nodes.push({ key: STYLE_STORE_KEY, type: "styles", text: stylesRef.current });
17859
- }
17860
- if (brandKitRef.current) {
17861
- nodes.push({ key: BRAND_KIT_KEY, type: "brand", text: brandKitRef.current });
17862
- }
17863
16655
  postToParentRef.current({ type: "ow:save-result", nodes });
17864
16656
  };
17865
16657
  const handleInsertSection = (e) => {
@@ -17870,12 +16662,8 @@ function OhhwellsBridge() {
17870
16662
  if (inserted) {
17871
16663
  const tracker = getSectionsTracker();
17872
16664
  postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
17873
- const reportHeight = () => {
17874
- const h = document.body.scrollHeight;
17875
- if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
17876
- };
17877
- reportHeight();
17878
- setTimeout(reportHeight, 500);
16665
+ const h = document.documentElement.scrollHeight;
16666
+ if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
17879
16667
  }
17880
16668
  };
17881
16669
  const handleSwitchSchedule = (e) => {
@@ -18068,17 +16856,13 @@ function OhhwellsBridge() {
18068
16856
  if (e.data?.type !== "ow:parent-scroll") return;
18069
16857
  const { iframeOffsetTop, headerH, canvasH } = e.data;
18070
16858
  parentScrollRef.current = { iframeOffsetTop, headerH, canvasH };
18071
- if (floatingPanelOpenRef.current) {
18072
- setParentScrollSnap({ iframeOffsetTop, headerH, canvasH });
18073
- }
18074
16859
  if (visibleViewportRef.current) {
18075
16860
  applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
18076
16861
  }
18077
16862
  const focusEl = activeElRef.current ?? selectedElRef.current;
18078
16863
  if (focusEl) {
18079
- const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
18080
- const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
18081
- applyToolbarPos(r2);
16864
+ const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
16865
+ applyToolbarPos(measureEl.getBoundingClientRect());
18082
16866
  }
18083
16867
  };
18084
16868
  const handleClickAt = (e) => {
@@ -18103,25 +16887,6 @@ function OhhwellsBridge() {
18103
16887
  postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "", elementType: stateCardImage.dataset.ohwEditable ?? "image" });
18104
16888
  return;
18105
16889
  }
18106
- const logoAtPoint = Array.from(
18107
- document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]')
18108
- ).map((el) => getLogoElement(el)).find((logo) => {
18109
- if (!logo) return false;
18110
- const r2 = logo.getBoundingClientRect();
18111
- return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
18112
- });
18113
- if (logoAtPoint) {
18114
- if (!logoHasUploadedImage(logoAtPoint)) {
18115
- deselectRef.current();
18116
- deactivateRef.current();
18117
- const identity = readLogoIdentityFromDom();
18118
- postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
18119
- return;
18120
- }
18121
- selectLogoRef.current(logoAtPoint);
18122
- openLogoSizePanelRef.current(logoAtPoint);
18123
- return;
18124
- }
18125
16890
  const textEditable = Array.from(
18126
16891
  document.querySelectorAll(NON_MEDIA_SELECTOR)
18127
16892
  ).find((el) => {
@@ -18193,14 +16958,6 @@ function OhhwellsBridge() {
18193
16958
  window.addEventListener("message", handleParentScroll);
18194
16959
  window.addEventListener("message", handlePointerSync);
18195
16960
  window.addEventListener("message", handleClickAt);
18196
- window.addEventListener("message", handleUpdateLogoIdentity);
18197
- const handleViewMode = (e) => {
18198
- if (e.data?.type !== "ow:view-mode") return;
18199
- const mode = e.data.mode === "Mobile" || e.data.mode === "mobile" ? "mobile" : "desktop";
18200
- setEditorViewport(mode);
18201
- applyLogoSizes(editContentRef.current);
18202
- };
18203
- window.addEventListener("message", handleViewMode);
18204
16961
  const handleViewportResize = () => {
18205
16962
  if (visibleViewportRef.current) {
18206
16963
  applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
@@ -18256,15 +17013,10 @@ function OhhwellsBridge() {
18256
17013
  window.removeEventListener("resize", handleViewportResize);
18257
17014
  window.removeEventListener("message", handlePointerSync);
18258
17015
  window.removeEventListener("message", handleClickAt);
18259
- window.removeEventListener("message", handleUpdateLogoIdentity);
18260
- window.removeEventListener("message", handleViewMode);
18261
17016
  window.removeEventListener("message", handleHydrate);
18262
17017
  window.removeEventListener("message", handleAiApplyTree);
18263
17018
  window.removeEventListener("message", handleAiDeleteSection);
18264
17019
  window.removeEventListener("message", handleAiSetSections);
18265
- window.removeEventListener("message", handleAiSetBrand);
18266
- window.removeEventListener("message", handleAiSetStyles);
18267
- window.removeEventListener("message", handleGetBrand);
18268
17020
  window.removeEventListener("message", handleDeactivate);
18269
17021
  window.removeEventListener("message", handleToastAction);
18270
17022
  window.removeEventListener("message", handleUiEscape);
@@ -18468,7 +17220,7 @@ function OhhwellsBridge() {
18468
17220
  postToParent2({
18469
17221
  type: "ow:ready",
18470
17222
  version: "1",
18471
- bridgeVersion: "0.1.61",
17223
+ bridgeVersion: "0.1.60",
18472
17224
  path: pathname,
18473
17225
  nodes: collectEditableNodes(editContentRef.current),
18474
17226
  sections
@@ -18863,10 +17615,10 @@ function OhhwellsBridge() {
18863
17615
  [postToParent2]
18864
17616
  );
18865
17617
  return bridgeRoot ? createPortal2(
18866
- /* @__PURE__ */ jsxs20(Fragment8, { children: [
18867
- /* @__PURE__ */ jsx33("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
18868
- isEditMode && /* @__PURE__ */ jsx33(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
18869
- 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(
18870
17622
  MediaOverlay,
18871
17623
  {
18872
17624
  hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
@@ -18877,7 +17629,7 @@ function OhhwellsBridge() {
18877
17629
  },
18878
17630
  `uploading-${key}`
18879
17631
  )),
18880
- mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx33(
17632
+ mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx32(
18881
17633
  MediaOverlay,
18882
17634
  {
18883
17635
  hover: mediaHover,
@@ -18886,11 +17638,11 @@ function OhhwellsBridge() {
18886
17638
  onVideoSettingsChange: handleVideoSettingsChange
18887
17639
  }
18888
17640
  ),
18889
- carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
18890
- siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
18891
- siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
18892
- isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
18893
- 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(
18894
17646
  "div",
18895
17647
  {
18896
17648
  className: "pointer-events-none fixed z-2147483646",
@@ -18900,7 +17652,7 @@ function OhhwellsBridge() {
18900
17652
  width: slot.width,
18901
17653
  height: slot.height
18902
17654
  },
18903
- children: /* @__PURE__ */ jsx33(
17655
+ children: /* @__PURE__ */ jsx32(
18904
17656
  DropIndicator,
18905
17657
  {
18906
17658
  direction: slot.direction,
@@ -18911,7 +17663,7 @@ function OhhwellsBridge() {
18911
17663
  },
18912
17664
  `footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
18913
17665
  )),
18914
- isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
17666
+ isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx32(
18915
17667
  "div",
18916
17668
  {
18917
17669
  className: "pointer-events-none fixed z-2147483646",
@@ -18921,7 +17673,7 @@ function OhhwellsBridge() {
18921
17673
  width: slot.width,
18922
17674
  height: slot.height
18923
17675
  },
18924
- children: /* @__PURE__ */ jsx33(
17676
+ children: /* @__PURE__ */ jsx32(
18925
17677
  DropIndicator,
18926
17678
  {
18927
17679
  direction: slot.direction,
@@ -18932,11 +17684,11 @@ function OhhwellsBridge() {
18932
17684
  },
18933
17685
  `nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
18934
17686
  )),
18935
- hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
18936
- hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
18937
- hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
18938
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx33(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
18939
- 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(
18940
17692
  FooterContainerChrome,
18941
17693
  {
18942
17694
  rect: toolbarRect,
@@ -18944,7 +17696,7 @@ function OhhwellsBridge() {
18944
17696
  addDisabled: !canAddFooterColumn()
18945
17697
  }
18946
17698
  ),
18947
- toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ jsx33(
17699
+ toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ jsx32(
18948
17700
  ItemInteractionLayer,
18949
17701
  {
18950
17702
  rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
@@ -18956,10 +17708,10 @@ function OhhwellsBridge() {
18956
17708
  dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
18957
17709
  onDragHandleDragStart: handleItemDragStart,
18958
17710
  onDragHandleDragEnd: handleItemDragEnd,
18959
- onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
18960
- onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
18961
- itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection,
18962
- 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(
18963
17715
  ItemActionToolbar,
18964
17716
  {
18965
17717
  onEditLink: openLinkPopoverForSelected,
@@ -18995,8 +17747,8 @@ function OhhwellsBridge() {
18995
17747
  ) : void 0
18996
17748
  }
18997
17749
  ),
18998
- toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ jsxs20(Fragment8, { children: [
18999
- /* @__PURE__ */ jsx33(
17750
+ toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ jsxs19(Fragment8, { children: [
17751
+ /* @__PURE__ */ jsx32(
19000
17752
  EditGlowChrome,
19001
17753
  {
19002
17754
  rect: toolbarRect,
@@ -19006,7 +17758,7 @@ function OhhwellsBridge() {
19006
17758
  hideHandle: isItemDragging
19007
17759
  }
19008
17760
  ),
19009
- /* @__PURE__ */ jsx33(
17761
+ /* @__PURE__ */ jsx32(
19010
17762
  FloatingToolbar,
19011
17763
  {
19012
17764
  rect: toolbarRect,
@@ -19019,7 +17771,7 @@ function OhhwellsBridge() {
19019
17771
  }
19020
17772
  )
19021
17773
  ] }),
19022
- maxBadge && /* @__PURE__ */ jsxs20(
17774
+ maxBadge && /* @__PURE__ */ jsxs19(
19023
17775
  "div",
19024
17776
  {
19025
17777
  "data-ohw-max-badge": "",
@@ -19045,7 +17797,7 @@ function OhhwellsBridge() {
19045
17797
  ]
19046
17798
  }
19047
17799
  ),
19048
- toggleState && !linkPopover && /* @__PURE__ */ jsx33(
17800
+ toggleState && !linkPopover && /* @__PURE__ */ jsx32(
19049
17801
  StateToggle,
19050
17802
  {
19051
17803
  rect: toggleState.rect,
@@ -19054,15 +17806,15 @@ function OhhwellsBridge() {
19054
17806
  onStateChange: handleStateChange
19055
17807
  }
19056
17808
  ),
19057
- sectionGap && !linkPopover && /* @__PURE__ */ jsxs20(
17809
+ sectionGap && !linkPopover && /* @__PURE__ */ jsxs19(
19058
17810
  "div",
19059
17811
  {
19060
17812
  "data-ohw-section-insert-line": "",
19061
17813
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
19062
17814
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
19063
17815
  children: [
19064
- /* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
19065
- /* @__PURE__ */ jsx33(
17816
+ /* @__PURE__ */ jsx32("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
17817
+ /* @__PURE__ */ jsx32(
19066
17818
  Badge,
19067
17819
  {
19068
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",
@@ -19079,11 +17831,11 @@ function OhhwellsBridge() {
19079
17831
  children: "Add Section"
19080
17832
  }
19081
17833
  ),
19082
- /* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } })
17834
+ /* @__PURE__ */ jsx32("div", { className: "flex-1 bg-primary", style: { height: 3 } })
19083
17835
  ]
19084
17836
  }
19085
17837
  ),
19086
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx33(
17838
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx32(
19087
17839
  LinkPopover,
19088
17840
  {
19089
17841
  panelRef: linkPopoverPanelRef,
@@ -19100,7 +17852,7 @@ function OhhwellsBridge() {
19100
17852
  },
19101
17853
  linkPopover.key
19102
17854
  ) : null,
19103
- floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx33(
17855
+ floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx32(
19104
17856
  FloatingPanel,
19105
17857
  {
19106
17858
  open: true,
@@ -19110,7 +17862,7 @@ function OhhwellsBridge() {
19110
17862
  onPositionChange: setFloatingPanelPos,
19111
17863
  parentScroll: parentScrollSnap ?? parentScrollRef.current,
19112
17864
  onClose: closeFloatingPanelOnly,
19113
- children: /* @__PURE__ */ jsx33(
17865
+ children: /* @__PURE__ */ jsx32(
19114
17866
  SocialsDisplayPanel,
19115
17867
  {
19116
17868
  display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
@@ -19121,115 +17873,11 @@ function OhhwellsBridge() {
19121
17873
  }
19122
17874
  )
19123
17875
  }
19124
- ) : null,
19125
- floatingPanel && floatingPanel.kind === "logo-size" && logoSizeDraft ? /* @__PURE__ */ jsx33(
19126
- FloatingPanel,
19127
- {
19128
- open: true,
19129
- title: floatingPanel.title,
19130
- context: floatingPanel.context,
19131
- position: floatingPanelPos,
19132
- onPositionChange: setFloatingPanelPos,
19133
- parentScroll: parentScrollSnap ?? parentScrollRef.current,
19134
- onClose: closeFloatingPanelAndDeselect,
19135
- children: /* @__PURE__ */ jsx33(
19136
- LogoSizePanel,
19137
- {
19138
- viewport: editorViewport,
19139
- sizePx: editorViewport === "mobile" && !logoSizeDraft.mobileFollowing ? logoSizeDraft.mobilePx : logoSizeDraft.desktopPx,
19140
- mobileFollowing: logoSizeDraft.mobileFollowing,
19141
- onSizeChange: (px) => {
19142
- const next = editorViewport === "mobile" ? { ...logoSizeDraft, mobilePx: px, mobileFollowing: false } : {
19143
- ...logoSizeDraft,
19144
- desktopPx: px,
19145
- mobilePx: logoSizeDraft.mobileFollowing ? px : logoSizeDraft.mobilePx
19146
- };
19147
- setLogoSizeDraft(next);
19148
- persistLogoSizeDraft(floatingPanel.placement, next);
19149
- },
19150
- onCustomizeMobile: () => {
19151
- const next = {
19152
- ...logoSizeDraft,
19153
- mobileFollowing: false,
19154
- mobilePx: logoSizeDraft.desktopPx
19155
- };
19156
- setLogoSizeDraft(next);
19157
- persistLogoSizeDraft(floatingPanel.placement, next);
19158
- },
19159
- onResetMobile: () => {
19160
- const next = {
19161
- ...logoSizeDraft,
19162
- mobileFollowing: true,
19163
- mobilePx: logoSizeDraft.desktopPx
19164
- };
19165
- setLogoSizeDraft(next);
19166
- persistLogoSizeDraft(floatingPanel.placement, next);
19167
- },
19168
- onUpdateEverywhere: () => {
19169
- const identity = readLogoIdentityFromDom();
19170
- postToParent2({ type: "ow:open-logo-settings", ...identity });
19171
- }
19172
- }
19173
- )
19174
- }
19175
17876
  ) : null
19176
17877
  ] }),
19177
17878
  bridgeRoot
19178
17879
  ) : null;
19179
17880
  }
19180
-
19181
- // src/ui/EmptySection.tsx
19182
- import Link4 from "next/link";
19183
- import { Fragment as Fragment9, jsx as jsx34, jsxs as jsxs21 } from "react/jsx-runtime";
19184
- function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
19185
- return /* @__PURE__ */ jsxs21(Fragment9, { children: [
19186
- /* @__PURE__ */ jsx34(
19187
- "p",
19188
- {
19189
- style: {
19190
- fontFamily: "var(--brand-font-body)",
19191
- fontSize: "0.75rem",
19192
- fontWeight: 500,
19193
- letterSpacing: "0.15em",
19194
- textTransform: "uppercase",
19195
- color: "var(--brand-accent)",
19196
- marginBottom: "1.5rem"
19197
- },
19198
- children: /* @__PURE__ */ jsx34(Link4, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ jsx34("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
19199
- }
19200
- ),
19201
- /* @__PURE__ */ jsx34(
19202
- "h1",
19203
- {
19204
- style: {
19205
- fontFamily: "var(--brand-font-heading)",
19206
- fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
19207
- lineHeight: 1.1,
19208
- letterSpacing: "-0.025em",
19209
- color: "var(--brand-text)",
19210
- marginBottom: "1rem"
19211
- },
19212
- ...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
19213
- children: title
19214
- }
19215
- ),
19216
- /* @__PURE__ */ jsx34(
19217
- "p",
19218
- {
19219
- style: {
19220
- fontFamily: "var(--brand-font-body)",
19221
- fontSize: "1rem",
19222
- lineHeight: 1.7,
19223
- fontWeight: 300,
19224
- color: "var(--brand-text-muted)",
19225
- maxWidth: "340px"
19226
- },
19227
- ...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
19228
- children: "This page doesn't have any content yet."
19229
- }
19230
- )
19231
- ] });
19232
- }
19233
17881
  export {
19234
17882
  AI_DEFAULT_BRAND,
19235
17883
  AI_TREE_SCHEMA_VERSIONS,
@@ -19246,7 +17894,6 @@ export {
19246
17894
  DropdownMenuItem,
19247
17895
  DropdownMenuSeparator,
19248
17896
  DropdownMenuTrigger,
19249
- EmptySection,
19250
17897
  ItemActionToolbar,
19251
17898
  ItemInteractionLayer,
19252
17899
  LinkEditorPanel,