@ohhwells/bridge 0.1.134-next.365 → 0.1.134-next.368

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
@@ -5924,6 +5924,7 @@ function applyStylesToDom(store) {
5924
5924
  section.setAttribute("data-ohw-style-bgcolor", "");
5925
5925
  }
5926
5926
  if (override.cardBackgroundColor !== void 0 && !isDrawerMarker) {
5927
+ detectItemGroups(section);
5927
5928
  section.style.setProperty("--ohw-card-bg", override.cardBackgroundColor);
5928
5929
  section.setAttribute("data-ohw-style-cardbg", "");
5929
5930
  }
@@ -7949,6 +7950,21 @@ function PricingCard({ node, ctx, path }) {
7949
7950
  const fg = emphasis.fg;
7950
7951
  const features = pricingFeatureItems(slots.features);
7951
7952
  const buttons = (node.children ?? []).map((child, i) => ({ child, i })).filter((entry) => entry.child.type === "button");
7953
+ const badge = featured.enabled && str(featured.badge) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
7954
+ "div",
7955
+ {
7956
+ ...ctx.keyFor ? { "data-ohw-key": ctx.keyFor(`${path}.featured.badge`), "data-ohw-editable": "plain" } : {},
7957
+ style: {
7958
+ alignSelf: "flex-start",
7959
+ padding: `${AI_TREE_TOKENS.spacing2 / 2}px ${AI_TREE_TOKENS.spacing3}px`,
7960
+ borderRadius: 999,
7961
+ background: ctx.brand.palette.primary,
7962
+ color: primaryButtonLabel(ctx.brand),
7963
+ ...typeStyle(AI_TREE_TOKENS.type.eyebrow, ctx.brand.fonts.body)
7964
+ },
7965
+ children: str(featured.badge)
7966
+ }
7967
+ ) : null;
7952
7968
  const headingBlock = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: AI_TREE_TOKENS.spacing2 }, children: [
7953
7969
  str(slots.heading) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
7954
7970
  "div",
@@ -7998,32 +8014,31 @@ function PricingCard({ node, ctx, path }) {
7998
8014
  position: "relative"
7999
8015
  },
8000
8016
  children: [
8001
- featured.enabled && str(featured.badge) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
8002
- "div",
8003
- {
8004
- style: {
8005
- alignSelf: "flex-start",
8006
- padding: `${AI_TREE_TOKENS.spacing2 / 2}px ${AI_TREE_TOKENS.spacing3}px`,
8007
- borderRadius: 999,
8008
- background: ctx.brand.palette.primary,
8009
- color: primaryButtonLabel(ctx.brand),
8010
- ...typeStyle(AI_TREE_TOKENS.type.eyebrow, ctx.brand.fonts.body)
8011
- },
8012
- children: str(featured.badge)
8013
- }
8014
- ),
8015
- emphasis.headerBg ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
8016
- "div",
8017
- {
8018
- style: {
8019
- background: emphasis.headerBg,
8020
- margin: `-${AI_TREE_TOKENS.paddingBlock}px -${AI_TREE_TOKENS.paddingBlock}px 0`,
8021
- padding: AI_TREE_TOKENS.paddingBlock,
8022
- borderRadius: `${cardRadius(slots)}px ${cardRadius(slots)}px 0 0`
8023
- },
8024
- children: headingBlock
8025
- }
8026
- ) : headingBlock,
8017
+ emphasis.headerBg ? (
8018
+ // The badge rides inside the band so the tint runs from the card's top edge down
8019
+ // through the price block, instead of starting underneath the badge.
8020
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
8021
+ "div",
8022
+ {
8023
+ style: {
8024
+ background: emphasis.headerBg,
8025
+ margin: `-${AI_TREE_TOKENS.paddingBlock}px -${AI_TREE_TOKENS.paddingBlock}px 0`,
8026
+ padding: AI_TREE_TOKENS.paddingBlock,
8027
+ borderRadius: `${cardRadius(slots)}px ${cardRadius(slots)}px 0 0`,
8028
+ display: "flex",
8029
+ flexDirection: "column",
8030
+ gap: AI_TREE_TOKENS.spacing8
8031
+ },
8032
+ children: [
8033
+ badge,
8034
+ headingBlock
8035
+ ]
8036
+ }
8037
+ )
8038
+ ) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
8039
+ badge,
8040
+ headingBlock
8041
+ ] }),
8027
8042
  features.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
8028
8043
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: { border: "none", borderTop: `1px solid ${fg}`, opacity: 0.2, margin: 0, width: "100%" } }),
8029
8044
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: AI_TREE_TOKENS.spacing4 }, children: [
@@ -18331,16 +18346,65 @@ function removePricingTier(tree, index) {
18331
18346
  return true;
18332
18347
  });
18333
18348
  }
18334
- function setPricingCardFeatured(tree, index, patch) {
18349
+ var PRICING_CARD_STYLES = [
18350
+ { value: "outline", label: "Outline", treatment: null },
18351
+ { value: "lift", label: "Lift", treatment: "lifted" },
18352
+ { value: "invert", label: "Invert", treatment: "inverted" },
18353
+ { value: "header", label: "Header", treatment: "accent-header" }
18354
+ ];
18355
+ var DEFAULT_FEATURED_BADGE = "Most popular";
18356
+ function featuredOf(target) {
18357
+ const raw = target?.slots?.featured;
18358
+ if (raw === true) return { enabled: true, treatment: "outlined" };
18359
+ return typeof raw === "object" && raw !== null ? raw : {};
18360
+ }
18361
+ function badgeOf(featured) {
18362
+ return typeof featured.badge === "string" ? featured.badge.trim() : "";
18363
+ }
18364
+ function pricingCardStyle(tree, index) {
18365
+ const featured = featuredOf(findPricingCollection(tree)?.children?.[index]);
18366
+ if (featured.enabled !== true) return "outline";
18367
+ return PRICING_CARD_STYLES.find((s) => s.treatment === featured.treatment)?.value ?? "outline";
18368
+ }
18369
+ function pricingCardFeaturedTag(tree, index) {
18370
+ const featured = featuredOf(findPricingCollection(tree)?.children?.[index]);
18371
+ return featured.enabled === true && badgeOf(featured).length > 0;
18372
+ }
18373
+ function composeFeatured(style, tagOn, badgeText) {
18374
+ const treatment = PRICING_CARD_STYLES.find((s) => s.value === style)?.treatment ?? null;
18375
+ if (tagOn) return { enabled: true, badge: badgeText || DEFAULT_FEATURED_BADGE, treatment: treatment ?? "outlined" };
18376
+ if (treatment) return { enabled: true, treatment };
18377
+ return badgeText.length > 0 ? { enabled: false, badge: badgeText } : { enabled: false };
18378
+ }
18379
+ function withPricingCard(tree, index, mutate) {
18335
18380
  return withPricingCollection(tree, (collection) => {
18336
18381
  const children = collection.children;
18337
18382
  if (index < 0 || index >= children.length) return false;
18338
18383
  const target = children[index];
18339
18384
  target.slots = target.slots ?? {};
18340
- target.slots.featured = { ...patch };
18385
+ mutate(target);
18341
18386
  return true;
18342
18387
  });
18343
18388
  }
18389
+ function setPricingCardStyle(tree, index, style) {
18390
+ if (!PRICING_CARD_STYLES.some((s) => s.value === style)) return null;
18391
+ return withPricingCard(tree, index, (target) => {
18392
+ const prev = featuredOf(target);
18393
+ const tagOn = prev.enabled === true && badgeOf(prev).length > 0;
18394
+ target.slots.featured = composeFeatured(style, tagOn, badgeOf(prev));
18395
+ });
18396
+ }
18397
+ function setPricingCardFeaturedTag(tree, index, on) {
18398
+ return withPricingCard(tree, index, (target) => {
18399
+ const prev = featuredOf(target);
18400
+ const style = pricingCardStyleOf(prev);
18401
+ target.slots.featured = composeFeatured(style, on, badgeOf(prev));
18402
+ });
18403
+ }
18404
+ function pricingCardStyleOf(featured) {
18405
+ if (featured.enabled !== true) return "outline";
18406
+ return PRICING_CARD_STYLES.find((s) => s.treatment === featured.treatment)?.value ?? "outline";
18407
+ }
18344
18408
  function addPricingCardButton(tree, index, label) {
18345
18409
  return withPricingCollection(tree, (collection) => {
18346
18410
  const children = collection.children;
@@ -18415,15 +18479,8 @@ function removePricingCardFeature(tree, index) {
18415
18479
 
18416
18480
  // src/ui/ai-section/AiPricingCardOverlay.tsx
18417
18481
  var import_jsx_runtime20 = require("react/jsx-runtime");
18418
- var EMPHASIS_TREATMENTS = [
18419
- { value: "outlined", label: "Outline" },
18420
- { value: "lifted", label: "Lift" },
18421
- { value: "inverted", label: "Invert" },
18422
- { value: "accent-header", label: "Header" }
18423
- ];
18424
- var PRIMARY4 = "#0885FE";
18425
- var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY4})`;
18426
- var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY4}) 60%, #000000)`;
18482
+ var PRIMARY4 = "var(--ohw-primary, #0885FE)";
18483
+ 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]";
18427
18484
  function findPricingCardElement(sectionId, index) {
18428
18485
  const sectionEl = findByInstanceId(sectionId);
18429
18486
  if (!sectionEl) return null;
@@ -18433,14 +18490,35 @@ function findPricingCardElement(sectionId, index) {
18433
18490
  }
18434
18491
  return null;
18435
18492
  }
18436
- function readRect3(ref) {
18437
- const el = ref && findPricingCardElement(ref.sectionId, ref.index);
18493
+ function cardRefFromTarget(target) {
18494
+ if (!(target instanceof Element)) return null;
18495
+ if (target.closest(CHROME_SELECTOR)) return null;
18496
+ const cardEl = target.closest("[data-ohw-pricing-card]");
18497
+ if (!cardEl) return null;
18498
+ const sectionEl = cardEl.closest("[data-ohw-section]");
18499
+ const unit = sectionEl ? movableUnit(sectionEl) : null;
18500
+ const sectionId = unit ? instanceIdOf(unit) || null : null;
18501
+ const index = Number(cardEl.dataset.ohwPricingIndex);
18502
+ if (!sectionId || Number.isNaN(index)) return null;
18503
+ return { sectionId, index };
18504
+ }
18505
+ function sameRef(a, b) {
18506
+ return a?.sectionId === b?.sectionId && a?.index === b?.index;
18507
+ }
18508
+ function rectOf(el) {
18438
18509
  if (!el) return null;
18439
18510
  const r2 = el.getBoundingClientRect();
18440
18511
  if (r2.width <= 0 || r2.height <= 0) return null;
18441
18512
  return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
18442
18513
  }
18443
- function useLiveCardRect(ref) {
18514
+ function readRect3(ref) {
18515
+ return rectOf(ref && findPricingCardElement(ref.sectionId, ref.index));
18516
+ }
18517
+ function readGridRect(ref) {
18518
+ const card = ref && findPricingCardElement(ref.sectionId, ref.index);
18519
+ return rectOf(card?.closest("[data-ohw-pricing-collection]") ?? card);
18520
+ }
18521
+ function useLiveCardRect(ref, grid = false) {
18444
18522
  const [rect, setRect] = (0, import_react11.useState)(null);
18445
18523
  (0, import_react11.useEffect)(() => {
18446
18524
  if (!ref) {
@@ -18448,7 +18526,7 @@ function useLiveCardRect(ref) {
18448
18526
  return;
18449
18527
  }
18450
18528
  const update = () => {
18451
- const next = readRect3(ref);
18529
+ const next = grid ? readGridRect(ref) : readRect3(ref);
18452
18530
  setRect(
18453
18531
  (prev) => prev && next && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
18454
18532
  );
@@ -18463,9 +18541,49 @@ function useLiveCardRect(ref) {
18463
18541
  window.removeEventListener("resize", update);
18464
18542
  clearInterval(interval);
18465
18543
  };
18466
- }, [ref?.sectionId, ref?.index]);
18544
+ }, [ref?.sectionId, ref?.index, grid]);
18467
18545
  return rect;
18468
18546
  }
18547
+ var TOOLBAR_GRID_GAP = 52;
18548
+ var TOOLBAR_GRID_GAP_MOBILE = 42;
18549
+ var TOOLBAR_EDGE_MARGIN2 = 4;
18550
+ function GridToolbarSlot({ gridRect, children }) {
18551
+ const slotRef = (0, import_react11.useRef)(null);
18552
+ const [shift, setShift] = (0, import_react11.useState)(0);
18553
+ const centerX = gridRect.left + gridRect.width / 2;
18554
+ (0, import_react11.useLayoutEffect)(() => {
18555
+ const slot = slotRef.current;
18556
+ if (!slot) return;
18557
+ const clamp = () => {
18558
+ const w = slot.offsetWidth;
18559
+ if (w <= 0) return;
18560
+ const half = w / 2;
18561
+ const clamped = Math.max(TOOLBAR_EDGE_MARGIN2 + half, Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half));
18562
+ setShift((prev) => Math.abs(prev - (clamped - centerX)) < 0.5 ? prev : clamped - centerX);
18563
+ };
18564
+ clamp();
18565
+ const ro = new ResizeObserver(clamp);
18566
+ ro.observe(slot);
18567
+ return () => ro.disconnect();
18568
+ }, [centerX, children]);
18569
+ const mobile = window.innerWidth <= 480;
18570
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
18571
+ "div",
18572
+ {
18573
+ ref: slotRef,
18574
+ "data-ohw-bridge": "",
18575
+ "data-ohw-item-interaction": "",
18576
+ className: "pointer-events-auto fixed",
18577
+ style: {
18578
+ top: gridRect.top - (mobile ? TOOLBAR_GRID_GAP_MOBILE : TOOLBAR_GRID_GAP),
18579
+ left: centerX + shift,
18580
+ transform: "translate(-50%, -100%)",
18581
+ zIndex: 2147483645
18582
+ },
18583
+ children
18584
+ }
18585
+ );
18586
+ }
18469
18587
  function requestValidateTree2(postToParent2, tree) {
18470
18588
  return new Promise((resolve) => {
18471
18589
  const id = `ai-validate-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
@@ -18483,40 +18601,93 @@ function requestValidateTree2(postToParent2, tree) {
18483
18601
  postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
18484
18602
  });
18485
18603
  }
18486
- function Pill2({
18487
- label,
18488
- onClick,
18489
- disabled,
18490
- active
18491
- }) {
18604
+ function StyleSwatch({ style }) {
18492
18605
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
18493
- "button",
18606
+ "span",
18494
18607
  {
18495
- type: "button",
18496
- onClick,
18497
- disabled,
18498
- style: {
18499
- height: 28,
18500
- padding: "0 10px",
18501
- display: "inline-flex",
18502
- alignItems: "center",
18503
- gap: 4,
18504
- borderRadius: 999,
18505
- border: "none",
18506
- cursor: disabled ? "default" : "pointer",
18507
- background: active ? OHW_BLUE_DARK2 : "#ffffff",
18508
- color: active ? "#ffffff" : OHW_BLUE_DARK2,
18509
- opacity: disabled ? 0.4 : 1,
18510
- fontSize: 12,
18511
- lineHeight: "16px",
18512
- fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
18513
- whiteSpace: "nowrap",
18514
- flex: "0 0 auto"
18515
- },
18516
- children: label
18608
+ "aria-hidden": true,
18609
+ className: cn(
18610
+ "inline-block h-4 w-[18px] shrink-0 rounded-[3px] border border-border bg-background",
18611
+ style === "lift" && "border-transparent shadow-[0_3px_5px_rgba(0,0,0,0.22)]",
18612
+ style === "invert" && "border-foreground bg-foreground",
18613
+ style === "header" && "bg-[linear-gradient(var(--ohw-foreground,#0c0a09)_48%,var(--ohw-background,#ffffff)_48%)]"
18614
+ )
18517
18615
  }
18518
18616
  );
18519
18617
  }
18618
+ function ButtonGlyph() {
18619
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("svg", { width: "18", height: "12", viewBox: "0 0 18 12", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
18620
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("rect", { x: "0.75", y: "0.75", width: "16.5", height: "10.5", rx: "3", stroke: "currentColor", strokeWidth: "1.5" }),
18621
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M5.5 6H12.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
18622
+ ] });
18623
+ }
18624
+ function FeatureGlyph({ mode }) {
18625
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": true, style: { pointerEvents: "none" }, children: [
18626
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("circle", { cx: "8", cy: "8", r: "7.25", stroke: "currentColor", strokeWidth: "1.5" }),
18627
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M5 8.2L7.2 10.3L11 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }),
18628
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("circle", { cx: "13.5", cy: "13.5", r: "4.25", fill: "var(--ohw-background, #ffffff)", stroke: "var(--ohw-background, #ffffff)", strokeWidth: "1" }),
18629
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("circle", { cx: "13.5", cy: "13.5", r: "3.75", fill: "var(--ohw-background, #ffffff)", stroke: PRIMARY4, strokeWidth: "1" }),
18630
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M11.5 13.5H15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" }),
18631
+ mode === "add" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { d: "M13.5 11.5V15.5", stroke: PRIMARY4, strokeWidth: "1.5", strokeLinecap: "round" })
18632
+ ] });
18633
+ }
18634
+ function ToolbarAction({
18635
+ label,
18636
+ onClick,
18637
+ disabled = false,
18638
+ children
18639
+ }) {
18640
+ const button = /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, onClick, className: "size-8", children });
18641
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
18642
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "inline-flex", children: button }) : button }),
18643
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: label })
18644
+ ] });
18645
+ }
18646
+ function ToolbarSeparator() {
18647
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { "aria-hidden": true, className: "mx-0.5 block h-6 w-px shrink-0 bg-border" });
18648
+ }
18649
+ function CardStyleMenu({
18650
+ value,
18651
+ onChange
18652
+ }) {
18653
+ const current = PRICING_CARD_STYLES.find((s) => s.value === value) ?? PRICING_CARD_STYLES[0];
18654
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1.5 pl-1.5", children: [
18655
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-xs text-muted-foreground", children: "Card style" }),
18656
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DropdownMenu, { modal: false, children: [
18657
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
18658
+ "button",
18659
+ {
18660
+ type: "button",
18661
+ "aria-label": "Card style",
18662
+ 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",
18663
+ children: [
18664
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StyleSwatch, { style: current.value }),
18665
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "flex-1 text-left", children: current.label }),
18666
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.ChevronDown, { size: 16, style: { pointerEvents: "none" } })
18667
+ ]
18668
+ }
18669
+ ) }),
18670
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DropdownMenuContent, { align: "end", sideOffset: 8, className: "w-[152px] min-w-[152px] p-1", children: PRICING_CARD_STYLES.map((style) => {
18671
+ const selected = style.value === value;
18672
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
18673
+ DropdownMenuItem,
18674
+ {
18675
+ role: "menuitemradio",
18676
+ "aria-checked": selected,
18677
+ onSelect: () => onChange(style.value),
18678
+ className: cn("grid grid-cols-[18px_1fr_16px] gap-2 py-2 pl-2 pr-2 text-[13px]", selected && "bg-muted"),
18679
+ children: [
18680
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StyleSwatch, { style: style.value }),
18681
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: style.label }),
18682
+ selected && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Check, { size: 16, className: "text-bridge-primary" })
18683
+ ]
18684
+ },
18685
+ style.value
18686
+ );
18687
+ }) })
18688
+ ] })
18689
+ ] });
18690
+ }
18520
18691
  function PricingCardToolbar({
18521
18692
  entry,
18522
18693
  index,
@@ -18524,8 +18695,8 @@ function PricingCardToolbar({
18524
18695
  error,
18525
18696
  onAddTier,
18526
18697
  onRemoveTier,
18527
- onToggleFeatured,
18528
- onSetTreatment,
18698
+ onSetStyle,
18699
+ onSetFeaturedTag,
18529
18700
  onAddButton,
18530
18701
  onRemoveButton,
18531
18702
  onAddFeature,
@@ -18533,55 +18704,66 @@ function PricingCardToolbar({
18533
18704
  }) {
18534
18705
  const collectionCount = pricingCardCount(entry.tree);
18535
18706
  const card = findPricingCardNode(entry.tree, index);
18536
- const featured = card?.slots?.featured;
18537
- const isFeatured = featured?.enabled === true;
18538
18707
  const buttonCount = (card?.children ?? []).filter((c) => c.type === "button").length;
18539
18708
  const featureCount = pricingCardFeatureCount(entry.tree, index);
18540
- const pillWrap = window.innerWidth <= 480 ? "wrap" : "nowrap";
18541
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
18709
+ const style = pricingCardStyle(entry.tree, index);
18710
+ const featuredTag = pricingCardFeaturedTag(entry.tree, index);
18711
+ const mobile = window.innerWidth <= 480;
18712
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
18542
18713
  "div",
18543
18714
  {
18544
18715
  "data-ohw-bridge": "",
18545
18716
  "data-ohw-toolbar": "",
18546
18717
  onMouseDown: (e) => e.stopPropagation(),
18547
- style: {
18548
- display: "flex",
18549
- flexDirection: "column",
18550
- gap: 6,
18551
- alignItems: "center",
18552
- background: OHW_BLUE2,
18553
- padding: 8,
18554
- borderRadius: 12,
18555
- boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
18556
- pointerEvents: pending ? "none" : "auto",
18557
- opacity: pending ? 0.6 : 1,
18558
- // Only cap width on mobile, where the pill rows wrap — on desktop the row stays on one
18559
- // line and should size to fit it, not get clipped/overflow against a fixed cap.
18560
- maxWidth: pillWrap === "wrap" ? "calc(100vw - 24px)" : "none"
18561
- },
18718
+ className: cn(
18719
+ "flex flex-col items-center gap-1.5 font-sans",
18720
+ pending && "pointer-events-none opacity-60"
18721
+ ),
18722
+ style: { maxWidth: mobile ? "calc(100vw - 24px)" : void 0 },
18562
18723
  children: [
18563
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { style: { display: "flex", gap: 6, flexWrap: pillWrap, justifyContent: "center" }, children: [
18564
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill2, { label: "+ Tier", onClick: onAddTier, disabled: collectionCount >= 4 }),
18565
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill2, { label: "- Tier", onClick: onRemoveTier, disabled: collectionCount <= 1 }),
18566
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill2, { label: "Featured", active: isFeatured, onClick: () => onToggleFeatured(!isFeatured) }),
18567
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill2, { label: "+ Button", onClick: onAddButton, disabled: buttonCount >= 2 }),
18568
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill2, { label: "- Button", onClick: onRemoveButton, disabled: buttonCount === 0 }),
18569
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill2, { label: "+ Feature", onClick: onAddFeature, disabled: featureCount >= 10 }),
18570
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Pill2, { label: "- Feature", onClick: onRemoveFeature, disabled: featureCount <= 1 })
18571
- ] }),
18572
- isFeatured && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { display: "flex", gap: 6, flexWrap: pillWrap, justifyContent: "center" }, children: EMPHASIS_TREATMENTS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
18573
- Pill2,
18724
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
18725
+ "div",
18574
18726
  {
18575
- label: t.label,
18576
- active: (featured?.treatment ?? "outlined") === t.value,
18577
- onClick: () => onSetTreatment(t.value)
18578
- },
18579
- t.value
18580
- )) }),
18581
- error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
18727
+ className: cn(
18728
+ "flex items-center gap-1 rounded-[10px] border border-border bg-background p-1 whitespace-nowrap",
18729
+ "shadow-[0px_10px_15px_-3px_rgba(0,0,0,0.1),0px_4px_6px_-4px_rgba(0,0,0,0.1)]",
18730
+ mobile ? "flex-wrap justify-center" : "flex-nowrap"
18731
+ ),
18732
+ children: [
18733
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CardStyleMenu, { value: style, onChange: onSetStyle }),
18734
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Tooltip, { children: [
18735
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
18736
+ CustomToolbarButton,
18737
+ {
18738
+ type: "button",
18739
+ "aria-label": featuredTag ? "Remove featured tag" : "Add featured tag",
18740
+ "aria-pressed": featuredTag,
18741
+ active: featuredTag,
18742
+ onClick: () => onSetFeaturedTag(!featuredTag),
18743
+ className: "size-8",
18744
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Star, { size: 16, fill: featuredTag ? "currentColor" : "none", style: { pointerEvents: "none" } })
18745
+ }
18746
+ ) }),
18747
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TooltipContent, { side: "bottom", sideOffset: 8, children: featuredTag ? "Remove featured tag" : "Add featured tag" })
18748
+ ] }),
18749
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
18750
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Add button", onClick: onAddButton, disabled: buttonCount >= 2, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ButtonGlyph, {}) }),
18751
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Remove button", onClick: onRemoveButton, disabled: buttonCount === 0, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "relative inline-flex", children: [
18752
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ButtonGlyph, {}),
18753
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Minus, { size: 10, strokeWidth: 2.5, className: "absolute -right-1.5 -top-1.5 rounded-full bg-background text-bridge-primary" })
18754
+ ] }) }),
18755
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Add feature", onClick: onAddFeature, disabled: featureCount >= 10, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(FeatureGlyph, { mode: "add" }) }),
18756
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Remove feature", onClick: onRemoveFeature, disabled: featureCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(FeatureGlyph, { mode: "remove" }) }),
18757
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarSeparator, {}),
18758
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Add tier", onClick: onAddTier, disabled: collectionCount >= 4, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Plus, { size: 16, style: { pointerEvents: "none" } }) }),
18759
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ToolbarAction, { label: "Remove tier", onClick: onRemoveTier, disabled: collectionCount <= 1, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Minus, { size: 16, style: { pointerEvents: "none" } }) })
18760
+ ]
18761
+ }
18762
+ ),
18763
+ error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "max-w-[260px] rounded-md bg-background px-2 py-1 text-center text-[11px] text-destructive shadow-sm", children: error })
18582
18764
  ]
18583
18765
  }
18584
- );
18766
+ ) });
18585
18767
  }
18586
18768
  function findPricingCardNode(tree, index) {
18587
18769
  const stack = tree.rows.flatMap((row) => row.blocks);
@@ -18607,25 +18789,13 @@ function AiPricingCardOverlay({
18607
18789
  activeRef.current = active;
18608
18790
  (0, import_react11.useEffect)(() => {
18609
18791
  const onMove = (e) => {
18792
+ const ref = cardRefFromTarget(e.target);
18610
18793
  const t = e.target;
18611
- if (!(t instanceof HTMLElement)) return;
18612
- 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]")) {
18613
- return;
18614
- }
18615
- const cardEl = t.closest("[data-ohw-pricing-card]");
18616
- if (!cardEl) {
18617
- setHover(null);
18618
- return;
18619
- }
18620
- const sectionEl = cardEl.closest("[data-ohw-section]");
18621
- const unit = sectionEl ? movableUnit(sectionEl) : null;
18622
- const sectionId = unit ? instanceIdOf(unit) || null : null;
18623
- const index = Number(cardEl.dataset.ohwPricingIndex);
18624
- if (!sectionId || Number.isNaN(index)) {
18625
- setHover(null);
18626
- return;
18627
- }
18628
- setHover({ sectionId, index });
18794
+ const overEditable = Boolean(t?.closest?.("[data-ohw-editable], [data-ohw-role], a, button"));
18795
+ setHover((prev) => {
18796
+ const next = ref && !overEditable ? ref : null;
18797
+ return sameRef(prev, next) ? prev : next;
18798
+ });
18629
18799
  };
18630
18800
  const onLeave = () => setHover(null);
18631
18801
  document.addEventListener("mousemove", onMove, { passive: true });
@@ -18637,15 +18807,12 @@ function AiPricingCardOverlay({
18637
18807
  }, []);
18638
18808
  (0, import_react11.useEffect)(() => {
18639
18809
  const onClick = (e) => {
18640
- const current = activeRef.current;
18641
- if (!current) return;
18642
18810
  const t = e.target;
18643
- if (!(t instanceof HTMLElement)) return;
18644
- if (t.closest("[data-ohw-item-interaction]")) return;
18645
- const cardEl = findPricingCardElement(current.sectionId, current.index);
18646
- if (cardEl && cardEl.contains(t)) return;
18647
- setActive(null);
18648
- setError(null);
18811
+ if (!(t instanceof Element)) return;
18812
+ if (t.closest(CHROME_SELECTOR)) return;
18813
+ const ref = cardRefFromTarget(t);
18814
+ setActive((prev) => sameRef(prev, ref) ? prev : ref);
18815
+ if (!ref || !sameRef(activeRef.current, ref)) setError(null);
18649
18816
  };
18650
18817
  document.addEventListener("click", onClick, true);
18651
18818
  return () => document.removeEventListener("click", onClick, true);
@@ -18663,6 +18830,7 @@ function AiPricingCardOverlay({
18663
18830
  const onKeyDown = (e) => {
18664
18831
  if (e.key !== "Escape") return;
18665
18832
  if (!activeRef.current) return;
18833
+ if (document.querySelector('[data-ohw-more-menu][data-state="open"]')) return;
18666
18834
  setActive(null);
18667
18835
  setError(null);
18668
18836
  };
@@ -18708,72 +18876,52 @@ function AiPricingCardOverlay({
18708
18876
  );
18709
18877
  const activeEntry = active ? findEntry(active.sectionId) : null;
18710
18878
  const activeCardRect = useLiveCardRect(active);
18711
- const hoverHandleRect = useLiveCardRect(!active && hover ? hover : null);
18879
+ const activeGridRect = useLiveCardRect(active, true);
18880
+ const hoverRect = useLiveCardRect(hover && !sameRef(hover, active) ? hover : null);
18712
18881
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
18713
- hoverHandleRect && hover && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
18714
- "button",
18715
- {
18716
- type: "button",
18717
- "data-ohw-toolbar": "",
18718
- onClick: () => setActive(hover),
18719
- "aria-label": "Configure pricing tier",
18720
- style: {
18721
- position: "fixed",
18722
- top: hoverHandleRect.top + 8,
18723
- left: hoverHandleRect.left + hoverHandleRect.width - 36,
18724
- width: 28,
18725
- height: 28,
18726
- borderRadius: 8,
18727
- border: `1.5px dashed ${PRIMARY4}`,
18728
- background: "#ffffff",
18729
- color: PRIMARY4,
18730
- display: "flex",
18731
- alignItems: "center",
18732
- justifyContent: "center",
18733
- cursor: "pointer",
18734
- zIndex: 2147483643,
18735
- fontSize: 14,
18736
- fontWeight: 700
18737
- },
18738
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Star, { size: 14, style: { pointerEvents: "none" } })
18739
- }
18740
- ),
18741
- activeCardRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
18742
- ItemInteractionLayer,
18743
- {
18744
- rect: activeCardRect,
18745
- state: "active-top",
18746
- toolbar: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
18747
- PricingCardToolbar,
18748
- {
18749
- entry: activeEntry,
18750
- index: active.index,
18751
- pending,
18752
- error,
18753
- onAddTier: () => runMutation(active.sectionId, addPricingTier),
18754
- onRemoveTier: () => {
18755
- void runMutation(active.sectionId, (tree) => removePricingTier(tree, active.index)).then(
18756
- (applied) => {
18757
- if (applied) setActive(null);
18758
- }
18759
- );
18760
- },
18761
- onToggleFeatured: (enabled) => runMutation(
18762
- active.sectionId,
18763
- (tree) => setPricingCardFeatured(tree, active.index, { enabled })
18764
- ),
18765
- onSetTreatment: (treatment) => runMutation(
18766
- active.sectionId,
18767
- (tree) => setPricingCardFeatured(tree, active.index, { enabled: true, treatment })
18768
- ),
18769
- onAddButton: () => runMutation(active.sectionId, (tree) => addPricingCardButton(tree, active.index, "Learn more")),
18770
- onRemoveButton: () => runMutation(active.sectionId, (tree) => removePricingCardButton(tree, active.index)),
18771
- onAddFeature: () => runMutation(active.sectionId, (tree) => addPricingCardFeature(tree, active.index, "New feature")),
18772
- onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
18773
- }
18774
- )
18775
- }
18776
- )
18882
+ hoverRect && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ItemInteractionLayer, { rect: hoverRect, state: "hover" }),
18883
+ activeCardRect && activeGridRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
18884
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ItemInteractionLayer, { rect: activeCardRect, state: "active-top" }),
18885
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GridToolbarSlot, { gridRect: activeGridRect, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
18886
+ PricingCardToolbar,
18887
+ {
18888
+ entry: activeEntry,
18889
+ index: active.index,
18890
+ pending,
18891
+ error,
18892
+ onAddTier: () => runMutation(active.sectionId, addPricingTier),
18893
+ onRemoveTier: () => {
18894
+ void runMutation(active.sectionId, (tree) => removePricingTier(tree, active.index)).then(
18895
+ (applied) => {
18896
+ if (applied) setActive(null);
18897
+ }
18898
+ );
18899
+ },
18900
+ onSetFeaturedTag: (on) => runMutation(active.sectionId, (tree) => setPricingCardFeaturedTag(tree, active.index, on)),
18901
+ onSetStyle: (style) => runMutation(active.sectionId, (tree) => setPricingCardStyle(tree, active.index, style)),
18902
+ onAddButton: () => runMutation(active.sectionId, (tree) => addPricingCardButton(tree, active.index, "Learn more")),
18903
+ onRemoveButton: () => runMutation(active.sectionId, (tree) => removePricingCardButton(tree, active.index)),
18904
+ onAddFeature: () => runMutation(active.sectionId, (tree) => addPricingCardFeature(tree, active.index, "New feature")),
18905
+ onRemoveFeature: () => runMutation(active.sectionId, (tree) => removePricingCardFeature(tree, active.index))
18906
+ }
18907
+ ) }),
18908
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
18909
+ "div",
18910
+ {
18911
+ "data-ohw-bridge": "",
18912
+ "data-ohw-item-interaction": "",
18913
+ "aria-hidden": true,
18914
+ className: "pointer-events-none fixed rounded-[4px] px-[7px] py-[3px] font-sans text-[11px] font-medium leading-none text-primary-foreground whitespace-nowrap",
18915
+ style: {
18916
+ top: activeCardRect.top + activeCardRect.height + 10,
18917
+ left: activeCardRect.left - 5,
18918
+ background: PRIMARY4,
18919
+ zIndex: 2147483644
18920
+ },
18921
+ children: "Pricing card"
18922
+ }
18923
+ )
18924
+ ] })
18777
18925
  ] });
18778
18926
  }
18779
18927
 
@@ -18852,8 +19000,8 @@ function extractYouTubeId(input) {
18852
19000
  // src/ui/ai-section/AiVideoOverlay.tsx
18853
19001
  var import_jsx_runtime21 = require("react/jsx-runtime");
18854
19002
  var PRIMARY5 = "#0885FE";
18855
- var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY5})`;
18856
- var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
19003
+ var OHW_BLUE2 = `var(--ohw-primary, ${PRIMARY5})`;
19004
+ var OHW_BLUE_DARK2 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY5}) 60%, #000000)`;
18857
19005
  function findVideoBlockElement(sectionId, path) {
18858
19006
  const sectionEl = findByInstanceId(sectionId);
18859
19007
  if (!sectionEl) return null;
@@ -18913,7 +19061,7 @@ function requestValidateTree3(postToParent2, tree) {
18913
19061
  postToParent2({ type: "ow:ai-validate-tree-request", id, tree });
18914
19062
  });
18915
19063
  }
18916
- function Pill3({
19064
+ function Pill2({
18917
19065
  label,
18918
19066
  onClick,
18919
19067
  disabled
@@ -18934,7 +19082,7 @@ function Pill3({
18934
19082
  border: "none",
18935
19083
  cursor: disabled ? "default" : "pointer",
18936
19084
  background: "#ffffff",
18937
- color: OHW_BLUE_DARK3,
19085
+ color: OHW_BLUE_DARK2,
18938
19086
  opacity: disabled ? 0.4 : 1,
18939
19087
  fontSize: 12,
18940
19088
  lineHeight: "16px",
@@ -18999,7 +19147,7 @@ function VideoUrlInput({ value, onCommit }) {
18999
19147
  {
19000
19148
  style: {
19001
19149
  flex: "0 0 auto",
19002
- color: OHW_BLUE_DARK3,
19150
+ color: OHW_BLUE_DARK2,
19003
19151
  fontSize: 10,
19004
19152
  lineHeight: "16px",
19005
19153
  fontWeight: 700,
@@ -19068,7 +19216,7 @@ function VideoToolbar({
19068
19216
  gap: 6,
19069
19217
  alignItems: "center",
19070
19218
  width: 280,
19071
- background: OHW_BLUE3,
19219
+ background: OHW_BLUE2,
19072
19220
  padding: 8,
19073
19221
  borderRadius: 12,
19074
19222
  boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
@@ -19077,7 +19225,7 @@ function VideoToolbar({
19077
19225
  },
19078
19226
  children: [
19079
19227
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(VideoUrlInput, { value: videoId, onCommit: onSetVideoId }),
19080
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Pill3, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
19228
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Pill2, { label: "Remove video", onClick: onRemove, disabled: !videoId }),
19081
19229
  error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
19082
19230
  ]
19083
19231
  }
@@ -19312,8 +19460,8 @@ function setCarouselAutoplay(tree, on) {
19312
19460
  // src/ui/ai-section/AiFadeCarouselOverlay.tsx
19313
19461
  var import_jsx_runtime22 = require("react/jsx-runtime");
19314
19462
  var PRIMARY6 = "#0885FE";
19315
- var OHW_BLUE4 = `var(--ohw-primary, ${PRIMARY6})`;
19316
- var OHW_BLUE_DARK4 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY6}) 60%, #000000)`;
19463
+ var OHW_BLUE3 = `var(--ohw-primary, ${PRIMARY6})`;
19464
+ var OHW_BLUE_DARK3 = `color-mix(in srgb, var(--ohw-primary, ${PRIMARY6}) 60%, #000000)`;
19317
19465
  function findCarouselItemElement(sectionId, index) {
19318
19466
  const sectionEl = findByInstanceId(sectionId);
19319
19467
  if (!sectionEl) return null;
@@ -19392,7 +19540,7 @@ function requestAssetPick2(postToParent2) {
19392
19540
  postToParent2({ type: "ow:asset-pick", id });
19393
19541
  });
19394
19542
  }
19395
- function Pill4({ label, onClick, disabled }) {
19543
+ function Pill3({ label, onClick, disabled }) {
19396
19544
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
19397
19545
  "button",
19398
19546
  {
@@ -19409,7 +19557,7 @@ function Pill4({ label, onClick, disabled }) {
19409
19557
  border: "none",
19410
19558
  cursor: disabled ? "default" : "pointer",
19411
19559
  background: "#ffffff",
19412
- color: OHW_BLUE_DARK4,
19560
+ color: OHW_BLUE_DARK3,
19413
19561
  opacity: disabled ? 0.4 : 1,
19414
19562
  fontSize: 12,
19415
19563
  lineHeight: "16px",
@@ -19446,7 +19594,7 @@ function TogglePill({
19446
19594
  border: "none",
19447
19595
  cursor: disabled ? "default" : "pointer",
19448
19596
  background: "#ffffff",
19449
- color: OHW_BLUE_DARK4,
19597
+ color: OHW_BLUE_DARK3,
19450
19598
  opacity: disabled ? 0.4 : 1,
19451
19599
  fontSize: 12,
19452
19600
  lineHeight: "16px",
@@ -19469,7 +19617,7 @@ function TogglePill({
19469
19617
  // Off is a grey track, not a washed-out blue: the pill's own white background already
19470
19618
  // carries the brand colour in the text, and a pale blue track next to it read as
19471
19619
  // "disabled control" rather than "switch that is off".
19472
- background: on ? OHW_BLUE_DARK4 : "#CBD5E1",
19620
+ background: on ? OHW_BLUE_DARK3 : "#CBD5E1",
19473
19621
  transition: "background 120ms ease"
19474
19622
  },
19475
19623
  children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
@@ -19512,7 +19660,7 @@ function CarouselSlideToolbar({
19512
19660
  flexDirection: "column",
19513
19661
  gap: 6,
19514
19662
  alignItems: "center",
19515
- background: OHW_BLUE4,
19663
+ background: OHW_BLUE3,
19516
19664
  padding: 8,
19517
19665
  borderRadius: 12,
19518
19666
  boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
@@ -19525,7 +19673,7 @@ function CarouselSlideToolbar({
19525
19673
  },
19526
19674
  children: [
19527
19675
  /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
19528
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Pill4, { label: "Change Image", onClick: onChangeImage }),
19676
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Pill3, { label: "Change Image", onClick: onChangeImage }),
19529
19677
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TogglePill, { label: "Autoplay", on: autoplay, onToggle: onToggleAutoplay })
19530
19678
  ] }),
19531
19679
  error && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
@@ -24173,7 +24321,7 @@ function applyVisibleViewport(el, parentScroll) {
24173
24321
  el.style.top = `${top}px`;
24174
24322
  el.style.height = `${height}px`;
24175
24323
  }
24176
- var TOOLBAR_EDGE_MARGIN2 = 4;
24324
+ var TOOLBAR_EDGE_MARGIN3 = 4;
24177
24325
  function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
24178
24326
  const isAbove = transform.includes("translateY(-100%)");
24179
24327
  let visualTop = isAbove ? top - approxH : top;
@@ -24200,8 +24348,8 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
24200
24348
  function clampToolbarLeft(centerX, toolbarWidth) {
24201
24349
  const half = toolbarWidth / 2;
24202
24350
  return Math.max(
24203
- TOOLBAR_EDGE_MARGIN2 + half,
24204
- Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half)
24351
+ TOOLBAR_EDGE_MARGIN3 + half,
24352
+ Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN3 - half)
24205
24353
  );
24206
24354
  }
24207
24355
  function calcToolbarPos(rect, parentScroll, toolbarW = 306) {