---
title: "How to add a framed video card with Claude (tested prompt and script)"
description: "Half a second in, the full-screen video shrinks to a rounded card floating on a butter-yellow backdrop, with a soft shadow under it. Install one skill and ask Claude Code, or run the Python script we tested yourself."
url: https://www.recharm.com/effects/framed-video-card
---

# How to add a framed video card with Claude

Half a second in, the full-screen video shrinks to a rounded card floating on a butter-yellow backdrop, with a soft shadow under it.

Made by the script on this page, from our own test clip.

## Get this effect

1. ### Switch to Code in your [Claude Desktop App](https://claude.com/download)

2. ### Install the skill (once)

   ```
   Install the Recharm video effects skill: download https://recharm-growth-staging.s3.us-east-2.amazonaws.com/website/downloads/recharm-video-effects.zip and unzip it into ~/.claude/skills
   ```

3. ### Ask for the effect

   ```
   Add a framed video card to input.mp4
   Second the video starts to shrink: 0.5
   Seconds the shrink takes: 0.6
   ```

## Several videos, several effects, one ask

Put your clips in the folder, mention them with @, and ask for everything at once. Claude runs one tested script after another on each clip, then joins them.

Add a framed video card to **@clip1.mp4**, put a sale badge on **@clip2.mp4**, give **@clip3.mp4** a VHS look, then join all three with crossfades.

## Settings you can change

Ask Claude to change any of these, or edit them at the top of the script.

| Setting                    | Default          | What it does                                                                       |
| -------------------------- | ---------------- | ---------------------------------------------------------------------------------- |
| `START`                    | `0.5`            | Second the video starts to shrink.                                                 |
| `SHRINK`                   | `0.6`            | Seconds the shrink takes.                                                          |
| `SIZE`                     | `0.80`           | Card size as a share of the frame.                                                 |
| `RADIUS`                   | `0.06`           | Corner radius as a share of the frame width.                                       |
| `BACKDROP`                 | `(247, 201, 72)` | Backdrop color.                                                                    |
| `SHADOW`                   | `0.45`           | Shadow strength (0-1).                                                             |
| `SHADOW_BLUR, SHADOW_DROP` | `0.035, 0.025`   | Shadow softness and how far it falls below the card, as shares of the frame width. |

## Without the skill

Don’t want to install the skill? Paste this prompt into Claude Code and Claude writes the script itself.

```
Turn input.mp4 into a framed video card. Play it full screen until 0.5 seconds, then over 0.6 seconds (ease-out) shrink it to 80% of the frame's width and height, centered, with its corners rounding to a radius of 6% of the frame width, onto a solid (247, 201, 72) yellow backdrop. Give the card a soft black drop shadow at 45% opacity, blurred by 3.5% of the frame width and shifted down by 2.5% of the frame width. Hold the card to the end. Use Python with Pillow for the mask and shadow (draw anything with Pillow, not ffmpeg's drawtext) and ffmpeg to read and write the video, keep the audio and the original size, and save it as output.mp4.
```

## Run it without Claude

This is the exact script we tested. Save it as `framed-video-card.py` and run:

```
python3 framed-video-card.py input.mp4 output.mp4
```

```
#!/usr/bin/env python3
"""Framed video card: the video shrinks onto a butter-yellow backdrop as a rounded card with a soft shadow.

Usage: python3 framed-video-card.py input.mp4 output.mp4
Needs ffmpeg and Pillow (pip install pillow).
"""
import json
import subprocess
import sys

from PIL import Image, ImageDraw, ImageFilter

START = 0.5                # second the video starts to shrink
SHRINK = 0.6               # seconds the shrink takes
SIZE = 0.80                # card width and height as a share of the frame
RADIUS = 0.06              # corner radius as a share of the frame width
BACKDROP = (247, 201, 72)  # backdrop color (butter yellow)
SHADOW = 0.45              # shadow strength (0-1)
SHADOW_BLUR = 0.035        # shadow softness as a share of the frame width
SHADOW_DROP = 0.025        # how far the shadow falls below the card, as a share of the frame width

def ease_out_cubic(p):
    p = min(max(p, 0), 1)
    return 1 - (1 - p) ** 3

def card_frame(video, t):
    """The frame at time t: the video scaled down and rounded, on the backdrop with its shadow."""
    p = ease_out_cubic((t - START) / SHRINK)
    if p == 0:
        return video
    scale = 1 - (1 - SIZE) * p
    cw, ch = round(w * scale), round(h * scale)
    x, y = (w - cw) // 2, (h - ch) // 2
    radius = round(w * RADIUS * p)
    mask = Image.new("L", (cw, ch))
    ImageDraw.Draw(mask).rounded_rectangle([0, 0, cw - 1, ch - 1], radius, fill=255)

    shadow = Image.new("L", (w, h))
    drop = round(w * SHADOW_DROP * p)
    ImageDraw.Draw(shadow).rounded_rectangle([x, y + drop, x + cw - 1, y + ch - 1 + drop], radius, fill=round(255 * SHADOW * p))
    shadow = shadow.filter(ImageFilter.GaussianBlur(w * SHADOW_BLUR))

    img = Image.new("RGB", (w, h), BACKDROP)
    img.paste((0, 0, 0), (0, 0), shadow)
    img.paste(video.resize((cw, ch), Image.LANCZOS), (x, y), mask)
    return img

def probe(path):
    info = json.loads(subprocess.check_output(["ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries",
                                               "stream=width,height,r_frame_rate", "-of", "json", path]))
    s = info["streams"][0]
    num, den = s["r_frame_rate"].split("/")
    return s["width"], s["height"], s["r_frame_rate"], float(num) / float(den)

src, out = sys.argv[1:3]
w, h, rate, fps = probe(src)
reader = subprocess.Popen(["ffmpeg", "-v", "error", "-i", src, "-f", "rawvideo", "-pix_fmt", "rgb24", "-"],
                          stdout=subprocess.PIPE)
writer = subprocess.Popen(["ffmpeg", "-y", "-v", "error", "-f", "rawvideo", "-pix_fmt", "rgb24", "-s", f"{w}x{h}",
                           "-r", rate, "-i", "-", "-i", src, "-map", "0:v", "-map", "1:a?",
                           "-c:v", "libx264", "-crf", "18", "-pix_fmt", "yuv420p", "-c:a", "copy", "-shortest", out],
                          stdin=subprocess.PIPE)
i = 0
while chunk := reader.stdout.read(w * h * 3):
    writer.stdin.write(card_frame(Image.frombytes("RGB", (w, h), chunk), i / fps).tobytes())
    i += 1
writer.stdin.close()
if reader.wait() or writer.wait():
    sys.exit("ffmpeg failed")
```

## More layouts and reframing

- [Background replacement **Background replacement**](https://www.recharm.com/effects/background-replacement)
- [Binocular view **Binocular view**](https://www.recharm.com/effects/binocular-view)
- [Blur region **Blur region**](https://www.recharm.com/effects/blur-region)
- [Cinematic bars **Cinematic bars**](https://www.recharm.com/effects/cinematic-bars)
- [Comic panel layout **Comic panel layout**](https://www.recharm.com/effects/comic-panel-layout)

## Find 3x _winning ads_

Recharm cuts your ad footage into tagged, searchable clips: hooks, testimonials, product shots. Find the shots that win, add the effect with Claude, and ship 3x more ad edits.

[Start 14-day free trial](https://www.recharm.com/get-started)
