Skip to content
Marketing
Skill

/render-hand-swipe-flavor-listicle

Render a 'hand-swipe flavor listicle' video from a config — the brand's REAL product cutouts each float on a flat flavor-matched color field under a persistent title and slide RIGHT-TO-LEFT one to the next like a phone-feed scroll, while a green-screen hand clip (back of hand

BOOST
From plugin
goose-skills
1.2k200 skills
Install
$ npx -y skills add gooseworks-ai/goose-skills --skill render-hand-swipe-flavor-listicle --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/render-hand-swipe-flavor-listicle

Context preview

The summary Claude sees to decide when to auto-load this skill.

Render a 'hand-swipe flavor listicle' video from a config — the brand's REAL product cutouts each float on a flat flavor-matched color field under a persistent title and slide RIGHT-TO-LEFT one to the next like a phone-feed scroll, while a green-screen hand clip (back of hand

SKILL.md

render-hand-swipe-flavor-listicle.SKILL.md
name: render-hand-swipe-flavor-listicle
description: Render a 'hand-swipe flavor listicle' video from a config — the brand's REAL product cutouts each float on a flat flavor-matched color field under a persistent title and slide RIGHT-TO-LEFT one to the next like a phone-feed scroll, while a green-screen hand clip (back of hand toward camera, index finger up) is trimmed to its clean finger-up window, looped once per flavor, keyed with a green-dominance alpha key, scaled down and anchored at the bottom, with an optional end card and an optional instrumental music bed — deterministic PIL plus FFmpeg assembly, FREE (the hand clip comes from create-video-fal and the bed from create-music-elevenlabs), so labels stay pixel-crisp. Use for the hand-swipe-flavor-listicle format.
status: active

render-hand-swipe-flavor-listicle

Render the **hand-swipe-flavor-listicle** format from a config: a short vertical (1080×1920, 30fps, ~7.5s) "N flavors of <Brand>" listicle. Each flavor is a card — a flat, saturated color field + a persistent title + the brand's REAL product cutout with a soft contact shadow. Cards change by sliding **right-to-left** (a phone-feed scroll), while a real-looking hand sweeps at the bottom of the frame. Music-only, no VO.

This capability is the **FREE, deterministic assembly** ($0, no keys). It never generates or edits the product — the cutouts are composited as-is, so labels stay crisp. It needs four kinds of input, gathered first (see **Getting the inputs**): product cutouts, a title TTF, a green-screen hand clip, and (optionally) a music bed.

Run

S=/tmp/gooseworks-scripts/render-hand-swipe-flavor-listicle/scripts   # after `gooseworks fetch render-hand-swipe-flavor-listicle`
python3 $S/build_hand_swipe_listicle.py config.json                 # writes config "output"
python3 $S/build_hand_swipe_listicle.py config.json --out final.mp4 # override the output
python3 $S/build_hand_swipe_listicle.py config.json --stills cards/ # one PNG per card, no video
python3 $S/build_hand_swipe_listicle.py config.json --work work/    # keep the intermediates in work/

Relative paths in `config.json` resolve against the config file's own folder. Render `--stills` first: it is instant and shows the title, colors and cutouts before the full render.

**Prereqs:** `python3` with Pillow, and `ffmpeg` + `ffprobe` on PATH. Nothing else.

Getting the inputs

| Input | Free route | Paid route (gated: confirm with the user first) | |---|---|---| | Product cutouts | The brand's transparent PNGs (PDP/press kit). | A brand-site photo is usually NOT a cutout. Remove its background with `create-image-fal`, model `fal-ai/birefnet/v2` (see below). | | Title TTF | Download a TTF matching `choices.title_style` (table below). | — | | Hand clip | The bundled clip (one woman's hand): `curl -fL -o hand-swipe-greenscreen.mp4 https://d2m0qbg34x1ii2.cloudfront.net/ads/samples/455dc125-e41c-46dc-9fa6-9ae125e9b6bf/media-hand-swipe-greenscreen.mp4` (also in the recipe's `config.hand.bundled_clip_url`). | A new clip via `create-video-fal` (see **Making the hand clip**). | | Music bed | None (`"music": null`, a silent cut). | `create-music-elevenlabs` (see **Making the music bed**). |

**Cutouts.** The renderer warns when an image has no transparent pixels: it would render as a white box with a rectangular shadow. Fix it before rendering, never by AI-regenerating the product. The cutout route is `create-image-fal` with model `fal-ai/birefnet/v2` (paid, gated), payload `{"image_url": "<public url of the product photo>"}`, the same route `render-vignette` uses. **Known gap:** birefnet returns `image`, not `images[]`, and `create-image-fal`'s `gen_image.py` currently reads only `images[]`, so check that capability's notes before relying on it. If no cutout route works, ask the user for transparent PNGs.

**Title font.** Always pass `title_font`. Without it the renderer falls back to whatever the machine has (Brush Script on macOS, DejaVu Sans Bold on Linux), so the same config renders a different title style on different machines. Free TTFs from Google Fonts, one per `title_style`:

| `choices.title_style` | Download | |---|---| | cursive / script | `curl -fL -o fonts/title.ttf https://github.com/google/fonts/raw/main/ofl/pacifico/Pacifico-Regular.ttf` | | bold condensed sans | `curl -fL -o fonts/title.ttf https://github.com/google/fonts/raw/main/ofl/anton/Anton-Regular.ttf` | | elegant serif | `curl -fL -o fonts/title.ttf https://github.com/google/fonts/raw/main/ofl/dmserifdisplay/DMSerifDisplay-Regular.ttf` | | hand-drawn marker | `curl -fL -o fonts/title.ttf https://github.com/google/fonts/raw/main/apache/permanentmarker/PermanentMarker-Regular.ttf` | | the brand's own display font | The brand's TTF/OTF file if you have it; otherwise the closest row above. |

The title is auto-shrunk (with a warning) until it fits 88% of the frame width, and the underline follows the drawn text, so long brand names never clip on the edges.

Config

`scripts/config.example.json` is the worked example (Lucky Energy "5 Flavors of Lucky"). Copy its structure, never its creative values.

| Field | What it is | |---|---| | `title` | The persistent header line (required). | | `title_font` | A TTF in the style from `choices.title_style` (see **Title font**). Missing → a warned, machine-dependent fallback. | | `title_size`, `title_y`, `title_color`, `title_underline` | Title layout (defaults 118, 200, white, true). `title_size` is a maximum: a too-wide title is shrunk to fit. | | `flavors[]` | `{ "bg": "#hex", "can": "cutout.png" }` per flavor, in play order (required, ≥2). `image` is accepted as an alias for `can`. Cutouts must be transparent PNGs. | | `can_height`, `can_center_y` | Product size + vertical center (defaults 950, 940). | | `slide.frames` | Frames per slide (default 12). `slide.direction` is fixed: always right-to-left (any other value is ignored with a warning). | | `hand_clip` | The green-screen h

Read more
Ships withgoose-skills

Put your AI agent on the growth team. Research customers and competitors, analyze what is working, create the next campaign, and learn from the result.

Get the whole plugin

Other skills on goose-skills.