@ohhwells/bridge 0.1.65-next.187 → 0.1.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -46,7 +46,6 @@ __export(index_exports, {
46
46
  DropdownMenuItem: () => DropdownMenuItem,
47
47
  DropdownMenuSeparator: () => DropdownMenuSeparator,
48
48
  DropdownMenuTrigger: () => DropdownMenuTrigger,
49
- EmptySection: () => EmptySection,
50
49
  ItemActionToolbar: () => ItemActionToolbar,
51
50
  ItemInteractionLayer: () => ItemInteractionLayer,
52
51
  LinkEditorPanel: () => LinkEditorPanel,
@@ -157,12 +156,7 @@ function parseAiSectionsState(raw) {
157
156
  media: entry.media && typeof entry.media === "object" ? entry.media : {}
158
157
  }));
159
158
  const removed = Array.isArray(parsed.removed) ? parsed.removed.filter((id) => typeof id === "string" && id.length > 0) : [];
160
- return {
161
- v: 1,
162
- sections,
163
- ...removed.length ? { removed } : {},
164
- ...parsed.hideTemplate === true ? { hideTemplate: true } : {}
165
- };
159
+ return { v: 1, sections, ...removed.length ? { removed } : {} };
166
160
  } catch {
167
161
  return EMPTY_AI_SECTIONS;
168
162
  }
@@ -175,7 +169,6 @@ function applyTreeToState(state, payload) {
175
169
  const entry = {
176
170
  id: payload.id,
177
171
  label: payload.label ?? "Generated section",
178
- ...typeof payload.path === "string" && payload.path ? { path: payload.path } : {},
179
172
  afterSection: payload.mode === "insert" && !insertBefore ? payload.targetSectionId ?? null : null,
180
173
  ...insertBefore && payload.targetSectionId ? { beforeSection: payload.targetSectionId } : {},
181
174
  ...payload.mode === "replace" && payload.targetSectionId ? { replaces: payload.targetSectionId } : {},
@@ -198,317 +191,6 @@ function deleteSectionFromState(state, sectionId) {
198
191
  return { ...state, v: 1, sections: state.sections, removed: [...removed, sectionId] };
199
192
  }
200
193
 
201
- // src/lib/brand-chrome.ts
202
- var BRAND_NAME_KEY = "__ohw_brand_name";
203
- var BRAND_TITLE_KEY = "__ohw_site_title";
204
- var BRAND_FAVICON_LETTER_KEY = "__ohw_favicon_letter";
205
- var BRAND_CHROME_KEYS = /* @__PURE__ */ new Set([
206
- BRAND_NAME_KEY,
207
- BRAND_TITLE_KEY,
208
- BRAND_FAVICON_LETTER_KEY
209
- ]);
210
- function upsertMeta(selector, attr, token, value) {
211
- let el = document.head.querySelector(selector);
212
- if (!el) {
213
- el = document.createElement("meta");
214
- el.setAttribute(attr, token);
215
- document.head.appendChild(el);
216
- }
217
- if (el.getAttribute("content") !== value) el.setAttribute("content", value);
218
- }
219
- function escapeXml(value) {
220
- return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
221
- }
222
- function applyLetterFavicon(letter) {
223
- 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>`;
224
- const href = `data:image/svg+xml,${encodeURIComponent(svg)}`;
225
- let link = document.head.querySelector('link[rel="icon"]');
226
- if (!link) {
227
- link = document.createElement("link");
228
- link.rel = "icon";
229
- document.head.appendChild(link);
230
- }
231
- link.type = "image/svg+xml";
232
- if (link.href !== href) link.href = href;
233
- }
234
- function applyBrandChrome(content) {
235
- const name = content[BRAND_NAME_KEY];
236
- if (typeof name === "string" && name.length > 0) {
237
- document.querySelectorAll("[data-ohw-wordmark]").forEach((el) => {
238
- if (el.textContent !== name) el.textContent = name;
239
- if (el.getAttribute("title") !== name) el.setAttribute("title", name);
240
- });
241
- }
242
- const title = content[BRAND_TITLE_KEY];
243
- if (typeof title === "string" && title.length > 0) {
244
- if (document.title !== title) document.title = title;
245
- upsertMeta('meta[property="og:title"]', "property", "og:title", title);
246
- upsertMeta('meta[name="twitter:title"]', "name", "twitter:title", title);
247
- }
248
- const letter = content[BRAND_FAVICON_LETTER_KEY];
249
- if (typeof letter === "string" && letter.length > 0) {
250
- applyLetterFavicon(letter);
251
- }
252
- }
253
-
254
- // src/lib/brand-kit.ts
255
- var BRAND_KIT_KEY = "__ohw_brand";
256
- var BRAND_VAR_PREFIX = "--ohw-brand-";
257
- var BRAND_VAR_NAMES = ["primary", "accent", "light", "dark", "surface", "border", "muted"].map(
258
- (role) => `${BRAND_VAR_PREFIX}${role}`
259
- );
260
- var FONT_VARS = {
261
- heading: ["--font-heading", "--font-display", "--brand-font-heading"],
262
- body: ["--font-body", "--brand-font-body"]
263
- };
264
- var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
265
- function brandColorVars(kit) {
266
- const { dark, primary, accent, light } = kit.palette;
267
- const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
268
- return {
269
- [`${BRAND_VAR_PREFIX}primary`]: primary,
270
- [`${BRAND_VAR_PREFIX}accent`]: accent,
271
- [`${BRAND_VAR_PREFIX}light`]: light,
272
- [`${BRAND_VAR_PREFIX}dark`]: dark,
273
- [`${BRAND_VAR_PREFIX}surface`]: mix(light, 95, dark),
274
- [`${BRAND_VAR_PREFIX}border`]: mix(light, 85, dark),
275
- [`${BRAND_VAR_PREFIX}muted`]: mix(dark, 62, light)
276
- };
277
- }
278
- function parseBrandKit(raw) {
279
- if (!raw) return null;
280
- try {
281
- const parsed = JSON.parse(raw);
282
- const p = parsed?.palette;
283
- const f = parsed?.fonts;
284
- 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") {
285
- return null;
286
- }
287
- return {
288
- palette: { dark: p.dark, primary: p.primary, accent: p.accent, light: p.light },
289
- fonts: { heading: f.heading, body: f.body }
290
- };
291
- } catch {
292
- return null;
293
- }
294
- }
295
- function familyOf(stack) {
296
- const first = stack.split(",")[0]?.trim() ?? "";
297
- return first.replace(/^['"]|['"]$/g, "");
298
- }
299
- function loadBrandFonts(families) {
300
- const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
301
- if (unique.length === 0) return;
302
- const spec = unique.map((f) => `${f.replace(/ /g, "+")}:400,500,600,700`).join("|");
303
- const href = `https://fonts.googleapis.com/css?family=${spec}&display=swap`;
304
- let link = document.getElementById(BRAND_FONT_LINK_ID);
305
- if (!link) {
306
- link = document.createElement("link");
307
- link.id = BRAND_FONT_LINK_ID;
308
- link.rel = "stylesheet";
309
- document.head.appendChild(link);
310
- }
311
- if (link.href !== href) link.href = href;
312
- }
313
- function applyBrandToDom(kit) {
314
- const root = document.documentElement;
315
- if (!kit) {
316
- for (const name of BRAND_VAR_NAMES) root.style.removeProperty(name);
317
- for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
318
- document.getElementById(BRAND_FONT_LINK_ID)?.remove();
319
- return;
320
- }
321
- for (const [name, value] of Object.entries(brandColorVars(kit))) root.style.setProperty(name, value);
322
- for (const name of FONT_VARS.heading) root.style.setProperty(name, kit.fonts.heading);
323
- for (const name of FONT_VARS.body) root.style.setProperty(name, kit.fonts.body);
324
- loadBrandFonts([familyOf(kit.fonts.heading), familyOf(kit.fonts.body)]);
325
- }
326
-
327
- // src/lib/section-styles.ts
328
- var STYLE_STORE_KEY = "__ohw_styles";
329
- var STYLE_SHEET_ID = "ohw-section-styles";
330
- function parseStyleStore(raw) {
331
- if (!raw) return null;
332
- try {
333
- const parsed = JSON.parse(raw);
334
- if (parsed?.v !== 1) return null;
335
- return {
336
- v: 1,
337
- sections: typeof parsed.sections === "object" && parsed.sections ? parsed.sections : {},
338
- nodes: typeof parsed.nodes === "object" && parsed.nodes ? parsed.nodes : {}
339
- };
340
- } catch {
341
- return null;
342
- }
343
- }
344
- var BG_VALUES = {
345
- surface: "color-mix(in srgb, var(--ohw-brand-light, var(--color-light, #ECECEB)) 94%, var(--ohw-brand-dark, var(--color-dark, #0C0A09)))",
346
- accent: "var(--ohw-brand-primary, var(--color-primary, #0078E5))",
347
- "accent-soft": "color-mix(in srgb, var(--ohw-brand-primary, var(--color-primary, #0078E5)) 12%, var(--ohw-brand-light, var(--color-light, #FFFFFF)))"
348
- };
349
- var HEADLINE_SIZES = { md: 24, lg: 32, xl: 40, display: 56 };
350
- function styleSheetCss() {
351
- const rules = [];
352
- for (const [tone, value] of Object.entries(BG_VALUES)) {
353
- rules.push(`[data-ohw-style-bg="${tone}"] { background: ${value} !important; }`);
354
- }
355
- rules.push(
356
- `[data-ohw-style-bg="accent"] { color: var(--ohw-brand-light, var(--color-light, #FFFFFF)) !important; }`
357
- );
358
- rules.push(
359
- `[data-ohw-style-distribution="space-between"] { display: flex !important; flex-direction: column; justify-content: space-between; }`,
360
- `[data-ohw-style-distribution="center"] { display: flex !important; flex-direction: column; justify-content: center; }`
361
- );
362
- for (const [scale, size] of Object.entries(HEADLINE_SIZES)) {
363
- rules.push(
364
- `[data-ohw-style-headline="${scale}"] :is(h1, h2, h3) { font-size: ${size}px !important; line-height: 1.15 !important; }`
365
- );
366
- }
367
- rules.push(
368
- `[data-ohw-style-aspect="fill-height"] img { height: 100% !important; aspect-ratio: auto !important; object-fit: cover; }`
369
- );
370
- for (const aspect of ["1:1", "4:5", "3:4", "3:2", "16:9", "2:1", "3:1"]) {
371
- rules.push(
372
- `[data-ohw-style-aspect="${aspect.replace(":", "-")}"] img { aspect-ratio: ${aspect.replace(":", " / ")} !important; height: auto !important; object-fit: cover; }`
373
- );
374
- }
375
- const pad = { tight: 40, balanced: 64, airy: 96 };
376
- for (const [spacing, px] of Object.entries(pad)) {
377
- rules.push(
378
- `[data-ohw-style-spacing="${spacing}"] { padding-top: ${px}px !important; padding-bottom: ${px}px !important; }`
379
- );
380
- }
381
- return rules.join("\n");
382
- }
383
- var STYLE_FONT_LINK_ID = "ohw-style-fonts";
384
- function loadStyleFonts(families) {
385
- const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
386
- const existing = document.getElementById(STYLE_FONT_LINK_ID);
387
- if (unique.length === 0) {
388
- existing?.remove();
389
- return;
390
- }
391
- const spec = unique.map((f) => `${f.replace(/ /g, "+")}:400,500,600,700`).join("|");
392
- const href = `https://fonts.googleapis.com/css?family=${spec}&display=swap`;
393
- let link = existing;
394
- if (!link) {
395
- link = document.createElement("link");
396
- link.id = STYLE_FONT_LINK_ID;
397
- link.rel = "stylesheet";
398
- document.head.appendChild(link);
399
- }
400
- if (link.href !== href) link.href = href;
401
- }
402
- var SECTION_ATTRS = {
403
- sectionBackground: "data-ohw-style-bg",
404
- textDistribution: "data-ohw-style-distribution",
405
- headlineScale: "data-ohw-style-headline",
406
- imageAspect: "data-ohw-style-aspect",
407
- spacing: "data-ohw-style-spacing"
408
- };
409
- var NODE_WROTE_ATTR = "data-ohw-style-node";
410
- var NODE_PROPS = ["color", "font-family", "font-size", "background"];
411
- function saveInline(el, prop) {
412
- const attr = `data-ohw-style-prev-${prop}`;
413
- if (!el.hasAttribute(attr)) el.setAttribute(attr, el.style.getPropertyValue(prop));
414
- }
415
- function restoreInline(el, prop) {
416
- const attr = `data-ohw-style-prev-${prop}`;
417
- if (!el.hasAttribute(attr)) return;
418
- const prev = el.getAttribute(attr) ?? "";
419
- if (prev) el.style.setProperty(prop, prev);
420
- else el.style.removeProperty(prop);
421
- el.removeAttribute(attr);
422
- }
423
- function ensureStyleSheet() {
424
- let el = document.getElementById(STYLE_SHEET_ID);
425
- if (!el) {
426
- el = document.createElement("style");
427
- el.id = STYLE_SHEET_ID;
428
- document.head.appendChild(el);
429
- }
430
- const css = styleSheetCss();
431
- if (el.textContent !== css) el.textContent = css;
432
- }
433
- function clearSectionAttrs(root) {
434
- for (const attr of Object.values(SECTION_ATTRS)) {
435
- for (const el of Array.from(root.querySelectorAll(`[${attr}]`))) el.removeAttribute(attr);
436
- }
437
- for (const el of Array.from(root.querySelectorAll("[data-ohw-style-bgcolor]"))) {
438
- restoreInline(el, "background");
439
- el.removeAttribute("data-ohw-style-bgcolor");
440
- }
441
- }
442
- function clearNodeProps(root) {
443
- for (const el of Array.from(root.querySelectorAll(`[${NODE_WROTE_ATTR}]`))) {
444
- const h = el;
445
- for (const prop of NODE_PROPS) restoreInline(h, prop);
446
- h.removeAttribute(NODE_WROTE_ATTR);
447
- }
448
- }
449
- function buttonSurfaceOf(el) {
450
- return el.closest("a, button") ?? el;
451
- }
452
- function applyStylesToDom(store) {
453
- ensureStyleSheet();
454
- clearSectionAttrs(document);
455
- clearNodeProps(document);
456
- loadStyleFonts(
457
- store ? Object.values(store.nodes).flatMap((n) => n.fontFamily ? [n.fontFamily] : []) : []
458
- );
459
- if (!store) return;
460
- for (const [sectionId, override] of Object.entries(store.sections)) {
461
- const sections = document.querySelectorAll(
462
- `[data-ohw-section="${CSS.escape(sectionId)}"]`
463
- );
464
- for (const section of Array.from(sections)) {
465
- for (const [prop, attr] of Object.entries(SECTION_ATTRS)) {
466
- const value = override[prop];
467
- if (value === void 0) continue;
468
- if (prop === "sectionBackground" && override.sectionBackgroundColor !== void 0) continue;
469
- section.setAttribute(attr, String(value).replace(":", "-"));
470
- }
471
- if (override.sectionBackgroundColor !== void 0) {
472
- saveInline(section, "background");
473
- section.style.setProperty("background", override.sectionBackgroundColor, "important");
474
- section.setAttribute("data-ohw-style-bgcolor", "");
475
- }
476
- }
477
- }
478
- for (const [key, override] of Object.entries(store.nodes)) {
479
- const nodes = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
480
- for (const el of Array.from(nodes)) {
481
- if (override.color !== void 0) {
482
- saveInline(el, "color");
483
- el.style.setProperty("color", override.color, "important");
484
- el.setAttribute(NODE_WROTE_ATTR, "");
485
- }
486
- if (override.fontFamily !== void 0) {
487
- saveInline(el, "font-family");
488
- el.style.setProperty("font-family", `'${override.fontFamily}'`, "important");
489
- el.setAttribute(NODE_WROTE_ATTR, "");
490
- }
491
- if (override.fontSize !== void 0) {
492
- saveInline(el, "font-size");
493
- el.style.setProperty("font-size", `${override.fontSize}px`, "important");
494
- el.setAttribute(NODE_WROTE_ATTR, "");
495
- }
496
- if (override.buttonBackground !== void 0 || override.buttonText !== void 0) {
497
- const surface = buttonSurfaceOf(el);
498
- if (override.buttonBackground !== void 0) {
499
- saveInline(surface, "background");
500
- surface.style.setProperty("background", override.buttonBackground, "important");
501
- }
502
- if (override.buttonText !== void 0) {
503
- saveInline(surface, "color");
504
- surface.style.setProperty("color", override.buttonText, "important");
505
- }
506
- surface.setAttribute(NODE_WROTE_ATTR, "");
507
- }
508
- }
509
- }
510
- }
511
-
512
194
  // src/ui/ai-tree/aiSectionsManager.tsx
513
195
  var import_react_dom = require("react-dom");
514
196
  var import_client = require("react-dom/client");
@@ -523,8 +205,7 @@ function lucideByName(name) {
523
205
  }
524
206
  var typeStyle = (spec, font) => ({
525
207
  fontFamily: font,
526
- // Headings shrink with the viewport (reaching full size around ~900px wide); body copy stays put.
527
- 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,
208
+ fontSize: spec.size,
528
209
  lineHeight: spec.line,
529
210
  fontWeight: spec.weight
530
211
  });
@@ -539,36 +220,6 @@ var FEATURE_LINE_CSS = [
539
220
  `background-color:currentColor;-webkit-mask:url("${CHECK_MASK}") no-repeat 0 0/24px 24px;`,
540
221
  `mask:url("${CHECK_MASK}") no-repeat 0 0/24px 24px}`
541
222
  ].join("");
542
- function hexLuminance(color) {
543
- const m = /^#([0-9a-f]{6})$/i.exec(color.trim());
544
- if (!m) return null;
545
- const [r2, g, b] = [0, 2, 4].map((i) => {
546
- const c = parseInt(m[1].slice(i, i + 2), 16) / 255;
547
- return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
548
- });
549
- return 0.2126 * r2 + 0.7152 * g + 0.0722 * b;
550
- }
551
- function hexContrast(a, b) {
552
- const la = hexLuminance(a);
553
- const lb = hexLuminance(b);
554
- if (la === null || lb === null) return null;
555
- const [hi, lo] = la > lb ? [la, lb] : [lb, la];
556
- return (hi + 0.05) / (lo + 0.05);
557
- }
558
- function accentBandContext(brand) {
559
- const p = brand.palette;
560
- const lightWins = (hexContrast(p.light, p.primary) ?? 99) >= (hexContrast(p.dark, p.primary) ?? 0);
561
- if (lightWins) {
562
- return {
563
- brand: { ...brand, palette: { dark: p.light, primary: p.light, accent: p.light, light: p.primary } },
564
- buttonLabel: p.primary
565
- };
566
- }
567
- return {
568
- brand: { ...brand, palette: { dark: p.dark, primary: p.dark, accent: p.dark, light: p.light } },
569
- buttonLabel: p.light
570
- };
571
- }
572
223
  function textAttrs(ctx, path) {
573
224
  return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
574
225
  }
@@ -581,8 +232,6 @@ var AI_RESPONSIVE_CSS = [
581
232
  " [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
582
233
  " [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
583
234
  " [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
584
- " [data-ai-responsive] { overflow-x: hidden; }",
585
- " [data-ai-responsive] img { max-width: 100%; }",
586
235
  "}"
587
236
  ].join("\n");
588
237
  var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
@@ -676,7 +325,7 @@ function ButtonEl({
676
325
  textDecoration: "none",
677
326
  cursor: "pointer",
678
327
  ...typeStyle(AI_TREE_TOKENS.type.button, ctx.brand.fonts.body),
679
- ...secondary ? { border: `1px solid ${ctx.brand.palette.dark}`, color: ctx.brand.palette.dark } : { background: ctx.brand.palette.primary, color: ctx.buttonLabel ?? AI_TREE_TOKENS.textPrimaryForeground }
328
+ ...secondary ? { border: `1px solid ${ctx.brand.palette.dark}`, color: ctx.brand.palette.dark } : { background: ctx.brand.palette.primary, color: AI_TREE_TOKENS.textPrimaryForeground }
680
329
  },
681
330
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { ...path ? textAttrs(ctx, `${path}.label`) : {}, children: str(slots.label) })
682
331
  }
@@ -1578,14 +1227,11 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
1578
1227
  return null;
1579
1228
  }
1580
1229
  const resolvedBrand = brand ?? AI_DEFAULT_BRAND;
1581
- const band = (tree.settings ?? {}).sectionBackground === "accent" ? accentBandContext(resolvedBrand) : null;
1582
- const blockBrand = band?.brand ?? resolvedBrand;
1583
1230
  const ctx = {
1584
- brand: blockBrand,
1231
+ brand: resolvedBrand,
1585
1232
  resolveMedia: resolveMedia ?? (() => null),
1586
- cardSurface: blockBrand.palette.light.toUpperCase() === AI_DEFAULT_BRAND.palette.light.toUpperCase() ? "#ECECEB" : `color-mix(in srgb, ${blockBrand.palette.light} 90%, ${blockBrand.palette.dark})`,
1587
- keyFor: editKeyPrefix ? (path) => `${editKeyPrefix}.${path}` : null,
1588
- ...band ? { buttonLabel: band.buttonLabel } : {}
1233
+ cardSurface: resolvedBrand.palette.light.toUpperCase() === AI_DEFAULT_BRAND.palette.light.toUpperCase() ? "#ECECEB" : `color-mix(in srgb, ${resolvedBrand.palette.light} 90%, ${resolvedBrand.palette.dark})`,
1234
+ keyFor: editKeyPrefix ? (path) => `${editKeyPrefix}.${path}` : null
1589
1235
  };
1590
1236
  const settings = tree.settings ?? {};
1591
1237
  const pad = AI_TREE_TOKENS.sectionPadding[settings.spacing ?? "balanced"];
@@ -1593,20 +1239,6 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
1593
1239
  const overlayAlpha = { low: 0.25, medium: 0.45, high: 0.65 }[settings.overlayIntensity ?? "medium"];
1594
1240
  const backgroundUrl = isOverlay && settings.backgroundMedia ? ctx.resolveMedia(settings.backgroundMedia) : null;
1595
1241
  const bgAttrs = ctx.keyFor && isOverlay && settings.backgroundMedia ? { "data-ohw-key": ctx.keyFor("settings.backgroundMedia"), "data-ohw-editable": "bg-image" } : {};
1596
- const toneBackground = (() => {
1597
- const { dark, primary, light } = resolvedBrand.palette;
1598
- switch (settings.sectionBackground) {
1599
- case "surface":
1600
- return `color-mix(in srgb, ${light} 94%, ${dark})`;
1601
- case "accent":
1602
- return primary;
1603
- case "accent-soft":
1604
- return `color-mix(in srgb, ${primary} 12%, ${light})`;
1605
- default:
1606
- return void 0;
1607
- }
1608
- })();
1609
- const distributed = !isOverlay && settings.textDistribution;
1610
1242
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1611
1243
  "section",
1612
1244
  {
@@ -1616,11 +1248,10 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
1616
1248
  style: {
1617
1249
  position: "relative",
1618
1250
  padding: `${pad}px 0`,
1619
- background: toneBackground ?? (isOverlay && !backgroundUrl ? "#DBEAFE" : void 0),
1251
+ background: isOverlay && !backgroundUrl ? "#DBEAFE" : void 0,
1620
1252
  backgroundImage: backgroundUrl ? `url(${backgroundUrl})` : void 0,
1621
1253
  backgroundSize: "cover",
1622
- backgroundPosition: "center",
1623
- color: settings.sectionBackground === "accent" ? blockBrand.palette.dark : void 0
1254
+ backgroundPosition: "center"
1624
1255
  },
1625
1256
  children: [
1626
1257
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
@@ -1644,24 +1275,10 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
1644
1275
  display: "grid",
1645
1276
  gridTemplateColumns: "repeat(12, 1fr)",
1646
1277
  gap: AI_TREE_TOKENS.spacing6,
1647
- alignItems: distributed === "space-between" ? "stretch" : (distributed ?? settings.verticalPosition) === "top" ? "start" : "center",
1278
+ alignItems: settings.verticalPosition === "top" ? "start" : "center",
1648
1279
  marginTop: r2 > 0 ? AI_TREE_TOKENS.spacing8 : 0
1649
1280
  },
1650
- children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1651
- "div",
1652
- {
1653
- "data-ai-cell": "",
1654
- style: {
1655
- gridColumn: `span ${Math.min(12, Math.max(1, block.span))}`,
1656
- minWidth: 0,
1657
- // space-between: each column becomes a flex column whose content spreads over
1658
- // the full row height instead of clumping at the top.
1659
- ...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
1660
- },
1661
- children: renderNode(block, ctx, `r${r2}.b${b}`)
1662
- },
1663
- b
1664
- ))
1281
+ children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { gridColumn: `span ${Math.min(12, Math.max(1, block.span))}`, minWidth: 0 }, children: renderNode(block, ctx, `r${r2}.b${b}`) }, b))
1665
1282
  },
1666
1283
  r2
1667
1284
  ))
@@ -1677,36 +1294,17 @@ var import_jsx_runtime2 = require("react/jsx-runtime");
1677
1294
  var CONTAINER_ATTR = "data-ohw-ai-generated";
1678
1295
  var REPLACED_ATTR = "data-ohw-ai-replaced-by";
1679
1296
  var REMOVED_ATTR = "data-ohw-ai-removed";
1680
- var TEMPLATE_HIDDEN_ATTR = "data-ohw-ai-template-hidden";
1681
- var CHROME_SECTION_IDS = /* @__PURE__ */ new Set(["navbar", "footer"]);
1682
- function readRootVar(name) {
1683
- if (typeof document === "undefined") return "";
1684
- return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
1685
- }
1686
- function deriveBrandOverride() {
1687
- const dark = readRootVar("--ohw-brand-dark");
1688
- const primary = readRootVar("--ohw-brand-primary");
1689
- const light = readRootVar("--ohw-brand-light");
1690
- if (!dark || !primary || !light) return null;
1691
- const accent = readRootVar("--ohw-brand-accent");
1692
- const heading = readRootVar("--font-heading") || readRootVar("--font-display");
1693
- const body = readRootVar("--font-body");
1694
- return {
1695
- palette: { dark, primary, accent: accent || dark, light },
1696
- fonts: {
1697
- heading: heading || AI_DEFAULT_BRAND.fonts.heading,
1698
- body: body || AI_DEFAULT_BRAND.fonts.body
1699
- }
1700
- };
1701
- }
1702
1297
  function deriveTemplateBrand() {
1703
- const dark = readRootVar("--color-dark");
1704
- const primary = readRootVar("--color-primary");
1705
- const light = readRootVar("--color-light");
1298
+ if (typeof document === "undefined") return null;
1299
+ const cs = getComputedStyle(document.documentElement);
1300
+ const read = (name) => cs.getPropertyValue(name).trim();
1301
+ const dark = read("--color-dark");
1302
+ const primary = read("--color-primary");
1303
+ const light = read("--color-light");
1706
1304
  if (!dark || !primary || !light) return null;
1707
- const accent = readRootVar("--color-accent");
1708
- const heading = readRootVar("--font-heading") || readRootVar("--font-display");
1709
- const body = readRootVar("--font-body");
1305
+ const accent = read("--color-accent");
1306
+ const heading = read("--font-heading") || read("--font-display");
1307
+ const body = read("--font-body");
1710
1308
  return {
1711
1309
  palette: { dark, primary, accent: accent || dark, light },
1712
1310
  fonts: {
@@ -1778,24 +1376,6 @@ function syncRemovedSections(state) {
1778
1376
  }
1779
1377
  }
1780
1378
  }
1781
- function syncTemplateHidden(state, pageHasSections) {
1782
- const hide = state.hideTemplate === true && pageHasSections;
1783
- for (const el of Array.from(document.querySelectorAll(`[${TEMPLATE_HIDDEN_ATTR}]`))) {
1784
- if (!hide) {
1785
- el.style.removeProperty("display");
1786
- el.removeAttribute(TEMPLATE_HIDDEN_ATTR);
1787
- }
1788
- }
1789
- if (!hide) return;
1790
- for (const el of Array.from(document.querySelectorAll("[data-ohw-section]"))) {
1791
- if (el.hasAttribute(CONTAINER_ATTR)) continue;
1792
- if (CHROME_SECTION_IDS.has(el.getAttribute("data-ohw-section") ?? "")) continue;
1793
- if (el.parentElement?.closest("[data-ohw-section]")) continue;
1794
- if (el.hasAttribute(REPLACED_ATTR) || el.hasAttribute(REMOVED_ATTR)) continue;
1795
- el.style.display = "none";
1796
- el.setAttribute(TEMPLATE_HIDDEN_ATTR, "");
1797
- }
1798
- }
1799
1379
  function syncReplacedOriginals(state) {
1800
1380
  for (const el of document.querySelectorAll(`[${REPLACED_ATTR}]`)) {
1801
1381
  const byId = el.getAttribute(REPLACED_ATTR) ?? "";
@@ -1816,12 +1396,8 @@ function syncReplacedOriginals(state) {
1816
1396
  }
1817
1397
  function applyAiSectionsToDom(state, options) {
1818
1398
  if (typeof document === "undefined") return;
1819
- const brandOverride = deriveBrandOverride();
1820
1399
  const templateBrand = deriveTemplateBrand();
1821
- const brandKey = brandOverride ? JSON.stringify(brandOverride) : "";
1822
- const pagePath = window.location.pathname;
1823
- const pageSections = state.sections.filter((entry) => !entry.path || entry.path === pagePath);
1824
- const activeIds = new Set(pageSections.map((entry) => entry.id));
1400
+ const activeIds = new Set(state.sections.map((entry) => entry.id));
1825
1401
  for (const [id, section] of mounted) {
1826
1402
  if (!activeIds.has(id)) {
1827
1403
  section.root.unmount();
@@ -1829,8 +1405,8 @@ function applyAiSectionsToDom(state, options) {
1829
1405
  mounted.delete(id);
1830
1406
  }
1831
1407
  }
1832
- for (const entry of pageSections) {
1833
- const serialized = JSON.stringify(entry) + brandKey;
1408
+ for (const entry of state.sections) {
1409
+ const serialized = JSON.stringify(entry);
1834
1410
  const existing = mounted.get(entry.id);
1835
1411
  if (existing && existing.serialized === serialized && existing.container.isConnected) {
1836
1412
  continue;
@@ -1844,7 +1420,6 @@ function applyAiSectionsToDom(state, options) {
1844
1420
  mounted.delete(entry.id);
1845
1421
  }
1846
1422
  container.setAttribute("data-ohw-section", entry.id);
1847
- container.setAttribute("data-ohw-instance", entry.id);
1848
1423
  container.setAttribute("data-ohw-section-label", entry.label);
1849
1424
  placeContainer(container, entry);
1850
1425
  const root = mounted.get(entry.id)?.root ?? (0, import_client.createRoot)(container);
@@ -1855,7 +1430,7 @@ function applyAiSectionsToDom(state, options) {
1855
1430
  AiTreeRenderer,
1856
1431
  {
1857
1432
  tree: entry.tree,
1858
- brand: brandOverride ?? entry.brand ?? options?.brand ?? templateBrand ?? void 0,
1433
+ brand: entry.brand ?? options?.brand ?? templateBrand ?? void 0,
1859
1434
  resolveMedia,
1860
1435
  editKeyPrefix: `ai.${entry.id}`
1861
1436
  }
@@ -1866,7 +1441,6 @@ function applyAiSectionsToDom(state, options) {
1866
1441
  }
1867
1442
  syncReplacedOriginals(state);
1868
1443
  syncRemovedSections(state);
1869
- syncTemplateHidden(state, pageSections.length > 0);
1870
1444
  }
1871
1445
 
1872
1446
  // src/useLinkHrefGuardian.ts
@@ -2473,7 +2047,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
2473
2047
  const autoId = (0, import_react5.useId)();
2474
2048
  const insertAfter = insertAfterProp ?? autoId;
2475
2049
  const [schedule, setSchedule] = (0, import_react5.useState)(null);
2476
- const [loading, setLoading] = (0, import_react5.useState)(initialScheduleId !== null);
2050
+ const [loading, setLoading] = (0, import_react5.useState)(true);
2477
2051
  const [inEditor, setInEditor] = (0, import_react5.useState)(false);
2478
2052
  const [isHovered, setIsHovered] = (0, import_react5.useState)(false);
2479
2053
  const [modalState, setModalState] = (0, import_react5.useState)(null);
@@ -2647,10 +2221,8 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
2647
2221
  "*"
2648
2222
  );
2649
2223
  };
2224
+ if (!inEditor && !loading && !schedule) return null;
2650
2225
  const sectionId = `scheduling-${insertAfter}`;
2651
- if (!inEditor && !loading && !schedule) {
2652
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("section", { "data-ohw-section": sectionId, "data-ohw-scheduling-anchor": insertAfter, style: { display: "none" } });
2653
- }
2654
2226
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
2655
2227
  "section",
2656
2228
  {
@@ -7755,9 +7327,6 @@ var import_lucide_react7 = require("lucide-react");
7755
7327
 
7756
7328
  // src/lib/sections.ts
7757
7329
  var LINK_PICKER_EXCLUDED_IDS = /* @__PURE__ */ new Set(["navbar", "footer"]);
7758
- function isChromeSection(el) {
7759
- return el.matches("header, nav, footer, aside");
7760
- }
7761
7330
  function titleCaseSectionId(id) {
7762
7331
  return id.split("-").filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
7763
7332
  }
@@ -7768,8 +7337,6 @@ function parseSectionsFromRoot(root) {
7768
7337
  const id = el.getAttribute("data-ohw-section") ?? "";
7769
7338
  if (!id || seen.has(id) || LINK_PICKER_EXCLUDED_IDS.has(id)) continue;
7770
7339
  if (el.parentElement?.closest("[data-ohw-section]")) continue;
7771
- if (el.hasAttribute("data-ohw-ai-template-hidden") || el.hasAttribute("data-ohw-ai-removed") || el.hasAttribute("data-ohw-ai-replaced-by"))
7772
- continue;
7773
7340
  seen.add(id);
7774
7341
  const label = el.getAttribute("data-ohw-section-label") ?? titleCaseSectionId(id);
7775
7342
  sections.push({ id, label });
@@ -7787,12 +7354,8 @@ function parseSectionsFromHtml(html) {
7787
7354
 
7788
7355
  // src/ui/ai-section/AiSectionOverlay.tsx
7789
7356
  var import_jsx_runtime17 = require("react/jsx-runtime");
7790
- function findSectionElement(instanceId) {
7791
- const escaped = CSS.escape(instanceId);
7792
- return document.querySelector(`[data-ohw-instance="${escaped}"]`) ?? document.querySelector(`[data-ohw-section="${escaped}"]:not([data-ohw-instance])`);
7793
- }
7794
- function readRect(instanceId) {
7795
- const el = findSectionElement(instanceId);
7357
+ function readRect(sectionId) {
7358
+ const el = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
7796
7359
  if (!el) return null;
7797
7360
  const r2 = el.getBoundingClientRect();
7798
7361
  if (r2.width <= 0 || r2.height <= 0) return null;
@@ -7815,7 +7378,7 @@ function useLiveSectionRect(sectionId) {
7815
7378
  const opts = { capture: true, passive: true };
7816
7379
  window.addEventListener("scroll", update, opts);
7817
7380
  window.addEventListener("resize", update);
7818
- const el = findSectionElement(sectionId);
7381
+ const el = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
7819
7382
  const ro = el ? new ResizeObserver(update) : null;
7820
7383
  if (el && ro) ro.observe(el);
7821
7384
  const interval = setInterval(update, 500);
@@ -7828,14 +7391,6 @@ function useLiveSectionRect(sectionId) {
7828
7391
  }, [sectionId]);
7829
7392
  return rect;
7830
7393
  }
7831
- function computeSectionBoundaryFlags(instanceId) {
7832
- const topLevel = Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
7833
- (el) => !el.parentElement?.closest("[data-ohw-section]") && !isChromeSection(el)
7834
- );
7835
- const index = topLevel.findIndex((el) => (el.dataset.ohwInstance ?? el.dataset.ohwSection) === instanceId);
7836
- if (index === -1) return { isFirst: true, isLast: true };
7837
- return { isFirst: index === 0, isLast: index === topLevel.length - 1 };
7838
- }
7839
7394
  var PRIMARY2 = "#0885FE";
7840
7395
  function edgeAwareRadius(rect) {
7841
7396
  const container = window.innerWidth <= 480 ? 16 : 24;
@@ -7909,7 +7464,6 @@ function AiSectionOverlay({
7909
7464
  }) {
7910
7465
  const [selectedId, setSelectedId] = (0, import_react8.useState)(null);
7911
7466
  const [reviewId, setReviewId] = (0, import_react8.useState)(null);
7912
- const [reviewButtonsHidden, setReviewButtonsHidden] = (0, import_react8.useState)(false);
7913
7467
  const reviewIdRef = (0, import_react8.useRef)(null);
7914
7468
  reviewIdRef.current = reviewId;
7915
7469
  const selectedIdRef = (0, import_react8.useRef)(null);
@@ -7918,7 +7472,7 @@ function AiSectionOverlay({
7918
7472
  (el) => {
7919
7473
  postToParent2({
7920
7474
  type: "ow:section-selected",
7921
- sectionId: el ? el.dataset.ohwInstance ?? el.dataset.ohwSection ?? null : null,
7475
+ sectionId: el?.dataset.ohwSection ?? null,
7922
7476
  sectionLabel: el ? el.dataset.ohwSectionLabel ?? titleCaseSectionId(el.dataset.ohwSection ?? "") : null
7923
7477
  });
7924
7478
  },
@@ -7927,7 +7481,7 @@ function AiSectionOverlay({
7927
7481
  const selectFromElement = (0, import_react8.useCallback)(
7928
7482
  (el, options) => {
7929
7483
  const sectionEl = el?.closest("[data-ohw-section]") ?? null;
7930
- const id = sectionEl ? sectionEl.dataset.ohwInstance ?? sectionEl.dataset.ohwSection ?? null : null;
7484
+ const id = sectionEl?.dataset.ohwSection ?? null;
7931
7485
  if (id === selectedIdRef.current) return;
7932
7486
  setSelectedId(id);
7933
7487
  if (options?.report !== false) report(sectionEl);
@@ -7968,10 +7522,9 @@ function AiSectionOverlay({
7968
7522
  }
7969
7523
  const found = readRect(sectionId) != null;
7970
7524
  setReviewId(found ? sectionId : null);
7971
- setReviewButtonsHidden(e.data.hideButtons === true);
7972
7525
  postToParent2({ type: "ow:ai-review-started", sectionId, found });
7973
7526
  if (found) {
7974
- document.querySelector(`[data-ohw-instance="${CSS.escape(sectionId)}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
7527
+ document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
7975
7528
  }
7976
7529
  }
7977
7530
  };
@@ -7990,7 +7543,7 @@ function AiSectionOverlay({
7990
7543
  return;
7991
7544
  }
7992
7545
  const sec = t.closest("[data-ohw-section]");
7993
- setHoveredId(sec ? sec.dataset.ohwInstance ?? sec.dataset.ohwSection ?? null : null);
7546
+ setHoveredId(sec?.dataset.ohwSection ?? null);
7994
7547
  };
7995
7548
  const onLeave = () => setHoveredId(null);
7996
7549
  document.addEventListener("mousemove", onMove, { passive: true });
@@ -8022,30 +7575,9 @@ function AiSectionOverlay({
8022
7575
  },
8023
7576
  [postToParent2]
8024
7577
  );
8025
- const activeSelectionId = reviewId ? null : selectedId;
8026
- const selectionRect = useLiveSectionRect(activeSelectionId);
7578
+ const selectionRect = useLiveSectionRect(reviewId ? null : selectedId);
8027
7579
  const reviewRect = useLiveSectionRect(reviewId);
8028
7580
  const hoverRect = useLiveSectionRect(reviewId || hoveredId === selectedId ? null : hoveredId);
8029
- (0, import_react8.useEffect)(() => {
8030
- const selectedEl = activeSelectionId ? findSectionElement(activeSelectionId) : null;
8031
- if (!activeSelectionId || !selectionRect || selectedEl && isChromeSection(selectedEl)) {
8032
- postToParent2({ type: "ow:section-rect", instanceId: null, rect: null });
8033
- return;
8034
- }
8035
- const { isFirst, isLast } = computeSectionBoundaryFlags(activeSelectionId);
8036
- postToParent2({
8037
- type: "ow:section-rect",
8038
- instanceId: activeSelectionId,
8039
- rect: {
8040
- top: selectionRect.top + window.scrollY,
8041
- left: selectionRect.left + window.scrollX,
8042
- width: selectionRect.width,
8043
- height: selectionRect.height
8044
- },
8045
- isFirst,
8046
- isLast
8047
- });
8048
- }, [activeSelectionId, selectionRect, postToParent2]);
8049
7581
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
8050
7582
  hoverRect && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
8051
7583
  "div",
@@ -8096,16 +7628,13 @@ function AiSectionOverlay({
8096
7628
  border: `2px solid ${PRIMARY2}`,
8097
7629
  borderRadius: edgeAwareRadius(reviewRect),
8098
7630
  zIndex: 2147483200,
8099
- // The veil itself: swallows clicks so the section stays locked until decided. This
8100
- // stopPropagation only guards the bubble phase; the bridge's capture-phase click
8101
- // handlers additionally bail on `[data-ohw-ai-review]`, without which a click on
8102
- // Accept/Discard resolves to the media beneath and opens the file picker.
7631
+ // The veil itself: swallows clicks so the section stays locked until decided.
8103
7632
  background: "rgba(8, 133, 254, 0.04)",
8104
7633
  pointerEvents: "auto",
8105
7634
  cursor: "default"
8106
7635
  },
8107
7636
  onClick: (e) => e.stopPropagation(),
8108
- children: !reviewButtonsHidden && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
7637
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
8109
7638
  "div",
8110
7639
  {
8111
7640
  style: {
@@ -12299,7 +11828,6 @@ function readLogoSizeState(content, placement) {
12299
11828
  function getLogoElement(el) {
12300
11829
  const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
12301
11830
  if (marked) return marked;
12302
- if (el.closest('[data-ohw-editable="icon"]')) return null;
12303
11831
  const root = el.closest("nav, [data-ohw-nav-root], footer");
12304
11832
  if (!root) return null;
12305
11833
  const anchor = el.closest("a");
@@ -12548,127 +12076,16 @@ function FloatingPanel({
12548
12076
  );
12549
12077
  }
12550
12078
 
12551
- // src/ui/logo-size-panel.tsx
12552
- var import_lucide_react15 = require("lucide-react");
12553
- var import_jsx_runtime28 = require("react/jsx-runtime");
12554
- function SizeSlider({
12555
- value,
12556
- onChange
12557
- }) {
12558
- const pct = (value - LOGO_SIZE_MIN) / (LOGO_SIZE_MAX - LOGO_SIZE_MIN) * 100;
12559
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex w-full flex-col gap-3", children: [
12560
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex w-full items-center gap-2 text-sm font-medium leading-5", children: [
12561
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "min-w-0 flex-1 text-foreground", children: "Size" }),
12562
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "shrink-0 whitespace-nowrap text-muted-foreground", children: [
12563
- value,
12564
- " px"
12565
- ] })
12566
- ] }),
12567
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "relative h-2 w-full rounded-full bg-primary-50", children: [
12568
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12569
- "div",
12570
- {
12571
- className: "absolute inset-y-0 left-0 rounded-full bg-primary",
12572
- style: { width: `${pct}%` }
12573
- }
12574
- ),
12575
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12576
- "input",
12577
- {
12578
- type: "range",
12579
- min: LOGO_SIZE_MIN,
12580
- max: LOGO_SIZE_MAX,
12581
- step: 1,
12582
- value,
12583
- "aria-label": "Logo size",
12584
- className: cn(
12585
- "absolute inset-0 h-full w-full cursor-pointer appearance-none bg-transparent",
12586
- "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:size-5",
12587
- "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2",
12588
- "[&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-background",
12589
- "[&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full",
12590
- "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary",
12591
- "[&::-moz-range-thumb]:bg-background"
12592
- ),
12593
- onChange: (e) => onChange(Number(e.target.value))
12594
- }
12595
- )
12596
- ] })
12597
- ] });
12598
- }
12599
- function LogoSizePanel({
12600
- viewport,
12601
- sizePx,
12602
- mobileFollowing = true,
12603
- onSizeChange,
12604
- onCustomizeMobile,
12605
- onResetMobile,
12606
- onUpdateEverywhere,
12607
- className
12608
- }) {
12609
- const showFollowing = viewport === "mobile" && mobileFollowing;
12610
- const showMobileSlider = viewport === "mobile" && !mobileFollowing;
12611
- const showDesktopSlider = viewport === "desktop";
12612
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn("flex w-full flex-col gap-4", className), children: [
12613
- showFollowing ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
12614
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-start gap-1", children: [
12615
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react15.Link, { size: 16, className: "mt-0.5 shrink-0 text-foreground", "aria-hidden": true }),
12616
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-sm font-semibold leading-5 text-foreground", children: "Following desktop size" })
12617
- ] }),
12618
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-sm leading-5 text-muted-foreground", children: "Mobile uses the desktop size until you customize it. Change the desktop size and it follows automatically." }),
12619
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12620
- Button,
12621
- {
12622
- type: "button",
12623
- variant: "outline",
12624
- size: "sm",
12625
- className: "h-9 w-full min-w-0 cursor-pointer",
12626
- onClick: onCustomizeMobile,
12627
- children: "Customize for mobile"
12628
- }
12629
- )
12630
- ] }) : null,
12631
- showDesktopSlider || showMobileSlider ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SizeSlider, { value: sizePx, onChange: onSizeChange }) : null,
12632
- showMobileSlider ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12633
- Button,
12634
- {
12635
- type: "button",
12636
- variant: "outline",
12637
- size: "sm",
12638
- className: "h-9 w-full min-w-0 cursor-pointer",
12639
- onClick: onResetMobile,
12640
- children: "Reset to desktop size"
12641
- }
12642
- ) : null,
12643
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "h-px w-full bg-border", role: "separator" }),
12644
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
12645
- Button,
12646
- {
12647
- type: "button",
12648
- variant: "outline",
12649
- size: "sm",
12650
- className: "h-9 w-full min-w-0 cursor-pointer gap-1",
12651
- onClick: onUpdateEverywhere,
12652
- children: [
12653
- "Update logo everywhere",
12654
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react15.ArrowUpRight, { size: 16, "aria-hidden": true })
12655
- ]
12656
- }
12657
- ),
12658
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-sm leading-5 text-muted-foreground", children: "Matches the right version to your background." })
12659
- ] });
12660
- }
12661
-
12662
12079
  // src/ui/socials-display-panel.tsx
12663
- var import_jsx_runtime29 = require("react/jsx-runtime");
12080
+ var import_jsx_runtime28 = require("react/jsx-runtime");
12664
12081
  function DisplaySwitch({
12665
12082
  label,
12666
12083
  checked,
12667
12084
  disabled,
12668
12085
  onChange
12669
12086
  }) {
12670
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex w-full items-center gap-2", children: [
12671
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
12087
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex w-full items-center gap-2", children: [
12088
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12672
12089
  "span",
12673
12090
  {
12674
12091
  className: cn(
@@ -12678,7 +12095,7 @@ function DisplaySwitch({
12678
12095
  children: label
12679
12096
  }
12680
12097
  ),
12681
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
12098
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12682
12099
  "button",
12683
12100
  {
12684
12101
  type: "button",
@@ -12692,7 +12109,7 @@ function DisplaySwitch({
12692
12109
  checked ? "bg-primary" : "bg-primary-50",
12693
12110
  disabled ? "cursor-default opacity-50" : "cursor-pointer"
12694
12111
  ),
12695
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
12112
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12696
12113
  "span",
12697
12114
  {
12698
12115
  className: cn(
@@ -12706,8 +12123,8 @@ function DisplaySwitch({
12706
12123
  ] });
12707
12124
  }
12708
12125
  function SocialsDisplayPanel({ display, onChange, className }) {
12709
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: cn("flex w-full flex-col gap-3", className), children: [
12710
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
12126
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn("flex w-full flex-col gap-3", className), children: [
12127
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12711
12128
  DisplaySwitch,
12712
12129
  {
12713
12130
  label: "Text",
@@ -12716,7 +12133,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
12716
12133
  onChange: (text) => onChange({ ...display, text })
12717
12134
  }
12718
12135
  ),
12719
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
12136
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
12720
12137
  DisplaySwitch,
12721
12138
  {
12722
12139
  label: "Icon",
@@ -13276,8 +12693,8 @@ function useNavItemDrag({
13276
12693
  }
13277
12694
 
13278
12695
  // src/ui/footer-container-chrome.tsx
13279
- var import_lucide_react16 = require("lucide-react");
13280
- var import_jsx_runtime30 = require("react/jsx-runtime");
12696
+ var import_lucide_react15 = require("lucide-react");
12697
+ var import_jsx_runtime29 = require("react/jsx-runtime");
13281
12698
  function FooterContainerChrome({
13282
12699
  rect,
13283
12700
  onAdd,
@@ -13285,7 +12702,7 @@ function FooterContainerChrome({
13285
12702
  }) {
13286
12703
  const chromeGap = 6;
13287
12704
  const buttonMargin = 7;
13288
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
12705
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
13289
12706
  "div",
13290
12707
  {
13291
12708
  "data-ohw-footer-container-chrome": "",
@@ -13297,8 +12714,8 @@ function FooterContainerChrome({
13297
12714
  width: rect.width + chromeGap * 2,
13298
12715
  height: rect.height + chromeGap * 2
13299
12716
  },
13300
- children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Tooltip, { children: [
13301
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
12717
+ children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Tooltip, { children: [
12718
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
13302
12719
  "button",
13303
12720
  {
13304
12721
  type: "button",
@@ -13317,10 +12734,10 @@ function FooterContainerChrome({
13317
12734
  if (addDisabled) return;
13318
12735
  onAdd();
13319
12736
  },
13320
- children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react16.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
12737
+ children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react15.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
13321
12738
  }
13322
12739
  ) }),
13323
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
12740
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
13324
12741
  ] })
13325
12742
  }
13326
12743
  ) });
@@ -13505,18 +12922,6 @@ function collectEditableNodes(extraContent, root = document) {
13505
12922
  }
13506
12923
  if (extraContent && !isScoped) {
13507
12924
  applyNavFooterDeleteOverrides(byKey, extraContent);
13508
- for (const key of LOGO_IMAGE_KEYS) {
13509
- if (!(key in extraContent)) continue;
13510
- byKey.set(key, { key, type: "image", text: extraContent[key] ?? "" });
13511
- }
13512
- for (const key of [LOGO_PLACEHOLDER_KEY, LOGO_ALT_KEY]) {
13513
- if (!(key in extraContent)) continue;
13514
- byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
13515
- }
13516
- for (const key of LOGO_SIZE_KEYS) {
13517
- if (!(key in extraContent)) continue;
13518
- byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
13519
- }
13520
12925
  }
13521
12926
  return Array.from(byKey.values());
13522
12927
  }
@@ -13782,14 +13187,14 @@ function deleteSelectedNavFooterItem(deps) {
13782
13187
  }
13783
13188
 
13784
13189
  // src/ui/navbar-container-chrome.tsx
13785
- var import_lucide_react17 = require("lucide-react");
13786
- var import_jsx_runtime31 = require("react/jsx-runtime");
13190
+ var import_lucide_react16 = require("lucide-react");
13191
+ var import_jsx_runtime30 = require("react/jsx-runtime");
13787
13192
  function NavbarContainerChrome({
13788
13193
  rect,
13789
13194
  onAdd
13790
13195
  }) {
13791
13196
  const chromeGap = 6;
13792
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
13197
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
13793
13198
  "div",
13794
13199
  {
13795
13200
  "data-ohw-navbar-container-chrome": "",
@@ -13801,7 +13206,7 @@ function NavbarContainerChrome({
13801
13206
  width: rect.width + chromeGap * 2,
13802
13207
  height: rect.height + chromeGap * 2
13803
13208
  },
13804
- children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
13209
+ children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
13805
13210
  "button",
13806
13211
  {
13807
13212
  type: "button",
@@ -13818,7 +13223,7 @@ function NavbarContainerChrome({
13818
13223
  e.stopPropagation();
13819
13224
  onAdd();
13820
13225
  },
13821
- children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react17.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
13226
+ children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react16.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
13822
13227
  }
13823
13228
  )
13824
13229
  }
@@ -13827,7 +13232,7 @@ function NavbarContainerChrome({
13827
13232
 
13828
13233
  // src/ui/drop-indicator.tsx
13829
13234
  var React10 = __toESM(require("react"), 1);
13830
- var import_jsx_runtime32 = require("react/jsx-runtime");
13235
+ var import_jsx_runtime31 = require("react/jsx-runtime");
13831
13236
  var dropIndicatorVariants = cva(
13832
13237
  "ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
13833
13238
  {
@@ -13851,7 +13256,7 @@ var dropIndicatorVariants = cva(
13851
13256
  );
13852
13257
  var DropIndicator = React10.forwardRef(
13853
13258
  ({ className, direction, state, ...props }, ref) => {
13854
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
13259
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
13855
13260
  "div",
13856
13261
  {
13857
13262
  ref,
@@ -13868,7 +13273,7 @@ var DropIndicator = React10.forwardRef(
13868
13273
  DropIndicator.displayName = "DropIndicator";
13869
13274
 
13870
13275
  // src/ui/badge.tsx
13871
- var import_jsx_runtime33 = require("react/jsx-runtime");
13276
+ var import_jsx_runtime32 = require("react/jsx-runtime");
13872
13277
  var badgeVariants = cva(
13873
13278
  "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",
13874
13279
  {
@@ -13886,12 +13291,12 @@ var badgeVariants = cva(
13886
13291
  }
13887
13292
  );
13888
13293
  function Badge({ className, variant, ...props }) {
13889
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
13294
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
13890
13295
  }
13891
13296
 
13892
13297
  // src/OhhwellsBridge.tsx
13893
- var import_lucide_react18 = require("lucide-react");
13894
- var import_jsx_runtime34 = require("react/jsx-runtime");
13298
+ var import_lucide_react17 = require("lucide-react");
13299
+ var import_jsx_runtime33 = require("react/jsx-runtime");
13895
13300
  var PRIMARY3 = "#0885FE";
13896
13301
  var IMAGE_FADE_MS = 300;
13897
13302
  function runOpacityFade(el, onDone) {
@@ -13985,10 +13390,21 @@ function parseSchedulingInsertAfter(insertAfter) {
13985
13390
  insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
13986
13391
  };
13987
13392
  }
13988
- function resolveEntryAnchor(entry) {
13989
- if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
13990
- const parsed = parseSchedulingInsertAfter(entry.insertAfter);
13991
- return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
13393
+ function resolveSchedulingInsert(insertAfter, explicitInsertBefore) {
13394
+ const parsed = parseSchedulingInsertAfter(insertAfter);
13395
+ const insertBefore = explicitInsertBefore ?? parsed.insertBefore;
13396
+ const effectiveInsertAfter = insertBefore && parsed.insertBefore === null ? `${insertAfter}${INSERT_BEFORE_MARKER}${insertBefore}` : insertAfter;
13397
+ return { effectiveInsertAfter, insertBefore };
13398
+ }
13399
+ function getSchedulingMountPoint(insertAfter) {
13400
+ const { anchor } = parseSchedulingInsertAfter(insertAfter);
13401
+ let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
13402
+ if (!anchorEl && anchor === "scheduling") {
13403
+ const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
13404
+ anchorEl = widgets.at(-1) ?? null;
13405
+ }
13406
+ if (!anchorEl) return null;
13407
+ return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
13992
13408
  }
13993
13409
  function schedulingMountDepth(insertAfter) {
13994
13410
  if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
@@ -14005,7 +13421,8 @@ function getPageSchedulingEntries(raw) {
14005
13421
  }
14006
13422
  }
14007
13423
  function isSchedulingWidgetMissing(entry) {
14008
- return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
13424
+ const { effectiveInsertAfter } = resolveSchedulingInsert(entry.insertAfter);
13425
+ return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
14009
13426
  }
14010
13427
  function hasMissingSchedulingWidgets(entries) {
14011
13428
  return entries.some(isSchedulingWidgetMissing);
@@ -14035,17 +13452,16 @@ function initSectionsFromContent(content, removeExisting = false) {
14035
13452
  } catch {
14036
13453
  }
14037
13454
  }
14038
- function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
14039
- const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
14040
- const sectionId = schedulingSectionId(widgetId);
13455
+ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId, explicitInsertBefore) {
13456
+ const { effectiveInsertAfter, insertBefore } = resolveSchedulingInsert(insertAfter, explicitInsertBefore);
13457
+ const sectionId = schedulingSectionId(effectiveInsertAfter);
14041
13458
  if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
14042
- const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
14043
- if (!anchorEl) return false;
14044
- const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
13459
+ const mountPoint = getSchedulingMountPoint(effectiveInsertAfter);
13460
+ if (!mountPoint) return false;
14045
13461
  const container = document.createElement("div");
14046
13462
  container.dataset.ohwSectionContainer = "scheduling";
14047
- if (beforeId) {
14048
- const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
13463
+ if (insertBefore) {
13464
+ const beforeAnchor = document.querySelector(`[data-ohw-section="${insertBefore}"]`);
14049
13465
  const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
14050
13466
  if (!beforePoint) return false;
14051
13467
  beforePoint.insertAdjacentElement("beforebegin", container);
@@ -14056,25 +13472,19 @@ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, be
14056
13472
  }
14057
13473
  tail.insertAdjacentElement("afterend", container);
14058
13474
  }
14059
- try {
14060
- const root = (0, import_client2.createRoot)(container);
14061
- (0, import_react_dom3.flushSync)(() => {
14062
- root.render(
14063
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
14064
- SchedulingWidget,
14065
- {
14066
- notifyOnConnect,
14067
- initialScheduleId: scheduleId,
14068
- insertAfter: widgetId
14069
- }
14070
- )
14071
- );
14072
- });
14073
- } catch (err) {
14074
- console.error("[ow:scheduling] render threw", err);
14075
- container.remove();
14076
- return false;
14077
- }
13475
+ const root = (0, import_client2.createRoot)(container);
13476
+ (0, import_react_dom3.flushSync)(() => {
13477
+ root.render(
13478
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
13479
+ SchedulingWidget,
13480
+ {
13481
+ notifyOnConnect,
13482
+ initialScheduleId: scheduleId,
13483
+ insertAfter: effectiveInsertAfter
13484
+ }
13485
+ )
13486
+ );
13487
+ });
14078
13488
  const tracker = getSectionsTracker();
14079
13489
  let sections = [];
14080
13490
  try {
@@ -14082,12 +13492,10 @@ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, be
14082
13492
  } catch {
14083
13493
  }
14084
13494
  const inEditor = typeof window !== "undefined" && window.self !== window.top;
14085
- if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
13495
+ if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === effectiveInsertAfter)) {
14086
13496
  sections.push({
14087
13497
  type: "scheduling",
14088
- insertAfter: widgetId,
14089
- anchorId,
14090
- beforeId: beforeId ?? null,
13498
+ insertAfter: effectiveInsertAfter,
14091
13499
  pagePath: window.location.pathname,
14092
13500
  ...scheduleId ? { scheduleId } : {}
14093
13501
  });
@@ -14101,8 +13509,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
14101
13509
  for (let i = pending.length - 1; i >= 0; i--) {
14102
13510
  const entry = pending[i];
14103
13511
  const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
14104
- const { anchorId, beforeId } = resolveEntryAnchor(entry);
14105
- if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
13512
+ if (mountSchedulingWidget(entry.insertAfter, shouldNotify, entry.scheduleId)) {
14106
13513
  pending.splice(i, 1);
14107
13514
  }
14108
13515
  }
@@ -14250,13 +13657,6 @@ function isInsideLinkEditor(target) {
14250
13657
  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"]')
14251
13658
  );
14252
13659
  }
14253
- function isInsideFloatingPanel(target) {
14254
- return Boolean(target.closest("[data-ohw-floating-panel]"));
14255
- }
14256
- function isPointOverFloatingPanel(clientX, clientY) {
14257
- const el = document.elementFromPoint(clientX, clientY);
14258
- return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
14259
- }
14260
13660
  function getHrefKeyFromElement(el) {
14261
13661
  if (!el) return null;
14262
13662
  const anchor = el.closest("[data-ohw-href-key]");
@@ -14304,7 +13704,8 @@ function isNavItemPointerTarget(el) {
14304
13704
  function getNavigationItemAnchor(el) {
14305
13705
  const anchor = el.matches("[data-ohw-href-key]") ? el : el.closest("[data-ohw-href-key]");
14306
13706
  if (!anchor) return null;
14307
- if (!anchor.querySelector('[data-ohw-editable="text"]') && !getSocialItem(anchor)) return null;
13707
+ if (!anchor.matches('[data-ohw-editable="text"], [data-ohw-editable="plain"]') && !anchor.querySelector('[data-ohw-editable="text"], [data-ohw-editable="plain"]') && !getSocialItem(anchor))
13708
+ return null;
14308
13709
  if (!isNavItemPointerTarget(anchor)) return null;
14309
13710
  return anchor;
14310
13711
  }
@@ -14494,7 +13895,7 @@ function getNavigationSelectionParent(el) {
14494
13895
  if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
14495
13896
  return getFooterLinksContainer();
14496
13897
  }
14497
- 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)) {
13898
+ if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
14498
13899
  return getNavigationRoot(el);
14499
13900
  }
14500
13901
  return null;
@@ -14740,7 +14141,7 @@ function EditGlowChrome({
14740
14141
  hideHandle = false
14741
14142
  }) {
14742
14143
  const GAP = SELECTION_CHROME_GAP2;
14743
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
14144
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
14744
14145
  "div",
14745
14146
  {
14746
14147
  ref: elRef,
@@ -14755,7 +14156,7 @@ function EditGlowChrome({
14755
14156
  zIndex: 2147483646
14756
14157
  },
14757
14158
  children: [
14758
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
14159
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
14759
14160
  "div",
14760
14161
  {
14761
14162
  style: {
@@ -14768,7 +14169,7 @@ function EditGlowChrome({
14768
14169
  }
14769
14170
  }
14770
14171
  ),
14771
- reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
14172
+ reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
14772
14173
  "div",
14773
14174
  {
14774
14175
  "data-ohw-drag-handle-container": "",
@@ -14780,7 +14181,7 @@ function EditGlowChrome({
14780
14181
  transform: "translate(calc(-100% - 7px), -50%)",
14781
14182
  pointerEvents: dragDisabled ? "none" : "auto"
14782
14183
  },
14783
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
14184
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
14784
14185
  DragHandle,
14785
14186
  {
14786
14187
  "aria-label": `Reorder ${reorderHrefKey}`,
@@ -14990,7 +14391,7 @@ function FloatingToolbar({
14990
14391
  return () => ro.disconnect();
14991
14392
  }, [showEditLink, activeCommands]);
14992
14393
  const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
14993
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
14394
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
14994
14395
  "div",
14995
14396
  {
14996
14397
  ref: setRefs,
@@ -15002,12 +14403,12 @@ function FloatingToolbar({
15002
14403
  zIndex: 2147483647,
15003
14404
  pointerEvents: "auto"
15004
14405
  },
15005
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(CustomToolbar, { children: [
15006
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react16.default.Fragment, { children: [
15007
- gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(CustomToolbarDivider, {}),
14406
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(CustomToolbar, { children: [
14407
+ TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_react16.default.Fragment, { children: [
14408
+ gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CustomToolbarDivider, {}),
15008
14409
  btns.map((btn) => {
15009
14410
  const isActive = activeCommands.has(btn.cmd);
15010
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
14411
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
15011
14412
  CustomToolbarButton,
15012
14413
  {
15013
14414
  title: btn.title,
@@ -15016,7 +14417,7 @@ function FloatingToolbar({
15016
14417
  e.preventDefault();
15017
14418
  onCommand(btn.cmd);
15018
14419
  },
15019
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
14420
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
15020
14421
  "svg",
15021
14422
  {
15022
14423
  width: "16",
@@ -15037,7 +14438,7 @@ function FloatingToolbar({
15037
14438
  );
15038
14439
  })
15039
14440
  ] }, gi)),
15040
- showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
14441
+ showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
15041
14442
  CustomToolbarButton,
15042
14443
  {
15043
14444
  type: "button",
@@ -15051,7 +14452,7 @@ function FloatingToolbar({
15051
14452
  e.preventDefault();
15052
14453
  e.stopPropagation();
15053
14454
  },
15054
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Link, { className: "size-4 shrink-0", "aria-hidden": true })
14455
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react17.Link, { className: "size-4 shrink-0", "aria-hidden": true })
15055
14456
  }
15056
14457
  ) : null
15057
14458
  ] })
@@ -15068,7 +14469,7 @@ function StateToggle({
15068
14469
  states,
15069
14470
  onStateChange
15070
14471
  }) {
15071
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
14472
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
15072
14473
  ToggleGroup,
15073
14474
  {
15074
14475
  "data-ohw-state-toggle": "",
@@ -15082,12 +14483,11 @@ function StateToggle({
15082
14483
  left: rect.right - 8,
15083
14484
  transform: "translateX(-100%)"
15084
14485
  },
15085
- children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
14486
+ children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
15086
14487
  }
15087
14488
  );
15088
14489
  }
15089
14490
  var contentCache = /* @__PURE__ */ new Map();
15090
- var fetchedContentPaths = /* @__PURE__ */ new Set();
15091
14491
  function resolveSubdomain(subdomainFromQuery) {
15092
14492
  if (subdomainFromQuery) return subdomainFromQuery;
15093
14493
  if (typeof window !== "undefined") {
@@ -15330,17 +14730,37 @@ function OhhwellsBridge() {
15330
14730
  [persistFields, selectField]
15331
14731
  );
15332
14732
  const fieldDragRef = (0, import_react16.useRef)(null);
14733
+ const buildFieldDropSlots = (0, import_react16.useCallback)((form, draggedKey) => {
14734
+ const others = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== draggedKey);
14735
+ const slots = others.map((el) => {
14736
+ const rect = el.getBoundingClientRect();
14737
+ return { top: rect.top, left: rect.left, width: rect.width };
14738
+ });
14739
+ const last = others[others.length - 1];
14740
+ if (last) {
14741
+ const rect = last.getBoundingClientRect();
14742
+ slots.push({ top: rect.bottom, left: rect.left, width: rect.width });
14743
+ }
14744
+ return slots;
14745
+ }, []);
15333
14746
  const handleFieldDragStart = (0, import_react16.useCallback)(() => {
15334
14747
  const wrapper = fieldPickElRef.current;
15335
14748
  const form = formPickElRef.current;
15336
14749
  if (!wrapper || !form) return;
15337
- fieldDragRef.current = { key: fieldKeyOf(wrapper), form };
15338
- }, []);
14750
+ const key = fieldKeyOf(wrapper);
14751
+ fieldDragRef.current = { key, form };
14752
+ setFieldDragging(true);
14753
+ setFieldDropSlots(buildFieldDropSlots(form, key));
14754
+ }, [buildFieldDropSlots]);
15339
14755
  const handleFieldDragEnd = (0, import_react16.useCallback)(() => {
15340
14756
  fieldDragRef.current = null;
15341
14757
  setFieldDropIndex(null);
14758
+ setFieldDropSlots([]);
14759
+ setFieldDragging(false);
15342
14760
  }, []);
15343
14761
  const [fieldDropIndex, setFieldDropIndex] = (0, import_react16.useState)(null);
14762
+ const [fieldDropSlots, setFieldDropSlots] = (0, import_react16.useState)([]);
14763
+ const [fieldDragging, setFieldDragging] = (0, import_react16.useState)(false);
15344
14764
  const clearFormPickRef = (0, import_react16.useRef)(clearFormPick);
15345
14765
  clearFormPickRef.current = clearFormPick;
15346
14766
  (0, import_react16.useEffect)(() => {
@@ -15406,6 +14826,13 @@ function OhhwellsBridge() {
15406
14826
  const [isItemDragging, setIsItemDragging] = (0, import_react16.useState)(false);
15407
14827
  const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react16.useState)(false);
15408
14828
  isFooterFrameSelectionRef.current = isFooterFrameSelection;
14829
+ const [floatingPanel, setFloatingPanel] = (0, import_react16.useState)(null);
14830
+ const floatingPanelOpenRef = (0, import_react16.useRef)(false);
14831
+ floatingPanelOpenRef.current = floatingPanel !== null;
14832
+ const [floatingPanelPos, setFloatingPanelPos] = (0, import_react16.useState)(null);
14833
+ const [logoSizeDraft, setLogoSizeDraft] = (0, import_react16.useState)(null);
14834
+ const [editorViewport, setEditorViewport] = (0, import_react16.useState)("desktop");
14835
+ const [parentScrollSnap, setParentScrollSnap] = (0, import_react16.useState)(null);
15409
14836
  const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react16.useState)(null);
15410
14837
  const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react16.useState)(null);
15411
14838
  const footerDragRef = (0, import_react16.useRef)(null);
@@ -15420,16 +14847,7 @@ function OhhwellsBridge() {
15420
14847
  const addNavAfterAnchorRef = (0, import_react16.useRef)(null);
15421
14848
  const editContentRef = (0, import_react16.useRef)({});
15422
14849
  const aiSectionsRef = (0, import_react16.useRef)("");
15423
- const brandKitRef = (0, import_react16.useRef)("");
15424
- const stylesRef = (0, import_react16.useRef)("");
15425
14850
  const pendingDeleteUndoRef = (0, import_react16.useRef)(null);
15426
- const [floatingPanel, setFloatingPanel] = (0, import_react16.useState)(null);
15427
- const floatingPanelOpenRef = (0, import_react16.useRef)(false);
15428
- const setFloatingPanelRef = (0, import_react16.useRef)(setFloatingPanel);
15429
- const [floatingPanelPos, setFloatingPanelPos] = (0, import_react16.useState)(null);
15430
- const [logoSizeDraft, setLogoSizeDraft] = (0, import_react16.useState)(null);
15431
- const [editorViewport, setEditorViewport] = (0, import_react16.useState)("desktop");
15432
- const [parentScrollSnap, setParentScrollSnap] = (0, import_react16.useState)(null);
15433
14851
  const [sitePages, setSitePages] = (0, import_react16.useState)([]);
15434
14852
  const [sectionsByPath, setSectionsByPath] = (0, import_react16.useState)({});
15435
14853
  const sectionsPrefetchGenRef = (0, import_react16.useRef)(0);
@@ -15438,18 +14856,7 @@ function OhhwellsBridge() {
15438
14856
  const linkPopoverOpenRef = (0, import_react16.useRef)(false);
15439
14857
  const linkPopoverGraceUntilRef = (0, import_react16.useRef)(0);
15440
14858
  setLinkPopoverRef.current = setLinkPopover;
15441
- setFloatingPanelRef.current = setFloatingPanel;
15442
14859
  linkPopoverSessionRef.current = linkPopover;
15443
- floatingPanelOpenRef.current = Boolean(floatingPanel);
15444
- (0, import_react16.useEffect)(() => {
15445
- const syncViewport = () => {
15446
- const next = window.innerWidth <= 480 ? "mobile" : "desktop";
15447
- setEditorViewport((prev) => prev === next ? prev : next);
15448
- };
15449
- syncViewport();
15450
- window.addEventListener("resize", syncViewport);
15451
- return () => window.removeEventListener("resize", syncViewport);
15452
- }, []);
15453
14860
  const {
15454
14861
  navDragRef,
15455
14862
  navDropSlots,
@@ -16534,6 +15941,25 @@ function OhhwellsBridge() {
16534
15941
  setLogoSizeDraft(null);
16535
15942
  deselectRef.current();
16536
15943
  }, []);
15944
+ (0, import_react16.useEffect)(() => {
15945
+ const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
15946
+ if (!session || !logoSizeDraft) {
15947
+ postToParentRef.current({ type: "ow:logo-size-panel", open: false });
15948
+ return;
15949
+ }
15950
+ postToParentRef.current({
15951
+ type: "ow:logo-size-panel",
15952
+ open: true,
15953
+ title: session.title,
15954
+ context: session.context ?? "",
15955
+ placement: session.placement,
15956
+ viewport: editorViewport,
15957
+ mobileFollowing: logoSizeDraft.mobileFollowing,
15958
+ sizePx: editorViewport === "mobile" && !logoSizeDraft.mobileFollowing ? logoSizeDraft.mobilePx : logoSizeDraft.desktopPx,
15959
+ min: LOGO_SIZE_MIN,
15960
+ max: LOGO_SIZE_MAX
15961
+ });
15962
+ }, [floatingPanel, logoSizeDraft, editorViewport]);
16537
15963
  const persistLogoSizeDraft = (0, import_react16.useCallback)(
16538
15964
  (placement, draft) => {
16539
15965
  const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
@@ -16692,27 +16118,15 @@ function OhhwellsBridge() {
16692
16118
  }
16693
16119
  const applyContent = (content) => {
16694
16120
  const imageLoads = [];
16695
- if (typeof content[BRAND_KIT_KEY] === "string") {
16696
- brandKitRef.current = content[BRAND_KIT_KEY];
16697
- applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
16698
- }
16699
16121
  if (typeof content[AI_SECTIONS_KEY] === "string") {
16700
16122
  aiSectionsRef.current = content[AI_SECTIONS_KEY];
16701
16123
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
16702
16124
  }
16703
- if (typeof content[STYLE_STORE_KEY] === "string") {
16704
- stylesRef.current = content[STYLE_STORE_KEY];
16705
- applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
16706
- }
16707
- applyBrandChrome(content);
16708
16125
  for (const [key, val] of Object.entries(content)) {
16709
16126
  if (key === "__ohw_sections") continue;
16710
16127
  if (key === AI_SECTIONS_KEY) continue;
16711
16128
  if (key === LOGO_PLACEHOLDER_KEY) continue;
16712
16129
  if (LOGO_IMAGE_KEYS.includes(key)) continue;
16713
- if (key === BRAND_KIT_KEY) continue;
16714
- if (key === STYLE_STORE_KEY) continue;
16715
- if (BRAND_CHROME_KEYS.has(key)) continue;
16716
16130
  if (applyVideoSettingNode(key, val)) continue;
16717
16131
  if (applyCarouselNode(key, val)) continue;
16718
16132
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -16770,9 +16184,7 @@ function OhhwellsBridge() {
16770
16184
  let cancelled = false;
16771
16185
  setFetchState("loading");
16772
16186
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
16773
- const initialPath = pathname;
16774
- fetchedContentPaths.add(`${subdomain}::${initialPath}`);
16775
- fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
16187
+ fetch(`${apiUrl}/api/public/sites/${subdomain}/content`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
16776
16188
  if (cancelled) return;
16777
16189
  const content = data?.content ?? {};
16778
16190
  contentCache.set(subdomain, content);
@@ -16801,6 +16213,7 @@ function OhhwellsBridge() {
16801
16213
  e.preventDefault();
16802
16214
  e.stopPropagation();
16803
16215
  if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
16216
+ setFieldDropSlots(buildFieldDropSlots(session.form, session.key));
16804
16217
  setFieldDropIndex(resolveIndex(session.form, e.clientY));
16805
16218
  };
16806
16219
  const onDrop = (e) => {
@@ -16815,6 +16228,8 @@ function OhhwellsBridge() {
16815
16228
  setFormPickRect(session.form.getBoundingClientRect());
16816
16229
  fieldDragRef.current = null;
16817
16230
  setFieldDropIndex(null);
16231
+ setFieldDropSlots([]);
16232
+ setFieldDragging(false);
16818
16233
  };
16819
16234
  window.addEventListener("dragover", onDragOver, true);
16820
16235
  window.addEventListener("drop", onDrop, true);
@@ -16822,7 +16237,7 @@ function OhhwellsBridge() {
16822
16237
  window.removeEventListener("dragover", onDragOver, true);
16823
16238
  window.removeEventListener("drop", onDrop, true);
16824
16239
  };
16825
- }, [isEditMode, persistFields, selectField]);
16240
+ }, [buildFieldDropSlots, isEditMode, persistFields, selectField]);
16826
16241
  (0, import_react16.useEffect)(() => {
16827
16242
  if (!isEditMode) return;
16828
16243
  const mark = () => document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
@@ -16889,21 +16304,10 @@ function OhhwellsBridge() {
16889
16304
  initSectionInstancesFromContent(content, window.location.pathname);
16890
16305
  observer?.disconnect();
16891
16306
  try {
16892
- applyBrandChrome(content);
16893
- if (typeof content[BRAND_KIT_KEY] === "string") {
16894
- applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
16895
- }
16896
- if (typeof content[STYLE_STORE_KEY] === "string") {
16897
- applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
16898
- }
16899
16307
  for (const [key, val] of Object.entries(content)) {
16900
16308
  if (key === "__ohw_sections") continue;
16901
16309
  if (key === LOGO_PLACEHOLDER_KEY) continue;
16902
16310
  if (LOGO_IMAGE_KEYS.includes(key)) continue;
16903
- if (key === BRAND_KIT_KEY) continue;
16904
- if (key === STYLE_STORE_KEY) continue;
16905
- if (key === STYLE_STORE_KEY) continue;
16906
- if (BRAND_CHROME_KEYS.has(key)) continue;
16907
16311
  if (applyVideoSettingNode(key, val)) continue;
16908
16312
  if (applyCarouselNode(key, val)) continue;
16909
16313
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -16946,17 +16350,6 @@ function OhhwellsBridge() {
16946
16350
  debounceTimer = setTimeout(applyFromCache, 150);
16947
16351
  };
16948
16352
  applyFromCache();
16949
- const pathCacheKey = `${subdomain}::${pathname}`;
16950
- if (!fetchedContentPaths.has(pathCacheKey)) {
16951
- fetchedContentPaths.add(pathCacheKey);
16952
- const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
16953
- fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
16954
- if (!data?.content) return;
16955
- contentCache.set(subdomain, data.content);
16956
- applyFromCache();
16957
- }).catch(() => {
16958
- });
16959
- }
16960
16353
  observer = new MutationObserver(scheduleApply);
16961
16354
  observer.observe(document.body, { childList: true, subtree: true });
16962
16355
  return () => {
@@ -17050,31 +16443,26 @@ function OhhwellsBridge() {
17050
16443
  }, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
17051
16444
  (0, import_react16.useEffect)(() => {
17052
16445
  if (!isEditMode) return;
17053
- let lastPosted = 0;
17054
16446
  const measure = () => {
17055
16447
  const h = document.body.scrollHeight;
17056
- if (h > 50 && Math.abs(h - lastPosted) > 1) {
17057
- lastPosted = h;
17058
- postToParent2({ type: "ow:height", height: h });
17059
- }
17060
- };
17061
- let raf = null;
17062
- const schedule = () => {
17063
- if (raf != null) return;
17064
- raf = requestAnimationFrame(() => {
17065
- raf = null;
17066
- measure();
17067
- });
16448
+ if (h > 50) postToParent2({ type: "ow:height", height: h });
17068
16449
  };
17069
16450
  const t1 = setTimeout(measure, 50);
17070
16451
  const t2 = setTimeout(measure, 500);
17071
- const ro = new ResizeObserver(schedule);
17072
- ro.observe(document.body);
16452
+ let lastWidth = window.innerWidth;
16453
+ let resizeTimer = null;
16454
+ const handleResize = () => {
16455
+ if (window.innerWidth === lastWidth) return;
16456
+ lastWidth = window.innerWidth;
16457
+ if (resizeTimer) clearTimeout(resizeTimer);
16458
+ resizeTimer = setTimeout(measure, 150);
16459
+ };
16460
+ window.addEventListener("resize", handleResize);
17073
16461
  return () => {
17074
16462
  clearTimeout(t1);
17075
16463
  clearTimeout(t2);
17076
- if (raf != null) cancelAnimationFrame(raf);
17077
- ro.disconnect();
16464
+ if (resizeTimer) clearTimeout(resizeTimer);
16465
+ window.removeEventListener("resize", handleResize);
17078
16466
  };
17079
16467
  }, [pathname, isEditMode, postToParent2]);
17080
16468
  (0, import_react16.useEffect)(() => {
@@ -17255,12 +16643,10 @@ function OhhwellsBridge() {
17255
16643
  return;
17256
16644
  }
17257
16645
  const target = e.target;
17258
- if (target.closest("[data-ohw-ai-review]")) return;
17259
16646
  if (target.closest("[data-ohw-toolbar]")) return;
17260
16647
  if (target.closest("[data-ohw-state-toggle]")) return;
17261
16648
  if (target.closest("[data-ohw-max-badge]")) return;
17262
16649
  if (isInsideLinkEditor(target)) return;
17263
- if (isInsideFloatingPanel(target)) return;
17264
16650
  if (target.closest("[data-ohw-form-toolbar]")) return;
17265
16651
  if (target.closest(
17266
16652
  '[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
@@ -17534,12 +16920,10 @@ function OhhwellsBridge() {
17534
16920
  };
17535
16921
  const handleDblClick = (e) => {
17536
16922
  const target = e.target;
17537
- if (target.closest("[data-ohw-ai-review]")) return;
17538
16923
  if (target.closest("[data-ohw-toolbar]")) return;
17539
16924
  if (target.closest("[data-ohw-state-toggle]")) return;
17540
16925
  if (target.closest("[data-ohw-max-badge]")) return;
17541
16926
  if (isInsideLinkEditor(target)) return;
17542
- if (isInsideFloatingPanel(target)) return;
17543
16927
  if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
17544
16928
  return;
17545
16929
  }
@@ -17580,14 +16964,11 @@ function OhhwellsBridge() {
17580
16964
  setSiblingHintRects([]);
17581
16965
  return;
17582
16966
  }
17583
- if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || isInsideFloatingPanel(target) || isPointOverFloatingPanel(e.clientX, e.clientY)) {
16967
+ if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || target.closest("[data-ohw-floating-panel]")) {
17584
16968
  hoveredItemElRef.current = null;
17585
16969
  setHoveredItemRect(null);
17586
16970
  hoveredNavContainerRef.current = null;
17587
16971
  setHoveredNavContainerRect(null);
17588
- siblingHintElRef.current = null;
17589
- setSiblingHintRect(null);
17590
- setSiblingHintRects([]);
17591
16972
  return;
17592
16973
  }
17593
16974
  {
@@ -17696,6 +17077,7 @@ function OhhwellsBridge() {
17696
17077
  hoveredNavContainerRef.current = null;
17697
17078
  setHoveredNavContainerRect(null);
17698
17079
  hoveredItemElRef.current = editable;
17080
+ setHoveredItemRect(editable.getBoundingClientRect());
17699
17081
  }
17700
17082
  }
17701
17083
  }
@@ -17992,7 +17374,7 @@ function OhhwellsBridge() {
17992
17374
  }
17993
17375
  };
17994
17376
  const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
17995
- if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
17377
+ if (linkPopoverOpenRef.current) {
17996
17378
  if (hoveredImageRef.current) {
17997
17379
  hoveredImageRef.current = null;
17998
17380
  hoveredImageHasTextOverlapRef.current = false;
@@ -18246,7 +17628,7 @@ function OhhwellsBridge() {
18246
17628
  }
18247
17629
  };
18248
17630
  const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
18249
- if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY) || document.documentElement.hasAttribute("data-ohw-section-picking")) {
17631
+ if (linkPopoverOpenRef.current || document.documentElement.hasAttribute("data-ohw-section-picking")) {
18250
17632
  if (activeStateElRef.current) {
18251
17633
  activeStateElRef.current.removeAttribute("data-ohw-state-hovered");
18252
17634
  activeStateElRef.current = null;
@@ -18321,7 +17703,8 @@ function OhhwellsBridge() {
18321
17703
  };
18322
17704
  const handleMouseMove = (e) => {
18323
17705
  const { clientX, clientY } = e;
18324
- if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY) || isOverEditorChrome(clientX, clientY)) {
17706
+ if (pointOwnedByFloatingPanel(clientX, clientY)) return;
17707
+ if (isOverEditorChrome(clientX, clientY)) {
18325
17708
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
18326
17709
  formHoverElRef.current = null;
18327
17710
  setFormHoverRect(null);
@@ -18329,12 +17712,6 @@ function OhhwellsBridge() {
18329
17712
  setHoveredItemRect(null);
18330
17713
  hoveredNavContainerRef.current = null;
18331
17714
  setHoveredNavContainerRect(null);
18332
- siblingHintElRef.current = null;
18333
- setSiblingHintRect(null);
18334
- setSiblingHintRects([]);
18335
- dismissImageHover();
18336
- clearImageHover();
18337
- setSectionGap(null);
18338
17715
  return;
18339
17716
  }
18340
17717
  probeSectionGapAt(clientX, clientY);
@@ -18345,11 +17722,7 @@ function OhhwellsBridge() {
18345
17722
  if (e.data?.type !== "ow:pointer-sync") return;
18346
17723
  const { clientX, clientY } = e.data;
18347
17724
  if (typeof clientX !== "number" || typeof clientY !== "number") return;
18348
- if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
18349
- dismissImageHover();
18350
- clearImageHover();
18351
- return;
18352
- }
17725
+ if (pointOwnedByFloatingPanel(clientX, clientY)) return;
18353
17726
  probeSectionGapAt(clientX, clientY);
18354
17727
  probeImageAt(clientX, clientY);
18355
17728
  probeHoverCardsAt(clientX, clientY);
@@ -18595,19 +17968,10 @@ function OhhwellsBridge() {
18595
17968
  if (e.data?.type !== "ow:hydrate") return;
18596
17969
  const content = e.data.content;
18597
17970
  if (!content) return;
18598
- if (typeof content[BRAND_KIT_KEY] === "string") {
18599
- brandKitRef.current = content[BRAND_KIT_KEY];
18600
- applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
18601
- }
18602
17971
  if (typeof content[AI_SECTIONS_KEY] === "string") {
18603
17972
  aiSectionsRef.current = content[AI_SECTIONS_KEY];
18604
17973
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
18605
17974
  }
18606
- if (typeof content[STYLE_STORE_KEY] === "string") {
18607
- stylesRef.current = content[STYLE_STORE_KEY];
18608
- applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
18609
- }
18610
- applyBrandChrome(content);
18611
17975
  let sectionsJson = null;
18612
17976
  for (const [key, val] of Object.entries(content)) {
18613
17977
  if (key === "__ohw_sections") {
@@ -18617,9 +17981,6 @@ function OhhwellsBridge() {
18617
17981
  if (key === AI_SECTIONS_KEY) continue;
18618
17982
  if (key === LOGO_PLACEHOLDER_KEY) continue;
18619
17983
  if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
18620
- if (key === BRAND_KIT_KEY) continue;
18621
- if (key === STYLE_STORE_KEY) continue;
18622
- if (BRAND_CHROME_KEYS.has(key)) continue;
18623
17984
  if (applyVideoSettingNode(key, val)) continue;
18624
17985
  if (applyCarouselNode(key, val)) continue;
18625
17986
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -18721,10 +18082,7 @@ function OhhwellsBridge() {
18721
18082
  const payload = e.data.payload;
18722
18083
  if (!payload || typeof payload.id !== "string" || !isRenderableTree(payload.tree)) return;
18723
18084
  const previous = aiSectionsRef.current;
18724
- const nextState = applyTreeToState(parseAiSectionsState(previous), {
18725
- ...payload,
18726
- path: payload.path ?? window.location.pathname
18727
- });
18085
+ const nextState = applyTreeToState(parseAiSectionsState(previous), payload);
18728
18086
  const nextValue = serializeAiSectionsState(nextState);
18729
18087
  aiSectionsRef.current = nextValue;
18730
18088
  applyAiSectionsToDom(nextState);
@@ -18761,42 +18119,12 @@ function OhhwellsBridge() {
18761
18119
  const value = typeof e.data.value === "string" ? e.data.value : "";
18762
18120
  aiSectionsRef.current = value;
18763
18121
  applyAiSectionsToDom(parseAiSectionsState(value));
18764
- applyStylesToDom(parseStyleStore(stylesRef.current));
18765
18122
  const restoredHeight = document.documentElement.scrollHeight;
18766
18123
  if (restoredHeight > 50) postToParentRef.current({ type: "ow:height", height: restoredHeight });
18767
18124
  postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: value }] });
18768
18125
  postAiSectionsChanged();
18769
18126
  };
18770
18127
  window.addEventListener("message", handleAiSetSections);
18771
- const handleAiSetBrand = (e) => {
18772
- if (e.data?.type !== "ow:ai-set-brand") return;
18773
- const value = typeof e.data.value === "string" ? e.data.value : "";
18774
- const previous = brandKitRef.current;
18775
- brandKitRef.current = value;
18776
- applyBrandToDom(parseBrandKit(value));
18777
- if (aiSectionsRef.current) applyAiSectionsToDom(parseAiSectionsState(aiSectionsRef.current));
18778
- applyStylesToDom(parseStyleStore(stylesRef.current));
18779
- postToParentRef.current({ type: "ow:change", nodes: [{ key: BRAND_KIT_KEY, text: value }] });
18780
- postToParentRef.current({ type: "ow:ai-brand-applied", previous, value });
18781
- };
18782
- window.addEventListener("message", handleAiSetBrand);
18783
- const handleAiSetStyles = (e) => {
18784
- if (e.data?.type !== "ow:ai-set-styles") return;
18785
- const value = typeof e.data.value === "string" ? e.data.value : "";
18786
- const previous = stylesRef.current;
18787
- stylesRef.current = value;
18788
- applyStylesToDom(parseStyleStore(value));
18789
- postToParentRef.current({ type: "ow:change", nodes: [{ key: STYLE_STORE_KEY, text: value }] });
18790
- postToParentRef.current({ type: "ow:ai-styles-applied", previous, value });
18791
- };
18792
- window.addEventListener("message", handleAiSetStyles);
18793
- const handleGetBrand = (e) => {
18794
- if (e.data?.type !== "ow:get-brand") return;
18795
- const template = deriveTemplateBrand();
18796
- const value = brandKitRef.current || (template ? JSON.stringify(template) : "");
18797
- postToParentRef.current({ type: "ow:brand-value", value });
18798
- };
18799
- window.addEventListener("message", handleGetBrand);
18800
18128
  const handleDeactivate = (e) => {
18801
18129
  if (e.data?.type !== "ow:deactivate") return;
18802
18130
  if (Date.now() < linkPopoverGraceUntilRef.current) return;
@@ -18805,12 +18133,6 @@ function OhhwellsBridge() {
18805
18133
  closeLinkPopoverRef.current();
18806
18134
  return;
18807
18135
  }
18808
- if (floatingPanelOpenRef.current) {
18809
- setFloatingPanelRef.current(null);
18810
- deselectRef.current();
18811
- deactivateRef.current();
18812
- return;
18813
- }
18814
18136
  deselectRef.current();
18815
18137
  deactivateRef.current();
18816
18138
  };
@@ -19057,12 +18379,6 @@ function OhhwellsBridge() {
19057
18379
  if (aiSectionsRef.current) {
19058
18380
  nodes.push({ key: AI_SECTIONS_KEY, type: "sections", text: aiSectionsRef.current });
19059
18381
  }
19060
- if (stylesRef.current) {
19061
- nodes.push({ key: STYLE_STORE_KEY, type: "styles", text: stylesRef.current });
19062
- }
19063
- if (brandKitRef.current) {
19064
- nodes.push({ key: BRAND_KIT_KEY, type: "brand", text: brandKitRef.current });
19065
- }
19066
18382
  document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
19067
18383
  const formKey = formKeyOf(form);
19068
18384
  if (!formKey) return;
@@ -19080,12 +18396,8 @@ function OhhwellsBridge() {
19080
18396
  if (inserted) {
19081
18397
  const tracker = getSectionsTracker();
19082
18398
  postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
19083
- const reportHeight = () => {
19084
- const h = document.body.scrollHeight;
19085
- if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
19086
- };
19087
- reportHeight();
19088
- setTimeout(reportHeight, 500);
18399
+ const h = document.documentElement.scrollHeight;
18400
+ if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
19089
18401
  }
19090
18402
  };
19091
18403
  const handleSwitchSchedule = (e) => {
@@ -19472,9 +18784,6 @@ function OhhwellsBridge() {
19472
18784
  window.removeEventListener("message", handleAiApplyTree);
19473
18785
  window.removeEventListener("message", handleAiDeleteSection);
19474
18786
  window.removeEventListener("message", handleAiSetSections);
19475
- window.removeEventListener("message", handleAiSetBrand);
19476
- window.removeEventListener("message", handleAiSetStyles);
19477
- window.removeEventListener("message", handleGetBrand);
19478
18787
  window.removeEventListener("message", handleDeactivate);
19479
18788
  window.removeEventListener("message", handleToastAction);
19480
18789
  window.removeEventListener("message", handleFormCount);
@@ -19681,7 +18990,7 @@ function OhhwellsBridge() {
19681
18990
  postToParent2({
19682
18991
  type: "ow:ready",
19683
18992
  version: "1",
19684
- bridgeVersion: "0.1.65",
18993
+ bridgeVersion: "0.1.64",
19685
18994
  path: pathname,
19686
18995
  nodes: collectEditableNodes(editContentRef.current),
19687
18996
  sections
@@ -19735,6 +19044,44 @@ function OhhwellsBridge() {
19735
19044
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
19736
19045
  refreshActiveCommandsRef.current();
19737
19046
  }, []);
19047
+ (0, import_react16.useEffect)(() => {
19048
+ const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
19049
+ if (!session || !logoSizeDraft) return;
19050
+ const onPanelAction = (e) => {
19051
+ const type = e.data?.type;
19052
+ if (type === "ow:logo-size-close") {
19053
+ closeFloatingPanelAndDeselect();
19054
+ return;
19055
+ }
19056
+ if (type === "ow:logo-size-update-everywhere") {
19057
+ postToParentRef.current({ type: "ow:open-logo-settings", ...readLogoIdentityFromDom() });
19058
+ return;
19059
+ }
19060
+ if (type === "ow:logo-size-customize-mobile" || type === "ow:logo-size-reset-mobile") {
19061
+ const following = type === "ow:logo-size-reset-mobile";
19062
+ const next2 = {
19063
+ ...logoSizeDraft,
19064
+ mobileFollowing: following,
19065
+ mobilePx: logoSizeDraft.desktopPx
19066
+ };
19067
+ setLogoSizeDraft(next2);
19068
+ persistLogoSizeDraft(session.placement, next2);
19069
+ return;
19070
+ }
19071
+ if (type !== "ow:logo-size-set") return;
19072
+ const px = Number(e.data.px);
19073
+ if (!Number.isFinite(px)) return;
19074
+ const next = editorViewport === "mobile" ? { ...logoSizeDraft, mobilePx: px, mobileFollowing: false } : {
19075
+ ...logoSizeDraft,
19076
+ desktopPx: px,
19077
+ mobilePx: logoSizeDraft.mobileFollowing ? px : logoSizeDraft.mobilePx
19078
+ };
19079
+ setLogoSizeDraft(next);
19080
+ persistLogoSizeDraft(session.placement, next);
19081
+ };
19082
+ window.addEventListener("message", onPanelAction);
19083
+ return () => window.removeEventListener("message", onPanelAction);
19084
+ }, [floatingPanel, logoSizeDraft, editorViewport, persistLogoSizeDraft, closeFloatingPanelAndDeselect]);
19738
19085
  const handleStateChange = (0, import_react16.useCallback)((state) => {
19739
19086
  if (!activeStateElRef.current) return;
19740
19087
  const el = activeStateElRef.current;
@@ -20076,10 +19423,10 @@ function OhhwellsBridge() {
20076
19423
  [postToParent2]
20077
19424
  );
20078
19425
  return bridgeRoot ? (0, import_react_dom4.createPortal)(
20079
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
20080
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
20081
- isEditMode && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
20082
- Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19426
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
19427
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
19428
+ isEditMode && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
19429
+ Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20083
19430
  MediaOverlay,
20084
19431
  {
20085
19432
  hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
@@ -20090,7 +19437,7 @@ function OhhwellsBridge() {
20090
19437
  },
20091
19438
  `uploading-${key}`
20092
19439
  )),
20093
- mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19440
+ mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20094
19441
  MediaOverlay,
20095
19442
  {
20096
19443
  hover: mediaHover,
@@ -20099,11 +19446,11 @@ function OhhwellsBridge() {
20099
19446
  onVideoSettingsChange: handleVideoSettingsChange
20100
19447
  }
20101
19448
  ),
20102
- carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
20103
- siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
20104
- siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
20105
- isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
20106
- isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19449
+ carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
19450
+ siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
19451
+ siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
19452
+ isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
19453
+ isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20107
19454
  "div",
20108
19455
  {
20109
19456
  className: "pointer-events-none fixed z-2147483646",
@@ -20113,7 +19460,7 @@ function OhhwellsBridge() {
20113
19460
  width: slot.width,
20114
19461
  height: slot.height
20115
19462
  },
20116
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19463
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20117
19464
  DropIndicator,
20118
19465
  {
20119
19466
  direction: slot.direction,
@@ -20124,7 +19471,7 @@ function OhhwellsBridge() {
20124
19471
  },
20125
19472
  `footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
20126
19473
  )),
20127
- isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19474
+ isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20128
19475
  "div",
20129
19476
  {
20130
19477
  className: "pointer-events-none fixed z-2147483646",
@@ -20134,7 +19481,7 @@ function OhhwellsBridge() {
20134
19481
  width: slot.width,
20135
19482
  height: slot.height
20136
19483
  },
20137
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19484
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20138
19485
  DropIndicator,
20139
19486
  {
20140
19487
  direction: slot.direction,
@@ -20145,10 +19492,10 @@ function OhhwellsBridge() {
20145
19492
  },
20146
19493
  `nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
20147
19494
  )),
20148
- hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
20149
- hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
20150
- hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
20151
- formPickRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19495
+ hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
19496
+ hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
19497
+ hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
19498
+ formPickRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20152
19499
  ItemInteractionLayer,
20153
19500
  {
20154
19501
  rect: formPickRect,
@@ -20156,13 +19503,13 @@ function OhhwellsBridge() {
20156
19503
  itemDragSurface: false,
20157
19504
  toolbarAlign: "left",
20158
19505
  chromeGap: 24,
20159
- toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
19506
+ toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
20160
19507
  "div",
20161
19508
  {
20162
19509
  "data-ohw-form-toolbar": "",
20163
19510
  className: "pointer-events-auto flex items-center gap-0.5 whitespace-nowrap rounded-lg border border-border bg-background p-1 shadow-md",
20164
19511
  children: [
20165
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19512
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20166
19513
  "button",
20167
19514
  {
20168
19515
  type: "button",
@@ -20170,11 +19517,11 @@ function OhhwellsBridge() {
20170
19517
  className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
20171
19518
  onClick: () => setFieldTypePickerOpen((open) => !open),
20172
19519
  "data-ohw-add-field": "",
20173
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Plus, { size: 15, "aria-hidden": true })
19520
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react17.Plus, { size: 15, "aria-hidden": true })
20174
19521
  }
20175
19522
  ),
20176
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
20177
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
19523
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
19524
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
20178
19525
  "button",
20179
19526
  {
20180
19527
  type: "button",
@@ -20189,11 +19536,11 @@ function OhhwellsBridge() {
20189
19536
  });
20190
19537
  },
20191
19538
  children: [
20192
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react18.Settings, { size: 14, "aria-hidden": true }),
19539
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react17.Settings, { size: 14, "aria-hidden": true }),
20193
19540
  "Form settings",
20194
19541
  formPickCount ? (
20195
19542
  // Counter pill, per the design — not a text suffix.
20196
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19543
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20197
19544
  "span",
20198
19545
  {
20199
19546
  "data-ohw-form-count": "",
@@ -20205,8 +19552,8 @@ function OhhwellsBridge() {
20205
19552
  ]
20206
19553
  }
20207
19554
  ),
20208
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
20209
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex items-center rounded-md bg-muted/70 p-0.5", children: ["default", "success"].map((state) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19555
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
19556
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex items-center rounded-md bg-muted/70 p-0.5", children: ["default", "success"].map((state) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20210
19557
  "button",
20211
19558
  {
20212
19559
  type: "button",
@@ -20236,7 +19583,7 @@ function OhhwellsBridge() {
20236
19583
  )
20237
19584
  }
20238
19585
  ),
20239
- formHoverRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19586
+ formHoverRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20240
19587
  ItemInteractionLayer,
20241
19588
  {
20242
19589
  rect: formHoverRect,
@@ -20244,11 +19591,11 @@ function OhhwellsBridge() {
20244
19591
  chromeGap: formHoverElRef.current && getFieldWrapper(formHoverElRef.current) ? 8 : 24
20245
19592
  }
20246
19593
  ),
20247
- fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19594
+ fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20248
19595
  ItemInteractionLayer,
20249
19596
  {
20250
19597
  rect: fieldPickRect,
20251
- state: "active-top",
19598
+ state: fieldDragging ? "dragging" : "active-top",
20252
19599
  itemDragSurface: false,
20253
19600
  toolbarAlign: "left",
20254
19601
  chromeGap: 10,
@@ -20256,7 +19603,7 @@ function OhhwellsBridge() {
20256
19603
  dragHandleLabel: "Reorder field",
20257
19604
  onDragHandleDragStart: handleFieldDragStart,
20258
19605
  onDragHandleDragEnd: handleFieldDragEnd,
20259
- toolbar: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19606
+ toolbar: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20260
19607
  FormFieldToolbar,
20261
19608
  {
20262
19609
  type: fieldPickState.type,
@@ -20269,33 +19616,32 @@ function OhhwellsBridge() {
20269
19616
  )
20270
19617
  }
20271
19618
  ),
20272
- fieldDropIndex !== null && formPickElRef.current ? (() => {
20273
- const wrappers = listFieldWrappers(formPickElRef.current).filter(
20274
- (el) => fieldKeyOf(el) !== fieldDragRef.current?.key
20275
- );
20276
- const anchor = wrappers[Math.min(fieldDropIndex, wrappers.length - 1)];
20277
- if (!anchor) return null;
20278
- const rect = anchor.getBoundingClientRect();
20279
- const atEnd = fieldDropIndex >= wrappers.length;
20280
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
20281
- "div",
20282
- {
20283
- className: "pointer-events-none fixed z-[2147483644]",
20284
- style: { top: atEnd ? rect.bottom : rect.top, left: rect.left, width: rect.width },
20285
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(DropIndicator, { direction: "horizontal", state: "dragActive" })
20286
- }
20287
- );
20288
- })() : null,
20289
- fieldTypePickerOpen && formPickRect && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19619
+ fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
19620
+ "div",
19621
+ {
19622
+ className: "pointer-events-none fixed z-[2147483644]",
19623
+ style: { top: slot.top, left: slot.left, width: slot.width },
19624
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
19625
+ DropIndicator,
19626
+ {
19627
+ direction: "horizontal",
19628
+ state: fieldDropIndex === i ? "dragActive" : "dragIdle",
19629
+ className: "!w-full"
19630
+ }
19631
+ )
19632
+ },
19633
+ `field-drop-${i}`
19634
+ )) : null,
19635
+ fieldTypePickerOpen && formPickRect && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20290
19636
  "div",
20291
19637
  {
20292
19638
  className: "pointer-events-none fixed z-[2147483645]",
20293
19639
  style: { top: formPickRect.top + 16, left: formPickRect.left + 24 },
20294
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(FieldTypePicker, { onPick: handleAddField })
19640
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(FieldTypePicker, { onPick: handleAddField })
20295
19641
  }
20296
19642
  ),
20297
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
20298
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19643
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
19644
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20299
19645
  FooterContainerChrome,
20300
19646
  {
20301
19647
  rect: toolbarRect,
@@ -20303,7 +19649,7 @@ function OhhwellsBridge() {
20303
19649
  addDisabled: !canAddFooterColumn()
20304
19650
  }
20305
19651
  ),
20306
- toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19652
+ toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20307
19653
  ItemInteractionLayer,
20308
19654
  {
20309
19655
  rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
@@ -20318,7 +19664,7 @@ function OhhwellsBridge() {
20318
19664
  onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
20319
19665
  onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
20320
19666
  itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection,
20321
- toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19667
+ toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20322
19668
  ItemActionToolbar,
20323
19669
  {
20324
19670
  onEditLink: openLinkPopoverForSelected,
@@ -20354,8 +19700,8 @@ function OhhwellsBridge() {
20354
19700
  ) : void 0
20355
19701
  }
20356
19702
  ),
20357
- toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
20358
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19703
+ toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
19704
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20359
19705
  EditGlowChrome,
20360
19706
  {
20361
19707
  rect: toolbarRect,
@@ -20365,7 +19711,7 @@ function OhhwellsBridge() {
20365
19711
  hideHandle: isItemDragging
20366
19712
  }
20367
19713
  ),
20368
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19714
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20369
19715
  FloatingToolbar,
20370
19716
  {
20371
19717
  rect: toolbarRect,
@@ -20378,7 +19724,7 @@ function OhhwellsBridge() {
20378
19724
  }
20379
19725
  )
20380
19726
  ] }),
20381
- maxBadge && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
19727
+ maxBadge && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
20382
19728
  "div",
20383
19729
  {
20384
19730
  "data-ohw-max-badge": "",
@@ -20404,7 +19750,7 @@ function OhhwellsBridge() {
20404
19750
  ]
20405
19751
  }
20406
19752
  ),
20407
- toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19753
+ toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20408
19754
  StateToggle,
20409
19755
  {
20410
19756
  rect: toggleState.rect,
@@ -20413,15 +19759,15 @@ function OhhwellsBridge() {
20413
19759
  onStateChange: handleStateChange
20414
19760
  }
20415
19761
  ),
20416
- sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
19762
+ sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
20417
19763
  "div",
20418
19764
  {
20419
19765
  "data-ohw-section-insert-line": "",
20420
19766
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
20421
19767
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
20422
19768
  children: [
20423
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
20424
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19769
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
19770
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20425
19771
  Badge,
20426
19772
  {
20427
19773
  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",
@@ -20438,11 +19784,11 @@ function OhhwellsBridge() {
20438
19784
  children: "Add Section"
20439
19785
  }
20440
19786
  ),
20441
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
19787
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
20442
19788
  ]
20443
19789
  }
20444
19790
  ),
20445
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19791
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20446
19792
  LinkPopover,
20447
19793
  {
20448
19794
  panelRef: linkPopoverPanelRef,
@@ -20459,7 +19805,7 @@ function OhhwellsBridge() {
20459
19805
  },
20460
19806
  linkPopover.key
20461
19807
  ) : null,
20462
- floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19808
+ floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20463
19809
  FloatingPanel,
20464
19810
  {
20465
19811
  open: true,
@@ -20469,7 +19815,7 @@ function OhhwellsBridge() {
20469
19815
  onPositionChange: setFloatingPanelPos,
20470
19816
  parentScroll: parentScrollSnap ?? parentScrollRef.current,
20471
19817
  onClose: closeFloatingPanelOnly,
20472
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
19818
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20473
19819
  SocialsDisplayPanel,
20474
19820
  {
20475
19821
  display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
@@ -20480,115 +19826,11 @@ function OhhwellsBridge() {
20480
19826
  }
20481
19827
  )
20482
19828
  }
20483
- ) : null,
20484
- floatingPanel && floatingPanel.kind === "logo-size" && logoSizeDraft ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
20485
- FloatingPanel,
20486
- {
20487
- open: true,
20488
- title: floatingPanel.title,
20489
- context: floatingPanel.context,
20490
- position: floatingPanelPos,
20491
- onPositionChange: setFloatingPanelPos,
20492
- parentScroll: parentScrollSnap ?? parentScrollRef.current,
20493
- onClose: closeFloatingPanelAndDeselect,
20494
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
20495
- LogoSizePanel,
20496
- {
20497
- viewport: editorViewport,
20498
- sizePx: editorViewport === "mobile" && !logoSizeDraft.mobileFollowing ? logoSizeDraft.mobilePx : logoSizeDraft.desktopPx,
20499
- mobileFollowing: logoSizeDraft.mobileFollowing,
20500
- onSizeChange: (px) => {
20501
- const next = editorViewport === "mobile" ? { ...logoSizeDraft, mobilePx: px, mobileFollowing: false } : {
20502
- ...logoSizeDraft,
20503
- desktopPx: px,
20504
- mobilePx: logoSizeDraft.mobileFollowing ? px : logoSizeDraft.mobilePx
20505
- };
20506
- setLogoSizeDraft(next);
20507
- persistLogoSizeDraft(floatingPanel.placement, next);
20508
- },
20509
- onCustomizeMobile: () => {
20510
- const next = {
20511
- ...logoSizeDraft,
20512
- mobileFollowing: false,
20513
- mobilePx: logoSizeDraft.desktopPx
20514
- };
20515
- setLogoSizeDraft(next);
20516
- persistLogoSizeDraft(floatingPanel.placement, next);
20517
- },
20518
- onResetMobile: () => {
20519
- const next = {
20520
- ...logoSizeDraft,
20521
- mobileFollowing: true,
20522
- mobilePx: logoSizeDraft.desktopPx
20523
- };
20524
- setLogoSizeDraft(next);
20525
- persistLogoSizeDraft(floatingPanel.placement, next);
20526
- },
20527
- onUpdateEverywhere: () => {
20528
- const identity = readLogoIdentityFromDom();
20529
- postToParent2({ type: "ow:open-logo-settings", ...identity });
20530
- }
20531
- }
20532
- )
20533
- }
20534
19829
  ) : null
20535
19830
  ] }),
20536
19831
  bridgeRoot
20537
19832
  ) : null;
20538
19833
  }
20539
-
20540
- // src/ui/EmptySection.tsx
20541
- var import_link = __toESM(require("next/link"), 1);
20542
- var import_jsx_runtime35 = require("react/jsx-runtime");
20543
- function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
20544
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
20545
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
20546
- "p",
20547
- {
20548
- style: {
20549
- fontFamily: "var(--brand-font-body)",
20550
- fontSize: "0.75rem",
20551
- fontWeight: 500,
20552
- letterSpacing: "0.15em",
20553
- textTransform: "uppercase",
20554
- color: "var(--brand-accent)",
20555
- marginBottom: "1.5rem"
20556
- },
20557
- children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_link.default, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
20558
- }
20559
- ),
20560
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
20561
- "h1",
20562
- {
20563
- style: {
20564
- fontFamily: "var(--brand-font-heading)",
20565
- fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
20566
- lineHeight: 1.1,
20567
- letterSpacing: "-0.025em",
20568
- color: "var(--brand-text)",
20569
- marginBottom: "1rem"
20570
- },
20571
- ...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
20572
- children: title
20573
- }
20574
- ),
20575
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
20576
- "p",
20577
- {
20578
- style: {
20579
- fontFamily: "var(--brand-font-body)",
20580
- fontSize: "1rem",
20581
- lineHeight: 1.7,
20582
- fontWeight: 300,
20583
- color: "var(--brand-text-muted)",
20584
- maxWidth: "340px"
20585
- },
20586
- ...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
20587
- children: "This page doesn't have any content yet."
20588
- }
20589
- )
20590
- ] });
20591
- }
20592
19834
  // Annotate the CommonJS export names for ESM import in node:
20593
19835
  0 && (module.exports = {
20594
19836
  AI_DEFAULT_BRAND,
@@ -20606,7 +19848,6 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
20606
19848
  DropdownMenuItem,
20607
19849
  DropdownMenuSeparator,
20608
19850
  DropdownMenuTrigger,
20609
- EmptySection,
20610
19851
  ItemActionToolbar,
20611
19852
  ItemInteractionLayer,
20612
19853
  LinkEditorPanel,