autoCutPlan()/autoCut(): given a beat grid and 2+ cameras, place camera cuts
on grid downbeats at a chosen bar cadence, cycling cameras so the same angle
never lands twice running, with a phase offset so a from-the-playhead run
doesn't open on the camera already live. Cut times come straight out of
gridTimes('bar') so a placed t IS a downbeat rather than a rounded neighbour.
Applied inside group() = one undo; refusals throw rather than half-apply.
UI: a scissors popover with cadence, range, per-camera checkboxes and a live
count that is literally the plan (previewed count == applied count).
FILM panel gains 'align to beat': snaps every shot's in/out to the nearest
downbeat, never reorders, clamps inside the scene, returns collapsing shots
untouched with a skipped list, and always names which grid it used.
Verified on scenes/music-video: 4 cuts at exact downbeats 3.749s apart
(2 bars at 128.02 BPM), cam2->cam3->cam4->cam1, one undo restores exactly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Beat grid consumed from Lane C's /beats: one top-level scene.beatGrid (beats
kept in FILE seconds, effective offset re-derived from the audio clip so
dragging the audio drags the grid and head-trim leaves it put). beat and bar
join the snap selector, so keys, clip and audio blocks, both trim edges, cuts
and the playhead all became musical for free. Grid drawn faint on beats and
brighter on downbeats, suppressed below ~7px spacing. Low confidence still
snaps but says so. Tempo extrapolates past the analysed range.
FILM panel mounts inside #timeline: sequence CRUD, editable shot rows (scene
dropdown, in/out, cut|dissolve + seconds, reorder, delete), live runtime, size
picker, and Render film with per-shot/per-frame progress - gated behind
hasContent() + a confirm that says plainly every shot replaces the open scene,
and locked while running so it cannot be started twice. film.js imported
lazily so its absence cannot stop the timeline mounting.
Verified live: grid 128.02 BPM/35 beats off house128.wav, snapped positions
8-10ms from the true 0.468735s grid across the whole file, bar snap hits a
downbeat, grid survives toJSON->load; FILM lists both sequences with the
server's 11.50s runtime and 3 editable rows.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Lane B: New... in the scene bar fetches the templates API and applies through
a new single apply path (applyScene = stage.applyState + load + preload, now
shared with Load), confirm-before-clobber via hasContent(), thumbs, toasts on
failure. ? overlay documents 24 real bindings read out of the code across
STAGE/TIMELINE/SCENE BAR, ignores ? while typing. Audio head-trim (left edge
eats into the source, one grouped undo). applyScene strips the template key so
saved scenes stay plain scene JSON.
Orchestrator SYNC-9 fix: help overlay dt column was auto-width + nowrap, so
long terms overflowed and the three columns overlapped visually.
Verified live: picker lists 3 (2 thumbs), no confirm when empty / confirms when
dirty, loads 7 entities + 2 cuts with bar refresh, no template key in toJSON,
overlay opens on ? and Escape closes, no hijack while typing. 5 suites green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>