@ohhwells/bridge 0.1.112-next.289 → 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]");
@@ -16809,7 +16627,7 @@ function getNavigationSelectionParent(el) {
16809
16627
  if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
16810
16628
  return getFooterLinksContainer();
16811
16629
  }
16812
- 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)) {
16813
16631
  return getNavigationRoot(el);
16814
16632
  }
16815
16633
  return null;
@@ -17025,6 +16843,7 @@ var ICONS = {
17025
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"/>',
17026
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"/>'
17027
16845
  };
16846
+ var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
17028
16847
  var SELECTION_CHROME_GAP2 = 4;
17029
16848
  var TOOLBAR_STROKE_GAP2 = 4;
17030
16849
  var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
@@ -17408,7 +17227,6 @@ function StateToggle({
17408
17227
  );
17409
17228
  }
17410
17229
  var contentCache = /* @__PURE__ */ new Map();
17411
- var fetchedContentPaths = /* @__PURE__ */ new Set();
17412
17230
  var brandingCache = /* @__PURE__ */ new Map();
17413
17231
  var OHW_LOADER_STYLE = {
17414
17232
  position: "fixed",
@@ -17957,6 +17775,13 @@ function OhhwellsBridge() {
17957
17775
  const [isItemDragging, setIsItemDragging] = (0, import_react17.useState)(false);
17958
17776
  const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react17.useState)(false);
17959
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);
17960
17785
  const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react17.useState)(null);
17961
17786
  const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react17.useState)(null);
17962
17787
  const footerDragRef = (0, import_react17.useRef)(null);
@@ -17973,15 +17798,7 @@ function OhhwellsBridge() {
17973
17798
  const aiSectionsRef = (0, import_react17.useRef)("");
17974
17799
  const brandKitRef = (0, import_react17.useRef)("");
17975
17800
  const stylesRef = (0, import_react17.useRef)("");
17976
- const appliedDrawerRef = (0, import_react17.useRef)(null);
17977
17801
  const pendingDeleteUndoRef = (0, import_react17.useRef)(null);
17978
- const [floatingPanel, setFloatingPanel] = (0, import_react17.useState)(null);
17979
- const floatingPanelOpenRef = (0, import_react17.useRef)(false);
17980
- const setFloatingPanelRef = (0, import_react17.useRef)(setFloatingPanel);
17981
- const [floatingPanelPos, setFloatingPanelPos] = (0, import_react17.useState)(null);
17982
- const [logoSizeDraft, setLogoSizeDraft] = (0, import_react17.useState)(null);
17983
- const [editorViewport, setEditorViewport] = (0, import_react17.useState)("desktop");
17984
- const [parentScrollSnap, setParentScrollSnap] = (0, import_react17.useState)(null);
17985
17802
  const [sitePages, setSitePages] = (0, import_react17.useState)([]);
17986
17803
  const [sectionsByPath, setSectionsByPath] = (0, import_react17.useState)({});
17987
17804
  const sectionsPrefetchGenRef = (0, import_react17.useRef)(0);
@@ -17990,18 +17807,7 @@ function OhhwellsBridge() {
17990
17807
  const linkPopoverOpenRef = (0, import_react17.useRef)(false);
17991
17808
  const linkPopoverGraceUntilRef = (0, import_react17.useRef)(0);
17992
17809
  setLinkPopoverRef.current = setLinkPopover;
17993
- setFloatingPanelRef.current = setFloatingPanel;
17994
17810
  linkPopoverSessionRef.current = linkPopover;
17995
- floatingPanelOpenRef.current = Boolean(floatingPanel);
17996
- (0, import_react17.useEffect)(() => {
17997
- const syncViewport = () => {
17998
- const next = window.innerWidth <= 480 ? "mobile" : "desktop";
17999
- setEditorViewport((prev) => prev === next ? prev : next);
18000
- };
18001
- syncViewport();
18002
- window.addEventListener("resize", syncViewport);
18003
- return () => window.removeEventListener("resize", syncViewport);
18004
- }, []);
18005
17811
  const {
18006
17812
  navDragRef,
18007
17813
  navPointerDragRef,
@@ -19337,7 +19143,6 @@ function OhhwellsBridge() {
19337
19143
  }
19338
19144
  if (typeof content[STYLE_STORE_KEY] === "string") {
19339
19145
  stylesRef.current = content[STYLE_STORE_KEY];
19340
- document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
19341
19146
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
19342
19147
  }
19343
19148
  applyBrandChrome(content);
@@ -19345,11 +19150,11 @@ function OhhwellsBridge() {
19345
19150
  for (const [key, val] of Object.entries(content)) {
19346
19151
  if (key === "__ohw_sections") continue;
19347
19152
  if (key === AI_SECTIONS_KEY) continue;
19348
- if (key === LOGO_PLACEHOLDER_KEY) continue;
19349
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
19350
19153
  if (key === BRAND_KIT_KEY) continue;
19351
19154
  if (key === STYLE_STORE_KEY) continue;
19352
19155
  if (BRAND_CHROME_KEYS.has(key)) continue;
19156
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
19157
+ if (LOGO_IMAGE_KEYS.includes(key)) continue;
19353
19158
  if (applyVideoSettingNode(key, val)) continue;
19354
19159
  if (applyCarouselNode(key, val)) continue;
19355
19160
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -19420,9 +19225,7 @@ function OhhwellsBridge() {
19420
19225
  let cancelled = false;
19421
19226
  setFetchState("loading");
19422
19227
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
19423
- const initialPath = pathname;
19424
- fetchedContentPaths.add(`${subdomain}::${initialPath}`);
19425
- 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) => {
19426
19229
  if (cancelled) return;
19427
19230
  const content = data?.content ?? {};
19428
19231
  const branding = Boolean(data?.showBranding);
@@ -19531,9 +19334,7 @@ function OhhwellsBridge() {
19531
19334
  }, [isEditMode]);
19532
19335
  (0, import_react17.useEffect)(() => {
19533
19336
  if (isEditMode || fetchState !== "done") return;
19534
- console.log("env", process.env.NEXT_PUBLIC_FLOWOPS_API_URL);
19535
19337
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
19536
- console.log({ apiUrl, subdomain });
19537
19338
  bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
19538
19339
  }, [isEditMode, fetchState, subdomain]);
19539
19340
  (0, import_react17.useEffect)(() => {
@@ -19558,17 +19359,16 @@ function OhhwellsBridge() {
19558
19359
  applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
19559
19360
  }
19560
19361
  if (typeof content[STYLE_STORE_KEY] === "string") {
19561
- document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
19562
19362
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
19563
19363
  }
19564
19364
  for (const [key, val] of Object.entries(content)) {
19565
19365
  if (key === "__ohw_sections") continue;
19566
19366
  if (key === AI_SECTIONS_KEY) continue;
19567
- if (key === LOGO_PLACEHOLDER_KEY) continue;
19568
- if (LOGO_IMAGE_KEYS.includes(key)) continue;
19569
19367
  if (key === BRAND_KIT_KEY) continue;
19570
19368
  if (key === STYLE_STORE_KEY) continue;
19571
19369
  if (BRAND_CHROME_KEYS.has(key)) continue;
19370
+ if (key === LOGO_PLACEHOLDER_KEY) continue;
19371
+ if (LOGO_IMAGE_KEYS.includes(key)) continue;
19572
19372
  if (applyVideoSettingNode(key, val)) continue;
19573
19373
  if (applyCarouselNode(key, val)) continue;
19574
19374
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -19619,17 +19419,6 @@ function OhhwellsBridge() {
19619
19419
  debounceTimer = setTimeout(applyFromCache, 150);
19620
19420
  };
19621
19421
  applyFromCache();
19622
- const pathCacheKey = `${subdomain}::${pathname}`;
19623
- if (!fetchedContentPaths.has(pathCacheKey)) {
19624
- fetchedContentPaths.add(pathCacheKey);
19625
- const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
19626
- fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
19627
- if (!data?.content) return;
19628
- contentCache.set(subdomain, data.content);
19629
- applyFromCache();
19630
- }).catch(() => {
19631
- });
19632
- }
19633
19422
  observer = new MutationObserver(scheduleApply);
19634
19423
  observer.observe(document.body, { childList: true, subtree: true });
19635
19424
  return () => {
@@ -19674,17 +19463,6 @@ function OhhwellsBridge() {
19674
19463
  if (!isEditMode) return;
19675
19464
  initSectionInstancesFromContent(editContentRef.current, pathname);
19676
19465
  }, [pathname, isEditMode]);
19677
- (0, import_react17.useEffect)(() => {
19678
- if (!isEditMode) return;
19679
- const observer = new MutationObserver(() => {
19680
- const drawer = document.querySelector("[data-ohw-nav-drawer]");
19681
- if (!drawer || drawer === appliedDrawerRef.current) return;
19682
- appliedDrawerRef.current = drawer;
19683
- applyStylesToDom(parseStyleStore(stylesRef.current));
19684
- });
19685
- observer.observe(document.body, { childList: true, subtree: true });
19686
- return () => observer.disconnect();
19687
- }, [isEditMode, pathname]);
19688
19466
  (0, import_react17.useEffect)(() => {
19689
19467
  const contentForNav = () => {
19690
19468
  if (isEditMode) return editContentRef.current;
@@ -19776,11 +19554,26 @@ function OhhwellsBridge() {
19776
19554
  const t2 = setTimeout(measure, 500);
19777
19555
  const ro = new ResizeObserver(schedule);
19778
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);
19779
19570
  return () => {
19780
19571
  clearTimeout(t1);
19781
19572
  clearTimeout(t2);
19782
19573
  if (raf != null) cancelAnimationFrame(raf);
19783
19574
  ro.disconnect();
19575
+ clearResizeTimers();
19576
+ window.removeEventListener("resize", handleResize);
19784
19577
  };
19785
19578
  }, [pathname, isEditMode, postToParent2]);
19786
19579
  (0, import_react17.useEffect)(() => {
@@ -20075,6 +19868,9 @@ function OhhwellsBridge() {
20075
19868
  if (target.closest("[data-ohw-state-toggle]")) return;
20076
19869
  if (target.closest("[data-ohw-max-badge]")) return;
20077
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
+ }
20078
19874
  if (isInsideFloatingPanel(target)) return;
20079
19875
  if (target.closest("[data-ohw-form-toolbar]")) return;
20080
19876
  if (target.closest(
@@ -20082,9 +19878,6 @@ function OhhwellsBridge() {
20082
19878
  )) {
20083
19879
  return;
20084
19880
  }
20085
- if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
20086
- clearMediaSelectionRef.current();
20087
- }
20088
19881
  {
20089
19882
  const formEl = getFormElement(target);
20090
19883
  const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
@@ -20248,6 +20041,14 @@ function OhhwellsBridge() {
20248
20041
  }
20249
20042
  const clickedButton = findClosestButtonLike(target);
20250
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
+ });
20251
20052
  if (isMediaEditable(editable) && !buttonOnMedia) {
20252
20053
  e.preventDefault();
20253
20054
  e.stopPropagation();
@@ -20274,6 +20075,11 @@ function OhhwellsBridge() {
20274
20075
  const hrefLookupTarget = buttonOnMedia ? clickedButton : editable;
20275
20076
  const hrefCtx = getHrefKeyFromElement(hrefLookupTarget);
20276
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
+ });
20277
20083
  if (navAnchor) {
20278
20084
  e.preventDefault();
20279
20085
  e.stopPropagation();
@@ -20443,9 +20249,6 @@ function OhhwellsBridge() {
20443
20249
  setHoveredItemRect(null);
20444
20250
  hoveredNavContainerRef.current = null;
20445
20251
  setHoveredNavContainerRect(null);
20446
- siblingHintElRef.current = null;
20447
- setSiblingHintRect(null);
20448
- setSiblingHintRects([]);
20449
20252
  return;
20450
20253
  }
20451
20254
  {
@@ -20566,6 +20369,7 @@ function OhhwellsBridge() {
20566
20369
  hoveredNavContainerRef.current = null;
20567
20370
  setHoveredNavContainerRect(null);
20568
20371
  hoveredItemElRef.current = editable;
20372
+ setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
20569
20373
  }
20570
20374
  }
20571
20375
  }
@@ -20862,7 +20666,7 @@ function OhhwellsBridge() {
20862
20666
  }
20863
20667
  };
20864
20668
  const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
20865
- if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
20669
+ if (linkPopoverOpenRef.current) {
20866
20670
  if (hoveredImageRef.current) {
20867
20671
  hoveredImageRef.current = null;
20868
20672
  hoveredImageHasTextOverlapRef.current = false;
@@ -21235,7 +21039,8 @@ function OhhwellsBridge() {
21235
21039
  };
21236
21040
  const handleMouseMove = (e) => {
21237
21041
  const { clientX, clientY } = e;
21238
- 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)) {
21239
21044
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
21240
21045
  formHoverElRef.current = null;
21241
21046
  setFormHoverRect(null);
@@ -21243,12 +21048,7 @@ function OhhwellsBridge() {
21243
21048
  setHoveredItemRect(null);
21244
21049
  hoveredNavContainerRef.current = null;
21245
21050
  setHoveredNavContainerRect(null);
21246
- siblingHintElRef.current = null;
21247
- setSiblingHintRect(null);
21248
- setSiblingHintRects([]);
21249
21051
  dismissImageHover();
21250
- clearImageHover();
21251
- setSectionGap(null);
21252
21052
  return;
21253
21053
  }
21254
21054
  if (probeSocialsRowAt(clientX, clientY)) return;
@@ -21260,11 +21060,7 @@ function OhhwellsBridge() {
21260
21060
  if (e.data?.type !== "ow:pointer-sync") return;
21261
21061
  const { clientX, clientY } = e.data;
21262
21062
  if (typeof clientX !== "number" || typeof clientY !== "number") return;
21263
- if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
21264
- dismissImageHover();
21265
- clearImageHover();
21266
- return;
21267
- }
21063
+ if (pointOwnedByFloatingPanel(clientX, clientY)) return;
21268
21064
  if (probeSocialsRowAt(clientX, clientY)) return;
21269
21065
  probeSectionGapAt(clientX, clientY);
21270
21066
  probeImageAt(clientX, clientY);
@@ -21603,7 +21399,6 @@ function OhhwellsBridge() {
21603
21399
  }
21604
21400
  if (typeof content[STYLE_STORE_KEY] === "string") {
21605
21401
  stylesRef.current = content[STYLE_STORE_KEY];
21606
- document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
21607
21402
  applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
21608
21403
  }
21609
21404
  applyBrandChrome(content);
@@ -21615,11 +21410,11 @@ function OhhwellsBridge() {
21615
21410
  continue;
21616
21411
  }
21617
21412
  if (key === AI_SECTIONS_KEY) continue;
21618
- if (key === LOGO_PLACEHOLDER_KEY) continue;
21619
- if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
21620
21413
  if (key === BRAND_KIT_KEY) continue;
21621
21414
  if (key === STYLE_STORE_KEY) continue;
21622
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;
21623
21418
  if (applyVideoSettingNode(key, val)) continue;
21624
21419
  if (applyCarouselNode(key, val)) continue;
21625
21420
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
@@ -21844,26 +21639,10 @@ function OhhwellsBridge() {
21844
21639
  const handleGetBrand = (e) => {
21845
21640
  if (e.data?.type !== "ow:get-brand") return;
21846
21641
  const template = deriveTemplateBrand();
21847
- const fallback = template ?? (() => {
21848
- const fonts = deriveTemplateFonts();
21849
- return fonts ? { palette: AI_DEFAULT_BRAND.palette, fonts } : null;
21850
- })();
21851
- const value = brandKitRef.current || (fallback ? JSON.stringify(fallback) : "");
21642
+ const value = brandKitRef.current || (template ? JSON.stringify(template) : "");
21852
21643
  postToParentRef.current({ type: "ow:brand-value", value });
21853
21644
  };
21854
21645
  window.addEventListener("message", handleGetBrand);
21855
- const handleGetTemplateFonts = (e) => {
21856
- if (e.data?.type !== "ow:get-template-fonts") return;
21857
- const fonts = deriveTemplateFonts();
21858
- postToParentRef.current({ type: "ow:template-fonts-value", value: fonts ? JSON.stringify(fonts) : "" });
21859
- };
21860
- window.addEventListener("message", handleGetTemplateFonts);
21861
- const handleGetTemplateBrand = (e) => {
21862
- if (e.data?.type !== "ow:get-template-brand") return;
21863
- const brand = deriveTemplateBrand();
21864
- postToParentRef.current({ type: "ow:template-brand-value", value: brand ? JSON.stringify(brand) : "" });
21865
- };
21866
- window.addEventListener("message", handleGetTemplateBrand);
21867
21646
  const handleMoveSection = (e) => {
21868
21647
  if (e.data?.type !== "ow:move-section") return;
21869
21648
  const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
@@ -22056,12 +21835,6 @@ function OhhwellsBridge() {
22056
21835
  closeLinkPopoverRef.current();
22057
21836
  return;
22058
21837
  }
22059
- if (floatingPanelOpenRef.current) {
22060
- setFloatingPanelRef.current(null);
22061
- deselectRef.current();
22062
- deactivateRef.current();
22063
- return;
22064
- }
22065
21838
  deselectRef.current();
22066
21839
  deactivateRef.current();
22067
21840
  clearMediaSelectionRef.current();
@@ -22350,12 +22123,8 @@ function OhhwellsBridge() {
22350
22123
  if (inserted) {
22351
22124
  const tracker = getSectionsTracker();
22352
22125
  postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
22353
- const reportHeight = () => {
22354
- const h = document.body.scrollHeight;
22355
- if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
22356
- };
22357
- reportHeight();
22358
- setTimeout(reportHeight, 500);
22126
+ const h = document.body.scrollHeight;
22127
+ if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
22359
22128
  }
22360
22129
  };
22361
22130
  const handleSwitchSchedule = (e) => {
@@ -22776,17 +22545,15 @@ function OhhwellsBridge() {
22776
22545
  window.removeEventListener("message", handleAiSetBrand);
22777
22546
  window.removeEventListener("message", handleAiSetStyles);
22778
22547
  window.removeEventListener("message", handleGetBrand);
22779
- window.removeEventListener("message", handleGetTemplateFonts);
22780
- window.removeEventListener("message", handleGetTemplateBrand);
22781
22548
  window.removeEventListener("message", handleMoveSection);
22782
22549
  window.removeEventListener("message", handlePanelDragging);
22783
22550
  window.removeEventListener("message", handleDeleteSection);
22784
22551
  window.removeEventListener("message", handleDuplicateSection);
22785
22552
  window.removeEventListener("message", handleDeactivate);
22553
+ document.documentElement.removeAttribute("data-ohw-panel-dragging");
22786
22554
  window.removeEventListener("message", handleToastAction);
22787
22555
  window.removeEventListener("message", handleFormCount);
22788
22556
  window.removeEventListener("message", handleUiEscape);
22789
- document.documentElement.removeAttribute("data-ohw-panel-dragging");
22790
22557
  autoSaveTimers.current.forEach(clearTimeout);
22791
22558
  autoSaveTimers.current.clear();
22792
22559
  if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
@@ -22989,7 +22756,7 @@ function OhhwellsBridge() {
22989
22756
  postToParent2({
22990
22757
  type: "ow:ready",
22991
22758
  version: "1",
22992
- bridgeVersion: "0.1.112",
22759
+ bridgeVersion: "0.1.111",
22993
22760
  path: pathname,
22994
22761
  nodes: collectEditableNodes(editContentRef.current),
22995
22762
  sections
@@ -23605,7 +23372,7 @@ function OhhwellsBridge() {
23605
23372
  "span",
23606
23373
  {
23607
23374
  "data-ohw-form-count": "",
23608
- 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",
23609
23376
  children: formPickCount
23610
23377
  }
23611
23378
  )
@@ -23843,11 +23610,11 @@ function OhhwellsBridge() {
23843
23610
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
23844
23611
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
23845
23612
  children: [
23846
- /* @__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 } }),
23847
23614
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
23848
23615
  Badge,
23849
23616
  {
23850
- 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",
23851
23618
  onClick: () => {
23852
23619
  window.parent.postMessage(
23853
23620
  {
@@ -23861,7 +23628,7 @@ function OhhwellsBridge() {
23861
23628
  children: "Add Section"
23862
23629
  }
23863
23630
  ),
23864
- /* @__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 } })
23865
23632
  ]
23866
23633
  }
23867
23634
  ),
@@ -23909,59 +23676,6 @@ function OhhwellsBridge() {
23909
23676
  ) : null
23910
23677
  ] });
23911
23678
  }
23912
-
23913
- // src/ui/EmptySection.tsx
23914
- var import_link = __toESM(require("next/link"), 1);
23915
- var import_jsx_runtime34 = require("react/jsx-runtime");
23916
- function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
23917
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
23918
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
23919
- "p",
23920
- {
23921
- style: {
23922
- fontFamily: "var(--brand-font-body)",
23923
- fontSize: "0.75rem",
23924
- fontWeight: 500,
23925
- letterSpacing: "0.15em",
23926
- textTransform: "uppercase",
23927
- color: "var(--brand-accent)",
23928
- marginBottom: "1.5rem"
23929
- },
23930
- 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" }) })
23931
- }
23932
- ),
23933
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
23934
- "h1",
23935
- {
23936
- style: {
23937
- fontFamily: "var(--brand-font-heading)",
23938
- fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
23939
- lineHeight: 1.1,
23940
- letterSpacing: "-0.025em",
23941
- color: "var(--brand-text)",
23942
- marginBottom: "1rem"
23943
- },
23944
- ...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
23945
- children: title
23946
- }
23947
- ),
23948
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
23949
- "p",
23950
- {
23951
- style: {
23952
- fontFamily: "var(--brand-font-body)",
23953
- fontSize: "1rem",
23954
- lineHeight: 1.7,
23955
- fontWeight: 300,
23956
- color: "var(--brand-text-muted)",
23957
- maxWidth: "340px"
23958
- },
23959
- ...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
23960
- children: "This page doesn't have any content yet."
23961
- }
23962
- )
23963
- ] });
23964
- }
23965
23679
  // Annotate the CommonJS export names for ESM import in node:
23966
23680
  0 && (module.exports = {
23967
23681
  AI_DEFAULT_BRAND,
@@ -23979,7 +23693,6 @@ function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey
23979
23693
  DropdownMenuItem,
23980
23694
  DropdownMenuSeparator,
23981
23695
  DropdownMenuTrigger,
23982
- EmptySection,
23983
23696
  ItemActionToolbar,
23984
23697
  ItemInteractionLayer,
23985
23698
  LinkEditorPanel,