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