Spaces:
Running
Running
| // @ts-nocheck | |
| // For You — Algorithmic Capture style. The 3-beat product showcase rendered as a | |
| // recommendation feed. Ground is FeedShell; every device is a real feed primitive: | |
| // FeedCard posts, EngagementRail counters, AlgoCore boost. No grey filler — | |
| // flopping posts, an AlgoCore-boosted post spiking to #1, and a pinned FREE card | |
| // locking in tell the whole story. | |
| import React from "react"; | |
| import { AbsoluteFill, useCurrentFrame, useVideoConfig } from "remotion"; | |
| import { FeedShell, FeedCard, EngagementRail, AlgoCore, fmt, MONO } from "../../feed/feed"; | |
| import { C, ACCENT_GRAD, withAlpha } from "../../chronixel/theme"; | |
| import { FONT } from "../../chronixel/fonts"; | |
| import { | |
| beat, | |
| springAt, | |
| clamp01, | |
| mix, | |
| osc, | |
| enter, | |
| EASE, | |
| SPRING, | |
| } from "../../chronixel/motion"; | |
| import { | |
| Post, | |
| Camera, | |
| Particles, | |
| GlowPulse, | |
| Shockwave, | |
| LightSweep, | |
| Streaks, | |
| } from "../../chronixel/fx"; | |
| /* ---------- shared: a big pill label that reads as a feed overlay tag ---------- */ | |
| const Tag: React.FC<{ | |
| text: string; | |
| p: number; | |
| big?: boolean; | |
| hot?: boolean; | |
| style?: React.CSSProperties; | |
| }> = ({ text, p, big = false, hot = false, style }) => ( | |
| <div | |
| style={{ | |
| display: "inline-flex", | |
| alignItems: "center", | |
| padding: big ? "16px 34px" : "11px 22px", | |
| borderRadius: 999, | |
| background: hot ? ACCENT_GRAD : C.glass, | |
| border: `1px solid ${hot ? "transparent" : C.glassBorder}`, | |
| boxShadow: hot ? `0 18px 50px -16px ${C.accentGlow}` : "none", | |
| fontFamily: MONO, | |
| fontWeight: 700, | |
| fontSize: big ? 30 : 21, | |
| letterSpacing: "0.18em", | |
| color: hot ? "#1a0d03" : C.textDim, | |
| opacity: clamp01(p), | |
| transform: `translateY(${(1 - clamp01(p)) * 24}px) scale(${0.9 + clamp01(p) * 0.1})`, | |
| whiteSpace: "nowrap", | |
| ...style, | |
| }} | |
| > | |
| {text} | |
| </div> | |
| ); | |
| /* ---------- thumb device: a draining time-meter for the PAIN beat ---------- */ | |
| const DrainThumb: React.FC<{ p: number; drain: number }> = ({ p, drain }) => { | |
| const frame = useCurrentFrame(); | |
| const wobble = osc(frame / 30, 2.2) * 1.5; | |
| return ( | |
| <AbsoluteFill style={{ alignItems: "center", justifyContent: "center" }}> | |
| {/* vertical drain column */} | |
| <div | |
| style={{ | |
| position: "relative", | |
| width: 88, | |
| height: 190, | |
| borderRadius: 16, | |
| border: `2px solid ${withAlpha(C.accent, 0.5)}`, | |
| overflow: "hidden", | |
| background: C.bg0, | |
| opacity: clamp01(p), | |
| transform: `translateY(${(1 - clamp01(p)) * 20}px)`, | |
| }} | |
| > | |
| <div | |
| style={{ | |
| position: "absolute", | |
| left: 0, | |
| right: 0, | |
| bottom: 0, | |
| height: `${(1 - drain * 0.8) * 100}%`, | |
| background: `linear-gradient(180deg, ${C.accent2}, ${C.accentDeep})`, | |
| boxShadow: `0 0 30px ${C.accentGlow}`, | |
| }} | |
| /> | |
| {/* drained ticks */} | |
| {[0.25, 0.5, 0.75].map((t) => ( | |
| <div | |
| key={t} | |
| style={{ | |
| position: "absolute", | |
| left: 0, | |
| right: 0, | |
| top: `${t * 100}%`, | |
| height: 1, | |
| background: withAlpha(C.text, 0.12), | |
| }} | |
| /> | |
| ))} | |
| </div> | |
| <div | |
| style={{ | |
| fontFamily: FONT, | |
| fontWeight: 800, | |
| fontSize: 46, | |
| color: C.accent, | |
| marginTop: 14, | |
| transform: `translateY(${wobble}px)`, | |
| opacity: clamp01(p), | |
| }} | |
| > | |
| {Math.round(drain * 80)}% | |
| </div> | |
| </AbsoluteFill> | |
| ); | |
| }; | |
| /* ============================================================================ | |
| BEAT 1 — PAIN. The For You feed surfaces manual-editing posts, but they FLOP: | |
| counters bleed down, an "80% TIME" drain meter and an "EXPENSIVE" price tag | |
| show why. The algorithm reads "LEARNING". | |
| ============================================================================ */ | |
| export const AlgorithmicCaptureScene01: React.FC = () => { | |
| const frame = useCurrentFrame(); | |
| const { fps } = useVideoConfig(); | |
| const intro = beat(frame, fps, 0, 0.5); | |
| // engagement bleeds DOWN as the post flops | |
| const flop = beat(frame, fps, 2.6, 5.2, EASE.inOut); | |
| const views = mix(2400, 180, flop); | |
| const likes = mix(96, 7, flop); | |
| const shares = mix(40, 2, flop); | |
| // drain meter fills toward 80% | |
| const drain = beat(frame, fps, 2.0, 4.6, EASE.expoOut); | |
| return ( | |
| <AbsoluteFill style={{ background: C.bg0 }}> | |
| <Post leak={0.4} aberration={0.7}> | |
| <Camera push={[1.06, 1]} drift={5}> | |
| <GlowPulse x="50%" y="58%" size={1100} color={C.accentSoft} strength={0.7} /> | |
| <Streaks count={3} opacity={0.22} /> | |
| <Particles count={14} maxSize={3} opacity={0.3} /> | |
| {/* the flopping post, centered */} | |
| <AbsoluteFill style={{ alignItems: "center", justifyContent: "center" }}> | |
| <div style={{ position: "relative", ...enter(frame, fps, 0.5, { from: "up", dist: 60 }) }}> | |
| <FeedCard | |
| caption="hand-editing motion graphics" | |
| handle="@editor_grind" | |
| badge="MANUAL EDIT" | |
| filled={1} | |
| thumb={<DrainThumb p={beat(frame, fps, 1.0, 1.8)} drain={drain} />} | |
| /> | |
| {/* engagement rail riding the right edge of the card */} | |
| <div style={{ position: "absolute", left: "100%", top: 40, marginLeft: 34 }}> | |
| <EngagementRail | |
| views={views} | |
| likes={likes} | |
| shares={shares} | |
| style={{ opacity: beat(frame, fps, 1.4, 2.2) }} | |
| /> | |
| </div> | |
| {/* FLOP arrow + label, left of the card */} | |
| <div | |
| style={{ | |
| position: "absolute", | |
| right: "100%", | |
| top: 120, | |
| marginRight: 40, | |
| display: "flex", | |
| flexDirection: "column", | |
| alignItems: "flex-end", | |
| gap: 18, | |
| }} | |
| > | |
| <Tag text="80% TIME" p={beat(frame, fps, 1.8, 2.6)} big /> | |
| <Tag text="EXPENSIVE" p={beat(frame, fps, 3.4, 4.2)} big /> | |
| {/* falling indicator */} | |
| <div | |
| style={{ | |
| fontFamily: FONT, | |
| fontWeight: 800, | |
| fontSize: 64, | |
| color: C.cool, | |
| opacity: beat(frame, fps, 3.0, 3.8) * (0.7 + 0.3 * osc(frame / 30, 1.6)), | |
| transform: `translateY(${beat(frame, fps, 3.0, 5.5) * 26}px)`, | |
| }} | |
| > | |
| ↓ FLOP | |
| </div> | |
| </div> | |
| </div> | |
| </AbsoluteFill> | |
| {/* big headline anchor */} | |
| <div | |
| style={{ | |
| position: "absolute", | |
| bottom: 150, | |
| left: 0, | |
| right: 0, | |
| textAlign: "center", | |
| fontFamily: FONT, | |
| fontWeight: 800, | |
| fontSize: 40, | |
| letterSpacing: "-0.02em", | |
| color: C.textDim, | |
| ...enter(frame, fps, 4.4, { from: "up", dist: 30 }), | |
| }} | |
| > | |
| the feed buries{" "} | |
| <span style={{ color: C.accent }}>slow, costly edits</span> | |
| </div> | |
| </Camera> | |
| <FeedShell intro={intro} boosting={0} /> | |
| </Post> | |
| </AbsoluteFill> | |
| ); | |
| }; | |
| /* ============================================================================ | |
| BEAT 2 — REVEAL. A new post drops: SCRIPT → AI → SCENES. The AlgoCore boosts | |
| it, finished scene thumbnails bloom out of the core, and engagement SPIKES | |
| to #1 with ZERO MANUAL EFFORT. Algorithm flips to "BOOSTING". | |
| ============================================================================ */ | |
| export const AlgorithmicCaptureScene02: React.FC = () => { | |
| const frame = useCurrentFrame(); | |
| const { fps } = useVideoConfig(); | |
| const intro = beat(frame, fps, 0, 0.5); | |
| const corePulse = beat(frame, fps, 1.2, 2.6, EASE.expoOut); // AlgoCore powers up | |
| const boost = beat(frame, fps, 2.4, 3.0); | |
| const spike = beat(frame, fps, 3.2, 5.6, EASE.expoOut); // counters rocket up | |
| const views = mix(180, 1_240_000, spike); | |
| const likes = mix(7, 318_000, spike); | |
| const shares = mix(2, 92_000, spike); | |
| // SCRIPT → AI → SCENES pipeline nodes | |
| const stages = ["SCRIPT", "AI", "SCENES"] as const; | |
| // finished-scene thumbnails blooming out of the core | |
| const blooms = [0, 1, 2, 3, 4, 5]; | |
| return ( | |
| <AbsoluteFill style={{ background: C.bg0 }}> | |
| <Post leak={0.5} aberration={0.8}> | |
| <Camera push={[1.05, 1]} drift={4}> | |
| <GlowPulse x="50%" y="50%" size={1300} color={C.accentSoft} strength={0.7 + corePulse * 0.4} /> | |
| <Streaks count={4} opacity={0.26} /> | |
| <Particles count={20} maxSize={4} opacity={0.45} /> | |
| {/* SCRIPT → AI → SCENES pipeline across the top */} | |
| <div | |
| style={{ | |
| position: "absolute", | |
| top: 230, | |
| left: 0, | |
| right: 0, | |
| display: "flex", | |
| alignItems: "center", | |
| justifyContent: "center", | |
| gap: 26, | |
| }} | |
| > | |
| {stages.map((s, i) => { | |
| const st = enter(frame, fps, 0.6 + i * 0.22, { from: "left", dist: 50 }); | |
| const hot = i === 1; | |
| return ( | |
| <React.Fragment key={s}> | |
| <div style={st}> | |
| <Tag text={s} p={1} hot={hot} big /> | |
| </div> | |
| {i < stages.length - 1 && ( | |
| <div | |
| style={{ | |
| fontFamily: FONT, | |
| fontWeight: 800, | |
| fontSize: 40, | |
| color: C.accent, | |
| opacity: beat(frame, fps, 1.0 + i * 0.22, 1.5 + i * 0.22), | |
| transform: `translateX(${osc(frame / 30 + i, 1.4) * 6}px)`, | |
| }} | |
| > | |
| → | |
| </div> | |
| )} | |
| </React.Fragment> | |
| ); | |
| })} | |
| </div> | |
| {/* the AlgoCore boosting the post, center */} | |
| <AbsoluteFill style={{ alignItems: "center", justifyContent: "center" }}> | |
| <div style={{ position: "relative", display: "flex", alignItems: "center", gap: 70 }}> | |
| {/* finished scene blooms radiating out */} | |
| {blooms.map((b) => { | |
| const ang = (b / blooms.length) * Math.PI * 2 - Math.PI / 2; | |
| const bp = springAt(frame, fps, 2.6 + b * 0.08, SPRING.BOUNCY); | |
| const r = mix(120, 320, clamp01(bp)) + osc(frame / 30 + b, 3) * 8; | |
| const cx = Math.cos(ang) * r; | |
| const cy = Math.sin(ang) * r * 0.62; | |
| return ( | |
| <div | |
| key={b} | |
| style={{ | |
| position: "absolute", | |
| left: 80, | |
| top: 0, | |
| width: 92, | |
| height: 60, | |
| marginLeft: -46, | |
| marginTop: -30, | |
| transform: `translate(${cx}px, ${cy}px) scale(${clamp01(bp)})`, | |
| borderRadius: 10, | |
| background: `linear-gradient(150deg, ${C.bg2}, ${C.bg0})`, | |
| border: `1px solid ${C.accentGlow}`, | |
| boxShadow: `0 10px 30px -8px ${C.accentGlow}`, | |
| overflow: "hidden", | |
| opacity: clamp01(bp), | |
| }} | |
| > | |
| <div | |
| style={{ | |
| position: "absolute", | |
| inset: 0, | |
| background: `radial-gradient(120% 100% at 30% 120%, ${C.accentSoft}, transparent 70%)`, | |
| }} | |
| /> | |
| <div | |
| style={{ | |
| position: "absolute", | |
| left: 10, | |
| bottom: 10, | |
| width: mix(20, 60, clamp01(bp)), | |
| height: 5, | |
| borderRadius: 3, | |
| background: ACCENT_GRAD, | |
| }} | |
| /> | |
| </div> | |
| ); | |
| })} | |
| {/* the core itself */} | |
| <div style={{ position: "relative", left: 34 }}> | |
| <AlgoCore p={0.6 + corePulse * 0.55} size={170} /> | |
| </div> | |
| {/* the boosted post */} | |
| <div style={{ ...enter(frame, fps, 0.9, { from: "right", dist: 70 }) }}> | |
| <div style={{ position: "relative" }}> | |
| <FeedCard | |
| caption="script → finished scenes" | |
| handle="@chronixel_ai" | |
| boosted | |
| badge="AI ◦ BOOSTED" | |
| filled={beat(frame, fps, 1.4, 2.8)} | |
| thumb={ | |
| <AbsoluteFill style={{ alignItems: "center", justifyContent: "center" }}> | |
| <div | |
| style={{ | |
| fontFamily: FONT, | |
| fontWeight: 800, | |
| fontSize: 60, | |
| color: "#1a0d03", | |
| background: ACCENT_GRAD, | |
| WebkitBackgroundClip: "text", | |
| backgroundClip: "text", | |
| opacity: beat(frame, fps, 1.8, 2.6), | |
| }} | |
| > | |
| ▶ | |
| </div> | |
| </AbsoluteFill> | |
| } | |
| /> | |
| {/* #1 rank badge slamming in */} | |
| <div | |
| style={{ | |
| position: "absolute", | |
| top: -28, | |
| right: -28, | |
| width: 96, | |
| height: 96, | |
| borderRadius: "50%", | |
| background: ACCENT_GRAD, | |
| display: "flex", | |
| alignItems: "center", | |
| justifyContent: "center", | |
| fontFamily: FONT, | |
| fontWeight: 800, | |
| fontSize: 44, | |
| color: "#1a0d03", | |
| boxShadow: `0 0 40px ${C.accentGlow}`, | |
| transform: `scale(${springAt(frame, fps, 3.4, SPRING.BOUNCY)})`, | |
| }} | |
| > | |
| #1 | |
| </div> | |
| {/* engagement rail spiking */} | |
| <div style={{ position: "absolute", left: "100%", top: 40, marginLeft: 34 }}> | |
| <EngagementRail | |
| views={views} | |
| likes={likes} | |
| shares={shares} | |
| style={{ opacity: beat(frame, fps, 2.8, 3.4) }} | |
| /> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </AbsoluteFill> | |
| <Shockwave at={3.4} x="62%" y="50%" size={520} /> | |
| <LightSweep at={3.0} strength={0.14} /> | |
| {/* ZERO MANUAL EFFORT anchor */} | |
| <div | |
| style={{ | |
| position: "absolute", | |
| bottom: 140, | |
| left: 0, | |
| right: 0, | |
| display: "flex", | |
| justifyContent: "center", | |
| }} | |
| > | |
| <Tag text="ZERO MANUAL EFFORT" p={beat(frame, fps, 4.2, 5.0)} big hot /> | |
| </div> | |
| </Camera> | |
| <FeedShell intro={intro} boosting={boost} /> | |
| </Post> | |
| </AbsoluteFill> | |
| ); | |
| }; | |
| /* ============================================================================ | |
| BEAT 3 — PAYOFF. The algorithm PINS the winning post to the top of the feed | |
| and stamps it 100% FREE — source + workflow + UI. A hard lock-in: the pinned | |
| card slams, a stamp lands with a shockwave, and a beacon pulses. | |
| ============================================================================ */ | |
| export const AlgorithmicCaptureScene03: React.FC = () => { | |
| const frame = useCurrentFrame(); | |
| const { fps } = useVideoConfig(); | |
| const intro = beat(frame, fps, 0, 0.5); | |
| // the pinned card slams down and locks | |
| const slam = springAt(frame, fps, 1.0, SPRING.HEAVY); | |
| const stampScale = springAt(frame, fps, 2.0, SPRING.HEAVY); | |
| const stampRot = mix(-16, -8, clamp01(stampScale)); | |
| const includes = ["SOURCE", "WORKFLOW", "UI CODE"] as const; | |
| // final views locked at #1 | |
| const views = mix(1_240_000, 3_600_000, beat(frame, fps, 2.4, 5.0, EASE.expoOut)); | |
| return ( | |
| <AbsoluteFill style={{ background: C.bg0 }}> | |
| <Post leak={0.55} aberration={0.9} bokeh={6}> | |
| <Camera push={[1.07, 1]} drift={4}> | |
| <GlowPulse x="50%" y="48%" size={1400} color={C.accentSoft} strength={0.8} /> | |
| <Streaks count={4} opacity={0.3} /> | |
| <Particles count={24} maxSize={4} opacity={0.5} /> | |
| {/* PINNED banner above the card */} | |
| <div | |
| style={{ | |
| position: "absolute", | |
| top: 200, | |
| left: 0, | |
| right: 0, | |
| display: "flex", | |
| justifyContent: "center", | |
| }} | |
| > | |
| <Tag | |
| text="◦ PINNED BY ALGORITHM ◦" | |
| p={beat(frame, fps, 0.4, 1.1)} | |
| big | |
| hot | |
| /> | |
| </div> | |
| {/* the locked-in pinned card */} | |
| <AbsoluteFill style={{ alignItems: "center", justifyContent: "center" }}> | |
| <div | |
| style={{ | |
| position: "relative", | |
| transform: `translateY(${(1 - clamp01(slam)) * -120}px) scale(${mix(0.94, 1, clamp01(slam))})`, | |
| opacity: clamp01(slam * 1.4), | |
| }} | |
| > | |
| <FeedCard | |
| caption="open-source AI motion engine" | |
| handle="@chronixel_ai" | |
| boosted | |
| badge="PINNED ◦ #1" | |
| filled={1} | |
| style={{ width: 560 }} | |
| thumb={ | |
| <AbsoluteFill style={{ alignItems: "center", justifyContent: "center" }}> | |
| {/* 100% FREE stamp */} | |
| <div | |
| style={{ | |
| transform: `scale(${clamp01(stampScale)}) rotate(${stampRot}deg)`, | |
| opacity: clamp01(stampScale * 1.3), | |
| padding: "18px 38px", | |
| borderRadius: 14, | |
| border: `4px solid ${C.accent}`, | |
| background: withAlpha(C.accent, 0.1), | |
| boxShadow: `0 0 50px ${C.accentGlow}, inset 0 0 30px ${C.accentSoft}`, | |
| fontFamily: FONT, | |
| fontWeight: 800, | |
| fontSize: 72, | |
| letterSpacing: "-0.02em", | |
| color: C.text, | |
| textShadow: `0 0 30px ${C.accentGlow}`, | |
| }} | |
| > | |
| 100% FREE | |
| </div> | |
| </AbsoluteFill> | |
| } | |
| /> | |
| {/* beacon pulse atop the card */} | |
| <div | |
| style={{ | |
| position: "absolute", | |
| top: -18, | |
| left: "50%", | |
| transform: "translateX(-50%)", | |
| display: "flex", | |
| alignItems: "center", | |
| gap: 10, | |
| padding: "8px 18px", | |
| borderRadius: 999, | |
| background: C.bg0, | |
| border: `1px solid ${C.accentGlow}`, | |
| opacity: beat(frame, fps, 1.4, 2.0), | |
| }} | |
| > | |
| <span | |
| style={{ | |
| width: 12, | |
| height: 12, | |
| borderRadius: "50%", | |
| background: C.accent, | |
| boxShadow: `0 0 ${10 + (0.5 + 0.5 * osc(frame / 30, 0.8)) * 16}px ${C.accentGlow}`, | |
| }} | |
| /> | |
| <span | |
| style={{ | |
| fontFamily: MONO, | |
| fontSize: 17, | |
| letterSpacing: "0.18em", | |
| color: C.accent, | |
| }} | |
| > | |
| LIVE ◦ {fmt(views)} | |
| </span> | |
| </div> | |
| {/* includes chips below the card */} | |
| <div | |
| style={{ | |
| position: "absolute", | |
| top: "100%", | |
| left: "50%", | |
| transform: "translateX(-50%)", | |
| marginTop: 28, | |
| display: "flex", | |
| gap: 16, | |
| }} | |
| > | |
| {includes.map((inc, i) => ( | |
| <div key={inc} style={enter(frame, fps, 2.6 + i * 0.14, { from: "up", dist: 26 })}> | |
| <Tag text={inc} p={1} /> | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| </AbsoluteFill> | |
| {/* impact rings on the lock-in stamp */} | |
| <Shockwave at={2.0} x="50%" y="44%" size={640} /> | |
| <Shockwave at={2.18} x="50%" y="44%" size={460} /> | |
| <LightSweep at={2.2} strength={0.16} /> | |
| </Camera> | |
| <FeedShell intro={intro} boosting={1} /> | |
| </Post> | |
| </AbsoluteFill> | |
| ); | |
| }; |