Skip to content
Back to skills

Frame Crop Guard

ASecurity

Catches bad crops before a render. A tall narrow tile showing a landscape frame keeps the jukebox and loses the face. A character sheet gets cut in half. A close-up is cropped through the eyes. A vertical version keeps the wrong side of the frame. The skill lays out the real compositions in headless Chrome to read the exact box, object-fit and object-position of every image and video, including the vertical layout. It finds faces and people in each source with Apple Vision and computes what i...

  • 4 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 10, 2026
ai-agentspythonrustswiftnode

Works with

  • cli

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned November 10, 2026

npx -y skills add teen-boop/AiProductionPipeline --skill frame-crop-guard --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Frame Crop Guard?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Frame Crop Guard
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/teen-boop-frame-crop-guard/badge)](https://www.skillsdirectory.com/skills/teen-boop-frame-crop-guard)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: frame-crop-guard
description: >-
  Catches bad crops before a render. A tall narrow tile showing a landscape frame keeps the jukebox and loses the
  face. A character sheet gets cut in half. A close-up is cropped through the eyes. A vertical version keeps the
  wrong side of the frame. The skill lays out the real compositions in headless Chrome to read the exact box,
  object-fit and object-position of every image and video, including the vertical layout. It finds faces and
  people in each source with Apple Vision and computes what is really visible after the push-in. Each crop is
  flagged LOST_SUBJECT, FACE_OUT, FACE_CUT, FACE_AT_EDGE, BODY_CUT, HEAVY_CROP or DISTORTED, with the
  object-position that fixes it or the advice to change the box. Writes a report and a sheet that shows each crop
  window on its source. Use before rendering any HyperFrames, Remotion or HTML video, slide or poster that places
  photos or clips in tiles, when the user says frames are badly cropped, "the crop cuts the face", "check the crops",
  or after changing a layout or swapping assets. Includes scripts/crop_boxes.mjs, crop_check.py and subjects.swift.
user-invocable: true
---

# Frame Crop Guard

A crop is a decision about who the shot is about. `object-fit: cover` in a box with a different shape from the source makes that decision silently, from the centre. In a real promo it kept a jukebox instead of two faces, showed a man from behind, and cut a character sheet in half. Nobody saw it until the render. This skill checks every crop against the people in the source before anything is rendered.

## 1. Read the real layout

```
node scripts/crop_boxes.mjs --width 1920 --height 1080 --out qc/boxes_16x9.json promo-16x9/compositions/*.html
node scripts/crop_boxes.mjs --width 1080 --height 1920 --out qc/boxes_9x16.json promo-9x16/compositions/*.html
```

- Each composition (`<template>` sub-compositions or plain pages) is laid out in headless Chrome at the target size. Scripts are not run, so this is the resting CSS layout, which is where crops are decided.
- **Vertical layouts:** a class that a runtime adds must be named. The default for a vertical size is `#root=is-portrait`, the HyperFrames promo convention. Without it the check measures the landscape CSS. Pass `--portrait-class "<selector>=<class>"` for other engines, or `""` to switch it off.
- For every `<img>` and `<video>` the script writes the box, object-fit, object-position, natural size, the clipping parent and `data-media-start`.

## 2. Check every crop

```
python3 scripts/crop_check.py qc/boxes_16x9.json --out qc/crops_16x9 --push 1.08
```

- **Faces and people.** Apple Vision finds faces and whole people in each source; for a video it uses the frame at media start + 0.5 s. The detector is compiled once from `subjects.swift` into `~/.cache/frame-crop-guard`. It needs macOS and the Xcode command line tools.
- **Visible window.** The part of the source that is visible comes from cover, contain or fill, object-position and the clipping parent. It is then shrunk by `--push`, the largest push-in the composition applies to media.

| Flag | Level | Meaning |
|---|---|---|
| LOST_SUBJECT | high | the source has faces, none is kept at 90% or more |
| FACE_OUT | high (largest face) | a face is outside the crop |
| FACE_CUT | high | a face is cut by the edge (15 to 90% visible) |
| DISTORTED | high | `object-fit: fill` stretches the image |
| FACE_AT_EDGE | medium | a whole face sits within 3% of the edge |
| BODY_CUT | medium | a person whose face is kept loses over 40% of the body (sheets, full-length shots) |
| HEAVY_CROP | medium | under 35% of a faceless source is visible (boards, text, wide plates) |

For each flagged item the report gives a fix. Either it is the `object-position` that centres the faces (or the people), or it says the subject is larger than the window: use contain, a wider box, or another source frame. The exit code is 1 while any high flag remains.

## 3. Look, then fix

Open `sheet.jpg`. It shows each source with the visible window in yellow, kept faces in green and lost or cut faces in red. The detector misses faces in profile, in silhouette and at very small sizes. It also sees faces you do not care about, such as a crew member at the edge of a set photo. The sheet is where you decide.

Fixes, best first:
1. **Match the box to the source.** Give tiles the source's aspect ratio (`aspect-ratio: 16 / 9`, a grid with `auto` columns and `justify-content: center`) instead of stretching a row of narrow strips. Fewer, larger tiles beat many slivers.
2. **Show fewer items in the vertical layout** (`:nth-child(n+4) { display: none }`) rather than squeezing every tile.
3. **Use the suggested `object-position`** for the layout where it applies (for example `&P #id img { object-position: 50% 14%; }`).
4. **`object-fit: contain`** on a matching background for screenshots, app pages and posters: their edges carry the content.
5. **Another source frame** when the subject is larger than any window the layout can give.

Re-run steps 1 and 2 until no high flags remain, for every aspect ratio. Then render, and check the encoded file with `render-cut-verification`.

## Never

- Never place a landscape frame in a tall tile, or the reverse, without running this check.
- Never trust a centre crop on character sheets, turnarounds, group shots or app screenshots.
- Never check only the landscape layout: vertical versions crop differently and fail more often.
- Never call a layout clean from the report alone; look at the sheet.

Files in this skill

  • SKILL.md5.4 KB
  • scripts/crop_boxes.mjs6.5 KB
  • scripts/crop_check.py11.8 KB
  • scripts/subjects.swift977 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in ai-agents →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.