@xenia-martech/sdk-js 1.2.0-dev.6 → 1.2.0-dev.7

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 (30) hide show
  1. package/README.md +1 -1
  2. package/dist/{actions-C18Kv-4w.d.cts → actions-35V37IT0.d.cts} +2 -1
  3. package/dist/{actions-C18Kv-4w.d.ts → actions-35V37IT0.d.ts} +2 -1
  4. package/dist/client/index.d.cts +4 -3
  5. package/dist/client/index.d.ts +4 -3
  6. package/dist/client/react/index.cjs +14 -7
  7. package/dist/client/react/index.cjs.map +1 -1
  8. package/dist/client/react/index.d.cts +10 -4
  9. package/dist/client/react/index.d.ts +10 -4
  10. package/dist/client/react/index.js +14 -7
  11. package/dist/client/react/index.js.map +1 -1
  12. package/dist/cms/contentful.d.cts +3 -2
  13. package/dist/cms/contentful.d.ts +3 -2
  14. package/dist/{consent-DgWdjsSy.d.cts → consent-BgAETCkL.d.cts} +2 -1
  15. package/dist/{consent-Cemn91j3.d.ts → consent-DRCV0N0d.d.ts} +2 -1
  16. package/dist/{cookie-names-CnL65Oly.d.cts → cookie-names-DFItnSLK.d.cts} +2 -1
  17. package/dist/{cookie-names-BvUaW3uo.d.ts → cookie-names-DU3MtcNG.d.ts} +2 -1
  18. package/dist/edge/index.d.cts +4 -3
  19. package/dist/edge/index.d.ts +4 -3
  20. package/dist/index.d.cts +4 -3
  21. package/dist/index.d.ts +4 -3
  22. package/dist/next/index.d.cts +7 -5
  23. package/dist/next/index.d.ts +7 -5
  24. package/dist/{personalize-content-c2DDAV6g.d.ts → personalize-content-Cwc2AomC.d.ts} +2 -1
  25. package/dist/{personalize-content-ghZPKlf1.d.cts → personalize-content-CxSdplMV.d.cts} +2 -1
  26. package/dist/server/index.d.cts +5 -4
  27. package/dist/server/index.d.ts +5 -4
  28. package/dist/{xenia-server-DV8Sjmoo.d.ts → xenia-server-Cf24mL0c.d.ts} +3 -2
  29. package/dist/{xenia-server-C3O-cWQT.d.cts → xenia-server-D-bx14lw.d.cts} +3 -2
  30. package/package.json +10 -10
package/README.md CHANGED
@@ -900,7 +900,7 @@ The page behind the rewrite reads the swaps back with `decodeVariant(token, secr
900
900
 
901
901
  **Debugging and QA.** `xeniaEdgeProxy({ debug, qa })` — turn both on only in development or on a QA deploy (e.g. `debug: process.env.NODE_ENV === "development"`):
902
902
 
903
- - `debug: true` writes what was decided for each of the last few pages to the `xenia_debug` cookie. Render `<XeniaDebugPanel />` from `/client/react` behind the same flag: a round Xenia launcher in the corner opens a small white card, like Next.js's dev tools menu, with the status, page, source and location, the decision per content key (click a key for the journey path it took), and the visitor profile. `position` picks the corner (default bottom-right, away from Next.js's own dev tools).
903
+ - `debug: true` writes what was decided for each of the last few pages to the `xenia_debug` cookie. Render `<XeniaDebugPanel />` from `/client/react` behind the same flag: a round Xenia launcher in the corner opens a small white card, like Next.js's dev tools menu, with the status, page, source and location, the decision per content key (click a key for the journey path it took), and the visitor profile. `position` picks the corner (default bottom-right, away from Next.js's own dev tools), and `defaultOpen` opens the card on page load (default closed; once the visitor opens or closes it, that sticks for the session).
904
904
  - Your own data: return `custom` from `debugInfo(info)` — `{ Moment: "thursday 12:00", Household: ["Emma: blue, shoes", "John: no taste"] }` — and the card shows each key as a row (a list one line per item). `renderExtra(page)` remains for anything else.
905
905
  - `qa: true` lets a tester place the visitor in a city (`?xn_geo=london`, from `QA_CITIES` or your own `qa: { cities }`), decide as of a day (`?xn_date=2026-12-24`), and forget both with `?xn_geo=off`; under `next dev`, `?xn_country=GB` too. The overrides last the visit.
906
906
 
@@ -1238,4 +1238,5 @@ declare function extractContentSwaps(body: JsonValue): ContentSwap[] | undefined
1238
1238
  */
1239
1239
  declare function parseActions(body: JsonValue): XeniaAction[];
1240
1240
 
1241
- export { type AnalyticsContext as A, type WidgetType as B, type ConsentState as C, XeniaClient as D, type XeniaClientOptions as E, type XeniaMarker as F, createXeniaClient as G, extractContentSwaps as H, type InteractionType as I, type JsonValue as J, parseActions as K, pendingTargets as L, type MessageCta as M, personalizeContent as N, personalizePage as O, type PagePersonalizeOptions as P, spliceSlots as Q, type ResolveBatchItem as R, type TrackOptions as T, type WidgetFormSubmit as W, type XeniaConfig as X, type XeniaEvent as a, type MessageTemplateFn as b, type MessageComponentRenderer as c, type WidgetSubmitResponse as d, type XeniaAction as e, type MessagePlacement as f, type AnalyticsEventName as g, type AnalyticsIdentity as h, type AnalyticsIngestResponse as i, type AppliedSwap as j, type ClientEvent as k, type CmsAdapter as l, type ContentSwap as m, type IdentifyRequest as n, type IdentifyResponse as o, Identity as p, type MessageMountContext as q, type MessageRenderContext as r, type PageRef as s, type PersonalizationSwap as t, type ResolveBatchResult as u, type ResolveOptions as v, type ResolveResult as w, type WebhookResponse as x, type WidgetPrize as y, type WidgetSegment as z };
1241
+ export { XeniaClient as D, createXeniaClient as G, extractContentSwaps as H, parseActions as K, pendingTargets as L, personalizeContent as N, personalizePage as O, spliceSlots as Q, Identity as p };
1242
+ export type { AnalyticsContext as A, WidgetType as B, ConsentState as C, XeniaClientOptions as E, XeniaMarker as F, InteractionType as I, JsonValue as J, MessageCta as M, PagePersonalizeOptions as P, ResolveBatchItem as R, TrackOptions as T, WidgetFormSubmit as W, XeniaConfig as X, XeniaEvent as a, MessageTemplateFn as b, MessageComponentRenderer as c, WidgetSubmitResponse as d, XeniaAction as e, MessagePlacement as f, AnalyticsEventName as g, AnalyticsIdentity as h, AnalyticsIngestResponse as i, AppliedSwap as j, ClientEvent as k, CmsAdapter as l, ContentSwap as m, IdentifyRequest as n, IdentifyResponse as o, MessageMountContext as q, MessageRenderContext as r, PageRef as s, PersonalizationSwap as t, ResolveBatchResult as u, ResolveOptions as v, ResolveResult as w, WebhookResponse as x, WidgetPrize as y, WidgetSegment as z };
@@ -1238,4 +1238,5 @@ declare function extractContentSwaps(body: JsonValue): ContentSwap[] | undefined
1238
1238
  */
1239
1239
  declare function parseActions(body: JsonValue): XeniaAction[];
1240
1240
 
1241
- export { type AnalyticsContext as A, type WidgetType as B, type ConsentState as C, XeniaClient as D, type XeniaClientOptions as E, type XeniaMarker as F, createXeniaClient as G, extractContentSwaps as H, type InteractionType as I, type JsonValue as J, parseActions as K, pendingTargets as L, type MessageCta as M, personalizeContent as N, personalizePage as O, type PagePersonalizeOptions as P, spliceSlots as Q, type ResolveBatchItem as R, type TrackOptions as T, type WidgetFormSubmit as W, type XeniaConfig as X, type XeniaEvent as a, type MessageTemplateFn as b, type MessageComponentRenderer as c, type WidgetSubmitResponse as d, type XeniaAction as e, type MessagePlacement as f, type AnalyticsEventName as g, type AnalyticsIdentity as h, type AnalyticsIngestResponse as i, type AppliedSwap as j, type ClientEvent as k, type CmsAdapter as l, type ContentSwap as m, type IdentifyRequest as n, type IdentifyResponse as o, Identity as p, type MessageMountContext as q, type MessageRenderContext as r, type PageRef as s, type PersonalizationSwap as t, type ResolveBatchResult as u, type ResolveOptions as v, type ResolveResult as w, type WebhookResponse as x, type WidgetPrize as y, type WidgetSegment as z };
1241
+ export { XeniaClient as D, createXeniaClient as G, extractContentSwaps as H, parseActions as K, pendingTargets as L, personalizeContent as N, personalizePage as O, spliceSlots as Q, Identity as p };
1242
+ export type { AnalyticsContext as A, WidgetType as B, ConsentState as C, XeniaClientOptions as E, XeniaMarker as F, InteractionType as I, JsonValue as J, MessageCta as M, PagePersonalizeOptions as P, ResolveBatchItem as R, TrackOptions as T, WidgetFormSubmit as W, XeniaConfig as X, XeniaEvent as a, MessageTemplateFn as b, MessageComponentRenderer as c, WidgetSubmitResponse as d, XeniaAction as e, MessagePlacement as f, AnalyticsEventName as g, AnalyticsIdentity as h, AnalyticsIngestResponse as i, AppliedSwap as j, ClientEvent as k, CmsAdapter as l, ContentSwap as m, IdentifyRequest as n, IdentifyResponse as o, MessageMountContext as q, MessageRenderContext as r, PageRef as s, PersonalizationSwap as t, ResolveBatchResult as u, ResolveOptions as v, ResolveResult as w, WebhookResponse as x, WidgetPrize as y, WidgetSegment as z };
@@ -1,5 +1,5 @@
1
- import { I as InteractionType, X as XeniaConfig, a as XeniaEvent, M as MessageCta, b as MessageTemplateFn, c as MessageComponentRenderer, W as WidgetFormSubmit, d as WidgetSubmitResponse, e as XeniaAction, f as MessagePlacement, C as ConsentState } from '../actions-C18Kv-4w.cjs';
2
- export { A as AnalyticsContext, g as AnalyticsEventName, h as AnalyticsIdentity, i as AnalyticsIngestResponse, j as AppliedSwap, k as ClientEvent, l as CmsAdapter, m as ContentSwap, n as IdentifyRequest, o as IdentifyResponse, p as Identity, J as JsonValue, q as MessageMountContext, r as MessageRenderContext, P as PagePersonalizeOptions, s as PageRef, t as PersonalizationSwap, R as ResolveBatchItem, u as ResolveBatchResult, v as ResolveOptions, w as ResolveResult, T as TrackOptions, x as WebhookResponse, y as WidgetPrize, z as WidgetSegment, B as WidgetType, D as XeniaClient, E as XeniaClientOptions, F as XeniaMarker, G as createXeniaClient, H as extractContentSwaps, K as parseActions, L as pendingTargets, N as personalizeContent, O as personalizePage, Q as spliceSlots } from '../actions-C18Kv-4w.cjs';
1
+ import { I as InteractionType, X as XeniaConfig, a as XeniaEvent, M as MessageCta, b as MessageTemplateFn, c as MessageComponentRenderer, W as WidgetFormSubmit, d as WidgetSubmitResponse, e as XeniaAction, f as MessagePlacement, C as ConsentState } from '../actions-35V37IT0.cjs';
2
+ export { A as AnalyticsContext, g as AnalyticsEventName, h as AnalyticsIdentity, i as AnalyticsIngestResponse, j as AppliedSwap, k as ClientEvent, l as CmsAdapter, m as ContentSwap, n as IdentifyRequest, o as IdentifyResponse, p as Identity, J as JsonValue, q as MessageMountContext, r as MessageRenderContext, P as PagePersonalizeOptions, s as PageRef, t as PersonalizationSwap, R as ResolveBatchItem, u as ResolveBatchResult, v as ResolveOptions, w as ResolveResult, T as TrackOptions, x as WebhookResponse, y as WidgetPrize, z as WidgetSegment, B as WidgetType, D as XeniaClient, E as XeniaClientOptions, F as XeniaMarker, G as createXeniaClient, H as extractContentSwaps, K as parseActions, L as pendingTargets, N as personalizeContent, O as personalizePage, Q as spliceSlots } from '../actions-35V37IT0.cjs';
3
3
 
4
4
  interface Parsed {
5
5
  eventId: string;
@@ -355,4 +355,5 @@ declare function consentCookieName(prefix?: string): string;
355
355
  */
356
356
  declare function consentCookie(state: ConsentState, prefix?: string, maxAgeDays?: number): string;
357
357
 
358
- export { ActionRenderer, AnalyticsQueue, type AnalyticsQueueOptions, type AutoTrackOptions, AutoTracker, ConsentState, type CtaHandler, InteractionType, type MessageAction, MessageComponentRenderer, MessageCta, MessagePlacement, MessageTemplateFn, type SlotMeta, type SubmitWidgetFormHandler, TokenProvider, WIDGET_RENDERERS, WidgetFormSubmit, type WidgetRenderer, WidgetSubmitResponse, type WidgetWireContext, XeniaAction, XeniaConfig, XeniaEvent, collectFields, computeSpinRotation, consentCookie, consentCookieName, hideContent, parseDataAttribute, readSlotMeta, resolveTarget, showContent, swapContent, wireFormSubmit };
358
+ export { ActionRenderer, AnalyticsQueue, AutoTracker, ConsentState, InteractionType, MessageComponentRenderer, MessageCta, MessagePlacement, MessageTemplateFn, TokenProvider, WIDGET_RENDERERS, WidgetFormSubmit, WidgetSubmitResponse, XeniaAction, XeniaConfig, XeniaEvent, collectFields, computeSpinRotation, consentCookie, consentCookieName, hideContent, parseDataAttribute, readSlotMeta, resolveTarget, showContent, swapContent, wireFormSubmit };
359
+ export type { AnalyticsQueueOptions, AutoTrackOptions, CtaHandler, MessageAction, SlotMeta, SubmitWidgetFormHandler, WidgetRenderer, WidgetWireContext };
@@ -1,5 +1,5 @@
1
- import { I as InteractionType, X as XeniaConfig, a as XeniaEvent, M as MessageCta, b as MessageTemplateFn, c as MessageComponentRenderer, W as WidgetFormSubmit, d as WidgetSubmitResponse, e as XeniaAction, f as MessagePlacement, C as ConsentState } from '../actions-C18Kv-4w.js';
2
- export { A as AnalyticsContext, g as AnalyticsEventName, h as AnalyticsIdentity, i as AnalyticsIngestResponse, j as AppliedSwap, k as ClientEvent, l as CmsAdapter, m as ContentSwap, n as IdentifyRequest, o as IdentifyResponse, p as Identity, J as JsonValue, q as MessageMountContext, r as MessageRenderContext, P as PagePersonalizeOptions, s as PageRef, t as PersonalizationSwap, R as ResolveBatchItem, u as ResolveBatchResult, v as ResolveOptions, w as ResolveResult, T as TrackOptions, x as WebhookResponse, y as WidgetPrize, z as WidgetSegment, B as WidgetType, D as XeniaClient, E as XeniaClientOptions, F as XeniaMarker, G as createXeniaClient, H as extractContentSwaps, K as parseActions, L as pendingTargets, N as personalizeContent, O as personalizePage, Q as spliceSlots } from '../actions-C18Kv-4w.js';
1
+ import { I as InteractionType, X as XeniaConfig, a as XeniaEvent, M as MessageCta, b as MessageTemplateFn, c as MessageComponentRenderer, W as WidgetFormSubmit, d as WidgetSubmitResponse, e as XeniaAction, f as MessagePlacement, C as ConsentState } from '../actions-35V37IT0.js';
2
+ export { A as AnalyticsContext, g as AnalyticsEventName, h as AnalyticsIdentity, i as AnalyticsIngestResponse, j as AppliedSwap, k as ClientEvent, l as CmsAdapter, m as ContentSwap, n as IdentifyRequest, o as IdentifyResponse, p as Identity, J as JsonValue, q as MessageMountContext, r as MessageRenderContext, P as PagePersonalizeOptions, s as PageRef, t as PersonalizationSwap, R as ResolveBatchItem, u as ResolveBatchResult, v as ResolveOptions, w as ResolveResult, T as TrackOptions, x as WebhookResponse, y as WidgetPrize, z as WidgetSegment, B as WidgetType, D as XeniaClient, E as XeniaClientOptions, F as XeniaMarker, G as createXeniaClient, H as extractContentSwaps, K as parseActions, L as pendingTargets, N as personalizeContent, O as personalizePage, Q as spliceSlots } from '../actions-35V37IT0.js';
3
3
 
4
4
  interface Parsed {
5
5
  eventId: string;
@@ -355,4 +355,5 @@ declare function consentCookieName(prefix?: string): string;
355
355
  */
356
356
  declare function consentCookie(state: ConsentState, prefix?: string, maxAgeDays?: number): string;
357
357
 
358
- export { ActionRenderer, AnalyticsQueue, type AnalyticsQueueOptions, type AutoTrackOptions, AutoTracker, ConsentState, type CtaHandler, InteractionType, type MessageAction, MessageComponentRenderer, MessageCta, MessagePlacement, MessageTemplateFn, type SlotMeta, type SubmitWidgetFormHandler, TokenProvider, WIDGET_RENDERERS, WidgetFormSubmit, type WidgetRenderer, WidgetSubmitResponse, type WidgetWireContext, XeniaAction, XeniaConfig, XeniaEvent, collectFields, computeSpinRotation, consentCookie, consentCookieName, hideContent, parseDataAttribute, readSlotMeta, resolveTarget, showContent, swapContent, wireFormSubmit };
358
+ export { ActionRenderer, AnalyticsQueue, AutoTracker, ConsentState, InteractionType, MessageComponentRenderer, MessageCta, MessagePlacement, MessageTemplateFn, TokenProvider, WIDGET_RENDERERS, WidgetFormSubmit, WidgetSubmitResponse, XeniaAction, XeniaConfig, XeniaEvent, collectFields, computeSpinRotation, consentCookie, consentCookieName, hideContent, parseDataAttribute, readSlotMeta, resolveTarget, showContent, swapContent, wireFormSubmit };
359
+ export type { AnalyticsQueueOptions, AutoTrackOptions, CtaHandler, MessageAction, SlotMeta, SubmitWidgetFormHandler, WidgetRenderer, WidgetWireContext };
@@ -3302,6 +3302,7 @@ function view(e) {
3302
3302
  };
3303
3303
  }
3304
3304
  var changed = (result) => !/^(base|control|suppressed)\b/.test(result);
3305
+ var heldOut = (d) => d.reason === "holdout" || d.result === "control";
3305
3306
  function debugStatus(entry) {
3306
3307
  const v = view(entry);
3307
3308
  if (v.source === "timeout" || v.source === "error") return "attention";
@@ -3345,7 +3346,7 @@ function Id({ value }) {
3345
3346
  ] }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: value });
3346
3347
  }
3347
3348
  var percent = (n) => `${Math.round(n <= 1 ? n * 100 : n)}%`;
3348
- function XeniaDebugPanel({ prefix = DEFAULT_PREFIX, position = "bottom-right", renderExtra }) {
3349
+ function XeniaDebugPanel({ prefix = DEFAULT_PREFIX, position = "bottom-right", defaultOpen = false, renderExtra }) {
3349
3350
  const [entry, setEntry] = react.useState(null);
3350
3351
  const [open, setOpen] = react.useState(false);
3351
3352
  const [tab, setTab] = react.useState("Decision");
@@ -3353,6 +3354,7 @@ function XeniaDebugPanel({ prefix = DEFAULT_PREFIX, position = "bottom-right", r
3353
3354
  const launcher = react.useRef(null);
3354
3355
  const card = react.useRef(null);
3355
3356
  const tabRefs = react.useRef({});
3357
+ const focusOnOpen = react.useRef(false);
3356
3358
  const id = react.useId();
3357
3359
  react.useEffect(() => {
3358
3360
  let timer;
@@ -3364,25 +3366,28 @@ function XeniaDebugPanel({ prefix = DEFAULT_PREFIX, position = "bottom-right", r
3364
3366
  };
3365
3367
  read();
3366
3368
  try {
3367
- setOpen(sessionStorage.getItem(OPEN_KEY) === "1");
3368
- const saved = sessionStorage.getItem(TAB_KEY);
3369
- if (saved === "Decision" || saved === "Visitor" || saved === "Request" || saved === "Site") setTab(saved);
3369
+ const saved = sessionStorage.getItem(OPEN_KEY);
3370
+ setOpen(saved === null ? defaultOpen : saved === "1");
3371
+ const savedTab = sessionStorage.getItem(TAB_KEY);
3372
+ if (savedTab === "Decision" || savedTab === "Visitor" || savedTab === "Request" || savedTab === "Site") setTab(savedTab);
3370
3373
  } catch {
3374
+ setOpen(defaultOpen);
3371
3375
  }
3372
3376
  const unwatch = watchNavigation(onNavigate);
3373
3377
  return () => {
3374
3378
  clearTimeout(timer);
3375
3379
  unwatch();
3376
3380
  };
3377
- }, [prefix]);
3381
+ }, [prefix, defaultOpen]);
3378
3382
  const toggle = react.useCallback((next, focusLauncher = false) => {
3379
3383
  setOpen(next);
3384
+ focusOnOpen.current = next;
3380
3385
  if (focusLauncher) launcher.current?.focus();
3381
3386
  remember(OPEN_KEY, next ? "1" : "0");
3382
3387
  }, []);
3383
3388
  react.useEffect(() => {
3384
3389
  if (!open) return;
3385
- card.current?.focus();
3390
+ if (focusOnOpen.current) card.current?.focus();
3386
3391
  const onKey = (e) => {
3387
3392
  if (e.key === "Escape" && root.current?.contains(document.activeElement)) toggle(false, true);
3388
3393
  };
@@ -3436,6 +3441,7 @@ function XeniaDebugPanel({ prefix = DEFAULT_PREFIX, position = "bottom-right", r
3436
3441
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "xdp-head-row", children: [
3437
3442
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "xdp-pill", "data-status": status, children: status === "personalized" ? "Personalized" : "Base content" }),
3438
3443
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "xdp-chip", title: v.source, children: sourceChip(v.source) }),
3444
+ v.decisions.some(heldOut) ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "xdp-chip", "data-tone": "holdout", title: "This visitor is in the holdout: they see base content on purpose, to measure the lift", children: "Holdout" }) : null,
3439
3445
  typeof v.ms === "number" && v.source === "xenia" ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "xdp-ms", children: [
3440
3446
  v.ms,
3441
3447
  " ms"
@@ -3499,7 +3505,7 @@ function DecisionTab({ v }) {
3499
3505
  /* @__PURE__ */ jsxRuntime.jsx("code", { className: "xdp-key", children: d.key }),
3500
3506
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "xdp-result", "data-result": changed(d.result) ? "changed" : "base", children: d.result })
3501
3507
  ] }),
3502
- d.reason ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "xdp-reason", children: d.reason }) : null,
3508
+ d.reason && d.reason !== "holdout" ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "xdp-reason", children: d.reason }) : null,
3503
3509
  d.trace.length ? /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "xdp-steps", "aria-label": "Journey path", children: d.trace.map(([step, outcome]) => /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
3504
3510
  /* @__PURE__ */ jsxRuntime.jsx("code", { children: step }),
3505
3511
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx(Id, { value: outcome }) })
@@ -3606,6 +3612,7 @@ var STYLES2 = `
3606
3612
  .xdp-pill[data-status=attention]{background:var(--xdp-warn-tint);color:var(--xdp-warn)}
3607
3613
  .xdp-chip{display:inline-flex;align-items:center;padding:2px 8px;border-radius:6px;background:var(--xdp-soft);color:var(--xdp-muted);font-size:12px;white-space:nowrap}
3608
3614
  code.xdp-chip{font-size:11.5px}
3615
+ .xdp-chip[data-tone=holdout]{background:var(--xdp-warn-tint);color:var(--xdp-warn);font-weight:600}
3609
3616
  .xdp-ms{margin-left:auto;color:var(--xdp-faint)}
3610
3617
  .xdp-path{display:block;margin-top:8px;font-size:13px;color:var(--xdp-ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
3611
3618
  .xdp-alert{margin:8px 0 0;padding:8px 10px;border-radius:8px;background:var(--xdp-warn-tint);color:var(--xdp-warn)}