veo-sdk 0.6.0 → 0.6.2

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.
Files changed (34) hide show
  1. package/dist/builder-ENKEIVF2.mjs +5 -0
  2. package/dist/{builder-3QPHB2VJ.mjs.map → builder-ENKEIVF2.mjs.map} +1 -1
  3. package/dist/builder.cjs +366 -20
  4. package/dist/builder.cjs.map +1 -1
  5. package/dist/builder.d.cts +2 -2
  6. package/dist/builder.d.ts +2 -2
  7. package/dist/builder.mjs +4 -4
  8. package/dist/{chunk-N4VFMZFA.mjs → chunk-4QZDNJJE.mjs} +3 -3
  9. package/dist/{chunk-N4VFMZFA.mjs.map → chunk-4QZDNJJE.mjs.map} +1 -1
  10. package/dist/{chunk-GMXQMZ4X.mjs → chunk-L3QQJLDJ.mjs} +3 -3
  11. package/dist/{chunk-GMXQMZ4X.mjs.map → chunk-L3QQJLDJ.mjs.map} +1 -1
  12. package/dist/{chunk-O6USA4TU.mjs → chunk-ZILDR4YE.mjs} +368 -22
  13. package/dist/chunk-ZILDR4YE.mjs.map +1 -0
  14. package/dist/detect-theme-X4K3TLUL.mjs +446 -0
  15. package/dist/detect-theme-X4K3TLUL.mjs.map +1 -0
  16. package/dist/{guide-preview-DylsEhrg.d.cts → guide-preview-DEFhfA4o.d.cts} +115 -0
  17. package/dist/{guide-preview-DylsEhrg.d.ts → guide-preview-DEFhfA4o.d.ts} +115 -0
  18. package/dist/index.cjs +994 -51
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +13 -1
  21. package/dist/index.d.ts +13 -1
  22. package/dist/index.mjs +141 -16
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/veo-builder.js +92 -20
  25. package/dist/veo-builder.js.map +1 -1
  26. package/dist/veo-guides.js +84 -12
  27. package/dist/veo-guides.js.map +1 -1
  28. package/dist/veo-theme.js +2 -0
  29. package/dist/veo-theme.js.map +1 -0
  30. package/dist/veo.js +2 -2
  31. package/dist/veo.js.map +1 -1
  32. package/package.json +2 -2
  33. package/dist/builder-3QPHB2VJ.mjs +0 -5
  34. package/dist/chunk-O6USA4TU.mjs.map +0 -1
@@ -668,6 +668,10 @@ var TEXT_PRESETS = {
668
668
  small: { size: 12, weight: 400, lineHeight: 1.5 }
669
669
  };
670
670
  function applyBlockStyle(el, style, kind) {
671
+ if (kind === "text") {
672
+ const explicit = style && typeof style === "object" ? style.preset : void 0;
673
+ el.dataset.veoPreset = typeof explicit === "string" ? explicit : el.classList.contains("veo-guide-title") ? "title" : "paragraph";
674
+ }
671
675
  if (!style || typeof style !== "object") return;
672
676
  const s = style;
673
677
  if (kind === "image" && s.bleed === true) {
@@ -684,8 +688,9 @@ function applyBlockStyle(el, style, kind) {
684
688
  if (kind === "text" && typeof s.preset === "string" && s.preset in TEXT_PRESETS) {
685
689
  const preset = TEXT_PRESETS[s.preset];
686
690
  if (preset) {
687
- el.style.fontSize = `${preset.size}px`;
688
- el.style.fontWeight = String(preset.weight);
691
+ const token = s.preset === "small" ? null : `--veo-t-${s.preset}`;
692
+ el.style.fontSize = token ? `var(${token}-size, ${preset.size}px)` : `${preset.size}px`;
693
+ el.style.fontWeight = token ? `var(${token}-weight, ${preset.weight})` : String(preset.weight);
689
694
  el.style.lineHeight = String(preset.lineHeight);
690
695
  }
691
696
  }
@@ -1363,20 +1368,92 @@ var GUIDE_STYLES = `
1363
1368
  .veo-guide-actions {
1364
1369
  display: flex; gap: 8px; justify-content: var(--veo-actions-justify);
1365
1370
  }
1371
+ /* Tema del workspace (design system): cada preset de texto toma sus tokens de
1372
+ las variables que publica \`applyThemeVars\` en la tarjeta. Las reglas solo
1373
+ existen bajo .veo-card--themed; los estilos inline del bloque las pisan. El
1374
+ \`*\` cubre el rich text (la regla global de fuente aplica a cada hijo). */
1375
+ .veo-card--themed [data-veo-preset="title"] {
1376
+ color: var(--veo-t-title-color); font-size: var(--veo-t-title-size);
1377
+ font-weight: var(--veo-t-title-weight); text-align: var(--veo-t-title-align);
1378
+ }
1379
+ .veo-card--themed [data-veo-preset="subtitle"] {
1380
+ color: var(--veo-t-subtitle-color); font-size: var(--veo-t-subtitle-size);
1381
+ font-weight: var(--veo-t-subtitle-weight); text-align: var(--veo-t-subtitle-align);
1382
+ }
1383
+ .veo-card--themed [data-veo-preset="paragraph"] {
1384
+ color: var(--veo-t-paragraph-color); font-size: var(--veo-t-paragraph-size);
1385
+ font-weight: var(--veo-t-paragraph-weight); text-align: var(--veo-t-paragraph-align);
1386
+ }
1387
+ .veo-card--themed [data-veo-preset="small"] { color: var(--veo-t-paragraph-color); }
1388
+ .veo-card--themed [data-veo-preset="title"], .veo-card--themed [data-veo-preset="title"] * {
1389
+ font-family: var(--veo-t-title-font, var(--veo-font));
1390
+ }
1391
+ .veo-card--themed [data-veo-preset="subtitle"], .veo-card--themed [data-veo-preset="subtitle"] * {
1392
+ font-family: var(--veo-t-subtitle-font, var(--veo-font));
1393
+ }
1394
+ .veo-card--themed [data-veo-preset="paragraph"], .veo-card--themed [data-veo-preset="paragraph"] *,
1395
+ .veo-card--themed [data-veo-preset="small"], .veo-card--themed [data-veo-preset="small"] * {
1396
+ font-family: var(--veo-t-paragraph-font, var(--veo-font));
1397
+ }
1398
+ /* Formulario del tema (pesta\xF1a Formulario). Dentro de un .veo-form los tokens
1399
+ de texto \`--veo-t-*\` se REDEFINEN con \xABTexto principal\xBB: la pregunta es un
1400
+ bloque con preset (su tama\xF1o va inline con esas variables), as\xED toma los del
1401
+ formulario y no los del modal. Etiquetas y opciones = \xABTexto secundario\xBB. */
1402
+ .veo-card--themed-form .veo-form {
1403
+ background: var(--veo-f-bg); padding: var(--veo-f-pad);
1404
+ border: var(--veo-f-border, none); border-radius: var(--veo-f-radius, 8px);
1405
+ box-shadow: var(--veo-f-shadow, none);
1406
+ --veo-t-title-color: var(--veo-f-primary-color); --veo-t-title-size: var(--veo-f-primary-size);
1407
+ --veo-t-title-weight: var(--veo-f-primary-weight); --veo-t-title-align: var(--veo-f-primary-align);
1408
+ --veo-t-title-font: var(--veo-f-primary-font);
1409
+ --veo-t-subtitle-color: var(--veo-f-primary-color); --veo-t-subtitle-size: var(--veo-f-primary-size);
1410
+ --veo-t-subtitle-weight: var(--veo-f-primary-weight); --veo-t-subtitle-align: var(--veo-f-primary-align);
1411
+ --veo-t-subtitle-font: var(--veo-f-primary-font);
1412
+ --veo-t-paragraph-color: var(--veo-f-primary-color); --veo-t-paragraph-size: var(--veo-f-primary-size);
1413
+ --veo-t-paragraph-weight: var(--veo-f-primary-weight); --veo-t-paragraph-align: var(--veo-f-primary-align);
1414
+ --veo-t-paragraph-font: var(--veo-f-primary-font);
1415
+ }
1416
+ .veo-card--themed-form .veo-form-label,
1417
+ .veo-card--themed-form .veo-form-option,
1418
+ .veo-card--themed-form .veo-scale-label {
1419
+ color: var(--veo-f-secondary-color); font-weight: var(--veo-f-secondary-weight);
1420
+ font-family: var(--veo-f-secondary-font, var(--veo-font));
1421
+ }
1422
+ .veo-card--themed-form .veo-form-label,
1423
+ .veo-card--themed-form .veo-form-option {
1424
+ font-size: var(--veo-f-secondary-size); text-align: var(--veo-f-secondary-align);
1425
+ }
1426
+ .veo-card--themed-form .veo-form-input:focus { outline-color: var(--veo-f-accent); }
1427
+ .veo-card--themed-form .veo-form-option input { accent-color: var(--veo-f-accent); }
1428
+ .veo-card--themed-form .veo-nps-btn:hover { border-color: var(--veo-scale-color, var(--veo-f-accent)); }
1429
+ .veo-card--themed-form .veo-scale-active.veo-nps-btn {
1430
+ background: var(--veo-scale-color, var(--veo-f-accent)); color: var(--veo-f-on-accent);
1431
+ border-color: var(--veo-scale-color, var(--veo-f-accent));
1432
+ }
1366
1433
  .veo-guide-cta {
1367
1434
  background: var(--veo-cta-bg, var(--veo-primary));
1368
- color: var(--veo-cta-color, #fff); border: none;
1369
- padding: 9px 18px; border-radius: var(--veo-cta-radius, 8px);
1370
- font-size: var(--veo-cta-size, 14px); font-weight: 500; cursor: pointer;
1435
+ color: var(--veo-cta-color, #fff); border: var(--veo-cta-border, none);
1436
+ padding: var(--veo-cta-pad, 9px 18px); border-radius: var(--veo-cta-radius, 8px);
1437
+ font-size: var(--veo-cta-size, 14px); font-weight: var(--veo-cta-weight, 500); cursor: pointer;
1371
1438
  transition: opacity 120ms ease;
1372
1439
  }
1373
1440
  .veo-guide-cta:hover { opacity: 0.9; }
1374
1441
  /* Presets del boton (editor): secundario = contorno; enlace = solo texto. */
1375
1442
  .veo-guide-cta--secondary {
1376
- background: transparent; color: var(--veo-primary);
1377
- border: 1px solid var(--veo-primary);
1443
+ background: var(--veo-cta2-bg, transparent); color: var(--veo-cta2-color, var(--veo-primary));
1444
+ border: var(--veo-cta2-border, 1px solid var(--veo-primary));
1445
+ padding: var(--veo-cta2-pad, var(--veo-cta-pad, 9px 18px));
1446
+ border-radius: var(--veo-cta2-radius, var(--veo-cta-radius, 8px));
1447
+ font-size: var(--veo-cta2-size, var(--veo-cta-size, 14px));
1448
+ font-weight: var(--veo-cta2-weight, var(--veo-cta-weight, 500));
1449
+ }
1450
+ .veo-guide-cta--link {
1451
+ background: transparent; color: var(--veo-cta3-color, var(--veo-primary));
1452
+ border: var(--veo-cta3-border, none); padding: var(--veo-cta3-pad, 0);
1453
+ border-radius: var(--veo-cta3-radius, 0);
1454
+ font-size: var(--veo-cta3-size, var(--veo-cta-size, 14px));
1455
+ font-weight: var(--veo-cta3-weight, var(--veo-cta-weight, 500));
1378
1456
  }
1379
- .veo-guide-cta--link { background: transparent; color: var(--veo-primary); padding: 0; }
1380
1457
  .veo-guide-cta--link:hover { opacity: 1; text-decoration: underline; }
1381
1458
  .veo-guide-cta:active { transform: translateY(1px); }
1382
1459
  .veo-guide-close {
@@ -1746,6 +1823,12 @@ var STATIC_SIDE = {
1746
1823
  left: "right",
1747
1824
  right: "left"
1748
1825
  };
1826
+ var OUTER_EDGES = {
1827
+ top: ["top", "left"],
1828
+ right: ["top", "right"],
1829
+ bottom: ["bottom", "right"],
1830
+ left: ["bottom", "left"]
1831
+ };
1749
1832
  function positionArrow(arrowEl, placement, data) {
1750
1833
  const side = STATIC_SIDE[placement.split("-")[0] ?? "bottom"] ?? "top";
1751
1834
  for (const prop of ["top", "bottom", "left", "right"]) {
@@ -1754,6 +1837,16 @@ function positionArrow(arrowEl, placement, data) {
1754
1837
  if (data?.x != null) arrowEl.style.setProperty("left", `${data.x}px`);
1755
1838
  if (data?.y != null) arrowEl.style.setProperty("top", `${data.y}px`);
1756
1839
  arrowEl.style.setProperty(side, "-6px");
1840
+ const width = arrowEl.dataset.veoBorder;
1841
+ if (width) {
1842
+ for (const edge of ["top", "right", "bottom", "left"]) {
1843
+ arrowEl.style.setProperty(
1844
+ `border-${edge}-width`,
1845
+ OUTER_EDGES[side].includes(edge) ? `${width}px` : "0"
1846
+ );
1847
+ }
1848
+ arrowEl.style.zIndex = "1";
1849
+ }
1757
1850
  }
1758
1851
 
1759
1852
  // src/plugins/guides/renderers/badge-renderer.ts
@@ -2901,6 +2994,168 @@ function buildScale(wrapper, doc, min, max, btnClass, symbol, opts = { labels: [
2901
2994
  return { wrapper, read: () => selected };
2902
2995
  }
2903
2996
 
2997
+ // src/plugins/guides/guide-theme.ts
2998
+ var WORKSPACE_THEME_ID = "workspace";
2999
+ var SHADOW_SPEC = {
3000
+ soft: { y: 4, blur: 14, alpha: 0.12 },
3001
+ medium: { y: 12, blur: 32, alpha: 0.22 },
3002
+ strong: { y: 24, blur: 64, alpha: 0.38 }
3003
+ };
3004
+ var JUSTIFY = {
3005
+ left: "flex-start",
3006
+ center: "center",
3007
+ right: "flex-end",
3008
+ distribute: "space-between"
3009
+ };
3010
+ function channels(hex) {
3011
+ const h = hex.replace("#", "");
3012
+ const full = h.length === 3 ? [...h].map((x) => x + x).join("") : h.slice(0, 6);
3013
+ const ch = (i) => Number.parseInt(full.slice(i, i + 2), 16) || 0;
3014
+ return [ch(0), ch(2), ch(4)];
3015
+ }
3016
+ function boxShadow(shadow, hex) {
3017
+ if (shadow === "none") return "none";
3018
+ const spec = SHADOW_SPEC[shadow];
3019
+ const [r, g, b] = channels(hex);
3020
+ return `0 ${spec.y}px ${spec.blur}px rgba(${r}, ${g}, ${b}, ${spec.alpha})`;
3021
+ }
3022
+ function readableOn(hex) {
3023
+ const [r, g, b] = channels(hex);
3024
+ return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255 > 0.6 ? "#111827" : "#ffffff";
3025
+ }
3026
+ function themeModeFor(theme, design) {
3027
+ if (!theme || design.theme !== WORKSPACE_THEME_ID) return null;
3028
+ return (design.colorMode === "dark" ? theme.dark : theme.light) ?? null;
3029
+ }
3030
+ function themeRowJustify(mode, inline, preset) {
3031
+ const box = inline ? mode.embedded : mode.overlay;
3032
+ if (box.align === "distribute") return null;
3033
+ const button = preset === "secondary" ? mode.buttons?.secondary : preset === "link" ? mode.buttons?.tertiary : preset === void 0 || preset === null || preset === "primary" ? mode.buttons?.primary : void 0;
3034
+ return button ? JUSTIFY[button.align] ?? null : null;
3035
+ }
3036
+ function appFont(ref, doc) {
3037
+ const view = doc.defaultView;
3038
+ if (!view) return null;
3039
+ if (ref === "inherit") return view.getComputedStyle(doc.body).fontFamily || null;
3040
+ if (ref === "app-heading") {
3041
+ const heading = Array.from(doc.querySelectorAll("h1,h2,h3")).find(
3042
+ (el) => el.getClientRects().length > 0
3043
+ );
3044
+ return view.getComputedStyle(heading ?? doc.body).fontFamily || null;
3045
+ }
3046
+ return ref;
3047
+ }
3048
+ function themeContainerDesign(mode, inline, tooltip = false) {
3049
+ const box = inline ? mode.embedded : mode.overlay;
3050
+ const tip = tooltip ? mode.tooltip : void 0;
3051
+ const padding = tip?.padding ?? box.padding;
3052
+ const out = {
3053
+ // El embebido va en el flujo de la página: sin fondo propio.
3054
+ background: tip ? tip.background : inline ? "transparent" : box.background ?? mode.colors.background,
3055
+ color: mode.colors.text,
3056
+ paddingTop: padding.top,
3057
+ paddingRight: padding.right,
3058
+ paddingBottom: padding.bottom,
3059
+ paddingLeft: padding.left,
3060
+ borderColor: tip?.borderColor ?? box.borderColor,
3061
+ borderWidth: tip?.borderWidth ?? box.borderWidth,
3062
+ radius: tip?.borderRadius ?? box.borderRadius
3063
+ };
3064
+ const shadow = tip?.shadow ?? box.shadow;
3065
+ const shadowColor = tip?.shadowColor ?? box.shadowColor;
3066
+ if (shadow === "none") {
3067
+ Object.assign(out, { shadowColor: "transparent", shadowBlur: 0 });
3068
+ } else {
3069
+ const spec = SHADOW_SPEC[shadow];
3070
+ const [r, g, b] = channels(shadowColor);
3071
+ Object.assign(out, {
3072
+ shadowX: 0,
3073
+ shadowY: spec.y,
3074
+ shadowBlur: spec.blur,
3075
+ shadowSpread: 0,
3076
+ shadowColor: `rgba(${r}, ${g}, ${b}, ${spec.alpha})`
3077
+ });
3078
+ }
3079
+ return out;
3080
+ }
3081
+ function applyThemeVars(card, mode, inline, tooltip = false) {
3082
+ const doc = card.ownerDocument ?? document;
3083
+ const box = inline ? mode.embedded : mode.overlay;
3084
+ const set = (name, value) => {
3085
+ if (value) card.style.setProperty(name, value);
3086
+ };
3087
+ card.classList.add("veo-card--themed");
3088
+ set("--veo-primary", mode.colors.accent);
3089
+ set("--veo-cta-color", readableOn(mode.colors.accent));
3090
+ const primary = mode.buttons?.primary;
3091
+ const publish = (prefix, b) => {
3092
+ if (!b) return;
3093
+ const p = b.padding;
3094
+ set(`${prefix}-bg`, b.background);
3095
+ set(`${prefix}-color`, b.color);
3096
+ set(`${prefix}-pad`, `${p.top}px ${p.right}px ${p.bottom}px ${p.left}px`);
3097
+ set(`${prefix}-size`, `${b.fontSize}px`);
3098
+ set(`${prefix}-weight`, String(b.fontWeight));
3099
+ set(`${prefix}-radius`, `${b.borderRadius}px`);
3100
+ set(
3101
+ `${prefix}-border`,
3102
+ b.borderWidth > 0 ? `${b.borderWidth}px solid ${b.borderColor}` : "none"
3103
+ );
3104
+ };
3105
+ publish("--veo-cta", primary);
3106
+ publish("--veo-cta2", mode.buttons?.secondary);
3107
+ publish("--veo-cta3", mode.buttons?.tertiary);
3108
+ set("--veo-text", mode.colors.text);
3109
+ set("--veo-text-secondary", mode.colors.textMuted);
3110
+ set("--veo-font", appFont("inherit", doc));
3111
+ set(
3112
+ "--veo-actions-justify",
3113
+ box.align === "distribute" || !primary ? JUSTIFY[box.align] : JUSTIFY[primary.align]
3114
+ );
3115
+ const form = mode.form;
3116
+ if (form) {
3117
+ card.classList.add("veo-card--themed-form");
3118
+ const fp = form.padding;
3119
+ set("--veo-f-bg", form.background);
3120
+ set("--veo-f-accent", form.accent);
3121
+ set("--veo-f-on-accent", form.onAccent);
3122
+ set("--veo-f-pad", `${fp.top}px ${fp.right}px ${fp.bottom}px ${fp.left}px`);
3123
+ if (typeof form.borderWidth === "number" && form.borderColor) {
3124
+ set(
3125
+ "--veo-f-border",
3126
+ form.borderWidth > 0 ? `${form.borderWidth}px solid ${form.borderColor}` : "none"
3127
+ );
3128
+ }
3129
+ if (typeof form.borderRadius === "number") set("--veo-f-radius", `${form.borderRadius}px`);
3130
+ if (form.shadow && form.shadowColor) {
3131
+ set("--veo-f-shadow", boxShadow(form.shadow, form.shadowColor));
3132
+ }
3133
+ for (const [name, t] of [
3134
+ ["primary", form.text.primary],
3135
+ ["secondary", form.text.secondary]
3136
+ ]) {
3137
+ set(`--veo-f-${name}-color`, t.color);
3138
+ set(`--veo-f-${name}-size`, `${t.fontSize}px`);
3139
+ set(`--veo-f-${name}-weight`, String(t.fontWeight));
3140
+ set(`--veo-f-${name}-align`, t.align);
3141
+ set(`--veo-f-${name}-font`, appFont(t.fontFamily, doc));
3142
+ }
3143
+ }
3144
+ const tip = tooltip ? mode.tooltip?.text : void 0;
3145
+ const tokens = [
3146
+ ["title", tip?.primary ?? mode.text.title],
3147
+ ["subtitle", tip?.secondary ?? mode.text.subtitle],
3148
+ ["paragraph", tip?.secondary ?? mode.text.paragraph]
3149
+ ];
3150
+ for (const [name, t] of tokens) {
3151
+ set(`--veo-t-${name}-color`, t.color);
3152
+ set(`--veo-t-${name}-size`, `${t.fontSize}px`);
3153
+ set(`--veo-t-${name}-weight`, String(t.fontWeight));
3154
+ set(`--veo-t-${name}-align`, t.align);
3155
+ set(`--veo-t-${name}-font`, appFont(t.fontFamily, doc));
3156
+ }
3157
+ }
3158
+
2904
3159
  // src/plugins/guides/layout.ts
2905
3160
  function groupLayout(blocks) {
2906
3161
  const rows = /* @__PURE__ */ new Map();
@@ -3164,13 +3419,83 @@ function markerOffset(anchor, marker, position, offset6) {
3164
3419
  }
3165
3420
  return { x: x + offset6.x, y: y + offset6.y };
3166
3421
  }
3422
+ var NO_CHILDREN = /* @__PURE__ */ new Set([
3423
+ "img",
3424
+ "input",
3425
+ "textarea",
3426
+ "select",
3427
+ "iframe",
3428
+ "video",
3429
+ "audio",
3430
+ "canvas",
3431
+ "br",
3432
+ "hr",
3433
+ "svg",
3434
+ "object",
3435
+ "embed"
3436
+ ]);
3437
+ function canNest(anchor) {
3438
+ const win = anchor.ownerDocument.defaultView;
3439
+ if (!win || !(anchor instanceof win.HTMLElement)) return false;
3440
+ if (NO_CHILDREN.has(anchor.tagName.toLowerCase())) return false;
3441
+ const cs = win.getComputedStyle(anchor);
3442
+ if (cs.display === "contents") return false;
3443
+ const tokens = `${cs.overflow} ${cs.overflowX} ${cs.overflowY}`.split(/\s+/).filter(Boolean);
3444
+ return tokens.every((t) => t === "visible");
3445
+ }
3167
3446
  function attachMarker(anchor, host, marker) {
3168
3447
  host.style.position = "absolute";
3169
3448
  host.style.zIndex = String(num(marker.zIndex, DEFAULT_MARKER_Z));
3170
3449
  host.style.margin = "0";
3450
+ const position = marker.position ?? "top-right";
3451
+ const offset6 = { x: num(marker.offsetX, 0), y: num(marker.offsetY, 0) };
3452
+ const markerSize = () => {
3453
+ const m = host.getBoundingClientRect();
3454
+ return { width: m.width, height: m.height };
3455
+ };
3456
+ if (canNest(anchor)) {
3457
+ const win = anchor.ownerDocument.defaultView;
3458
+ const prevPosition = anchor.style.position;
3459
+ const computed = win.getComputedStyle(anchor).position;
3460
+ if (!computed || computed === "static") anchor.style.position = "relative";
3461
+ anchor.appendChild(host);
3462
+ const swallowClick = (e) => {
3463
+ e.preventDefault();
3464
+ e.stopPropagation();
3465
+ };
3466
+ const swallow = (e) => e.stopPropagation();
3467
+ host.addEventListener("click", swallowClick);
3468
+ host.addEventListener("pointerdown", swallow);
3469
+ host.addEventListener("mousedown", swallow);
3470
+ const update2 = () => {
3471
+ const { x, y } = markerOffset(
3472
+ {
3473
+ left: -anchor.clientLeft,
3474
+ top: -anchor.clientTop,
3475
+ width: anchor.offsetWidth,
3476
+ height: anchor.offsetHeight
3477
+ },
3478
+ markerSize(),
3479
+ position,
3480
+ offset6
3481
+ );
3482
+ host.style.left = `${Math.round(x)}px`;
3483
+ host.style.top = `${Math.round(y)}px`;
3484
+ };
3485
+ update2();
3486
+ const stop2 = autoUpdate(anchor, host, update2, { ancestorScroll: false, layoutShift: false });
3487
+ return () => {
3488
+ stop2();
3489
+ host.removeEventListener("click", swallowClick);
3490
+ host.removeEventListener("pointerdown", swallow);
3491
+ host.removeEventListener("mousedown", swallow);
3492
+ host.remove();
3493
+ anchor.style.position = prevPosition;
3494
+ };
3495
+ }
3496
+ anchor.ownerDocument.body.appendChild(host);
3171
3497
  const update = () => {
3172
3498
  const a = anchor.getBoundingClientRect();
3173
- const m = host.getBoundingClientRect();
3174
3499
  const { x, y } = markerOffset(
3175
3500
  {
3176
3501
  left: a.left + window.scrollX,
@@ -3178,15 +3503,19 @@ function attachMarker(anchor, host, marker) {
3178
3503
  width: a.width,
3179
3504
  height: a.height
3180
3505
  },
3181
- { width: m.width, height: m.height },
3182
- marker.position ?? "top-right",
3183
- { x: num(marker.offsetX, 0), y: num(marker.offsetY, 0) }
3506
+ markerSize(),
3507
+ position,
3508
+ offset6
3184
3509
  );
3185
3510
  host.style.left = `${Math.round(x)}px`;
3186
3511
  host.style.top = `${Math.round(y)}px`;
3187
3512
  };
3188
3513
  update();
3189
- return autoUpdate(anchor, host, update);
3514
+ const stop = autoUpdate(anchor, host, update);
3515
+ return () => {
3516
+ stop();
3517
+ host.remove();
3518
+ };
3190
3519
  }
3191
3520
 
3192
3521
  // src/plugins/guides/renderers/composite-renderer.ts
@@ -3222,6 +3551,11 @@ function applyRowStyle(rowEl, style) {
3222
3551
  if (style.valign && ROW_VALIGN[style.valign]) s.alignItems = ROW_VALIGN[style.valign];
3223
3552
  }
3224
3553
  var CompositeRenderer = class extends BaseRenderer {
3554
+ constructor() {
3555
+ super(...arguments);
3556
+ /** Alineación de filas de botones según el tema del workspace (null = sin tema). */
3557
+ this.themeRowJustify = null;
3558
+ }
3225
3559
  async render(context) {
3226
3560
  const idx = context.nav?.stepIndex ?? 0;
3227
3561
  const step = context.guide.guideSteps[idx];
@@ -3252,7 +3586,13 @@ var CompositeRenderer = class extends BaseRenderer {
3252
3586
  if (typeof design.zIndex === "number") host.style.zIndex = String(design.zIndex);
3253
3587
  const card = doc.createElement("div");
3254
3588
  card.className = "veo-card";
3255
- applyCompositeDesign(card, design);
3589
+ const themeMode = themeModeFor(context.guide.theme, design);
3590
+ const inline = step.presentation === "inline";
3591
+ const tooltipLike = !inline && (badgeMode || step.position === "relative-to-element");
3592
+ if (themeMode) applyThemeVars(card, themeMode, inline, tooltipLike);
3593
+ this.themeRowJustify = themeMode ? (preset) => themeRowJustify(themeMode, inline, preset) : null;
3594
+ const cardDesign = themeMode ? { ...themeContainerDesign(themeMode, inline, tooltipLike), ...design } : design;
3595
+ applyCompositeDesign(card, cardDesign);
3256
3596
  if (typeof design.ariaLabel === "string" && design.ariaLabel.trim()) {
3257
3597
  card.setAttribute("role", "dialog");
3258
3598
  card.setAttribute("aria-label", design.ariaLabel.trim());
@@ -3323,7 +3663,7 @@ var CompositeRenderer = class extends BaseRenderer {
3323
3663
  });
3324
3664
  }
3325
3665
  card.appendChild(closeBtn);
3326
- reserveCloseSpace(card, blocks, closePos, design);
3666
+ reserveCloseSpace(card, blocks, closePos, cardDesign);
3327
3667
  }
3328
3668
  if (badgeMode && anchor) {
3329
3669
  closeTooltip = this.renderBadgeMode(
@@ -3336,7 +3676,8 @@ var CompositeRenderer = class extends BaseRenderer {
3336
3676
  doc,
3337
3677
  context,
3338
3678
  idx,
3339
- design
3679
+ // Con el tema ya fundido: la flecha del tooltip toma su fondo y borde.
3680
+ cardDesign
3340
3681
  );
3341
3682
  return;
3342
3683
  }
@@ -3359,7 +3700,7 @@ var CompositeRenderer = class extends BaseRenderer {
3359
3700
  }
3360
3701
  const wrapper = doc.createElement("div");
3361
3702
  wrapper.className = "veo-composite-anchored";
3362
- const caretEl = design.caret === false ? null : makeCaret(doc, design);
3703
+ const caretEl = design.caret === false ? null : makeCaret(doc, cardDesign);
3363
3704
  if (caretEl) wrapper.appendChild(caretEl);
3364
3705
  wrapper.appendChild(card);
3365
3706
  root.appendChild(wrapper);
@@ -3419,6 +3760,7 @@ var CompositeRenderer = class extends BaseRenderer {
3419
3760
  const row = doc.createElement("div");
3420
3761
  row.className = "veo-guide-actions";
3421
3762
  let rowAlign;
3763
+ const firstPreset = b.style?.preset;
3422
3764
  while (i < cell.length && cell[i]?.block.type === "button") {
3423
3765
  const { block: bb, index: bi } = cell[i];
3424
3766
  if (!rowAlign) {
@@ -3429,6 +3771,10 @@ var CompositeRenderer = class extends BaseRenderer {
3429
3771
  i++;
3430
3772
  }
3431
3773
  if (rowAlign) row.style.justifyContent = ROW_ALIGN[rowAlign] ?? "flex-end";
3774
+ else {
3775
+ const themed = this.themeRowJustify?.(firstPreset);
3776
+ if (themed) row.style.justifyContent = themed;
3777
+ }
3432
3778
  container.appendChild(row);
3433
3779
  continue;
3434
3780
  }
@@ -3715,9 +4061,7 @@ var CompositeRenderer = class extends BaseRenderer {
3715
4061
  root.appendChild(wrapper);
3716
4062
  if (marker) {
3717
4063
  host.style.display = "inline-block";
3718
- (anchor.ownerDocument ?? document).body.appendChild(host);
3719
4064
  this.registerCleanup(attachMarker(anchor, host, marker));
3720
- this.registerCleanup(() => host.remove());
3721
4065
  } else {
3722
4066
  host.style.display = "inline-block";
3723
4067
  const pos = inlinePosOf(step.inlinePosition);
@@ -3843,6 +4187,7 @@ function makeCaret(doc, design) {
3843
4187
  if (typeof design.borderWidth === "number" && design.borderWidth > 0) {
3844
4188
  const bc = typeof design.borderColor === "string" ? design.borderColor : "#bbbbbb";
3845
4189
  s.border = `${design.borderWidth}px solid ${bc}`;
4190
+ caret.dataset.veoBorder = String(design.borderWidth);
3846
4191
  }
3847
4192
  return caret;
3848
4193
  }
@@ -4577,7 +4922,8 @@ function normalize(input) {
4577
4922
  guideSteps: input.guideSteps,
4578
4923
  activationRules,
4579
4924
  displayFrequency: "always",
4580
- displayPriority: 0
4925
+ displayPriority: 0,
4926
+ ...input.theme ? { theme: input.theme } : {}
4581
4927
  };
4582
4928
  }
4583
4929
  function createSingleStepRenderer(type) {
@@ -4815,5 +5161,5 @@ function buildSelectorPath(element, maxAncestors = 5) {
4815
5161
  }
4816
5162
 
4817
5163
  export { ALWAYS_BLOCK_SELECTORS, BadgeRenderer, BannerRenderer, CompositeRenderer, CustomRenderer, DEFAULT_AUTOCAPTURE_CONFIG, DEFAULT_TRACKER_BATCH_SIZE, DEFAULT_TRACKER_FLUSH_INTERVAL_MS, DEFAULT_TRACKER_MAX_RETRIES, FREQUENCY_CACHE_KEY_PREFIX, FREQUENCY_CACHE_MAX_ENTRIES, FREQUENCY_CACHE_TTL_MS, FormRenderer, GUIDE_STYLES, InlineCustomRenderer, InlineFormRenderer, InlineRenderer, MAX_ANCESTORS, ModalRenderer, PRIORITY_ATTRIBUTES, RAW_BLOCK_ATTR, SENSITIVE_ATTRIBUTES, TooltipRenderer, WALKTHROUGH_ABANDONMENT_TIMEOUT_MS, WALKTHROUGH_STATE_KEY_PREFIX, WalkthroughRenderer, activationDelayMs, applyBlockStyle, buildContentBlock, buildSelectorPath, clearBuilderToken, clearPreviewToken, closeGuidePreview, filterHumanClasses, getPreviewToken, groupLayout, hasDocument, hasLocalStorage, hasNavigatorSendBeacon, hasWindow, isAutomaticActivation, isBuilderMode, isDeviceAllowed, isSnoozed, previewGuide, resolveBuilderContext, resolveBuilderToken, stepMatchesPage, uuidv7 };
4818
- //# sourceMappingURL=chunk-O6USA4TU.mjs.map
4819
- //# sourceMappingURL=chunk-O6USA4TU.mjs.map
5164
+ //# sourceMappingURL=chunk-ZILDR4YE.mjs.map
5165
+ //# sourceMappingURL=chunk-ZILDR4YE.mjs.map