diff --git a/src/remotion/ShortsVideo.tsx b/src/remotion/ShortsVideo.tsx index 94cff0e..6d782aa 100644 --- a/src/remotion/ShortsVideo.tsx +++ b/src/remotion/ShortsVideo.tsx @@ -81,7 +81,7 @@ const Scene: React.FC<{ - {label ? : null} + {label ? : null} {scene === "stat" && stat ? ( @@ -106,7 +106,7 @@ const Scene: React.FC<{ )} - + {/* time code (subtle, right side) */}
= ({ variant = 0 }) => { - const frame = useCurrentFrame(); const { width, height } = useVideoConfig(); + const frame = useCurrentFrame(); const t = frame / 60; - const p = PALETTES[variant % PALETTES.length]; + const s = SCENES[variant % SCENES.length]; + const stroke = "rgba(255,255,255,0.14)"; + const strokeSoft = "rgba(255,255,255,0.07)"; return ( - -
-
- {/* faint dot grid */} + + {/* faint motion — shape drifts very slowly (transform only, cheap) */} + + {s.motif === "circles" && ( + <> + + + + + )} + {s.motif === "plus" && ( + <> + {[0.12, 0.22, 0.5, 0.72, 0.88].map((x, i) => ( + + + + + ))} + + )} + {s.motif === "barcode" && ( + <> + {[30, 70, 110, 150, 190, 230, 270, 310].map((x, i) => ( + + ))} + {[width - 330, width - 290, width - 250, width - 210, width - 170, width - 130, width - 90].map((x, i) => ( + + ))} + + )} + {s.motif === "rings" && ( + <> + + + + + )} + {s.motif === "diag" && ( + <> + {[0, 1, 2, 3, 4, 5].map((i) => ( + + ))} + {[0, 1, 2, 3].map((i) => ( + + ))} + + )} + + {/* slow drift to keep the frame alive */}
); }; -/** Glass card (translucent, rounded, border) for caption blocks. */ +/** Flat card (solid white — inversion against the black background). */ export const GlassCard: React.FC<{ children: React.ReactNode; style?: React.CSSProperties; @@ -87,12 +120,10 @@ export const GlassCard: React.FC<{ left: "5%", right: "5%", bottom: "13%", - padding: "30px 32px", - borderRadius: 28, - background: "rgba(8,10,18,0.68)", - border: "1px solid rgba(255,255,255,0.14)", - boxShadow: "0 14px 44px rgba(0,0,0,0.4)", - transform: `translateY(${(1 - pop) * 26}px) scale(${0.97 + pop * 0.03})`, + padding: "30px 34px", + borderRadius: 20, + background: "#f2f2f4", + transform: `translateY(${(1 - pop) * 26}px)`, ...style, }} > @@ -101,11 +132,11 @@ export const GlassCard: React.FC<{ ); }; -/** Karaoke caption: active sentence full-bright, others dimmed (synced to TTS). */ +/** Karaoke caption: active sentence full-black, others grey (on white card). */ export const CaptionKaraoke: React.FC<{ sentences: { w: string; start: number; end: number }[]; size?: number; -}> = ({ sentences, size = 44 }) => { +}> = ({ sentences, size = 46 }) => { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const now = frame / fps; @@ -114,13 +145,6 @@ export const CaptionKaraoke: React.FC<{ for (let i = 0; i < sentences.length; i++) { if (now >= sentences[i].start) { activeIdx = i; break; } } - const active = sentences[activeIdx]; - const flash = active - ? interpolate(now, [active.start, active.start + 0.12, active.start + 0.35], [1, 1.06, 1], { - extrapolateLeft: "clamp", - extrapolateRight: "clamp", - }) - : 1; return (
{sentences.map((s, i) => ( - + {s.w} {i < sentences.length - 1 ? " " : ""} @@ -146,14 +167,14 @@ export const CaptionKaraoke: React.FC<{ ); }; -/** Big display title with word-by-word kinetic entrance. */ +/** Big display title, word-by-word kinetic entrance, accent = inverted block. */ export const KineticTitle: React.FC<{ text: string; size?: number; accentIndex?: number; accentColor?: string; position?: "top" | "center"; -}> = ({ text, size = 88, accentIndex = -1, accentColor = "#a5b4fc", position = "top" }) => { +}> = ({ text, size = 88, accentIndex = -1, position = "top" }) => { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const pop = spring({ frame, fps, config: { damping: 13, stiffness: 100 } }); @@ -175,20 +196,23 @@ export const KineticTitle: React.FC<{ key={i} style={{ display: "inline-block", - marginRight: "0.2em", + marginRight: "0.18em", + marginBottom: "0.08em", fontFamily: FONT_DISPLAY, fontWeight: 800, fontSize: size, lineHeight: 1.1, letterSpacing: "-0.03em", - color: i === accentIndex ? accentColor : "#ffffff", - textShadow: "0 4px 24px rgba(0,0,0,0.5)", + color: i === accentIndex ? "#000000" : "#ffffff", + background: i === accentIndex ? "#ffffff" : "transparent", + padding: i === accentIndex ? "0 0.1em 0.02em" : "0", + borderRadius: 10, opacity: interpolate(frame, [i * dur, i * dur + dur * 0.5], [0, 1], { extrapolateRight: "clamp", }), - transform: `scale(${interpolate(frame, [i * dur, i * dur + dur * 0.6], [0.78, 1], { + transform: `translateY(${interpolate(frame, [i * dur, i * dur + dur * 0.6], [26, 0], { extrapolateRight: "clamp", - })})`, + })}px)`, }} > {w} @@ -198,12 +222,11 @@ export const KineticTitle: React.FC<{ ); }; -/** Huge stat/number card (pattern interrupt for facts). */ +/** Huge stat with a thin rectangle frame behind (flat, editorial). */ export const StatCounter: React.FC<{ value: string; label: string; - color?: string; -}> = ({ value, label, color = "#a5b4fc" }) => { +}> = ({ value, label }) => { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const pop = spring({ frame, fps, config: { damping: 14, stiffness: 90 } }); @@ -211,34 +234,55 @@ export const StatCounter: React.FC<{
+
+
{value}
{label} @@ -247,36 +291,32 @@ export const StatCounter: React.FC<{ ); }; -/** Top-left scene label pill. */ -export const BrandTag: React.FC<{ label: string; variant?: number }> = ({ label, variant = 0 }) => { - const p = PALETTES[variant % PALETTES.length]; - return ( -
- {label} -
- ); -}; +/** Top-left scene label (flat outline pill). */ +export const BrandTag: React.FC<{ label: string }> = ({ label }) => ( +
+ {label} +
+); -/** Bottom progress bar (per-segment fill). */ -export const ProgressBar: React.FC<{ total: number; variant?: number }> = ({ total, variant = 0 }) => { +/** Bottom progress bar — solid white fill on faint track. */ +export const ProgressBar: React.FC<{ total: number }> = ({ total }) => { const frame = useCurrentFrame(); - const p = PALETTES[variant % PALETTES.length]; const pct = interpolate(frame, [0, total], [0, 100], { extrapolateRight: "clamp" }); return (
= ({ tot left: "6%", right: "6%", bottom: "6%", - height: 8, + height: 7, borderRadius: 99, - background: "rgba(255,255,255,0.16)", + background: "rgba(255,255,255,0.18)", overflow: "hidden", }} > @@ -296,7 +336,7 @@ export const ProgressBar: React.FC<{ total: number; variant?: number }> = ({ tot width: `${pct}%`, height: "100%", borderRadius: 99, - background: `linear-gradient(90deg, rgb(${p.a1}), rgb(${p.a2}))`, + background: "#ffffff", }} />
@@ -308,8 +348,8 @@ export const SlideMotion: React.FC<{ children: React.ReactNode }> = ({ children const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const t = frame / fps; - const y = Math.sin(t * 1.4) * 14; - const scale = 1 + Math.sin(t * 0.8) * 0.014; + const y = Math.sin(t * 1.4) * 12; + const scale = 1 + Math.sin(t * 0.8) * 0.012; return ( {children}