@walkeros/explorer 4.7.2 → 4.8.0-next-1791441510508

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.
@@ -0,0 +1,2626 @@
1
+ "use client"
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/design/components/index.ts
22
+ var components_exports = {};
23
+ __export(components_exports, {
24
+ ArticleTeaserTracking: () => ArticleTeaserTracking,
25
+ Button: () => Button,
26
+ Card: () => Card,
27
+ CardGrid: () => CardGrid,
28
+ CaseCard: () => CaseCard,
29
+ CheckList: () => CheckList,
30
+ Cluster: () => Cluster,
31
+ DestinationMappingViz: () => DestinationMappingViz,
32
+ EventLegend: () => EventLegend,
33
+ Eyebrow: () => Eyebrow,
34
+ FaqItem: () => FaqItem,
35
+ FeatureItem: () => FeatureItem,
36
+ Hero: () => Hero,
37
+ HeroTaggingViz: () => HeroTaggingViz,
38
+ HighlightCard: () => HighlightCard,
39
+ Icon: () => Icon,
40
+ InlineCode: () => InlineCode,
41
+ InstallCommand: () => InstallCommand,
42
+ PlanCard: () => PlanCard,
43
+ ProblemCard: () => ProblemCard,
44
+ Section: () => Section,
45
+ SectionHeading: () => SectionHeading,
46
+ Split: () => Split,
47
+ Stat: () => Stat,
48
+ Text: () => Text,
49
+ TextLink: () => TextLink
50
+ });
51
+ module.exports = __toCommonJS(components_exports);
52
+
53
+ // src/design/components/cx.ts
54
+ function cx(...names) {
55
+ return names.filter((name) => Boolean(name)).join(" ");
56
+ }
57
+
58
+ // src/design/components/atoms/Button.tsx
59
+ var import_jsx_runtime = require("react/jsx-runtime");
60
+ function classes({
61
+ variant = "primary",
62
+ block = false,
63
+ className
64
+ }) {
65
+ return cx(
66
+ "elb-btn",
67
+ `elb-btn--${variant}`,
68
+ block && "elb-btn--block",
69
+ className
70
+ );
71
+ }
72
+ function LinkButton({
73
+ children,
74
+ variant,
75
+ arrow,
76
+ block,
77
+ className,
78
+ linkComponent: Link,
79
+ ...anchor
80
+ }) {
81
+ const props = {
82
+ ...anchor,
83
+ className: classes({ variant, block, className })
84
+ };
85
+ const content = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
86
+ children,
87
+ arrow && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": "true", children: " \u2192" })
88
+ ] });
89
+ return Link ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Link, { ...props, children: content }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { ...props, children: content });
90
+ }
91
+ function ButtonElement({
92
+ children,
93
+ variant,
94
+ arrow,
95
+ block,
96
+ className,
97
+ type = "button",
98
+ ...rest
99
+ }) {
100
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
101
+ "button",
102
+ {
103
+ ...rest,
104
+ type,
105
+ className: classes({ variant, block, className }),
106
+ children: [
107
+ children,
108
+ arrow && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": "true", children: " \u2192" })
109
+ ]
110
+ }
111
+ );
112
+ }
113
+ function Button(props) {
114
+ return props.href === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ButtonElement, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LinkButton, { ...props });
115
+ }
116
+
117
+ // src/design/components/atoms/InlineCode.tsx
118
+ var import_jsx_runtime2 = require("react/jsx-runtime");
119
+ function InlineCode({ children, className, ...rest }) {
120
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { ...rest, className: cx("elb-code-inline", className), children });
121
+ }
122
+
123
+ // src/design/components/atoms/EventLegend.tsx
124
+ var import_jsx_runtime3 = require("react/jsx-runtime");
125
+ var PARTS = [
126
+ ["entity", "var(--event-entity)"],
127
+ ["action", "var(--event-action)"],
128
+ ["property", "var(--event-property)"],
129
+ ["context", "var(--event-context)"],
130
+ ["globals", "var(--event-globals)"]
131
+ ];
132
+ function EventLegend({ parts, className, ...rest }) {
133
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ...rest, className: cx("elb-legend", className), "data-theme": "dark", children: PARTS.filter(([part]) => !parts || parts.includes(part)).map(
134
+ ([part, color]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "elb-legend__item", children: [
135
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
136
+ "i",
137
+ {
138
+ className: "elb-legend__swatch",
139
+ style: { background: color },
140
+ "aria-hidden": "true"
141
+ }
142
+ ),
143
+ part
144
+ ] }, part)
145
+ ) });
146
+ }
147
+
148
+ // src/design/components/atoms/Icon.tsx
149
+ var import_jsx_runtime4 = require("react/jsx-runtime");
150
+ function Icon({ name, size = 16, className, ...rest }) {
151
+ const svg = {
152
+ "aria-hidden": true,
153
+ focusable: false,
154
+ ...rest,
155
+ width: size,
156
+ height: size,
157
+ className: cx("elb-icon", `elb-icon--${name}`, className)
158
+ };
159
+ return name === "check" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { ...svg, viewBox: "0 0 16 16", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
160
+ "path",
161
+ {
162
+ d: "M3 8.5l3 3 7-7",
163
+ fill: "none",
164
+ stroke: "currentColor",
165
+ strokeWidth: 2,
166
+ strokeLinecap: "round",
167
+ strokeLinejoin: "round"
168
+ }
169
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { ...svg, viewBox: "0 0 24 24", children: [
170
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
171
+ "rect",
172
+ {
173
+ x: 9,
174
+ y: 9,
175
+ width: 12,
176
+ height: 12,
177
+ rx: 2,
178
+ fill: "none",
179
+ stroke: "currentColor",
180
+ strokeWidth: 2
181
+ }
182
+ ),
183
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
184
+ "path",
185
+ {
186
+ d: "M5 15V5a2 2 0 0 1 2-2h10",
187
+ fill: "none",
188
+ stroke: "currentColor",
189
+ strokeWidth: 2
190
+ }
191
+ )
192
+ ] });
193
+ }
194
+
195
+ // src/design/components/atoms/Eyebrow.tsx
196
+ var import_jsx_runtime5 = require("react/jsx-runtime");
197
+ function Eyebrow({
198
+ children,
199
+ variant = "eyebrow",
200
+ tone = "link",
201
+ className,
202
+ ...rest
203
+ }) {
204
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
205
+ "p",
206
+ {
207
+ ...rest,
208
+ className: cx(
209
+ "elb-eyebrow",
210
+ variant === "label" && "elb-eyebrow--label",
211
+ tone === "muted" && "elb-eyebrow--muted",
212
+ className
213
+ ),
214
+ children
215
+ }
216
+ );
217
+ }
218
+
219
+ // src/design/components/atoms/Stat.tsx
220
+ var import_jsx_runtime6 = require("react/jsx-runtime");
221
+ function Stat({ value, children, className, ...rest }) {
222
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ...rest, className: cx("elb-stat", className), children: [
223
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "elb-stat__value", children: value }),
224
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "elb-stat__label", children })
225
+ ] });
226
+ }
227
+
228
+ // src/design/components/atoms/Text.tsx
229
+ var import_jsx_runtime7 = require("react/jsx-runtime");
230
+ function Text({
231
+ children,
232
+ size = "body",
233
+ tone = "muted",
234
+ className,
235
+ ...rest
236
+ }) {
237
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
238
+ "p",
239
+ {
240
+ ...rest,
241
+ className: cx(
242
+ "elb-text",
243
+ size === "lg" && "elb-text--lg",
244
+ tone === "fg" && "elb-text--fg",
245
+ className
246
+ ),
247
+ children
248
+ }
249
+ );
250
+ }
251
+
252
+ // src/design/components/atoms/TextLink.tsx
253
+ var import_jsx_runtime8 = require("react/jsx-runtime");
254
+ function TextLink({
255
+ href,
256
+ children,
257
+ tone = "link",
258
+ arrow = false,
259
+ linkComponent: Link,
260
+ className,
261
+ ...rest
262
+ }) {
263
+ const props = {
264
+ ...rest,
265
+ href,
266
+ className: cx(
267
+ "elb-text-link",
268
+ tone === "muted" && "elb-text-link--muted",
269
+ className
270
+ )
271
+ };
272
+ const content = /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
273
+ children,
274
+ arrow && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "aria-hidden": "true", children: " \u2192" })
275
+ ] });
276
+ return Link ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Link, { ...props, children: content }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("a", { ...props, children: content });
277
+ }
278
+
279
+ // src/design/components/atoms/Card.tsx
280
+ var import_jsx_runtime9 = require("react/jsx-runtime");
281
+ function Card({
282
+ children,
283
+ padding = "md",
284
+ radius = "lg",
285
+ hover = false,
286
+ highlight = false,
287
+ glow = false,
288
+ className,
289
+ ...rest
290
+ }) {
291
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
292
+ "div",
293
+ {
294
+ ...rest,
295
+ className: cx(
296
+ "elb-card",
297
+ `elb-card--pad-${padding}`,
298
+ radius === "xl" && "elb-card--radius-xl",
299
+ hover && "elb-card--hover",
300
+ highlight && "elb-card--highlight",
301
+ glow && "elb-card--glow",
302
+ className
303
+ ),
304
+ children
305
+ }
306
+ );
307
+ }
308
+
309
+ // src/design/components/atoms/InstallCommand.tsx
310
+ var import_react = require("react");
311
+ var import_jsx_runtime10 = require("react/jsx-runtime");
312
+ var CONFIRM_MS = 1400;
313
+ async function copyText(text) {
314
+ try {
315
+ await navigator.clipboard.writeText(text);
316
+ return true;
317
+ } catch {
318
+ return false;
319
+ }
320
+ }
321
+ function InstallCommand({
322
+ command = "npm i -g @walkeros/cli",
323
+ className,
324
+ "aria-describedby": describedBy,
325
+ ...rest
326
+ }) {
327
+ const hintId = (0, import_react.useId)();
328
+ const [state, setState] = (0, import_react.useState)("idle");
329
+ const mounted = (0, import_react.useRef)(true);
330
+ const timer = (0, import_react.useRef)(void 0);
331
+ (0, import_react.useEffect)(() => {
332
+ mounted.current = true;
333
+ return () => {
334
+ mounted.current = false;
335
+ clearTimeout(timer.current);
336
+ };
337
+ }, []);
338
+ const copy = async () => {
339
+ const copied = await copyText(command);
340
+ if (!mounted.current) return;
341
+ clearTimeout(timer.current);
342
+ setState(copied ? "done" : "failed");
343
+ if (copied) timer.current = setTimeout(() => setState("idle"), CONFIRM_MS);
344
+ };
345
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
346
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
347
+ "button",
348
+ {
349
+ ...rest,
350
+ "aria-describedby": describedBy ? `${hintId} ${describedBy}` : hintId,
351
+ type: "button",
352
+ className: cx("elb-cmd", className),
353
+ onClick: () => {
354
+ void copy();
355
+ },
356
+ children: [
357
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
358
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "elb-cmd__prompt", "aria-hidden": "true", children: [
359
+ "$",
360
+ " "
361
+ ] }),
362
+ command
363
+ ] }),
364
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
365
+ "span",
366
+ {
367
+ className: cx(
368
+ "elb-cmd__icon",
369
+ state === "done" && "elb-cmd__icon--done"
370
+ ),
371
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { name: state === "done" ? "check" : "copy" })
372
+ }
373
+ )
374
+ ]
375
+ }
376
+ ),
377
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { id: hintId, hidden: true, children: "Copy install command" }),
378
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "elb-cmd__status", role: "status", children: state === "done" ? "Copied" : state === "failed" ? "Copy failed" : "" })
379
+ ] });
380
+ }
381
+
382
+ // src/design/components/molecules/CheckList.tsx
383
+ var import_jsx_runtime11 = require("react/jsx-runtime");
384
+ function CheckList({
385
+ items,
386
+ layout = "inline",
387
+ align = "start",
388
+ className,
389
+ ...rest
390
+ }) {
391
+ const stack = layout === "stack";
392
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
393
+ "ul",
394
+ {
395
+ ...rest,
396
+ className: cx(
397
+ "elb-checklist",
398
+ stack && "elb-checklist--stack",
399
+ align === "center" && "elb-checklist--center",
400
+ className
401
+ ),
402
+ children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("li", { className: "elb-checklist__item", children: [
403
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { name: "check", size: stack ? 14 : 16 }),
404
+ item
405
+ ] }, index))
406
+ }
407
+ );
408
+ }
409
+
410
+ // src/design/components/molecules/SectionHeading.tsx
411
+ var import_jsx_runtime12 = require("react/jsx-runtime");
412
+ function SectionHeading({
413
+ title,
414
+ eyebrow,
415
+ lead,
416
+ level = 2,
417
+ size = "lg",
418
+ highlight,
419
+ align = "start",
420
+ className,
421
+ ...rest
422
+ }) {
423
+ const hero = level === 1;
424
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
425
+ "div",
426
+ {
427
+ ...rest,
428
+ className: cx(
429
+ "elb-sh",
430
+ (hero || align === "center") && "elb-sh--center",
431
+ className
432
+ ),
433
+ children: [
434
+ eyebrow !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Eyebrow, { children: eyebrow }),
435
+ hero ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("h1", { className: "elb-sh__title elb-sh__title--display", children: [
436
+ title,
437
+ highlight !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
438
+ " ",
439
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "elb-sh__highlight", children: highlight })
440
+ ] })
441
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h2", { className: cx("elb-sh__title", `elb-sh__title--${size}`), children: title }),
442
+ lead !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: cx("elb-sh__lead", hero && "elb-sh__lead--hero"), children: lead })
443
+ ]
444
+ }
445
+ );
446
+ }
447
+
448
+ // src/design/components/molecules/ProblemCard.tsx
449
+ var import_jsx_runtime13 = require("react/jsx-runtime");
450
+ function ProblemCard({
451
+ number,
452
+ title,
453
+ children,
454
+ className,
455
+ ...rest
456
+ }) {
457
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
458
+ Card,
459
+ {
460
+ ...rest,
461
+ padding: "sm",
462
+ hover: true,
463
+ className: cx("elb-problem-card", className),
464
+ children: [
465
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("h3", { className: "elb-problem-card__title", children: [
466
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "elb-problem-card__number", children: number }),
467
+ title
468
+ ] }),
469
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "elb-problem-card__text", children })
470
+ ]
471
+ }
472
+ );
473
+ }
474
+
475
+ // src/design/components/molecules/FeatureItem.tsx
476
+ var import_jsx_runtime14 = require("react/jsx-runtime");
477
+ function FeatureItem({
478
+ title,
479
+ children,
480
+ href,
481
+ linkLabel = "Docs",
482
+ linkComponent,
483
+ linkAttributes,
484
+ className,
485
+ ...rest
486
+ }) {
487
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { ...rest, className: cx("elb-feature", className), children: [
488
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { name: "check", size: 20 }),
489
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
490
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "elb-feature__title", children: title }),
491
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "elb-feature__text", children }),
492
+ href !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
493
+ TextLink,
494
+ {
495
+ ...linkAttributes,
496
+ href,
497
+ arrow: true,
498
+ linkComponent,
499
+ className: "elb-feature__link",
500
+ children: linkLabel
501
+ }
502
+ )
503
+ ] })
504
+ ] });
505
+ }
506
+
507
+ // src/design/components/molecules/FaqItem.tsx
508
+ var import_react2 = require("react");
509
+ var import_jsx_runtime15 = require("react/jsx-runtime");
510
+ function FaqItem({
511
+ question,
512
+ children,
513
+ className,
514
+ ...rest
515
+ }) {
516
+ const parts = Array.isArray(children) ? children : [children];
517
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("details", { ...rest, className: cx("elb-faq", className), children: [
518
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("summary", { className: "elb-faq__question", children: question }),
519
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "elb-faq__answer", children: parts.map(
520
+ (part, index) => typeof part === "string" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { children: part }, index) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react2.Fragment, { children: part }, index)
521
+ ) })
522
+ ] });
523
+ }
524
+
525
+ // src/design/components/molecules/PlanCard.tsx
526
+ var import_jsx_runtime16 = require("react/jsx-runtime");
527
+ function PlanCard({
528
+ label,
529
+ title,
530
+ children,
531
+ features,
532
+ cta,
533
+ highlight = false,
534
+ linkComponent,
535
+ className,
536
+ ...rest
537
+ }) {
538
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
539
+ Card,
540
+ {
541
+ ...rest,
542
+ padding: "md",
543
+ highlight,
544
+ className: cx("elb-plan", className),
545
+ children: [
546
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Eyebrow, { variant: "label", tone: highlight ? "link" : "muted", children: label }),
547
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h3", { className: "elb-plan__title", children: title }),
548
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "elb-plan__text", children }),
549
+ features && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(CheckList, { items: features, layout: "stack" }),
550
+ cta && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
551
+ Button,
552
+ {
553
+ ...cta.attributes,
554
+ href: cta.href,
555
+ variant: highlight ? "primary" : "secondary",
556
+ block: true,
557
+ linkComponent,
558
+ children: cta.label
559
+ }
560
+ )
561
+ ]
562
+ }
563
+ );
564
+ }
565
+
566
+ // src/design/components/molecules/CaseCard.tsx
567
+ var import_jsx_runtime17 = require("react/jsx-runtime");
568
+ function CaseCard({
569
+ label,
570
+ title,
571
+ children,
572
+ stats,
573
+ className,
574
+ ...rest
575
+ }) {
576
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Card, { ...rest, padding: "md", className: cx("elb-case-card", className), children: [
577
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Eyebrow, { variant: "label", children: label }),
578
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "elb-case-card__title", children: title }),
579
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "elb-case-card__text", children }),
580
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "elb-case-card__stats", children: stats.map((stat, index) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Stat, { value: stat.value, children: stat.label }, index)) })
581
+ ] });
582
+ }
583
+
584
+ // src/design/components/molecules/HighlightCard.tsx
585
+ var import_jsx_runtime18 = require("react/jsx-runtime");
586
+ function HighlightCard({
587
+ label,
588
+ title,
589
+ children,
590
+ cta,
591
+ linkComponent,
592
+ className,
593
+ ...rest
594
+ }) {
595
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
596
+ Card,
597
+ {
598
+ ...rest,
599
+ padding: "lg",
600
+ radius: "xl",
601
+ hover: true,
602
+ glow: true,
603
+ className: cx("elb-highlight-card", className),
604
+ children: [
605
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Eyebrow, { variant: "label", children: label }),
606
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { className: "elb-highlight-card__title", children: title }),
607
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "elb-highlight-card__text", children }),
608
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
609
+ Button,
610
+ {
611
+ ...cta.attributes,
612
+ href: cta.href,
613
+ variant: "secondary",
614
+ arrow: true,
615
+ linkComponent,
616
+ className: "elb-highlight-card__cta",
617
+ children: cta.label
618
+ }
619
+ )
620
+ ]
621
+ }
622
+ );
623
+ }
624
+
625
+ // src/design/components/layout/Section.tsx
626
+ var import_jsx_runtime19 = require("react/jsx-runtime");
627
+ function Section({
628
+ children,
629
+ tone = "default",
630
+ className,
631
+ ...rest
632
+ }) {
633
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
634
+ "section",
635
+ {
636
+ ...rest,
637
+ className: cx(
638
+ "elb-section",
639
+ tone === "alt" && "elb-section--alt",
640
+ className
641
+ ),
642
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "elb-section__inner", children })
643
+ }
644
+ );
645
+ }
646
+
647
+ // src/design/components/layout/CardGrid.tsx
648
+ var import_jsx_runtime20 = require("react/jsx-runtime");
649
+ function CardGrid({
650
+ children,
651
+ min,
652
+ gap = "cards",
653
+ className,
654
+ ...rest
655
+ }) {
656
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
657
+ "div",
658
+ {
659
+ ...rest,
660
+ className: cx(
661
+ "elb-card-grid",
662
+ `elb-card-grid--min-${min}`,
663
+ gap === "features" && "elb-card-grid--features",
664
+ className
665
+ ),
666
+ children
667
+ }
668
+ );
669
+ }
670
+
671
+ // src/design/components/layout/Split.tsx
672
+ var import_jsx_runtime21 = require("react/jsx-runtime");
673
+ function Split({
674
+ start,
675
+ end,
676
+ variant = "even",
677
+ className,
678
+ ...rest
679
+ }) {
680
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
681
+ "div",
682
+ {
683
+ ...rest,
684
+ className: cx(
685
+ "elb-split",
686
+ variant === "aside" && "elb-split--aside",
687
+ className
688
+ ),
689
+ children: [
690
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "elb-split__start", children: start }),
691
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "elb-split__end", children: end })
692
+ ]
693
+ }
694
+ );
695
+ }
696
+
697
+ // src/design/components/layout/Cluster.tsx
698
+ var import_jsx_runtime22 = require("react/jsx-runtime");
699
+ function Cluster({
700
+ children,
701
+ gap = "actions",
702
+ align = "start",
703
+ className,
704
+ ...rest
705
+ }) {
706
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
707
+ "div",
708
+ {
709
+ ...rest,
710
+ className: cx(
711
+ "elb-cluster",
712
+ gap === "links" && "elb-cluster--links",
713
+ align === "center" && "elb-cluster--center",
714
+ className
715
+ ),
716
+ children
717
+ }
718
+ );
719
+ }
720
+
721
+ // src/design/components/layout/Hero.tsx
722
+ var import_jsx_runtime23 = require("react/jsx-runtime");
723
+ function Hero({
724
+ eyebrow,
725
+ title,
726
+ highlight,
727
+ lead,
728
+ actions,
729
+ proof,
730
+ children,
731
+ className,
732
+ ...rest
733
+ }) {
734
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("section", { ...rest, className: cx("elb-hero", className), children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "elb-hero__inner", children: [
735
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
736
+ SectionHeading,
737
+ {
738
+ level: 1,
739
+ eyebrow,
740
+ title,
741
+ highlight,
742
+ lead
743
+ }
744
+ ),
745
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "elb-hero__actions", children: actions }),
746
+ proof !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "elb-hero__proof", children: proof }),
747
+ children !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "elb-hero__demo", children })
748
+ ] }) });
749
+ }
750
+
751
+ // src/design/components/viz/DestinationMappingViz.tsx
752
+ var import_react3 = require("react");
753
+
754
+ // src/design/components/viz/data/destination-mapping.ts
755
+ var GENERATED_ID = "\u2026";
756
+ var MAPPING_CAPTION = "50+ destination packages ship with the project. Removing GA4 or adding a new pixel is a block in this file, not a re-instrumentation project across every page.";
757
+ var GA4_MEASUREMENT_ID = "G-XXXXXXXXXX";
758
+ var MAPPING_EVENTS = [
759
+ {
760
+ entity: "product",
761
+ action: "view",
762
+ data: { id: "ers", price: 420, currency: "EUR" },
763
+ destinations: [
764
+ {
765
+ id: "ga4",
766
+ label: "GA4",
767
+ rule: {
768
+ name: "view_item",
769
+ data: {
770
+ map: {
771
+ currency: "data.currency",
772
+ value: "data.price",
773
+ items: { loop: ["this", { map: { item_id: "data.id" } }] }
774
+ }
775
+ }
776
+ },
777
+ calls: [
778
+ [
779
+ "gtag",
780
+ "event",
781
+ "view_item",
782
+ {
783
+ currency: "EUR",
784
+ value: 420,
785
+ items: [{ item_id: "ers" }],
786
+ send_to: GA4_MEASUREMENT_ID
787
+ }
788
+ ]
789
+ ]
790
+ },
791
+ {
792
+ id: "meta",
793
+ label: "Meta Pixel",
794
+ rule: {
795
+ name: "ViewContent",
796
+ data: {
797
+ map: {
798
+ value: "data.price",
799
+ currency: "data.currency",
800
+ contents: {
801
+ set: [
802
+ {
803
+ map: {
804
+ id: "data.id",
805
+ quantity: { key: "data.quantity", value: 1 }
806
+ }
807
+ }
808
+ ]
809
+ },
810
+ content_type: { value: "product" }
811
+ }
812
+ }
813
+ },
814
+ calls: [
815
+ [
816
+ "fbq",
817
+ "track",
818
+ "ViewContent",
819
+ {
820
+ value: 420,
821
+ currency: "EUR",
822
+ contents: [{ id: "ers", quantity: 1 }],
823
+ content_type: "product"
824
+ },
825
+ { eventID: GENERATED_ID }
826
+ ]
827
+ ]
828
+ },
829
+ {
830
+ id: "tiktok",
831
+ label: "TikTok Pixel",
832
+ rule: {
833
+ name: "ViewContent",
834
+ data: {
835
+ map: {
836
+ content_id: "data.id",
837
+ content_type: { value: "product" },
838
+ value: "data.price",
839
+ currency: "data.currency"
840
+ }
841
+ }
842
+ },
843
+ calls: [
844
+ [
845
+ "ttq.track",
846
+ "ViewContent",
847
+ {
848
+ content_id: "ers",
849
+ content_type: "product",
850
+ value: 420,
851
+ currency: "EUR"
852
+ },
853
+ { event_id: GENERATED_ID }
854
+ ]
855
+ ]
856
+ },
857
+ {
858
+ id: "amplitude",
859
+ label: "Amplitude",
860
+ rule: {
861
+ name: "Product Viewed",
862
+ data: {
863
+ map: {
864
+ product_id: "data.id",
865
+ price: "data.price",
866
+ currency: "data.currency"
867
+ }
868
+ }
869
+ },
870
+ calls: [
871
+ [
872
+ "amplitude.track",
873
+ "Product Viewed",
874
+ { product_id: "ers", price: 420, currency: "EUR" }
875
+ ]
876
+ ]
877
+ }
878
+ ]
879
+ },
880
+ {
881
+ entity: "lead",
882
+ action: "submit",
883
+ data: { type: "demo", value: 2500, currency: "EUR" },
884
+ destinations: [
885
+ {
886
+ id: "ga4",
887
+ label: "GA4",
888
+ rule: {
889
+ name: "generate_lead",
890
+ data: { map: { value: "data.value", currency: "data.currency" } }
891
+ },
892
+ calls: [
893
+ [
894
+ "gtag",
895
+ "event",
896
+ "generate_lead",
897
+ { value: 2500, currency: "EUR", send_to: GA4_MEASUREMENT_ID }
898
+ ]
899
+ ]
900
+ },
901
+ {
902
+ id: "meta",
903
+ label: "Meta Pixel",
904
+ rule: {
905
+ name: "Lead",
906
+ data: { map: { value: "data.value", currency: "data.currency" } }
907
+ },
908
+ calls: [
909
+ [
910
+ "fbq",
911
+ "track",
912
+ "Lead",
913
+ { value: 2500, currency: "EUR" },
914
+ { eventID: GENERATED_ID }
915
+ ]
916
+ ]
917
+ },
918
+ {
919
+ id: "tiktok",
920
+ label: "TikTok Pixel",
921
+ rule: {
922
+ name: "Contact",
923
+ data: { map: { value: "data.value", currency: "data.currency" } }
924
+ },
925
+ calls: [
926
+ [
927
+ "ttq.track",
928
+ "Contact",
929
+ { value: 2500, currency: "EUR" },
930
+ { event_id: GENERATED_ID }
931
+ ]
932
+ ]
933
+ },
934
+ {
935
+ id: "amplitude",
936
+ label: "Amplitude",
937
+ rule: {
938
+ name: "Lead Submitted",
939
+ data: {
940
+ map: {
941
+ lead_type: "data.type",
942
+ value: "data.value",
943
+ currency: "data.currency"
944
+ }
945
+ }
946
+ },
947
+ calls: [
948
+ [
949
+ "amplitude.track",
950
+ "Lead Submitted",
951
+ { lead_type: "demo", value: 2500, currency: "EUR" }
952
+ ]
953
+ ]
954
+ }
955
+ ]
956
+ },
957
+ {
958
+ entity: "order",
959
+ action: "complete",
960
+ data: { id: "0rd3r1d", value: 462, currency: "EUR" },
961
+ nested: [
962
+ { entity: "product", data: { id: "ers", price: 420, quantity: 1 } }
963
+ ],
964
+ destinations: [
965
+ {
966
+ id: "ga4",
967
+ label: "GA4",
968
+ rule: {
969
+ name: "purchase",
970
+ data: {
971
+ map: {
972
+ transaction_id: "data.id",
973
+ value: "data.value",
974
+ currency: "data.currency",
975
+ items: {
976
+ loop: [
977
+ "nested",
978
+ {
979
+ map: {
980
+ item_id: "data.id",
981
+ price: "data.price",
982
+ quantity: "data.quantity"
983
+ }
984
+ }
985
+ ]
986
+ }
987
+ }
988
+ }
989
+ },
990
+ calls: [
991
+ [
992
+ "gtag",
993
+ "event",
994
+ "purchase",
995
+ {
996
+ transaction_id: "0rd3r1d",
997
+ value: 462,
998
+ currency: "EUR",
999
+ items: [{ item_id: "ers", price: 420, quantity: 1 }],
1000
+ send_to: GA4_MEASUREMENT_ID
1001
+ }
1002
+ ]
1003
+ ]
1004
+ },
1005
+ {
1006
+ id: "meta",
1007
+ label: "Meta Pixel",
1008
+ rule: {
1009
+ name: "Purchase",
1010
+ data: {
1011
+ map: {
1012
+ value: "data.value",
1013
+ currency: "data.currency",
1014
+ contents: {
1015
+ loop: [
1016
+ "nested",
1017
+ { map: { id: "data.id", quantity: "data.quantity" } }
1018
+ ]
1019
+ },
1020
+ content_type: { value: "product" }
1021
+ }
1022
+ }
1023
+ },
1024
+ calls: [
1025
+ [
1026
+ "fbq",
1027
+ "track",
1028
+ "Purchase",
1029
+ {
1030
+ value: 462,
1031
+ currency: "EUR",
1032
+ contents: [{ id: "ers", quantity: 1 }],
1033
+ content_type: "product"
1034
+ },
1035
+ { eventID: GENERATED_ID }
1036
+ ]
1037
+ ]
1038
+ },
1039
+ {
1040
+ id: "tiktok",
1041
+ label: "TikTok Pixel",
1042
+ rule: {
1043
+ name: "CompletePayment",
1044
+ data: {
1045
+ map: {
1046
+ order_id: "data.id",
1047
+ value: "data.value",
1048
+ currency: "data.currency",
1049
+ contents: {
1050
+ loop: [
1051
+ "nested",
1052
+ {
1053
+ map: {
1054
+ content_id: "data.id",
1055
+ quantity: "data.quantity",
1056
+ price: "data.price"
1057
+ }
1058
+ }
1059
+ ]
1060
+ },
1061
+ content_type: { value: "product" }
1062
+ }
1063
+ }
1064
+ },
1065
+ calls: [
1066
+ [
1067
+ "ttq.track",
1068
+ "CompletePayment",
1069
+ {
1070
+ order_id: "0rd3r1d",
1071
+ value: 462,
1072
+ currency: "EUR",
1073
+ contents: [{ content_id: "ers", quantity: 1, price: 420 }],
1074
+ content_type: "product"
1075
+ },
1076
+ { event_id: GENERATED_ID }
1077
+ ]
1078
+ ]
1079
+ },
1080
+ {
1081
+ id: "amplitude",
1082
+ label: "Amplitude",
1083
+ rule: {
1084
+ silent: true,
1085
+ settings: {
1086
+ revenue: {
1087
+ loop: [
1088
+ "nested",
1089
+ {
1090
+ map: {
1091
+ productId: "data.id",
1092
+ price: "data.price",
1093
+ quantity: "data.quantity",
1094
+ revenueType: { value: "purchase" },
1095
+ currency: { value: "EUR" }
1096
+ }
1097
+ }
1098
+ ]
1099
+ }
1100
+ }
1101
+ },
1102
+ calls: [
1103
+ [
1104
+ "amplitude.revenue",
1105
+ {
1106
+ productId: "ers",
1107
+ price: 420,
1108
+ quantity: 1,
1109
+ revenueType: "purchase",
1110
+ currency: "EUR"
1111
+ }
1112
+ ]
1113
+ ]
1114
+ }
1115
+ ]
1116
+ }
1117
+ ];
1118
+
1119
+ // src/design/components/viz/parts/CodeTokens.tsx
1120
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1121
+ function CodeTokens({
1122
+ tokens,
1123
+ active = false
1124
+ }) {
1125
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: tokens.map((token, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1126
+ "span",
1127
+ {
1128
+ className: cx(
1129
+ "elb-viz-tok",
1130
+ `elb-viz-tok--${token.kind}`,
1131
+ active && token.mark && `elb-viz-tok--mark-${token.mark}`
1132
+ ),
1133
+ children: token.t
1134
+ },
1135
+ index
1136
+ )) });
1137
+ }
1138
+ function CodeLine({ number, bar, className, children }) {
1139
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cx("elb-viz-line", className), children: [
1140
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1141
+ "span",
1142
+ {
1143
+ className: cx("elb-viz-line__bar", bar && `elb-viz-line__bar--${bar}`),
1144
+ "aria-hidden": "true"
1145
+ }
1146
+ ),
1147
+ number !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "elb-viz-line__number", children: number }),
1148
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "elb-viz-line__code", children })
1149
+ ] });
1150
+ }
1151
+
1152
+ // src/design/components/viz/parts/tokens.ts
1153
+ function tok(t, kind, mark) {
1154
+ return mark ? { t, kind, mark } : { t, kind };
1155
+ }
1156
+ function typedLength(tokens) {
1157
+ return tokens.reduce((length, token) => length + token.t.length, 0);
1158
+ }
1159
+ function truncate(tokens, n) {
1160
+ const out = [];
1161
+ let left = n;
1162
+ for (const token of tokens) {
1163
+ if (left <= 0) break;
1164
+ const t = token.t.slice(0, left);
1165
+ out.push({ ...token, t });
1166
+ left -= t.length;
1167
+ }
1168
+ return out;
1169
+ }
1170
+
1171
+ // src/design/components/viz/parts/format.ts
1172
+ var ELIDED = "{\u2026}";
1173
+ function isRecord(value) {
1174
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1175
+ }
1176
+ function literal(value) {
1177
+ if (typeof value === "string")
1178
+ return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
1179
+ if (typeof value !== "object" || value === null) return String(value);
1180
+ if (Array.isArray(value)) return `[${value.map(literal).join(", ")}]`;
1181
+ const entries = Object.entries(value);
1182
+ return entries.length === 0 ? "{}" : `{ ${entries.map(([key, item]) => `${key}: ${literal(item)}`).join(", ")} }`;
1183
+ }
1184
+ function formatRule(entity, action, rule) {
1185
+ const fields = [];
1186
+ if (rule.name !== void 0) fields.push(`"name": "${rule.name}"`);
1187
+ if (rule.silent) fields.push('"silent": true');
1188
+ if (rule.data !== void 0) fields.push(`"data": ${ELIDED}`);
1189
+ if (rule.settings !== void 0) {
1190
+ const settings = Object.keys(rule.settings).map(
1191
+ (key) => `"${key}": ${ELIDED}`
1192
+ );
1193
+ fields.push(`"settings": { ${settings.join(", ")} }`);
1194
+ }
1195
+ return `"${entity}": { "${action}": { ${fields.join(", ")} } }`;
1196
+ }
1197
+ function formatCall(record) {
1198
+ const [fn, ...args] = record;
1199
+ const at = args.findIndex(isRecord);
1200
+ const params = args[at];
1201
+ if (at < 0 || params === void 0 || !isRecord(params))
1202
+ return [`${fn}(${args.map(literal).join(", ")})`];
1203
+ const fields = Object.entries(params);
1204
+ if (fn === "amplitude.revenue") {
1205
+ if (fields.length === 0) return ["amplitude.revenue(new Revenue())"];
1206
+ return [
1207
+ "amplitude.revenue(new Revenue()",
1208
+ ...fields.map(
1209
+ ([key, value], index) => ` .set${key.charAt(0).toUpperCase()}${key.slice(1)}(${literal(value)})${index === fields.length - 1 ? ")" : ""}`
1210
+ )
1211
+ ];
1212
+ }
1213
+ const before = args.slice(0, at).map(literal);
1214
+ const after = args.slice(at + 1).map(literal);
1215
+ return [
1216
+ `${fn}(${[...before, "{"].join(", ")}`,
1217
+ ...fields.map(([key, value]) => ` ${key}: ${literal(value)},`),
1218
+ `}${after.map((arg) => `, ${arg}`).join("")})`
1219
+ ];
1220
+ }
1221
+ function formatElb(event) {
1222
+ const name = literal(`${event.entity} ${event.action}`);
1223
+ const data = literal(event.data);
1224
+ if (!event.nested?.length) return `elb(${name}, ${data})`;
1225
+ const nested = event.nested.map(
1226
+ (entity) => `{ entity: ${literal(entity.entity)}, \u2026 }`
1227
+ );
1228
+ return `elb({ name: ${name}, data: ${data}, nested: [${nested.join(", ")}] })`;
1229
+ }
1230
+ var TOKEN = /"[^"]*"|'[^']*'|\d+(?:\.\d+)?|[A-Za-z_]\w*|\s+|./g;
1231
+ var CALLS = /^(?:gtag|fbq|elb|ttq|track|amplitude|revenue|Revenue|set[A-Z]\w*)$/;
1232
+ function tokenizeCode(line, highlight) {
1233
+ const tokens = [];
1234
+ for (const match of line.matchAll(TOKEN)) {
1235
+ const t = match[0];
1236
+ const isKey = /^\s*:/.test(line.slice((match.index ?? 0) + t.length));
1237
+ if (t.startsWith('"') || t.startsWith("'")) {
1238
+ const marked = highlight !== void 0 && t.slice(1, -1) === highlight;
1239
+ tokens.push(
1240
+ tok(t, isKey ? "key" : "value", marked ? "entity" : void 0)
1241
+ );
1242
+ } else if (/^\d/.test(t) || t === "true" || t === "false") {
1243
+ tokens.push(tok(t, "num"));
1244
+ } else if (CALLS.test(t)) {
1245
+ tokens.push(tok(t, "fn"));
1246
+ } else if (/^[A-Za-z_]/.test(t)) {
1247
+ tokens.push(tok(t, isKey ? "key" : "text"));
1248
+ } else if (/^\s+$/.test(t)) {
1249
+ tokens.push(tok(t, "text"));
1250
+ } else {
1251
+ tokens.push(tok(t, "punct"));
1252
+ }
1253
+ }
1254
+ return tokens;
1255
+ }
1256
+
1257
+ // src/design/components/viz/parts/VizFrame.tsx
1258
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1259
+ function VizFrame({
1260
+ variant,
1261
+ children,
1262
+ className,
1263
+ ...rest
1264
+ }) {
1265
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1266
+ "div",
1267
+ {
1268
+ ...rest,
1269
+ "data-theme": "dark",
1270
+ className: cx("elb-viz", `elb-viz--${variant}`, className),
1271
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "elb-viz__body", children })
1272
+ }
1273
+ );
1274
+ }
1275
+
1276
+ // src/design/components/viz/DestinationMappingViz.tsx
1277
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1278
+ function DestinationMappingViz({
1279
+ initialEvent = 0,
1280
+ caption = MAPPING_CAPTION,
1281
+ ...rest
1282
+ }) {
1283
+ const [index, setIndex] = (0, import_react3.useState)(initialEvent);
1284
+ const event = MAPPING_EVENTS[index];
1285
+ const name = `${event.entity} ${event.action}`;
1286
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(VizFrame, { ...rest, variant: "mapping", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "elb-viz-mapping", children: [
1287
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "elb-viz-mapping__pick", children: [
1288
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "elb-viz-mapping__label", children: "Pick an event" }),
1289
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "elb-viz-mapping__chips", children: MAPPING_EVENTS.map((item, position) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1290
+ "button",
1291
+ {
1292
+ type: "button",
1293
+ "aria-label": `${item.entity} ${item.action}`,
1294
+ "aria-pressed": position === index,
1295
+ className: cx(
1296
+ "elb-viz-mapping__chip",
1297
+ position === index && "elb-viz-mapping__chip--active"
1298
+ ),
1299
+ onClick: () => setIndex(position),
1300
+ children: [
1301
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "elb-viz-mapping__chip-entity", children: item.entity }),
1302
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "elb-viz-mapping__chip-action", children: item.action })
1303
+ ]
1304
+ },
1305
+ `${item.entity} ${item.action}`
1306
+ )) })
1307
+ ] }),
1308
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "elb-viz-mapping__event", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CodeTokens, { tokens: tokenizeCode(formatElb(event), name), active: true }) }),
1309
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "elb-viz-mapping__body", children: [
1310
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "elb-viz-mapping__comment", children: "// same event, four destinations, zero app code touched" }),
1311
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "elb-viz-mapping__cards", children: event.destinations.map((destination) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "elb-viz-mapping__card", children: [
1312
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "elb-viz-mapping__name", children: destination.label }),
1313
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "elb-viz-mapping__row", children: [
1314
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "elb-viz-mapping__tag", children: "mapping" }),
1315
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "elb-viz-mapping__rule", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1316
+ CodeTokens,
1317
+ {
1318
+ tokens: tokenizeCode(
1319
+ formatRule(
1320
+ event.entity,
1321
+ event.action,
1322
+ destination.rule
1323
+ ),
1324
+ destination.rule.name
1325
+ ),
1326
+ active: true
1327
+ }
1328
+ ) })
1329
+ ] }),
1330
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "elb-viz-mapping__row elb-viz-mapping__row--sends", children: [
1331
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "elb-viz-mapping__tag", children: "sends" }),
1332
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "elb-viz-mapping__calls", children: destination.calls.flatMap((call) => formatCall(call)).map((line, position) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "elb-viz-mapping__line", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1333
+ CodeTokens,
1334
+ {
1335
+ tokens: tokenizeCode(line, destination.rule.name),
1336
+ active: true
1337
+ }
1338
+ ) }, position)) })
1339
+ ] })
1340
+ ] }, destination.id)) })
1341
+ ] }),
1342
+ caption !== "" && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "elb-viz-mapping__caption", children: caption })
1343
+ ] }) });
1344
+ }
1345
+
1346
+ // src/design/components/viz/HeroTaggingViz.tsx
1347
+ var import_react6 = require("react");
1348
+
1349
+ // src/design/components/viz/parts/timeline.ts
1350
+ function clamp(x) {
1351
+ return Math.max(0, Math.min(1, x));
1352
+ }
1353
+ function ease(x) {
1354
+ return x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2;
1355
+ }
1356
+
1357
+ // src/design/components/viz/data/hero.ts
1358
+ var HERO_ARTICLES = [
1359
+ { kicker: "Tech", title: "Return of the Bug", thumb: "bug" },
1360
+ { kicker: "Tech", title: "The quiet return of RSS", thumb: "tech" },
1361
+ { kicker: "Food", title: "Why sourdough came back", thumb: "food" }
1362
+ ];
1363
+ var HERO_START = 9e3;
1364
+ var HERO_LOOP = 11500;
1365
+ var CUE = {
1366
+ slideInStart: 0,
1367
+ slideInEnd: 500,
1368
+ entityStart: 900,
1369
+ entityEnd: 1500,
1370
+ impressionStart: 1800,
1371
+ impressionEnd: 2600,
1372
+ categoryStart: 2900,
1373
+ categoryEnd: 3600,
1374
+ titleStart: 3900,
1375
+ titleEnd: 4700,
1376
+ actionStart: 5e3,
1377
+ actionEnd: 5800,
1378
+ impressionEvent: 6200,
1379
+ moveStart: 6900,
1380
+ moveEnd: 7700,
1381
+ click: 7850,
1382
+ openEvent: 8e3,
1383
+ fadeOut: 10600,
1384
+ slideOutStart: 10800,
1385
+ slideOutEnd: 11400
1386
+ };
1387
+ var MAX_ROWS = 24;
1388
+ var PAST = 1e4;
1389
+ var ENTITY = [
1390
+ tok("data-elb", "attr"),
1391
+ tok("=", "punct"),
1392
+ tok('"article"', "str")
1393
+ ];
1394
+ var IMPRESSION = [
1395
+ tok("data-elbaction", "attr"),
1396
+ tok("=", "punct"),
1397
+ tok('"impression"', "str")
1398
+ ];
1399
+ var CATEGORY = [
1400
+ tok(" ", "punct"),
1401
+ tok("data-elb-article", "attr"),
1402
+ tok("=", "punct"),
1403
+ tok('"category:#innerText"', "str")
1404
+ ];
1405
+ var TITLE = [
1406
+ tok(" ", "punct"),
1407
+ tok("data-elb-article", "attr"),
1408
+ tok("=", "punct"),
1409
+ tok('"title:#innerText"', "str")
1410
+ ];
1411
+ var ACTION = [
1412
+ tok(" ", "punct"),
1413
+ tok("data-elbaction", "attr"),
1414
+ tok("=", "punct"),
1415
+ tok('"click:open"', "str")
1416
+ ];
1417
+ var TYPING = [
1418
+ [CUE.entityStart, CUE.entityEnd],
1419
+ [CUE.impressionStart, CUE.impressionEnd],
1420
+ [CUE.categoryStart, CUE.categoryEnd],
1421
+ [CUE.titleStart, CUE.titleEnd],
1422
+ [CUE.actionStart, CUE.actionEnd]
1423
+ ];
1424
+ function articleAt(loop) {
1425
+ return HERO_ARTICLES[loop % HERO_ARTICLES.length];
1426
+ }
1427
+ function caretSlot(ph) {
1428
+ if (ph >= CUE.entityStart - 400 && ph < CUE.impressionStart - 300)
1429
+ return "entity";
1430
+ if (ph >= CUE.impressionStart - 300 && ph < CUE.categoryStart - 100)
1431
+ return "impression";
1432
+ if (ph >= CUE.categoryStart - 100 && ph < CUE.titleStart - 100)
1433
+ return "category";
1434
+ if (ph >= CUE.titleStart - 100 && ph < CUE.actionStart - 100) return "title";
1435
+ if (ph >= CUE.actionStart - 100 && ph < CUE.moveStart) return "action";
1436
+ return null;
1437
+ }
1438
+ function typed(tokens, start, end, ph) {
1439
+ return truncate(
1440
+ tokens,
1441
+ Math.round(clamp((ph - start) / (end - start)) * typedLength(tokens))
1442
+ );
1443
+ }
1444
+ function heroLines(article, ph) {
1445
+ const slot = caretSlot(ph);
1446
+ const indent = tok(" ", "punct");
1447
+ const entity = typed(ENTITY, CUE.entityStart, CUE.entityEnd, ph);
1448
+ const impression = typed(
1449
+ IMPRESSION,
1450
+ CUE.impressionStart,
1451
+ CUE.impressionEnd,
1452
+ ph
1453
+ );
1454
+ const category = typed(CATEGORY, CUE.categoryStart, CUE.categoryEnd, ph);
1455
+ const title = typed(TITLE, CUE.titleStart, CUE.titleEnd, ph);
1456
+ const action = typed(ACTION, CUE.actionStart, CUE.actionEnd, ph);
1457
+ const lines = [
1458
+ {
1459
+ id: "open",
1460
+ tokens: [
1461
+ tok("<article", "tag"),
1462
+ tok(" ", "punct"),
1463
+ tok("class", "attr"),
1464
+ tok("=", "punct"),
1465
+ tok('"teaser"', "str")
1466
+ ],
1467
+ on: false,
1468
+ caret: null
1469
+ },
1470
+ ph >= CUE.entityStart - 400 ? {
1471
+ id: "entity",
1472
+ tokens: [indent, ...entity],
1473
+ on: true,
1474
+ caret: slot === "entity" ? 1 + entity.length : null
1475
+ } : null,
1476
+ ph >= CUE.impressionStart - 300 ? {
1477
+ id: "impression",
1478
+ tokens: [indent, ...impression],
1479
+ on: true,
1480
+ caret: slot === "impression" ? 1 + impression.length : null
1481
+ } : null,
1482
+ { id: "close", tokens: [tok(">", "tag")], on: false, caret: null },
1483
+ {
1484
+ id: "image",
1485
+ tokens: [
1486
+ indent,
1487
+ tok("<img", "tag"),
1488
+ tok(" ", "punct"),
1489
+ tok("src", "attr"),
1490
+ tok("=", "punct"),
1491
+ tok(`"/img/${article.thumb}.jpg"`, "str"),
1492
+ tok(" ", "punct"),
1493
+ tok("alt", "attr"),
1494
+ tok("=", "punct"),
1495
+ tok('""', "str"),
1496
+ tok(" />", "tag")
1497
+ ],
1498
+ on: false,
1499
+ caret: null
1500
+ },
1501
+ {
1502
+ id: "category",
1503
+ tokens: [
1504
+ indent,
1505
+ tok("<span", "tag"),
1506
+ tok(" ", "punct"),
1507
+ tok("class", "attr"),
1508
+ tok("=", "punct"),
1509
+ tok('"kicker"', "str"),
1510
+ ...category,
1511
+ tok(">", "tag"),
1512
+ tok(article.kicker, "text"),
1513
+ tok("</span>", "tag")
1514
+ ],
1515
+ on: ph >= CUE.categoryStart - 100,
1516
+ caret: slot === "category" ? 6 + category.length : null
1517
+ },
1518
+ {
1519
+ id: "title",
1520
+ tokens: [
1521
+ indent,
1522
+ tok("<h3", "tag"),
1523
+ ...title,
1524
+ tok(">", "tag"),
1525
+ tok(article.title, "text"),
1526
+ tok("</h3>", "tag")
1527
+ ],
1528
+ on: ph >= CUE.titleStart - 100,
1529
+ caret: slot === "title" ? 2 + title.length : null
1530
+ },
1531
+ {
1532
+ id: "action",
1533
+ tokens: [
1534
+ indent,
1535
+ tok("<a", "tag"),
1536
+ ...action,
1537
+ tok(">", "tag"),
1538
+ tok("Open \u2192", "text"),
1539
+ tok("</a>", "tag")
1540
+ ],
1541
+ on: ph >= CUE.actionStart - 100,
1542
+ caret: slot === "action" ? 2 + action.length : null
1543
+ },
1544
+ { id: "end", tokens: [tok("</article>", "tag")], on: false, caret: null }
1545
+ ];
1546
+ return lines.filter((line) => line !== null).map((line, index) => ({ ...line, n: index + 1 }));
1547
+ }
1548
+ function heroEvents(article) {
1549
+ const data = { category: article.kicker, title: article.title };
1550
+ return [
1551
+ { name: "article impression", data },
1552
+ { name: "article open", data }
1553
+ ];
1554
+ }
1555
+ function heroRows(loop, ph) {
1556
+ const rows = [];
1557
+ for (let j = loop; j >= 0 && rows.length < MAX_ROWS; j--) {
1558
+ const [impression, open] = heroEvents(articleAt(j));
1559
+ const current = j === loop;
1560
+ if (!current || ph >= CUE.openEvent)
1561
+ rows.push({
1562
+ ...open,
1563
+ key: `${j}-open`,
1564
+ age: current ? ph - CUE.openEvent : PAST
1565
+ });
1566
+ if (!current || ph >= CUE.impressionEvent)
1567
+ rows.push({
1568
+ ...impression,
1569
+ key: `${j}-impression`,
1570
+ age: current ? ph - CUE.impressionEvent : PAST
1571
+ });
1572
+ }
1573
+ return rows.slice(0, MAX_ROWS);
1574
+ }
1575
+ function heroFrame(t) {
1576
+ const loop = Math.floor(t / HERO_LOOP);
1577
+ const ph = t - loop * HERO_LOOP;
1578
+ const article = articleAt(loop);
1579
+ const slideIn = ease(
1580
+ clamp((ph - CUE.slideInStart) / (CUE.slideInEnd - CUE.slideInStart))
1581
+ );
1582
+ const slideOut = ease(
1583
+ clamp((ph - CUE.slideOutStart) / (CUE.slideOutEnd - CUE.slideOutStart))
1584
+ );
1585
+ const move = ease(
1586
+ clamp((ph - CUE.moveStart) / (CUE.moveEnd - CUE.moveStart))
1587
+ );
1588
+ const ripple = clamp((ph - CUE.click) / 550);
1589
+ const cursorShown = ph >= CUE.moveStart - 200 && ph < CUE.fadeOut + 200;
1590
+ const fadingOut = ph > CUE.fadeOut ? 1 - clamp((ph - CUE.fadeOut) / 200) : 1;
1591
+ return {
1592
+ article,
1593
+ lines: heroLines(article, ph),
1594
+ fade: ph < 250 ? ph / 250 : ph > CUE.fadeOut ? 1 - clamp((ph - CUE.fadeOut) / (HERO_LOOP - CUE.fadeOut - 150)) : 1,
1595
+ caretOn: TYPING.some(([start, end]) => ph >= start && ph <= end) || ph % 900 < 500,
1596
+ card: {
1597
+ opacity: clamp(ph / 250) * (1 - slideOut),
1598
+ offset: ph >= CUE.slideOutStart ? -slideOut * 190 : (1 - slideIn) * 190,
1599
+ entity: ph >= CUE.entityEnd,
1600
+ impression: ph >= CUE.impressionEnd,
1601
+ category: ph >= CUE.categoryEnd,
1602
+ title: ph >= CUE.titleEnd,
1603
+ action: ph >= CUE.actionEnd
1604
+ },
1605
+ cursor: {
1606
+ x: 22 + (1 - move) * 190,
1607
+ y: 11 - (1 - move) * 80,
1608
+ opacity: cursorShown ? clamp((ph - (CUE.moveStart - 200)) / 200) * fadingOut : 0,
1609
+ ring: 1 + ripple * 1.8,
1610
+ ringOpacity: ph >= CUE.click ? (1 - ripple) * 0.9 : 0,
1611
+ pressed: ph >= CUE.click && ph < CUE.click + 180
1612
+ },
1613
+ rows: heroRows(loop, ph)
1614
+ };
1615
+ }
1616
+
1617
+ // src/design/components/viz/parts/EventsTable.tsx
1618
+ var import_react4 = require("react");
1619
+
1620
+ // src/design/components/viz/parts/style.ts
1621
+ function vizStyle(vars) {
1622
+ const style = {};
1623
+ return Object.assign(style, vars);
1624
+ }
1625
+
1626
+ // src/design/components/viz/parts/EventsTable.tsx
1627
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1628
+ var SKELETON_ROWS = 6;
1629
+ function EventsTable({ rows }) {
1630
+ const skeletons = Math.max(0, SKELETON_ROWS - rows.length);
1631
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "elb-viz-table", children: [
1632
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "elb-viz-table__head", children: [
1633
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "elb-viz-table__query", children: [
1634
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__keyword", children: "SELECT" }),
1635
+ " *",
1636
+ " ",
1637
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__keyword", children: "FROM" }),
1638
+ " ",
1639
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__source", children: "walkerOS.events" })
1640
+ ] }),
1641
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "elb-viz-table__live", children: [
1642
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__dot", "aria-hidden": "true" }),
1643
+ "live"
1644
+ ] })
1645
+ ] }),
1646
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "elb-viz-table__body", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "elb-viz-table__scroll", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "elb-viz-table__rows", children: [
1647
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "elb-viz-table__row elb-viz-table__row--header", children: [
1648
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__cell elb-viz-table__cell--n", children: "Row" }),
1649
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "elb-viz-table__cell", children: [
1650
+ "name",
1651
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__type", children: "STRING" })
1652
+ ] }),
1653
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "elb-viz-table__cell", children: [
1654
+ "data",
1655
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__type", children: "JSON" })
1656
+ ] })
1657
+ ] }),
1658
+ rows.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
1659
+ "div",
1660
+ {
1661
+ className: "elb-viz-table__row elb-viz-table__row--event",
1662
+ style: vizStyle({
1663
+ "--elb-viz-row-tint": 14 * (1 - clamp(row.age / 1600)),
1664
+ "--elb-viz-row-opacity": clamp(row.age / 300),
1665
+ "--elb-viz-row-shift": (1 - ease(clamp(row.age / 500))) * -80
1666
+ }),
1667
+ children: [
1668
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__cell elb-viz-table__cell--n", children: index + 1 }),
1669
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__cell", children: row.name }),
1670
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "elb-viz-table__cell elb-viz-table__json", children: [
1671
+ "{",
1672
+ Object.entries(row.data).map(([key, value], position) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react4.Fragment, { children: [
1673
+ position === 0 ? '"' : ',"',
1674
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__json-key", children: key }),
1675
+ '":"',
1676
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__json-value", children: value }),
1677
+ '"'
1678
+ ] }, key)),
1679
+ "}"
1680
+ ] })
1681
+ ]
1682
+ },
1683
+ row.key
1684
+ )),
1685
+ Array.from({ length: skeletons }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
1686
+ "div",
1687
+ {
1688
+ className: "elb-viz-table__row elb-viz-table__row--skeleton",
1689
+ "aria-hidden": "true",
1690
+ children: [
1691
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__cell elb-viz-table__cell--n", children: rows.length + index + 1 }),
1692
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__cell", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__bar" }) }),
1693
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__cell", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "elb-viz-table__bar" }) })
1694
+ ]
1695
+ },
1696
+ `skeleton-${index}`
1697
+ ))
1698
+ ] }) }) })
1699
+ ] });
1700
+ }
1701
+
1702
+ // src/design/components/viz/parts/hooks.ts
1703
+ var import_react5 = require("react");
1704
+ var REDUCED_MOTION = "(prefers-reduced-motion: reduce)";
1705
+ function useInView(ref, threshold) {
1706
+ const [inView, setInView] = (0, import_react5.useState)(false);
1707
+ (0, import_react5.useEffect)(() => {
1708
+ const element = ref.current;
1709
+ if (!element || typeof IntersectionObserver === "undefined") {
1710
+ setInView(true);
1711
+ return void 0;
1712
+ }
1713
+ const observer = new IntersectionObserver(
1714
+ (entries) => {
1715
+ const entry = entries[entries.length - 1];
1716
+ if (entry)
1717
+ setInView(
1718
+ entry.isIntersecting && entry.intersectionRatio >= threshold
1719
+ );
1720
+ },
1721
+ { threshold }
1722
+ );
1723
+ observer.observe(element);
1724
+ return () => observer.disconnect();
1725
+ }, [ref, threshold]);
1726
+ return inView;
1727
+ }
1728
+ function useReducedMotion() {
1729
+ const [reduced, setReduced] = (0, import_react5.useState)(false);
1730
+ (0, import_react5.useEffect)(() => {
1731
+ if (typeof window.matchMedia !== "function") return void 0;
1732
+ const media = window.matchMedia(REDUCED_MOTION);
1733
+ const update = () => setReduced(media.matches);
1734
+ update();
1735
+ media.addEventListener("change", update);
1736
+ return () => media.removeEventListener("change", update);
1737
+ }, []);
1738
+ return reduced;
1739
+ }
1740
+
1741
+ // src/design/components/viz/parts/Pill.tsx
1742
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1743
+ function Pill({
1744
+ part,
1745
+ variant = "solid",
1746
+ className,
1747
+ children
1748
+ }) {
1749
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1750
+ "span",
1751
+ {
1752
+ className: cx(
1753
+ "elb-viz-pill",
1754
+ `elb-viz-pill--${part}`,
1755
+ variant === "outline" && "elb-viz-pill--outline",
1756
+ className
1757
+ ),
1758
+ children
1759
+ }
1760
+ );
1761
+ }
1762
+
1763
+ // src/design/components/viz/parts/Thumb.tsx
1764
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1765
+ var BUG_LINES = [
1766
+ "M36 46 L28 42",
1767
+ "M35 54 L27 56",
1768
+ "M38 61 L31 66",
1769
+ "M76 46 L84 42",
1770
+ "M77 54 L85 56",
1771
+ "M74 61 L81 66",
1772
+ "M51 25 Q47 17 42 16",
1773
+ "M61 25 Q65 17 70 16"
1774
+ ];
1775
+ var BUG_SPOTS = [
1776
+ [47, 44, 3.4],
1777
+ [65, 44, 3.4],
1778
+ [45, 56, 2.8],
1779
+ [67, 56, 2.8]
1780
+ ];
1781
+ function Bug() {
1782
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
1783
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("rect", { className: "elb-viz-thumb__ground", width: 112, height: 86 }),
1784
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1785
+ "ellipse",
1786
+ {
1787
+ className: "elb-viz-thumb__shadow",
1788
+ cx: 56,
1789
+ cy: 66,
1790
+ rx: 30,
1791
+ ry: 6
1792
+ }
1793
+ ),
1794
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1795
+ "g",
1796
+ {
1797
+ className: "elb-viz-thumb__legs",
1798
+ strokeWidth: 2.4,
1799
+ strokeLinecap: "round",
1800
+ children: BUG_LINES.map((d) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { d }, d))
1801
+ }
1802
+ ),
1803
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("circle", { className: "elb-viz-thumb__ink", cx: 42, cy: 16, r: 2 }),
1804
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("circle", { className: "elb-viz-thumb__ink", cx: 70, cy: 16, r: 2 }),
1805
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1806
+ "ellipse",
1807
+ {
1808
+ className: "elb-viz-thumb__ink",
1809
+ cx: 56,
1810
+ cy: 30,
1811
+ rx: 10,
1812
+ ry: 7.5
1813
+ }
1814
+ ),
1815
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("circle", { className: "elb-viz-thumb__eye", cx: 52, cy: 29, r: 1.6 }),
1816
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("circle", { className: "elb-viz-thumb__eye", cx: 60, cy: 29, r: 1.6 }),
1817
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1818
+ "ellipse",
1819
+ {
1820
+ className: "elb-viz-thumb__shell",
1821
+ cx: 56,
1822
+ cy: 50,
1823
+ rx: 21,
1824
+ ry: 18
1825
+ }
1826
+ ),
1827
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { className: "elb-viz-thumb__seam", d: "M56 33 L56 68", strokeWidth: 2 }),
1828
+ BUG_SPOTS.map(([x, y, r]) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1829
+ "circle",
1830
+ {
1831
+ className: "elb-viz-thumb__ink",
1832
+ cx: x,
1833
+ cy: y,
1834
+ r
1835
+ },
1836
+ `${x}-${y}`
1837
+ )),
1838
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1839
+ "path",
1840
+ {
1841
+ className: "elb-viz-thumb__shine",
1842
+ d: "M44 38 Q48 35 52 36",
1843
+ strokeWidth: 2,
1844
+ strokeLinecap: "round"
1845
+ }
1846
+ )
1847
+ ] });
1848
+ }
1849
+ function Tech() {
1850
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
1851
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("rect", { className: "elb-viz-thumb__ground", width: 112, height: 86 }),
1852
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1853
+ "rect",
1854
+ {
1855
+ className: "elb-viz-thumb__badge",
1856
+ x: 38,
1857
+ y: 25,
1858
+ width: 36,
1859
+ height: 36,
1860
+ rx: 8
1861
+ }
1862
+ ),
1863
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("circle", { className: "elb-viz-thumb__dot", cx: 47, cy: 52, r: 3.2 }),
1864
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1865
+ "path",
1866
+ {
1867
+ className: "elb-viz-thumb__wave",
1868
+ d: "M45 42 A10 10 0 0 1 57 54",
1869
+ strokeWidth: 3.5,
1870
+ strokeLinecap: "round"
1871
+ }
1872
+ ),
1873
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1874
+ "path",
1875
+ {
1876
+ className: "elb-viz-thumb__wave",
1877
+ d: "M45 34.5 A17.5 17.5 0 0 1 64.5 54",
1878
+ strokeWidth: 3.5,
1879
+ strokeLinecap: "round"
1880
+ }
1881
+ )
1882
+ ] });
1883
+ }
1884
+ function Food() {
1885
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
1886
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("rect", { className: "elb-viz-thumb__ground", width: 112, height: 86 }),
1887
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1888
+ "ellipse",
1889
+ {
1890
+ className: "elb-viz-thumb__plate",
1891
+ cx: 56,
1892
+ cy: 62,
1893
+ rx: 44,
1894
+ ry: 10
1895
+ }
1896
+ ),
1897
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1898
+ "ellipse",
1899
+ {
1900
+ className: "elb-viz-thumb__loaf",
1901
+ cx: 56,
1902
+ cy: 50,
1903
+ rx: 31,
1904
+ ry: 19
1905
+ }
1906
+ ),
1907
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1908
+ "ellipse",
1909
+ {
1910
+ className: "elb-viz-thumb__crust",
1911
+ cx: 56,
1912
+ cy: 45,
1913
+ rx: 25,
1914
+ ry: 13
1915
+ }
1916
+ ),
1917
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1918
+ "path",
1919
+ {
1920
+ className: "elb-viz-thumb__score",
1921
+ d: "M40 44 Q56 35 72 44",
1922
+ strokeWidth: 2.2,
1923
+ strokeLinecap: "round"
1924
+ }
1925
+ ),
1926
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1927
+ "path",
1928
+ {
1929
+ className: "elb-viz-thumb__score",
1930
+ d: "M44 51 Q56 45 68 51",
1931
+ strokeWidth: 2.2,
1932
+ strokeLinecap: "round"
1933
+ }
1934
+ )
1935
+ ] });
1936
+ }
1937
+ function Thumb({ kind }) {
1938
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1939
+ "svg",
1940
+ {
1941
+ className: cx("elb-viz-thumb", `elb-viz-thumb--${kind}`),
1942
+ viewBox: "0 0 112 86",
1943
+ preserveAspectRatio: "xMidYMid slice",
1944
+ "aria-hidden": "true",
1945
+ focusable: "false",
1946
+ children: kind === "bug" ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Bug, {}) : kind === "tech" ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Tech, {}) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Food, {})
1947
+ }
1948
+ );
1949
+ }
1950
+
1951
+ // src/design/components/viz/HeroTaggingViz.tsx
1952
+ var import_jsx_runtime30 = require("react/jsx-runtime");
1953
+ var MAX_STEP = 64;
1954
+ function HeroTaggingViz({
1955
+ playing = true,
1956
+ speed = 1,
1957
+ startAt = HERO_START,
1958
+ ...rest
1959
+ }) {
1960
+ const paneRef = (0, import_react6.useRef)(null);
1961
+ const inView = useInView(paneRef, 0);
1962
+ const reduced = useReducedMotion();
1963
+ const [time, setTime] = (0, import_react6.useState)(startAt);
1964
+ const animate = playing && inView && !reduced;
1965
+ (0, import_react6.useEffect)(() => {
1966
+ if (!animate) return void 0;
1967
+ let frame = 0;
1968
+ let last = performance.now();
1969
+ const step = (now) => {
1970
+ const elapsed = Math.min(MAX_STEP, now - last);
1971
+ last = now;
1972
+ setTime((value) => value + elapsed * speed);
1973
+ frame = requestAnimationFrame(step);
1974
+ };
1975
+ frame = requestAnimationFrame(step);
1976
+ return () => cancelAnimationFrame(frame);
1977
+ }, [animate, speed]);
1978
+ const { article, lines, fade: fade2, caretOn, card, cursor, rows } = heroFrame(time);
1979
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(VizFrame, { ...rest, variant: "hero", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "elb-viz-hero", children: [
1980
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { ref: paneRef, className: "elb-viz-hero__pane", children: [
1981
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "elb-viz-hero__bar", children: [
1982
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "elb-viz-hero__dots", "aria-hidden": "true", children: [
1983
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", {}),
1984
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", {}),
1985
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", {})
1986
+ ] }),
1987
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "elb-viz-hero__file", children: "ArticleTeaser.html" })
1988
+ ] }),
1989
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1990
+ "div",
1991
+ {
1992
+ className: "elb-viz-hero__code",
1993
+ style: vizStyle({ "--elb-viz-fade": fade2 }),
1994
+ children: lines.map((line) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1995
+ CodeLine,
1996
+ {
1997
+ number: line.n,
1998
+ bar: line.on ? "entity" : void 0,
1999
+ className: cx(
2000
+ "elb-viz-hero__line",
2001
+ line.on && "elb-viz-hero__line--on"
2002
+ ),
2003
+ children: line.caret === null ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(CodeTokens, { tokens: line.tokens }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
2004
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(CodeTokens, { tokens: line.tokens.slice(0, line.caret) }),
2005
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
2006
+ "span",
2007
+ {
2008
+ className: "elb-viz-caret",
2009
+ style: vizStyle({ "--elb-viz-caret": caretOn ? 1 : 0 })
2010
+ }
2011
+ ),
2012
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(CodeTokens, { tokens: line.tokens.slice(line.caret) })
2013
+ ] })
2014
+ },
2015
+ line.id
2016
+ ))
2017
+ }
2018
+ ),
2019
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "elb-viz-hero__stage", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
2020
+ "div",
2021
+ {
2022
+ className: cx(
2023
+ "elb-viz-hero__card",
2024
+ card.entity && "elb-viz-hero__card--tagged"
2025
+ ),
2026
+ style: vizStyle({
2027
+ "--elb-viz-card-opacity": card.opacity,
2028
+ "--elb-viz-card-offset": card.offset
2029
+ }),
2030
+ children: [
2031
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "elb-viz-hero__pills", children: [
2032
+ card.entity && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Pill, { part: "entity", children: "article" }),
2033
+ card.impression && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Pill, { part: "action", children: "impression" })
2034
+ ] }),
2035
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "elb-viz-hero__thumb", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Thumb, { kind: article.thumb }) }),
2036
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "elb-viz-hero__text", children: [
2037
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
2038
+ "span",
2039
+ {
2040
+ className: cx(
2041
+ "elb-viz-hero__kicker",
2042
+ card.category && "elb-viz-hero__kicker--on"
2043
+ ),
2044
+ children: article.kicker
2045
+ }
2046
+ ),
2047
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "elb-viz-hero__title", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
2048
+ "span",
2049
+ {
2050
+ className: cx(
2051
+ "elb-viz-hero__mark",
2052
+ card.title && "elb-viz-hero__mark--on"
2053
+ ),
2054
+ children: article.title
2055
+ }
2056
+ ) }),
2057
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "elb-viz-hero__foot", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
2058
+ "span",
2059
+ {
2060
+ className: cx(
2061
+ "elb-viz-hero__link",
2062
+ card.action && "elb-viz-hero__link--on"
2063
+ ),
2064
+ children: [
2065
+ "Open \u2192",
2066
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
2067
+ "span",
2068
+ {
2069
+ className: "elb-viz-hero__cursor",
2070
+ "aria-hidden": "true",
2071
+ style: vizStyle({
2072
+ "--elb-viz-cursor-x": cursor.x,
2073
+ "--elb-viz-cursor-y": cursor.y,
2074
+ "--elb-viz-cursor-opacity": cursor.opacity,
2075
+ "--elb-viz-ring-scale": cursor.ring,
2076
+ "--elb-viz-ring-opacity": cursor.ringOpacity,
2077
+ "--elb-viz-press": cursor.pressed ? 0.8 : 1
2078
+ }),
2079
+ children: [
2080
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "elb-viz-hero__ring" }),
2081
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "elb-viz-hero__pointer" })
2082
+ ]
2083
+ }
2084
+ )
2085
+ ]
2086
+ }
2087
+ ) })
2088
+ ] })
2089
+ ]
2090
+ }
2091
+ ) })
2092
+ ] }),
2093
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(EventsTable, { rows })
2094
+ ] }) });
2095
+ }
2096
+
2097
+ // src/design/components/viz/ArticleTeaserTracking.tsx
2098
+ var import_react7 = require("react");
2099
+
2100
+ // src/design/components/viz/data/article-teaser.ts
2101
+ var TEASER_ENTITY = "article";
2102
+ var TEASER_ACTION = "click:open";
2103
+ var TEASER_PAGE_IDS = ["home", "article"];
2104
+ var TEASER_PAGES = {
2105
+ home: {
2106
+ template: "HomePage.tsx",
2107
+ organism: "HomeFeed",
2108
+ pagetype: "homepage",
2109
+ list: "homefeed",
2110
+ items: "stories",
2111
+ step: 3,
2112
+ listEffect: "homefeed",
2113
+ globalsEffect: "homepage",
2114
+ header: "<HomeFeed /> \xB7 homepage",
2115
+ articles: [
2116
+ { kicker: "Tech", title: "Return of the Bug" },
2117
+ { kicker: "Tech", title: "The quiet return of RSS" },
2118
+ { kicker: "Food", title: "Why sourdough came back" }
2119
+ ]
2120
+ },
2121
+ article: {
2122
+ template: "ArticlePage.tsx",
2123
+ organism: "RelatedStories",
2124
+ pagetype: "article",
2125
+ list: "related",
2126
+ items: "related",
2127
+ step: 4,
2128
+ listEffect: "related",
2129
+ globalsEffect: "articlepage",
2130
+ header: "<RelatedStories /> \xB7 article page",
2131
+ heading: "Related stories",
2132
+ articles: [
2133
+ { kicker: "Tech", title: "The quiet return of RSS" },
2134
+ { kicker: "Science", title: "A year on the ice shelf" },
2135
+ { kicker: "Culture", title: "Small venues, big nights" }
2136
+ ]
2137
+ }
2138
+ };
2139
+ var TEASER_STEPS = [
2140
+ { step: 1, label: "Atom" },
2141
+ { step: 2, label: "Molecule" },
2142
+ { step: 3, label: TEASER_PAGES.home.organism },
2143
+ { step: 4, label: TEASER_PAGES.article.organism },
2144
+ { step: 5, label: "Pages" }
2145
+ ];
2146
+ var TEASER_CAPTIONS = {
2147
+ 1: `Link carries the ${TEASER_ACTION} action wherever it is rendered.`,
2148
+ 2: `ArticleTeaser makes each card an ${TEASER_ENTITY} entity and reads category and title from its elements.`,
2149
+ 3: `${TEASER_PAGES.home.organism} wraps three teasers and adds list:${TEASER_PAGES.home.list} context to their events.`,
2150
+ 4: `${TEASER_PAGES.article.organism} reuses the same ArticleTeaser and adds list:${TEASER_PAGES.article.list} context.`,
2151
+ 5: "Each page template sets pagetype as a global, which is added to every event on that page."
2152
+ };
2153
+ var file = (step, name, level) => ({
2154
+ kind: "file",
2155
+ step,
2156
+ name,
2157
+ level
2158
+ });
2159
+ var code = (step, tokens, effect, part) => ({ kind: "code", step, tokens, effect, part });
2160
+ var PROPERTY = `data-elb-${TEASER_ENTITY}`;
2161
+ function buildItems() {
2162
+ const items = [
2163
+ file(1, "Link.tsx", "atom"),
2164
+ code(1, [
2165
+ tok("export const", "kw"),
2166
+ tok(" Link ", "text"),
2167
+ tok("= ({ href, children }) => (", "punct")
2168
+ ]),
2169
+ code(
2170
+ 1,
2171
+ [
2172
+ tok(" ", "punct"),
2173
+ tok("<a", "tag"),
2174
+ tok(" ", "punct"),
2175
+ tok("href", "attr"),
2176
+ tok("={href} ", "punct"),
2177
+ tok("data-elbaction", "attr", "action"),
2178
+ tok("=", "punct"),
2179
+ tok(`"${TEASER_ACTION}"`, "str", "action"),
2180
+ tok(">", "tag")
2181
+ ],
2182
+ "action",
2183
+ "action"
2184
+ ),
2185
+ code(1, [tok(" ", "punct"), tok("{children}", "punct")]),
2186
+ code(1, [tok(" ", "punct"), tok("</a>", "tag")]),
2187
+ code(1, [tok(");", "punct")]),
2188
+ file(2, "ArticleTeaser.tsx", "molecule"),
2189
+ code(2, [
2190
+ tok("export const", "kw"),
2191
+ tok(" ArticleTeaser ", "text"),
2192
+ tok("= ({", "punct")
2193
+ ]),
2194
+ code(2, [tok(" title, category, image, url, position,", "punct")]),
2195
+ code(2, [tok("}) => (", "punct")]),
2196
+ code(
2197
+ 2,
2198
+ [
2199
+ tok(" ", "punct"),
2200
+ tok("<article", "tag"),
2201
+ tok(" ", "punct"),
2202
+ tok("data-elb", "attr", "entity"),
2203
+ tok("=", "punct"),
2204
+ tok(`"${TEASER_ENTITY}"`, "str", "entity")
2205
+ ],
2206
+ "entity",
2207
+ "entity"
2208
+ ),
2209
+ code(
2210
+ 2,
2211
+ [
2212
+ tok(" ", "punct"),
2213
+ tok(PROPERTY, "attr", "property"),
2214
+ tok("={`", "punct"),
2215
+ tok("position:${position}", "str", "property"),
2216
+ tok("`}", "punct"),
2217
+ tok(">", "tag")
2218
+ ],
2219
+ "position",
2220
+ "property"
2221
+ ),
2222
+ code(
2223
+ 2,
2224
+ [
2225
+ tok(" ", "punct"),
2226
+ tok("<img", "tag"),
2227
+ tok(" ", "punct"),
2228
+ tok("src", "attr"),
2229
+ tok("={image} ", "punct"),
2230
+ tok("/>", "tag")
2231
+ ],
2232
+ "image"
2233
+ ),
2234
+ code(
2235
+ 2,
2236
+ [
2237
+ tok(" ", "punct"),
2238
+ tok("<span", "tag"),
2239
+ tok(" ", "punct"),
2240
+ tok(PROPERTY, "attr", "property"),
2241
+ tok("=", "punct"),
2242
+ tok('"category:#innerText"', "str", "property"),
2243
+ tok(">", "tag"),
2244
+ tok("{category}", "punct"),
2245
+ tok("</span>", "tag")
2246
+ ],
2247
+ "category",
2248
+ "property"
2249
+ ),
2250
+ code(
2251
+ 2,
2252
+ [
2253
+ tok(" ", "punct"),
2254
+ tok("<h3", "tag"),
2255
+ tok(" ", "punct"),
2256
+ tok(PROPERTY, "attr", "property"),
2257
+ tok("=", "punct"),
2258
+ tok('"title:#innerText"', "str", "property"),
2259
+ tok(">", "tag"),
2260
+ tok("{title}", "punct"),
2261
+ tok("</h3>", "tag")
2262
+ ],
2263
+ "title",
2264
+ "property"
2265
+ ),
2266
+ code(2, [
2267
+ tok(" ", "punct"),
2268
+ tok("<Link", "tag"),
2269
+ tok(" ", "punct"),
2270
+ tok("href", "attr"),
2271
+ tok("={url}", "punct"),
2272
+ tok(">", "tag"),
2273
+ tok("Open \u2192", "text"),
2274
+ tok("</Link>", "tag")
2275
+ ]),
2276
+ code(2, [tok(" ", "punct"), tok("</article>", "tag")]),
2277
+ code(2, [tok(");", "punct")])
2278
+ ];
2279
+ for (const id of TEASER_PAGE_IDS) {
2280
+ const page = TEASER_PAGES[id];
2281
+ items.push(
2282
+ file(page.step, `${page.organism}.tsx`, "organism"),
2283
+ code(
2284
+ page.step,
2285
+ [
2286
+ tok("<section", "tag"),
2287
+ tok(" ", "punct"),
2288
+ tok("data-elbcontext", "attr", "context"),
2289
+ tok("=", "punct"),
2290
+ tok(`"list:${page.list}"`, "str", "context"),
2291
+ tok(">", "tag")
2292
+ ],
2293
+ page.listEffect,
2294
+ "context"
2295
+ ),
2296
+ code(page.step, [
2297
+ tok(` {${page.items}.map((s, i) => `, "punct"),
2298
+ tok("<ArticleTeaser", "tag"),
2299
+ tok(" {...s} ", "punct"),
2300
+ tok("position", "attr"),
2301
+ tok("={i + 1} ", "punct"),
2302
+ tok("/>", "tag"),
2303
+ tok(")}", "punct")
2304
+ ]),
2305
+ code(page.step, [tok("</section>", "tag")])
2306
+ );
2307
+ }
2308
+ for (const id of TEASER_PAGE_IDS) {
2309
+ const page = TEASER_PAGES[id];
2310
+ items.push(
2311
+ file(5, page.template, "template"),
2312
+ code(
2313
+ 5,
2314
+ [
2315
+ tok("<main", "tag"),
2316
+ tok(" ", "punct"),
2317
+ tok("data-elbglobals", "attr", "globals"),
2318
+ tok("=", "punct"),
2319
+ tok(`"pagetype:${page.pagetype}"`, "str", "globals"),
2320
+ tok(">", "tag")
2321
+ ],
2322
+ page.globalsEffect,
2323
+ "globals"
2324
+ ),
2325
+ code(5, [tok(" ", "punct"), tok(`<${page.organism} />`, "tag")]),
2326
+ code(5, [tok("</main>", "tag")])
2327
+ );
2328
+ }
2329
+ return items;
2330
+ }
2331
+ var TEASER_ITEMS = buildItems();
2332
+ function hasEffect(item) {
2333
+ return item.kind === "code" && item.effect !== void 0;
2334
+ }
2335
+ function teaserStepStart(step) {
2336
+ return TEASER_ITEMS.findIndex((item) => item.step === step);
2337
+ }
2338
+ function teaserStepEnd(step) {
2339
+ let end = teaserStepStart(step);
2340
+ while (end < TEASER_ITEMS.length && TEASER_ITEMS[end].step === step) end += 1;
2341
+ return end;
2342
+ }
2343
+ function teaserAdvance(n) {
2344
+ if (n >= TEASER_ITEMS.length) return null;
2345
+ const item = TEASER_ITEMS[n];
2346
+ if (item.kind === "file" && (n === 0 || TEASER_ITEMS[n - 1].step !== item.step))
2347
+ return { next: n + 1, delay: 1300 };
2348
+ let next = n;
2349
+ while (next < TEASER_ITEMS.length && TEASER_ITEMS[next].step === item.step && !hasEffect(TEASER_ITEMS[next]))
2350
+ next += 1;
2351
+ if (next < TEASER_ITEMS.length && TEASER_ITEMS[next].step === item.step)
2352
+ next += 1;
2353
+ if (next >= TEASER_ITEMS.length) return { next, delay: null };
2354
+ return {
2355
+ next,
2356
+ delay: 1700 + (TEASER_ITEMS[next].step !== item.step ? 1600 : 0)
2357
+ };
2358
+ }
2359
+
2360
+ // src/design/components/viz/ArticleTeaserTracking.tsx
2361
+ var import_jsx_runtime31 = require("react/jsx-runtime");
2362
+ var FIRST_DELAY = 800;
2363
+ var JUMP_DELAY = 250;
2364
+ var SCROLL_DELAY = 400;
2365
+ function fade(on) {
2366
+ return cx("elb-viz-teaser__fade", on && "elb-viz-teaser__fade--on");
2367
+ }
2368
+ function TeaserCard({
2369
+ article,
2370
+ position,
2371
+ seen,
2372
+ ahead
2373
+ }) {
2374
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
2375
+ "div",
2376
+ {
2377
+ className: cx(
2378
+ "elb-viz-teaser__card",
2379
+ seen.has("entity") && "elb-viz-teaser__card--entity",
2380
+ ahead && "elb-viz-teaser__card--ahead"
2381
+ ),
2382
+ children: [
2383
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "elb-viz-teaser__pills", children: [
2384
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Pill, { part: "entity", className: fade(seen.has("entity")), children: TEASER_ENTITY }),
2385
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2386
+ Pill,
2387
+ {
2388
+ part: "property",
2389
+ variant: "outline",
2390
+ className: fade(seen.has("position")),
2391
+ children: position
2392
+ }
2393
+ )
2394
+ ] }),
2395
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cx("elb-viz-teaser__photo", fade(seen.has("image"))), children: "photo" }),
2396
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2397
+ "span",
2398
+ {
2399
+ className: cx(
2400
+ "elb-viz-teaser__kicker",
2401
+ fade(seen.has("category")),
2402
+ seen.has("category") && "elb-viz-teaser__kicker--on"
2403
+ ),
2404
+ children: article.kicker
2405
+ }
2406
+ ),
2407
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2408
+ "span",
2409
+ {
2410
+ className: cx(
2411
+ "elb-viz-teaser__title",
2412
+ fade(seen.has("title")),
2413
+ seen.has("title") && "elb-viz-teaser__title--on"
2414
+ ),
2415
+ children: article.title
2416
+ }
2417
+ ),
2418
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2419
+ "span",
2420
+ {
2421
+ className: cx(
2422
+ "elb-viz-teaser__link",
2423
+ fade(seen.has("action")),
2424
+ seen.has("action") && "elb-viz-teaser__link--on"
2425
+ ),
2426
+ children: "Open \u2192"
2427
+ }
2428
+ )
2429
+ ]
2430
+ }
2431
+ );
2432
+ }
2433
+ function TeaserGroup({
2434
+ page,
2435
+ seen,
2436
+ current,
2437
+ lead
2438
+ }) {
2439
+ const globalsOn = seen.has(page.globalsEffect);
2440
+ const listOn = seen.has(page.listEffect);
2441
+ const reached = page.step <= current;
2442
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
2443
+ "div",
2444
+ {
2445
+ className: cx(
2446
+ "elb-viz-teaser__page",
2447
+ globalsOn && "elb-viz-teaser__page--on",
2448
+ !reached && !lead && "elb-viz-teaser__page--ahead"
2449
+ ),
2450
+ children: [
2451
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "elb-viz-teaser__page-pill", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2452
+ Pill,
2453
+ {
2454
+ part: "globals",
2455
+ className: fade(globalsOn),
2456
+ children: `pagetype:${page.pagetype}`
2457
+ }
2458
+ ) }),
2459
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
2460
+ "div",
2461
+ {
2462
+ className: cx(
2463
+ "elb-viz-teaser__list",
2464
+ listOn && "elb-viz-teaser__list--on"
2465
+ ),
2466
+ children: [
2467
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cx("elb-viz-teaser__list-head", fade(listOn)), children: [
2468
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "elb-viz-teaser__list-label", children: [
2469
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "elb-viz-teaser__list-name", children: page.header }),
2470
+ page.heading !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "elb-viz-teaser__list-heading", children: page.heading })
2471
+ ] }),
2472
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Pill, { part: "context", children: `list:${page.list}` })
2473
+ ] }),
2474
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "elb-viz-teaser__cards", children: page.articles.map((article, index) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2475
+ TeaserCard,
2476
+ {
2477
+ article,
2478
+ position: index + 1,
2479
+ seen,
2480
+ ahead: !reached && !(lead && index === 0)
2481
+ },
2482
+ article.title
2483
+ )) })
2484
+ ]
2485
+ }
2486
+ )
2487
+ ]
2488
+ }
2489
+ );
2490
+ }
2491
+ function ArticleTeaserTracking({
2492
+ autoplay = true,
2493
+ speed = 1,
2494
+ initialStep,
2495
+ ...rest
2496
+ }) {
2497
+ const codeRef = (0, import_react7.useRef)(null);
2498
+ const inView = useInView(codeRef, 0.35);
2499
+ const reduced = useReducedMotion();
2500
+ const [shown, setShown] = (0, import_react7.useState)(
2501
+ () => initialStep ? teaserStepEnd(initialStep) : 0
2502
+ );
2503
+ const [delay, setDelay] = (0, import_react7.useState)(FIRST_DELAY);
2504
+ const playing = autoplay && inView && !reduced;
2505
+ (0, import_react7.useEffect)(() => {
2506
+ if (reduced) setShown(TEASER_ITEMS.length);
2507
+ }, [reduced]);
2508
+ (0, import_react7.useEffect)(() => {
2509
+ if (!playing || delay === null) return void 0;
2510
+ const timer = setTimeout(() => {
2511
+ const advance = teaserAdvance(shown);
2512
+ if (!advance) {
2513
+ setDelay(null);
2514
+ return;
2515
+ }
2516
+ setShown(advance.next);
2517
+ setDelay(advance.delay);
2518
+ }, delay / speed);
2519
+ return () => clearTimeout(timer);
2520
+ }, [playing, delay, shown, speed]);
2521
+ (0, import_react7.useEffect)(() => {
2522
+ const pane = codeRef.current;
2523
+ if (!pane || shown === 0 || typeof pane.scrollTo !== "function")
2524
+ return void 0;
2525
+ const timer = setTimeout(() => {
2526
+ const line = pane.querySelector(`[data-line="${shown - 1}"]`);
2527
+ const top = line instanceof HTMLElement ? line.offsetTop - pane.clientHeight / 2 : 0;
2528
+ pane.scrollTo({
2529
+ top: Math.max(0, top),
2530
+ behavior: reduced ? "auto" : "smooth"
2531
+ });
2532
+ }, SCROLL_DELAY);
2533
+ return () => clearTimeout(timer);
2534
+ }, [shown, reduced]);
2535
+ const jump = (step) => {
2536
+ if (autoplay && !reduced) {
2537
+ setShown(teaserStepStart(step));
2538
+ setDelay(JUMP_DELAY);
2539
+ } else {
2540
+ setShown(teaserStepEnd(step));
2541
+ }
2542
+ };
2543
+ const count = Math.min(shown, TEASER_ITEMS.length);
2544
+ const visibleStep = count > 0 ? TEASER_ITEMS[count - 1].step : 0;
2545
+ const current = visibleStep === 0 ? 1 : visibleStep;
2546
+ const seen = /* @__PURE__ */ new Set();
2547
+ for (const item of TEASER_ITEMS.slice(0, count))
2548
+ if (item.kind === "code" && item.effect) seen.add(item.effect);
2549
+ let lineNumber = 0;
2550
+ let separated = false;
2551
+ const lines = TEASER_ITEMS.map((item, index) => {
2552
+ const visible = item.step <= visibleStep;
2553
+ const lineClass = cx(
2554
+ "elb-viz-teaser__line",
2555
+ visible && "elb-viz-teaser__line--visible",
2556
+ visible && item.step < current && "elb-viz-teaser__line--dim",
2557
+ item.kind === "file" && "elb-viz-teaser__line--file"
2558
+ );
2559
+ if (item.kind === "file") {
2560
+ lineNumber = 0;
2561
+ const fileClass = cx(
2562
+ "elb-viz-teaser__file",
2563
+ separated && "elb-viz-teaser__file--separated"
2564
+ );
2565
+ separated = true;
2566
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { "data-line": index, className: lineClass, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: fileClass, children: [
2567
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "elb-viz-teaser__file-name", children: item.name }),
2568
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "elb-viz-teaser__file-level", children: item.level })
2569
+ ] }) }, index);
2570
+ }
2571
+ lineNumber += 1;
2572
+ const reached = index < count;
2573
+ const isCurrent = index === count - 1 && item.effect !== void 0;
2574
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { "data-line": index, className: lineClass, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2575
+ CodeLine,
2576
+ {
2577
+ number: lineNumber,
2578
+ bar: reached ? item.part : void 0,
2579
+ className: cx(
2580
+ "elb-viz-teaser__code",
2581
+ isCurrent && `elb-viz-teaser__code--current-${item.part ?? "plain"}`
2582
+ ),
2583
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(CodeTokens, { tokens: item.tokens, active: reached })
2584
+ }
2585
+ ) }, index);
2586
+ });
2587
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VizFrame, { ...rest, variant: "teaser", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "elb-viz-teaser", children: [
2588
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "elb-viz-teaser__header", children: [
2589
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "elb-viz-teaser__steps", children: TEASER_STEPS.map(({ step, label }) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
2590
+ "button",
2591
+ {
2592
+ type: "button",
2593
+ "aria-label": `Step ${step}: ${label}`,
2594
+ "aria-pressed": step === current,
2595
+ className: cx(
2596
+ "elb-viz-teaser__step",
2597
+ step === current && "elb-viz-teaser__step--active",
2598
+ step < current && "elb-viz-teaser__step--done"
2599
+ ),
2600
+ onClick: () => jump(step),
2601
+ children: [
2602
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "elb-viz-teaser__step-number", children: step }),
2603
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { children: label })
2604
+ ]
2605
+ },
2606
+ step
2607
+ )) }),
2608
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "elb-viz-teaser__legend", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(EventLegend, {}) })
2609
+ ] }),
2610
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "elb-viz-teaser__caption", children: TEASER_CAPTIONS[current] }),
2611
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "elb-viz-teaser__body", children: [
2612
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "elb-viz-teaser__pane", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { ref: codeRef, className: "elb-viz-teaser__scroll", children: lines }) }),
2613
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "elb-viz-teaser__pages", children: TEASER_PAGE_IDS.map((id, index) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
2614
+ TeaserGroup,
2615
+ {
2616
+ page: TEASER_PAGES[id],
2617
+ seen,
2618
+ current,
2619
+ lead: index === 0
2620
+ },
2621
+ id
2622
+ )) })
2623
+ ] })
2624
+ ] }) });
2625
+ }
2626
+ //# sourceMappingURL=index.cjs.map