@make-pictures/kits 0.0.0-stage → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -2
  3. package/dist/chunk-3SUIELJV.mjs +601 -0
  4. package/dist/chunk-4Z3G6FPZ.mjs +485 -0
  5. package/dist/chunk-AHA23PHC.mjs +678 -0
  6. package/dist/chunk-CW623YVB.mjs +1124 -0
  7. package/dist/chunk-NNA7XXQB.mjs +1059 -0
  8. package/dist/chunk-S4CHTWOS.mjs +1237 -0
  9. package/dist/chunk-WAA7P5FT.mjs +912 -0
  10. package/dist/data-storytelling/AnimatedBarRace.d.ts +37 -0
  11. package/dist/data-storytelling/MetricComparisonCard.d.ts +29 -0
  12. package/dist/data-storytelling/TimelineTrack.d.ts +29 -0
  13. package/dist/data-storytelling/index.cjs +1224 -0
  14. package/dist/data-storytelling/index.d.ts +3 -0
  15. package/dist/data-storytelling/index.mjs +10 -0
  16. package/dist/index.cjs +6010 -0
  17. package/dist/index.d.ts +7 -0
  18. package/dist/index.mjs +108 -0
  19. package/dist/isometric-3d/IsometricStudioEnvironment.d.ts +8 -0
  20. package/dist/isometric-3d/Stylized3DCharacter.d.ts +29 -0
  21. package/dist/isometric-3d/index.cjs +611 -0
  22. package/dist/isometric-3d/index.d.ts +2 -0
  23. package/dist/isometric-3d/index.mjs +8 -0
  24. package/dist/kinetic-typography/AnimatedMetricCounter.d.ts +36 -0
  25. package/dist/kinetic-typography/ImpactKeywordCard.d.ts +31 -0
  26. package/dist/kinetic-typography/WordByWordStage.d.ts +47 -0
  27. package/dist/kinetic-typography/index.cjs +665 -0
  28. package/dist/kinetic-typography/index.d.ts +3 -0
  29. package/dist/kinetic-typography/index.mjs +14 -0
  30. package/dist/motion-diagrams-2d/CameraRig.d.ts +34 -0
  31. package/dist/motion-diagrams-2d/CodePayloadToast.d.ts +14 -0
  32. package/dist/motion-diagrams-2d/DataFlowEdge.d.ts +24 -0
  33. package/dist/motion-diagrams-2d/NodeBox.d.ts +65 -0
  34. package/dist/motion-diagrams-2d/SystemNode.d.ts +21 -0
  35. package/dist/motion-diagrams-2d/index.cjs +1137 -0
  36. package/dist/motion-diagrams-2d/index.d.ts +5 -0
  37. package/dist/motion-diagrams-2d/index.mjs +28 -0
  38. package/dist/paper-diorama-3d/ImageCutout3D.d.ts +47 -0
  39. package/dist/paper-diorama-3d/PaperCutout3D.d.ts +62 -0
  40. package/dist/paper-diorama-3d/PaperPopUpBook3D.d.ts +51 -0
  41. package/dist/paper-diorama-3d/PaperStageLighting3D.d.ts +12 -0
  42. package/dist/paper-diorama-3d/index.cjs +1087 -0
  43. package/dist/paper-diorama-3d/index.d.ts +4 -0
  44. package/dist/paper-diorama-3d/index.mjs +34 -0
  45. package/dist/product-frames/BrowserFrame.d.ts +28 -0
  46. package/dist/product-frames/PhoneFrame.d.ts +23 -0
  47. package/dist/product-frames/ScreenSpotlightOverlay.d.ts +34 -0
  48. package/dist/product-frames/frameMedia.d.ts +24 -0
  49. package/dist/product-frames/index.cjs +507 -0
  50. package/dist/product-frames/index.d.ts +8 -0
  51. package/dist/product-frames/index.mjs +12 -0
  52. package/dist/vfx/CinematicLensOverlay.d.ts +29 -0
  53. package/dist/vfx/ParticleField.d.ts +18 -0
  54. package/dist/vfx/SceneTransition.d.ts +24 -0
  55. package/dist/vfx/StagePostProcessing3D.d.ts +44 -0
  56. package/dist/vfx/index.cjs +933 -0
  57. package/dist/vfx/index.d.ts +4 -0
  58. package/dist/vfx/index.mjs +14 -0
  59. package/package.json +95 -4
@@ -0,0 +1,1237 @@
1
+ // packages/kits/src/data-storytelling/AnimatedBarRace.tsx
2
+ import {
3
+ Easing,
4
+ interpolate,
5
+ spring,
6
+ useCurrentFrame,
7
+ useVideoConfig
8
+ } from "remotion";
9
+ import {
10
+ FONTS,
11
+ SPRING_PRESETS,
12
+ STUDIO_THEME,
13
+ THEME,
14
+ useStudioFontsReady
15
+ } from "@make-pictures/core";
16
+ import { jsx, jsxs } from "react/jsx-runtime";
17
+ var DEFAULT_BAR_PALETTE = [
18
+ "#2563EB",
19
+ "#10B981",
20
+ "#38BDF8",
21
+ "#F59E0B",
22
+ "#F43F5E",
23
+ "#A855F7"
24
+ ];
25
+ function evaluateItemValueAtFrame(item, f) {
26
+ const kf = item.keyframes;
27
+ if (!kf || kf.length === 0) {
28
+ return item.value;
29
+ }
30
+ const sorted = [...kf].sort((a, b) => a.frame - b.frame);
31
+ if (f <= sorted[0].frame) return sorted[0].value;
32
+ if (f >= sorted[sorted.length - 1].frame) {
33
+ return sorted[sorted.length - 1].value;
34
+ }
35
+ for (let i = 0; i < sorted.length - 1; i++) {
36
+ const a = sorted[i];
37
+ const b = sorted[i + 1];
38
+ if (f >= a.frame && f <= b.frame) {
39
+ return interpolate(f, [a.frame, Math.max(a.frame + 1, b.frame)], [a.value, b.value], {
40
+ easing: Easing.inOut(Easing.cubic),
41
+ extrapolateLeft: "clamp",
42
+ extrapolateRight: "clamp"
43
+ });
44
+ }
45
+ }
46
+ return item.value;
47
+ }
48
+ function getExactRanksAtFrame(items, f) {
49
+ const scored = items.map((item, origIdx) => ({
50
+ id: item.id,
51
+ val: evaluateItemValueAtFrame(item, f),
52
+ origIdx
53
+ }));
54
+ scored.sort((a, b) => b.val !== a.val ? b.val - a.val : a.origIdx - b.origIdx);
55
+ const map = /* @__PURE__ */ new Map();
56
+ scored.forEach((entry, rank) => {
57
+ map.set(entry.id, rank);
58
+ });
59
+ return map;
60
+ }
61
+ function getSmoothedRanks(items, frame) {
62
+ const hasKeyframes = items.some((it) => it.keyframes && it.keyframes.length > 1);
63
+ if (!hasKeyframes) {
64
+ return getExactRanksAtFrame(items, frame);
65
+ }
66
+ const radius = 12;
67
+ const accum = /* @__PURE__ */ new Map();
68
+ let weightSum = 0;
69
+ for (let df = -radius; df <= radius; df++) {
70
+ const w = 0.5 * (1 + Math.cos(Math.PI * df / (radius + 1)));
71
+ weightSum += w;
72
+ const ranks = getExactRanksAtFrame(items, Math.max(0, frame + df));
73
+ for (const [id, r] of ranks.entries()) {
74
+ accum.set(id, (accum.get(id) ?? 0) + r * w);
75
+ }
76
+ }
77
+ const result = /* @__PURE__ */ new Map();
78
+ for (const [id, sum] of accum.entries()) {
79
+ result.set(id, sum / Math.max(1e-6, weightSum));
80
+ }
81
+ return result;
82
+ }
83
+ var AnimatedBarRace = ({
84
+ items,
85
+ orientation = "horizontal",
86
+ title,
87
+ subtitle,
88
+ valuePrefix = "",
89
+ valueSuffix = "",
90
+ decimals = 0,
91
+ maxItems = 6,
92
+ enterFrame,
93
+ startFrame,
94
+ staggerFrames = 5,
95
+ variant = "dark",
96
+ safeBox9x16 = true,
97
+ style
98
+ }) => {
99
+ const frame = useCurrentFrame();
100
+ const { fps, width, height } = useVideoConfig();
101
+ useStudioFontsReady();
102
+ const effectiveStart = Math.max(2, startFrame ?? enterFrame ?? 2);
103
+ const cardEnter = spring({
104
+ frame: frame - effectiveStart,
105
+ fps,
106
+ config: SPRING_PRESETS.snappy
107
+ });
108
+ if (cardEnter <= 5e-3 || items.length === 0) {
109
+ return null;
110
+ }
111
+ const visibleCount = Math.min(items.length, Math.max(1, maxItems));
112
+ const smoothedRanks = getSmoothedRanks(items, frame);
113
+ const evaluated = items.map((item, idx) => {
114
+ const rawVal = evaluateItemValueAtFrame(item, frame);
115
+ const rank = smoothedRanks.get(item.id) ?? idx;
116
+ const color = item.color ?? DEFAULT_BAR_PALETTE[idx % DEFAULT_BAR_PALETTE.length];
117
+ return {
118
+ item,
119
+ idx,
120
+ rawVal,
121
+ rank,
122
+ color
123
+ };
124
+ });
125
+ const maxVal = Math.max(1e-6, ...evaluated.map((e) => e.rawVal));
126
+ const isVerticalViewport = height > width;
127
+ const isLight = variant === "light";
128
+ const cardWidth = isVerticalViewport && safeBox9x16 ? Math.min(830, width - 90) : 980;
129
+ const rowHeight = isVerticalViewport ? 72 : 76;
130
+ const rowGap = 14;
131
+ return /* @__PURE__ */ jsxs(
132
+ "div",
133
+ {
134
+ style: {
135
+ width: cardWidth,
136
+ padding: isVerticalViewport ? "28px 30px" : "34px 40px",
137
+ borderRadius: 26,
138
+ boxSizing: "border-box",
139
+ backgroundColor: isLight ? STUDIO_THEME.colors.bgSurfaceGlass : "rgba(13, 15, 26, 0.88)",
140
+ border: isLight ? `1.5px solid ${STUDIO_THEME.colors.border.subtle}` : "1.5px solid rgba(255, 255, 255, 0.12)",
141
+ boxShadow: isLight ? STUDIO_THEME.shadows.cardElevated : THEME.shadows.card,
142
+ backdropFilter: "blur(16px)",
143
+ opacity: cardEnter,
144
+ transform: `translateY(${interpolate(cardEnter, [0, 1], [24, 0]).toFixed(2)}px) scale(${interpolate(cardEnter, [0, 1], [0.95, 1]).toFixed(4)})`,
145
+ ...style
146
+ },
147
+ children: [
148
+ (title || subtitle) && /* @__PURE__ */ jsxs("div", { style: { marginBottom: 24 }, children: [
149
+ title && /* @__PURE__ */ jsx(
150
+ "div",
151
+ {
152
+ style: {
153
+ fontFamily: FONTS.display,
154
+ fontSize: isVerticalViewport ? 30 : 34,
155
+ fontWeight: 800,
156
+ letterSpacing: "-0.02em",
157
+ color: isLight ? STUDIO_THEME.colors.text.slate900 : THEME.colors.textPrimary
158
+ },
159
+ children: title
160
+ }
161
+ ),
162
+ subtitle && /* @__PURE__ */ jsx(
163
+ "div",
164
+ {
165
+ style: {
166
+ marginTop: 4,
167
+ fontFamily: FONTS.sans,
168
+ fontSize: 18,
169
+ fontWeight: 500,
170
+ color: isLight ? STUDIO_THEME.colors.text.secondary : THEME.colors.textSecondary
171
+ },
172
+ children: subtitle
173
+ }
174
+ )
175
+ ] }),
176
+ orientation === "horizontal" ? /* @__PURE__ */ jsx(
177
+ "div",
178
+ {
179
+ style: {
180
+ position: "relative",
181
+ height: visibleCount * (rowHeight + rowGap) - rowGap
182
+ },
183
+ children: evaluated.map(({ item, idx, rawVal, rank, color }) => {
184
+ if (rank > visibleCount - 0.15) return null;
185
+ const barGrow = spring({
186
+ frame: frame - (effectiveStart + 4 + idx * staggerFrames),
187
+ fps,
188
+ config: SPRING_PRESETS.smooth
189
+ });
190
+ const fillRatio = Math.max(0.04, rawVal / maxVal * barGrow);
191
+ const displayVal = rawVal * barGrow;
192
+ const yTop = rank * (rowHeight + rowGap);
193
+ const rankBadge = Math.min(visibleCount, Math.round(rank) + 1);
194
+ return /* @__PURE__ */ jsxs(
195
+ "div",
196
+ {
197
+ style: {
198
+ position: "absolute",
199
+ left: 0,
200
+ right: 0,
201
+ top: 0,
202
+ height: rowHeight,
203
+ transform: `translate3d(0, ${yTop.toFixed(2)}px, 0)`,
204
+ display: "flex",
205
+ alignItems: "center",
206
+ gap: 16,
207
+ opacity: barGrow
208
+ },
209
+ children: [
210
+ /* @__PURE__ */ jsx(
211
+ "div",
212
+ {
213
+ style: {
214
+ width: 38,
215
+ height: 38,
216
+ borderRadius: 12,
217
+ flexShrink: 0,
218
+ display: "flex",
219
+ alignItems: "center",
220
+ justifyContent: "center",
221
+ fontFamily: FONTS.mono,
222
+ fontSize: 16,
223
+ fontWeight: 800,
224
+ color: rankBadge === 1 ? "#FFFFFF" : isLight ? "#334155" : "#CBD5E1",
225
+ backgroundColor: rankBadge === 1 ? color : isLight ? "rgba(15, 23, 42, 0.07)" : "rgba(255, 255, 255, 0.08)"
226
+ },
227
+ children: rankBadge
228
+ }
229
+ ),
230
+ /* @__PURE__ */ jsxs(
231
+ "div",
232
+ {
233
+ style: {
234
+ flex: 1,
235
+ minWidth: 0,
236
+ display: "flex",
237
+ flexDirection: "column",
238
+ gap: 8
239
+ },
240
+ children: [
241
+ /* @__PURE__ */ jsxs(
242
+ "div",
243
+ {
244
+ style: {
245
+ display: "flex",
246
+ alignItems: "center",
247
+ justifyContent: "space-between",
248
+ gap: 12
249
+ },
250
+ children: [
251
+ /* @__PURE__ */ jsxs(
252
+ "div",
253
+ {
254
+ style: {
255
+ display: "flex",
256
+ alignItems: "center",
257
+ gap: 8,
258
+ fontFamily: FONTS.sans,
259
+ fontSize: 20,
260
+ fontWeight: 700,
261
+ color: isLight ? STUDIO_THEME.colors.text.slate900 : THEME.colors.textPrimary,
262
+ whiteSpace: "nowrap",
263
+ overflow: "hidden",
264
+ textOverflow: "ellipsis"
265
+ },
266
+ children: [
267
+ item.icon,
268
+ /* @__PURE__ */ jsx("span", { children: item.label }),
269
+ item.badge && /* @__PURE__ */ jsx(
270
+ "span",
271
+ {
272
+ style: {
273
+ fontFamily: FONTS.mono,
274
+ fontSize: 12,
275
+ fontWeight: 700,
276
+ padding: "2px 8px",
277
+ borderRadius: 9999,
278
+ color,
279
+ backgroundColor: `${color}22`
280
+ },
281
+ children: item.badge
282
+ }
283
+ )
284
+ ]
285
+ }
286
+ ),
287
+ /* @__PURE__ */ jsxs(
288
+ "div",
289
+ {
290
+ style: {
291
+ fontFamily: FONTS.mono,
292
+ fontVariantNumeric: "tabular-nums",
293
+ fontSize: 17,
294
+ fontWeight: 700,
295
+ padding: "4px 12px",
296
+ borderRadius: 9999,
297
+ color: "#FFFFFF",
298
+ backgroundColor: color,
299
+ boxShadow: `0 4px 14px ${color}44`
300
+ },
301
+ children: [
302
+ valuePrefix,
303
+ displayVal.toFixed(decimals),
304
+ valueSuffix
305
+ ]
306
+ }
307
+ )
308
+ ]
309
+ }
310
+ ),
311
+ /* @__PURE__ */ jsx(
312
+ "div",
313
+ {
314
+ style: {
315
+ width: "100%",
316
+ height: 16,
317
+ borderRadius: 9999,
318
+ backgroundColor: isLight ? "rgba(15, 23, 42, 0.07)" : "rgba(255, 255, 255, 0.08)",
319
+ overflow: "hidden"
320
+ },
321
+ children: /* @__PURE__ */ jsx(
322
+ "div",
323
+ {
324
+ style: {
325
+ width: `${(fillRatio * 100).toFixed(2)}%`,
326
+ height: "100%",
327
+ borderRadius: 9999,
328
+ background: `linear-gradient(90deg, ${color}CC 0%, ${color} 100%)`,
329
+ boxShadow: `0 0 18px ${color}66`
330
+ }
331
+ }
332
+ )
333
+ }
334
+ )
335
+ ]
336
+ }
337
+ )
338
+ ]
339
+ },
340
+ item.id
341
+ );
342
+ })
343
+ }
344
+ ) : (
345
+ /* Vertical Column Chart Mode */
346
+ /* @__PURE__ */ jsx(
347
+ "div",
348
+ {
349
+ style: {
350
+ display: "flex",
351
+ alignItems: "flex-end",
352
+ justifyContent: "space-between",
353
+ gap: 18,
354
+ height: isVerticalViewport ? 340 : 320,
355
+ paddingTop: 28
356
+ },
357
+ children: [...evaluated].sort((a, b) => a.rank - b.rank).slice(0, visibleCount).map(({ item, idx, rawVal, color }) => {
358
+ const barGrow = spring({
359
+ frame: frame - (effectiveStart + 4 + idx * staggerFrames),
360
+ fps,
361
+ config: SPRING_PRESETS.smooth
362
+ });
363
+ const fillRatio = Math.max(0.06, rawVal / maxVal * barGrow);
364
+ const displayVal = rawVal * barGrow;
365
+ return /* @__PURE__ */ jsxs(
366
+ "div",
367
+ {
368
+ style: {
369
+ flex: 1,
370
+ height: "100%",
371
+ display: "flex",
372
+ flexDirection: "column",
373
+ alignItems: "center",
374
+ justifyContent: "flex-end",
375
+ gap: 10,
376
+ opacity: barGrow
377
+ },
378
+ children: [
379
+ /* @__PURE__ */ jsxs(
380
+ "div",
381
+ {
382
+ style: {
383
+ fontFamily: FONTS.mono,
384
+ fontVariantNumeric: "tabular-nums",
385
+ fontSize: 15,
386
+ fontWeight: 700,
387
+ padding: "3px 10px",
388
+ borderRadius: 9999,
389
+ color: "#FFFFFF",
390
+ backgroundColor: color
391
+ },
392
+ children: [
393
+ valuePrefix,
394
+ displayVal.toFixed(decimals),
395
+ valueSuffix
396
+ ]
397
+ }
398
+ ),
399
+ /* @__PURE__ */ jsx(
400
+ "div",
401
+ {
402
+ style: {
403
+ width: "100%",
404
+ maxWidth: 74,
405
+ height: `${(fillRatio * 74).toFixed(2)}%`,
406
+ borderRadius: "14px 14px 6px 6px",
407
+ background: `linear-gradient(180deg, ${color} 0%, ${color}AA 100%)`,
408
+ boxShadow: `0 8px 24px ${color}44`
409
+ }
410
+ }
411
+ ),
412
+ /* @__PURE__ */ jsx(
413
+ "div",
414
+ {
415
+ style: {
416
+ fontFamily: FONTS.sans,
417
+ fontSize: 16,
418
+ fontWeight: 700,
419
+ textAlign: "center",
420
+ color: isLight ? STUDIO_THEME.colors.text.slate900 : THEME.colors.textPrimary
421
+ },
422
+ children: item.label
423
+ }
424
+ )
425
+ ]
426
+ },
427
+ item.id
428
+ );
429
+ })
430
+ }
431
+ )
432
+ )
433
+ ]
434
+ }
435
+ );
436
+ };
437
+
438
+ // packages/kits/src/data-storytelling/TimelineTrack.tsx
439
+ import { Check } from "lucide-react";
440
+ import {
441
+ interpolate as interpolate2,
442
+ spring as spring2,
443
+ useCurrentFrame as useCurrentFrame2,
444
+ useVideoConfig as useVideoConfig2
445
+ } from "remotion";
446
+ import {
447
+ FONTS as FONTS2,
448
+ SPRING_PRESETS as SPRING_PRESETS2,
449
+ STUDIO_THEME as STUDIO_THEME2,
450
+ THEME as THEME2,
451
+ useStudioFontsReady as useStudioFontsReady2
452
+ } from "@make-pictures/core";
453
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
454
+ var TimelineTrack = ({
455
+ milestones,
456
+ orientation,
457
+ accentColor = STUDIO_THEME2.colors.brand[600],
458
+ enterFrame,
459
+ startFrame,
460
+ variant = "dark",
461
+ safeBox9x16 = true,
462
+ style
463
+ }) => {
464
+ const frame = useCurrentFrame2();
465
+ const { fps, width, height } = useVideoConfig2();
466
+ useStudioFontsReady2();
467
+ const effectiveStart = Math.max(2, startFrame ?? enterFrame ?? 2);
468
+ const trackEnter = spring2({
469
+ frame: frame - effectiveStart,
470
+ fps,
471
+ config: SPRING_PRESETS2.snappy
472
+ });
473
+ if (trackEnter <= 5e-3 || milestones.length === 0) {
474
+ return null;
475
+ }
476
+ const normalized = milestones.map((m) => ({
477
+ ...m,
478
+ resolvedFrame: m.fromFrame ?? m.frame ?? 0
479
+ }));
480
+ const sorted = [...normalized].sort(
481
+ (a, b) => a.resolvedFrame - b.resolvedFrame
482
+ );
483
+ const isVerticalViewport = height > width;
484
+ const resolvedOrientation = orientation ?? (isVerticalViewport && sorted.length >= 4 ? "vertical" : "horizontal");
485
+ const isLight = variant === "light";
486
+ let activeIdx = 0;
487
+ let continuousIndex = 0;
488
+ for (let i = 0; i < sorted.length; i++) {
489
+ if (frame >= sorted[i].resolvedFrame) {
490
+ activeIdx = i;
491
+ }
492
+ if (i > 0 && frame >= sorted[i].resolvedFrame) {
493
+ const segProgress = spring2({
494
+ frame: frame - sorted[i].resolvedFrame,
495
+ fps,
496
+ config: SPRING_PRESETS2.smooth
497
+ });
498
+ continuousIndex = i - 1 + segProgress;
499
+ }
500
+ }
501
+ const totalSteps = Math.max(1, sorted.length - 1);
502
+ const fillFraction = sorted.length <= 1 ? 1 : Math.min(1, Math.max(0, continuousIndex / totalSteps));
503
+ const activeColor = sorted[activeIdx]?.color ?? accentColor;
504
+ const containerWidth = isVerticalViewport && safeBox9x16 ? Math.min(830, width - 90) : 1120;
505
+ const haloScale = 1 + 0.08 * Math.sin(frame * (60 / Math.max(1, fps)) * 0.042);
506
+ if (resolvedOrientation === "vertical") {
507
+ return /* @__PURE__ */ jsx2(
508
+ "div",
509
+ {
510
+ style: {
511
+ width: Math.min(containerWidth, 680),
512
+ padding: "30px 34px",
513
+ borderRadius: 26,
514
+ boxSizing: "border-box",
515
+ backgroundColor: isLight ? STUDIO_THEME2.colors.bgSurfaceGlass : "rgba(13, 15, 26, 0.88)",
516
+ border: isLight ? `1.5px solid ${STUDIO_THEME2.colors.border.subtle}` : "1.5px solid rgba(255, 255, 255, 0.12)",
517
+ boxShadow: isLight ? STUDIO_THEME2.shadows.cardElevated : THEME2.shadows.card,
518
+ opacity: trackEnter,
519
+ transform: `translateY(${interpolate2(trackEnter, [0, 1], [22, 0]).toFixed(2)}px)`,
520
+ ...style
521
+ },
522
+ children: /* @__PURE__ */ jsxs2(
523
+ "div",
524
+ {
525
+ style: {
526
+ position: "relative",
527
+ display: "flex",
528
+ flexDirection: "column",
529
+ gap: 28
530
+ },
531
+ children: [
532
+ /* @__PURE__ */ jsx2(
533
+ "div",
534
+ {
535
+ style: {
536
+ position: "absolute",
537
+ left: 21,
538
+ top: 22,
539
+ bottom: 22,
540
+ width: 4,
541
+ borderRadius: 9999,
542
+ backgroundColor: isLight ? "rgba(15, 23, 42, 0.10)" : "rgba(255, 255, 255, 0.12)"
543
+ },
544
+ children: /* @__PURE__ */ jsx2(
545
+ "div",
546
+ {
547
+ style: {
548
+ width: "100%",
549
+ height: `${(fillFraction * 100).toFixed(2)}%`,
550
+ borderRadius: 9999,
551
+ backgroundColor: activeColor,
552
+ boxShadow: `0 0 16px ${activeColor}88`
553
+ }
554
+ }
555
+ )
556
+ }
557
+ ),
558
+ sorted.map((m, idx) => {
559
+ const isCompleted = idx < activeIdx;
560
+ const isActive = idx === activeIdx;
561
+ const nodeColor = m.color ?? accentColor;
562
+ const pop = spring2({
563
+ frame: Math.max(0, frame - m.resolvedFrame),
564
+ fps,
565
+ config: SPRING_PRESETS2.snappy
566
+ });
567
+ return /* @__PURE__ */ jsxs2(
568
+ "div",
569
+ {
570
+ style: {
571
+ position: "relative",
572
+ display: "flex",
573
+ alignItems: "center",
574
+ gap: 20,
575
+ zIndex: 2
576
+ },
577
+ children: [
578
+ /* @__PURE__ */ jsx2(
579
+ "div",
580
+ {
581
+ style: {
582
+ width: 46,
583
+ height: 46,
584
+ borderRadius: 9999,
585
+ flexShrink: 0,
586
+ display: "flex",
587
+ alignItems: "center",
588
+ justifyContent: "center",
589
+ backgroundColor: isActive || isCompleted ? nodeColor : isLight ? "#FFFFFF" : "#1E293B",
590
+ border: `3px solid ${isActive || isCompleted ? nodeColor : isLight ? "#CBD5E1" : "rgba(255,255,255,0.2)"}`,
591
+ boxShadow: isActive ? `0 0 28px ${nodeColor}88` : "none",
592
+ transform: `scale(${isActive ? (haloScale * (0.94 + 0.08 * pop)).toFixed(3) : "1"})`
593
+ },
594
+ children: isCompleted ? /* @__PURE__ */ jsx2(Check, { size: 22, color: "#FFFFFF", strokeWidth: 3 }) : /* @__PURE__ */ jsx2(
595
+ "span",
596
+ {
597
+ style: {
598
+ fontFamily: FONTS2.mono,
599
+ fontSize: 15,
600
+ fontWeight: 800,
601
+ color: isActive ? "#FFFFFF" : isLight ? "#64748B" : "#94A3B8"
602
+ },
603
+ children: idx + 1
604
+ }
605
+ )
606
+ }
607
+ ),
608
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: 3 }, children: [
609
+ m.era && /* @__PURE__ */ jsx2(
610
+ "span",
611
+ {
612
+ style: {
613
+ fontFamily: FONTS2.mono,
614
+ fontSize: 13,
615
+ fontWeight: 700,
616
+ letterSpacing: "0.07em",
617
+ textTransform: "uppercase",
618
+ color: isActive ? nodeColor : isLight ? STUDIO_THEME2.colors.text.muted : THEME2.colors.textMuted
619
+ },
620
+ children: m.era
621
+ }
622
+ ),
623
+ /* @__PURE__ */ jsx2(
624
+ "span",
625
+ {
626
+ style: {
627
+ fontFamily: FONTS2.display,
628
+ fontSize: 22,
629
+ fontWeight: 800,
630
+ color: isActive || isCompleted ? isLight ? STUDIO_THEME2.colors.text.slate900 : THEME2.colors.textPrimary : isLight ? "#94A3B8" : "#64748B"
631
+ },
632
+ children: m.label
633
+ }
634
+ ),
635
+ m.detail && /* @__PURE__ */ jsx2(
636
+ "span",
637
+ {
638
+ style: {
639
+ fontFamily: FONTS2.sans,
640
+ fontSize: 16,
641
+ fontWeight: 500,
642
+ color: isLight ? STUDIO_THEME2.colors.text.secondary : THEME2.colors.textSecondary
643
+ },
644
+ children: m.detail
645
+ }
646
+ )
647
+ ] })
648
+ ]
649
+ },
650
+ m.id
651
+ );
652
+ })
653
+ ]
654
+ }
655
+ )
656
+ }
657
+ );
658
+ }
659
+ return /* @__PURE__ */ jsx2(
660
+ "div",
661
+ {
662
+ style: {
663
+ width: containerWidth,
664
+ padding: isVerticalViewport ? "28px 26px" : "32px 42px",
665
+ borderRadius: 26,
666
+ boxSizing: "border-box",
667
+ backgroundColor: isLight ? STUDIO_THEME2.colors.bgSurfaceGlass : "rgba(13, 15, 26, 0.88)",
668
+ border: isLight ? `1.5px solid ${STUDIO_THEME2.colors.border.subtle}` : "1.5px solid rgba(255, 255, 255, 0.12)",
669
+ boxShadow: isLight ? STUDIO_THEME2.shadows.cardElevated : THEME2.shadows.card,
670
+ opacity: trackEnter,
671
+ transform: `translateY(${interpolate2(trackEnter, [0, 1], [22, 0]).toFixed(2)}px)`,
672
+ ...style
673
+ },
674
+ children: /* @__PURE__ */ jsxs2(
675
+ "div",
676
+ {
677
+ style: {
678
+ position: "relative",
679
+ display: "flex",
680
+ alignItems: "flex-start",
681
+ justifyContent: "space-between"
682
+ },
683
+ children: [
684
+ /* @__PURE__ */ jsx2(
685
+ "div",
686
+ {
687
+ style: {
688
+ position: "absolute",
689
+ left: "8%",
690
+ right: "8%",
691
+ top: 22,
692
+ height: 5,
693
+ borderRadius: 9999,
694
+ backgroundColor: isLight ? "rgba(15, 23, 42, 0.10)" : "rgba(255, 255, 255, 0.12)",
695
+ zIndex: 1
696
+ },
697
+ children: /* @__PURE__ */ jsx2(
698
+ "div",
699
+ {
700
+ style: {
701
+ width: `${(fillFraction * 100).toFixed(2)}%`,
702
+ height: "100%",
703
+ borderRadius: 9999,
704
+ backgroundColor: activeColor,
705
+ boxShadow: `0 0 18px ${activeColor}88`
706
+ }
707
+ }
708
+ )
709
+ }
710
+ ),
711
+ sorted.map((m, idx) => {
712
+ const isCompleted = idx < activeIdx;
713
+ const isActive = idx === activeIdx;
714
+ const nodeColor = m.color ?? accentColor;
715
+ return /* @__PURE__ */ jsxs2(
716
+ "div",
717
+ {
718
+ style: {
719
+ position: "relative",
720
+ zIndex: 2,
721
+ flex: 1,
722
+ display: "flex",
723
+ flexDirection: "column",
724
+ alignItems: "center",
725
+ textAlign: "center",
726
+ gap: 10,
727
+ padding: "0 8px"
728
+ },
729
+ children: [
730
+ /* @__PURE__ */ jsx2(
731
+ "div",
732
+ {
733
+ style: {
734
+ width: 48,
735
+ height: 48,
736
+ borderRadius: 9999,
737
+ display: "flex",
738
+ alignItems: "center",
739
+ justifyContent: "center",
740
+ backgroundColor: isActive || isCompleted ? nodeColor : isLight ? "#FFFFFF" : "#0F172A",
741
+ border: `3px solid ${isActive || isCompleted ? nodeColor : isLight ? "#CBD5E1" : "rgba(255,255,255,0.22)"}`,
742
+ boxShadow: isActive ? `0 0 28px ${nodeColor}99` : "none",
743
+ transform: `scale(${isActive ? haloScale.toFixed(3) : "1"})`
744
+ },
745
+ children: isCompleted ? /* @__PURE__ */ jsx2(Check, { size: 22, color: "#FFFFFF", strokeWidth: 3 }) : /* @__PURE__ */ jsx2(
746
+ "span",
747
+ {
748
+ style: {
749
+ fontFamily: FONTS2.mono,
750
+ fontSize: 16,
751
+ fontWeight: 800,
752
+ color: isActive ? "#FFFFFF" : isLight ? "#64748B" : "#94A3B8"
753
+ },
754
+ children: idx + 1
755
+ }
756
+ )
757
+ }
758
+ ),
759
+ m.era && /* @__PURE__ */ jsx2(
760
+ "span",
761
+ {
762
+ style: {
763
+ fontFamily: FONTS2.mono,
764
+ fontSize: 13,
765
+ fontWeight: 700,
766
+ letterSpacing: "0.07em",
767
+ textTransform: "uppercase",
768
+ padding: "2px 10px",
769
+ borderRadius: 9999,
770
+ color: isActive ? "#FFFFFF" : isLight ? "#64748B" : "#94A3B8",
771
+ backgroundColor: isActive ? nodeColor : isLight ? "rgba(15, 23, 42, 0.06)" : "rgba(255, 255, 255, 0.07)"
772
+ },
773
+ children: m.era
774
+ }
775
+ ),
776
+ /* @__PURE__ */ jsx2(
777
+ "div",
778
+ {
779
+ style: {
780
+ fontFamily: FONTS2.display,
781
+ fontSize: isVerticalViewport ? 19 : 21,
782
+ fontWeight: 800,
783
+ lineHeight: 1.2,
784
+ color: isActive || isCompleted ? isLight ? STUDIO_THEME2.colors.text.slate900 : THEME2.colors.textPrimary : isLight ? "#94A3B8" : "#64748B"
785
+ },
786
+ children: m.label
787
+ }
788
+ ),
789
+ m.detail && /* @__PURE__ */ jsx2(
790
+ "div",
791
+ {
792
+ style: {
793
+ fontFamily: FONTS2.sans,
794
+ fontSize: 15,
795
+ fontWeight: 500,
796
+ color: isLight ? STUDIO_THEME2.colors.text.secondary : THEME2.colors.textSecondary
797
+ },
798
+ children: m.detail
799
+ }
800
+ )
801
+ ]
802
+ },
803
+ m.id
804
+ );
805
+ })
806
+ ]
807
+ }
808
+ )
809
+ }
810
+ );
811
+ };
812
+
813
+ // packages/kits/src/data-storytelling/MetricComparisonCard.tsx
814
+ import { ArrowRight } from "lucide-react";
815
+ import {
816
+ Easing as Easing2,
817
+ interpolate as interpolate3,
818
+ spring as spring3,
819
+ useCurrentFrame as useCurrentFrame3,
820
+ useVideoConfig as useVideoConfig3
821
+ } from "remotion";
822
+ import {
823
+ FONTS as FONTS3,
824
+ SPRING_PRESETS as SPRING_PRESETS3,
825
+ STUDIO_THEME as STUDIO_THEME3,
826
+ THEME as THEME3,
827
+ useStudioFontsReady as useStudioFontsReady3
828
+ } from "@make-pictures/core";
829
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
830
+ function computeAutoDelta(before, after) {
831
+ if (Math.abs(before) < 1e-6) {
832
+ return after >= 0 ? `+${after.toFixed(0)}` : `${after.toFixed(0)}`;
833
+ }
834
+ const pct = (after - before) / Math.abs(before) * 100;
835
+ const sign = pct >= 0 ? "+" : "";
836
+ return `${sign}${Math.round(pct)}%`;
837
+ }
838
+ var RadialGauge = ({
839
+ fraction,
840
+ color,
841
+ textLabel,
842
+ isLight,
843
+ size
844
+ }) => {
845
+ const stroke = 12;
846
+ const radius = (size - stroke) / 2;
847
+ const circumference = 2 * Math.PI * radius;
848
+ const clamped = Math.max(0, Math.min(1, fraction));
849
+ const dashOffset = circumference * (1 - clamped);
850
+ return /* @__PURE__ */ jsxs3(
851
+ "div",
852
+ {
853
+ style: {
854
+ position: "relative",
855
+ width: size,
856
+ height: size,
857
+ display: "flex",
858
+ alignItems: "center",
859
+ justifyContent: "center"
860
+ },
861
+ children: [
862
+ /* @__PURE__ */ jsxs3("svg", { width: size, height: size, style: { transform: "rotate(-90deg)" }, children: [
863
+ /* @__PURE__ */ jsx3(
864
+ "circle",
865
+ {
866
+ cx: size / 2,
867
+ cy: size / 2,
868
+ r: radius,
869
+ fill: "none",
870
+ stroke: isLight ? "rgba(15, 23, 42, 0.08)" : "rgba(255, 255, 255, 0.10)",
871
+ strokeWidth: stroke
872
+ }
873
+ ),
874
+ /* @__PURE__ */ jsx3(
875
+ "circle",
876
+ {
877
+ cx: size / 2,
878
+ cy: size / 2,
879
+ r: radius,
880
+ fill: "none",
881
+ stroke: color,
882
+ strokeWidth: stroke,
883
+ strokeLinecap: "round",
884
+ strokeDasharray: circumference,
885
+ strokeDashoffset: dashOffset
886
+ }
887
+ )
888
+ ] }),
889
+ /* @__PURE__ */ jsx3(
890
+ "span",
891
+ {
892
+ style: {
893
+ position: "absolute",
894
+ fontFamily: FONTS3.display,
895
+ fontVariantNumeric: "tabular-nums",
896
+ fontSize: size >= 156 ? 32 : 28,
897
+ fontWeight: 800,
898
+ letterSpacing: "-0.03em",
899
+ color: isLight ? STUDIO_THEME3.colors.text.slate900 : THEME3.colors.textPrimary
900
+ },
901
+ children: textLabel
902
+ }
903
+ )
904
+ ]
905
+ }
906
+ );
907
+ };
908
+ var MetricComparisonCard = ({
909
+ title,
910
+ beforeLabel,
911
+ beforeValue,
912
+ afterLabel,
913
+ afterValue,
914
+ maxValue,
915
+ prefix = "",
916
+ unit = "",
917
+ decimals = 0,
918
+ deltaBadge,
919
+ mode = "rings",
920
+ beforeColor = "#64748B",
921
+ afterColor = STUDIO_THEME3.colors.accents.emerald,
922
+ enterFrame,
923
+ startFrame,
924
+ variant = "dark",
925
+ safeBox9x16 = true,
926
+ style
927
+ }) => {
928
+ const frame = useCurrentFrame3();
929
+ const { fps, width, height } = useVideoConfig3();
930
+ useStudioFontsReady3();
931
+ const effectiveStart = Math.max(2, startFrame ?? enterFrame ?? 2);
932
+ const enter = spring3({
933
+ frame: frame - effectiveStart,
934
+ fps,
935
+ config: SPRING_PRESETS3.snappy
936
+ });
937
+ if (enter <= 5e-3) {
938
+ return null;
939
+ }
940
+ const beforeProgress = interpolate3(
941
+ frame,
942
+ [effectiveStart + 4, effectiveStart + 44],
943
+ [0, 1],
944
+ {
945
+ easing: Easing2.out(Easing2.cubic),
946
+ extrapolateLeft: "clamp",
947
+ extrapolateRight: "clamp"
948
+ }
949
+ );
950
+ const afterProgress = interpolate3(
951
+ frame,
952
+ [effectiveStart + 14, effectiveStart + 60],
953
+ [0, 1],
954
+ {
955
+ easing: Easing2.out(Easing2.cubic),
956
+ extrapolateLeft: "clamp",
957
+ extrapolateRight: "clamp"
958
+ }
959
+ );
960
+ const badgePop = spring3({
961
+ frame: frame - (effectiveStart + 24),
962
+ fps,
963
+ config: SPRING_PRESETS3.snappy
964
+ });
965
+ const ceiling = Math.max(
966
+ 1e-6,
967
+ maxValue ?? Math.max(Math.abs(beforeValue), Math.abs(afterValue)) * 1.12
968
+ );
969
+ const curBefore = beforeValue * beforeProgress;
970
+ const curAfter = afterValue * afterProgress;
971
+ const beforeFrac = Math.abs(curBefore) / ceiling;
972
+ const afterFrac = Math.abs(curAfter) / ceiling;
973
+ const formattedBefore = `${prefix}${curBefore.toFixed(decimals)}${unit}`;
974
+ const formattedAfter = `${prefix}${curAfter.toFixed(decimals)}${unit}`;
975
+ const resolvedDelta = deltaBadge ?? computeAutoDelta(beforeValue, afterValue);
976
+ const isVerticalViewport = height > width;
977
+ const isLight = variant === "light";
978
+ const cardWidth = isVerticalViewport && safeBox9x16 ? Math.min(830, width - 90) : 880;
979
+ const gaugeSize = isVerticalViewport ? 148 : 164;
980
+ return /* @__PURE__ */ jsxs3(
981
+ "div",
982
+ {
983
+ style: {
984
+ width: cardWidth,
985
+ padding: isVerticalViewport ? "28px 30px" : "34px 42px",
986
+ borderRadius: 26,
987
+ boxSizing: "border-box",
988
+ backgroundColor: isLight ? STUDIO_THEME3.colors.bgSurfaceGlass : "rgba(13, 15, 26, 0.88)",
989
+ border: isLight ? `1.5px solid ${STUDIO_THEME3.colors.border.subtle}` : "1.5px solid rgba(255, 255, 255, 0.12)",
990
+ boxShadow: isLight ? STUDIO_THEME3.shadows.cardElevated : THEME3.shadows.glow(afterColor, 0.7),
991
+ backdropFilter: "blur(16px)",
992
+ opacity: enter,
993
+ transform: `translateY(${interpolate3(enter, [0, 1], [24, 0]).toFixed(2)}px) scale(${interpolate3(enter, [0, 1], [0.95, 1]).toFixed(4)})`,
994
+ ...style
995
+ },
996
+ children: [
997
+ /* @__PURE__ */ jsxs3(
998
+ "div",
999
+ {
1000
+ style: {
1001
+ display: "flex",
1002
+ alignItems: "center",
1003
+ justifyContent: "space-between",
1004
+ gap: 16,
1005
+ marginBottom: 26
1006
+ },
1007
+ children: [
1008
+ title ? /* @__PURE__ */ jsx3(
1009
+ "div",
1010
+ {
1011
+ style: {
1012
+ fontFamily: FONTS3.display,
1013
+ fontSize: isVerticalViewport ? 28 : 30,
1014
+ fontWeight: 800,
1015
+ letterSpacing: "-0.02em",
1016
+ color: isLight ? STUDIO_THEME3.colors.text.slate900 : THEME3.colors.textPrimary
1017
+ },
1018
+ children: title
1019
+ }
1020
+ ) : /* @__PURE__ */ jsx3("div", {}),
1021
+ /* @__PURE__ */ jsx3(
1022
+ "div",
1023
+ {
1024
+ style: {
1025
+ fontFamily: FONTS3.mono,
1026
+ fontSize: 17,
1027
+ fontWeight: 800,
1028
+ padding: "6px 16px",
1029
+ borderRadius: 9999,
1030
+ color: "#FFFFFF",
1031
+ backgroundColor: afterColor,
1032
+ boxShadow: `0 8px 24px ${afterColor}55`,
1033
+ opacity: badgePop,
1034
+ transform: `scale(${interpolate3(badgePop, [0, 1], [0.85, 1]).toFixed(3)})`
1035
+ },
1036
+ children: resolvedDelta
1037
+ }
1038
+ )
1039
+ ]
1040
+ }
1041
+ ),
1042
+ mode === "rings" ? /* @__PURE__ */ jsxs3(
1043
+ "div",
1044
+ {
1045
+ style: {
1046
+ display: "flex",
1047
+ alignItems: "center",
1048
+ justifyContent: "space-around",
1049
+ gap: 20
1050
+ },
1051
+ children: [
1052
+ /* @__PURE__ */ jsxs3(
1053
+ "div",
1054
+ {
1055
+ style: {
1056
+ display: "flex",
1057
+ flexDirection: "column",
1058
+ alignItems: "center",
1059
+ gap: 12
1060
+ },
1061
+ children: [
1062
+ /* @__PURE__ */ jsx3(
1063
+ RadialGauge,
1064
+ {
1065
+ fraction: beforeFrac,
1066
+ color: beforeColor,
1067
+ textLabel: formattedBefore,
1068
+ isLight,
1069
+ size: gaugeSize
1070
+ }
1071
+ ),
1072
+ /* @__PURE__ */ jsx3(
1073
+ "span",
1074
+ {
1075
+ style: {
1076
+ fontFamily: FONTS3.sans,
1077
+ fontSize: 19,
1078
+ fontWeight: 600,
1079
+ color: isLight ? STUDIO_THEME3.colors.text.secondary : THEME3.colors.textSecondary
1080
+ },
1081
+ children: beforeLabel
1082
+ }
1083
+ )
1084
+ ]
1085
+ }
1086
+ ),
1087
+ /* @__PURE__ */ jsx3(
1088
+ "div",
1089
+ {
1090
+ style: {
1091
+ width: 52,
1092
+ height: 52,
1093
+ borderRadius: 9999,
1094
+ display: "flex",
1095
+ alignItems: "center",
1096
+ justifyContent: "center",
1097
+ backgroundColor: isLight ? "rgba(15, 23, 42, 0.06)" : "rgba(255, 255, 255, 0.08)",
1098
+ opacity: badgePop
1099
+ },
1100
+ children: /* @__PURE__ */ jsx3(ArrowRight, { size: 26, color: afterColor, strokeWidth: 2.8 })
1101
+ }
1102
+ ),
1103
+ /* @__PURE__ */ jsxs3(
1104
+ "div",
1105
+ {
1106
+ style: {
1107
+ display: "flex",
1108
+ flexDirection: "column",
1109
+ alignItems: "center",
1110
+ gap: 12
1111
+ },
1112
+ children: [
1113
+ /* @__PURE__ */ jsx3(
1114
+ RadialGauge,
1115
+ {
1116
+ fraction: afterFrac,
1117
+ color: afterColor,
1118
+ textLabel: formattedAfter,
1119
+ isLight,
1120
+ size: gaugeSize
1121
+ }
1122
+ ),
1123
+ /* @__PURE__ */ jsx3(
1124
+ "span",
1125
+ {
1126
+ style: {
1127
+ fontFamily: FONTS3.sans,
1128
+ fontSize: 19,
1129
+ fontWeight: 700,
1130
+ color: isLight ? STUDIO_THEME3.colors.text.slate900 : THEME3.colors.textPrimary
1131
+ },
1132
+ children: afterLabel
1133
+ }
1134
+ )
1135
+ ]
1136
+ }
1137
+ )
1138
+ ]
1139
+ }
1140
+ ) : (
1141
+ /* Horizontal Bars Mode */
1142
+ /* @__PURE__ */ jsx3("div", { style: { display: "flex", flexDirection: "column", gap: 22 }, children: [
1143
+ {
1144
+ lbl: beforeLabel,
1145
+ txt: formattedBefore,
1146
+ frac: beforeFrac,
1147
+ col: beforeColor,
1148
+ bold: false
1149
+ },
1150
+ {
1151
+ lbl: afterLabel,
1152
+ txt: formattedAfter,
1153
+ frac: afterFrac,
1154
+ col: afterColor,
1155
+ bold: true
1156
+ }
1157
+ ].map((row, idx) => /* @__PURE__ */ jsxs3(
1158
+ "div",
1159
+ {
1160
+ style: { display: "flex", flexDirection: "column", gap: 8 },
1161
+ children: [
1162
+ /* @__PURE__ */ jsxs3(
1163
+ "div",
1164
+ {
1165
+ style: {
1166
+ display: "flex",
1167
+ justifyContent: "space-between",
1168
+ alignItems: "center"
1169
+ },
1170
+ children: [
1171
+ /* @__PURE__ */ jsx3(
1172
+ "span",
1173
+ {
1174
+ style: {
1175
+ fontFamily: FONTS3.sans,
1176
+ fontSize: 20,
1177
+ fontWeight: row.bold ? 700 : 600,
1178
+ color: row.bold ? isLight ? STUDIO_THEME3.colors.text.slate900 : THEME3.colors.textPrimary : isLight ? STUDIO_THEME3.colors.text.secondary : THEME3.colors.textSecondary
1179
+ },
1180
+ children: row.lbl
1181
+ }
1182
+ ),
1183
+ /* @__PURE__ */ jsx3(
1184
+ "span",
1185
+ {
1186
+ style: {
1187
+ fontFamily: FONTS3.mono,
1188
+ fontVariantNumeric: "tabular-nums",
1189
+ fontSize: 22,
1190
+ fontWeight: 800,
1191
+ color: row.bold ? row.col : isLight ? "#475569" : "#CBD5E1"
1192
+ },
1193
+ children: row.txt
1194
+ }
1195
+ )
1196
+ ]
1197
+ }
1198
+ ),
1199
+ /* @__PURE__ */ jsx3(
1200
+ "div",
1201
+ {
1202
+ style: {
1203
+ width: "100%",
1204
+ height: 18,
1205
+ borderRadius: 9999,
1206
+ backgroundColor: isLight ? "rgba(15, 23, 42, 0.08)" : "rgba(255, 255, 255, 0.09)",
1207
+ overflow: "hidden"
1208
+ },
1209
+ children: /* @__PURE__ */ jsx3(
1210
+ "div",
1211
+ {
1212
+ style: {
1213
+ width: `${Math.max(4, row.frac * 100).toFixed(2)}%`,
1214
+ height: "100%",
1215
+ borderRadius: 9999,
1216
+ backgroundColor: row.col,
1217
+ boxShadow: row.bold ? `0 0 18px ${row.col}66` : "none"
1218
+ }
1219
+ }
1220
+ )
1221
+ }
1222
+ )
1223
+ ]
1224
+ },
1225
+ idx
1226
+ )) })
1227
+ )
1228
+ ]
1229
+ }
1230
+ );
1231
+ };
1232
+
1233
+ export {
1234
+ AnimatedBarRace,
1235
+ TimelineTrack,
1236
+ MetricComparisonCard
1237
+ };