A newspaper-grade animated chart: serif headline and dek, a two-line chart that draws year by year, a shaded 2020 band, a crossover callout and a source note, all with fictional but internally consistent data.
Written and rendered by AI CSS Animations Oct 12, 2026
Newspaper graphics desks developed a disciplined chart style: a headline that states the finding, a chart with direct labels and light gridlines, annotations that explain why the data moves, and a source line underneath. Animated, the chart builds in the order a reader should take it in. Publishers and brands borrow the style because it signals rigor and makes a single point unmistakable.
<inputs>
You're making an animated newspaper-style data graphic with fictional data. I may supply any of these; if I don't give you something, use the default and don't ask.
- Kicker / headline: "TRANSPORT" / "Bikes now outnumber cars on Marrowford's bridges".
- Dek: "After a decade of steady growth, cycling overtook driving across the Ferrow River in 2025."
- Data, average weekday crossings in thousands, 2016–2025. Bikes: 8.2, 8.9, 9.6, 10.8, 13.9, 15.1, 16.4, 18.0, 19.7, 21.3. Cars: 31.0, 30.4, 29.8, 28.9, 22.1, 24.6, 23.8, 22.5, 21.6, 20.4.
- Source line: "Marrowford City Transport Office, automated bridge counters. 2025 figures are provisional."
- Length: 10 seconds.
</inputs>
<direction>
Page #F8F5EF; text #141414; secondary #66625C; gridlines #DAD4C9 at 1px; baseline #141414 at 1.5px. One series carries the story: bikes #0B7A75 at 4px; cars neutral #9C968C at 3px; 2020 band #ECE5D8.
Type: headline "Source Serif 4" 700, 64px, sentence case, ≤2 lines; dek "Source Serif 4" 400, 30px, #444; kicker "Libre Franklin" 700, 18px, tracking 0.12em, bike color; chart text "Libre Franklin" 500, 20px, tabular numerals; source 16px, #66625C.
Layout: 120px side margins. Kicker, headline and dek stack top-left; the chart title ("Average weekday crossings, Ferrow River bridges") sits above a 1,400×460 plot. Gridlines every 10,000; y labels sit just above them at the left, no axis line, the unit only on the top one ("40,000 crossings"). X labels every year ("2016", "'17"…). Label series at their line ends; no legend.
Annotations interpret rather than restate: short text, a 1px leader ending in a 4px dot on the data, never crossing a line. Every number must match the data (cars −24% in 2020; bikes +160% since 2016).
Easing: easeOutCubic and easeInOutSine only, 0.3–0.6s for text. Lines draw through an evenly advancing clip, a dot and live value riding each leading edge.
Authentic: high data-ink, direct labels, one color doing the talking, a sourced footnote. Cheap: glossy charts, rainbow series.
Banned: bouncy easing, gradients, shadows, dual axes, chart libraries, all-caps headlines, real publication names or logos, emoji.
</direction>
<structure>
- 0–1.6s: kicker, headline, then dek (from 0.9s), each rising 16px as it fades in.
- 1.6–2.4s: chart title, gridlines (left to right, 40ms apart) and axis labels.
- 2.4–5.4s: both lines draw 2016→2025, leading values counting up.
- 5.4–6.4s: the 2020 band shades in; annotation: "Lockdowns cut car crossings by nearly a quarter."
- 6.4–7.8s: a ring pulses once at the crossover; callout: "2025: 21,300 bikes vs. 20,400 cars a day."
- 7.8–8.6s: end labels "Bikes" and "Cars"; "+160% since 2016" by the bike line.
- 8.6–9.2s: the source line ("Source: …") fades in.
- 9.2–10s: hold.
Other lengths: stretch the line draw first; keep the 0.8s hold.
</structure>
<build>
One self-contained index.html (inline CSS and JS; Google Fonts via <link> are fine), a 1920×1080 (16:9) stage scaled to fit the window, built for 60fps. Use SVG with hand-computed scales; three.js isn't needed.
window.seek(t) (t in seconds) sets every visual from t alone, clamping past the end to the last frame. No CSS transitions or CSS animations, no setTimeout/setInterval, no state carried between frames. Any randomness comes from a seeded PRNG keyed to the frame, never Math.random.
With no ?render in the URL, call seek from requestAnimationFrame so it plays in a browser; with ?render, don't start that loop.
</build>
<check>
Before showing me, step through one frame per second (0–10s) and look at each. Fix overlaps, clipped or cramped text and anything off-style: every number matching the data, annotations clear of lines and each other, a clean two-line headline. Confirm the final frame holds.
</check> Ours, and free to use under CC0: copy it, change it, ship it. No credit needed.
A light analytics dashboard builds itself from fictional data that adds up: counters roll on tabular figures, sparkline…
A crisp live-sports graphics package over a soft-focus stadium feed: score bug with running clock, layered lower third,…
The front door is /hyperframes. This skill makes a short, design-led, unnarrated motion graphic (motion is the message;…
<inputs> Ask me for: 8 to 12 UI states I want the shape to become (e.g. button, loader, player, slider, toggle, tabs, c…