Nothing broke — the first render shipped. The month rail lights in step with the stats (3 lit at 2.7s, all 12 lit at the close) and the final values land exactly: 48 / 312,000 / 12.
Banned list —Beat grid —Build method —Self-review —
<direction>
A 9-second year-in-review film in Remotion (1080x1080 square, 270 frames at 30fps) for 2025. House style: near-black #0a0a0a, white type, ONE orange accent #ff5c1a, Arial/Helvetica bold, no webfonts. A twelve-dot month rail lights January to December while three annual stats count up in sequence (48 PROJECTS SHIPPED / 312,000 VIEWS / 12 CITIES), then the film closes on THANKS FOR THE YEAR.. Fictional year, sample figures, labelled SAMPLE on screen.
Banned: real company year-in-review claims, glows, gradients, stock photos, more than three headline stats.
</direction>
<structure>
Frames 0-30: heading "2025 IN REVIEW — SAMPLE YEAR" in. Frames 30-90 / 90-150 / 150-210: one stat per beat — value counts up while its month rail dots light (Jan-Apr / May-Aug / Sep-Dec). Frames 210-270: closer "THANKS FOR THE YEAR." + "ALL FIGURES ARE SAMPLE DATA"; hold.
</structure>
<build>
One Remotion component, 1080x1080, 30fps. Stats are a data array (value, formatter, label); count-ups use interpolate() with clamping; month dots light by a pure function of the frame. Everything computed from the frame number.
</build>
<gotchas>
- The month rail must finish lighting exactly when the third stat lands, or the year feels unfinished.
- Square framing is tight: stats stack vertically with generous gaps; never squeeze three stats into one row at 1080px.
- Format during the count (thousands separators), not after it.
</gotchas>
Before you finish: step through the timeline at five points and fix anything that overlaps, clips the frame, or drifts off the beat grid.
The month rail is the idea: twelve dots light as the year passes, so three stats feel like a year, not a list. A fictional year with sample figures — swap in your real ones.