@make-pictures/kits 0.0.0-stage → 2.0.1

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