@ohhwells/bridge 0.1.112-next.291 → 0.1.112

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,
@@ -353,17 +352,16 @@ var LEGACY_BRAND_VAR_NAMES = [
353
352
  "text-muted",
354
353
  "surface",
355
354
  "border",
356
- "on-primary"
355
+ "on-primary",
356
+ "navbar-background"
357
357
  ].map((role) => `--brand-${role}`);
358
358
  var FONT_VARS = {
359
359
  heading: ["--font-heading", "--font-display", "--brand-font-heading"],
360
360
  body: ["--font-body", "--brand-font-body"]
361
361
  };
362
362
  var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
363
- var CUSTOM_FONT_STYLE_ID = "ohw-brand-custom-fonts";
364
- var CUSTOM_FONT_FORMATS = /* @__PURE__ */ new Set(["woff2", "woff", "truetype", "opentype"]);
365
- function brandColorVars(palette) {
366
- const { dark, primary, accent, light } = palette;
363
+ function brandColorVars(kit) {
364
+ const { dark, primary, accent, light } = kit.palette;
367
365
  const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
368
366
  const surface = mix(light, 95, dark);
369
367
  const border = mix(light, 85, dark);
@@ -386,42 +384,22 @@ function brandColorVars(palette) {
386
384
  "--brand-border": border,
387
385
  // Buttons/bands painted in the primary colour assume it's dark/saturated enough to need
388
386
  // light text on top — the same assumption LOGO_IMAGE's light-on-dark navbar mark makes.
389
- "--brand-on-primary": light
387
+ "--brand-on-primary": light,
388
+ "--brand-navbar-background": dark
390
389
  };
391
390
  }
392
- function parseCustomFontWeight(raw) {
393
- if (typeof raw !== "object" || raw === null) return null;
394
- const w = raw;
395
- if (typeof w.weight !== "number" || !Number.isFinite(w.weight)) return null;
396
- if (typeof w.url !== "string" || !w.url) return null;
397
- if (typeof w.format !== "string" || !CUSTOM_FONT_FORMATS.has(w.format)) return null;
398
- const weightEnd = typeof w.weightEnd === "number" && Number.isFinite(w.weightEnd) && w.weightEnd > w.weight ? w.weightEnd : void 0;
399
- return { weight: w.weight, ...weightEnd !== void 0 ? { weightEnd } : {}, url: w.url, format: w.format };
400
- }
401
- function parseCustomFont(raw) {
402
- if (typeof raw !== "object" || raw === null) return null;
403
- const f = raw;
404
- if (typeof f.family !== "string" || !f.family) return null;
405
- if (typeof f.label !== "string" || !f.label) return null;
406
- if (!Array.isArray(f.weights)) return null;
407
- const weights = f.weights.map(parseCustomFontWeight).filter((w) => w !== null);
408
- if (weights.length === 0) return null;
409
- return { family: f.family, label: f.label, weights };
410
- }
411
391
  function parseBrandKit(raw) {
412
392
  if (!raw) return null;
413
393
  try {
414
394
  const parsed = JSON.parse(raw);
415
395
  const p = parsed?.palette;
416
396
  const f = parsed?.fonts;
417
- const palette = p && typeof p.dark === "string" && typeof p.primary === "string" && typeof p.accent === "string" && typeof p.light === "string" ? { dark: p.dark, primary: p.primary, accent: p.accent, light: p.light } : void 0;
418
- const fonts = f && typeof f.heading === "string" && typeof f.body === "string" ? { heading: f.heading, body: f.body } : void 0;
419
- const customFonts = Array.isArray(parsed?.customFonts) ? parsed.customFonts.map(parseCustomFont).filter((c) => c !== null) : void 0;
420
- if (!palette && !fonts && !customFonts) return null;
397
+ 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") {
398
+ return null;
399
+ }
421
400
  return {
422
- ...palette ? { palette } : {},
423
- ...fonts ? { fonts } : {},
424
- ...customFonts ? { customFonts } : {}
401
+ palette: { dark: p.dark, primary: p.primary, accent: p.accent, light: p.light },
402
+ fonts: { heading: f.heading, body: f.body }
425
403
  };
426
404
  } catch {
427
405
  return null;
@@ -431,16 +409,11 @@ function familyOf(stack) {
431
409
  const first = stack.split(",")[0]?.trim() ?? "";
432
410
  return first.replace(/^['"]|['"]$/g, "");
433
411
  }
434
- function quoteFamily(family) {
435
- return `'${family.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
436
- }
437
- var WEIGHT_SCALE = [100, 200, 300, 400, 500, 600, 700, 800, 900];
438
412
  function loadBrandFonts(families) {
439
413
  const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
440
414
  if (unique.length === 0) return;
441
- const weights = WEIGHT_SCALE.join(";");
442
- const spec = unique.map((f) => `family=${f.replace(/ /g, "+")}:wght@${weights}`).join("&");
443
- const href = `https://fonts.googleapis.com/css2?${spec}&display=swap`;
415
+ const spec = unique.map((f) => `${f.replace(/ /g, "+")}:400,500,600,700`).join("|");
416
+ const href = `https://fonts.googleapis.com/css?family=${spec}&display=swap`;
444
417
  let link = document.getElementById(BRAND_FONT_LINK_ID);
445
418
  if (!link) {
446
419
  link = document.createElement("link");
@@ -450,54 +423,18 @@ function loadBrandFonts(families) {
450
423
  }
451
424
  if (link.href !== href) link.href = href;
452
425
  }
453
- function escapeCssString(value) {
454
- return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
455
- }
456
- function loadCustomFonts(fonts) {
457
- const list = fonts ?? [];
458
- let style = document.getElementById(CUSTOM_FONT_STYLE_ID);
459
- if (list.length === 0) {
460
- style?.remove();
461
- return;
462
- }
463
- if (!style) {
464
- style = document.createElement("style");
465
- style.id = CUSTOM_FONT_STYLE_ID;
466
- document.head.appendChild(style);
467
- }
468
- style.textContent = list.flatMap(
469
- (font) => font.weights.map((w) => {
470
- const weightDescriptor = w.weightEnd ? `${w.weight} ${w.weightEnd}` : `${w.weight}`;
471
- return `@font-face { font-family: '${escapeCssString(font.family)}'; src: url('${escapeCssString(w.url)}') format('${w.format}'); font-weight: ${weightDescriptor}; font-display: swap; }`;
472
- })
473
- ).join("\n");
474
- }
475
426
  function applyBrandToDom(kit) {
476
427
  const root = document.documentElement;
477
428
  if (!kit) {
478
429
  for (const name of [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES]) root.style.removeProperty(name);
479
430
  for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
480
431
  document.getElementById(BRAND_FONT_LINK_ID)?.remove();
481
- document.getElementById(CUSTOM_FONT_STYLE_ID)?.remove();
482
432
  return;
483
433
  }
484
- if (kit.palette) {
485
- for (const [name, value] of Object.entries(brandColorVars(kit.palette))) root.style.setProperty(name, value);
486
- }
487
- if (kit.customFonts) {
488
- loadCustomFonts(kit.customFonts);
489
- }
490
- if (kit.fonts) {
491
- const heading = quoteFamily(kit.fonts.heading);
492
- const body = quoteFamily(kit.fonts.body);
493
- for (const name of FONT_VARS.heading) root.style.setProperty(name, heading);
494
- for (const name of FONT_VARS.body) root.style.setProperty(name, body);
495
- const customFamilies = new Set((kit.customFonts ?? []).map((f) => f.family));
496
- const googleFamilies = [familyOf(kit.fonts.heading), familyOf(kit.fonts.body)].filter(
497
- (f) => !customFamilies.has(f)
498
- );
499
- loadBrandFonts(googleFamilies);
500
- }
434
+ for (const [name, value] of Object.entries(brandColorVars(kit))) root.style.setProperty(name, value);
435
+ for (const name of FONT_VARS.heading) root.style.setProperty(name, kit.fonts.heading);
436
+ for (const name of FONT_VARS.body) root.style.setProperty(name, kit.fonts.body);
437
+ loadBrandFonts([familyOf(kit.fonts.heading), familyOf(kit.fonts.body)]);
501
438
  }
502
439
 
503
440
  // src/lib/section-styles.ts
@@ -522,20 +459,6 @@ var BG_VALUES = {
522
459
  accent: "var(--ohw-brand-primary, var(--color-primary, #0078E5))",
523
460
  "accent-soft": "color-mix(in srgb, var(--ohw-brand-primary, var(--color-primary, #0078E5)) 12%, var(--ohw-brand-light, var(--color-light, #FFFFFF)))"
524
461
  };
525
- var NAVBAR_COLOR_TOKENS = ["dark", "primary", "accent", "light"];
526
- function navbarColorVar(token) {
527
- const fallback = {
528
- dark: "#0C0A09",
529
- primary: "#0078E5",
530
- accent: "#0078E5",
531
- light: "#FFFFFF"
532
- };
533
- return `var(--ohw-brand-${token}, var(--color-${token}, ${fallback[token]}))`;
534
- }
535
- function resolveNavbarValue(value) {
536
- if (value === void 0) return void 0;
537
- return NAVBAR_COLOR_TOKENS.includes(value) ? navbarColorVar(value) : value;
538
- }
539
462
  var HEADLINE_SIZES = { md: 24, lg: 32, xl: 40, display: 56 };
540
463
  function styleSheetCss() {
541
464
  const rules = [];
@@ -705,16 +628,8 @@ function applyStylesToDom(store) {
705
628
  for (const [sectionId, override] of Object.entries(store.sections)) {
706
629
  const escaped = CSS.escape(sectionId);
707
630
  const byInstance = document.querySelectorAll(`[data-ohw-instance="${escaped}"]`);
708
- const sections = Array.from(
709
- byInstance.length ? byInstance : document.querySelectorAll(`[data-ohw-section="${escaped}"]`)
710
- );
711
- const isNavbar = sectionId === "navbar";
712
- if (isNavbar) {
713
- const drawer = document.querySelector("[data-ohw-nav-drawer]");
714
- if (drawer && !sections.includes(drawer)) sections.push(drawer);
715
- }
631
+ const sections = byInstance.length ? byInstance : document.querySelectorAll(`[data-ohw-section="${escaped}"]`);
716
632
  for (const marker of Array.from(sections)) {
717
- const isDrawerMarker = isNavbar && marker.hasAttribute("data-ohw-nav-drawer");
718
633
  const section = marker.querySelector(":scope > [data-ai-section]") ?? marker;
719
634
  for (const [prop, attr] of Object.entries(SECTION_ATTRS)) {
720
635
  const value = override[prop];
@@ -722,23 +637,19 @@ function applyStylesToDom(store) {
722
637
  if (prop === "sectionBackground" && override.sectionBackgroundColor !== void 0) continue;
723
638
  section.setAttribute(attr, String(value).replace(":", "-"));
724
639
  }
725
- const bgOverride = isDrawerMarker ? override.navbarMobileBackground ?? override.sectionBackgroundColor : override.sectionBackgroundColor;
726
- const textOverride = isDrawerMarker ? override.navbarMobileTextColor ?? override.textColor : override.textColor;
727
- const bgValue = isNavbar ? resolveNavbarValue(bgOverride) : bgOverride;
728
- const textValue = isNavbar ? resolveNavbarValue(textOverride) : textOverride;
729
- if (bgValue !== void 0) {
640
+ if (override.sectionBackgroundColor !== void 0) {
730
641
  saveInline(section, "background");
731
- section.style.setProperty("background", bgValue, "important");
642
+ section.style.setProperty("background", override.sectionBackgroundColor, "important");
732
643
  section.setAttribute("data-ohw-style-bgcolor", "");
733
644
  }
734
- if (textValue !== void 0 || override.fontFamily !== void 0) {
645
+ if (override.textColor !== void 0 || override.fontFamily !== void 0) {
735
646
  const textEls = marker.querySelectorAll(
736
647
  '[data-ohw-editable="text"], [data-ohw-editable="plain"], [data-ohw-field-label]'
737
648
  );
738
649
  for (const el of Array.from(textEls)) {
739
- if (textValue !== void 0) {
650
+ if (override.textColor !== void 0) {
740
651
  saveInline(el, "color");
741
- el.style.setProperty("color", textValue, "important");
652
+ el.style.setProperty("color", override.textColor, "important");
742
653
  el.setAttribute(NODE_WROTE_ATTR, "");
743
654
  }
744
655
  if (override.fontFamily !== void 0) {
@@ -1444,22 +1355,6 @@ function accentBandContext(brand) {
1444
1355
  function textAttrs(ctx, path) {
1445
1356
  return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
1446
1357
  }
1447
- var AI_RESPONSIVE_CSS = [
1448
- "@media (max-width: 960px) {",
1449
- " [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
1450
- ' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
1451
- "}",
1452
- "@media (max-width: 640px) {",
1453
- " [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
1454
- " [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
1455
- // Group containers flatten to a column on phones; span placements come along for free.
1456
- " [data-ai-responsive] [data-ai-group] { display: flex !important; flex-direction: column !important; }",
1457
- " [data-ai-responsive] [data-ai-group] > * { grid-column: auto !important; }",
1458
- " [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
1459
- " [data-ai-responsive] { overflow-x: hidden; }",
1460
- " [data-ai-responsive] img { max-width: 100%; }",
1461
- "}"
1462
- ].join("\n");
1463
1358
  var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
1464
1359
  function MediaBox({
1465
1360
  refValue,
@@ -1472,17 +1367,13 @@ function MediaBox({
1472
1367
  const url = refValue ? ctx.resolveMedia(refValue) : null;
1473
1368
  const isIcon = /^(lucide|simple):/.test(refValue);
1474
1369
  const aspectRatio = aspect && /^\d+:\d+$/.test(aspect) ? aspect.replace(":", " / ") : void 0;
1475
- const editAttrs = ctx.keyFor && editPath ? {
1476
- "data-ohw-key": ctx.keyFor(editPath),
1477
- "data-ohw-editable": isIcon ? "icon" : "image"
1478
- } : {};
1370
+ const editAttrs = ctx.keyFor && editPath && !isIcon ? { "data-ohw-key": ctx.keyFor(editPath), "data-ohw-editable": "image" } : {};
1479
1371
  if (isIcon) {
1480
1372
  const Icon = refValue.startsWith("lucide:") ? lucideByName(refValue.slice(7)) : null;
1481
1373
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1482
1374
  "span",
1483
1375
  {
1484
1376
  "data-ai-icon": refValue,
1485
- ...editAttrs,
1486
1377
  style: {
1487
1378
  display: "inline-flex",
1488
1379
  width: 48,
@@ -2375,7 +2266,7 @@ function CollectionBlock({ node, ctx, path }) {
2375
2266
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2376
2267
  "div",
2377
2268
  {
2378
- "data-ai-grid": String(itemsPerRow),
2269
+ "data-ai-grid": "",
2379
2270
  style: {
2380
2271
  display: "grid",
2381
2272
  gridTemplateColumns: `repeat(${itemsPerRow}, 1fr)`,
@@ -2728,7 +2619,6 @@ function AiTreeRenderer({
2728
2619
  {
2729
2620
  "data-ai-section": tree.tag ?? "",
2730
2621
  ...bgAttrs,
2731
- "data-ai-responsive": "",
2732
2622
  style: {
2733
2623
  position: "relative",
2734
2624
  padding: `${pad}px 0`,
@@ -2739,13 +2629,12 @@ function AiTreeRenderer({
2739
2629
  color: settings.sectionBackground === "accent" ? blockBrand.palette.dark : void 0
2740
2630
  },
2741
2631
  children: [
2742
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
2743
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
2744
2632
  isOverlay && backgroundUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
2633
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
2745
2634
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2746
2635
  "div",
2747
2636
  {
2748
- "data-ai-section-inner": "",
2637
+ "data-ai-container": "",
2749
2638
  style: {
2750
2639
  position: "relative",
2751
2640
  maxWidth: AI_TREE_TOKENS.sectionMaxWidth,
@@ -2756,7 +2645,7 @@ function AiTreeRenderer({
2756
2645
  children: tree.rows.map((row, r2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2757
2646
  "div",
2758
2647
  {
2759
- "data-ai-columns": "",
2648
+ "data-ai-row": "",
2760
2649
  style: {
2761
2650
  display: "grid",
2762
2651
  gridTemplateColumns: "repeat(12, 1fr)",
@@ -2806,52 +2695,14 @@ function readRootVar(name) {
2806
2695
  if (typeof document === "undefined") return "";
2807
2696
  return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
2808
2697
  }
2809
- function normalizeColorToHex(value) {
2810
- if (!value || typeof document === "undefined") return value;
2811
- const canvas = document.createElement("canvas");
2812
- canvas.width = 1;
2813
- canvas.height = 1;
2814
- const ctx = canvas.getContext("2d");
2815
- if (!ctx) return value;
2816
- ctx.fillStyle = value;
2817
- ctx.fillRect(0, 0, 1, 1);
2818
- const [r2, g, b] = ctx.getImageData(0, 0, 1, 1).data;
2819
- const toHex = (n) => n.toString(16).padStart(2, "0");
2820
- return `#${toHex(r2)}${toHex(g)}${toHex(b)}`;
2821
- }
2822
- var GENERIC_FONT_KEYWORDS = /* @__PURE__ */ new Set([
2823
- "serif",
2824
- "sans-serif",
2825
- "monospace",
2826
- "cursive",
2827
- "fantasy",
2828
- "system-ui",
2829
- "ui-serif",
2830
- "ui-sans-serif",
2831
- "ui-monospace",
2832
- "ui-rounded",
2833
- "math",
2834
- "emoji",
2835
- "fangsong"
2836
- ]);
2837
- function primaryFontFamily(stack) {
2838
- const first = stack.split(",").map((part) => part.trim().replace(/^["']|["']$/g, "")).find((part) => part && !GENERIC_FONT_KEYWORDS.has(part.toLowerCase()));
2839
- return first ?? "";
2840
- }
2841
- function humanizeFontFamily(name) {
2842
- return name.replace(/^__/, "").replace(/_[0-9a-f]{6}$/i, "").replace(/_/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").trim().replace(/\s+/g, " ").replace(/(^|\s)([a-z])/g, (_, sep, c) => sep + c.toUpperCase());
2843
- }
2844
- function readFontVar(name) {
2845
- return humanizeFontFamily(primaryFontFamily(readRootVar(name)));
2846
- }
2847
2698
  function deriveBrandOverride() {
2848
2699
  const dark = readRootVar("--ohw-brand-dark");
2849
2700
  const primary = readRootVar("--ohw-brand-primary");
2850
2701
  const light = readRootVar("--ohw-brand-light");
2851
2702
  if (!dark || !primary || !light) return null;
2852
2703
  const accent = readRootVar("--ohw-brand-accent");
2853
- const heading = readFontVar("--font-heading") || readFontVar("--font-display");
2854
- const body = readFontVar("--font-body");
2704
+ const heading = readRootVar("--font-heading") || readRootVar("--font-display");
2705
+ const body = readRootVar("--font-body");
2855
2706
  return {
2856
2707
  palette: { dark, primary, accent: accent || dark, light },
2857
2708
  fonts: {
@@ -2860,55 +2711,22 @@ function deriveBrandOverride() {
2860
2711
  }
2861
2712
  };
2862
2713
  }
2863
- function deriveTemplateBrandLive() {
2714
+ function deriveTemplateBrand() {
2864
2715
  const primary = readRootVar("--brand-primary") || readRootVar("--color-primary");
2865
2716
  const dark = readRootVar("--brand-text") || readRootVar("--color-dark");
2866
2717
  const light = readRootVar("--brand-background") || readRootVar("--color-light");
2867
2718
  if (!dark || !primary || !light) return null;
2868
2719
  const accent = readRootVar("--brand-accent") || readRootVar("--color-accent");
2869
- const heading = readFontVar("--brand-font-heading") || readFontVar("--font-heading") || readFontVar("--font-display");
2870
- const body = readFontVar("--brand-font-body") || readFontVar("--font-body");
2720
+ const heading = readRootVar("--brand-font-heading") || readRootVar("--font-heading") || readRootVar("--font-display");
2721
+ const body = readRootVar("--brand-font-body") || readRootVar("--font-body");
2871
2722
  return {
2872
- palette: {
2873
- dark: normalizeColorToHex(dark),
2874
- primary: normalizeColorToHex(primary),
2875
- accent: normalizeColorToHex(accent || dark),
2876
- light: normalizeColorToHex(light)
2877
- },
2723
+ palette: { dark, primary, accent: accent || dark, light },
2878
2724
  fonts: {
2879
2725
  heading: heading || AI_DEFAULT_BRAND.fonts.heading,
2880
2726
  body: body || AI_DEFAULT_BRAND.fonts.body
2881
2727
  }
2882
2728
  };
2883
2729
  }
2884
- function deriveTemplateFontsLive() {
2885
- const heading = readFontVar("--brand-font-heading") || readFontVar("--font-heading") || readFontVar("--font-display");
2886
- const body = readFontVar("--brand-font-body") || readFontVar("--font-body");
2887
- if (!heading && !body) return null;
2888
- return {
2889
- heading: heading || AI_DEFAULT_BRAND.fonts.heading,
2890
- body: body || AI_DEFAULT_BRAND.fonts.body
2891
- };
2892
- }
2893
- var OVERRIDE_VAR_NAMES = [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES, ...FONT_VARS.heading, ...FONT_VARS.body];
2894
- function withOverrideStripped(read) {
2895
- const root = document.documentElement;
2896
- const restore = OVERRIDE_VAR_NAMES.map((name) => [name, root.style.getPropertyValue(name)]);
2897
- for (const name of OVERRIDE_VAR_NAMES) root.style.removeProperty(name);
2898
- try {
2899
- return read();
2900
- } finally {
2901
- for (const [name, value] of restore) if (value) root.style.setProperty(name, value);
2902
- }
2903
- }
2904
- var TEMPLATE_BRAND_SNAPSHOT = typeof document === "undefined" ? null : withOverrideStripped(deriveTemplateBrandLive);
2905
- var TEMPLATE_FONTS_SNAPSHOT = typeof document === "undefined" ? null : withOverrideStripped(deriveTemplateFontsLive);
2906
- function deriveTemplateBrand() {
2907
- return TEMPLATE_BRAND_SNAPSHOT;
2908
- }
2909
- function deriveTemplateFonts() {
2910
- return TEMPLATE_FONTS_SNAPSHOT;
2911
- }
2912
2730
  function deriveTemplateButtonStyle() {
2913
2731
  if (typeof document === "undefined") return null;
2914
2732
  const candidates = Array.from(
@@ -7406,12 +7224,12 @@ var cva = (base, config) => (props) => {
7406
7224
  var import_radix_ui2 = require("radix-ui");
7407
7225
  var import_jsx_runtime5 = require("react/jsx-runtime");
7408
7226
  var toggleVariants = cva(
7409
- "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-bridge-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
7227
+ "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
7410
7228
  {
7411
7229
  variants: {
7412
7230
  variant: {
7413
7231
  default: "bg-transparent border-0",
7414
- outline: "border border-input bg-transparent shadow-xs hover:bg-bridge-accent hover:text-accent-foreground"
7232
+ outline: "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground"
7415
7233
  },
7416
7234
  size: {
7417
7235
  default: "px-2 py-1",
@@ -7504,10 +7322,10 @@ var DragHandle = React4.forwardRef(
7504
7322
  type,
7505
7323
  "data-slot": "drag-handle",
7506
7324
  className: cn(
7507
- "inline-flex h-7 w-4 shrink-0 items-center justify-center rounded-md transition-all duration-200 max-h-7.5",
7325
+ "inline-flex h-7 w-4 shrink-0 items-center justify-center rounded-md transition-all duration-200 max-h-[30px]",
7508
7326
  "bg-white border border-transparent text-stone-500 shadow-md cursor-grab",
7509
7327
  "enabled:hover:border enabled:hover:border-stone-200 enabled:hover:text-stone-950",
7510
- "enabled:active:border enabled:active:border-bridge-primary enabled:active:bg-primary-50 enabled:active:text-stone-950 enabled:active:shadow enabled:active:cursor-grabbing",
7328
+ "enabled:active:border enabled:active:border-primary enabled:active:bg-primary-50 enabled:active:text-stone-950 enabled:active:shadow enabled:active:cursor-grabbing",
7511
7329
  "disabled:cursor-not-allowed disabled:opacity-40 disabled:text-stone-950 disabled:pointer-events-none",
7512
7330
  className
7513
7331
  ),
@@ -7529,7 +7347,7 @@ var CustomToolbar = React5.forwardRef(({ className, onMouseDown, ...props }, ref
7529
7347
  "data-ohw-toolbar": "",
7530
7348
  className: cn(
7531
7349
  // Figma: bg background, radius 8, gap-1, p-0.5, shadow-md — no border
7532
- "inline-flex h-8 items-center gap-1 rounded-(--radius,0.5rem) bg-background p-0.5 font-sans whitespace-nowrap shadow-md",
7350
+ "inline-flex h-8 items-center gap-1 rounded-[var(--radius,0.5rem)] bg-background p-0.5 font-sans whitespace-nowrap shadow-md",
7533
7351
  className
7534
7352
  ),
7535
7353
  onMouseDown: (e) => {
@@ -7558,7 +7376,7 @@ var CustomToolbarButton = React5.forwardRef(
7558
7376
  type,
7559
7377
  className: cn(
7560
7378
  "inline-flex size-7 shrink-0 items-center justify-center rounded-[calc(var(--radius,0.5rem)-2px)] text-foreground transition-colors",
7561
- active ? "bg-bridge-primary text-primary-foreground" : "bg-transparent hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
7379
+ active ? "bg-primary text-primary-foreground" : "bg-transparent hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
7562
7380
  className
7563
7381
  ),
7564
7382
  ...props
@@ -8822,13 +8640,13 @@ function FormFieldToolbar({
8822
8640
  ]
8823
8641
  }
8824
8642
  ) }),
8825
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-47.5 p-1", children: FIELD_TYPES.map((entry) => {
8643
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-[190px] p-1", children: FIELD_TYPES.map((entry) => {
8826
8644
  const Icon = TYPE_ICONS[entry.type];
8827
8645
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
8828
8646
  DropdownMenuItem,
8829
8647
  {
8830
8648
  onSelect: () => onTypeChange(entry.type),
8831
- className: "rounded-md py-2 text-[13px] " + (entry.type === type ? "bg-bridge-primary/10" : ""),
8649
+ className: "rounded-md py-2 text-[13px] " + (entry.type === type ? "bg-primary/10" : ""),
8832
8650
  children: [
8833
8651
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
8834
8652
  entry.label
@@ -8845,7 +8663,7 @@ function FormFieldToolbar({
8845
8663
  type: "button",
8846
8664
  "aria-pressed": required,
8847
8665
  onClick: onRequiredToggle,
8848
- className: "flex h-7 items-center gap-1.5 whitespace-nowrap rounded-md px-2 text-[13px] font-medium transition-colors " + (required ? "bg-bridge-primary/10 text-bridge-primary" : "text-foreground hover:bg-muted/70"),
8666
+ className: "flex h-7 items-center gap-1.5 whitespace-nowrap rounded-md px-2 text-[13px] font-medium transition-colors " + (required ? "bg-primary/10 text-primary" : "text-foreground hover:bg-muted/70"),
8849
8667
  "data-ohw-field-required-toggle": "",
8850
8668
  children: [
8851
8669
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.Asterisk, { size: 14, strokeWidth: 2, "aria-hidden": true }),
@@ -8865,7 +8683,7 @@ function FormFieldToolbar({
8865
8683
  children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.MoreHorizontal, { size: 15, "aria-hidden": true })
8866
8684
  }
8867
8685
  ) }),
8868
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-42.5 p-1", children: [
8686
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-[170px] p-1", children: [
8869
8687
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuItem, { onSelect: onDuplicate, className: "rounded-md py-2 text-[13px]", children: [
8870
8688
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.Copy, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
8871
8689
  "Duplicate"
@@ -8893,7 +8711,7 @@ function FieldTypePicker({ onPick }) {
8893
8711
  {
8894
8712
  type: "button",
8895
8713
  onClick: () => onPick(entry.type),
8896
- className: "flex h-[76px] flex-col items-center justify-center gap-2 rounded-xl border border-border text-[15px] font-medium text-foreground transition-colors hover:border-bridge-primary hover:bg-bridge-primary/5",
8714
+ className: "flex h-[76px] flex-col items-center justify-center gap-2 rounded-xl border border-border text-[15px] font-medium text-foreground transition-colors hover:border-primary hover:bg-primary/5",
8897
8715
  children: [
8898
8716
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: 26, strokeWidth: 1.5, "aria-hidden": true }),
8899
8717
  entry.label
@@ -8919,7 +8737,7 @@ var buttonVariants = cva(
8919
8737
  {
8920
8738
  variants: {
8921
8739
  variant: {
8922
- default: "bg-bridge-primary text-primary-foreground hover:opacity-90",
8740
+ default: "bg-primary text-primary-foreground hover:opacity-90",
8923
8741
  outline: "border border-border bg-background text-foreground shadow-sm hover:bg-muted/80",
8924
8742
  ghost: "min-w-0 px-3 py-2 text-foreground hover:bg-muted/50"
8925
8743
  },
@@ -9014,7 +8832,6 @@ function MediaOverlay({
9014
8832
  (prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
9015
8833
  );
9016
8834
  }, [isVideo]);
9017
- const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
9018
8835
  const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
9019
8836
  const box = {
9020
8837
  position: "fixed",
@@ -9120,8 +8937,8 @@ function MediaOverlay({
9120
8937
  pointerEvents: hover.hasTextOverlap ? "none" : "auto",
9121
8938
  // Selected: a firm component ring with no wash, so the image reads as chosen rather
9122
8939
  // than hovered. Hover keeps the existing tinted preview.
9123
- boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
9124
- background: selected ? "transparent" : "color-mix(in srgb, var(--color-bridge-primary) 20%, transparent)"
8940
+ boxShadow: selected ? "inset 0 0 0 2px var(--color-primary)" : "inset 0 0 0 1.5px var(--color-primary)",
8941
+ background: selected ? "transparent" : "color-mix(in srgb, var(--color-primary) 20%, transparent)"
9125
8942
  },
9126
8943
  onClick: () => onSelect && !selected ? onSelect(hover.key) : onReplace(hover.key),
9127
8944
  children: [
@@ -9144,17 +8961,17 @@ function MediaOverlay({
9144
8961
  },
9145
8962
  children: [
9146
8963
  isVideo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
9147
- replaceLabel
8964
+ isVideo ? "Replace video" : "Replace image"
9148
8965
  ]
9149
8966
  }
9150
8967
  ),
9151
- showChrome && replaceMode !== "none" && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
8968
+ replaceMode === "none" ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
9152
8969
  Button,
9153
8970
  {
9154
8971
  "data-ohw-media-overlay": "",
9155
8972
  variant: "outline",
9156
8973
  size: "sm",
9157
- "aria-label": replaceLabel,
8974
+ "aria-label": isVideo ? "Replace video" : "Replace image",
9158
8975
  className: "gap-1.5 cursor-pointer hover:bg-background",
9159
8976
  style: {
9160
8977
  ...OVERLAY_BUTTON_STYLE,
@@ -9177,7 +8994,7 @@ function MediaOverlay({
9177
8994
  },
9178
8995
  children: [
9179
8996
  isVideo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
9180
- replaceMode === "full" ? replaceLabel : null
8997
+ replaceMode === "full" ? isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image" : null
9181
8998
  ]
9182
8999
  }
9183
9000
  )
@@ -9215,8 +9032,8 @@ function CarouselOverlay({
9215
9032
  height: rect.height,
9216
9033
  zIndex: 2147483646,
9217
9034
  pointerEvents: "auto",
9218
- boxShadow: "inset 0 0 0 1.5px var(--color-bridge-primary)",
9219
- background: "color-mix(in srgb, var(--color-bridge-primary) 20%, transparent)"
9035
+ boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
9036
+ background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
9220
9037
  },
9221
9038
  onClick: () => onEdit(hover.key),
9222
9039
  children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
@@ -10069,7 +9886,7 @@ function SectionTreeItem({
10069
9886
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
10070
9887
  "div",
10071
9888
  {
10072
- className: "-mr-px h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
9889
+ className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
10073
9890
  "aria-hidden": true
10074
9891
  }
10075
9892
  ),
@@ -10088,7 +9905,7 @@ function SectionTreeItem({
10088
9905
  className: cn(
10089
9906
  "flex h-9 min-w-0 flex-1 items-center gap-2 rounded-md border border-border bg-background p-3",
10090
9907
  interactive && "cursor-pointer hover:bg-muted/30",
10091
- interactive && selected && "border-bridge-primary"
9908
+ interactive && selected && "border-primary"
10092
9909
  ),
10093
9910
  children: [
10094
9911
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
@@ -10218,7 +10035,7 @@ function UrlOrPageInput({
10218
10035
  };
10219
10036
  const fieldClassName = cn(
10220
10037
  "data-ohw-link-field flex h-[36px] w-full items-center overflow-hidden rounded-md border bg-background pl-3 pr-3 py-2 outline-none transition-[border-color,box-shadow]",
10221
- urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-bridge-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
10038
+ urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
10222
10039
  );
10223
10040
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
10224
10041
  /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
@@ -14125,7 +13942,6 @@ function readLogoSizeState(content, placement) {
14125
13942
  function getLogoElement(el) {
14126
13943
  const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
14127
13944
  if (marked) return marked;
14128
- if (el.closest('[data-ohw-editable="icon"]')) return null;
14129
13945
  const root = el.closest("nav, [data-ohw-nav-root], footer");
14130
13946
  if (!root) return null;
14131
13947
  const anchor = el.closest("a");
@@ -14413,7 +14229,7 @@ function DisplaySwitch({
14413
14229
  onClick: () => onChange(!checked),
14414
14230
  className: cn(
14415
14231
  "relative h-5 w-9 shrink-0 rounded-full transition-colors",
14416
- checked ? "bg-bridge-primary" : "bg-primary-50",
14232
+ checked ? "bg-primary" : "bg-primary-50",
14417
14233
  disabled ? "cursor-default opacity-50" : "cursor-pointer"
14418
14234
  ),
14419
14235
  children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
@@ -14421,7 +14237,7 @@ function DisplaySwitch({
14421
14237
  {
14422
14238
  className: cn(
14423
14239
  "absolute top-0.5 h-4 w-4 rounded-full bg-white transition-all",
14424
- checked ? "left-4.5" : "left-0.5"
14240
+ checked ? "left-[1.125rem]" : "left-0.5"
14425
14241
  )
14426
14242
  }
14427
14243
  )
@@ -16056,7 +15872,7 @@ var badgeVariants = cva(
16056
15872
  {
16057
15873
  variants: {
16058
15874
  variant: {
16059
- default: "border-transparent bg-bridge-primary text-primary-foreground",
15875
+ default: "border-transparent bg-primary text-primary-foreground",
16060
15876
  secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
16061
15877
  destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
16062
15878
  outline: "text-foreground"
@@ -16238,10 +16054,21 @@ function parseSchedulingInsertAfter(insertAfter) {
16238
16054
  insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
16239
16055
  };
16240
16056
  }
16241
- function resolveEntryAnchor(entry) {
16242
- if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
16243
- const parsed = parseSchedulingInsertAfter(entry.insertAfter);
16244
- return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
16057
+ function resolveSchedulingInsert(insertAfter, explicitInsertBefore) {
16058
+ const parsed = parseSchedulingInsertAfter(insertAfter);
16059
+ const insertBefore = explicitInsertBefore ?? parsed.insertBefore;
16060
+ const effectiveInsertAfter = insertBefore && parsed.insertBefore === null ? `${insertAfter}${INSERT_BEFORE_MARKER}${insertBefore}` : insertAfter;
16061
+ return { effectiveInsertAfter, insertBefore };
16062
+ }
16063
+ function getSchedulingMountPoint(insertAfter) {
16064
+ const { anchor } = parseSchedulingInsertAfter(insertAfter);
16065
+ let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
16066
+ if (!anchorEl && anchor === "scheduling") {
16067
+ const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
16068
+ anchorEl = widgets.at(-1) ?? null;
16069
+ }
16070
+ if (!anchorEl) return null;
16071
+ return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
16245
16072
  }
16246
16073
  function schedulingMountDepth(insertAfter) {
16247
16074
  if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
@@ -16258,7 +16085,8 @@ function getPageSchedulingEntries(raw) {
16258
16085
  }
16259
16086
  }
16260
16087
  function isSchedulingWidgetMissing(entry) {
16261
- return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
16088
+ const { effectiveInsertAfter } = resolveSchedulingInsert(entry.insertAfter);
16089
+ return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
16262
16090
  }
16263
16091
  function hasMissingSchedulingWidgets(entries) {
16264
16092
  return entries.some(isSchedulingWidgetMissing);
@@ -16296,18 +16124,17 @@ function initSectionsFromContent(content, removeExisting = false, currentPath =
16296
16124
  } catch {
16297
16125
  }
16298
16126
  }
16299
- function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
16300
- const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
16301
- const sectionId = schedulingSectionId(widgetId);
16127
+ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId, explicitInsertBefore) {
16128
+ const { effectiveInsertAfter, insertBefore } = resolveSchedulingInsert(insertAfter, explicitInsertBefore);
16129
+ const sectionId = schedulingSectionId(effectiveInsertAfter);
16302
16130
  if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
16303
- const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
16304
- if (!anchorEl) return false;
16305
- const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
16131
+ const mountPoint = getSchedulingMountPoint(effectiveInsertAfter);
16132
+ if (!mountPoint) return false;
16306
16133
  const container = document.createElement("div");
16307
16134
  container.dataset.ohwSectionContainer = "scheduling";
16308
16135
  container.dataset.ohwInstance = sectionId;
16309
- if (beforeId) {
16310
- const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
16136
+ if (insertBefore) {
16137
+ const beforeAnchor = document.querySelector(`[data-ohw-section="${insertBefore}"]`);
16311
16138
  const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
16312
16139
  if (!beforePoint) return false;
16313
16140
  beforePoint.insertAdjacentElement("beforebegin", container);
@@ -16318,26 +16145,20 @@ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, be
16318
16145
  }
16319
16146
  tail.insertAdjacentElement("afterend", container);
16320
16147
  }
16321
- try {
16322
- const root = (0, import_client2.createRoot)(container);
16323
- schedulingRoots.set(container, root);
16324
- (0, import_react_dom4.flushSync)(() => {
16325
- root.render(
16326
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
16327
- SchedulingWidget,
16328
- {
16329
- notifyOnConnect,
16330
- initialScheduleId: scheduleId,
16331
- insertAfter: widgetId
16332
- }
16333
- )
16334
- );
16335
- });
16336
- } catch (err) {
16337
- console.error("[ow:scheduling] render threw", err);
16338
- container.remove();
16339
- return false;
16340
- }
16148
+ const root = (0, import_client2.createRoot)(container);
16149
+ schedulingRoots.set(container, root);
16150
+ (0, import_react_dom4.flushSync)(() => {
16151
+ root.render(
16152
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
16153
+ SchedulingWidget,
16154
+ {
16155
+ notifyOnConnect,
16156
+ initialScheduleId: scheduleId,
16157
+ insertAfter: effectiveInsertAfter
16158
+ }
16159
+ )
16160
+ );
16161
+ });
16341
16162
  const tracker = getSectionsTracker();
16342
16163
  let sections = [];
16343
16164
  try {
@@ -16345,12 +16166,10 @@ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, be
16345
16166
  } catch {
16346
16167
  }
16347
16168
  const inEditor = typeof window !== "undefined" && window.self !== window.top;
16348
- if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
16169
+ if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === effectiveInsertAfter)) {
16349
16170
  sections.push({
16350
16171
  type: "scheduling",
16351
- insertAfter: widgetId,
16352
- anchorId,
16353
- beforeId: beforeId ?? null,
16172
+ insertAfter: effectiveInsertAfter,
16354
16173
  pagePath: window.location.pathname,
16355
16174
  ...scheduleId ? { scheduleId } : {}
16356
16175
  });
@@ -16364,8 +16183,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
16364
16183
  for (let i = pending.length - 1; i >= 0; i--) {
16365
16184
  const entry = pending[i];
16366
16185
  const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
16367
- const { anchorId, beforeId } = resolveEntryAnchor(entry);
16368
- if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
16186
+ if (mountSchedulingWidget(entry.insertAfter, shouldNotify, entry.scheduleId ?? null)) {
16369
16187
  pending.splice(i, 1);
16370
16188
  }
16371
16189
  }
@@ -16529,11 +16347,6 @@ function applyLinkByKey(key, val) {
16529
16347
  hrefAnchors.forEach((el) => applyLinkHref(el, val));
16530
16348
  }
16531
16349
  }
16532
- function isInsideLinkEditor(target) {
16533
- return Boolean(
16534
- 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"]')
16535
- );
16536
- }
16537
16350
  function isInsideFloatingPanel(target) {
16538
16351
  return Boolean(target.closest("[data-ohw-floating-panel]"));
16539
16352
  }
@@ -16541,6 +16354,11 @@ function isPointOverFloatingPanel(clientX, clientY) {
16541
16354
  const el = document.elementFromPoint(clientX, clientY);
16542
16355
  return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
16543
16356
  }
16357
+ function isInsideLinkEditor(target) {
16358
+ return Boolean(
16359
+ 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"]')
16360
+ );
16361
+ }
16544
16362
  function getHrefKeyFromElement(el) {
16545
16363
  if (!el) return null;
16546
16364
  const anchor = el.closest("[data-ohw-href-key]");
@@ -16700,7 +16518,6 @@ function isFooterAddItemDisabled(selected) {
16700
16518
  }
16701
16519
  function resolveFooterColumnSelectionTarget(target, clientX, clientY) {
16702
16520
  if (getNavigationItemAnchor(target)) return null;
16703
- if (target.closest("[data-ohw-editable]")) return null;
16704
16521
  const column = getFooterColumn(target);
16705
16522
  if (!column) return null;
16706
16523
  if (isPointOverNavItem(column, clientX, clientY)) return null;
@@ -16810,7 +16627,7 @@ function getNavigationSelectionParent(el) {
16810
16627
  if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
16811
16628
  return getFooterLinksContainer();
16812
16629
  }
16813
- 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)) {
16630
+ if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
16814
16631
  return getNavigationRoot(el);
16815
16632
  }
16816
16633
  return null;
@@ -16842,12 +16659,6 @@ function collectNavigationItemSiblingHintRects(selected) {
16842
16659
  return [];
16843
16660
  }).filter((el) => isNavigationItem2(el) && el !== selected).map((el) => el.getBoundingClientRect());
16844
16661
  }
16845
- if (selected.closest('footer, [data-ohw-section="footer"]')) {
16846
- const group = findFooterItemGroup2(selected);
16847
- if (group) {
16848
- return Array.from(group.querySelectorAll("[data-ohw-href-key]")).filter((el) => isNavigationItem2(el) && el !== selected).map((el) => el.getBoundingClientRect());
16849
- }
16850
- }
16851
16662
  return listNavigationItems().filter((el) => el !== selected && !el.closest("[data-ohw-nav-children]")).map((el) => el.getBoundingClientRect());
16852
16663
  }
16853
16664
  function placeCaretAtPoint(el, x, y) {
@@ -17032,6 +16843,7 @@ var ICONS = {
17032
16843
  insertUnorderedList: '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>',
17033
16844
  insertOrderedList: '<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'
17034
16845
  };
16846
+ var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
17035
16847
  var SELECTION_CHROME_GAP2 = 4;
17036
16848
  var TOOLBAR_STROKE_GAP2 = 4;
17037
16849
  var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
@@ -17415,7 +17227,6 @@ function StateToggle({
17415
17227
  );
17416
17228
  }
17417
17229
  var contentCache = /* @__PURE__ */ new Map();
17418
- var fetchedContentPaths = /* @__PURE__ */ new Set();
17419
17230
  var brandingCache = /* @__PURE__ */ new Map();
17420
17231
  var OHW_LOADER_STYLE = {
17421
17232
  position: "fixed",
@@ -17964,6 +17775,13 @@ function OhhwellsBridge() {
17964
17775
  const [isItemDragging, setIsItemDragging] = (0, import_react17.useState)(false);
17965
17776
  const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react17.useState)(false);
17966
17777
  isFooterFrameSelectionRef.current = isFooterFrameSelection;
17778
+ const [floatingPanel, setFloatingPanel] = (0, import_react17.useState)(null);
17779
+ const floatingPanelOpenRef = (0, import_react17.useRef)(false);
17780
+ floatingPanelOpenRef.current = floatingPanel !== null;
17781
+ const [floatingPanelPos, setFloatingPanelPos] = (0, import_react17.useState)(null);
17782
+ const [logoSizeDraft, setLogoSizeDraft] = (0, import_react17.useState)(null);
17783
+ const [editorViewport, setEditorViewport] = (0, import_react17.useState)("desktop");
17784
+ const [parentScrollSnap, setParentScrollSnap] = (0, import_react17.useState)(null);
17967
17785
  const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react17.useState)(null);
17968
17786
  const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react17.useState)(null);
17969
17787
  const footerDragRef = (0, import_react17.useRef)(null);
@@ -17980,15 +17798,7 @@ function OhhwellsBridge() {
17980
17798
  const aiSectionsRef = (0, import_react17.useRef)("");
17981
17799
  const brandKitRef = (0, import_react17.useRef)("");
17982
17800
  const stylesRef = (0, import_react17.useRef)("");
17983
- const appliedDrawerRef = (0, import_react17.useRef)(null);
17984
17801
  const pendingDeleteUndoRef = (0, import_react17.useRef)(null);
17985
- const [floatingPanel, setFloatingPanel] = (0, import_react17.useState)(null);
17986
- const floatingPanelOpenRef = (0, import_react17.useRef)(false);
17987
- const setFloatingPanelRef = (0, import_react17.useRef)(setFloatingPanel);
17988
- const [floatingPanelPos, setFloatingPanelPos] = (0, import_react17.useState)(null);
17989
- const [logoSizeDraft, setLogoSizeDraft] = (0, import_react17.useState)(null);
17990
- const [editorViewport, setEditorViewport] = (0, import_react17.useState)("desktop");
17991
- const [parentScrollSnap, setParentScrollSnap] = (0, import_react17.useState)(null);
17992
17802
  const [sitePages, setSitePages] = (0, import_react17.useState)([]);
17993
17803
  const [sectionsByPath, setSectionsByPath] = (0, import_react17.useState)({});
17994
17804
  const sectionsPrefetchGenRef = (0, import_react17.useRef)(0);
@@ -17997,18 +17807,7 @@ function OhhwellsBridge() {
17997
17807
  const linkPopoverOpenRef = (0, import_react17.useRef)(false);
17998
17808
  const linkPopoverGraceUntilRef = (0, import_react17.useRef)(0);
17999
17809
  setLinkPopoverRef.current = setLinkPopover;
18000
- setFloatingPanelRef.current = setFloatingPanel;
18001
17810
  linkPopoverSessionRef.current = linkPopover;
18002
- floatingPanelOpenRef.current = Boolean(floatingPanel);
18003
- (0, import_react17.useEffect)(() => {
18004
- const syncViewport = () => {
18005
- const next = window.innerWidth <= 480 ? "mobile" : "desktop";
18006
- setEditorViewport((prev) => prev === next ? prev : next);
18007
- };
18008
- syncViewport();
18009
- window.addEventListener("resize", syncViewport);
18010
- return () => window.removeEventListener("resize", syncViewport);
18011
- }, []);
18012
17811
  const {
18013
17812
  navDragRef,
18014
17813
  navPointerDragRef,
@@ -19344,7 +19143,6 @@ function OhhwellsBridge() {
19344
19143
  }
19345
19144
  if (typeof content[STYLE_STORE_KEY] === "string") {
19346
19145
  stylesRef.current = content[STYLE_STORE_KEY];
19347
- document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
19348
19146
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
19349
19147
  }
19350
19148
  applyBrandChrome(content);
@@ -19352,11 +19150,11 @@ function OhhwellsBridge() {
19352
19150
  for (const [key, val] of Object.entries(content)) {
19353
19151
  if (key === "__ohw_sections") continue;
19354
19152
  if (key === AI_SECTIONS_KEY) continue;
19355
- if (key === LOGO_PLACEHOLDER_KEY) continue;
19356
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
19357
19153
  if (key === BRAND_KIT_KEY) continue;
19358
19154
  if (key === STYLE_STORE_KEY) continue;
19359
19155
  if (BRAND_CHROME_KEYS.has(key)) continue;
19156
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
19157
+ if (LOGO_IMAGE_KEYS.includes(key)) continue;
19360
19158
  if (applyVideoSettingNode(key, val)) continue;
19361
19159
  if (applyCarouselNode(key, val)) continue;
19362
19160
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -19427,9 +19225,7 @@ function OhhwellsBridge() {
19427
19225
  let cancelled = false;
19428
19226
  setFetchState("loading");
19429
19227
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
19430
- const initialPath = pathname;
19431
- fetchedContentPaths.add(`${subdomain}::${initialPath}`);
19432
- fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
19228
+ fetch(`${apiUrl}/api/public/sites/${subdomain}/content`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
19433
19229
  if (cancelled) return;
19434
19230
  const content = data?.content ?? {};
19435
19231
  const branding = Boolean(data?.showBranding);
@@ -19538,9 +19334,7 @@ function OhhwellsBridge() {
19538
19334
  }, [isEditMode]);
19539
19335
  (0, import_react17.useEffect)(() => {
19540
19336
  if (isEditMode || fetchState !== "done") return;
19541
- console.log("env", process.env.NEXT_PUBLIC_FLOWOPS_API_URL);
19542
19337
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
19543
- console.log({ apiUrl, subdomain });
19544
19338
  bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
19545
19339
  }, [isEditMode, fetchState, subdomain]);
19546
19340
  (0, import_react17.useEffect)(() => {
@@ -19565,17 +19359,16 @@ function OhhwellsBridge() {
19565
19359
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
19566
19360
  }
19567
19361
  if (typeof content[STYLE_STORE_KEY] === "string") {
19568
- document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
19569
19362
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
19570
19363
  }
19571
19364
  for (const [key, val] of Object.entries(content)) {
19572
19365
  if (key === "__ohw_sections") continue;
19573
19366
  if (key === AI_SECTIONS_KEY) continue;
19574
- if (key === LOGO_PLACEHOLDER_KEY) continue;
19575
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
19576
19367
  if (key === BRAND_KIT_KEY) continue;
19577
19368
  if (key === STYLE_STORE_KEY) continue;
19578
19369
  if (BRAND_CHROME_KEYS.has(key)) continue;
19370
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
19371
+ if (LOGO_IMAGE_KEYS.includes(key)) continue;
19579
19372
  if (applyVideoSettingNode(key, val)) continue;
19580
19373
  if (applyCarouselNode(key, val)) continue;
19581
19374
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -19626,17 +19419,6 @@ function OhhwellsBridge() {
19626
19419
  debounceTimer = setTimeout(applyFromCache, 150);
19627
19420
  };
19628
19421
  applyFromCache();
19629
- const pathCacheKey = `${subdomain}::${pathname}`;
19630
- if (!fetchedContentPaths.has(pathCacheKey)) {
19631
- fetchedContentPaths.add(pathCacheKey);
19632
- const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
19633
- fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
19634
- if (!data?.content) return;
19635
- contentCache.set(subdomain, data.content);
19636
- applyFromCache();
19637
- }).catch(() => {
19638
- });
19639
- }
19640
19422
  observer = new MutationObserver(scheduleApply);
19641
19423
  observer.observe(document.body, { childList: true, subtree: true });
19642
19424
  return () => {
@@ -19681,17 +19463,6 @@ function OhhwellsBridge() {
19681
19463
  if (!isEditMode) return;
19682
19464
  initSectionInstancesFromContent(editContentRef.current, pathname);
19683
19465
  }, [pathname, isEditMode]);
19684
- (0, import_react17.useEffect)(() => {
19685
- if (!isEditMode) return;
19686
- const observer = new MutationObserver(() => {
19687
- const drawer = document.querySelector("[data-ohw-nav-drawer]");
19688
- if (!drawer || drawer === appliedDrawerRef.current) return;
19689
- appliedDrawerRef.current = drawer;
19690
- applyStylesToDom(parseStyleStore(stylesRef.current));
19691
- });
19692
- observer.observe(document.body, { childList: true, subtree: true });
19693
- return () => observer.disconnect();
19694
- }, [isEditMode, pathname]);
19695
19466
  (0, import_react17.useEffect)(() => {
19696
19467
  const contentForNav = () => {
19697
19468
  if (isEditMode) return editContentRef.current;
@@ -19783,11 +19554,26 @@ function OhhwellsBridge() {
19783
19554
  const t2 = setTimeout(measure, 500);
19784
19555
  const ro = new ResizeObserver(schedule);
19785
19556
  ro.observe(document.body);
19557
+ let lastWidth = window.innerWidth;
19558
+ let resizeTimers = [];
19559
+ const clearResizeTimers = () => {
19560
+ resizeTimers.forEach(clearTimeout);
19561
+ resizeTimers = [];
19562
+ };
19563
+ const handleResize = () => {
19564
+ if (window.innerWidth === lastWidth) return;
19565
+ lastWidth = window.innerWidth;
19566
+ clearResizeTimers();
19567
+ resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
19568
+ };
19569
+ window.addEventListener("resize", handleResize);
19786
19570
  return () => {
19787
19571
  clearTimeout(t1);
19788
19572
  clearTimeout(t2);
19789
19573
  if (raf != null) cancelAnimationFrame(raf);
19790
19574
  ro.disconnect();
19575
+ clearResizeTimers();
19576
+ window.removeEventListener("resize", handleResize);
19791
19577
  };
19792
19578
  }, [pathname, isEditMode, postToParent2]);
19793
19579
  (0, import_react17.useEffect)(() => {
@@ -20082,6 +19868,9 @@ function OhhwellsBridge() {
20082
19868
  if (target.closest("[data-ohw-state-toggle]")) return;
20083
19869
  if (target.closest("[data-ohw-max-badge]")) return;
20084
19870
  if (isInsideLinkEditor(target)) return;
19871
+ if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
19872
+ clearMediaSelectionRef.current();
19873
+ }
20085
19874
  if (isInsideFloatingPanel(target)) return;
20086
19875
  if (target.closest("[data-ohw-form-toolbar]")) return;
20087
19876
  if (target.closest(
@@ -20089,9 +19878,6 @@ function OhhwellsBridge() {
20089
19878
  )) {
20090
19879
  return;
20091
19880
  }
20092
- if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
20093
- clearMediaSelectionRef.current();
20094
- }
20095
19881
  {
20096
19882
  const formEl = getFormElement(target);
20097
19883
  const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
@@ -20255,6 +20041,14 @@ function OhhwellsBridge() {
20255
20041
  }
20256
20042
  const clickedButton = findClosestButtonLike(target);
20257
20043
  const buttonOnMedia = Boolean(clickedButton && isMediaEditable(editable) && editable.contains(clickedButton));
20044
+ console.log("[click-debug]", {
20045
+ editableType: editable.dataset.ohwEditable,
20046
+ editableTag: editable.tagName,
20047
+ targetTag: target.tagName,
20048
+ clickedButtonTag: clickedButton?.tagName ?? null,
20049
+ buttonOnMedia,
20050
+ isMediaEditableEditable: isMediaEditable(editable)
20051
+ });
20258
20052
  if (isMediaEditable(editable) && !buttonOnMedia) {
20259
20053
  e.preventDefault();
20260
20054
  e.stopPropagation();
@@ -20281,6 +20075,11 @@ function OhhwellsBridge() {
20281
20075
  const hrefLookupTarget = buttonOnMedia ? clickedButton : editable;
20282
20076
  const hrefCtx = getHrefKeyFromElement(hrefLookupTarget);
20283
20077
  const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
20078
+ console.log("[click-debug 2]", {
20079
+ hrefLookupTargetTag: hrefLookupTarget.tagName,
20080
+ hrefCtx: hrefCtx ? { key: hrefCtx.key } : null,
20081
+ navAnchorTag: navAnchor?.tagName ?? null
20082
+ });
20284
20083
  if (navAnchor) {
20285
20084
  e.preventDefault();
20286
20085
  e.stopPropagation();
@@ -20322,7 +20121,7 @@ function OhhwellsBridge() {
20322
20121
  return;
20323
20122
  }
20324
20123
  const footerColClick = target.closest("[data-ohw-footer-col]");
20325
- if (footerColClick && !target.closest("[data-ohw-editable]")) {
20124
+ if (footerColClick) {
20326
20125
  e.preventDefault();
20327
20126
  e.stopPropagation();
20328
20127
  selectFrameRef.current(footerColClick);
@@ -20450,9 +20249,6 @@ function OhhwellsBridge() {
20450
20249
  setHoveredItemRect(null);
20451
20250
  hoveredNavContainerRef.current = null;
20452
20251
  setHoveredNavContainerRect(null);
20453
- siblingHintElRef.current = null;
20454
- setSiblingHintRect(null);
20455
- setSiblingHintRects([]);
20456
20252
  return;
20457
20253
  }
20458
20254
  {
@@ -20484,7 +20280,7 @@ function OhhwellsBridge() {
20484
20280
  const navContainer = target.closest("[data-ohw-nav-container]");
20485
20281
  if (!navContainer) {
20486
20282
  const footerLinks = target.closest("[data-ohw-footer-links], .rb-footer-links") ?? null;
20487
- if (footerLinks && selected2 !== footerLinks && !getNavigationItemAnchor(target) && !target.closest("[data-ohw-footer-col], [data-ohw-footer-column]") && !target.closest("[data-ohw-editable]")) {
20283
+ if (footerLinks && selected2 !== footerLinks && !getNavigationItemAnchor(target) && !target.closest("[data-ohw-footer-col], [data-ohw-footer-column]")) {
20488
20284
  hoveredNavContainerRef.current = footerLinks;
20489
20285
  setHoveredNavContainerRect(footerLinks.getBoundingClientRect());
20490
20286
  hoveredItemElRef.current = null;
@@ -20522,7 +20318,7 @@ function OhhwellsBridge() {
20522
20318
  return;
20523
20319
  }
20524
20320
  const footerCol = target.closest("[data-ohw-footer-col]") ?? target.closest("[data-ohw-footer-column]");
20525
- if (footerCol && !target.closest("[data-ohw-editable]")) {
20321
+ if (footerCol) {
20526
20322
  hoveredNavContainerRef.current = null;
20527
20323
  setHoveredNavContainerRect(null);
20528
20324
  if (selectedElRef.current === footerCol) return;
@@ -20573,6 +20369,7 @@ function OhhwellsBridge() {
20573
20369
  hoveredNavContainerRef.current = null;
20574
20370
  setHoveredNavContainerRect(null);
20575
20371
  hoveredItemElRef.current = editable;
20372
+ setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
20576
20373
  }
20577
20374
  }
20578
20375
  }
@@ -20869,7 +20666,7 @@ function OhhwellsBridge() {
20869
20666
  }
20870
20667
  };
20871
20668
  const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
20872
- if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
20669
+ if (linkPopoverOpenRef.current) {
20873
20670
  if (hoveredImageRef.current) {
20874
20671
  hoveredImageRef.current = null;
20875
20672
  hoveredImageHasTextOverlapRef.current = false;
@@ -21242,7 +21039,8 @@ function OhhwellsBridge() {
21242
21039
  };
21243
21040
  const handleMouseMove = (e) => {
21244
21041
  const { clientX, clientY } = e;
21245
- if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY) || isOverEditorChrome(clientX, clientY)) {
21042
+ if (pointOwnedByFloatingPanel(clientX, clientY)) return;
21043
+ if (isOverEditorChrome(clientX, clientY)) {
21246
21044
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
21247
21045
  formHoverElRef.current = null;
21248
21046
  setFormHoverRect(null);
@@ -21250,12 +21048,7 @@ function OhhwellsBridge() {
21250
21048
  setHoveredItemRect(null);
21251
21049
  hoveredNavContainerRef.current = null;
21252
21050
  setHoveredNavContainerRect(null);
21253
- siblingHintElRef.current = null;
21254
- setSiblingHintRect(null);
21255
- setSiblingHintRects([]);
21256
21051
  dismissImageHover();
21257
- clearImageHover();
21258
- setSectionGap(null);
21259
21052
  return;
21260
21053
  }
21261
21054
  if (probeSocialsRowAt(clientX, clientY)) return;
@@ -21267,11 +21060,7 @@ function OhhwellsBridge() {
21267
21060
  if (e.data?.type !== "ow:pointer-sync") return;
21268
21061
  const { clientX, clientY } = e.data;
21269
21062
  if (typeof clientX !== "number" || typeof clientY !== "number") return;
21270
- if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
21271
- dismissImageHover();
21272
- clearImageHover();
21273
- return;
21274
- }
21063
+ if (pointOwnedByFloatingPanel(clientX, clientY)) return;
21275
21064
  if (probeSocialsRowAt(clientX, clientY)) return;
21276
21065
  probeSectionGapAt(clientX, clientY);
21277
21066
  probeImageAt(clientX, clientY);
@@ -21610,7 +21399,6 @@ function OhhwellsBridge() {
21610
21399
  }
21611
21400
  if (typeof content[STYLE_STORE_KEY] === "string") {
21612
21401
  stylesRef.current = content[STYLE_STORE_KEY];
21613
- document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
21614
21402
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
21615
21403
  }
21616
21404
  applyBrandChrome(content);
@@ -21622,11 +21410,11 @@ function OhhwellsBridge() {
21622
21410
  continue;
21623
21411
  }
21624
21412
  if (key === AI_SECTIONS_KEY) continue;
21625
- if (key === LOGO_PLACEHOLDER_KEY) continue;
21626
- if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
21627
21413
  if (key === BRAND_KIT_KEY) continue;
21628
21414
  if (key === STYLE_STORE_KEY) continue;
21629
21415
  if (BRAND_CHROME_KEYS.has(key)) continue;
21416
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
21417
+ if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
21630
21418
  if (applyVideoSettingNode(key, val)) continue;
21631
21419
  if (applyCarouselNode(key, val)) continue;
21632
21420
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -21851,26 +21639,10 @@ function OhhwellsBridge() {
21851
21639
  const handleGetBrand = (e) => {
21852
21640
  if (e.data?.type !== "ow:get-brand") return;
21853
21641
  const template = deriveTemplateBrand();
21854
- const fallback = template ?? (() => {
21855
- const fonts = deriveTemplateFonts();
21856
- return fonts ? { palette: AI_DEFAULT_BRAND.palette, fonts } : null;
21857
- })();
21858
- const value = brandKitRef.current || (fallback ? JSON.stringify(fallback) : "");
21642
+ const value = brandKitRef.current || (template ? JSON.stringify(template) : "");
21859
21643
  postToParentRef.current({ type: "ow:brand-value", value });
21860
21644
  };
21861
21645
  window.addEventListener("message", handleGetBrand);
21862
- const handleGetTemplateFonts = (e) => {
21863
- if (e.data?.type !== "ow:get-template-fonts") return;
21864
- const fonts = deriveTemplateFonts();
21865
- postToParentRef.current({ type: "ow:template-fonts-value", value: fonts ? JSON.stringify(fonts) : "" });
21866
- };
21867
- window.addEventListener("message", handleGetTemplateFonts);
21868
- const handleGetTemplateBrand = (e) => {
21869
- if (e.data?.type !== "ow:get-template-brand") return;
21870
- const brand = deriveTemplateBrand();
21871
- postToParentRef.current({ type: "ow:template-brand-value", value: brand ? JSON.stringify(brand) : "" });
21872
- };
21873
- window.addEventListener("message", handleGetTemplateBrand);
21874
21646
  const handleMoveSection = (e) => {
21875
21647
  if (e.data?.type !== "ow:move-section") return;
21876
21648
  const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
@@ -22063,12 +21835,6 @@ function OhhwellsBridge() {
22063
21835
  closeLinkPopoverRef.current();
22064
21836
  return;
22065
21837
  }
22066
- if (floatingPanelOpenRef.current) {
22067
- setFloatingPanelRef.current(null);
22068
- deselectRef.current();
22069
- deactivateRef.current();
22070
- return;
22071
- }
22072
21838
  deselectRef.current();
22073
21839
  deactivateRef.current();
22074
21840
  clearMediaSelectionRef.current();
@@ -22357,12 +22123,8 @@ function OhhwellsBridge() {
22357
22123
  if (inserted) {
22358
22124
  const tracker = getSectionsTracker();
22359
22125
  postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
22360
- const reportHeight = () => {
22361
- const h = document.body.scrollHeight;
22362
- if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
22363
- };
22364
- reportHeight();
22365
- setTimeout(reportHeight, 500);
22126
+ const h = document.body.scrollHeight;
22127
+ if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
22366
22128
  }
22367
22129
  };
22368
22130
  const handleSwitchSchedule = (e) => {
@@ -22783,17 +22545,15 @@ function OhhwellsBridge() {
22783
22545
  window.removeEventListener("message", handleAiSetBrand);
22784
22546
  window.removeEventListener("message", handleAiSetStyles);
22785
22547
  window.removeEventListener("message", handleGetBrand);
22786
- window.removeEventListener("message", handleGetTemplateFonts);
22787
- window.removeEventListener("message", handleGetTemplateBrand);
22788
22548
  window.removeEventListener("message", handleMoveSection);
22789
22549
  window.removeEventListener("message", handlePanelDragging);
22790
22550
  window.removeEventListener("message", handleDeleteSection);
22791
22551
  window.removeEventListener("message", handleDuplicateSection);
22792
22552
  window.removeEventListener("message", handleDeactivate);
22553
+ document.documentElement.removeAttribute("data-ohw-panel-dragging");
22793
22554
  window.removeEventListener("message", handleToastAction);
22794
22555
  window.removeEventListener("message", handleFormCount);
22795
22556
  window.removeEventListener("message", handleUiEscape);
22796
- document.documentElement.removeAttribute("data-ohw-panel-dragging");
22797
22557
  autoSaveTimers.current.forEach(clearTimeout);
22798
22558
  autoSaveTimers.current.clear();
22799
22559
  if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
@@ -22996,7 +22756,7 @@ function OhhwellsBridge() {
22996
22756
  postToParent2({
22997
22757
  type: "ow:ready",
22998
22758
  version: "1",
22999
- bridgeVersion: "0.1.112",
22759
+ bridgeVersion: "0.1.111",
23000
22760
  path: pathname,
23001
22761
  nodes: collectEditableNodes(editContentRef.current),
23002
22762
  sections
@@ -23612,7 +23372,7 @@ function OhhwellsBridge() {
23612
23372
  "span",
23613
23373
  {
23614
23374
  "data-ohw-form-count": "",
23615
- className: "ml-0.5 inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-bridge-primary px-1.5 text-[11px] font-semibold text-primary-foreground",
23375
+ className: "ml-0.5 inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-primary px-1.5 text-[11px] font-semibold text-primary-foreground",
23616
23376
  children: formPickCount
23617
23377
  }
23618
23378
  )
@@ -23850,11 +23610,11 @@ function OhhwellsBridge() {
23850
23610
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
23851
23611
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
23852
23612
  children: [
23853
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
23613
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
23854
23614
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
23855
23615
  Badge,
23856
23616
  {
23857
- className: "px-8 py-1 bg-bridge-primary hover:bg-bridge-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
23617
+ 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",
23858
23618
  onClick: () => {
23859
23619
  window.parent.postMessage(
23860
23620
  {
@@ -23868,7 +23628,7 @@ function OhhwellsBridge() {
23868
23628
  children: "Add Section"
23869
23629
  }
23870
23630
  ),
23871
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
23631
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
23872
23632
  ]
23873
23633
  }
23874
23634
  ),
@@ -23916,59 +23676,6 @@ function OhhwellsBridge() {
23916
23676
  ) : null
23917
23677
  ] });
23918
23678
  }
23919
-
23920
- // src/ui/EmptySection.tsx
23921
- var import_link = __toESM(require("next/link"), 1);
23922
- var import_jsx_runtime34 = require("react/jsx-runtime");
23923
- function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
23924
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
23925
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
23926
- "p",
23927
- {
23928
- style: {
23929
- fontFamily: "var(--brand-font-body)",
23930
- fontSize: "0.75rem",
23931
- fontWeight: 500,
23932
- letterSpacing: "0.15em",
23933
- textTransform: "uppercase",
23934
- color: "var(--brand-accent)",
23935
- marginBottom: "1.5rem"
23936
- },
23937
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_link.default, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
23938
- }
23939
- ),
23940
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
23941
- "h1",
23942
- {
23943
- style: {
23944
- fontFamily: "var(--brand-font-heading)",
23945
- fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
23946
- lineHeight: 1.1,
23947
- letterSpacing: "-0.025em",
23948
- color: "var(--brand-text)",
23949
- marginBottom: "1rem"
23950
- },
23951
- ...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
23952
- children: title
23953
- }
23954
- ),
23955
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
23956
- "p",
23957
- {
23958
- style: {
23959
- fontFamily: "var(--brand-font-body)",
23960
- fontSize: "1rem",
23961
- lineHeight: 1.7,
23962
- fontWeight: 300,
23963
- color: "var(--brand-text-muted)",
23964
- maxWidth: "340px"
23965
- },
23966
- ...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
23967
- children: "This page doesn't have any content yet."
23968
- }
23969
- )
23970
- ] });
23971
- }
23972
23679
  // Annotate the CommonJS export names for ESM import in node:
23973
23680
  0 && (module.exports = {
23974
23681
  AI_DEFAULT_BRAND,
@@ -23986,7 +23693,6 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
23986
23693
  DropdownMenuItem,
23987
23694
  DropdownMenuSeparator,
23988
23695
  DropdownMenuTrigger,
23989
- EmptySection,
23990
23696
  ItemActionToolbar,
23991
23697
  ItemInteractionLayer,
23992
23698
  LinkEditorPanel,