AI CSS Animations

Election Night Board

An election-night board for a fictional country: 120 hexagon districts fill with party colors as results declare, seat counts and vote tallies climb in lockstep, and the seat bar's teal edge crosses the 61-seat majority line for the call.

Written and rendered by AI CSS Animations Oct 16, 2026

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

About this style

Results graphics have been the centerpiece of election-night television for decades, moving from studio boards and hand-turned gadgets to computer-driven maps and live counters. Hexagon cartograms give every district a tile of the same size, so a dense city seat weighs as much on screen as a vast rural one, which a geographic map hides. A seat bar with a marked majority line answers the night's main question at a glance, and newsrooms around the world pair the two in broadcast and online coverage.

The prompt

Make a 10-second election-night results board for a fictional country: a hex map fills district by district, vote tallies count, and the seat bar crosses the majority line.

<inputs>
- Network: Tarnbrook News. Title: "Valdren Assembly Election".
- Seats: 120 districts; 61 for a majority.
- Parties, final seats and votes: Tidewater Alliance (teal) 64 seats, 2,148,310 votes; Commonfield Party (amber) 38 seats, 1,703,955 votes; Upland League (plum) 13 seats, 897,402 votes; Independents (slate) 5 seats, 463,090 votes. Totals: 120 seats and 5,212,757 votes, so 41.2%, 32.7%, 17.2% and 8.9%.
- Call line: "Tidewater Alliance wins a majority".
- Length: 10 seconds.
If I don't give you something, use the default and don't ask.
</inputs>

<direction>
Palette: studio light #EEF2F6; panels #FFFFFF with a 1px #D5DCE4 border and 12px radius; ink #121821; muted #5B6775; undeclared hexes #D9DEE5; Tidewater #0E9AA7, Commonfield #E39B2E, Upland #8A4FB0, Independents #7D8796; a static LIVE chip #D7263D. Party colors appear only where they mean that party.
Type: Public Sans with tabular figures on every number. Title 800 at 56px; network bug 700 at 22px, uppercase; party names 700 at 30px; seat numbers 800 at 80px; vote counts 500 at 26px; percentages 700 at 30px; labels 600 at 22px, uppercase, tracked 0.08em.
Layout, 96px side margins: network bug and LIVE chip at y 64–100; the title at y 112–168 on the left, with "Declared 0 of 120" (30px) right-aligned on the same line. Map panel x 96–1056, y 200–860. Right column x 1120–1824: a reserved call slot at y 200–264, then four party rows, 130px tall with 16px gaps, from y 288: a 10px color bar, the name, the vote count and percentage beneath it, and the seat number right-aligned. Seat bar across x 96–1824 at y 912–960 with its label above at y 884; the majority tick is a 3px ink line at x 974 (seat 61 of 120) from y 900 to 972, labeled "61 for a majority".
Hex map: pointy-top hexagons on an axial grid, centers 56px apart, each drawn 51px wide so a 5px gap of panel white separates them. Author the country's silhouette as a coarse polygon, keep the cells whose centers fall inside, and add or trim edge cells until there are exactly 120. Group them into five contiguous regions; draw 3px ink borders in the gaps where regions meet and a 2px ink outline around the country.
Winners: assign them once from a seeded lean field so parties cluster (Tidewater along the west coast, Commonfield across the center and east, Upland in the northern hills, Independents scattered), then flip the lowest-margin cells until the counts are exactly 64 / 38 / 13 / 5. The declaration order is seeded but plausible: dense city districts first, remote ones last. Choose it so Commonfield leads on seats until about 4.5s, Tidewater leads by 5.0s, and Tidewater's 61st seat is the district that declares at 7.0s.
Seat bar: 120 blocks of 14.4px with 2px gaps. Tidewater fills from the left; Commonfield, Upland and Independents fill from the right, in that order inward; undeclared seats are the gray gap between.
Popular vote: each party's count rises along its own smooth curve against districts declared (Commonfield running slightly ahead early, Tidewater catching up late), ending exactly on its total; percentages are recomputed from the live counts every frame, so they shift a few points and settle on 41.2 / 32.7 / 17.2 / 8.9.
Motion: data moves in lockstep and everything else is still. A declared hex fills from its center outward (0.3s, cubic-bezier(0.2, 0.8, 0.2, 1)) while a 2px white ring grows from 1× to 1.5× and fades over 0.4s, once per hex. Seat bar blocks extend over 0.25s on cubic-bezier(0.16, 1, 0.3, 1). Panels build once at the start (rising 12px over 0.4s) and never move again.
The real thing is a newsroom instrument: every number reconciles, map and bar move together, and the call lands once with restraint. The cheap version is a spinning globe, confetti and a swooping 3D bar chart.
Banned: real parties, countries, politicians, flags or emblems; red-versus-blue party colors; confetti or fireworks; 3D; gradients on data; pie or donut charts; faces or photos; a blinking LIVE dot; counts that don't reconcile; anything flashing more than 3 times per second.
</direction>

<structure>
0.0–0.8s: the header builds: the network bug wipes in from the left, the LIVE chip appears, the title rises 16px out of a mask, and the declared counter fades up at the right.
0.8–1.6s: the map appears as undeclared gray hexes, each scaling from 0 in a west-to-east sweep (5ms stagger); the region borders draw on over 0.4s.
1.6–2.4s: party rows rise into place 80ms apart, showing 0 seats and 0 votes; the seat bar track and majority tick draw, with the tick's label.
2.4–8.0s: districts declare in the seeded order, slowly at first, fastest around 5s, easing at the end; seat numbers, seat bar, vote counts, percentages and the declared counter update together.
7.0–7.4s: Tidewater's 61st seat lands: its bar edge passes the tick, the tick turns teal and thickens to 5px, and a teal call band reading "TIDEWATER ALLIANCE WINS A MAJORITY" (white, 700, 28px) wipes into the call slot from the left.
8.0–8.8s: the last districts declare; seats read 64 / 38 / 13 / 5 and the counter reads "Declared 120 of 120"; the LIVE chip becomes an ink FINAL chip; a check mark draws beside Tidewater's seat number.
8.8–10.0s: hold, nothing moving.
For other durations, stretch the declaration phase, keep the majority call 1s before the last declaration, and hold at least 1s.
</structure>

<build>
One self-contained index.html, CSS and JS inline. Google Fonts via <link> are fine; await document.fonts.load() for each face before defining window.seek. No other libraries (no three.js: this style is flat). Draw in inline SVG whose attributes seek sets directly. 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. Assign winners and the declaration order once at load; every number on screen is derived from which districts have declared by t. 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. On every sampled frame, count the filled hexes per party and confirm they match the row seat numbers and the seat bar; confirm the call lands exactly with Tidewater's 61st seat, the final percentages sum to 100.0, the hex gaps are even, and the call band covers nothing. 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.

Similar prompts

More like this on the motion design inspiration board: Data visualization inspirationMap animation inspiration