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