@ohhwells/bridge 0.1.136 → 0.1.137

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  // src/OhhwellsBridge.tsx
4
- import React12, { useCallback as useCallback12, useEffect as useEffect17, useLayoutEffect as useLayoutEffect5, useRef as useRef14, useState as useState18 } from "react";
4
+ import React12, { useCallback as useCallback12, useEffect as useEffect17, useLayoutEffect as useLayoutEffect6, useRef as useRef14, useState as useState18 } from "react";
5
5
  import { createRoot as createRoot3 } from "react-dom/client";
6
6
  import { flushSync as flushSync3 } from "react-dom";
7
7
 
@@ -7829,6 +7829,21 @@ function PricingCard({ node, ctx, path }) {
7829
7829
  const fg = emphasis.fg;
7830
7830
  const features = pricingFeatureItems(slots.features);
7831
7831
  const buttons = (node.children ?? []).map((child, i) => ({ child, i })).filter((entry) => entry.child.type === "button");
7832
+ const badge = featured.enabled && str(featured.badge) ? /* @__PURE__ */ jsx(
7833
+ "div",
7834
+ {
7835
+ ...ctx.keyFor ? { "data-ohw-key": ctx.keyFor(`${path}.featured.badge`), "data-ohw-editable": "plain" } : {},
7836
+ style: {
7837
+ alignSelf: "flex-start",
7838
+ padding: `${AI_TREE_TOKENS.spacing2 / 2}px ${AI_TREE_TOKENS.spacing3}px`,
7839
+ borderRadius: 999,
7840
+ background: ctx.brand.palette.primary,
7841
+ color: primaryButtonLabel(ctx.brand),
7842
+ ...typeStyle(AI_TREE_TOKENS.type.eyebrow, ctx.brand.fonts.body)
7843
+ },
7844
+ children: str(featured.badge)
7845
+ }
7846
+ ) : null;
7832
7847
  const headingBlock = /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: AI_TREE_TOKENS.spacing2 }, children: [
7833
7848
  str(slots.heading) && /* @__PURE__ */ jsx(
7834
7849
  "div",
@@ -7878,32 +7893,31 @@ function PricingCard({ node, ctx, path }) {
7878
7893
  position: "relative"
7879
7894
  },
7880
7895
  children: [
7881
- featured.enabled && str(featured.badge) && /* @__PURE__ */ jsx(
7882
- "div",
7883
- {
7884
- style: {
7885
- alignSelf: "flex-start",
7886
- padding: `${AI_TREE_TOKENS.spacing2 / 2}px ${AI_TREE_TOKENS.spacing3}px`,
7887
- borderRadius: 999,
7888
- background: ctx.brand.palette.primary,
7889
- color: primaryButtonLabel(ctx.brand),
7890
- ...typeStyle(AI_TREE_TOKENS.type.eyebrow, ctx.brand.fonts.body)
7891
- },
7892
- children: str(featured.badge)
7893
- }
7894
- ),
7895
- emphasis.headerBg ? /* @__PURE__ */ jsx(
7896
- "div",
7897
- {
7898
- style: {
7899
- background: emphasis.headerBg,
7900
- margin: `-${AI_TREE_TOKENS.paddingBlock}px -${AI_TREE_TOKENS.paddingBlock}px 0`,
7901
- padding: AI_TREE_TOKENS.paddingBlock,
7902
- borderRadius: `${cardRadius(slots)}px ${cardRadius(slots)}px 0 0`
7903
- },
7904
- children: headingBlock
7905
- }
7906
- ) : headingBlock,
7896
+ emphasis.headerBg ? (
7897
+ // The badge rides inside the band so the tint runs from the card's top edge down
7898
+ // through the price block, instead of starting underneath the badge.
7899
+ /* @__PURE__ */ jsxs(
7900
+ "div",
7901
+ {
7902
+ style: {
7903
+ background: emphasis.headerBg,
7904
+ margin: `-${AI_TREE_TOKENS.paddingBlock}px -${AI_TREE_TOKENS.paddingBlock}px 0`,
7905
+ padding: AI_TREE_TOKENS.paddingBlock,
7906
+ borderRadius: `${cardRadius(slots)}px ${cardRadius(slots)}px 0 0`,
7907
+ display: "flex",
7908
+ flexDirection: "column",
7909
+ gap: AI_TREE_TOKENS.spacing8
7910
+ },
7911
+ children: [
7912
+ badge,
7913
+ headingBlock
7914
+ ]
7915
+ }
7916
+ )
7917
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
7918
+ badge,
7919
+ headingBlock
7920
+ ] }),
7907
7921
  features.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
7908
7922
  /* @__PURE__ */ jsx("hr", { style: { border: "none", borderTop: `1px solid ${fg}`, opacity: 0.2, margin: 0, width: "100%" } }),
7909
7923
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: AI_TREE_TOKENS.spacing4 }, children: [
@@ -18147,8 +18161,8 @@ function AiMediaStripOverlay({
18147
18161
  }
18148
18162
 
18149
18163
  // src/ui/ai-section/AiPricingCardOverlay.tsx
18150
- import { useCallback as useCallback4, useEffect as useEffect7, useRef as useRef6, useState as useState9 } from "react";
18151
- import { Star as Star2 } from "lucide-react";
18164
+ import { useCallback as useCallback4, useEffect as useEffect7, useLayoutEffect as useLayoutEffect4, useRef as useRef6, useState as useState9 } from "react";
18165
+ import { Check as Check2, ChevronDown as ChevronDown3, Minus, Plus as Plus2, Star as Star2 } from "lucide-react";
18152
18166
 
18153
18167
  // src/lib/ai-pricing-tree.ts
18154
18168
  var PRICING_MIN_CARDS = 1;
@@ -18208,16 +18222,65 @@ function removePricingTier(tree, index) {
18208
18222
  return true;
18209
18223
  });
18210
18224
  }
18211
- function setPricingCardFeatured(tree, index, patch) {
18225
+ var PRICING_CARD_STYLES = [
18226
+ { value: "outline", label: "Outline", treatment: null },
18227
+ { value: "lift", label: "Lift", treatment: "lifted" },
18228
+ { value: "invert", label: "Invert", treatment: "inverted" },
18229
+ { value: "header", label: "Header", treatment: "accent-header" }
18230
+ ];
18231
+ var DEFAULT_FEATURED_BADGE = "Most popular";
18232
+ function featuredOf(target) {
18233
+ const raw = target?.slots?.featured;
18234
+ if (raw === true) return { enabled: true, treatment: "outlined" };
18235
+ return typeof raw === "object" && raw !== null ? raw : {};
18236
+ }
18237
+ function badgeOf(featured) {
18238
+ return typeof featured.badge === "string" ? featured.badge.trim() : "";
18239
+ }
18240
+ function pricingCardStyle(tree, index) {
18241
+ const featured = featuredOf(findPricingCollection(tree)?.children?.[index]);
18242
+ if (featured.enabled !== true) return "outline";
18243
+ return PRICING_CARD_STYLES.find((s) => s.treatment === featured.treatment)?.value ?? "outline";
18244
+ }
18245
+ function pricingCardFeaturedTag(tree, index) {
18246
+ const featured = featuredOf(findPricingCollection(tree)?.children?.[index]);
18247
+ return featured.enabled === true && badgeOf(featured).length > 0;
18248
+ }
18249
+ function composeFeatured(style, tagOn, badgeText) {
18250
+ const treatment = PRICING_CARD_STYLES.find((s) => s.value === style)?.treatment ?? null;
18251
+ if (tagOn) return { enabled: true, badge: badgeText || DEFAULT_FEATURED_BADGE, treatment: treatment ?? "outlined" };
18252
+ if (treatment) return { enabled: true, treatment };
18253
+ return badgeText.length > 0 ? { enabled: false, badge: badgeText } : { enabled: false };
18254
+ }
18255
+ function withPricingCard(tree, index, mutate) {
18212
18256
  return withPricingCollection(tree, (collection) => {
18213
18257
  const children = collection.children;
18214
18258
  if (index < 0 || index >= children.length) return false;
18215
18259
  const target = children[index];
18216
18260
  target.slots = target.slots ?? {};
18217
- target.slots.featured = { ...patch };
18261
+ mutate(target);
18218
18262
  return true;
18219
18263
  });
18220
18264
  }
18265
+ function setPricingCardStyle(tree, index, style) {
18266
+ if (!PRICING_CARD_STYLES.some((s) => s.value === style)) return null;
18267
+ return withPricingCard(tree, index, (target) => {
18268
+ const prev = featuredOf(target);
18269
+ const tagOn = prev.enabled === true && badgeOf(prev).length > 0;
18270
+ target.slots.featured = composeFeatured(style, tagOn, badgeOf(prev));
18271
+ });
18272
+ }
18273
+ function setPricingCardFeaturedTag(tree, index, on) {
18274
+ return withPricingCard(tree, index, (target) => {
18275
+ const prev = featuredOf(target);
18276
+ const style = pricingCardStyleOf(prev);
18277
+ target.slots.featured = composeFeatured(style, on, badgeOf(prev));
18278
+ });
18279
+ }
18280
+ function pricingCardStyleOf(featured) {
18281
+ if (featured.enabled !== true) return "outline";
18282
+ return PRICING_CARD_STYLES.find((s) => s.treatment === featured.treatment)?.value ?? "outline";
18283
+ }
18221
18284
  function addPricingCardButton(tree, index, label) {
18222
18285
  return withPricingCollection(tree, (collection) => {
18223
18286
  const children = collection.children;
@@ -18292,15 +18355,8 @@ function removePricingCardFeature(tree, index) {
18292
18355
 
18293
18356
  // src/ui/ai-section/AiPricingCardOverlay.tsx
18294
18357
  import { Fragment as Fragment7, jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
18295
- var EMPHASIS_TREATMENTS = [
18296
- { value: "outlined", label: "Outline" },
18297
- { value: "lifted", label: "Lift" },
18298
- { value: "inverted", label: "Invert" },
18299
- { value: "accent-header", label: "Header" }
18300
- ];
18301
- var PRIMARY4 = "#0885FE";
18302
- var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY4})`;
18303
- var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY4}) 60%, #000000)`;
18358
+ var PRIMARY4 = "var(--ohw-primary, #0885FE)";
18359
+ var CHROME_SELECTOR = "[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-link-modal-root], [data-ohw-section-picker], [data-ohw-ai-review], [data-ohw-more-menu]";
18304
18360
  function findPricingCardElement(sectionId, index) {
18305
18361
  const sectionEl = findByInstanceId(sectionId);
18306
18362
  if (!sectionEl) return null;
@@ -18310,14 +18366,35 @@ function findPricingCardElement(sectionId, index) {
18310
18366
  }
18311
18367
  return null;
18312
18368
  }
18313
- function readRect3(ref) {
18314
- const el = ref && findPricingCardElement(ref.sectionId, ref.index);
18369
+ function cardRefFromTarget(target) {
18370
+ if (!(target instanceof Element)) return null;
18371
+ if (target.closest(CHROME_SELECTOR)) return null;
18372
+ const cardEl = target.closest("[data-ohw-pricing-card]");
18373
+ if (!cardEl) return null;
18374
+ const sectionEl = cardEl.closest("[data-ohw-section]");
18375
+ const unit = sectionEl ? movableUnit(sectionEl) : null;
18376
+ const sectionId = unit ? instanceIdOf(unit) || null : null;
18377
+ const index = Number(cardEl.dataset.ohwPricingIndex);
18378
+ if (!sectionId || Number.isNaN(index)) return null;
18379
+ return { sectionId, index };
18380
+ }
18381
+ function sameRef(a, b) {
18382
+ return a?.sectionId === b?.sectionId && a?.index === b?.index;
18383
+ }
18384
+ function rectOf(el) {
18315
18385
  if (!el) return null;
18316
18386
  const r2 = el.getBoundingClientRect();
18317
18387
  if (r2.width <= 0 || r2.height <= 0) return null;
18318
18388
  return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
18319
18389
  }
18320
- function useLiveCardRect(ref) {
18390
+ function readRect3(ref) {
18391
+ return rectOf(ref && findPricingCardElement(ref.sectionId, ref.index));
18392
+ }
18393
+ function readGridRect(ref) {
18394
+ const card = ref && findPricingCardElement(ref.sectionId, ref.index);
18395
+ return rectOf(card?.closest("[data-ohw-pricing-collection]") ?? card);
18396
+ }
18397
+ function useLiveCardRect(ref, grid = false) {
18321
18398
  const [rect, setRect] = useState9(null);
18322
18399
  useEffect7(() => {
18323
18400
  if (!ref) {
@@ -18325,7 +18402,7 @@ function useLiveCardRect(ref) {
18325
18402
  return;
18326
18403
  }
18327
18404
  const update = () => {
18328
- const next = readRect3(ref);
18405
+ const next = grid ? readGridRect(ref) : readRect3(ref);
18329
18406
  setRect(
18330
18407
  (prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
18331
18408
  );
@@ -18340,9 +18417,49 @@ function useLiveCardRect(ref) {
18340
18417
  window.removeEventListener("resize", update);
18341
18418
  clearInterval(interval);
18342
18419
  };
18343
- }, [ref?.sectionId, ref?.index]);
18420
+ }, [ref?.sectionId, ref?.index, grid]);
18344
18421
  return rect;
18345
18422
  }
18423
+ var TOOLBAR_GRID_GAP = 52;
18424
+ var TOOLBAR_GRID_GAP_MOBILE = 42;
18425
+ var TOOLBAR_EDGE_MARGIN2 = 4;
18426
+ function GridToolbarSlot({ gridRect, children }) {
18427
+ const slotRef = useRef6(null);
18428
+ const [shift, setShift] = useState9(0);
18429
+ const centerX = gridRect.left + gridRect.width / 2;
18430
+ useLayoutEffect4(() => {
18431
+ const slot = slotRef.current;
18432
+ if (!slot) return;
18433
+ const clamp = () => {
18434
+ const w = slot.offsetWidth;
18435
+ if (w <= 0) return;
18436
+ const half = w / 2;
18437
+ const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
18438
+ setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
18439
+ };
18440
+ clamp();
18441
+ const ro = new ResizeObserver(clamp);
18442
+ ro.observe(slot);
18443
+ return () => ro.disconnect();
18444
+ }, [centerX, children]);
18445
+ const mobile = window.innerWidth <= 480;
18446
+ return /* @__PURE__ */ jsx20(
18447
+ "div",
18448
+ {
18449
+ ref: slotRef,
18450
+ "data-ohw-bridge": "",
18451
+ "data-ohw-item-interaction": "",
18452
+ className: "pointer-events-auto fixed",
18453
+ style: {
18454
+ top: gridRect.top - (mobile ? TOOLBAR_GRID_GAP_MOBILE : TOOLBAR_GRID_GAP),
18455
+ left: centerX + shift,
18456
+ transform: "translate(-50%, -100%)",
18457
+ zIndex: 2147483645
18458
+ },
18459
+ children
18460
+ }
18461
+ );
18462
+ }
18346
18463
  function requestValidateTree2(postToParent2, tree) {
18347
18464
  return new Promise((resolve) => {
18348
18465
  const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
@@ -18360,40 +18477,93 @@ function requestValidateTree2(postToParent2, tree) {
18360
18477
  postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
18361
18478
  });
18362
18479
  }
18363
- function Pill2({
18364
- label,
18365
- onClick,
18366
- disabled,
18367
- active
18368
- }) {
18480
+ function StyleSwatch({ style }) {
18369
18481
  return /* @__PURE__ */ jsx20(
18370
- "button",
18482
+ "span",
18371
18483
  {
18372
- type: "button",
18373
- onClick,
18374
- disabled,
18375
- style: {
18376
- height: 28,
18377
- padding: "0 10px",
18378
- display: "inline-flex",
18379
- alignItems: "center",
18380
- gap: 4,
18381
- borderRadius: 999,
18382
- border: "none",
18383
- cursor: disabled ? "default" : "pointer",
18384
- background: active ? OHW_BLUE_DARK2 : "#ffffff",
18385
- color: active ? "#ffffff" : OHW_BLUE_DARK2,
18386
- opacity: disabled ? 0.4 : 1,
18387
- fontSize: 12,
18388
- lineHeight: "16px",
18389
- fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
18390
- whiteSpace: "nowrap",
18391
- flex: "0 0 auto"
18392
- },
18393
- children: label
18484
+ "aria-hidden": true,
18485
+ className: cn(
18486
+ "inline-block h-4 w-[18px] shrink-0 rounded-[3px] border border-border bg-background",
18487
+ style === "lift" && "border-transparent shadow-[0_3px_5px_rgba(0,0,0,0.22)]",
18488
+ style === "invert" && "border-foreground bg-foreground",
18489
+ style === "header" && "bg-[linear-gradient(var(--ohw-foreground,#0c0a09)_48%,var(--ohw-background,#ffffff)_48%)]"
18490
+ )
18394
18491
  }
18395
18492
  );
18396
18493
  }
18494
+ function ButtonGlyph() {
18495
+ return /* @__PURE__ */ jsxs11("svg", { width: "18", height: "12", viewBox: "0 0 18 12", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
18496
+ /* @__PURE__ */ jsx20("rect", { x: "0.75", y: "0.75", width: "16.5", height: "10.5", rx: "3", stroke: "currentColor", strokeWidth: "1.5" }),
18497
+ /* @__PURE__ */ jsx20("path", { d: "M5.5 6H12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
18498
+ ] });
18499
+ }
18500
+ function FeatureGlyph({ mode }) {
18501
+ return /* @__PURE__ */ jsxs11("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
18502
+ /* @__PURE__ */ jsx20("circle", { cx: "8", cy: "8", r: "7.25", stroke: "currentColor", strokeWidth: "1.5" }),
18503
+ /* @__PURE__ */ jsx20("path", { d: "M5 8.2L7.2 10.3L11 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }),
18504
+ /* @__PURE__ */ jsx20("circle", { cx: "13.5", cy: "13.5", r: "4.25", fill: "var(--ohw-background, #ffffff)", stroke: "var(--ohw-background, #ffffff)", strokeWidth: "1" }),
18505
+ /* @__PURE__ */ jsx20("circle", { cx: "13.5", cy: "13.5", r: "3.75", fill: "var(--ohw-background, #ffffff)", stroke: PRIMARY4, strokeWidth: "1" }),
18506
+ /* @__PURE__ */ jsx20("path", { d: "M11.5 13.5H15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" }),
18507
+ mode === "add" && /* @__PURE__ */ jsx20("path", { d: "M13.5 11.5V15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" })
18508
+ ] });
18509
+ }
18510
+ function ToolbarAction({
18511
+ label,
18512
+ onClick,
18513
+ disabled = false,
18514
+ children
18515
+ }) {
18516
+ const button = /* @__PURE__ */ jsx20(CustomToolbarButton, { type: "button", "aria-label": label, disabled, onClick, className: "size-8", children });
18517
+ return /* @__PURE__ */ jsxs11(Tooltip, { children: [
18518
+ /* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ jsx20("span", { className: "inline-flex", children: button }) : button }),
18519
+ /* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
18520
+ ] });
18521
+ }
18522
+ function ToolbarSeparator() {
18523
+ return /* @__PURE__ */ jsx20("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
18524
+ }
18525
+ function CardStyleMenu({
18526
+ value,
18527
+ onChange
18528
+ }) {
18529
+ const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
18530
+ return /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
18531
+ /* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
18532
+ /* @__PURE__ */ jsxs11(DropdownMenu, { modal: false, children: [
18533
+ /* @__PURE__ */ jsx20(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(
18534
+ "button",
18535
+ {
18536
+ type: "button",
18537
+ "aria-label": "Card style",
18538
+ className: "inline-flex h-8 min-w-[110px] items-center gap-[7px] rounded-[6px] bg-transparent px-2 text-[13px] font-medium text-foreground transition-colors hover:bg-muted data-[state=open]:bg-muted",
18539
+ children: [
18540
+ /* @__PURE__ */ jsx20(StyleSwatch, { style: current.value }),
18541
+ /* @__PURE__ */ jsx20("span", { className: "flex-1 text-left", children: current.label }),
18542
+ /* @__PURE__ */ jsx20(ChevronDown3, { size: 16, style: { pointerEvents: "none" } })
18543
+ ]
18544
+ }
18545
+ ) }),
18546
+ /* @__PURE__ */ jsx20(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[152px] min-w-[152px] p-1", children: PRICING_CARD_STYLES.map((style) => {
18547
+ const selected = style.value === value;
18548
+ return /* @__PURE__ */ jsxs11(
18549
+ DropdownMenuItem,
18550
+ {
18551
+ role: "menuitemradio",
18552
+ "aria-checked": selected,
18553
+ onSelect: () => onChange(style.value),
18554
+ className: cn("grid grid-cols-[18px_1fr_16px] gap-2 py-2 pl-2 pr-2 text-[13px]", selected && "bg-muted"),
18555
+ children: [
18556
+ /* @__PURE__ */ jsx20(StyleSwatch, { style: style.value }),
18557
+ /* @__PURE__ */ jsx20("span", { children: style.label }),
18558
+ selected && /* @__PURE__ */ jsx20(Check2, { size: 16, className: "text-bridge-primary" })
18559
+ ]
18560
+ },
18561
+ style.value
18562
+ );
18563
+ }) })
18564
+ ] })
18565
+ ] });
18566
+ }
18397
18567
  function PricingCardToolbar({
18398
18568
  entry,
18399
18569
  index,
@@ -18401,8 +18571,8 @@ function PricingCardToolbar({
18401
18571
  error,
18402
18572
  onAddTier,
18403
18573
  onRemoveTier,
18404
- onToggleFeatured,
18405
- onSetTreatment,
18574
+ onSetStyle,
18575
+ onSetFeaturedTag,
18406
18576
  onAddButton,
18407
18577
  onRemoveButton,
18408
18578
  onAddFeature,
@@ -18410,55 +18580,66 @@ function PricingCardToolbar({
18410
18580
  }) {
18411
18581
  const collectionCount = pricingCardCount(entry.tree);
18412
18582
  const card = findPricingCardNode(entry.tree, index);
18413
- const featured = card?.slots?.featured;
18414
- const isFeatured = featured?.enabled === true;
18415
18583
  const buttonCount = (card?.children ?? []).filter((c) => c.type === "button").length;
18416
18584
  const featureCount = pricingCardFeatureCount(entry.tree, index);
18417
- const pillWrap = window.innerWidth <= 480 ? "wrap" : "nowrap";
18418
- return /* @__PURE__ */ jsxs11(
18585
+ const style = pricingCardStyle(entry.tree, index);
18586
+ const featuredTag = pricingCardFeaturedTag(entry.tree, index);
18587
+ const mobile = window.innerWidth <= 480;
18588
+ return /* @__PURE__ */ jsx20(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsxs11(
18419
18589
  "div",
18420
18590
  {
18421
18591
  "data-ohw-bridge": "",
18422
18592
  "data-ohw-toolbar": "",
18423
18593
  onMouseDown: (e) => e.stopPropagation(),
18424
- style: {
18425
- display: "flex",
18426
- flexDirection: "column",
18427
- gap: 6,
18428
- alignItems: "center",
18429
- background: OHW_BLUE2,
18430
- padding: 8,
18431
- borderRadius: 12,
18432
- boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
18433
- pointerEvents: pending ? "none" : "auto",
18434
- opacity: pending ? 0.6 : 1,
18435
- // Only cap width on mobile, where the pill rows wrap — on desktop the row stays on one
18436
- // line and should size to fit it, not get clipped/overflow against a fixed cap.
18437
- maxWidth: pillWrap === "wrap" ? "calc(100vw - 24px)" : "none"
18438
- },
18594
+ className: cn(
18595
+ "flex flex-col items-center gap-1.5 font-sans",
18596
+ pending && "pointer-events-none opacity-60"
18597
+ ),
18598
+ style: { maxWidth: mobile ? "calc(100vw - 24px)" : void 0 },
18439
18599
  children: [
18440
- /* @__PURE__ */ jsxs11("div", { style: { display: "flex", gap: 6, flexWrap: pillWrap, justifyContent: "center" }, children: [
18441
- /* @__PURE__ */ jsx20(Pill2, { label: "+ Tier", onClick: onAddTier, disabled: collectionCount >= 4 }),
18442
- /* @__PURE__ */ jsx20(Pill2, { label: "- Tier", onClick: onRemoveTier, disabled: collectionCount <= 1 }),
18443
- /* @__PURE__ */ jsx20(Pill2, { label: "Featured", active: isFeatured, onClick: () => onToggleFeatured(!isFeatured) }),
18444
- /* @__PURE__ */ jsx20(Pill2, { label: "+ Button", onClick: onAddButton, disabled: buttonCount >= 2 }),
18445
- /* @__PURE__ */ jsx20(Pill2, { label: "- Button", onClick: onRemoveButton, disabled: buttonCount === 0 }),
18446
- /* @__PURE__ */ jsx20(Pill2, { label: "+ Feature", onClick: onAddFeature, disabled: featureCount >= 10 }),
18447
- /* @__PURE__ */ jsx20(Pill2, { label: "- Feature", onClick: onRemoveFeature, disabled: featureCount <= 1 })
18448
- ] }),
18449
- isFeatured && /* @__PURE__ */ jsx20("div", { style: { display: "flex", gap: 6, flexWrap: pillWrap, justifyContent: "center" }, children: EMPHASIS_TREATMENTS.map((t) => /* @__PURE__ */ jsx20(
18450
- Pill2,
18600
+ /* @__PURE__ */ jsxs11(
18601
+ "div",
18451
18602
  {
18452
- label: t.label,
18453
- active: (featured?.treatment ?? "outlined") === t.value,
18454
- onClick: () => onSetTreatment(t.value)
18455
- },
18456
- t.value
18457
- )) }),
18458
- error && /* @__PURE__ */ jsx20("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
18603
+ className: cn(
18604
+ "flex items-center gap-1 rounded-[10px] border border-border bg-background p-1 whitespace-nowrap",
18605
+ "shadow-[0px_10px_15px_-3px_rgba(0,0,0,0.1),0px_4px_6px_-4px_rgba(0,0,0,0.1)]",
18606
+ mobile ? "flex-wrap justify-center" : "flex-nowrap"
18607
+ ),
18608
+ children: [
18609
+ /* @__PURE__ */ jsx20(CardStyleMenu, { value: style, onChange: onSetStyle }),
18610
+ /* @__PURE__ */ jsxs11(Tooltip, { children: [
18611
+ /* @__PURE__ */ jsx20(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx20(
18612
+ CustomToolbarButton,
18613
+ {
18614
+ type: "button",
18615
+ "aria-label": featuredTag ? "Remove featured tag" : "Add featured tag",
18616
+ "aria-pressed": featuredTag,
18617
+ active: featuredTag,
18618
+ onClick: () => onSetFeaturedTag(!featuredTag),
18619
+ className: "size-8",
18620
+ children: /* @__PURE__ */ jsx20(Star2, { size: 16, fill: featuredTag ? "currentColor" : "none", style: { pointerEvents: "none" } })
18621
+ }
18622
+ ) }),
18623
+ /* @__PURE__ */ jsx20(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Remove featured tag" : "Add featured tag" })
18624
+ ] }),
18625
+ /* @__PURE__ */ jsx20(ToolbarSeparator, {}),
18626
+ /* @__PURE__ */ jsx20(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ jsx20(ButtonGlyph, {}) }),
18627
+ /* @__PURE__ */ jsx20(ToolbarAction, { label: "Remove button", onClick: onRemoveButton, disabled: buttonCount === 0, children: /* @__PURE__ */ jsxs11("span", { className: "relative inline-flex", children: [
18628
+ /* @__PURE__ */ jsx20(ButtonGlyph, {}),
18629
+ /* @__PURE__ */ jsx20(Minus, { size: 10, strokeWidth: 2.5, className: "absolute -right-1.5 -top-1.5 rounded-full bg-background text-bridge-primary" })
18630
+ ] }) }),
18631
+ /* @__PURE__ */ jsx20(ToolbarAction, { label: "Add feature", onClick: onAddFeature, disabled: featureCount >= 10, children: /* @__PURE__ */ jsx20(FeatureGlyph, { mode: "add" }) }),
18632
+ /* @__PURE__ */ jsx20(ToolbarAction, { label: "Remove feature", onClick: onRemoveFeature, disabled: featureCount <= 1, children: /* @__PURE__ */ jsx20(FeatureGlyph, { mode: "remove" }) }),
18633
+ /* @__PURE__ */ jsx20(ToolbarSeparator, {}),
18634
+ /* @__PURE__ */ jsx20(ToolbarAction, { label: "Add tier", onClick: onAddTier, disabled: collectionCount >= 4, children: /* @__PURE__ */ jsx20(Plus2, { size: 16, style: { pointerEvents: "none" } }) }),
18635
+ /* @__PURE__ */ jsx20(ToolbarAction, { label: "Remove tier", onClick: onRemoveTier, disabled: collectionCount <= 1, children: /* @__PURE__ */ jsx20(Minus, { size: 16, style: { pointerEvents: "none" } }) })
18636
+ ]
18637
+ }
18638
+ ),
18639
+ error && /* @__PURE__ */ jsx20("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
18459
18640
  ]
18460
18641
  }
18461
- );
18642
+ ) });
18462
18643
  }
18463
18644
  function findPricingCardNode(tree, index) {
18464
18645
  const stack = tree.rows.flatMap((row) => row.blocks);
@@ -18484,25 +18665,13 @@ function AiPricingCardOverlay({
18484
18665
  activeRef.current = active;
18485
18666
  useEffect7(() => {
18486
18667
  const onMove = (e) => {
18668
+ const ref = cardRefFromTarget(e.target);
18487
18669
  const t = e.target;
18488
- if (!(t instanceof HTMLElement)) return;
18489
- if (t.closest("[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-link-modal-root], [data-ohw-section-picker], [data-ohw-ai-review]")) {
18490
- return;
18491
- }
18492
- const cardEl = t.closest("[data-ohw-pricing-card]");
18493
- if (!cardEl) {
18494
- setHover(null);
18495
- return;
18496
- }
18497
- const sectionEl = cardEl.closest("[data-ohw-section]");
18498
- const unit = sectionEl ? movableUnit(sectionEl) : null;
18499
- const sectionId = unit ? instanceIdOf(unit) || null : null;
18500
- const index = Number(cardEl.dataset.ohwPricingIndex);
18501
- if (!sectionId || Number.isNaN(index)) {
18502
- setHover(null);
18503
- return;
18504
- }
18505
- setHover({ sectionId, index });
18670
+ const overEditable = Boolean(t?.closest?.("[data-ohw-editable], [data-ohw-role], a, button"));
18671
+ setHover((prev) => {
18672
+ const next = ref && !overEditable ? ref : null;
18673
+ return sameRef(prev, next) ? prev : next;
18674
+ });
18506
18675
  };
18507
18676
  const onLeave = () => setHover(null);
18508
18677
  document.addEventListener("mousemove", onMove, { passive: true });
@@ -18514,15 +18683,12 @@ function AiPricingCardOverlay({
18514
18683
  }, []);
18515
18684
  useEffect7(() => {
18516
18685
  const onClick = (e) => {
18517
- const current = activeRef.current;
18518
- if (!current) return;
18519
18686
  const t = e.target;
18520
- if (!(t instanceof HTMLElement)) return;
18521
- if (t.closest("[data-ohw-item-interaction]")) return;
18522
- const cardEl = findPricingCardElement(current.sectionId, current.index);
18523
- if (cardEl && cardEl.contains(t)) return;
18524
- setActive(null);
18525
- setError(null);
18687
+ if (!(t instanceof Element)) return;
18688
+ if (t.closest(CHROME_SELECTOR)) return;
18689
+ const ref = cardRefFromTarget(t);
18690
+ setActive((prev) => sameRef(prev, ref) ? prev : ref);
18691
+ if (!ref || !sameRef(activeRef.current, ref)) setError(null);
18526
18692
  };
18527
18693
  document.addEventListener("click", onClick, true);
18528
18694
  return () => document.removeEventListener("click", onClick, true);
@@ -18540,6 +18706,7 @@ function AiPricingCardOverlay({
18540
18706
  const onKeyDown = (e) => {
18541
18707
  if (e.key !== "Escape") return;
18542
18708
  if (!activeRef.current) return;
18709
+ if (document.querySelector('[data-ohw-more-menu][data-state="open"]')) return;
18543
18710
  setActive(null);
18544
18711
  setError(null);
18545
18712
  };
@@ -18585,72 +18752,52 @@ function AiPricingCardOverlay({
18585
18752
  );
18586
18753
  const activeEntry = active ? findEntry(active.sectionId) : null;
18587
18754
  const activeCardRect = useLiveCardRect(active);
18588
- const hoverHandleRect = useLiveCardRect(!active && hover ? hover : null);
18755
+ const activeGridRect = useLiveCardRect(active, true);
18756
+ const hoverRect = useLiveCardRect(hover && !sameRef(hover, active) ? hover : null);
18589
18757
  return /* @__PURE__ */ jsxs11(Fragment7, { children: [
18590
- hoverHandleRect && hover && /* @__PURE__ */ jsx20(
18591
- "button",
18592
- {
18593
- type: "button",
18594
- "data-ohw-toolbar": "",
18595
- onClick: () => setActive(hover),
18596
- "aria-label": "Configure pricing tier",
18597
- style: {
18598
- position: "fixed",
18599
- top: hoverHandleRect.top + 8,
18600
- left: hoverHandleRect.left + hoverHandleRect.width - 36,
18601
- width: 28,
18602
- height: 28,
18603
- borderRadius: 8,
18604
- border: `1.5px dashed ${PRIMARY4}`,
18605
- background: "#ffffff",
18606
- color: PRIMARY4,
18607
- display: "flex",
18608
- alignItems: "center",
18609
- justifyContent: "center",
18610
- cursor: "pointer",
18611
- zIndex: 2147483643,
18612
- fontSize: 14,
18613
- fontWeight: 700
18614
- },
18615
- children: /* @__PURE__ */ jsx20(Star2, { size: 14, style: { pointerEvents: "none" } })
18616
- }
18617
- ),
18618
- activeCardRect && active && activeEntry && /* @__PURE__ */ jsx20(
18619
- ItemInteractionLayer,
18620
- {
18621
- rect: activeCardRect,
18622
- state: "active-top",
18623
- toolbar: /* @__PURE__ */ jsx20(
18624
- PricingCardToolbar,
18625
- {
18626
- entry: activeEntry,
18627
- index: active.index,
18628
- pending,
18629
- error,
18630
- onAddTier: () => runMutation(active.sectionId, addPricingTier),
18631
- onRemoveTier: () => {
18632
- void runMutation(active.sectionId, (tree) => removePricingTier(tree, active.index)).then(
18633
- (applied) => {
18634
- if (applied) setActive(null);
18635
- }
18636
- );
18637
- },
18638
- onToggleFeatured: (enabled) => runMutation(
18639
- active.sectionId,
18640
- (tree) => setPricingCardFeatured(tree, active.index, { enabled })
18641
- ),
18642
- onSetTreatment: (treatment) => runMutation(
18643
- active.sectionId,
18644
- (tree) => setPricingCardFeatured(tree, active.index, { enabled: true, treatment })
18645
- ),
18646
- onAddButton: () => runMutation(active.sectionId, (tree) => addPricingCardButton(tree, active.index, "Learn more")),
18647
- onRemoveButton: () => runMutation(active.sectionId, (tree) => removePricingCardButton(tree, active.index)),
18648
- onAddFeature: () => runMutation(active.sectionId, (tree) => addPricingCardFeature(tree, active.index, "New feature")),
18649
- onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
18650
- }
18651
- )
18652
- }
18653
- )
18758
+ hoverRect && /* @__PURE__ */ jsx20(ItemInteractionLayer, { rect: hoverRect, state: "hover" }),
18759
+ activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ jsxs11(Fragment7, { children: [
18760
+ /* @__PURE__ */ jsx20(ItemInteractionLayer, { rect: activeCardRect, state: "active-top" }),
18761
+ /* @__PURE__ */ jsx20(GridToolbarSlot, { gridRect: activeGridRect, children: /* @__PURE__ */ jsx20(
18762
+ PricingCardToolbar,
18763
+ {
18764
+ entry: activeEntry,
18765
+ index: active.index,
18766
+ pending,
18767
+ error,
18768
+ onAddTier: () => runMutation(active.sectionId, addPricingTier),
18769
+ onRemoveTier: () => {
18770
+ void runMutation(active.sectionId, (tree) => removePricingTier(tree, active.index)).then(
18771
+ (applied) => {
18772
+ if (applied) setActive(null);
18773
+ }
18774
+ );
18775
+ },
18776
+ onSetFeaturedTag: (on) => runMutation(active.sectionId, (tree) => setPricingCardFeaturedTag(tree, active.index, on)),
18777
+ onSetStyle: (style) => runMutation(active.sectionId, (tree) => setPricingCardStyle(tree, active.index, style)),
18778
+ onAddButton: () => runMutation(active.sectionId, (tree) => addPricingCardButton(tree, active.index, "Learn more")),
18779
+ onRemoveButton: () => runMutation(active.sectionId, (tree) => removePricingCardButton(tree, active.index)),
18780
+ onAddFeature: () => runMutation(active.sectionId, (tree) => addPricingCardFeature(tree, active.index, "New feature")),
18781
+ onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
18782
+ }
18783
+ ) }),
18784
+ /* @__PURE__ */ jsx20(
18785
+ "div",
18786
+ {
18787
+ "data-ohw-bridge": "",
18788
+ "data-ohw-item-interaction": "",
18789
+ "aria-hidden": true,
18790
+ className: "pointer-events-none fixed rounded-[4px] px-[7px] py-[3px] font-sans text-[11px] font-medium leading-none text-primary-foreground whitespace-nowrap",
18791
+ style: {
18792
+ top: activeCardRect.top + activeCardRect.height + 10,
18793
+ left: activeCardRect.left - 5,
18794
+ background: PRIMARY4,
18795
+ zIndex: 2147483644
18796
+ },
18797
+ children: "Pricing card"
18798
+ }
18799
+ )
18800
+ ] })
18654
18801
  ] });
18655
18802
  }
18656
18803
 
@@ -18729,8 +18876,8 @@ function extractYouTubeId(input) {
18729
18876
  // src/ui/ai-section/AiVideoOverlay.tsx
18730
18877
  import { Fragment as Fragment8, jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
18731
18878
  var PRIMARY5 = "#0885FE";
18732
- var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY5})`;
18733
- var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
18879
+ var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY5})`;
18880
+ var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
18734
18881
  function findVideoBlockElement(sectionId, path) {
18735
18882
  const sectionEl = findByInstanceId(sectionId);
18736
18883
  if (!sectionEl) return null;
@@ -18790,7 +18937,7 @@ function requestValidateTree3(postToParent2, tree) {
18790
18937
  postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
18791
18938
  });
18792
18939
  }
18793
- function Pill3({
18940
+ function Pill2({
18794
18941
  label,
18795
18942
  onClick,
18796
18943
  disabled
@@ -18811,7 +18958,7 @@ function Pill3({
18811
18958
  border: "none",
18812
18959
  cursor: disabled ? "default" : "pointer",
18813
18960
  background: "#ffffff",
18814
- color: OHW_BLUE_DARK3,
18961
+ color: OHW_BLUE_DARK2,
18815
18962
  opacity: disabled ? 0.4 : 1,
18816
18963
  fontSize: 12,
18817
18964
  lineHeight: "16px",
@@ -18876,7 +19023,7 @@ function VideoUrlInput({ value, onCommit }) {
18876
19023
  {
18877
19024
  style: {
18878
19025
  flex: "0 0 auto",
18879
- color: OHW_BLUE_DARK3,
19026
+ color: OHW_BLUE_DARK2,
18880
19027
  fontSize: 10,
18881
19028
  lineHeight: "16px",
18882
19029
  fontWeight: 700,
@@ -18945,7 +19092,7 @@ function VideoToolbar({
18945
19092
  gap: 6,
18946
19093
  alignItems: "center",
18947
19094
  width: 280,
18948
- background: OHW_BLUE3,
19095
+ background: OHW_BLUE2,
18949
19096
  padding: 8,
18950
19097
  borderRadius: 12,
18951
19098
  boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
@@ -18954,7 +19101,7 @@ function VideoToolbar({
18954
19101
  },
18955
19102
  children: [
18956
19103
  /* @__PURE__ */ jsx21(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
18957
- /* @__PURE__ */ jsx21(Pill3, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
19104
+ /* @__PURE__ */ jsx21(Pill2, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
18958
19105
  error && /* @__PURE__ */ jsx21("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
18959
19106
  ]
18960
19107
  }
@@ -19189,8 +19336,8 @@ function setCarouselAutoplay(tree, on) {
19189
19336
  // src/ui/ai-section/AiFadeCarouselOverlay.tsx
19190
19337
  import { Fragment as Fragment9, jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
19191
19338
  var PRIMARY6 = "#0885FE";
19192
- var OHW_BLUE4 = `var(--ohw-primary, ${PRIMARY6})`;
19193
- var OHW_BLUE_DARK4 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY6}) 60%, #000000)`;
19339
+ var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY6})`;
19340
+ var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY6}) 60%, #000000)`;
19194
19341
  function findCarouselItemElement(sectionId, index) {
19195
19342
  const sectionEl = findByInstanceId(sectionId);
19196
19343
  if (!sectionEl) return null;
@@ -19269,7 +19416,7 @@ function requestAssetPick2(postToParent2) {
19269
19416
  postToParent2({ type: "ow:asset-pick", id });
19270
19417
  });
19271
19418
  }
19272
- function Pill4({ label, onClick, disabled }) {
19419
+ function Pill3({ label, onClick, disabled }) {
19273
19420
  return /* @__PURE__ */ jsx22(
19274
19421
  "button",
19275
19422
  {
@@ -19286,7 +19433,7 @@ function Pill4({ label, onClick, disabled }) {
19286
19433
  border: "none",
19287
19434
  cursor: disabled ? "default" : "pointer",
19288
19435
  background: "#ffffff",
19289
- color: OHW_BLUE_DARK4,
19436
+ color: OHW_BLUE_DARK3,
19290
19437
  opacity: disabled ? 0.4 : 1,
19291
19438
  fontSize: 12,
19292
19439
  lineHeight: "16px",
@@ -19323,7 +19470,7 @@ function TogglePill({
19323
19470
  border: "none",
19324
19471
  cursor: disabled ? "default" : "pointer",
19325
19472
  background: "#ffffff",
19326
- color: OHW_BLUE_DARK4,
19473
+ color: OHW_BLUE_DARK3,
19327
19474
  opacity: disabled ? 0.4 : 1,
19328
19475
  fontSize: 12,
19329
19476
  lineHeight: "16px",
@@ -19346,7 +19493,7 @@ function TogglePill({
19346
19493
  // Off is a grey track, not a washed-out blue: the pill's own white background already
19347
19494
  // carries the brand colour in the text, and a pale blue track next to it read as
19348
19495
  // "disabled control" rather than "switch that is off".
19349
- background: on ? OHW_BLUE_DARK4 : "#CBD5E1",
19496
+ background: on ? OHW_BLUE_DARK3 : "#CBD5E1",
19350
19497
  transition: "background 120ms ease"
19351
19498
  },
19352
19499
  children: /* @__PURE__ */ jsx22(
@@ -19389,7 +19536,7 @@ function CarouselSlideToolbar({
19389
19536
  flexDirection: "column",
19390
19537
  gap: 6,
19391
19538
  alignItems: "center",
19392
- background: OHW_BLUE4,
19539
+ background: OHW_BLUE3,
19393
19540
  padding: 8,
19394
19541
  borderRadius: 12,
19395
19542
  boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
@@ -19402,7 +19549,7 @@ function CarouselSlideToolbar({
19402
19549
  },
19403
19550
  children: [
19404
19551
  /* @__PURE__ */ jsxs13("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
19405
- /* @__PURE__ */ jsx22(Pill4, { label: "Change Image", onClick: onChangeImage }),
19552
+ /* @__PURE__ */ jsx22(Pill3, { label: "Change Image", onClick: onChangeImage }),
19406
19553
  /* @__PURE__ */ jsx22(TogglePill, { label: "Autoplay", on: autoplay, onToggle: onToggleAutoplay })
19407
19554
  ] }),
19408
19555
  error && /* @__PURE__ */ jsx22("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
@@ -20194,7 +20341,7 @@ function Label({ className, ...props }) {
20194
20341
  }
20195
20342
 
20196
20343
  // src/ui/link-modal/UrlOrPageInput.tsx
20197
- import { ChevronDown as ChevronDown3, File as File2, X as X3 } from "lucide-react";
20344
+ import { ChevronDown as ChevronDown4, File as File2, X as X3 } from "lucide-react";
20198
20345
  import { jsx as jsx28, jsxs as jsxs17 } from "react/jsx-runtime";
20199
20346
  function FieldChevron({
20200
20347
  onClick
@@ -20207,7 +20354,7 @@ function FieldChevron({
20207
20354
  onClick,
20208
20355
  "aria-label": "Open page list",
20209
20356
  tabIndex: -1,
20210
- children: /* @__PURE__ */ jsx28(ChevronDown3, { size: 16 })
20357
+ children: /* @__PURE__ */ jsx28(ChevronDown4, { size: 16 })
20211
20358
  }
20212
20359
  );
20213
20360
  }
@@ -20437,7 +20584,7 @@ function LinkEditorPanel({ state, onClose }) {
20437
20584
  // src/ui/link-modal/SectionPickerOverlay.tsx
20438
20585
  import { useCallback as useCallback7, useEffect as useEffect11, useMemo as useMemo2, useRef as useRef10, useState as useState13 } from "react";
20439
20586
  import { createPortal as createPortal2 } from "react-dom";
20440
- import { ArrowLeft as ArrowLeft2, Check as Check2 } from "lucide-react";
20587
+ import { ArrowLeft as ArrowLeft2, Check as Check3 } from "lucide-react";
20441
20588
  import { usePathname, useRouter as useRouter2 } from "next/navigation";
20442
20589
 
20443
20590
  // src/lib/parent-scroll.ts
@@ -20783,7 +20930,7 @@ function SectionPickerOverlay({
20783
20930
  className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
20784
20931
  style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
20785
20932
  "aria-hidden": true,
20786
- children: /* @__PURE__ */ jsx30(Check2, { className: "size-5" })
20933
+ children: /* @__PURE__ */ jsx30(Check3, { className: "size-5" })
20787
20934
  }
20788
20935
  ) : null
20789
20936
  ]
@@ -21236,7 +21383,7 @@ function addFooterColumnWithPersist({
21236
21383
  import {
21237
21384
  useCallback as useCallback9,
21238
21385
  useEffect as useEffect14,
21239
- useLayoutEffect as useLayoutEffect4,
21386
+ useLayoutEffect as useLayoutEffect5,
21240
21387
  useRef as useRef11,
21241
21388
  useState as useState15
21242
21389
  } from "react";
@@ -21333,7 +21480,7 @@ function FloatingPanel({
21333
21480
  return () => window.removeEventListener("message", onParentScroll);
21334
21481
  }, [open]);
21335
21482
  const positionRef = useRef11(position);
21336
- useLayoutEffect4(() => {
21483
+ useLayoutEffect5(() => {
21337
21484
  if (!open) {
21338
21485
  positionRef.current = position;
21339
21486
  return;
@@ -21343,7 +21490,7 @@ function FloatingPanel({
21343
21490
  }
21344
21491
  positionRef.current = position;
21345
21492
  }, [open, position, liveScroll, parentScroll]);
21346
- useLayoutEffect4(() => {
21493
+ useLayoutEffect5(() => {
21347
21494
  if (!open || !panelRef.current) return;
21348
21495
  const el = panelRef.current;
21349
21496
  const header = el.querySelector("[data-ohw-floating-panel-header]");
@@ -21552,7 +21699,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
21552
21699
  }
21553
21700
 
21554
21701
  // src/ui/button-style-panel.tsx
21555
- import { Check as Check3 } from "lucide-react";
21702
+ import { Check as Check4 } from "lucide-react";
21556
21703
  import { jsx as jsx34, jsxs as jsxs23 } from "react/jsx-runtime";
21557
21704
  var SIZE_LABEL = { s: "S", m: "M", l: "L" };
21558
21705
  function ButtonStylePanel({
@@ -21623,7 +21770,7 @@ function ButtonStylePanel({
21623
21770
  {
21624
21771
  className: "absolute right-0.5 top-0.5 flex size-5 items-center justify-center rounded-full bg-primary text-primary-foreground",
21625
21772
  "aria-hidden": true,
21626
- children: /* @__PURE__ */ jsx34(Check3, { className: "size-3", strokeWidth: 3 })
21773
+ children: /* @__PURE__ */ jsx34(Check4, { className: "size-3", strokeWidth: 3 })
21627
21774
  }
21628
21775
  ) : null
21629
21776
  ]
@@ -22648,7 +22795,7 @@ function useSectionDrag({
22648
22795
  }
22649
22796
 
22650
22797
  // src/ui/footer-container-chrome.tsx
22651
- import { Plus as Plus2 } from "lucide-react";
22798
+ import { Plus as Plus3 } from "lucide-react";
22652
22799
  import { jsx as jsx35, jsxs as jsxs24 } from "react/jsx-runtime";
22653
22800
  function FooterContainerChrome({
22654
22801
  rect,
@@ -22689,7 +22836,7 @@ function FooterContainerChrome({
22689
22836
  if (addDisabled) return;
22690
22837
  onAdd();
22691
22838
  },
22692
- children: /* @__PURE__ */ jsx35(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
22839
+ children: /* @__PURE__ */ jsx35(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
22693
22840
  }
22694
22841
  ) }),
22695
22842
  /* @__PURE__ */ jsx35(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
@@ -22868,7 +23015,7 @@ function deleteSelectedNavFooterItem(deps) {
22868
23015
  }
22869
23016
 
22870
23017
  // src/ui/navbar-container-chrome.tsx
22871
- import { Plus as Plus3 } from "lucide-react";
23018
+ import { Plus as Plus4 } from "lucide-react";
22872
23019
  import { jsx as jsx36 } from "react/jsx-runtime";
22873
23020
  function NavbarContainerChrome({
22874
23021
  rect,
@@ -22904,7 +23051,7 @@ function NavbarContainerChrome({
22904
23051
  e.stopPropagation();
22905
23052
  onAdd();
22906
23053
  },
22907
- children: /* @__PURE__ */ jsx36(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
23054
+ children: /* @__PURE__ */ jsx36(Plus4, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
22908
23055
  }
22909
23056
  )
22910
23057
  }
@@ -22976,7 +23123,7 @@ function Badge({ className, variant, ...props }) {
22976
23123
  }
22977
23124
 
22978
23125
  // src/OhhwellsBridge.tsx
22979
- import { Brush as Brush2, Link as Link2, Plus as Plus4, Settings } from "lucide-react";
23126
+ import { Brush as Brush2, Link as Link2, Plus as Plus5, Settings } from "lucide-react";
22980
23127
  import { Fragment as Fragment12, jsx as jsx39, jsxs as jsxs25 } from "react/jsx-runtime";
22981
23128
  var PRIMARY7 = "#0885FE";
22982
23129
  var IMAGE_FADE_MS = 300;
@@ -24056,7 +24203,7 @@ function applyVisibleViewport(el, parentScroll) {
24056
24203
  el.style.top = `${top}px`;
24057
24204
  el.style.height = `${height}px`;
24058
24205
  }
24059
- var TOOLBAR_EDGE_MARGIN2 = 4;
24206
+ var TOOLBAR_EDGE_MARGIN3 = 4;
24060
24207
  function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
24061
24208
  const isAbove = transform.includes("translateY(-100%)");
24062
24209
  let visualTop = isAbove ? top - approxH : top;
@@ -24083,8 +24230,8 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
24083
24230
  function clampToolbarLeft(centerX, toolbarWidth) {
24084
24231
  const half = toolbarWidth / 2;
24085
24232
  return Math.max(
24086
- TOOLBAR_EDGE_MARGIN2 + half,
24087
- Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half)
24233
+ TOOLBAR_EDGE_MARGIN3 + half,
24234
+ Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN3 - half)
24088
24235
  );
24089
24236
  }
24090
24237
  function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
@@ -24523,7 +24670,7 @@ function OhhwellsBridge() {
24523
24670
  }, []);
24524
24671
  const subdomainFromQuery = searchParams.get("subdomain");
24525
24672
  const [subdomain, setSubdomain] = useState18(() => resolveSubdomain(subdomainFromQuery));
24526
- useLayoutEffect5(() => {
24673
+ useLayoutEffect6(() => {
24527
24674
  const next = resolveSubdomain(subdomainFromQuery);
24528
24675
  if (next !== subdomain) setSubdomain(next);
24529
24676
  if (next) return;
@@ -26638,7 +26785,7 @@ function OhhwellsBridge() {
26638
26785
  isFooterFrameSelection,
26639
26786
  postToParent2
26640
26787
  ]);
26641
- useLayoutEffect5(() => {
26788
+ useLayoutEffect6(() => {
26642
26789
  if (!subdomain || isEditMode) {
26643
26790
  setFetchState("done");
26644
26791
  return;
@@ -26978,7 +27125,7 @@ function OhhwellsBridge() {
26978
27125
  if (debounceTimer) clearTimeout(debounceTimer);
26979
27126
  };
26980
27127
  }, [subdomain, isEditMode, pathname]);
26981
- useLayoutEffect5(() => {
27128
+ useLayoutEffect6(() => {
26982
27129
  const el = document.getElementById("ohw-loader");
26983
27130
  if (!el) return;
26984
27131
  const visible = Boolean(subdomain) && fetchState !== "done";
@@ -30771,7 +30918,7 @@ function OhhwellsBridge() {
30771
30918
  postToParent2({
30772
30919
  type: "ow:ready",
30773
30920
  version: "1",
30774
- bridgeVersion: "0.1.135",
30921
+ bridgeVersion: "0.1.136",
30775
30922
  path: pathname,
30776
30923
  nodes: collectEditableNodes(editContentRef.current),
30777
30924
  sections
@@ -31507,7 +31654,7 @@ function OhhwellsBridge() {
31507
31654
  className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
31508
31655
  onClick: () => setFieldTypePickerOpen((open) => !open),
31509
31656
  "data-ohw-add-field": "",
31510
- children: /* @__PURE__ */ jsx39(Plus4, { size: 15, "aria-hidden": true })
31657
+ children: /* @__PURE__ */ jsx39(Plus5, { size: 15, "aria-hidden": true })
31511
31658
  }
31512
31659
  ),
31513
31660
  /* @__PURE__ */ jsx39("div", { className: "mx-0.5 h-5 w-px bg-border" }),