Need a deck? just a sec.
A paid social campaign for Gamma, produced as a take-home for an AI Creative Strategist role.
The brief asked for three video variants, statics in three ratios, and a process note. The normal way to do that is screen record the product, cut it in Premiere, hand back three exports. That gets you three assets. It does not get you a fourth.
The real constraint in paid social is not making one good ad. A creative that works on Meta is spent in two to three weeks, so the number that governs cost over a quarter is how fast the replacement lands. So I set a different problem: build the asset in a way where the thirtieth variant costs about what the fourth did.
The product UI in these spots is not a screen recording. It is rebuilt as vector in plain HTML and CSS, driven by a deterministic seek function that returns the exact state of any frame at any time. Puppeteer steps that one frame at a time in headless Chrome and pipes PNGs into ffmpeg, so every run is frame identical. Because the frame is a pure function of time, everything describing the ad is data: copy, timing, camera keyframes, captions, slides. Changing the concept is editing a config, not reopening a design file.
Three hooks, one spine
Three genuinely different openers run against one identical middle. A person reading the message, a team channel where the ask is already sitting there, and a title card that states the need with no setup. Each is a hypothesis about a different axis: a face buys attention, a channel buys recognition, a line buys clarity.
The middle never changes, because the middle is where viewers leave. It is one unbroken 11.1 second take of the real product flow that never cuts away from the screen, so the payoff and the product are the same shot. All three land on 20.00 seconds exactly, because each opener buys its length out of its own close.
Building the system before the output
The first pass built the engine, not the spot. That is the whole bet, and it is visible in the file structure: 2,663 lines of engine across 13 files, then three finished videos that are each a short config on top of it.
It paid off twice. Once when the concept changed completely mid-build, which cost 50 minutes instead of a restart, and the previous concept still renders untouched from its archived config. Again on every round of revisions, where a note like the captions are in the wrong place is a coordinate change and a re-render rather than a re-edit.
Diagnosing motion by measuring it, not watching it
Several rounds of feedback were about a transition feeling choppy. Watching it back and guessing produced three failed fixes.
Tracking the object frame by frame found the cause in one pass. The canvas clipped content flat against the page with no visible boundary, so the final slide's bottom edge sat pinned on the clip line for thirteen consecutive frames while its top climbed. It was not scrolling into place. It was inflating, because the bottom physically could not move.
The same approach fixed the cut into the send beat. Measuring pixel difference across the cut gave a number to work against: 117,677 differing pixels before, 305 after. That is the difference between an edit that reads as a scene change and one that is invisible.
Handed over as a system
182 files across 13 folders, not three exports. Alpha layers on ProRes 4444 and VP9 so any line can be reworded without touching the base. A 65 piece component library for Figma. A build script where changing one constant re-cuts all three videos consistently. The statics render from the same config as the video, which is why the times on screen match across all of it.
I wrote none of the code by hand. Claude Opus 5 through Claude Code built the engine, the overlay layers and the build script, and drove every render. The concept, the campaign line, the hook structure, the pacing and every creative call were mine, and several rounds were rejected and rebuilt on my direction. The AI is in how it was made, not in what plays.



