On an aged white ground, a hand-painted black square, a long red bar, thin black bars and small colored planes drift in from far away along one diagonal, turning slowly as they come, and settle into a floating Suprematist arrangement with a small title.
Written and rendered by AI CSS Animations Oct 18, 2026
Suprematism was launched by Kazimir Malevich at the exhibition 0,10 in Petrograd in December 1915, where his Black Square hung high across a corner of the room. Malevich reduced painting to pure geometric forms, squares, bars, crosses and circles, floating at angles on a white ground he thought of as infinite space. El Lissitzky carried its floating planes into typography, book design and architecture. Its off-axis, weightless arrangements still recur in posters, album covers and brand systems.
Make a 10-second Suprematist composition: a black square, red bars and colored planes drift at angles on a white ground and settle into a weightless arrangement. <inputs> Title: WEIGHTLESS. Line: Forms in open space. Details: Hall 3 · Open daily. Duration: 10s. If I don't give you something, use the default and don't ask. </inputs> <direction> Palette, oil on an aged ground: ground #EEEADF, a touch warmer and darker toward the edges (#E4DDCB), black #161513, red #C62E27, ochre #E0A42C, blue #2B4A8E, green #3F7552, and pale grey #C9C4B8 at 60% for two ghost planes. Paint, never vector: render each form once at load into its own sprite. Edges wander ±0.8px along their length on low-frequency seeded noise, corners are very slightly softened, flat color carries faint brush direction (long streaks at 3%), and the black forms show fine craquelure (a seeded network of 1px cracks, 10% lighter). The ground has a faint canvas weave and brush texture at 3%. The forms at their final positions (center, size, angle). Everything lies on a dominant axis of −32° or its perpendicular, except the square: - the black square: 340×340 centered at (720, 470), turned −8°; - a long red bar: 900×52 centered at (1100, 400), on the −32° axis, its lower end tucked behind the square; - three thin black bars parallel to it, 520×14, 360×10 and 240×8, stacked below it and offset to the right; - a blue bar, 320×64, centered at (1360, 280), on the perpendicular (58°), crossing the red bar near its upper end; - an ochre trapezoid, 300 wide and 120 tall, centered at (1290, 640), on the axis; - a green plane, 240×60, centered at (960, 790), on the axis; - a black circle, 130px across, at (1600, 470); - a small red square, 80×80, at (480, 780), turned 14°; - a small red cross of two 140×18 bars at (1640, 760), on the axis; - two ghost planes, 520×90 and 300×300, behind the cluster as if far away. At least 30% of the ground stays empty around the cluster, and no form comes within 120px of the edges. Type, small and out of the way: the title in "Syncopate" 700, 52px, tracked 0.3em, black, baseline at (120, 940); the line and details in "Tenor Sans" 400, 22px, tracked 0.16em, on one line at baseline 984. Motion is weightless, as if the forms float in open space. Each enters from far away (scale 0.4 and 40% opacity, rising to full), drifting in along the dominant axis from the lower left or the upper right and turning 10–30° as it comes, and glides into place critically damped: p(s) = target + (start − target)·(1 + s/τ)·e^(−s/τ), with s the seconds since it started, τ = 0.5s for small forms and 0.8s for large ones, so nothing overshoots. Depth is parallax: the whole cluster shares one slow drift of 60px along the axis that eases to rest by 8.4s, and large near forms travel up to 1.5× as far as small far ones. Once a form has arrived it turns no faster than 6° per second. The real thing is pure form floating in infinite white, tension between angles and hand-painted edges; the cheap version is crisp vector shapes on pure white over a grid. Banned: grids, purely horizontal and vertical layouts, outlines, gradients, drop shadows, glow, arrows, heavy type, stars or any political symbol, pure white, perfectly crisp vector edges, bounce or overshoot, more than two forms entering at once, anything flashing more than 3 times per second. </direction> <structure> 0.0–0.8s: the empty ground; the two ghost planes surface from far away. 0.8–2.0s: the black square drifts in from the lower left, turning, and slows into place. 1.6–3.0s: the long red bar glides in along the axis from the upper right and slips its lower end behind the square; the three thin bars follow it, 0.2s apart. 3.0–4.4s: the blue bar crosses in on the perpendicular; the ochre trapezoid and the green plane arrive from the lower left. 4.4–5.6s: the small forms arrive, 0.3s apart: the circle, the red square, the cross. 5.6–6.6s: every form is in place; the cluster continues its slow common drift, near forms shifting more than far ones. 6.6–7.6s: the title, then the line, fade up 0.3s apart, rising 8px. 7.6–8.4s: the drift eases to rest. 8.4–10.0s: hold, completely still. For other durations, scale every timestamp proportionally. </structure> <build> One self-contained index.html, CSS and JS inline. Google Fonts via <link> are fine; no other libraries (no three.js: this style is flat). Draw in Canvas 2D, repainting every frame from scratch, the backing store sized from CSS size × devicePixelRatio. Canvas won't fetch fonts itself: await document.fonts.load() for each face, then define window.seek. Render each form's painted sprite (wandering edges, brush direction, craquelure) and the ground once at load into offscreen canvases; each frame draws the sprites with transforms computed in closed form from t. The stage is 1920×1080 (16:9), scaled to fit the window. Design for 60fps. window.seek(t), t in seconds, must compute every visual from t alone: no CSS transitions or animations, no setTimeout or setInterval, no state carried between frames, and randomness only from a seeded PRNG. Anything cumulative is precomputed once at load at a fixed step or solved analytically from t, so any frame can be drawn directly. Without ?render in the URL, drive seek from requestAnimationFrame so it plays in a browser (loop after a 1s end hold); with ?render, don't start that loop. </build> <check> Before showing me, step through one frame per second: screenshot each and look at it. Fix overlaps, clipped or cramped text, accidental edge collisions, and anything off-style or Banned. Check every form ends on the −32° axis or its perpendicular (except the square), edges read as hand-painted rather than vector-crisp at 1280×720, no form overshoots its place, the cluster leaves wide empty ground, and the title stays clear of every form. Confirm seek(duration) and seek(duration + 1) match, so the final frame holds. </check>
Ours, and free to use under CC0: copy it, change it, ship it. No credit needed.
A jazz-tempo film title sequence in flat vermilion, mustard, bone and black: hand-cut paper shards jab in on the beat,…
A Swiss-style event poster that builds itself on a visible 12-column grid: grotesque type rises out of baseline masks,…
A primary-colored circle, square and triangle roll, drop and turn into place on a black bar, assembling a constructed B…
A Constructivist poster in motion: red bars, a wedge piercing a black circle, halftone fields and condensed uppercase t…
More like this on the motion design inspiration board: Motion graphics inspiration