Recolor the three blobs, preview the animation, then generate standalone HTML.
Original design by Marina Budarina, Figma Community file "Animated gradients"
The generated file is fully self-contained (no dependencies, no external assets).
It's free to use, no attribution required. If you ship it somewhere, tag it, and I'll feature it here.
DashPad uses this gradient in its hero
.html file.The output has no dependencies: no JS libraries, no build step, no external images or fonts.
Drop the <div class="gradient-card">…</div> block and its
<style> straight into any page. To resize it, just override the
width/height on .gradient-card; the SVG paths scale with
it since preserveAspectRatio="none" stretches to fill.
The animation is SMIL (native SVG <animate>), supported in every modern
browser (Chrome, Safari, Firefox, Edge) with no JavaScript running after page load. It respects
prefers-reduced-motion by disabling the animation for users who've asked for less
motion. The blur is a CSS filter, so it's GPU-accelerated like any other CSS effect.
Free to use for anything, commercial included, no attribution required. The design itself is from Marina Budarina's Figma Community file; credit to her ( @marina_uiux) is appreciated if you're sharing where it came from.
Curious how a Figma file becomes an animated SVG? Here's the full pipeline.
The animation originates from a Figma Community file, “Animated gradients”. The design is three frames of one card, each a snapshot of a soft gradient mid-motion. Figma's Smart Animate tweens between them, so the three frames are really keyframes of a single loop.
A .fig is a ZIP. Inside, canvas.fig is Figma's binary
fig-kiwi container: an 8-byte fig-kiwi magic, a version, then
length-prefixed chunks. Chunk 1 is the compiled Kiwi schema (raw DEFLATE); chunk 2
is the document's node tree (Zstandard-compressed in newer files). Decoding the
schema lets you decode the message into a tree of nodes: frames, groups, and vectors.
These are rendered live below from the same path data the studio uses, not images, but the actual decoded vectors drawn statically:
Each frame is a 612×367 card (40px corners, a 10px inside white stroke) over a
#141516 base. Inside are two stacked layers, each holding the same
three blob shapes:
mix-blend-mode: color-dodge, which is what blows out the highlights and gives the
gradient its glow.Every blob is just a filled Bézier path under a heavy blur. In Figma the group carries a
FOREGROUND_BLUR of radius: 180, i.e. a blur radius of 90.
The blur is applied in CSS on each layer (filter: blur(90px)) rather
than with an in-SVG feGaussianBlur. Safari/WebKit miscomputes SVG filter regions when
the card is stretched to a different aspect ratio (and can freeze the filter mid-animation), which
leaves the blobs clipped or static; CSS blur works in screen pixels and re-renders every frame, so
it stays correct and portable across browsers.
Each vector's fillGeometry points at a commands blob, a little binary
path program: one tag byte (1=move, 4=cubic, close at the end) followed
by float32 coordinate pairs. Decoding it yields an SVG path. The blob's coordinates
are local to the vector, so each point is run through the vector's transform and then its group's
transform to land in the frame's coordinate space (0–612 × 0–367):
framePoint = groupTransform( vectorTransform( localPoint ) )
The transforms here are pure translations, which is exactly why the blobs appear to glide: Smart Animate is just moving the same shapes around between frames.
No JavaScript animation here, it's SMIL. Each blob is one <path> with an
<animate> on its d attribute, cycling through all three frames and
back to the first:
<path fill="#F6C944" d="…frame 1…">
<animate attributeName="d" dur="13.5s" repeatCount="indefinite"
calcMode="spline" keyTimes="0;0.333;0.666;1"
keySplines="0.45 0 0.25 1; 0.45 0 0.25 1; 0.45 0 0.25 1"
values="…f1…;…f2…;…f3…;…f1…" />
</path>
Path interpolation only works if every values entry has the same command
structure. Because the blobs are the same shapes translated, their command counts match
across frames (7 / 6 / 9 commands for the three blobs), so the browser interpolates each control
point linearly, reproducing Smart Animate exactly. The keySplines apply an
ease-in-out to each segment.
The page embeds the decoded path data for all three frames. Changing a color re-renders the two SVG layers with the new fills (each blob's color is shared between the base and dodge layers, as in the source). Generate HTML assembles a complete, dependency-free document with your colors baked into the paths, the exact same markup you see in the preview.