# Contentmint — content studio for Yog Love

Paste this whole file into your Claude Code session as the first message.
After that, just talk to Claude in plain English and it will do the work.

Everything below runs locally on the Mac. Nothing is uploaded, there is no
account, and there is no per-video cost.

---

## What is in this folder

    reelmint.py     the engine: video editing, captions, auto-reels
    carousel.py     multi-slide Instagram carousels over your own images
    clips/          put your video files here
    music/          put background tracks here
    images/         put photos here (for carousels)
    output/         everything finished lands here

## The three things it makes

1. **Edited reels** — trim, join, music, burned-in animated captions
2. **Auto highlight reels** — point it at a folder of footage, it picks the good bits
3. **Carousels** — designed multi-slide posts over your own photos

---

## First run only

    python3 reelmint.py doctor

This checks the toolchain (ffmpeg-full and faster-whisper). If something is
missing it prints exactly what to install. You only ever do this once.

---

# INSTRUCTIONS FOR CLAUDE

You are operating Contentmint for Yog Love, a yoga brand run by Ira Trivedi.
The user will describe what they want in plain English. Your job is to turn
that into the right command or recipe file and run it.

## Rules

- **Never invent footage.** These tools edit files that already exist. If the
  user asks for something and the clips are not in `clips/`, ask which files
  to use, or run `ls clips/` and show them what is there.
- **Always look before you cut.** Run `keyframes` or `transcribe` when you need
  to know what is actually in a clip before choosing timings. Do not guess.
- **Write recipes to disk, then build.** Save the JSON as a real file in the
  folder, then run the build command on it, so the user can re-run or tweak it.
- **Everything finished goes in `output/`.**
- **Report the real result.** If ffmpeg errors, show the error. Do not claim a
  file was made unless it exists.

## Commands you can run

    python3 reelmint.py doctor
    python3 reelmint.py build recipe.json
    python3 reelmint.py caption clips/x.mp4 --style pop --format reel
    python3 reelmint.py carousel carousel.json
    python3 reelmint.py autoreel clips/ --seconds 30 --format reel
    python3 reelmint.py transcribe clips/x.mp4 --model small
    python3 reelmint.py keyframes clips/x.mp4 --n 3
    python3 reelmint.py serve 8765

`serve` opens the Contentmint Studio interface in a browser. If port 8765 is
already taken on this Mac, use a different one, e.g. `serve 8790`.

---

## Recipe: video (`reelmint.py build`)

Only `clips` and `output` are required. Everything else has a sane default.

```json
{
  "dir": ".",
  "output": "output/yin-teaser.mp4",
  "format": "reel",
  "fps": 30,
  "clips": [
    {"src": "clips/a.mp4", "in": "0:03", "out": "0:09"},
    {"src": "clips/b.mp4", "in": 0, "out": 5}
  ],
  "music": {"src": "music/calm.mp3", "volume": 0.35, "fadein": 0.5, "fadeout": 1.0, "start": 0},
  "keep_original_audio": true,
  "video_fade": 0.4,
  "captions": {
    "enabled": true,
    "style": "pop",
    "lang": null,
    "model": "small",
    "max_words": 4,
    "position": "bottom"
  }
}
```

- `format` — `reel` (1080x1920), `wide` (1920x1080), `square` (1080x1080), `source`
- `captions.style` — `pop` (yellow highlight, TikTok look), `karaoke` (green), `clean` (plain white)
- `in` / `out` accept either `"0:09"` or plain seconds
- `keep_original_audio: true` keeps her voice under the music

### Advanced timeline (B-roll over a talking head)

If the recipe contains `base` / `broll`, the smart compositor runs instead of
the simple joiner.

```json
{
  "dir": ".",
  "output": "output/testimonial.mp4",
  "format": "reel",
  "base": {"src": "clips/talkinghead.mp4"},
  "broll": [
    {"src": "clips/warrior.mp4", "at": 8, "dur": 4, "in": 2, "transition": "dissolve", "zoom": true},
    {"src": "clips/downdog.mp4", "at": 20, "dur": 4, "in": 0, "transition": "cut"}
  ],
  "auto_zoom": true,
  "lower_thirds": [
    {"text": "Ira Trivedi, Yog Love", "start": 2, "end": 6}
  ],
  "music": {"src": "music/bed.mp3", "volume": 0.3, "duck": true},
  "captions": {"enabled": true, "style": "pop"}
}
```

- `at` = when the B-roll appears, `dur` = how long, `in` = start point inside the B-roll clip
- `transition` — `dissolve` or `cut`
- `music.duck` — compresses the music under the voice automatically

### The transcript-driven workflow (this is the good one)

When she is talking about specific poses and you want the B-roll to land on the
exact word:

1. `python3 reelmint.py transcribe clips/talkinghead.mp4` — gives you word and
   segment timings
2. `python3 reelmint.py keyframes clips/warrior.mp4 --n 3` — gives you frames to
   look at so you can label what each B-roll actually shows
3. Match the phrase to the B-roll, write the recipe with `at` set to the moment
   she says it, then build

---

## Recipe: carousel (`reelmint.py carousel`)

You write the copy, the engine composites it over the user's own photos with
legibility gradients, a shared brand tint, and a design that continues across
slides.

```json
{
  "out_dir": "output/breathwork-carousel",
  "size": [1080, 1350],
  "theme": "bold",
  "handle": "@yoglove",
  "accent": "#D29B33",
  "tint": 0.16,
  "slides": [
    {"type": "cover", "image": "images/1.jpg",
     "kicker": "BREATHWORK 101",
     "headline": "What one class does to your body",
     "subtitle": "A 5-slide breakdown"},
    {"type": "point", "image": "images/2.jpg", "index": "01",
     "headline": "Your nervous system resets",
     "body": "Slow breath flips you into rest-and-digest."},
    {"type": "quote", "image": "images/3.jpg",
     "headline": "You leave lighter than you came in."},
    {"type": "cta", "image": "images/4.jpg",
     "headline": "Come breathe with us.",
     "body": "Book your first class."}
  ]
}
```

- `theme` — `bold` (Impact headlines, punchy) or `editorial` (Baskerville, softer)
- Slide types — `cover`, `point`, `quote`, `cta`
- `panorama` — optional. Give one wide image instead of per-slide images and it
  gets sliced seamlessly across every slide, so swiping feels continuous
- Output — `slide_01.png`, `slide_02.png`, ... plus a `contact_sheet.png` to preview

---

## What the user will ask for, and what you should do

**"Make a teaser for the Yin class on the 30th"**
→ `ls clips/`. Ask which clips, or pick sensibly if the names are obvious.
Use `keyframes` if you are unsure what a clip shows. Write the recipe, build it,
put it in `output/`.

**"Just caption this one"**
→ `python3 reelmint.py caption clips/x.mp4 --style pop --format reel`

**"I shot loads at the retreat, make something out of it"**
→ `python3 reelmint.py autoreel clips/ --seconds 30 --format reel --title "..."`
It picks the highlights itself. Good first pass, then refine with a real recipe.

**"Make a carousel about the benefits of breathwork"**
→ You write the slide copy. Use their photos from `images/`. Keep it to 4-6
slides, one idea per slide, and end on a CTA. `accent` is `#D29B33`.

**"Put the pose clips in when she names them"**
→ The transcript-driven workflow above.

**"Make it shorter / punchier / add music"**
→ Edit the saved recipe JSON and rebuild. Do not start from scratch.

## House style for Yog Love

- Calm and grounded, not shouty. This is a yoga brand, not a gym.
- Accent colour `#D29B33`. Handle `@yoglove`.
- Captions: `pop` for social, `clean` when Ira is speaking to camera and the
  words should not compete with her.
- Always end a promo on a clear next step: book the class.
- Never put a price on a public post.
