@actioneer/ads 1.0.9 → 1.0.10

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 (51) hide show
  1. package/DESIGN.md +98 -57
  2. package/README.md +19 -7
  3. package/components/answer.js +1 -1
  4. package/components/assistant-ui/composer-harness.js +13 -10
  5. package/components/body-page-header.d.ts +9 -4
  6. package/components/body-page-header.js +10 -10
  7. package/components/breadcrumbs.js +22 -22
  8. package/components/card.js +18 -18
  9. package/components/chart.d.ts +9 -0
  10. package/components/chart.js +738 -717
  11. package/components/chip.js +12 -12
  12. package/components/collection-header.js +4 -4
  13. package/components/connector-card.js +30 -30
  14. package/components/date-range-picker.js +1 -1
  15. package/components/detail-list.d.ts +28 -0
  16. package/components/detail-list.js +52 -0
  17. package/components/drawer.d.ts +38 -15
  18. package/components/drawer.js +150 -86
  19. package/components/empty-state.d.ts +3 -2
  20. package/components/empty-state.js +22 -22
  21. package/components/field.d.ts +16 -0
  22. package/components/field.js +63 -42
  23. package/components/file-dropzone.d.ts +15 -4
  24. package/components/file-dropzone.js +100 -64
  25. package/components/filter-bar.d.ts +44 -0
  26. package/components/filter-bar.js +89 -0
  27. package/components/index.d.ts +3 -0
  28. package/components/index.js +526 -513
  29. package/components/input-field.d.ts +1 -1
  30. package/components/input-field.js +24 -22
  31. package/components/modal.js +56 -53
  32. package/components/panel.js +26 -27
  33. package/components/sidebar.js +54 -54
  34. package/components/sparkline.d.ts +30 -0
  35. package/components/sparkline.js +69 -0
  36. package/demo/components/add-to-artifact.js +5 -2
  37. package/examples/README.md +4 -2
  38. package/examples/call-logs-screen.tsx +381 -0
  39. package/examples/campaign-analysis-screen.tsx +114 -72
  40. package/examples/campaigns-screen.tsx +218 -160
  41. package/examples/guardrails-settings-screen.tsx +123 -0
  42. package/fonts/geist-variable.woff2 +0 -0
  43. package/fonts.css +12 -17
  44. package/lib/icons.js +3 -3
  45. package/llms.txt +107 -39
  46. package/manifest.json +3100 -892
  47. package/package.json +1 -1
  48. package/styles.css +102 -59
  49. package/theme.css +81 -37
  50. package/fonts/aribau-grotesk-medium.woff2 +0 -0
  51. package/fonts/aribau-grotesk-regular.woff2 +0 -0
@@ -1,13 +1,13 @@
1
1
  "use client";
2
2
  import { jsx as r, jsxs as c } from "react/jsx-runtime";
3
- import * as n from "react";
3
+ import * as o from "react";
4
4
  import { MotionConfig as j, motion as _ } from "motion/react";
5
5
  import { User as E, PanelLeft as H } from "../lib/icons.js";
6
- import { cn as o } from "../lib/cn.js";
6
+ import { cn as n } from "../lib/cn.js";
7
7
  import { springSidebar as I } from "../lib/motion.js";
8
8
  import { Tooltip as L } from "./tooltip.js";
9
9
  import { Avatar as M } from "./avatar.js";
10
- const z = n.createContext({
10
+ const z = o.createContext({
11
11
  collapsed: !1,
12
12
  toggle: () => {
13
13
  },
@@ -15,9 +15,9 @@ const z = n.createContext({
15
15
  }
16
16
  });
17
17
  function W() {
18
- return n.useContext(z);
18
+ return o.useContext(z);
19
19
  }
20
- const K = n.forwardRef(
20
+ const K = o.forwardRef(
21
21
  ({
22
22
  className: a,
23
23
  collapsed: e,
@@ -27,27 +27,27 @@ const K = n.forwardRef(
27
27
  keyboardToggle: d = !0,
28
28
  ...l
29
29
  }, b) => {
30
- const [g, y] = n.useState(i), f = e !== void 0, u = f ? e : g, m = n.useCallback(
30
+ const [g, y] = o.useState(i), f = e !== void 0, u = f ? e : g, m = o.useCallback(
31
31
  (p) => {
32
32
  f || y(p), t == null || t(p);
33
33
  },
34
34
  [f, t]
35
- ), x = n.useCallback(
35
+ ), v = o.useCallback(
36
36
  () => m(!u),
37
37
  [u, m]
38
38
  );
39
- n.useEffect(() => {
39
+ o.useEffect(() => {
40
40
  if (!d) return;
41
41
  const p = (h) => {
42
- (h.metaKey || h.ctrlKey) && h.key.toLowerCase() === "b" && (h.preventDefault(), x());
42
+ (h.metaKey || h.ctrlKey) && h.key.toLowerCase() === "b" && (h.preventDefault(), v());
43
43
  };
44
44
  return document.addEventListener("keydown", p), () => document.removeEventListener("keydown", p);
45
- }, [d, x]);
46
- const v = n.useMemo(
47
- () => ({ collapsed: u, toggle: x, setCollapsed: m }),
48
- [u, x, m]
45
+ }, [d, v]);
46
+ const x = o.useMemo(
47
+ () => ({ collapsed: u, toggle: v, setCollapsed: m }),
48
+ [u, v, m]
49
49
  );
50
- return /* @__PURE__ */ r(z.Provider, { value: v, children: /* @__PURE__ */ r(j, { reducedMotion: "user", children: /* @__PURE__ */ r(
50
+ return /* @__PURE__ */ r(z.Provider, { value: x, children: /* @__PURE__ */ r(j, { reducedMotion: "user", children: /* @__PURE__ */ r(
51
51
  _.aside,
52
52
  {
53
53
  ref: b,
@@ -63,7 +63,7 @@ const K = n.forwardRef(
63
63
  opacity: 1
64
64
  },
65
65
  transition: I,
66
- className: o(
66
+ className: n(
67
67
  "group/sidebar flex h-full shrink-0 flex-col bg-background",
68
68
  a
69
69
  ),
@@ -103,7 +103,7 @@ function k({
103
103
  onClick: (l) => {
104
104
  e == null || e(l), d();
105
105
  },
106
- className: o(
106
+ className: n(
107
107
  "inline-flex size-(--sidebar-item) shrink-0 items-center justify-center rounded-sm border border-transparent text-muted-foreground",
108
108
  "transition-colors hover:border-border hover:bg-elevated hover:text-foreground",
109
109
  "outline-none focus-visible:ring-3 focus-visible:ring-ring",
@@ -126,8 +126,8 @@ function Z({
126
126
  className: d,
127
127
  ...l
128
128
  }) {
129
- const b = n.isValidElement(a) && a.type === R, g = o(
130
- b ? "flex min-w-0 items-center rounded-m outline-none focus-visible:ring-3 focus-visible:ring-ring" : o(
129
+ const b = o.isValidElement(a) && a.type === R, g = n(
130
+ b ? "flex min-w-0 items-center rounded-m outline-none focus-visible:ring-3 focus-visible:ring-ring" : n(
131
131
  // 20px mark centered in a 32px square — the same box as every other rail icon.
132
132
  // group/brand lets a BrandMark logo play its blip loop on hover.
133
133
  "group/brand flex size-(--sidebar-item) items-center justify-center",
@@ -141,7 +141,7 @@ function Z({
141
141
  return /* @__PURE__ */ c(
142
142
  "div",
143
143
  {
144
- className: o(
144
+ className: n(
145
145
  "flex h-(--sidebar-header) shrink-0 items-center justify-between gap-2 px-4",
146
146
  "group-data-[collapsed=true]/sidebar:justify-center group-data-[collapsed=true]/sidebar:px-2",
147
147
  d
@@ -158,14 +158,14 @@ function Z({
158
158
  }
159
159
  );
160
160
  }
161
- const R = n.forwardRef(
161
+ const R = o.forwardRef(
162
162
  ({ className: a, name: e, logoSrc: i, showName: t = !0, ...s }, d) => {
163
163
  const l = e.trim().charAt(0).toUpperCase();
164
164
  return /* @__PURE__ */ c(
165
165
  "span",
166
166
  {
167
167
  ref: d,
168
- className: o("flex min-w-0 items-center gap-2.5", a),
168
+ className: n("flex min-w-0 items-center gap-2.5", a),
169
169
  ...s,
170
170
  children: [
171
171
  i ? /* @__PURE__ */ r(
@@ -192,12 +192,12 @@ const R = n.forwardRef(
192
192
  }
193
193
  );
194
194
  R.displayName = "SidebarWorkspace";
195
- const q = n.forwardRef(
195
+ const q = o.forwardRef(
196
196
  ({ className: a, ...e }, i) => /* @__PURE__ */ r(
197
197
  "div",
198
198
  {
199
199
  ref: i,
200
- className: o(
200
+ className: n(
201
201
  "flex h-(--sidebar-header) shrink-0 items-center justify-between gap-2 px-3",
202
202
  "group-data-[collapsed=true]/sidebar:justify-center group-data-[collapsed=true]/sidebar:px-2",
203
203
  a
@@ -207,31 +207,31 @@ const q = n.forwardRef(
207
207
  )
208
208
  );
209
209
  q.displayName = "SidebarHeader";
210
- const A = n.forwardRef(
211
- ({ className: a, ...e }, i) => /* @__PURE__ */ r("nav", { ref: i, className: o("min-h-0 flex-1 space-y-5 overflow-y-auto p-3", a), ...e })
210
+ const A = o.forwardRef(
211
+ ({ className: a, ...e }, i) => /* @__PURE__ */ r("nav", { ref: i, className: n("min-h-0 flex-1 space-y-5 overflow-y-auto p-3", a), ...e })
212
212
  );
213
213
  A.displayName = "SidebarNav";
214
- const B = n.forwardRef(
214
+ const B = o.forwardRef(
215
215
  ({ className: a, label: e, children: i, ...t }, s) => /* @__PURE__ */ c("div", { ref: s, className: a, ...t, children: [
216
216
  e && /* @__PURE__ */ r("div", { className: "mb-1.5 px-3 text-s font-normal uppercase leading-4 tracking-wider text-tertiary group-data-[collapsed=true]/sidebar:hidden", children: e }),
217
217
  /* @__PURE__ */ r("div", { className: "flex flex-col gap-0.5 group-data-[collapsed=true]/sidebar:gap-2", children: i })
218
218
  ] })
219
219
  );
220
220
  B.displayName = "SidebarSection";
221
- const D = n.forwardRef(
221
+ const D = o.forwardRef(
222
222
  ({ className: a, icon: e, isActive: i, endContent: t, children: s, title: d, ...l }, b) => /* @__PURE__ */ c(
223
223
  "a",
224
224
  {
225
225
  ref: b,
226
226
  "aria-current": i ? "page" : void 0,
227
227
  title: d ?? (typeof s == "string" ? s : void 0),
228
- className: o(
228
+ className: n(
229
229
  "group/sidebar-item flex h-9 items-center gap-2.5 rounded-md border border-transparent px-3 text-m leading-[var(--text-m--line-height)] font-normal text-sidebar-foreground",
230
- "transition-[background-color,border-color,color] duration-150 ease-out motion-reduce:transition-none",
230
+ "transition-[background-color,border-color,color,box-shadow] duration-150 ease-out motion-reduce:transition-none",
231
231
  "outline-none focus-visible:ring-3 focus-visible:ring-ring",
232
232
  // Collapsed: a centered square (--sidebar-item) so every rail item lines up.
233
233
  "group-data-[collapsed=true]/sidebar:mx-auto group-data-[collapsed=true]/sidebar:size-(--sidebar-item) group-data-[collapsed=true]/sidebar:justify-center group-data-[collapsed=true]/sidebar:p-0",
234
- i ? "bg-sidebar-accent text-sidebar-accent-foreground" : "hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground",
234
+ i ? "bg-sidebar-accent text-sidebar-accent-foreground shadow-nav-active" : "hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground",
235
235
  a
236
236
  ),
237
237
  ...l,
@@ -241,7 +241,7 @@ const D = n.forwardRef(
241
241
  {
242
242
  "aria-hidden": !0,
243
243
  className: "flex shrink-0 items-center justify-center transition-transform duration-150 ease-out group-hover/sidebar-item:scale-110 motion-reduce:transition-none motion-reduce:group-hover/sidebar-item:scale-100 [&_svg]:size-4 [&_svg]:shrink-0",
244
- children: i && n.isValidElement(e) ? n.cloneElement(e, { weight: "fill" }) : e
244
+ children: i && o.isValidElement(e) ? o.cloneElement(e, { weight: "fill" }) : e
245
245
  }
246
246
  ),
247
247
  /* @__PURE__ */ r("span", { className: "min-w-0 flex-1 truncate group-data-[collapsed=true]/sidebar:hidden", children: s }),
@@ -251,24 +251,24 @@ const D = n.forwardRef(
251
251
  )
252
252
  );
253
253
  D.displayName = "SidebarItem";
254
- const F = n.forwardRef(
254
+ const F = o.forwardRef(
255
255
  ({ className: a, ...e }, i) => /* @__PURE__ */ r(
256
256
  "div",
257
257
  {
258
258
  ref: i,
259
- className: o("shrink-0 p-3 group-data-[collapsed=true]/sidebar:px-2", a),
259
+ className: n("shrink-0 p-3 group-data-[collapsed=true]/sidebar:px-2", a),
260
260
  ...e
261
261
  }
262
262
  )
263
263
  );
264
264
  F.displayName = "SidebarFooter";
265
- const U = n.forwardRef(
265
+ const U = o.forwardRef(
266
266
  ({ className: a, icon: e, children: i, ...t }, s) => /* @__PURE__ */ r("div", { className: "px-3 pb-0.5 group-data-[collapsed=true]/sidebar:px-2", children: /* @__PURE__ */ c(
267
267
  "button",
268
268
  {
269
269
  ref: s,
270
270
  type: "button",
271
- className: o(
271
+ className: n(
272
272
  "flex h-9 w-full items-center justify-start gap-2 rounded-md px-3",
273
273
  "text-m leading-[var(--text-m--line-height)] font-normal text-sidebar-foreground",
274
274
  // Reads as a normal nav item: transparent at rest, the shared White
@@ -289,12 +289,12 @@ const U = n.forwardRef(
289
289
  ) })
290
290
  );
291
291
  U.displayName = "SidebarAction";
292
- const V = n.forwardRef(
292
+ const V = o.forwardRef(
293
293
  ({ className: a, label: e, children: i, ...t }, s) => /* @__PURE__ */ c(
294
294
  "div",
295
295
  {
296
296
  ref: s,
297
- className: o("group-data-[collapsed=true]/sidebar:hidden", a),
297
+ className: n("group-data-[collapsed=true]/sidebar:hidden", a),
298
298
  ...t,
299
299
  children: [
300
300
  e && /* @__PURE__ */ r("div", { className: "mb-1.5 px-3 text-s font-normal uppercase leading-4 tracking-wider text-tertiary", children: e }),
@@ -304,27 +304,27 @@ const V = n.forwardRef(
304
304
  )
305
305
  );
306
306
  V.displayName = "SidebarHistory";
307
- const $ = n.forwardRef(({ className: a, children: e, title: i, action: t, isActive: s, icon: d, ...l }, b) => {
308
- const g = n.useRef(null), y = n.useRef(null), [f, u] = n.useState(0);
309
- n.useLayoutEffect(() => {
310
- const v = g.current, p = y.current;
311
- if (!v || !p) return;
307
+ const $ = o.forwardRef(({ className: a, children: e, title: i, action: t, isActive: s, icon: d, ...l }, b) => {
308
+ const g = o.useRef(null), y = o.useRef(null), [f, u] = o.useState(0);
309
+ o.useLayoutEffect(() => {
310
+ const x = g.current, p = y.current;
311
+ if (!x || !p) return;
312
312
  const h = () => {
313
- const w = p.scrollWidth - v.clientWidth;
313
+ const w = p.scrollWidth - x.clientWidth;
314
314
  u(w > 0 ? w + (t ? 32 : 0) : 0);
315
315
  };
316
316
  h();
317
317
  const N = new ResizeObserver(h);
318
- return N.observe(v), N.observe(p), () => N.disconnect();
318
+ return N.observe(x), N.observe(p), () => N.disconnect();
319
319
  }, [e, t]);
320
- const m = f > 0, x = Math.max(500, Math.round(f * 18));
320
+ const m = f > 0, v = Math.max(500, Math.round(f * 18));
321
321
  return /* @__PURE__ */ c(
322
322
  "div",
323
323
  {
324
- className: o(
324
+ className: n(
325
325
  "group/hist relative flex items-center rounded-md transition-colors",
326
326
  "text-sidebar-foreground",
327
- s ? "bg-sidebar-accent text-sidebar-accent-foreground" : "hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground"
327
+ s ? "bg-sidebar-accent text-sidebar-accent-foreground shadow-nav-active" : "hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground"
328
328
  ),
329
329
  children: [
330
330
  d && /* @__PURE__ */ r(
@@ -340,7 +340,7 @@ const $ = n.forwardRef(({ className: a, children: e, title: i, action: t, isActi
340
340
  {
341
341
  ref: b,
342
342
  title: i ?? (typeof e == "string" ? e : void 0),
343
- className: o(
343
+ className: n(
344
344
  // Left pad matches a SidebarItem's text column (px-3 + icon size-4 +
345
345
  // gap-2.5 = 2.375rem) so history titles line up under the nav labels.
346
346
  "block min-w-0 flex-1 rounded-md py-1.5 pr-3 ps-(--sidebar-text-indent) text-m leading-[var(--text-m--line-height)] font-normal",
@@ -352,7 +352,7 @@ const $ = n.forwardRef(({ className: a, children: e, title: i, action: t, isActi
352
352
  "span",
353
353
  {
354
354
  ref: g,
355
- className: o(
355
+ className: n(
356
356
  "block overflow-hidden",
357
357
  // Rest: fade the right edge (no ellipsis). Hover: the title scrolls,
358
358
  // so fade the LEFT edge where it exits; the action backdrop (or the
@@ -364,14 +364,14 @@ const $ = n.forwardRef(({ className: a, children: e, title: i, action: t, isActi
364
364
  "span",
365
365
  {
366
366
  ref: y,
367
- className: o(
367
+ className: n(
368
368
  "block w-max whitespace-nowrap transition-transform ease-linear",
369
369
  m && "group-hover/hist:[transform:translateX(var(--mq-x))]",
370
370
  "motion-reduce:transition-none motion-reduce:group-hover/hist:[transform:none]"
371
371
  ),
372
372
  style: {
373
373
  "--mq-x": `-${f}px`,
374
- transitionDuration: `${x}ms`
374
+ transitionDuration: `${v}ms`
375
375
  },
376
376
  children: e
377
377
  }
@@ -383,7 +383,7 @@ const $ = n.forwardRef(({ className: a, children: e, title: i, action: t, isActi
383
383
  t && /* @__PURE__ */ r(
384
384
  "span",
385
385
  {
386
- className: o(
386
+ className: n(
387
387
  // Rounded end matches the row's radius so the backdrop doesn't
388
388
  // square off the highlight's right corners.
389
389
  "absolute inset-y-0 right-0 flex items-center rounded-e-md pl-8 pr-1",
@@ -401,12 +401,12 @@ const $ = n.forwardRef(({ className: a, children: e, title: i, action: t, isActi
401
401
  );
402
402
  });
403
403
  $.displayName = "SidebarHistoryItem";
404
- const O = n.forwardRef(
404
+ const O = o.forwardRef(
405
405
  ({ className: a, name: e, role: i, src: t, hideAvatar: s, ...d }, l) => /* @__PURE__ */ c(
406
406
  "a",
407
407
  {
408
408
  ref: l,
409
- className: o(
409
+ className: n(
410
410
  "flex items-center gap-2.5 rounded-md border border-transparent p-2 transition-colors hover:border-wg10",
411
411
  "outline-none focus-visible:ring-3 focus-visible:ring-ring",
412
412
  "group-data-[collapsed=true]/sidebar:mx-auto group-data-[collapsed=true]/sidebar:size-(--sidebar-item) group-data-[collapsed=true]/sidebar:justify-center group-data-[collapsed=true]/sidebar:p-0",
@@ -0,0 +1,30 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Sparkline — a tiny, axis-less trend line for a stat card (principle
4
+ * `analytics-surfaces`, user-mandated 2026-11-14).
5
+ *
6
+ * It draws one series in a chart-palette colour: a 2px line, a wash under it
7
+ * that fades top-to-bottom from 20% of the colour to nothing (the same wash
8
+ * `LineChart` carries), and a dot on the latest value. There are no axes,
9
+ * gridlines, labels or tooltip — the stat card's number is the value; the
10
+ * sparkline only says which way it has been moving. It fills its container's
11
+ * width; give it a height.
12
+ *
13
+ * Use it inside a resting stat card, beside the number, or in a table's
14
+ * "Last 7 days" column at `height={28}` with `dot={false}` (principle
15
+ * `collection-screens`). For a trend people read values from, use `LineChart`.
16
+ */
17
+ export type SparklineColor = 1 | 2 | 3 | 4 | 5 | 6;
18
+ export interface SparklineProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "color"> {
19
+ /** The series, oldest first. Needs at least two values to draw. */
20
+ data: number[];
21
+ /** Which `chart-1…6` series colour to draw in. @default 1 */
22
+ color?: SparklineColor;
23
+ /** Height in px. @default 48 */
24
+ height?: number;
25
+ /** Mark the latest value with a round dot. Turn off in table cells. @default true */
26
+ dot?: boolean;
27
+ /** Accessible summary of the trend, e.g. "Calls analysed rising over 7 days". */
28
+ label: string;
29
+ }
30
+ export declare const Sparkline: React.ForwardRefExoticComponent<SparklineProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,69 @@
1
+ "use client";
2
+ import { jsxs as c, jsx as o } from "react/jsx-runtime";
3
+ import * as u from "react";
4
+ import { cn as j } from "../lib/cn.js";
5
+ const r = 100, m = 4, z = u.forwardRef(
6
+ ({ className: $, data: k, color: h = 1, height: e = 48, dot: v = !0, label: x, style: b, ...y }, g) => {
7
+ const d = u.useId().replace(/[^a-zA-Z0-9]/g, ""), n = `var(--color-chart-${h})`, s = k.filter((a) => Number.isFinite(a)), p = Math.min(...s), w = Math.max(...s) - p || 1, t = s.map((a, i) => [
8
+ s.length > 1 ? i / (s.length - 1) * r : r,
9
+ m + (e - 2 * m) * (1 - (a - p) / w)
10
+ ]), f = t.map(([a, i], N) => `${N === 0 ? "M" : "L"}${a.toFixed(2)},${i.toFixed(2)}`).join(" "), L = t.length > 1 ? `${f} L${r},${e} L0,${e} Z` : "", l = t[t.length - 1];
11
+ return /* @__PURE__ */ c(
12
+ "div",
13
+ {
14
+ ref: g,
15
+ "data-slot": "sparkline",
16
+ role: "img",
17
+ "aria-label": x,
18
+ className: j("relative w-full", $),
19
+ style: { height: e, ...b },
20
+ ...y,
21
+ children: [
22
+ t.length > 1 && /* @__PURE__ */ c(
23
+ "svg",
24
+ {
25
+ "aria-hidden": !0,
26
+ className: "absolute inset-0 size-full overflow-visible",
27
+ viewBox: `0 0 ${r} ${e}`,
28
+ preserveAspectRatio: "none",
29
+ children: [
30
+ /* @__PURE__ */ o("defs", { children: /* @__PURE__ */ c("linearGradient", { id: `${d}-wash`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
31
+ /* @__PURE__ */ o("stop", { offset: "0%", stopColor: n, stopOpacity: 0.2 }),
32
+ /* @__PURE__ */ o("stop", { offset: "100%", stopColor: n, stopOpacity: 0 })
33
+ ] }) }),
34
+ /* @__PURE__ */ o("path", { "data-slot": "sparkline-area", d: L, fill: `url(#${d}-wash)`, stroke: "none" }),
35
+ /* @__PURE__ */ o(
36
+ "path",
37
+ {
38
+ "data-slot": "sparkline-line",
39
+ d: f,
40
+ fill: "none",
41
+ stroke: n,
42
+ strokeWidth: 2,
43
+ strokeLinecap: "round",
44
+ strokeLinejoin: "round",
45
+ vectorEffect: "non-scaling-stroke"
46
+ }
47
+ )
48
+ ]
49
+ }
50
+ ),
51
+ v && l && t.length > 1 && // The end dot is HTML so it stays round while the SVG stretches.
52
+ /* @__PURE__ */ o(
53
+ "span",
54
+ {
55
+ "aria-hidden": !0,
56
+ "data-slot": "sparkline-dot",
57
+ className: "absolute size-2 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-card",
58
+ style: { left: `${l[0] / r * 100}%`, top: `${l[1] / e * 100}%`, background: n }
59
+ }
60
+ )
61
+ ]
62
+ }
63
+ );
64
+ }
65
+ );
66
+ z.displayName = "Sparkline";
67
+ export {
68
+ z as Sparkline
69
+ };
@@ -36,6 +36,7 @@ import "../../components/autocomplete.js";
36
36
  import "../../components/slider.js";
37
37
  import "../../components/segmented.js";
38
38
  import "../../components/filters.js";
39
+ import "../../components/filter-bar.js";
39
40
  import { Modal as q, ModalHeader as J, ModalTitle as Q, ModalBody as x, ModalFooter as g } from "../../components/modal.js";
40
41
  import "../../components/drawer.js";
41
42
  import "../../components/popover.js";
@@ -56,6 +57,8 @@ import "../../components/avatar.js";
56
57
  import "../../components/badge.js";
57
58
  import "../../components/chip.js";
58
59
  import "../../components/timeline.js";
60
+ import "../../components/detail-list.js";
61
+ import "../../components/sparkline.js";
59
62
  import "../../components/alert.js";
60
63
  import "../../components/surface-loader.js";
61
64
  import "../../components/pixel-blast-svg.js";
@@ -107,7 +110,7 @@ import "../../components/assistant-ui/quote.js";
107
110
  import "../../components/assistant-ui/sources.js";
108
111
  import "../../components/assistant-ui/tool-fallback.js";
109
112
  import "../../components/assistant-ui/tool-group.js";
110
- function ii({
113
+ function ni({
111
114
  block: i,
112
115
  trigger: v = "button",
113
116
  className: A,
@@ -359,5 +362,5 @@ function ii({
359
362
  ] });
360
363
  }
361
364
  export {
362
- ii as AddToArtifact
365
+ ni as AddToArtifact
363
366
  };
@@ -13,8 +13,10 @@ root in `MotionConfig`, `ToastProvider` and `TooltipProvider`.
13
13
  | `agents-screen.tsx` | `AgentsScreen` | A full list page: `PageHeader` with a primary action, a summary strip, `Tabs` with counts leading a `SearchDisclosure`, a filter `Dropdown`, a sortable `Table` with clickable rows and a pinned action column, per-row actions with `Tooltip`s, and filtered `EmptyState`s. |
14
14
  | `settings-screen.tsx` | `SettingsScreen` | A settings card: `Card` header with a status `Badge`, an `InputField`, a `SettingList` of `SettingRow`s with `Switch` and `Button` controls, and one primary action. |
15
15
  | `workspace-header.tsx` | `WorkspaceHeaderScreen` | A page header with a status `Badge` and trailing actions, then `Tabs` with counts whose panels hold `Card`s. |
16
- | `campaigns-screen.tsx` | `CampaignsScreen` | The collection-screen recipe: `BodyPageHeader` with one primary action, counted `Tabs` leading `SearchDisclosure` + `Filters`, a multi-select `Table` (hover-revealed checkboxes, cohort child rows, `isActive` open row) whose page size fills the panel with `Pagination` at the bottom, a shell-level `Drawer` with status under the title and Performance / Details sections, and the fixed-height New campaign `Modal`. |
17
- | `campaign-analysis-screen.tsx` | `CampaignAnalysisScreen` | The record-analytics recipe: a 16px `Breadcrumbs` title with the primary action on the same row, record `Tabs`, outlined stat cards with `Progress`, and outlined `BarChart` / `LineChart` cards with header legends and printed values. |
16
+ | `campaigns-screen.tsx` | `CampaignsScreen` | The collection-screen recipe: `BodyPageHeader` with one primary action, counted `Tabs` leading `SearchDisclosure` + `Filters`, a multi-select `Table` (hover-revealed checkboxes, cohort child rows, `isActive` open row) whose page size fills the panel with `Pagination` at the bottom, a shell-level `Drawer` with status under the title and Performance / Details sections, and the fixed-height New campaign `Modal` (`NewCampaignModal`: `Field info` for optional guidance, `Field actions` for the source switch, inline `FileDropzone`, single-select `Table` of saved audiences). |
17
+ | `call-logs-screen.tsx` | `CallLogsScreen`, `CallPanel` | The record-call-logs recipe: a campaign's Call logs tab titled by `Breadcrumbs` (status in `meta`, Test call + Launch in `actions`), a `Table` of calls (Number · plain-chip Status · Outcome · Duration) that fills the panel, and a footer-less call panel — grounded `DrawerHeader`, scrolling `DrawerSection`s (Summary, Recording, Transcript, Follow-ups, CRM write-back, Captured fields) with `DetailList` attributes and a collapsed Call metadata. |
18
+ | `guardrails-settings-screen.tsx` | `GuardrailsSettingsScreen` | The settings-screen recipe: `BodyPageHeader` with one save action and full-width setting groups (16px title over a `SettingList` of `SettingRow`s with Switch / value Button / Badge controls). |
19
+ | `campaign-analysis-screen.tsx` | `CampaignAnalysisScreen` | The record-analytics recipe: an 18px `Breadcrumbs` title with the primary action on the same row, record `Tabs`, outlined stat cards with `Progress`, and outlined `BarChart` / `LineChart` cards with header legends and printed values. |
18
20
 
19
21
  ```tsx
20
22
  // app/agents/page.tsx