Taste Distillation
Measure a set of reference videos into a reusable style pack - colour grade as a 3D LUT, cut rhythm as a shot-length distribution, hero stills, screen-blend overlay plates, and a text spec for a generative model. Use when the user wants to capture the look of reference footage, build a repeatable look, mint assets from references, or reproduce someone's grade and pacing.
affaan-m on GitHub
Curated by PromptsEdge from a public repo · MIT license. All credit goes to the author.
What is this skill?
This standalone skill ships its implementation in scripts/; use
When to use
- "capture the look of these clips" / "distill the vibe" / "make this repeatable"
- User has reference footage and wants a LUT, a grade, or matching pacing
- Building a library of looks partitioned by genre
- Any request where the answer would otherwise be "describe the style in a prompt"
taste-application for the subsequent generated or local-take edit. Keep each
named genre in its own pack. Measurements from Flash Ethereal must not be
silently reused for Fluid Sketch or 3D Cyber Glitch. A measured zero is valid
data; distinguish it from an absent field.
Local dependencies are in scripts/requirements.txt. Separately authorized
provider work also needs scripts/requirements-live.txt, credentials and
explicit TASTE_FORGE_ALLOW_LIVE=1. --dry-run does not read credentials or
submit jobs. Never infer that a workflow was saved from a local endpoint name;
use the actual provider-side workflow or request evidence.
Turn reference videos into a style pack: a folder of measurements and assets that later stages consume deterministically.
The Core Finding
Prompting cannot deliver a grade. Measurement can.
Measured on real footage: three paid generations with escalating colour direction moved midtone a* from +1.9 → +2.8 → +0.3 against a +24.9 target, and contrast never left ~19 against a 34.7 target. Applying a measured pack to the same footage hit chroma MAE 1.88 and contrast 33.7 in one deterministic pass, for free.
So the split is: the model supplies content, motion and lighting structure; the pack supplies the look. Colour words in a generation prompt are worse than useless — they cost money and push the render away from the neutral base the LUT wants. Say so explicitly in the prompt: "Colour: none. Render neutral. Grading is applied afterwards."
What a Pack Contains
stylepacks/<genre>/
grade.json measured colour statistics (see below)
cadence.json every detected shot boundary + the derived distribution
look.cube 33^3 LUT, drag straight into Resolve as a node LUT
spec.json VLM description, grounded in the measurements
grounding.txt the measured facts fed to the VLM
stills/ full-res frames from the longest shots (conditioning images)
plates/ screen-blend overlay elements lifted onto black
props/ minted GLB meshes
pack.json manifest
Running It
python mint.py --genre <name> --refs a.mov b.mov c.mov # offline, no API key
python distill.py --genre <name> # one VLM call
mint.py is pure numeric analysis — no network, no key, deterministic, so a pack
can be regenerated rather than backed up.
The Measurements That Matter
Chroma by luminance zone, not globally
Colour identity usually lives in one luminance band. A global a*/b* offset
mathematically cannot represent split-toning. Measure chroma inside zones
(L* edges [0,15,35,55,75,100]).
A real signature: violet at L*25 (a* +24.9, b* −17.5), near-neutral at both ends. Reporting only the darkest and lightest zones calls that "uniform cast" — always print the whole curve.
Median + MAD, never mean + std
Chroma in real reference sets is strongly right-skewed. On one measured reel the mean midtone chroma was 36.9 against a median of 17.5, so a mean-based LUT pushed colour ~3x harder than the material warranted.
Contrast is std(L*), not white minus black
The white−black range is ~100 on almost any real footage and discriminates nothing.
Background share is a first-class statistic
Record the share of pixels below L*10. No moment of the distribution can see it: a clip can hold the right mean, std and chroma while its blacks have been lifted into grey. This is exactly how a grade once scored MAE 1.88 / contrast 33.7 while the actual frame was a muddy purple mess.
Mask the interface before measuring
Screen-recorded references carry static furniture — letterbox bars, a status bar, a like icon, caption text. All of it lands in the statistics as if it were the look: black bars inflate shadow weight, a red heart skews a* toward magenta. Temporal variance separates them cleanly — the footage moves, the interface does not — so no hand-tuned crop is needed. On real material this keeps ~65% of pixels.
Cadence needs an adaptive threshold
The right content-detector threshold is material-dependent: a high-contrast action reference cuts hard enough for 30, a moody one hides its cuts under it. Sweep descending thresholds and take the highest one that still recovers ≥90% of the shots the most sensitive setting finds — that biases toward real cuts over noise. Reject thresholds implying an absurd cut rate (>100/min); continuous camera moves trip the detector every frame.
Run the whole sweep in one decode pass with a shared StatsManager. The
naive version re-decodes per threshold, which on 60fps source is the difference
between seconds and minutes.
Overlay Plates: Assets, Not Screenshots
A still is a whole frame — compositing one just puts a second picture on top. A plate is the reference's graphic vocabulary (flares, streaks, glitch fragments) lifted onto black so it screen-blends with no keying.
Two traps, both hit on real material:
- Absolute thresholds fail. On a bright reference an
L>55 AND chroma>12selection takes ~90% of frame, and the "plate" is the picture — including a recognisable face. Select by percentile (~top 3%) and reject any plate covering more than ~22% of frame. - Rank by separation, not by brightness. "Share of bright saturated pixels"
ranks a washed-out frame top and a black frame with one intense flare — the
actual signature — near the bottom. Score
p99.5(energy) / median(energy).
Also mask before scoring: burnt-in typography is bright, saturated and high-contrast, so an unmasked run yields a perfect plate of someone else's title card.
Grounding the VLM
Feed the measurements into the system prompt before asking for a description. Ungrounded, a VLM will report "no apparent colour grading, neutral" on footage with a +24.9 a* cast. Grounded, it describes the cast correctly and infers the secondary accent independently.
Ban hedging words (varied, mixed, dynamic, some, often, neutral,
or) — a model cannot render "varied lighting". Enforce the ban in code, not
just in the prompt: it was violated in roughly one run in three. Re-ask
per-field, keep the least-hedged answer after N attempts rather than failing.
Caveat worth stating to the user: once the spec is grounded in the measurements it is no longer an independent check on them.
LUT Baking Gotchas
- A LUT can only encode a per-pixel RGB function. Anything distribution-dependent (histogram matching, percentile anchors) must be reduced to a constant before baking, or it silently measures the uniform LUT grid instead of the footage.
cv2.cvtColor(LAB2RGB)clamps internally, so an out-of-gamut test using it reports 0%. Convert Lab→linear sRGB by hand; a real measurement was 83.3% OOG.- Offset chroma transfer, not affine. Affine divides by the source σ and overshoots — on real footage it flipped b* to +11.6 against a −17.5 target. Offset took MAE from 6.23 to 2.13.
- Gamut compression cost 3.8x runtime for identical MAE. Make it opt-in.
Anti-Patterns
| Don't | Why |
|---|---|
| Tune against synthetic test footage | Cost four separate wrong conclusions on one project; real footage overturned every one |
| Trust MAE alone | 1.88 MAE looked like success on a visibly broken frame |
| Use mean/std for chroma | Right-skewed; pushes ~3x too hard |
| Compare only endpoint zones | Both ends are near-neutral by construction |
| Describe the look and stop | The spec is for content and structure; the pack is for colour |
Handoff
The pack is the interface. Once it exists, use the taste-application skill to
generate and assemble against it, or hand look.cube to a colourist directly.
Bundled Code
scripts/ in this skill is a working implementation, not pseudocode. It has no
project-specific assumptions: point it at any reference videos and it produces a
pack.
pip install -r scripts/requirements.txt
export FAL_KEY=... # only needed for the stages that call fal
Every network call is stubbed under TASTE_FORGE_DRY_RUN=1 or --dry-run, so
the plan, prompts, track layout and manifest can be inspected without spending.
Install this skill
- 1
Get the skill — it’s free
Use the Get this skill panel. Unlocked skills stay in My skills. - 2
Download or clone the files
Download the zip, or clone the repo and copy theskills/taste-distillationfolder. - 3
Put it where your agent looks for skills
For Claude Code, use your personal skills folder (every project) or a project’s own folder:~/.claude/skills/taste-distillation/SKILL.md # all projects .claude/skills/taste-distillation/SKILL.md # this project only
- 4
Just ask
No command needed. The agent reads the skill’s description and loads it on its own when your request matches.
Heads up: this skill ships scripts the agent can run on your machine. Read them before installing.
SKILL.md frontmatter
What your agent reads to decide when to load this skill.
--- name: taste-distillation description: Measure a set of reference videos into a reusable style pack - colour grade as a 3D LUT, cut rhythm as a shot-length distribution, hero stills, screen-blend overlay plates, and a text spec for a generative model. Use when the user wants to capture the look of reference footage, build a repeatable look, mint assets from references, or reproduce someone's grade and pacing. ---
Files
This skill lives in a public GitHub repo. Browse the files on GitHub ↗
Related skills
View all →- Vite PatternsFreeVite build tool patterns including config, plugins, HMR, env variables, proxy setup, SSR, library mode, dependency pre-bundling, and build optimization. Activate when working with vite.config.ts, Vite plugins, or Vite-based projects.
- Video EditingFreeAI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.
- Team Agent OrchestrationFreeRun team-based orchestration for agent squads using work items, ownership, agent Kanban, merge gates, and control pane handoffs. Use when coordinating an agent squad with work items, ownership, Kanban, and merge gates.
- Taste ApplicationFreeGenerate new video against a distilled style pack and cut it into a finished piece - plan takes from the reference's cut rhythm, generate on fal, grade with the pack's measured LUT, cut at the measured cadence, weave in existing footage, composite overlay plates, mint 3D props, and verify the result numerically. Use when the user wants to make a video in a captured style, supplement existing footage, or assemble generated clips into a real edit.