# .smoothcapture Project Format (for agents)

A `.smoothcapture` bundle is a **directory** containing media plus JSON. The CLI covers recording, smart zoom, presets, and export; everything else is edited by rewriting `project.json` directly. All JSON is Codable-compatible with ISO-8601 dates; unknown/missing fields fall back to defaults, but keep the existing structure intact.

```
demo.smoothcapture/
|--- project.json        # the full edit/effects document (this file is what you edit)
|--- takes.json          # take index {takes:[{id,name,relativePath,bundleInfo,...}], selectedTakeId}
|--- take-settings.json  # per-take look settings (background, crop, cursor, aspect)
|--- bundleinfo.json     # recording metadata + media manifest (do not edit)
|--- screen.mp4          # captured video
|--- cursor.bin          # cursor positions/clicks (binary v5; some bundles have cursor.json v2)
|--- webcam.mp4 / microphone.m4a / system-audio.m4a / keyboard.json   # optional
`--- recording.log
```

**Golden rule:** never edit `project.json` while the project is open in the SmoothCapture editor (its autosave will clobber you) - or call `smoothcapture cli project reload --path <bundle>` right after your edit.

## project.json - fields worth editing

Only the commonly useful fields are listed; leave the rest untouched.

### Canvas & background
| Field | Type | Meaning |
|---|---|---|
| `backgroundPadding` | float | Video scale within canvas; `0.9` ~ 10% padding, `1.0` = edge-to-edge |
| `backgroundCornerRadius` | float | Rounded corners on the video, ~`0.06` |
| `selectedBackgroundImage` | string | Bundled background name, e.g. `"Apple/20250901_Mac"` |
| `borderEnabled` / `borderWidth` / `borderColor` | bool/float/rgb | Border around the video; `borderStyle`: `solid`/`gradient`/`glow` |

Aspect ratio lives in **take-settings.json** (`previewAspectRatio`): `matchVideo`, `widescreen16x9`, `standard4x3`, `square1x1`, `portrait9x16`, `portrait9x19_5`.

### Zoom effects (`zoomEffects` array)
Prefer `cli project autozoom`; hand-write only when you need a zoom at an exact moment:
```json
{
  "id": "<uuid>",
  "startTime": 3.0, "endTime": 7.5,
  "startZoom": 0.9, "endZoom": 2.0,
  "zoomInDuration": 1.9, "zoomOutDuration": 1.9,
  "cinematicMode": true,
  "manualCenterEnabled": false,
  "name": "Zoom 1"
}
```
- Times are in **timeline seconds**. `startZoom` usually equals `backgroundPadding`; `endZoom` is the peak (2.0 = 2x).
- `cinematicMode: true` makes the camera follow the cursor while zoomed.
- To zoom at a fixed point instead: `"manualCenterEnabled": true, "manualCenterX": 0.5, "manualCenterY": 0.3` (normalized 0-1).
- Do **not** write keyframes - they are regenerated from these scalar fields on load.
- Keep effects non-overlapping and inside the video duration.

### Trims & speed (`videoSegments` array)
```json
{"id":"<uuid>","startTime":0,"endTime":12.4,"speed":1.0,"sourceTakeId":"take-1"}
```
Cut dead time by splitting into multiple segments that skip source ranges; `speed` > 1 fast-forwards a segment. Times are source-video seconds.

### Cursor
`showCursor` (bool), `cursorSize` (in take-settings), `cinematicCursorEnabled` (smoothed motion), `clickRippleEnabled`, `clickSoundEnabled`/`clickSoundVolume`, `cursorFollowEnabled` (camera follows cursor).

### Webcam
`webcamEnabled` (bool), `webcamPosition` (`bottomLeft`, `bottomRight`, `topLeft`, `topRight`, ...), `webcamSize` (float, fraction of canvas), `webcamCornerRadius`, `webcamShape`, plus shadow/border fields prefixed `webcamShadow*`/`webcamBorder*`. Time-varying layouts (fullscreen intro -> corner overlay) live in `cameraLayouts`.

### Keystroke overlay
`keystrokeDisplayEnabled` (bool) with `keystrokePosition`, `keystrokeFont`, etc. Requires the recording to contain keyboard data (Accessibility permission at record time).

### Audio
`recordingAudioVolume`, `systemAudioVolume` (0-1 floats), matching `*Delay` fields in seconds.

### Crop (take-settings.json)
`cropEnabled` plus `cropX/cropY/cropWidth/cropHeight` (normalized 0-1 of the source video).

## Verification tip

After editing, `smoothcapture cli export --path <bundle> --output check.mp4 --preset 1080p30` and inspect a frame (`ffmpeg -ss <t> -i check.mp4 -frames:v 1 frame.png`). The export renders exactly what the editor preview would show.
