# Story countdown 9:16

3-2-1 countdown with pulse rings, then a headline and a pill CTA. Vertical 1080×1920 for Stories, Reels, Shorts. 6 s.

- Category: social · Tags: countdown, story, reels, shorts, vertical, 9:16
- Spec: 1080×1920 @ 30 fps · 6s (9:16)
- License: CC0 · Tier: free
- JSON: https://gimgs.net/motion/story-countdown.json
- Kind: html
- Template HTML: https://gimgs.net/motion/story-countdown/template.html
- Player: https://gimgs.net/motion/story-countdown/play?p=<base64url JSON params>[&t=<seconds>]
- Credits: gimgs — https://gimgs.net/motion
- Page: https://gimgs.net/motion/story-countdown.html

## Params

| name | type | default | description |
|---|---|---|---|
| `from` | integer | `3` | Count from this number down to 1 (one second each) |
| `goText` | string | `"GO"` | Word shown after the countdown |
| `headline` | string | `"New drop this Friday"` | Two-line headline under the number |
| `cta` | string | `"Set a reminder"` | Pill button text |
| `accent` | string (color) | `"#ff4d6d"` | Rings, GO, pill, progress bar and the top glow |
| `bg` | string (color) | `"#0b0c10"` | Base background |

Default params (base64url for `?p=`): `eyJmcm9tIjozLCJnb1RleHQiOiJHTyIsImhlYWRsaW5lIjoiTmV3IGRyb3AgdGhpcyBGcmlkYXkiLCJjdGEiOiJTZXQgYSByZW1pbmRlciIsImFjY2VudCI6IiNmZjRkNmQiLCJiZyI6IiMwYjBjMTAifQ`

## Prompt

## When to use
Teasers and announcements for vertical social video: product drops, live-stream start, giveaway deadline, event reminder.

## How to adapt
- `from` = 3 gives the classic 3-2-1; the GO word appears at `from` seconds, headline at `from + 0.35`, CTA at `from + 0.7`. With `from: 5` the clip is fully used (6 s total); with `from: 1` there is a long hold — cut at ~3 s.
- Keep `headline` under ~40 characters for two clean lines at 96px.
- Match `accent` to the campaign colour; the top glow is derived from it automatically.
- Add sound: a tick per second and a hit on GO line up with t = 0,1,2,… and t = `from`.

## Do not change
`window.motion`, `#stage` size (1080×1920), `animation-fill-mode: both`.

## Flow

1. **Write copy**
   headline ≤ 40 chars, cta ≤ 20 chars.
2. **Render 9:16**
   `viewport 1080×1920; frames 0…179 at t=i/30 → ffmpeg -framerate 30 -i frame-%04d.png -c:v libx264 -pix_fmt yuv420p story.mp4`
3. **Add audio**
   `ffmpeg -i story.mp4 -i ticks.wav -c:v copy -shortest story-audio.mp4`

## Render

Open frame_url in a headless browser with viewport width×height (deviceScaleFactor 1), wait for document.documentElement.dataset.motionReady === '1', screenshot; repeat for t = i/fps (i = 0…frames-1); then `ffmpeg -framerate <fps> -i frame-%04d.png -c:v libx264 -pix_fmt yuv420p out.mp4`. Or drop ?t to play it live.

## Contract

Self-contained HTML. Declares window.motion = { width, height, fps, duration, params, apply(params) [, seek(t)] }; root element #stage sized width×height; animations are CSS/WAAPI with animation-fill-mode: both so any t can be seeked via document.getAnimations(). The host runtime (injected by /play) merges ?p params, calls apply(), scales #stage to the viewport and, when ?t is given, pauses and seeks deterministically.
