@actioneer/ads 0.5.3 → 0.5.5

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 (95) hide show
  1. package/components/accordion.js +15 -15
  2. package/components/agent-icon.d.ts +64 -0
  3. package/components/agent-icon.js +251 -0
  4. package/components/ai-elements/agent-trace.d.ts +8 -1
  5. package/components/ai-elements/agent-trace.js +164 -129
  6. package/components/ai-elements/chain-of-thought-icon.d.ts +42 -0
  7. package/components/ai-elements/chain-of-thought-icon.js +283 -0
  8. package/components/ai-elements/chain-of-thought.js +7 -7
  9. package/components/ai-elements/chart.js +38 -35
  10. package/components/ai-elements/index.d.ts +1 -0
  11. package/components/ai-elements/inline-citation.js +40 -40
  12. package/components/ai-elements/message.js +5 -5
  13. package/components/ai-elements/queue.js +1 -1
  14. package/components/ai-elements/research-activity.d.ts +2 -0
  15. package/components/ai-elements/research-activity.js +79 -81
  16. package/components/ai-elements/task-progress.js +2 -2
  17. package/components/ai-elements/tool.d.ts +4 -2
  18. package/components/ai-elements/tool.js +74 -54
  19. package/components/ai-elements/transcript.js +1 -1
  20. package/components/alert.js +1 -1
  21. package/components/answer.d.ts +2643 -311
  22. package/components/answer.js +1836 -425
  23. package/components/assistant-ui/answer-tool-ui.js +23 -28
  24. package/components/assistant-ui/chain-of-thought.d.ts +7 -2
  25. package/components/assistant-ui/composer-harness.js +20 -16
  26. package/components/assistant-ui/reasoning.js +35 -31
  27. package/components/assistant-ui/tool-fallback.js +125 -122
  28. package/components/assistant-ui/tool-group.d.ts +3 -1
  29. package/components/assistant-ui/tool-group.js +48 -43
  30. package/components/audio-waveform.js +14 -14
  31. package/components/autocomplete.js +52 -48
  32. package/components/avatar.js +58 -44
  33. package/components/badge.js +3 -3
  34. package/components/brand-texture.js +1 -1
  35. package/components/breadcrumbs.d.ts +27 -1
  36. package/components/breadcrumbs.js +94 -42
  37. package/components/button.js +15 -15
  38. package/components/carousel.js +10 -10
  39. package/components/chart.d.ts +14 -0
  40. package/components/chart.js +747 -614
  41. package/components/chip.js +3 -3
  42. package/components/code-block.d.ts +39 -17
  43. package/components/code-block.js +153 -104
  44. package/components/command-palette.js +27 -25
  45. package/components/connector-card.js +2 -2
  46. package/components/dropdown.js +65 -61
  47. package/components/empty-state.js +15 -15
  48. package/components/field.js +23 -23
  49. package/components/index.d.ts +5 -0
  50. package/components/index.js +523 -470
  51. package/components/infinite-canvas.js +60 -60
  52. package/components/kbd.js +6 -6
  53. package/components/link.js +6 -6
  54. package/components/modal.js +22 -20
  55. package/components/page-header.js +1 -1
  56. package/components/pagination.js +22 -22
  57. package/components/pixel-blast-svg.js +1 -1
  58. package/components/pixel-icon.d.ts +31 -0
  59. package/components/pixel-icon.js +733 -0
  60. package/components/popover.js +46 -42
  61. package/components/ripple.d.ts +29 -0
  62. package/components/ripple.js +17 -0
  63. package/components/segmented.js +24 -23
  64. package/components/select.js +71 -67
  65. package/components/selection-action-bar.js +22 -22
  66. package/components/sidebar.d.ts +11 -3
  67. package/components/sidebar.js +161 -148
  68. package/components/stepper.d.ts +2 -0
  69. package/components/stepper.js +80 -43
  70. package/components/table.d.ts +7 -0
  71. package/components/table.js +223 -155
  72. package/components/tabs.d.ts +3 -1
  73. package/components/tabs.js +165 -144
  74. package/components/textarea.js +10 -8
  75. package/components/toast.js +48 -46
  76. package/components/tooltip.js +61 -59
  77. package/components/tree.js +44 -41
  78. package/components/typography.d.ts +1 -1
  79. package/components/typography.js +25 -25
  80. package/components/viz-charts.d.ts +62 -0
  81. package/components/viz-charts.js +408 -0
  82. package/fonts/aribau-grotesk-500.otf +0 -0
  83. package/fonts/aribau-grotesk-600.woff2 +0 -0
  84. package/fonts.css +6 -4
  85. package/lib/icons.d.ts +411 -402
  86. package/lib/icons.js +109 -107
  87. package/lib/viz-format.d.ts +25 -0
  88. package/lib/viz-format.js +40 -0
  89. package/llms.txt +111 -8
  90. package/manifest.json +1096 -58
  91. package/package.json +5 -5
  92. package/styles.css +226 -96
  93. package/theme.css +220 -92
  94. package/fonts/aribau-grotesk-400.otf +0 -0
  95. package/fonts/aribau-grotesk-700.otf +0 -0
@@ -0,0 +1,62 @@
1
+ import * as React from "react";
2
+ export interface VizSeries {
3
+ name: string;
4
+ /** Omit to take the palette color for its index. */
5
+ color?: string;
6
+ values: number[];
7
+ /** Render dashed — a 2nd+ event line, not the primary. */
8
+ dashed?: boolean;
9
+ /** Faded dashed ghost — a "previous period" compare series. */
10
+ ghost?: boolean;
11
+ }
12
+ export interface SeriesChartProps {
13
+ type?: "line" | "area" | "bar";
14
+ labels: string[];
15
+ series: VizSeries[];
16
+ height?: number;
17
+ /** Formatter for the value axis + tooltip; defaults to abbr / commafy. */
18
+ formatAxis?: (v: number) => string;
19
+ formatValue?: (v: number) => string;
20
+ className?: string;
21
+ }
22
+ export declare function SeriesChart({ type, labels, series, height, formatAxis, formatValue, className, }: SeriesChartProps): React.JSX.Element;
23
+ export interface FunnelStep {
24
+ label: string;
25
+ value: number;
26
+ /** Median seconds from the previous step. */
27
+ medianTime?: number | null;
28
+ avgTime?: number | null;
29
+ }
30
+ export interface FunnelVizProps {
31
+ steps: FunnelStep[];
32
+ height?: number;
33
+ className?: string;
34
+ }
35
+ export declare function FunnelViz({ steps, height, className }: FunnelVizProps): React.JSX.Element;
36
+ export interface FunnelBarsHorizontalProps {
37
+ steps: FunnelStep[];
38
+ className?: string;
39
+ }
40
+ export declare function FunnelBarsHorizontal({ steps, className }: FunnelBarsHorizontalProps): React.JSX.Element;
41
+ export interface RetentionPoint {
42
+ label: string;
43
+ v: number;
44
+ }
45
+ export interface RetentionCurveProps {
46
+ points: RetentionPoint[];
47
+ height?: number;
48
+ className?: string;
49
+ }
50
+ export declare function RetentionCurve({ points, height, className }: RetentionCurveProps): React.JSX.Element;
51
+ export interface RetentionCohort {
52
+ label: string;
53
+ size: number;
54
+ /** One per column; null = period not yet elapsed. */
55
+ values: (number | null)[];
56
+ }
57
+ export interface RetentionGridProps {
58
+ cols: string[];
59
+ cohorts: RetentionCohort[];
60
+ className?: string;
61
+ }
62
+ export declare function RetentionGrid({ cols, cohorts, className }: RetentionGridProps): React.JSX.Element;
@@ -0,0 +1,408 @@
1
+ "use client";
2
+ import { jsx as a, jsxs as c, Fragment as J } from "react/jsx-runtime";
3
+ import * as $ from "react";
4
+ import { cn as D } from "../lib/cn.js";
5
+ import { fmtDuration as B, pct1 as z, abbr as V, commafy as H } from "../lib/viz-format.js";
6
+ const G = [
7
+ "var(--color-chart-1)",
8
+ "var(--color-chart-2)",
9
+ "var(--color-chart-3)",
10
+ "var(--color-chart-4)",
11
+ "var(--color-chart-5)",
12
+ "var(--color-chart-6)"
13
+ ], O = (e) => G[e % G.length], A = "var(--color-chart-1)", E = "var(--color-ink-400)", U = "var(--border)", Q = "var(--foreground)";
14
+ function Y(e, s = 4) {
15
+ if (e <= 0) return { max: 1, ticks: [0, 1] };
16
+ const d = e / s, i = Math.pow(10, Math.floor(Math.log10(d))), o = ([1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10].find((w) => w * i >= d) ?? 10) * i, l = Math.ceil(e / o) * o, y = [];
17
+ for (let w = 0; w <= l + o / 1e6; w += o) y.push(w);
18
+ return { max: l, ticks: y };
19
+ }
20
+ function Z(e, s = 8) {
21
+ if (e.length <= s) return e;
22
+ const d = Math.ceil(e.length / s);
23
+ return e.map((i, u) => u % d === 0 || u === e.length - 1 ? i : null);
24
+ }
25
+ function P(e) {
26
+ if (!e.length) return "";
27
+ if (e.length === 1) return `M${e[0][0]},${e[0][1]}`;
28
+ let s = `M${e[0][0]},${e[0][1]}`;
29
+ for (let d = 1; d < e.length; d++) {
30
+ const [i, u] = e[d - 1], [o, l] = e[d], y = (i + o) / 2;
31
+ s += `C${y},${u} ${y},${l} ${o},${l}`;
32
+ }
33
+ return s;
34
+ }
35
+ function _({
36
+ x: e,
37
+ y: s,
38
+ title: d,
39
+ rows: i,
40
+ flip: u
41
+ }) {
42
+ return /* @__PURE__ */ c(
43
+ "div",
44
+ {
45
+ className: "pointer-events-none absolute z-10 min-w-[184px] max-w-[248px] rounded-lg bg-foreground px-3 py-2.5 text-background shadow-elevation",
46
+ style: {
47
+ left: e,
48
+ top: s,
49
+ transform: `translate(${u ? "calc(-100% - 12px)" : "12px"}, -50%)`
50
+ },
51
+ children: [
52
+ /* @__PURE__ */ a("div", { className: "mb-1.5 text-xs text-background/60", children: d }),
53
+ /* @__PURE__ */ a("div", { className: "flex flex-col gap-1", children: i.map((o, l) => /* @__PURE__ */ c("div", { className: "flex items-center gap-2 text-xs", children: [
54
+ o.dashed ? /* @__PURE__ */ a(
55
+ "span",
56
+ {
57
+ "aria-hidden": !0,
58
+ className: "h-0 w-3 shrink-0 border-t border-dashed",
59
+ style: { borderColor: o.swatch ?? "currentColor" }
60
+ }
61
+ ) : o.swatch ? /* @__PURE__ */ a("span", { "aria-hidden": !0, className: "size-2 shrink-0 rounded-dot", style: { background: o.swatch } }) : null,
62
+ /* @__PURE__ */ a("span", { className: "min-w-0 flex-1 truncate text-background/70", children: o.label }),
63
+ /* @__PURE__ */ a("span", { className: "shrink-0 font-medium tabular-nums", children: o.value })
64
+ ] }, l)) })
65
+ ]
66
+ }
67
+ );
68
+ }
69
+ function ee({
70
+ items: e
71
+ }) {
72
+ return /* @__PURE__ */ a("div", { className: "mb-3 flex flex-wrap items-center justify-end gap-x-4 gap-y-1", children: e.map((s) => /* @__PURE__ */ c("span", { className: "inline-flex items-center gap-1.5 text-xs text-secondary", children: [
73
+ /* @__PURE__ */ a(
74
+ "span",
75
+ {
76
+ "aria-hidden": !0,
77
+ className: D("h-0 w-4 shrink-0", s.dashed ? "border-t-2 border-dashed" : "border-t-[3px]"),
78
+ style: { borderColor: s.color }
79
+ }
80
+ ),
81
+ s.label
82
+ ] }, s.label)) });
83
+ }
84
+ const b = { l: 56, r: 18, t: 18, b: 34 };
85
+ function ne({
86
+ type: e = "line",
87
+ labels: s,
88
+ series: d,
89
+ height: i = 300,
90
+ formatAxis: u = V,
91
+ formatValue: o = H,
92
+ className: l
93
+ }) {
94
+ const [y, w] = $.useState(720), N = $.useRef(null);
95
+ $.useEffect(() => {
96
+ if (!N.current) return;
97
+ const t = new ResizeObserver(([x]) => w(x.contentRect.width));
98
+ return t.observe(N.current), () => t.disconnect();
99
+ }, []);
100
+ const [h, f] = $.useState(null), m = Math.max(0, y - b.l - b.r), M = Math.max(0, i - b.t - b.b), r = d.filter((t) => !t.ghost), { max: n, ticks: p } = Y(Math.max(1, ...d.flatMap((t) => t.values))), k = (t) => b.t + M - t / n * M, R = s.length, v = (t) => e === "bar" ? b.l + (t + 0.5) / R * m : b.l + (R <= 1 ? m / 2 : t / (R - 1) * m), j = [...p].reverse(), C = r.map((t, x) => ({ label: t.name, color: t.color ?? O(x), dashed: t.dashed }));
101
+ return /* @__PURE__ */ c("div", { ref: N, className: D("relative w-full font-sans", l), children: [
102
+ C.length > 1 && /* @__PURE__ */ a(ee, { items: C }),
103
+ /* @__PURE__ */ c(
104
+ "svg",
105
+ {
106
+ width: y,
107
+ height: i,
108
+ className: "block select-none",
109
+ onMouseLeave: () => f(null),
110
+ onMouseMove: (t) => {
111
+ const x = t.currentTarget.getBoundingClientRect(), T = t.clientX - x.left, L = Math.round((T - b.l) / m * (R - 1));
112
+ f(Math.max(0, Math.min(R - 1, L)));
113
+ },
114
+ children: [
115
+ j.map((t, x) => /* @__PURE__ */ c("g", { children: [
116
+ /* @__PURE__ */ a(
117
+ "line",
118
+ {
119
+ x1: b.l,
120
+ x2: b.l + m,
121
+ y1: k(t),
122
+ y2: k(t),
123
+ stroke: U,
124
+ strokeWidth: 1,
125
+ strokeDasharray: t === 0 ? void 0 : "3 4",
126
+ opacity: t === 0 ? 0.9 : 0.6
127
+ }
128
+ ),
129
+ /* @__PURE__ */ a("text", { x: b.l - 10, y: k(t), dy: "0.32em", textAnchor: "end", className: "fill-tertiary text-[11px] tabular-nums", children: u(t) })
130
+ ] }, x)),
131
+ Z(s).map(
132
+ (t, x) => t == null ? null : /* @__PURE__ */ a("text", { x: v(x), y: i - 12, textAnchor: "middle", className: "fill-tertiary text-[11px] tabular-nums", children: t }, x)
133
+ ),
134
+ e === "bar" && r.map((t, x) => {
135
+ const T = m / R, L = Math.min(T * 0.7, 64), F = (L - (r.length - 1)) / r.length;
136
+ return t.values.map((I, S) => {
137
+ const K = b.l + S * T + (T - L) / 2 + x * (F + 1), q = h != null && h !== S;
138
+ return /* @__PURE__ */ a(
139
+ "rect",
140
+ {
141
+ x: K,
142
+ y: k(I),
143
+ width: Math.max(0, F),
144
+ height: b.t + M - k(I),
145
+ rx: 2,
146
+ fill: t.color ?? O(x),
147
+ opacity: q ? 0.4 : 1
148
+ },
149
+ `${x}-${S}`
150
+ );
151
+ });
152
+ }),
153
+ e === "area" && r[0] && /* @__PURE__ */ a(
154
+ "path",
155
+ {
156
+ d: `${P(r[0].values.map((t, x) => [v(x), k(t)]))} L${v(R - 1)},${k(0)} L${v(0)},${k(0)} Z`,
157
+ fill: r[0].color ?? O(0),
158
+ opacity: 0.12
159
+ }
160
+ ),
161
+ e !== "bar" && d.map((t, x) => {
162
+ const T = t.color ?? O(r.indexOf(t)), L = t.ghost ? "2 4" : t.dashed ? "6 5" : void 0, F = t.ghost ? 1.75 : x === 0 ? 2.5 : 2;
163
+ return /* @__PURE__ */ a(
164
+ "path",
165
+ {
166
+ d: P(t.values.map((I, S) => [v(S), k(I)])),
167
+ fill: "none",
168
+ stroke: T,
169
+ strokeWidth: F,
170
+ strokeDasharray: L,
171
+ strokeLinecap: "round",
172
+ strokeLinejoin: "round",
173
+ opacity: t.ghost ? 0.4 : 1
174
+ },
175
+ x
176
+ );
177
+ }),
178
+ h != null && e !== "bar" && /* @__PURE__ */ c(J, { children: [
179
+ /* @__PURE__ */ a("line", { x1: v(h), x2: v(h), y1: b.t, y2: b.t + M, stroke: Q, strokeWidth: 1, opacity: 0.18 }),
180
+ r.map((t, x) => /* @__PURE__ */ a(
181
+ "circle",
182
+ {
183
+ cx: v(h),
184
+ cy: k(t.values[h]),
185
+ r: 4.5,
186
+ fill: t.color ?? O(x),
187
+ stroke: "var(--card)",
188
+ strokeWidth: 2
189
+ },
190
+ x
191
+ ))
192
+ ] })
193
+ ]
194
+ }
195
+ ),
196
+ h != null && /* @__PURE__ */ a(
197
+ _,
198
+ {
199
+ x: v(h),
200
+ y: b.t + M / 2,
201
+ flip: v(h) > b.l + m * 0.66,
202
+ title: s[h],
203
+ rows: d.map((t) => ({
204
+ swatch: t.color ?? O(r.indexOf(t)),
205
+ dashed: t.ghost,
206
+ label: t.name,
207
+ value: o(t.values[h])
208
+ }))
209
+ }
210
+ )
211
+ ] });
212
+ }
213
+ const g = { l: 22, r: 16, t: 28, b: 98 }, X = "viz-funnel-hatch";
214
+ function oe({ steps: e, height: s = 320, className: d }) {
215
+ var r;
216
+ const [i, u] = $.useState(720), o = $.useRef(null);
217
+ $.useEffect(() => {
218
+ if (!o.current) return;
219
+ const n = new ResizeObserver(([p]) => u(p.contentRect.width));
220
+ return n.observe(o.current), () => n.disconnect();
221
+ }, []);
222
+ const [l, y] = $.useState(null), w = Math.max(0, i - g.l - g.r), N = Math.max(0, s - g.t - g.b), h = ((r = e[0]) == null ? void 0 : r.value) || 1, f = (n) => g.t + N - n * N, m = w / Math.max(1, e.length), M = Math.min(m * 0.56, 120);
223
+ return /* @__PURE__ */ c("div", { ref: o, className: D("relative w-full font-sans", d), children: [
224
+ /* @__PURE__ */ c("svg", { width: i, height: s, className: "block select-none", children: [
225
+ /* @__PURE__ */ a("defs", { children: /* @__PURE__ */ c("pattern", { id: X, width: 6, height: 6, patternTransform: "rotate(45)", patternUnits: "userSpaceOnUse", children: [
226
+ /* @__PURE__ */ a("rect", { width: 6, height: 6, fill: E, opacity: 0.07 }),
227
+ /* @__PURE__ */ a("line", { x1: 0, y1: 0, x2: 0, y2: 6, stroke: E, strokeWidth: 2.5, opacity: 0.22 })
228
+ ] }) }),
229
+ [1, 0.75, 0.5, 0.25, 0].map((n) => /* @__PURE__ */ c("g", { children: [
230
+ /* @__PURE__ */ a("line", { x1: g.l, x2: g.l + w, y1: f(n), y2: f(n), stroke: U, strokeWidth: 1, strokeDasharray: n === 0 ? void 0 : "3 4", opacity: n === 0 ? 0.9 : 0.6 }),
231
+ /* @__PURE__ */ a("text", { x: g.l, y: f(n) - 4, className: "fill-tertiary text-[10px] tabular-nums", children: n * 100 })
232
+ ] }, n)),
233
+ e.map((n, p) => {
234
+ const k = n.value / h, R = p === 0 ? 1 : e[p - 1].value / h, v = g.l + p * m + m / 2, j = v - M / 2, C = f(k), t = l != null && l !== p;
235
+ return /* @__PURE__ */ c("g", { opacity: t ? 0.55 : 1, onMouseEnter: () => y(p), onMouseLeave: () => y(null), children: [
236
+ p > 0 && /* @__PURE__ */ a("rect", { x: j, y: f(R), width: M, height: Math.max(0, C - f(R)), rx: 4, fill: `url(#${X})` }),
237
+ /* @__PURE__ */ a("rect", { x: j, y: C, width: M, height: Math.max(0, g.t + N - C), rx: 4, fill: A }),
238
+ /* @__PURE__ */ a("text", { x: v, y: C + 16, textAnchor: "middle", className: "fill-[var(--card)] text-[12px] font-medium tabular-nums", children: V(n.value) }),
239
+ /* @__PURE__ */ a("text", { x: v, y: g.t + N + 24, textAnchor: "middle", className: "fill-secondary text-[12.5px] font-medium", children: n.label }),
240
+ /* @__PURE__ */ c("text", { x: v, y: g.t + N + 45, textAnchor: "middle", className: "fill-foreground text-[12px] font-medium tabular-nums", children: [
241
+ H(n.value),
242
+ " ",
243
+ /* @__PURE__ */ a("tspan", { className: "fill-tertiary", children: p === 0 ? "entered" : `→ ${z(k * 100)}` })
244
+ ] }),
245
+ p > 0 && /* @__PURE__ */ c("text", { x: v, y: g.t + N + 66, textAnchor: "middle", className: "fill-tertiary text-[12px] font-medium tabular-nums", children: [
246
+ "↘ ",
247
+ z((1 - n.value / e[p - 1].value) * 100)
248
+ ] }),
249
+ p > 0 && n.medianTime != null && /* @__PURE__ */ c("text", { x: v, y: g.t + N + 86, textAnchor: "middle", className: "fill-tertiary text-[11px] tabular-nums", children: [
250
+ "◷ ",
251
+ B(n.medianTime)
252
+ ] })
253
+ ] }, p);
254
+ })
255
+ ] }),
256
+ l != null && e[l] && /* @__PURE__ */ a(
257
+ _,
258
+ {
259
+ x: g.l + l * m + m / 2,
260
+ y: g.t + N / 2,
261
+ flip: l >= e.length - 2,
262
+ title: e[l].label,
263
+ rows: [
264
+ { swatch: A, label: "Converted", value: H(e[l].value) },
265
+ ...l > 0 ? [
266
+ { swatch: E, label: "Dropped off", value: `−${H(e[l - 1].value - e[l].value)}` },
267
+ { label: "Conversion so far", value: z(e[l].value / h * 100) },
268
+ { label: "From previous", value: z(e[l].value / e[l - 1].value * 100) },
269
+ { label: "Median time", value: B(e[l].medianTime) }
270
+ ] : []
271
+ ]
272
+ }
273
+ )
274
+ ] });
275
+ }
276
+ function ce({ steps: e, className: s }) {
277
+ var i;
278
+ const d = ((i = e[0]) == null ? void 0 : i.value) || 1;
279
+ return /* @__PURE__ */ a("div", { className: D("flex w-full flex-col gap-[30px] font-sans", s), children: e.map((u, o) => {
280
+ const l = u.value / d, y = o === 0 ? 1 : e[o - 1].value / d;
281
+ return /* @__PURE__ */ c("div", { className: "w-full", children: [
282
+ /* @__PURE__ */ c("div", { className: "mb-1.5 flex items-baseline justify-between gap-3", children: [
283
+ /* @__PURE__ */ c("span", { className: "truncate text-[12.5px] font-medium text-secondary", children: [
284
+ /* @__PURE__ */ c("span", { className: "text-tertiary tabular-nums", children: [
285
+ o + 1,
286
+ "."
287
+ ] }),
288
+ " ",
289
+ u.label
290
+ ] }),
291
+ /* @__PURE__ */ c("div", { className: "flex shrink-0 items-baseline gap-3", children: [
292
+ o > 0 && u.avgTime != null && /* @__PURE__ */ c("span", { className: "text-[11px] text-tertiary tabular-nums", children: [
293
+ "Avg time ",
294
+ B(u.avgTime)
295
+ ] }),
296
+ /* @__PURE__ */ a("span", { className: "text-[12.5px] font-medium text-foreground tabular-nums", children: z(l * 100) })
297
+ ] })
298
+ ] }),
299
+ /* @__PURE__ */ c("div", { className: "relative h-[46px] w-full overflow-hidden rounded-lg bg-muted-foreground/[0.06]", children: [
300
+ o > 0 && /* @__PURE__ */ a(
301
+ "div",
302
+ {
303
+ className: "absolute inset-y-0 left-0",
304
+ style: {
305
+ width: `${y * 100}%`,
306
+ backgroundImage: `repeating-linear-gradient(45deg, color-mix(in srgb, ${E} 9%, transparent) 0 4px, color-mix(in srgb, ${E} 22%, transparent) 4px 5px)`
307
+ }
308
+ }
309
+ ),
310
+ /* @__PURE__ */ a("div", { className: "absolute inset-y-0 left-0 flex items-center rounded-lg", style: { width: `${l * 100}%`, background: A }, children: /* @__PURE__ */ a("span", { className: "ml-3 text-[12px] font-medium text-[var(--card)] tabular-nums", children: V(u.value) }) })
311
+ ] })
312
+ ] }, o);
313
+ }) });
314
+ }
315
+ const W = { l: 48, r: 24, t: 34, b: 34 };
316
+ function se({ points: e, height: s = 300, className: d }) {
317
+ const [i, u] = $.useState(720), o = $.useRef(null);
318
+ $.useEffect(() => {
319
+ if (!o.current) return;
320
+ const r = new ResizeObserver(([n]) => u(n.contentRect.width));
321
+ return r.observe(o.current), () => r.disconnect();
322
+ }, []);
323
+ const [l, y] = $.useState(null), w = Math.max(0, i - W.l - W.r), N = Math.max(0, s - W.t - W.b), h = e.length, f = (r) => W.l + (h <= 1 ? w / 2 : r / (h - 1) * w), m = (r) => W.t + N - r / 100 * N, M = e.map((r, n) => [f(n), m(r.v)]);
324
+ return /* @__PURE__ */ c("div", { ref: o, className: D("relative w-full font-sans", d), children: [
325
+ /* @__PURE__ */ c(
326
+ "svg",
327
+ {
328
+ width: i,
329
+ height: s,
330
+ className: "block select-none",
331
+ onMouseLeave: () => y(null),
332
+ onMouseMove: (r) => {
333
+ const n = r.currentTarget.getBoundingClientRect(), p = Math.round((r.clientX - n.left - W.l) / w * (h - 1));
334
+ y(Math.max(0, Math.min(h - 1, p)));
335
+ },
336
+ children: [
337
+ [100, 75, 50, 25, 0].map((r) => /* @__PURE__ */ c("g", { children: [
338
+ /* @__PURE__ */ a("line", { x1: W.l, x2: W.l + w, y1: m(r), y2: m(r), stroke: U, strokeWidth: 1, strokeDasharray: r === 0 ? void 0 : "3 4", opacity: r === 0 ? 0.9 : 0.6 }),
339
+ /* @__PURE__ */ c("text", { x: W.l - 10, y: m(r), dy: "0.32em", textAnchor: "end", className: "fill-tertiary text-[11px] tabular-nums", children: [
340
+ r,
341
+ "%"
342
+ ] })
343
+ ] }, r)),
344
+ Z(e).map(
345
+ (r, n) => r == null ? null : /* @__PURE__ */ a("text", { x: f(n), y: s - 12, textAnchor: "middle", className: "fill-tertiary text-[11px] tabular-nums", children: r.label }, n)
346
+ ),
347
+ /* @__PURE__ */ a("path", { d: `${P(M)} L${f(h - 1)},${m(0)} L${f(0)},${m(0)} Z`, fill: A, opacity: 0.12 }),
348
+ /* @__PURE__ */ a("path", { d: P(M), fill: "none", stroke: A, strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round" }),
349
+ e.map((r, n) => /* @__PURE__ */ c("g", { children: [
350
+ /* @__PURE__ */ c("text", { x: f(n), y: m(r.v) - 12, textAnchor: "middle", className: "fill-foreground text-[11.5px] font-medium tabular-nums", children: [
351
+ r.v,
352
+ "%"
353
+ ] }),
354
+ /* @__PURE__ */ a("circle", { cx: f(n), cy: m(r.v), r: l === n ? 5 : 3.5, fill: "var(--card)", stroke: A, strokeWidth: 2 })
355
+ ] }, n))
356
+ ]
357
+ }
358
+ ),
359
+ l != null && e[l] && /* @__PURE__ */ a(
360
+ _,
361
+ {
362
+ x: f(l),
363
+ y: m(e[l].v),
364
+ flip: l >= h - 2,
365
+ title: e[l].label,
366
+ rows: [{ swatch: A, label: "Retention", value: `${e[l].v}%` }]
367
+ }
368
+ )
369
+ ] });
370
+ }
371
+ function te(e) {
372
+ const s = 10 + Math.max(0, Math.min(100, e)) / 100 * 78;
373
+ return `color-mix(in srgb, ${A} ${s}%, transparent)`;
374
+ }
375
+ function ie({ cols: e, cohorts: s, className: d }) {
376
+ return /* @__PURE__ */ a("div", { className: D("w-full overflow-x-auto font-sans", d), children: /* @__PURE__ */ c("table", { className: "w-full border-collapse text-left", children: [
377
+ /* @__PURE__ */ a("thead", { children: /* @__PURE__ */ c("tr", { className: "text-xs font-medium text-tertiary", children: [
378
+ /* @__PURE__ */ a("th", { className: "sticky left-0 w-[1%] bg-card py-2 pr-4 whitespace-nowrap", children: "Cohort" }),
379
+ /* @__PURE__ */ a("th", { className: "w-[1%] py-2 pr-4 text-right whitespace-nowrap", children: "Users" }),
380
+ e.map((i) => /* @__PURE__ */ a("th", { className: "px-1.5 py-2 text-center tabular-nums", children: i }, i))
381
+ ] }) }),
382
+ /* @__PURE__ */ a("tbody", { children: s.map((i) => /* @__PURE__ */ c("tr", { children: [
383
+ /* @__PURE__ */ a("td", { className: "sticky left-0 w-[1%] bg-card py-1.5 pr-4 text-[12.5px] text-secondary whitespace-nowrap", children: i.label }),
384
+ /* @__PURE__ */ a("td", { className: "w-[1%] py-1.5 pr-4 text-right text-[12.5px] text-secondary tabular-nums whitespace-nowrap", children: H(i.size) }),
385
+ i.values.map((u, o) => /* @__PURE__ */ a("td", { className: "px-1 py-1", children: u == null ? /* @__PURE__ */ a("div", { className: "py-[9px] text-center text-[12.5px] text-tertiary/45 tabular-nums", children: "—" }) : /* @__PURE__ */ c(
386
+ "div",
387
+ {
388
+ className: D(
389
+ "rounded-md py-[9px] text-center text-[12.5px] tabular-nums",
390
+ u >= 50 ? "text-[var(--card)]" : "text-secondary"
391
+ ),
392
+ style: { background: te(u) },
393
+ children: [
394
+ u,
395
+ "%"
396
+ ]
397
+ }
398
+ ) }, o))
399
+ ] }, i.label)) })
400
+ ] }) });
401
+ }
402
+ export {
403
+ ce as FunnelBarsHorizontal,
404
+ oe as FunnelViz,
405
+ se as RetentionCurve,
406
+ ie as RetentionGrid,
407
+ ne as SeriesChart
408
+ };
Binary file
Binary file
package/fonts.css CHANGED
@@ -1,8 +1,10 @@
1
1
  /* @actioneer/ads — generated by scripts/build-lib-styles.mjs. Do not edit. */
2
2
  /* Aribau Grotesk — ADS 1.0 brand typeface.
3
- Two weights only: Regular (400) and Bold (700).
4
- The weight RANGES fold Tailwind's intermediate utilities onto these two
5
- physical files: `font-normal`/`font-medium` → Regular, `font-semibold`/`font-bold` → Bold.
3
+ TWO weights only: Regular (400) and Semibold (600). Use `font-normal` and
4
+ `font-semibold` — there is NO dedicated bold face, so never reach for
5
+ `font-bold` (it would just fold onto the 600 file). The weight RANGES map
6
+ Tailwind's utilities onto the two physical files:
7
+ `font-normal` → Regular (100–500), `font-semibold` → Semibold (600–900).
6
8
  `font-synthesis-weight: none` (set in index.css) prevents faux weights. */
7
9
  @font-face {
8
10
  font-family: "Aribau Grotesk";
@@ -13,7 +15,7 @@
13
15
  }
14
16
  @font-face {
15
17
  font-family: "Aribau Grotesk";
16
- src: url("./fonts/aribau-grotesk-700.otf") format("opentype");
18
+ src: url("./fonts/aribau-grotesk-600.woff2") format("woff2");
17
19
  font-weight: 600 900;
18
20
  font-style: normal;
19
21
  font-display: swap;