AI CSS Animations

Game of Life

Conway's Game of Life on a deep aubergine grid, every cell colored by its age from butter to periwinkle: a Gosper gun fires gliders with warm wakes into an eater, a pulsar and pentadecathlon tick, an R-pentomino erupts into chaos and the run pauses at generation 148.

Written and rendered by AI CSS Animations Oct 19, 2026

Type
prompt
Made with
Claude Opus 5.5 in Claude Code
Built in
Canvas
Topics
Shapes
What Claude made from the prompt below in Claude Code: one HTML file rendered frame by frame to video. Silent preview.

About this style

The Game of Life is a cellular automaton devised by the mathematician John Horton Conway in 1970 and made famous by Martin Gardner's Scientific American column that October. Each cell on a grid lives or dies by counting its eight neighbors, and from that single rule come still lifes, oscillators, gliders that travel across the grid and long chaotic eruptions such as the R-pentomino. Bill Gosper found the first glider gun in 1970, proving that a finite pattern can grow forever, and later work showed the rules can carry out any computation. Programmers, artists and science communicators still use it as the classic picture of complex behavior arising from simple rules.

The prompt

Make a 10-second Game of Life film: Conway's rules run on a grid where every cell is colored by how long it has been alive, with a glider gun firing into an eater, oscillators ticking and an R-pentomino erupting into chaos.

<inputs>
If I don't give you something, use the default and don't ask.
- Title: "Nothing here is drawn."
- Line: "Conway's Game of Life, every cell colored by its age"
- Rule: B3/S23: a dead cell with exactly 3 live neighbors is born; a live cell with 2 or 3 live neighbors survives; every other cell dies or stays dead.
- Speed: 20 generations per second from 1.0 s, pausing at generation 148.
- Length: 10 seconds.
</inputs>

<direction>
- Palette, warm age on deep aubergine: board #1A1020 with a 2px grid dot #2C1E34 at every cell corner. A live cell's color comes from its age a (generations alive, 1 at birth), interpolated on ln a between six stops: 1 butter #FFF3B0, 3 marigold #FFC857, 8 coral #FF7F51, 20 raspberry #E8487A, 60 violet #9B4DCA, 150 and older periwinkle #4F5BD5. Moving things stay warm and bright; anything that sits still cools to violet and blue. Type #FFF3E0, secondary #B8A6C4.
- Ghosts: when a cell dies it leaves its last color behind at strength 0.85·e^(−Δt/0.25), Δt the seconds since it died, so gliders trail short warm wakes and period-2 cells shimmer instead of blinking: no cell's brightness drops more than about 30% between generations.
- The grid: 160 × 90 visible cells at 12px, filling the 1920×1080 stage. A live cell is a 10px square with 3px corner radius centered in its slot, with a 1px top edge 8% lighter, like an enamel tile. Simulate on a 256 × 160 board with the visible window at offset (48, 35); cells beyond the window keep evolving but aren't drawn, so nothing reflects off the frame edge. The camera is locked; cells sit on exact pixels.
- Generation 0, in visible-window cell coordinates (x right, y down), each RLE pattern's top-left cell at the coordinate given, unrotated:
  - Gosper glider gun at (56, 8): 24bo$22bobo$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o$2o8bo3bob2o4bobo$10bo5bo7bo$11bo3bo$12b2o!
  - eater 1 at (102, 40): 2o$obo$2bo$2b2o!
  - pulsar at (128, 6): 2b3o3b3o2b2$o4bobo4bo$o4bobo4bo$o4bobo4bo$2b3o3b3o2b2$2b3o3b3o2b$o4bobo4bo$o4bobo4bo$o4bobo4bo2$2b3o3b3o!
  - pentadecathlon at (136, 30): 2bo4bo2b$2ob4ob2o$2bo4bo!
  - blinker at (60, 31): 3o!; toad at (67, 30): b3o$3o!; beacon at (76, 29): 2o$2o$2b2o$2b2o!
  - a row of still lifes: block at (57, 77) 2o$2o!; beehive at (64, 76) b2o$o2bo$b2o!; loaf at (72, 75) b2o$o2bo$bobo$2bo!; boat at (81, 76) 2o$obo$bo!; tub at (89, 76) bo$obo$bo!; pond at (96, 75) b2o$o2bo$o2bo$b2o!
  - R-pentomino at (128, 62): 2o$b2o$bo!
- What these exact placements do (verified): nothing interferes with anything else through generation 170, and no live cell ever enters the title column (x < 50). The gun releases a glider every 30 generations, each one standing free at generations 36, 66, 96 and 126; they cross down and to the right at one cell diagonally per 4 generations, and the eater swallows them at generations 103 and 133 and stays intact. The R-pentomino grows into a churning field of debris that spills off the right and bottom edges. The window holds 159 live cells at generation 0, 292 at 100 and 347 at 148.
- Between generations: the shown state is generation n = floor(g), g = 20·(t − 1.0); a newborn cell scales from 0.6 to 1 and fades in over the first 40% of its generation; a dying cell becomes its ghost. The still lifes are alive from generation 0, so they visibly cool from butter through violet to periwinkle in the first seconds.
- Labels, HTML, each on a 1px #B8A6C4 leader ending in a 4px dot on the pattern it names, set in empty board space, never more than three at once: "Gosper glider gun · period 30", "Pulsar · period 3", "Pentadecathlon · period 15", "Glider · one cell diagonally every 4 generations" (riding with the first glider), "Eater · swallows each glider", "R-pentomino · 5 cells at generation 0", "Still lifes cool to blue".
- Type, left column x 120–560, over empty board: the title in Bricolage Grotesque 700 (opsz 96), 66px, #FFF3E0, two lines from (120, 150); the line in Bricolage Grotesque 400, 26px, secondary, beneath. Counters from (120, 620) at 54px intervals: labels in Bricolage Grotesque 600, 20px, uppercase, tracked 0.12em, secondary; values in Kode Mono 500, 32px, tabular figures: Generation, Population (live cells in the window), Gliders fired (adding one at 36, 66, 96 and 126), Gliders eaten (at 103 and 133). Under them an age key: six 14px swatches with "1" and "150+ generations" at the ends in Kode Mono 400, 20px. At the pause, a chip "Paused · generation 148" in Kode Mono 500, 22px, on #2C1E34 with 10px padding.
- Easing: text rises 12px as it fades in over 0.5 s on cubic-bezier(0.22, 1, 0.36, 1); labels draw their leader over 0.25 s, then fade in.
- Premium: a small machine you can read (gun, stream, eater) beside real chaos, color that tells age at a glance, gliders leaving warm wakes, numbers that match the board. Cheap: random green squares blinking on black, a structureless soup, a grid that wraps around.
Banned: wraparound edges, random soups other than the R-pentomino, cells off the grid, glow or bloom, green-on-black, blobby metaballs, full-frame flashes, anything flashing more than 3 times per second.
</direction>

<structure>
- 0.0–1.0s: the dotted board; the patterns print in cell by cell from left to right (0.6 s), still at generation 0; the title and line rise in.
- 1.0–3.2s: the run starts; the gun churns, the pulsar and pentadecathlon pulse, the R-pentomino starts to swell, and the still lifes cool to blue; labels for the gun, pulsar and pentadecathlon attach 0.2 s apart and clear at 3.2 s; the first glider stands free at 2.8 s; the counters rise in at 1.6 s.
- 3.2–5.8s: gliders stream down toward the eater with warm wakes; the glider and R-pentomino labels; the debris field spreads with new cells warm and settled cells cooling.
- 5.8–7.8s: the eater label attaches and the first glider is swallowed at 6.15 s, the second at 7.65 s; the still-lifes label appears. The 6.0 s frame: a glider about to hit the eater, two more in flight, chaos at the lower right.
- 7.8–8.4s: labels clear; the run continues to generation 148.
- 8.4s: pause: everything stops mid-step; the chip appears; ghosts finish fading by 9.0 s so the frame turns crisp.
- 8.4–10.0s: hold.
For other lengths, change how many generations run before the pause at the same 20 per second; keep at least 1 s of hold.
</structure>

<build>
- One self-contained index.html (inline CSS and JS), a 1920×1080 (16:9) stage scaled to fit the window, designed for 60fps. No image, video, texture or model files: every shape and texture is generated in code.
- window.seek(t), t in seconds, computes every visual from t alone: no CSS transitions or CSS animations, no setTimeout/setInterval, no state carried between frames, randomness only from a seeded PRNG. Anything cumulative is solved analytically from t or precomputed once at load at a fixed step. Past the end, seek clamps to the last frame.
- 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.
- Google Fonts via <link> are fine; await document.fonts.load() for each face before defining window.seek.
- Engine: Canvas 2D, repainting every frame from scratch, the backing store sized from CSS size × devicePixelRatio. Canvas won't fetch fonts itself, so the awaited loads matter.
- Run all 170 generations once at load on the 256 × 160 board and store every generation, plus each cell's birth and death generation; seek(t) derives ages, ghosts and counters from those arrays and never steps the rules.
</build>

<check>
Before showing me, step through one frame per second (t = 0…10): screenshot each and look at it. Fix overlaps, clipped or cramped text, and anything off-style or Banned. Log the generations when gliders stand free (36, 66, 96, 126) and when the eater is touched (103, 133), and the populations at 0, 100 and 148 (159, 292, 347): any mismatch means a pattern is placed wrong. Check no cell crosses the left column, the counters match the board, labels never cover a live pattern, and still lifes end periwinkle while moving things stay warm. Confirm seek(10) and seek(11) match, so the final frame holds.
</check>

Ours, and free to use under CC0: copy it, change it, ship it. No credit needed.

Similar prompts

More like this on the motion design inspiration board: Motion graphics inspiration