motionrender 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/cli.js +2634 -528
  2. package/dist/index.js +46 -1
  3. package/dist/player.js +13 -13
  4. package/dist/react.js +704 -9
  5. package/dist/types/packages/ai/src/agent.d.ts +57 -0
  6. package/dist/types/packages/ai/src/brand-scraper.d.ts +35 -0
  7. package/dist/types/packages/ai/src/captions.d.ts +11 -0
  8. package/dist/types/packages/ai/src/compose.d.ts +2 -0
  9. package/dist/types/packages/ai/src/edit.d.ts +69 -0
  10. package/dist/types/packages/ai/src/index.d.ts +8 -1
  11. package/dist/types/packages/ai/src/plan.d.ts +42 -0
  12. package/dist/types/packages/ai/src/prompt.d.ts +18 -0
  13. package/dist/types/packages/ai/src/providers.d.ts +35 -2
  14. package/dist/types/packages/ai/src/registry.d.ts +81 -0
  15. package/dist/types/packages/ai/src/retime.d.ts +7 -0
  16. package/dist/types/packages/ai/src/shorts.d.ts +75 -0
  17. package/dist/types/packages/cli/src/agent-cli.d.ts +15 -0
  18. package/dist/types/packages/cli/src/ai-studio-page.d.ts +1 -1
  19. package/dist/types/packages/cli/src/ai.d.ts +1 -1
  20. package/dist/types/packages/cli/src/build.d.ts +2 -0
  21. package/dist/types/packages/cli/src/templates.d.ts +13 -4
  22. package/dist/types/packages/contracts/src/index.d.ts +12 -12
  23. package/dist/types/packages/core/src/review.d.ts +24 -0
  24. package/dist/types/packages/ffmpeg/src/index.d.ts +1 -0
  25. package/dist/types/packages/jobs/src/queue.d.ts +2 -2
  26. package/dist/types/packages/jobs/src/redis.d.ts +2 -2
  27. package/dist/types/packages/react/src/components.d.ts +166 -0
  28. package/dist/types/packages/react/src/index.d.ts +54 -2
  29. package/dist/types/packages/react/src/springs.d.ts +25 -0
  30. package/dist/types/packages/schema/src/captions.d.ts +2 -0
  31. package/dist/types/packages/schema/src/index.d.ts +66 -66
  32. package/dist/types/scripts/eval-briefs.d.ts +67 -0
  33. package/package.json +1 -1
  34. package/skills/ove/SKILL.md +40 -2
  35. package/skills/ove-agent/SKILL.md +144 -0
  36. package/skills/ove-code-video/SKILL.md +17 -9
  37. package/skills/ove-motion-graphics/SKILL.md +113 -0
  38. package/skills/ove-react-video/SKILL.md +212 -0
  39. package/skills/ove-remotion/SKILL.md +122 -0
  40. package/studio/assets/index-DmZj9wTZ.css +1 -0
  41. package/studio/assets/index-n3DJI_GV.js +10 -0
  42. package/studio/index.html +2 -2
  43. package/templates/case-study/composition.json +25 -10
  44. package/templates/event-invite/composition.json +12 -2
  45. package/templates/explainer-square/composition.json +1 -1
  46. package/templates/keynote-wide/composition.json +2 -2
  47. package/templates/kinetic-reel/composition.json +73 -0
  48. package/templates/kinetic-reel/composition.schema.json +9295 -0
  49. package/templates/kinetic-reel/template.json +17 -0
  50. package/templates/kinetic-reel/video.bundle.js +72 -0
  51. package/templates/kinetic-reel/video.tsx +283 -0
  52. package/templates/product-card/composition.json +7 -2
  53. package/templates/product-wide/composition.json +1 -1
  54. package/templates/quote-card/composition.json +6 -1
  55. package/templates/saas-launch/composition.json +70 -0
  56. package/templates/saas-launch/composition.schema.json +9295 -0
  57. package/templates/saas-launch/template.json +16 -0
  58. package/templates/saas-launch/video.bundle.js +72 -0
  59. package/templates/saas-launch/video.tsx +217 -0
  60. package/templates/sale-promo/composition.json +16 -1
  61. package/templates/showcase-tall/composition.json +4 -4
  62. package/templates/slideshow/composition.json +1 -1
  63. package/templates/social-reel/composition.json +19 -4
  64. package/templates/story-tall/composition.json +1 -1
  65. package/studio/assets/index-CzOvWv9w.css +0 -1
  66. package/studio/assets/index-J_fvKgng.js +0 -11
package/dist/react.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // packages/react/src/index.ts
2
- import { Children, createContext, createElement, isValidElement, useContext } from "react";
2
+ import { Children, createContext, createElement as createElement2, isValidElement, useContext } from "react";
3
3
 
4
4
  // packages/builder/src/index.ts
5
5
  function spring(options) {
@@ -20,7 +20,658 @@ function interpolate(x, input, output, options = {}) {
20
20
  return output[i - 1] + (output[i] - output[i - 1]) * (t >= 0 && t <= 1 ? ease(t) : t);
21
21
  }
22
22
 
23
+ // packages/react/src/springs.ts
24
+ var springPresets = {
25
+ bouncy: { damping: 10, stiffness: 120, mass: 0.8 },
26
+ snappy: { damping: 18, stiffness: 180, mass: 0.5 },
27
+ smooth: { damping: 20, stiffness: 90, mass: 1 },
28
+ wobbly: { damping: 7, stiffness: 85, mass: 1 },
29
+ gentle: { damping: 24, stiffness: 70, mass: 1.2 }
30
+ };
31
+ function springValue(options) {
32
+ const { frame, fps = 30, from = 0, to = 1, delay = 0 } = options;
33
+ const currentFrame = frame - delay;
34
+ if (currentFrame <= 0) return from;
35
+ const presetConfig = options.preset ? springPresets[options.preset] : springPresets.bouncy;
36
+ const damping = options.damping ?? presetConfig.damping;
37
+ const stiffness = options.stiffness ?? presetConfig.stiffness;
38
+ const mass = options.mass ?? presetConfig.mass;
39
+ return spring({ frame: currentFrame, fps, damping, stiffness, mass, from, to });
40
+ }
41
+ function stagger(index, framesPerItem = 3, startDelay = 0) {
42
+ return startDelay + Math.max(0, index) * framesPerItem;
43
+ }
44
+
45
+ // packages/react/src/components.ts
46
+ import { createElement } from "react";
47
+ function AmbientGlow({
48
+ orbs = [
49
+ { x: "20%", y: "15%", size: 600, color: "#6366f1", opacity: 0.25, speed: 0.03, phase: 0 },
50
+ { x: "80%", y: "75%", size: 700, color: "#ec4899", opacity: 0.2, speed: 0.025, phase: 2 },
51
+ { x: "50%", y: "90%", size: 500, color: "#06b6d4", opacity: 0.18, speed: 0.035, phase: 4 }
52
+ ],
53
+ style,
54
+ blur = 100
55
+ }) {
56
+ const frame = useCurrentFrame();
57
+ return createElement("div", {
58
+ style: {
59
+ position: "absolute",
60
+ inset: 0,
61
+ overflow: "hidden",
62
+ pointerEvents: "none",
63
+ ...style
64
+ }
65
+ }, orbs.map((orb, index) => {
66
+ const speed = orb.speed ?? 0.03;
67
+ const phase = orb.phase ?? index * 1.5;
68
+ const dx = Math.sin(frame * speed + phase) * 40;
69
+ const dy = Math.cos(frame * speed * 0.8 + phase) * 35;
70
+ const size = typeof orb.size === "number" ? `${orb.size}px` : orb.size ?? "500px";
71
+ return createElement("div", {
72
+ key: index,
73
+ style: {
74
+ position: "absolute",
75
+ left: typeof orb.x === "number" ? `${orb.x}px` : orb.x,
76
+ top: typeof orb.y === "number" ? `${orb.y}px` : orb.y,
77
+ width: size,
78
+ height: size,
79
+ transform: `translate(calc(-50% + ${dx.toFixed(1)}px), calc(-50% + ${dy.toFixed(1)}px))`,
80
+ background: `radial-gradient(circle, ${orb.color} 0%, rgba(0,0,0,0) 70%)`,
81
+ opacity: orb.opacity ?? 0.2,
82
+ filter: `blur(${blur}px)`,
83
+ willChange: "transform"
84
+ }
85
+ });
86
+ }));
87
+ }
88
+ function GlassCard({
89
+ children,
90
+ style,
91
+ delay = 0,
92
+ preset = "snappy"
93
+ }) {
94
+ const frame = useCurrentFrame();
95
+ const { fps } = useVideoConfig();
96
+ const progress = springValue({ frame, fps, delay, preset, from: 0, to: 1 });
97
+ const y = (1 - progress) * 28;
98
+ const scale = 0.94 + progress * 0.06;
99
+ const opacity = Math.min(1, Math.max(0, progress * 1.4));
100
+ return createElement("div", {
101
+ style: {
102
+ background: "rgba(255, 255, 255, 0.05)",
103
+ backdropFilter: "blur(24px)",
104
+ WebkitBackdropFilter: "blur(24px)",
105
+ border: "1px solid rgba(255, 255, 255, 0.12)",
106
+ boxShadow: "0 20px 50px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.15)",
107
+ borderRadius: 20,
108
+ padding: 32,
109
+ opacity,
110
+ transform: `translateY(${y.toFixed(2)}px) scale(${scale.toFixed(3)})`,
111
+ willChange: "transform, opacity",
112
+ ...style
113
+ }
114
+ }, children);
115
+ }
116
+ function KineticText({
117
+ text,
118
+ delay = 0,
119
+ staggerDelay = 3,
120
+ preset = "bouncy",
121
+ style,
122
+ wordStyle,
123
+ wordTriggers
124
+ }) {
125
+ const frame = useCurrentFrame();
126
+ const { fps } = useVideoConfig();
127
+ const words = text.split(/\s+/).filter(Boolean);
128
+ return createElement("span", {
129
+ style: {
130
+ display: "inline-flex",
131
+ flexWrap: "wrap",
132
+ gap: "0.28em",
133
+ ...style
134
+ }
135
+ }, words.map((word, index) => {
136
+ let wordDelay = delay + index * staggerDelay;
137
+ if (wordTriggers && wordTriggers.length > 0) {
138
+ const stripped = word.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
139
+ const trigger = wordTriggers.find((t) => t.word.replace(/[^a-zA-Z0-9]/g, "").toLowerCase() === stripped);
140
+ if (trigger !== void 0) {
141
+ wordDelay = trigger.frame;
142
+ }
143
+ }
144
+ const progress = springValue({ frame, fps, delay: wordDelay, preset, from: 0, to: 1 });
145
+ const y = (1 - progress) * 32;
146
+ const opacity = Math.min(1, Math.max(0, progress * 1.5));
147
+ const scale = 0.85 + progress * 0.15;
148
+ return createElement("span", {
149
+ key: index,
150
+ style: {
151
+ display: "inline-block",
152
+ opacity,
153
+ transform: `translateY(${y.toFixed(2)}px) scale(${scale.toFixed(3)})`,
154
+ willChange: "transform, opacity",
155
+ ...wordStyle
156
+ }
157
+ }, word);
158
+ }));
159
+ }
160
+ function NumberTicker({
161
+ value,
162
+ from = 0,
163
+ prefix = "",
164
+ suffix = "",
165
+ decimals = 0,
166
+ delay = 0,
167
+ preset = "smooth",
168
+ style
169
+ }) {
170
+ const frame = useCurrentFrame();
171
+ const { fps } = useVideoConfig();
172
+ const progress = springValue({ frame, fps, delay, preset, from: 0, to: 1 });
173
+ const current = from + (value - from) * progress;
174
+ const formatted = current.toLocaleString("en-US", {
175
+ minimumFractionDigits: decimals,
176
+ maximumFractionDigits: decimals
177
+ });
178
+ return createElement("span", {
179
+ style: {
180
+ fontVariantNumeric: "tabular-nums",
181
+ display: "inline-block",
182
+ ...style
183
+ }
184
+ }, `${prefix}${formatted}${suffix}`);
185
+ }
186
+ function Badge({
187
+ children,
188
+ dot = true,
189
+ dotColor = "#10b981",
190
+ delay = 0,
191
+ style
192
+ }) {
193
+ const frame = useCurrentFrame();
194
+ const { fps } = useVideoConfig();
195
+ const progress = springValue({ frame, fps, delay, preset: "bouncy", from: 0, to: 1 });
196
+ const scale = 0.8 + progress * 0.2;
197
+ const opacity = Math.min(1, Math.max(0, progress * 1.5));
198
+ return createElement(
199
+ "div",
200
+ {
201
+ style: {
202
+ display: "inline-flex",
203
+ alignItems: "center",
204
+ gap: 8,
205
+ padding: "6px 14px",
206
+ borderRadius: 9999,
207
+ background: "rgba(255, 255, 255, 0.08)",
208
+ border: "1px solid rgba(255, 255, 255, 0.16)",
209
+ color: "#f9fafb",
210
+ fontSize: 14,
211
+ fontWeight: 500,
212
+ letterSpacing: "0.02em",
213
+ opacity,
214
+ transform: `scale(${scale.toFixed(3)})`,
215
+ willChange: "transform, opacity",
216
+ ...style
217
+ }
218
+ },
219
+ dot ? createElement("span", {
220
+ style: {
221
+ width: 8,
222
+ height: 8,
223
+ borderRadius: "50%",
224
+ background: dotColor,
225
+ boxShadow: `0 0 10px ${dotColor}`
226
+ }
227
+ }) : null,
228
+ children
229
+ );
230
+ }
231
+ function DeviceFrame({
232
+ children,
233
+ title = "Application Preview",
234
+ url,
235
+ delay = 0,
236
+ style
237
+ }) {
238
+ const frame = useCurrentFrame();
239
+ const { fps } = useVideoConfig();
240
+ const progress = springValue({ frame, fps, delay, preset: "snappy", from: 0, to: 1 });
241
+ const y = (1 - progress) * 45;
242
+ const scale = 0.92 + progress * 0.08;
243
+ const opacity = Math.min(1, Math.max(0, progress * 1.3));
244
+ return createElement(
245
+ "div",
246
+ {
247
+ style: {
248
+ display: "flex",
249
+ flexDirection: "column",
250
+ background: "#131722",
251
+ borderRadius: 16,
252
+ border: "1px solid rgba(255, 255, 255, 0.1)",
253
+ boxShadow: "0 30px 80px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.05)",
254
+ overflow: "hidden",
255
+ opacity,
256
+ transform: `translateY(${y.toFixed(2)}px) scale(${scale.toFixed(3)})`,
257
+ willChange: "transform, opacity",
258
+ ...style
259
+ }
260
+ },
261
+ // Top bar
262
+ createElement(
263
+ "div",
264
+ {
265
+ style: {
266
+ display: "flex",
267
+ alignItems: "center",
268
+ padding: "12px 16px",
269
+ background: "rgba(255, 255, 255, 0.03)",
270
+ borderBottom: "1px solid rgba(255, 255, 255, 0.06)",
271
+ gap: 12
272
+ }
273
+ },
274
+ // Traffic lights
275
+ createElement(
276
+ "div",
277
+ { style: { display: "flex", gap: 6 } },
278
+ createElement("span", { style: { width: 10, height: 10, borderRadius: "50%", background: "#ef4444" } }),
279
+ createElement("span", { style: { width: 10, height: 10, borderRadius: "50%", background: "#f59e0b" } }),
280
+ createElement("span", { style: { width: 10, height: 10, borderRadius: "50%", background: "#10b981" } })
281
+ ),
282
+ // URL or Title bar
283
+ url ? createElement("div", {
284
+ style: {
285
+ flex: 1,
286
+ maxWidth: 360,
287
+ margin: "0 auto",
288
+ background: "rgba(0, 0, 0, 0.25)",
289
+ padding: "3px 12px",
290
+ borderRadius: 6,
291
+ fontSize: 12,
292
+ color: "#94a3b8",
293
+ textAlign: "center",
294
+ fontFamily: "monospace",
295
+ border: "1px solid rgba(255, 255, 255, 0.05)"
296
+ }
297
+ }, url) : createElement("div", {
298
+ style: {
299
+ flex: 1,
300
+ textAlign: "center",
301
+ fontSize: 13,
302
+ color: "#94a3b8",
303
+ fontWeight: 500
304
+ }
305
+ }, title)
306
+ ),
307
+ // Frame content
308
+ createElement("div", {
309
+ style: {
310
+ position: "relative",
311
+ flex: 1,
312
+ overflow: "hidden"
313
+ }
314
+ }, children)
315
+ );
316
+ }
317
+ function ProgressBar({
318
+ value,
319
+ delay = 0,
320
+ color = "#38bdf8",
321
+ height = 8,
322
+ style
323
+ }) {
324
+ const frame = useCurrentFrame();
325
+ const { fps } = useVideoConfig();
326
+ const target = Math.min(1, Math.max(0, value));
327
+ const progress = springValue({ frame, fps, delay, preset: "smooth", from: 0, to: target });
328
+ return createElement("div", {
329
+ style: {
330
+ width: "100%",
331
+ height,
332
+ background: "rgba(255, 255, 255, 0.1)",
333
+ borderRadius: 9999,
334
+ overflow: "hidden",
335
+ ...style
336
+ }
337
+ }, createElement("div", {
338
+ style: {
339
+ width: `${(progress * 100).toFixed(2)}%`,
340
+ height: "100%",
341
+ background: color,
342
+ boxShadow: `0 0 12px ${color}`,
343
+ borderRadius: 9999,
344
+ willChange: "width"
345
+ }
346
+ }));
347
+ }
348
+ function BentoGrid({
349
+ columns = 3,
350
+ gap = 20,
351
+ style,
352
+ children
353
+ }) {
354
+ const gridTemplateColumns = typeof columns === "number" ? `repeat(${columns}, minmax(0, 1fr))` : columns;
355
+ const gapValue = typeof gap === "number" ? `${gap}px` : gap;
356
+ return createElement("div", {
357
+ style: {
358
+ display: "grid",
359
+ gridTemplateColumns,
360
+ gap: gapValue,
361
+ width: "100%",
362
+ ...style
363
+ }
364
+ }, children);
365
+ }
366
+ function BentoCard({
367
+ colSpan = 1,
368
+ rowSpan = 1,
369
+ title,
370
+ subtitle,
371
+ badge,
372
+ icon,
373
+ delay = 0,
374
+ preset = "snappy",
375
+ glowColor = "rgba(99, 102, 241, 0.15)",
376
+ style,
377
+ children
378
+ }) {
379
+ const frame = useCurrentFrame();
380
+ const { fps } = useVideoConfig();
381
+ const progress = springValue({ frame, fps, delay, preset, from: 0, to: 1 });
382
+ const y = (1 - progress) * 24;
383
+ const scale = 0.95 + progress * 0.05;
384
+ const opacity = Math.min(1, Math.max(0, progress * 1.4));
385
+ const gridColumn = typeof colSpan === "number" ? `span ${colSpan} / span ${colSpan}` : colSpan;
386
+ const gridRow = typeof rowSpan === "number" ? `span ${rowSpan} / span ${rowSpan}` : rowSpan;
387
+ return createElement(
388
+ "div",
389
+ {
390
+ style: {
391
+ gridColumn,
392
+ gridRow,
393
+ position: "relative",
394
+ background: "rgba(18, 20, 29, 0.75)",
395
+ backdropFilter: "blur(20px)",
396
+ WebkitBackdropFilter: "blur(20px)",
397
+ border: "1px solid rgba(255, 255, 255, 0.08)",
398
+ boxShadow: `0 12px 32px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 40px ${glowColor}`,
399
+ borderRadius: 20,
400
+ padding: 24,
401
+ display: "flex",
402
+ flexDirection: "column",
403
+ overflow: "hidden",
404
+ opacity,
405
+ transform: `translateY(${y.toFixed(2)}px) scale(${scale.toFixed(3)})`,
406
+ willChange: "transform, opacity",
407
+ ...style
408
+ }
409
+ },
410
+ title || badge || icon ? createElement(
411
+ "div",
412
+ {
413
+ style: {
414
+ display: "flex",
415
+ alignItems: "center",
416
+ justifyContent: "space-between",
417
+ marginBottom: subtitle || children ? 16 : 0,
418
+ gap: 12
419
+ }
420
+ },
421
+ createElement(
422
+ "div",
423
+ {
424
+ style: { display: "flex", alignItems: "center", gap: 10 }
425
+ },
426
+ icon ? createElement("div", {
427
+ style: {
428
+ display: "flex",
429
+ alignItems: "center",
430
+ justifyContent: "center",
431
+ width: 36,
432
+ height: 36,
433
+ borderRadius: 10,
434
+ background: "rgba(255, 255, 255, 0.06)",
435
+ border: "1px solid rgba(255, 255, 255, 0.1)"
436
+ }
437
+ }, icon) : null,
438
+ title ? createElement("div", {
439
+ style: {
440
+ fontSize: 18,
441
+ fontWeight: 600,
442
+ color: "#f8fafc",
443
+ letterSpacing: "-0.01em"
444
+ }
445
+ }, title) : null
446
+ ),
447
+ badge ? typeof badge === "string" ? createElement(Badge, null, badge) : badge : null
448
+ ) : null,
449
+ subtitle ? createElement("div", {
450
+ style: {
451
+ fontSize: 14,
452
+ color: "#94a3b8",
453
+ lineHeight: 1.5,
454
+ marginBottom: children ? 16 : 0
455
+ }
456
+ }, subtitle) : null,
457
+ children
458
+ );
459
+ }
460
+ function Typewriter({
461
+ text,
462
+ delay = 0,
463
+ speed = 0.75,
464
+ cursor = true,
465
+ cursorChar = "\u258D",
466
+ cursorBlinkSpeed = 16,
467
+ style,
468
+ cursorStyle
469
+ }) {
470
+ const frame = useCurrentFrame();
471
+ const elapsed = Math.max(0, frame - delay);
472
+ const charCount = Math.min(text.length, Math.floor(elapsed * speed));
473
+ const visibleText = text.slice(0, charCount);
474
+ const isDone = charCount >= text.length;
475
+ const blink = cursor && Math.floor(frame / (cursorBlinkSpeed / 2)) % 2 === 0;
476
+ return createElement(
477
+ "span",
478
+ {
479
+ style: {
480
+ display: "inline-flex",
481
+ alignItems: "baseline",
482
+ fontFamily: "monospace",
483
+ ...style
484
+ }
485
+ },
486
+ visibleText,
487
+ cursor ? createElement("span", {
488
+ style: {
489
+ display: "inline-block",
490
+ marginLeft: 2,
491
+ opacity: blink ? 1 : isDone ? 0.3 : 0,
492
+ color: "#38bdf8",
493
+ willChange: "opacity",
494
+ ...cursorStyle
495
+ }
496
+ }, cursorChar) : null
497
+ );
498
+ }
499
+ function Waveform({
500
+ bars = 24,
501
+ height = 50,
502
+ color = "#6366f1",
503
+ activeColor = "#ec4899",
504
+ speed = 0.12,
505
+ delay = 0,
506
+ preset = "snappy",
507
+ style
508
+ }) {
509
+ const frame = useCurrentFrame();
510
+ const { fps } = useVideoConfig();
511
+ const progress = springValue({ frame, fps, delay, preset, from: 0, to: 1 });
512
+ const opacity = Math.min(1, Math.max(0, progress * 1.5));
513
+ const barElements = [];
514
+ for (let i = 0; i < bars; i++) {
515
+ const wave1 = Math.sin(frame * speed + i * 0.45);
516
+ const wave2 = Math.cos(frame * speed * 0.7 + i * 0.3);
517
+ const wave3 = Math.sin(frame * speed * 1.3 + i * 0.8);
518
+ const combined = (wave1 + wave2 + wave3) / 3;
519
+ const normalized = (combined + 1) / 2;
520
+ const barHeight = Math.max(8, normalized * height * progress);
521
+ barElements.push(createElement("div", {
522
+ key: i,
523
+ style: {
524
+ width: 4,
525
+ height: `${barHeight.toFixed(1)}px`,
526
+ borderRadius: 9999,
527
+ background: `linear-gradient(to top, ${color}, ${activeColor})`,
528
+ opacity: 0.6 + normalized * 0.4,
529
+ boxShadow: normalized > 0.65 ? `0 0 10px ${activeColor}` : void 0,
530
+ transformOrigin: "bottom",
531
+ willChange: "height"
532
+ }
533
+ }));
534
+ }
535
+ return createElement("div", {
536
+ style: {
537
+ display: "inline-flex",
538
+ alignItems: "center",
539
+ gap: 4,
540
+ height,
541
+ opacity,
542
+ willChange: "opacity",
543
+ ...style
544
+ }
545
+ }, barElements);
546
+ }
547
+ function CodeEditor({
548
+ filename = "main.ts",
549
+ code,
550
+ language = "typescript",
551
+ delay = 0,
552
+ highlightLines = [],
553
+ showLineNumbers = true,
554
+ preset = "snappy",
555
+ style
556
+ }) {
557
+ const frame = useCurrentFrame();
558
+ const { fps } = useVideoConfig();
559
+ const progress = springValue({ frame, fps, delay, preset, from: 0, to: 1 });
560
+ const y = (1 - progress) * 35;
561
+ const scale = 0.94 + progress * 0.06;
562
+ const opacity = Math.min(1, Math.max(0, progress * 1.4));
563
+ const lines = code.trim().split("\n");
564
+ return createElement(
565
+ "div",
566
+ {
567
+ style: {
568
+ display: "flex",
569
+ flexDirection: "column",
570
+ background: "#0d1117",
571
+ borderRadius: 14,
572
+ border: "1px solid rgba(255, 255, 255, 0.12)",
573
+ boxShadow: "0 25px 60px rgba(0, 0, 0, 0.65)",
574
+ fontFamily: 'Consolas, Monaco, "Courier New", monospace',
575
+ fontSize: 14,
576
+ overflow: "hidden",
577
+ opacity,
578
+ transform: `translateY(${y.toFixed(2)}px) scale(${scale.toFixed(3)})`,
579
+ willChange: "transform, opacity",
580
+ ...style
581
+ }
582
+ },
583
+ createElement(
584
+ "div",
585
+ {
586
+ style: {
587
+ display: "flex",
588
+ alignItems: "center",
589
+ padding: "10px 16px",
590
+ background: "rgba(255, 255, 255, 0.03)",
591
+ borderBottom: "1px solid rgba(255, 255, 255, 0.06)",
592
+ gap: 12
593
+ }
594
+ },
595
+ createElement(
596
+ "div",
597
+ { style: { display: "flex", gap: 6 } },
598
+ createElement("span", { style: { width: 10, height: 10, borderRadius: "50%", background: "#ef4444" } }),
599
+ createElement("span", { style: { width: 10, height: 10, borderRadius: "50%", background: "#f59e0b" } }),
600
+ createElement("span", { style: { width: 10, height: 10, borderRadius: "50%", background: "#10b981" } })
601
+ ),
602
+ createElement("div", {
603
+ style: {
604
+ color: "#94a3b8",
605
+ fontSize: 12,
606
+ fontWeight: 500,
607
+ margin: "0 auto"
608
+ }
609
+ }, filename),
610
+ createElement("div", {
611
+ style: {
612
+ color: "#64748b",
613
+ fontSize: 11,
614
+ textTransform: "uppercase",
615
+ letterSpacing: "0.05em"
616
+ }
617
+ }, language)
618
+ ),
619
+ createElement("div", {
620
+ style: {
621
+ padding: "16px 0",
622
+ overflowX: "auto",
623
+ lineHeight: 1.6
624
+ }
625
+ }, lines.map((line, idx) => {
626
+ const lineNum = idx + 1;
627
+ const isHighlighted = highlightLines.includes(lineNum);
628
+ return createElement(
629
+ "div",
630
+ {
631
+ key: idx,
632
+ style: {
633
+ display: "flex",
634
+ padding: "0 20px",
635
+ background: isHighlighted ? "rgba(56, 189, 248, 0.12)" : "transparent",
636
+ borderLeft: isHighlighted ? "3px solid #38bdf8" : "3px solid transparent"
637
+ }
638
+ },
639
+ showLineNumbers ? createElement("span", {
640
+ style: {
641
+ width: 32,
642
+ flexShrink: 0,
643
+ color: isHighlighted ? "#38bdf8" : "#475569",
644
+ userSelect: "none",
645
+ textAlign: "right",
646
+ marginRight: 16
647
+ }
648
+ }, lineNum) : null,
649
+ createElement("span", {
650
+ style: {
651
+ color: isHighlighted ? "#f8fafc" : "#cbd5e1",
652
+ whiteSpace: "pre"
653
+ }
654
+ }, line || " ")
655
+ );
656
+ }))
657
+ );
658
+ }
659
+
23
660
  // packages/react/src/index.ts
661
+ function spring2(options) {
662
+ const damping = options.config?.damping ?? options.damping;
663
+ const stiffness = options.config?.stiffness ?? options.stiffness;
664
+ const mass = options.config?.mass ?? options.mass;
665
+ return spring({
666
+ frame: options.frame,
667
+ fps: options.fps,
668
+ damping,
669
+ stiffness,
670
+ mass,
671
+ from: options.from,
672
+ to: options.to
673
+ });
674
+ }
24
675
  var shared = globalThis.__oveReact ??= { frame: createContext(null), config: createContext(null) };
25
676
  function useCurrentFrame() {
26
677
  const frame = useContext(shared.frame);
@@ -41,7 +692,7 @@ function delayRender(label) {
41
692
  function continueRender(handle) {
42
693
  globalThis.__oveDelays?.delete(handle);
43
694
  }
44
- var mediaMarker = (kind, props, extra = {}) => createElement("i", {
695
+ var mediaMarker = (kind, props, extra = {}) => createElement2("i", {
45
696
  hidden: true,
46
697
  "data-ove-media": kind,
47
698
  "data-src": props.src,
@@ -59,16 +710,16 @@ function Video(props) {
59
710
  return mediaMarker("video", props, { "data-left": props.left ?? 0, "data-top": props.top ?? 0, "data-width": props.width ?? 0, "data-height": props.height ?? 0, "data-fit": props.objectFit ?? "cover", "data-layer": props.layer ?? "back", "data-muted": props.muted ? 1 : 0 });
60
711
  }
61
712
  function Img(props) {
62
- return createElement("img", props);
713
+ return createElement2("img", props);
63
714
  }
64
715
  function AbsoluteFill({ style, children, ...rest }) {
65
- return createElement("div", { style: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0, display: "flex", flexDirection: "column", ...style }, ...rest }, children);
716
+ return createElement2("div", { style: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0, display: "flex", flexDirection: "column", ...style }, ...rest }, children);
66
717
  }
67
718
  function Sequence({ from = 0, durationInFrames = Infinity, layout = "absolute-fill", children }) {
68
719
  const frame = useCurrentFrame();
69
720
  if (frame < from || frame >= from + durationInFrames) return null;
70
- const inner = createElement(shared.frame.Provider, { value: frame - from }, children);
71
- return layout === "none" ? inner : createElement(AbsoluteFill, null, inner);
721
+ const inner = createElement2(shared.frame.Provider, { value: frame - from }, children);
722
+ return layout === "none" ? inner : createElement2(AbsoluteFill, null, inner);
72
723
  }
73
724
  function Series({ children }) {
74
725
  let start = 0;
@@ -77,11 +728,11 @@ function Series({ children }) {
77
728
  const { durationInFrames, offset = 0, children: inner } = child.props;
78
729
  if (!(durationInFrames > 0)) throw new Error("Every Series.Sequence needs a durationInFrames");
79
730
  start += offset;
80
- const element = createElement(Sequence, { key: i, from: start, durationInFrames }, inner);
731
+ const element = createElement2(Sequence, { key: i, from: start, durationInFrames }, inner);
81
732
  start += durationInFrames;
82
733
  return element;
83
734
  });
84
- return createElement("div", { style: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0 } }, ...parts);
735
+ return createElement2("div", { style: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0 } }, ...parts);
85
736
  }
86
737
  Series.Sequence = function SeriesSequence(_props) {
87
738
  return null;
@@ -122,19 +773,63 @@ function random(seed) {
122
773
  h ^= h >>> 16;
123
774
  return (h >>> 0) / 4294967296;
124
775
  }
776
+ var staticFile = (src) => src.replace(/^\/+/, "");
777
+ function Loop({ durationInFrames, times = Infinity, children }) {
778
+ const frame = useCurrentFrame();
779
+ if (frame >= durationInFrames * times) return null;
780
+ const looped = frame % durationInFrames;
781
+ return createElement2(shared.frame.Provider, { value: looped }, children);
782
+ }
783
+ function Freeze({ frame = 0, children }) {
784
+ return createElement2(shared.frame.Provider, { value: frame }, children);
785
+ }
786
+ function Composition(props) {
787
+ if (typeof globalThis !== "undefined") {
788
+ const list = globalThis.__oveCompositions ??= [];
789
+ list.push(props);
790
+ }
791
+ return null;
792
+ }
793
+ function Folder({ children }) {
794
+ return createElement2("div", { style: { display: "contents" } }, children);
795
+ }
796
+ function Still(props) {
797
+ return Composition({ ...props, durationInFrames: 1 });
798
+ }
125
799
  export {
126
800
  AbsoluteFill,
801
+ AmbientGlow,
127
802
  Audio,
803
+ Badge,
804
+ BentoCard,
805
+ BentoGrid,
806
+ CodeEditor,
807
+ Composition,
808
+ DeviceFrame,
128
809
  Easing,
810
+ Folder,
811
+ Freeze,
812
+ GlassCard,
129
813
  Img,
814
+ KineticText,
815
+ Loop,
816
+ NumberTicker,
817
+ ProgressBar,
130
818
  Sequence,
131
819
  Series,
820
+ Still,
821
+ Typewriter,
132
822
  Video,
823
+ Waveform,
133
824
  continueRender,
134
825
  delayRender,
135
826
  interpolate,
136
827
  random,
137
- spring,
828
+ spring2 as spring,
829
+ springPresets,
830
+ springValue,
831
+ stagger,
832
+ staticFile,
138
833
  useCurrentFrame,
139
834
  useVideoConfig
140
835
  };