@arbidocs/blocks 0.4.0 → 0.4.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 (74) hide show
  1. package/README.md +22 -0
  2. package/dist/{chunk-7G3JNSJB.cjs → chunk-2K33YGM6.cjs} +51 -14
  3. package/dist/chunk-2K33YGM6.cjs.map +1 -0
  4. package/dist/{chunk-S5T7ZTX2.js → chunk-2ORA62OF.js} +3 -3
  5. package/dist/{chunk-S5T7ZTX2.js.map → chunk-2ORA62OF.js.map} +1 -1
  6. package/dist/{chunk-RBXZYNVB.js → chunk-6P6AEQJB.js} +195 -35
  7. package/dist/chunk-6P6AEQJB.js.map +1 -0
  8. package/dist/{chunk-5TYEJOXY.js → chunk-7PEELPMA.js} +52 -15
  9. package/dist/chunk-7PEELPMA.js.map +1 -0
  10. package/dist/{chunk-KUA3BCT2.cjs → chunk-AE5FHFZ5.cjs} +6 -6
  11. package/dist/{chunk-KUA3BCT2.cjs.map → chunk-AE5FHFZ5.cjs.map} +1 -1
  12. package/dist/{chunk-FZQJ2S6P.cjs → chunk-DREI7EQ2.cjs} +197 -33
  13. package/dist/chunk-DREI7EQ2.cjs.map +1 -0
  14. package/dist/chunk-J2BGSWXM.cjs +990 -0
  15. package/dist/chunk-J2BGSWXM.cjs.map +1 -0
  16. package/dist/{chunk-6ALISABK.cjs → chunk-LRUCMZK6.cjs} +7 -4
  17. package/dist/{chunk-6ALISABK.cjs.map → chunk-LRUCMZK6.cjs.map} +1 -1
  18. package/dist/chunk-OBLSURHV.js +973 -0
  19. package/dist/chunk-OBLSURHV.js.map +1 -0
  20. package/dist/{chunk-DVLEQURC.js → chunk-QXEJXIP4.js} +7 -4
  21. package/dist/{chunk-DVLEQURC.js.map → chunk-QXEJXIP4.js.map} +1 -1
  22. package/dist/collaboration/index.cjs +1 -1
  23. package/dist/collaboration/index.js +1 -1
  24. package/dist/components/Chart.d.ts +9 -1
  25. package/dist/components/ContactForm.d.ts +15 -3
  26. package/dist/components/TeamGrid.d.ts +14 -2
  27. package/dist/components/editorial/ArticleList.d.ts +32 -0
  28. package/dist/components/editorial/Bands.d.ts +29 -0
  29. package/dist/components/editorial/EditorialHeading.d.ts +17 -0
  30. package/dist/components/editorial/EditorialHero.d.ts +46 -0
  31. package/dist/components/editorial/EditorialSection.d.ts +47 -0
  32. package/dist/components/editorial/Eyebrow.d.ts +14 -0
  33. package/dist/components/editorial/PanelGrid.d.ts +45 -0
  34. package/dist/components/editorial/ProfileCard.d.ts +27 -0
  35. package/dist/components/editorial/PullQuote.d.ts +17 -0
  36. package/dist/components/editorial/Reveal.d.ts +15 -0
  37. package/dist/components/editorial/index.d.ts +12 -0
  38. package/dist/components/editorial/lists.d.ts +42 -0
  39. package/dist/components/editorial/tone.d.ts +33 -0
  40. package/dist/facts/FactsViewToggle.d.ts +3 -1
  41. package/dist/facts/fact-row.d.ts +32 -0
  42. package/dist/facts/index.cjs +34 -5
  43. package/dist/facts/index.cjs.map +1 -1
  44. package/dist/facts/index.d.ts +1 -0
  45. package/dist/facts/index.js +31 -4
  46. package/dist/facts/index.js.map +1 -1
  47. package/dist/files/ViewToggle.d.ts +6 -2
  48. package/dist/files/ViewerChrome.d.ts +11 -14
  49. package/dist/files/index.cjs +20 -54
  50. package/dist/files/index.cjs.map +1 -1
  51. package/dist/files/index.js +17 -51
  52. package/dist/files/index.js.map +1 -1
  53. package/dist/index.cjs +161 -101
  54. package/dist/index.d.ts +1 -0
  55. package/dist/index.js +6 -6
  56. package/dist/shell/ActionCluster.d.ts +7 -2
  57. package/dist/shell/AskField.d.ts +6 -1
  58. package/dist/shell/index.cjs +42 -42
  59. package/dist/shell/index.js +1 -1
  60. package/dist/site/index.cjs +107 -47
  61. package/dist/site/index.d.ts +1 -0
  62. package/dist/site/index.js +2 -2
  63. package/dist/studio/index.cjs +71 -71
  64. package/dist/studio/index.js +3 -3
  65. package/package.json +3 -3
  66. package/src/blocks.css +17 -0
  67. package/dist/chunk-5TYEJOXY.js.map +0 -1
  68. package/dist/chunk-7G3JNSJB.cjs.map +0 -1
  69. package/dist/chunk-FZQJ2S6P.cjs.map +0 -1
  70. package/dist/chunk-MMYCZRKT.cjs +0 -168
  71. package/dist/chunk-MMYCZRKT.cjs.map +0 -1
  72. package/dist/chunk-RBXZYNVB.js.map +0 -1
  73. package/dist/chunk-UTWX2X2A.js +0 -165
  74. package/dist/chunk-UTWX2X2A.js.map +0 -1
@@ -0,0 +1,973 @@
1
+ "use client";
2
+ import { useEditorialTone, formatIndex, EditorialToneContext, BlockLink, BlockImage } from './chunk-6P6AEQJB.js';
3
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
4
+ import { useMemo, useRef, useState, useEffect } from 'react';
5
+ import { cn } from '@arbidocs/react/ui';
6
+ import { Check, ArrowUpRight } from 'lucide-react';
7
+
8
+ function CollectionDetail({
9
+ items,
10
+ slug,
11
+ getSlug,
12
+ renderList,
13
+ renderDetail,
14
+ renderNotFound
15
+ }) {
16
+ if (!slug) return /* @__PURE__ */ jsx(Fragment, { children: renderList(items) });
17
+ const index = items.findIndex((item) => getSlug(item) === slug);
18
+ if (index === -1) {
19
+ return /* @__PURE__ */ jsx(Fragment, { children: renderNotFound ? renderNotFound(slug) : /* @__PURE__ */ jsx("p", { role: "status", "data-slot": "collection-not-found", children: "Not found" }) });
20
+ }
21
+ return /* @__PURE__ */ jsx(Fragment, { children: renderDetail(items[index], { previous: items[index - 1], next: items[index + 1] }) });
22
+ }
23
+ var W = 440;
24
+ var H = 160;
25
+ var PAD = { top: 8, right: 8, bottom: 22, left: 40 };
26
+ var color = (i) => `hsl(var(--chart-${i % 5 + 1}))`;
27
+ function truncateLabel(label, max) {
28
+ const chars = Array.from(label);
29
+ return chars.length <= max ? label : `${chars.slice(0, Math.max(1, max - 1)).join("").trimEnd()}\u2026`;
30
+ }
31
+ var defaultFormat = (v) => v >= 1e3 ? `${Math.round(v / 100) / 10}k` : String(v);
32
+ function polar(cx, cy, r, angle) {
33
+ return [cx + r * Math.sin(angle), cy - r * Math.cos(angle)];
34
+ }
35
+ function Chart({
36
+ type,
37
+ labels,
38
+ series,
39
+ ariaLabel,
40
+ formatValue = defaultFormat,
41
+ hideLegend = false,
42
+ emptyLabel = "No data",
43
+ maxLabelChars,
44
+ className,
45
+ testId
46
+ }) {
47
+ const max = useMemo(() => Math.max(...series.flatMap((s) => s.values), 1), [series]);
48
+ if (!labels.length || !series.length) {
49
+ return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: emptyLabel });
50
+ }
51
+ const legendItems = type === "pie" ? labels.map((label, i) => ({ label, color: color(i) })) : series.map((s, i) => ({ label: s.label ?? s.key, color: color(i) }));
52
+ let body;
53
+ if (type === "pie") {
54
+ const values = series[0].values;
55
+ const total = values.reduce((a, b) => a + Math.max(b, 0), 0);
56
+ const cx = 80;
57
+ const cy = 80;
58
+ const r = 72;
59
+ let angle = 0;
60
+ body = /* @__PURE__ */ jsx("svg", { viewBox: "0 0 160 160", className: "mx-auto h-40 w-40", role: "img", "aria-label": ariaLabel, children: total > 0 && values.map((v, i) => {
61
+ const sweep = Math.max(v, 0) / total * Math.PI * 2;
62
+ if (sweep === 0) return null;
63
+ const title = `${labels[i]}: ${formatValue(v)}`;
64
+ if (sweep >= Math.PI * 2 - 1e-6) {
65
+ return /* @__PURE__ */ jsx("circle", { cx, cy, r, fill: color(i), children: /* @__PURE__ */ jsx("title", { children: title }) }, i);
66
+ }
67
+ const [x1, y1] = polar(cx, cy, r, angle);
68
+ const [x2, y2] = polar(cx, cy, r, angle + sweep);
69
+ const d = `M${cx},${cy} L${x1},${y1} A${r},${r} 0 ${sweep > Math.PI ? 1 : 0} 1 ${x2},${y2} Z`;
70
+ angle += sweep;
71
+ return /* @__PURE__ */ jsx("path", { d, fill: color(i), children: /* @__PURE__ */ jsx("title", { children: title }) }, i);
72
+ }) });
73
+ } else {
74
+ const plotW = W - PAD.left - PAD.right;
75
+ const plotH = H - PAD.top - PAD.bottom;
76
+ const y = (v) => PAD.top + plotH - v / max * plotH;
77
+ const band = plotW / labels.length;
78
+ const xCenter = (i) => PAD.left + band * i + band / 2;
79
+ const maxChars = maxLabelChars ?? Math.max(3, Math.floor((band - 4) / 5));
80
+ body = /* @__PURE__ */ jsxs("svg", { viewBox: `0 0 ${W} ${H}`, className: "h-auto w-full", role: "img", "aria-label": ariaLabel, children: [
81
+ [0, max / 2, max].map((v) => /* @__PURE__ */ jsxs("g", { children: [
82
+ /* @__PURE__ */ jsx(
83
+ "line",
84
+ {
85
+ x1: PAD.left,
86
+ x2: W - PAD.right,
87
+ y1: y(v),
88
+ y2: y(v),
89
+ className: "stroke-border",
90
+ strokeDasharray: "2,2"
91
+ }
92
+ ),
93
+ /* @__PURE__ */ jsx(
94
+ "text",
95
+ {
96
+ x: PAD.left - 4,
97
+ y: y(v) + 3,
98
+ textAnchor: "end",
99
+ className: "fill-muted-foreground text-[9px]",
100
+ children: formatValue(v)
101
+ }
102
+ )
103
+ ] }, v)),
104
+ labels.map((label, i) => /* @__PURE__ */ jsxs(
105
+ "text",
106
+ {
107
+ x: xCenter(i),
108
+ y: H - 6,
109
+ textAnchor: "middle",
110
+ className: "fill-muted-foreground text-[9px]",
111
+ children: [
112
+ truncateLabel(label, maxChars),
113
+ Array.from(label).length > maxChars && /* @__PURE__ */ jsx("title", { children: label })
114
+ ]
115
+ },
116
+ i
117
+ )),
118
+ type === "bar" && series.map((s, si) => {
119
+ const barW = band * 0.7 / series.length;
120
+ return s.values.map((v, i) => /* @__PURE__ */ jsx(
121
+ "rect",
122
+ {
123
+ x: xCenter(i) - band * 0.7 / 2 + si * barW,
124
+ y: y(v),
125
+ width: barW,
126
+ height: PAD.top + plotH - y(v),
127
+ fill: color(si),
128
+ rx: 1.5,
129
+ children: /* @__PURE__ */ jsx("title", { children: `${labels[i]} ${s.label ?? s.key}: ${formatValue(v)}` })
130
+ },
131
+ `${s.key}-${i}`
132
+ ));
133
+ }),
134
+ type === "line" && series.map((s, si) => /* @__PURE__ */ jsxs("g", { children: [
135
+ /* @__PURE__ */ jsx(
136
+ "polyline",
137
+ {
138
+ fill: "none",
139
+ stroke: color(si),
140
+ strokeWidth: 2,
141
+ points: s.values.map((v, i) => `${xCenter(i)},${y(v)}`).join(" ")
142
+ }
143
+ ),
144
+ s.values.map((v, i) => /* @__PURE__ */ jsx("circle", { cx: xCenter(i), cy: y(v), r: 2.5, fill: color(si), children: /* @__PURE__ */ jsx("title", { children: `${labels[i]} ${s.label ?? s.key}: ${formatValue(v)}` }) }, i))
145
+ ] }, s.key))
146
+ ] });
147
+ }
148
+ return /* @__PURE__ */ jsxs(
149
+ "figure",
150
+ {
151
+ className: cn("flex flex-col gap-2", className),
152
+ "data-slot": "chart",
153
+ "data-type": type,
154
+ "data-testid": testId,
155
+ children: [
156
+ body,
157
+ !hideLegend && /* @__PURE__ */ jsx("figcaption", { className: "flex flex-wrap justify-center gap-x-4 gap-y-1 text-xs text-muted-foreground", children: legendItems.map((item) => /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
158
+ /* @__PURE__ */ jsx(
159
+ "span",
160
+ {
161
+ "aria-hidden": "true",
162
+ className: "inline-block size-2 rounded-full",
163
+ style: { background: item.color }
164
+ }
165
+ ),
166
+ item.label
167
+ ] }, item.label)) })
168
+ ]
169
+ }
170
+ );
171
+ }
172
+ function Eyebrow({ children, index, rule = false, tone, className, testId }) {
173
+ const t = useEditorialTone(tone);
174
+ return /* @__PURE__ */ jsxs(
175
+ "p",
176
+ {
177
+ className: cn(
178
+ "flex items-center gap-3 text-xs font-semibold uppercase tracking-wider",
179
+ t.subtle,
180
+ className
181
+ ),
182
+ "data-slot": "eyebrow",
183
+ "data-testid": testId,
184
+ children: [
185
+ rule && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "h-px w-8 shrink-0 bg-primary" }),
186
+ index !== void 0 && /* @__PURE__ */ jsx("span", { className: cn("tabular-nums", t.accent), children: formatIndex(index) }),
187
+ /* @__PURE__ */ jsx("span", { children })
188
+ ]
189
+ }
190
+ );
191
+ }
192
+ function EditorialHeading({
193
+ eyebrow,
194
+ index,
195
+ title,
196
+ lead,
197
+ level = 2,
198
+ align = "start",
199
+ tone,
200
+ className,
201
+ testId
202
+ }) {
203
+ const t = useEditorialTone(tone);
204
+ const Heading = `h${level}`;
205
+ return /* @__PURE__ */ jsxs(
206
+ "div",
207
+ {
208
+ className: cn("max-w-3xl", align === "center" && "mx-auto text-center", className),
209
+ "data-slot": "editorial-heading",
210
+ "data-testid": testId,
211
+ children: [
212
+ (eyebrow || index !== void 0) && /* @__PURE__ */ jsx(
213
+ Eyebrow,
214
+ {
215
+ index,
216
+ tone,
217
+ className: cn("mb-4", align === "center" && "justify-center"),
218
+ children: eyebrow
219
+ }
220
+ ),
221
+ /* @__PURE__ */ jsx(
222
+ Heading,
223
+ {
224
+ className: cn(
225
+ "font-display text-3xl font-semibold tracking-tight text-balance sm:text-4xl",
226
+ t.text
227
+ ),
228
+ children: title
229
+ }
230
+ ),
231
+ lead && /* @__PURE__ */ jsx("p", { className: cn("mt-4 text-lg leading-relaxed", t.muted), children: lead })
232
+ ]
233
+ }
234
+ );
235
+ }
236
+ var SURFACE_CLASS = {
237
+ plain: "bg-background text-foreground",
238
+ muted: "bg-muted text-foreground",
239
+ inverse: "bg-foreground text-background"
240
+ };
241
+ var SURFACE_TONE = {
242
+ plain: "default",
243
+ muted: "default",
244
+ inverse: "inverse"
245
+ };
246
+ function renderTitle(title, emphasis) {
247
+ if (typeof title !== "string" || !emphasis || !title.includes(emphasis)) return title;
248
+ const parts = title.split(emphasis);
249
+ return parts.map((part, i) => /* @__PURE__ */ jsxs("span", { children: [
250
+ part,
251
+ i < parts.length - 1 && /* @__PURE__ */ jsx("em", { className: "italic text-primary", children: emphasis })
252
+ ] }, i));
253
+ }
254
+ function EditorialHero({
255
+ eyebrow,
256
+ eyebrowRule = false,
257
+ title,
258
+ emphasis,
259
+ lede,
260
+ actions,
261
+ footer,
262
+ aside,
263
+ backdrop,
264
+ align = "start",
265
+ size = "page",
266
+ surface = "plain",
267
+ className,
268
+ testId,
269
+ testIds
270
+ }) {
271
+ const tone = SURFACE_TONE[surface];
272
+ const t = useEditorialTone(tone);
273
+ const centered = align === "center" && !aside;
274
+ const ids = {
275
+ root: testIds?.root ?? testId,
276
+ eyebrow: testIds?.eyebrow ?? (testId ? `${testId}-eyebrow` : void 0),
277
+ title: testIds?.title ?? (testId ? `${testId}-title` : void 0),
278
+ lede: testIds?.lede ?? (testId ? `${testId}-lede` : void 0),
279
+ actions: testIds?.actions ?? (testId ? `${testId}-actions` : void 0),
280
+ aside: testIds?.aside ?? (testId ? `${testId}-aside` : void 0)
281
+ };
282
+ return /* @__PURE__ */ jsx(EditorialToneContext.Provider, { value: tone, children: /* @__PURE__ */ jsxs(
283
+ "section",
284
+ {
285
+ className: cn("relative isolate overflow-hidden", SURFACE_CLASS[surface], className),
286
+ "data-slot": "editorial-hero",
287
+ "data-size": size,
288
+ "data-testid": ids.root,
289
+ children: [
290
+ backdrop && /* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 -z-10", children: backdrop }),
291
+ /* @__PURE__ */ jsxs(
292
+ "div",
293
+ {
294
+ className: cn(
295
+ "mx-auto max-w-7xl px-5 lg:px-8",
296
+ size === "cover" ? "py-16 lg:py-28" : "py-14 lg:py-24",
297
+ aside && "grid items-center gap-12 lg:grid-cols-[1.02fr_0.98fr] lg:gap-14"
298
+ ),
299
+ children: [
300
+ /* @__PURE__ */ jsxs("div", { className: cn("max-w-3xl", centered && "mx-auto text-center"), children: [
301
+ eyebrow && /* @__PURE__ */ jsx(
302
+ Eyebrow,
303
+ {
304
+ rule: eyebrowRule,
305
+ tone,
306
+ className: cn("mb-6", centered && "justify-center"),
307
+ testId: ids.eyebrow,
308
+ children: eyebrow
309
+ }
310
+ ),
311
+ /* @__PURE__ */ jsx(
312
+ "h1",
313
+ {
314
+ className: cn(
315
+ "font-display font-semibold tracking-tight text-balance",
316
+ size === "cover" ? "text-[2.6rem] leading-[1.03] sm:text-6xl lg:text-[4.4rem]" : "text-4xl leading-[1.05] sm:text-5xl",
317
+ t.text
318
+ ),
319
+ "data-testid": ids.title,
320
+ children: renderTitle(title, emphasis)
321
+ }
322
+ ),
323
+ lede && /* @__PURE__ */ jsx(
324
+ "p",
325
+ {
326
+ className: cn(
327
+ "mt-6 max-w-2xl text-lg leading-relaxed",
328
+ centered && "mx-auto",
329
+ t.muted
330
+ ),
331
+ "data-testid": ids.lede,
332
+ children: lede
333
+ }
334
+ ),
335
+ actions && /* @__PURE__ */ jsx(
336
+ "div",
337
+ {
338
+ className: cn(
339
+ "mt-8 flex flex-col gap-3 sm:flex-row",
340
+ centered && "sm:justify-center"
341
+ ),
342
+ "data-testid": ids.actions,
343
+ children: actions
344
+ }
345
+ ),
346
+ footer && /* @__PURE__ */ jsx("div", { className: cn("mt-8", centered && "flex justify-center"), children: footer })
347
+ ] }),
348
+ aside && /* @__PURE__ */ jsx(
349
+ "div",
350
+ {
351
+ className: "relative min-w-0",
352
+ "data-slot": "editorial-hero-aside",
353
+ "data-testid": ids.aside,
354
+ children: aside
355
+ }
356
+ )
357
+ ]
358
+ }
359
+ )
360
+ ]
361
+ }
362
+ ) });
363
+ }
364
+ function EditorialSection({
365
+ id,
366
+ eyebrow,
367
+ index,
368
+ title,
369
+ lead,
370
+ action,
371
+ layout = "stacked",
372
+ surface = "plain",
373
+ bordered = false,
374
+ spacing = "lg",
375
+ backdrop,
376
+ "aria-label": ariaLabel,
377
+ children,
378
+ className,
379
+ testId
380
+ }) {
381
+ const tone = SURFACE_TONE[surface];
382
+ const t = useEditorialTone(tone);
383
+ const hasHeading = Boolean(title || eyebrow || index !== void 0);
384
+ const heading = hasHeading && title ? /* @__PURE__ */ jsx(EditorialHeading, { eyebrow, index, title, lead, tone }) : null;
385
+ const split = layout !== "stacked";
386
+ return /* @__PURE__ */ jsx(EditorialToneContext.Provider, { value: tone, children: /* @__PURE__ */ jsxs(
387
+ "section",
388
+ {
389
+ id,
390
+ "aria-label": title ? void 0 : ariaLabel,
391
+ className: cn(
392
+ "relative isolate overflow-hidden scroll-mt-24",
393
+ SURFACE_CLASS[surface],
394
+ bordered && cn("border-y", t.hairline),
395
+ className
396
+ ),
397
+ "data-slot": "editorial-section",
398
+ "data-testid": testId,
399
+ children: [
400
+ backdrop && /* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 -z-10", children: backdrop }),
401
+ /* @__PURE__ */ jsx(
402
+ "div",
403
+ {
404
+ className: cn(
405
+ "mx-auto max-w-7xl px-5 lg:px-8",
406
+ spacing === "lg" ? "py-16 lg:py-24" : "py-12 lg:py-16",
407
+ split && cn(
408
+ "grid gap-10 lg:gap-16",
409
+ layout === "split-wide" ? "lg:grid-cols-[1fr_1.4fr]" : "lg:grid-cols-2"
410
+ )
411
+ ),
412
+ children: split ? /* @__PURE__ */ jsxs(Fragment, { children: [
413
+ heading && /* @__PURE__ */ jsx("div", { children: heading }),
414
+ /* @__PURE__ */ jsx("div", { className: "min-w-0", children })
415
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
416
+ heading && /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-between gap-6 sm:flex-row sm:items-end", children: [
417
+ heading,
418
+ action && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: action })
419
+ ] }),
420
+ children && /* @__PURE__ */ jsx("div", { className: cn(heading && "mt-12 lg:mt-14"), children })
421
+ ] })
422
+ }
423
+ )
424
+ ]
425
+ }
426
+ ) });
427
+ }
428
+ function EditorialProse({
429
+ paragraphs,
430
+ columns = 1,
431
+ size = "base",
432
+ className,
433
+ testId
434
+ }) {
435
+ const t = useEditorialTone();
436
+ return /* @__PURE__ */ jsx(
437
+ "div",
438
+ {
439
+ className: cn(
440
+ size === "lg" ? "text-lg" : "text-base",
441
+ "leading-relaxed",
442
+ t.muted,
443
+ columns === 2 ? "gap-10 md:columns-2" : "max-w-prose",
444
+ className
445
+ ),
446
+ "data-slot": "editorial-prose",
447
+ "data-testid": testId,
448
+ children: paragraphs.map((p, i) => /* @__PURE__ */ jsx("p", { className: cn(columns === 2 ? "mb-5 break-inside-avoid" : "mt-5 first:mt-0"), children: p }, i))
449
+ }
450
+ );
451
+ }
452
+ function DefinitionList({
453
+ items,
454
+ layout = "rows",
455
+ marker = "dot",
456
+ className,
457
+ testId
458
+ }) {
459
+ const t = useEditorialTone();
460
+ return /* @__PURE__ */ jsx(
461
+ "dl",
462
+ {
463
+ className: cn(layout === "rows" ? "space-y-3" : "divide-y", t.hairline, className),
464
+ "data-slot": "definition-list",
465
+ "data-layout": layout,
466
+ "data-testid": testId,
467
+ children: items.map(
468
+ (item, i) => layout === "rows" ? /* @__PURE__ */ jsxs(
469
+ "div",
470
+ {
471
+ className: cn(
472
+ "flex gap-4 rounded-sm border p-5 transition-colors",
473
+ t.panel,
474
+ t.panelHover
475
+ ),
476
+ "data-testid": item.testId ?? (testId ? `${testId}-item-${i}` : void 0),
477
+ children: [
478
+ item.icon ? /* @__PURE__ */ jsx(
479
+ "span",
480
+ {
481
+ className: cn(
482
+ "flex size-9 shrink-0 items-center justify-center rounded-sm border",
483
+ t.tile
484
+ ),
485
+ "aria-hidden": "true",
486
+ children: item.icon
487
+ }
488
+ ) : marker === "dot" && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "mt-2 size-2 shrink-0 rounded-full bg-primary" }),
489
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
490
+ /* @__PURE__ */ jsx("dt", { className: "font-medium", children: item.term }),
491
+ /* @__PURE__ */ jsx("dd", { className: cn("mt-0.5 text-sm", t.muted), children: item.description })
492
+ ] })
493
+ ]
494
+ },
495
+ i
496
+ ) : /* @__PURE__ */ jsxs(
497
+ "div",
498
+ {
499
+ className: "grid gap-1 py-4 sm:grid-cols-[minmax(0,1fr)_minmax(0,2fr)] sm:gap-8",
500
+ "data-testid": item.testId ?? (testId ? `${testId}-item-${i}` : void 0),
501
+ children: [
502
+ /* @__PURE__ */ jsx("dt", { className: "font-medium", children: item.term }),
503
+ /* @__PURE__ */ jsx("dd", { className: cn("text-sm leading-relaxed", t.muted), children: item.description })
504
+ ]
505
+ },
506
+ i
507
+ )
508
+ )
509
+ }
510
+ );
511
+ }
512
+ function CheckList({ items, columns = 1, icon, className, testId }) {
513
+ const t = useEditorialTone();
514
+ return /* @__PURE__ */ jsx(
515
+ "ul",
516
+ {
517
+ className: cn(columns === 2 ? "grid gap-4 sm:grid-cols-2" : "space-y-3", className),
518
+ "data-slot": "check-list",
519
+ "data-testid": testId,
520
+ children: items.map((item, i) => /* @__PURE__ */ jsxs(
521
+ "li",
522
+ {
523
+ className: cn("flex items-start gap-3 text-sm leading-relaxed", t.muted),
524
+ "data-testid": testId ? `${testId}-item-${i}` : void 0,
525
+ children: [
526
+ /* @__PURE__ */ jsx(
527
+ "span",
528
+ {
529
+ "aria-hidden": "true",
530
+ className: cn(
531
+ "mt-0.5 flex size-5 shrink-0 items-center justify-center rounded-full border",
532
+ t.tile
533
+ ),
534
+ children: icon ?? /* @__PURE__ */ jsx(Check, { className: "size-3" })
535
+ }
536
+ ),
537
+ /* @__PURE__ */ jsx("span", { children: item })
538
+ ]
539
+ },
540
+ i
541
+ ))
542
+ }
543
+ );
544
+ }
545
+ function TagList({ items, label, className, testId }) {
546
+ const t = useEditorialTone();
547
+ if (items.length === 0) return null;
548
+ return /* @__PURE__ */ jsx(
549
+ "ul",
550
+ {
551
+ "aria-label": label,
552
+ className: cn("flex flex-wrap gap-1.5", className),
553
+ "data-slot": "tag-list",
554
+ "data-testid": testId,
555
+ children: items.map((tag) => /* @__PURE__ */ jsx("li", { className: cn("rounded-sm border px-2 py-0.5 text-[11px]", t.chip), children: tag }, tag))
556
+ }
557
+ );
558
+ }
559
+ function Reveal({ children, delay = 0, className, testId }) {
560
+ const ref = useRef(null);
561
+ const [state, setState] = useState("idle");
562
+ useEffect(() => {
563
+ const el = ref.current;
564
+ if (!el || typeof IntersectionObserver === "undefined") return;
565
+ setState("pending");
566
+ const io = new IntersectionObserver(
567
+ (entries) => {
568
+ if (entries.some((e) => e.isIntersecting)) {
569
+ setState("shown");
570
+ io.disconnect();
571
+ }
572
+ },
573
+ { rootMargin: "0px 0px -90px 0px" }
574
+ );
575
+ io.observe(el);
576
+ return () => io.disconnect();
577
+ }, []);
578
+ return /* @__PURE__ */ jsx(
579
+ "div",
580
+ {
581
+ ref,
582
+ "data-slot": "reveal",
583
+ "data-reveal": state === "idle" ? void 0 : state,
584
+ style: delay ? { "--reveal-delay": `${delay}ms` } : void 0,
585
+ className: cn(className),
586
+ "data-testid": testId,
587
+ children
588
+ }
589
+ );
590
+ }
591
+ var COLS = {
592
+ 2: "sm:grid-cols-2",
593
+ 3: "sm:grid-cols-2 lg:grid-cols-3",
594
+ 4: "sm:grid-cols-2 lg:grid-cols-4"
595
+ };
596
+ function PanelGrid({
597
+ items,
598
+ columns = 3,
599
+ variant = "cards",
600
+ numbered = false,
601
+ reveal = false,
602
+ linkComponent,
603
+ headingLevel = 3,
604
+ tone,
605
+ className,
606
+ testId
607
+ }) {
608
+ const t = useEditorialTone(tone);
609
+ const Heading = `h${headingLevel}`;
610
+ const joined = variant === "joined";
611
+ return /* @__PURE__ */ jsx(EditorialToneContext.Provider, { value: t.tone, children: /* @__PURE__ */ jsx(
612
+ "ul",
613
+ {
614
+ className: cn(
615
+ "grid",
616
+ joined ? cn("gap-px overflow-hidden rounded-sm border", t.hairline) : "gap-4",
617
+ joined && (t.tone === "inverse" ? "bg-background/15" : "bg-border"),
618
+ COLS[columns] ?? COLS[3],
619
+ className
620
+ ),
621
+ "data-slot": "panel-grid",
622
+ "data-variant": variant,
623
+ "data-testid": testId,
624
+ children: items.map((item, i) => {
625
+ const number = item.index ?? (numbered ? i + 1 : void 0);
626
+ const inner = /* @__PURE__ */ jsxs(
627
+ "div",
628
+ {
629
+ className: cn(
630
+ "group flex h-full flex-col p-6 transition-colors duration-300",
631
+ joined ? cn(
632
+ t.tone === "inverse" ? "bg-foreground" : "bg-background",
633
+ item.href && "hover:bg-muted/40"
634
+ ) : cn("rounded-sm border", t.panel, item.href && t.panelHover)
635
+ ),
636
+ "data-testid": item.testId ?? (testId ? `${testId}-item-${i}` : void 0),
637
+ children: [
638
+ (item.icon || number !== void 0 || item.href) && /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4", children: [
639
+ item.icon ? /* @__PURE__ */ jsx(
640
+ "span",
641
+ {
642
+ "aria-hidden": "true",
643
+ className: cn(
644
+ "flex size-11 items-center justify-center rounded-sm border",
645
+ t.tile
646
+ ),
647
+ children: item.icon
648
+ }
649
+ ) : /* @__PURE__ */ jsx("span", {}),
650
+ number !== void 0 ? /* @__PURE__ */ jsx("span", { className: cn("font-display text-sm tabular-nums", t.subtle), children: formatIndex(number) }) : item.href && /* @__PURE__ */ jsx(
651
+ ArrowUpRight,
652
+ {
653
+ "aria-hidden": "true",
654
+ className: cn(
655
+ "size-4 transition-colors group-hover:text-primary",
656
+ t.subtle
657
+ )
658
+ }
659
+ )
660
+ ] }),
661
+ item.kicker && /* @__PURE__ */ jsx(
662
+ "p",
663
+ {
664
+ className: cn(
665
+ "text-xs font-semibold uppercase tracking-wider",
666
+ item.icon || number !== void 0 ? "mt-5" : "",
667
+ t.accent
668
+ ),
669
+ children: item.kicker
670
+ }
671
+ ),
672
+ /* @__PURE__ */ jsx(
673
+ Heading,
674
+ {
675
+ className: cn(
676
+ "font-display text-lg font-semibold leading-snug",
677
+ item.icon || number !== void 0 || item.kicker ? "mt-4" : "",
678
+ t.text
679
+ ),
680
+ children: item.title
681
+ }
682
+ ),
683
+ item.body && /* @__PURE__ */ jsx("div", { className: cn("mt-2 text-sm leading-relaxed", t.muted), children: item.body }),
684
+ item.points && item.points.length > 0 && /* @__PURE__ */ jsx(
685
+ CheckList,
686
+ {
687
+ items: item.points,
688
+ className: cn("mt-4 space-y-2 border-t pt-4", t.hairline)
689
+ }
690
+ ),
691
+ item.tags && item.tags.length > 0 && /* @__PURE__ */ jsx(TagList, { items: item.tags, className: "mt-auto pt-5" }),
692
+ item.footer && /* @__PURE__ */ jsx("div", { className: cn("mt-auto pt-5 text-xs", t.subtle), children: item.footer })
693
+ ]
694
+ }
695
+ );
696
+ const cell = /* @__PURE__ */ jsx(BlockLink, { href: item.href, linkComponent, className: "block h-full", children: inner });
697
+ return /* @__PURE__ */ jsx("li", { className: "min-w-0", children: reveal ? /* @__PURE__ */ jsx(Reveal, { delay: i * 90, className: "h-full", children: cell }) : cell }, i);
698
+ })
699
+ }
700
+ ) });
701
+ }
702
+ function PullQuote({
703
+ quote,
704
+ attribution,
705
+ cite,
706
+ align = "start",
707
+ size = "md",
708
+ className,
709
+ testId
710
+ }) {
711
+ const t = useEditorialTone();
712
+ const centered = align === "center";
713
+ return /* @__PURE__ */ jsxs(
714
+ "figure",
715
+ {
716
+ className: cn(
717
+ "max-w-3xl",
718
+ centered ? "mx-auto text-center" : "border-l-2 border-primary pl-6 lg:pl-8",
719
+ className
720
+ ),
721
+ "data-slot": "pull-quote",
722
+ "data-testid": testId,
723
+ children: [
724
+ /* @__PURE__ */ jsx(
725
+ "blockquote",
726
+ {
727
+ cite,
728
+ className: cn(
729
+ "font-display font-medium leading-snug text-balance",
730
+ size === "lg" ? "text-3xl sm:text-4xl" : "text-2xl sm:text-3xl",
731
+ t.text
732
+ ),
733
+ children: /* @__PURE__ */ jsx("p", { children: quote })
734
+ }
735
+ ),
736
+ attribution && /* @__PURE__ */ jsxs("figcaption", { className: cn("mt-5 text-sm", t.muted), children: [
737
+ /* @__PURE__ */ jsx("span", { className: cn("font-semibold", t.text), children: attribution.name }),
738
+ attribution.role && /* @__PURE__ */ jsxs("span", { children: [
739
+ ", ",
740
+ attribution.role
741
+ ] })
742
+ ] })
743
+ ]
744
+ }
745
+ );
746
+ }
747
+ var COLS2 = {
748
+ 2: "md:grid-cols-2",
749
+ 3: "md:grid-cols-2 lg:grid-cols-3"
750
+ };
751
+ function MetaLine({ meta, className }) {
752
+ if (!meta || meta.length === 0) return null;
753
+ return /* @__PURE__ */ jsx("p", { className, children: meta.map((m, i) => /* @__PURE__ */ jsxs("span", { children: [
754
+ i > 0 && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: " \xB7 " }),
755
+ m
756
+ ] }, i)) });
757
+ }
758
+ function ArticleList({
759
+ items,
760
+ layout = "cards",
761
+ featureFirst = false,
762
+ columns = 3,
763
+ linkComponent,
764
+ empty,
765
+ className,
766
+ testId
767
+ }) {
768
+ const t = useEditorialTone();
769
+ if (items.length === 0) return empty ? /* @__PURE__ */ jsx(Fragment, { children: empty }) : null;
770
+ const idOf = (item, i) => item.testId ?? (testId ? `${testId}-item-${i}` : void 0);
771
+ if (layout === "rows") {
772
+ return /* @__PURE__ */ jsx(
773
+ "ul",
774
+ {
775
+ className: cn("divide-y border-y", t.hairline, className),
776
+ "data-slot": "article-list",
777
+ "data-layout": "rows",
778
+ "data-testid": testId,
779
+ children: items.map((item, i) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(BlockLink, { href: item.href, linkComponent, className: "group block", children: /* @__PURE__ */ jsxs(
780
+ "article",
781
+ {
782
+ className: "grid gap-2 py-6 transition-colors sm:grid-cols-[10rem_minmax(0,1fr)_auto] sm:gap-8",
783
+ "data-testid": idOf(item, i),
784
+ children: [
785
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
786
+ item.kicker && /* @__PURE__ */ jsx("p", { className: cn("text-xs font-semibold uppercase tracking-wider", t.accent), children: item.kicker }),
787
+ /* @__PURE__ */ jsx(MetaLine, { meta: item.meta, className: cn("text-xs", t.subtle) })
788
+ ] }),
789
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
790
+ /* @__PURE__ */ jsx(
791
+ "h3",
792
+ {
793
+ className: cn(
794
+ "font-display text-xl font-semibold leading-snug transition-colors group-hover:text-primary",
795
+ t.text
796
+ ),
797
+ children: item.title
798
+ }
799
+ ),
800
+ item.summary && /* @__PURE__ */ jsx("p", { className: cn("mt-2 text-sm leading-relaxed", t.muted), children: item.summary })
801
+ ] }),
802
+ item.href && /* @__PURE__ */ jsx(
803
+ ArrowUpRight,
804
+ {
805
+ "aria-hidden": "true",
806
+ className: cn(
807
+ "hidden size-4 transition-colors group-hover:text-primary sm:block",
808
+ t.subtle
809
+ )
810
+ }
811
+ )
812
+ ]
813
+ }
814
+ ) }) }, i))
815
+ }
816
+ );
817
+ }
818
+ const card = (item, i, lead) => /* @__PURE__ */ jsx(BlockLink, { href: item.href, linkComponent, className: "group block h-full", children: /* @__PURE__ */ jsxs(
819
+ "article",
820
+ {
821
+ className: cn(
822
+ "flex h-full flex-col rounded-sm border transition-colors duration-300",
823
+ t.panel,
824
+ item.href && t.panelHover,
825
+ lead ? "p-6 lg:p-8" : "p-6"
826
+ ),
827
+ "data-testid": idOf(item, i),
828
+ children: [
829
+ item.imageUrl && /* @__PURE__ */ jsx(
830
+ BlockImage,
831
+ {
832
+ src: item.imageUrl,
833
+ alt: item.imageAlt ?? "",
834
+ aspect: "16:9",
835
+ rounded: "none",
836
+ className: "mb-5 w-full"
837
+ }
838
+ ),
839
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
840
+ item.kicker ? /* @__PURE__ */ jsx("p", { className: cn("text-xs font-semibold uppercase tracking-wider", t.accent), children: item.kicker }) : /* @__PURE__ */ jsx("span", {}),
841
+ item.href && /* @__PURE__ */ jsx(
842
+ ArrowUpRight,
843
+ {
844
+ "aria-hidden": "true",
845
+ className: cn("size-4 transition-colors group-hover:text-primary", t.subtle)
846
+ }
847
+ )
848
+ ] }),
849
+ /* @__PURE__ */ jsx(
850
+ "h3",
851
+ {
852
+ className: cn(
853
+ "mt-3 font-display font-semibold leading-snug",
854
+ lead ? "text-2xl sm:text-3xl" : "text-lg",
855
+ t.text
856
+ ),
857
+ children: item.title
858
+ }
859
+ ),
860
+ item.summary && /* @__PURE__ */ jsx(
861
+ "p",
862
+ {
863
+ className: cn(
864
+ "mt-3 flex-1 text-sm leading-relaxed",
865
+ lead && "max-w-xl text-base",
866
+ t.muted
867
+ ),
868
+ children: item.summary
869
+ }
870
+ ),
871
+ /* @__PURE__ */ jsx(MetaLine, { meta: item.meta, className: cn("mt-5 text-xs", t.subtle) })
872
+ ]
873
+ }
874
+ ) });
875
+ if (featureFirst && items.length > 1) {
876
+ const [lead, ...rest] = items;
877
+ return /* @__PURE__ */ jsxs(
878
+ "div",
879
+ {
880
+ className: cn("grid gap-5 lg:grid-cols-[1.4fr_1fr]", className),
881
+ "data-slot": "article-list",
882
+ "data-layout": "feature",
883
+ "data-testid": testId,
884
+ children: [
885
+ /* @__PURE__ */ jsx("div", { children: card(lead, 0, true) }),
886
+ /* @__PURE__ */ jsx("ul", { className: "grid gap-5", children: rest.map((item, i) => /* @__PURE__ */ jsx("li", { children: card(item, i + 1, false) }, i)) })
887
+ ]
888
+ }
889
+ );
890
+ }
891
+ return /* @__PURE__ */ jsx(
892
+ "ul",
893
+ {
894
+ className: cn("grid gap-5", COLS2[columns] ?? COLS2[3], className),
895
+ "data-slot": "article-list",
896
+ "data-layout": "cards",
897
+ "data-testid": testId,
898
+ children: items.map((item, i) => /* @__PURE__ */ jsx("li", { children: card(item, i, false) }, i))
899
+ }
900
+ );
901
+ }
902
+ function ProofStrip({
903
+ lead,
904
+ items,
905
+ label,
906
+ surface = "muted",
907
+ className,
908
+ testId
909
+ }) {
910
+ const tone = SURFACE_TONE[surface];
911
+ const t = useEditorialTone(tone);
912
+ return /* @__PURE__ */ jsx(EditorialToneContext.Provider, { value: tone, children: /* @__PURE__ */ jsx(
913
+ "section",
914
+ {
915
+ "aria-label": label,
916
+ className: cn("border-y", t.hairline, SURFACE_CLASS[surface], className),
917
+ "data-slot": "proof-strip",
918
+ "data-testid": testId,
919
+ children: /* @__PURE__ */ jsxs("div", { className: "mx-auto flex max-w-7xl flex-col items-center gap-5 px-5 py-6 lg:flex-row lg:justify-between lg:px-8", children: [
920
+ lead && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2.5 text-sm font-medium", children: lead }),
921
+ /* @__PURE__ */ jsx("ul", { className: "flex flex-wrap items-center justify-center gap-x-6 gap-y-2", children: items.map((item, i) => /* @__PURE__ */ jsx(
922
+ "li",
923
+ {
924
+ className: cn("text-xs font-semibold uppercase tracking-wider", t.subtle),
925
+ children: item
926
+ },
927
+ i
928
+ )) })
929
+ ] })
930
+ }
931
+ ) });
932
+ }
933
+ function CtaBand({
934
+ title,
935
+ lead,
936
+ actions,
937
+ backdrop,
938
+ surface = "inverse",
939
+ className,
940
+ testId
941
+ }) {
942
+ const tone = SURFACE_TONE[surface];
943
+ const t = useEditorialTone(tone);
944
+ return /* @__PURE__ */ jsx(EditorialToneContext.Provider, { value: tone, children: /* @__PURE__ */ jsxs(
945
+ "section",
946
+ {
947
+ className: cn("relative isolate overflow-hidden", SURFACE_CLASS[surface], className),
948
+ "data-slot": "cta-band",
949
+ "data-testid": testId,
950
+ children: [
951
+ backdrop && /* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 -z-10", children: backdrop }),
952
+ /* @__PURE__ */ jsxs("div", { className: "mx-auto max-w-4xl px-5 py-20 text-center lg:px-8 lg:py-24", children: [
953
+ /* @__PURE__ */ jsx(
954
+ "h2",
955
+ {
956
+ className: cn(
957
+ "font-display text-3xl font-semibold tracking-tight text-balance sm:text-4xl",
958
+ t.text
959
+ ),
960
+ children: title
961
+ }
962
+ ),
963
+ lead && /* @__PURE__ */ jsx("p", { className: cn("mx-auto mt-4 max-w-2xl text-lg", t.muted), children: lead }),
964
+ actions && /* @__PURE__ */ jsx("div", { className: "mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row", children: actions })
965
+ ] })
966
+ ]
967
+ }
968
+ ) });
969
+ }
970
+
971
+ export { ArticleList, Chart, CheckList, CollectionDetail, CtaBand, DefinitionList, EditorialHeading, EditorialHero, EditorialProse, EditorialSection, Eyebrow, PanelGrid, ProofStrip, PullQuote, Reveal, TagList };
972
+ //# sourceMappingURL=chunk-OBLSURHV.js.map
973
+ //# sourceMappingURL=chunk-OBLSURHV.js.map