# TASK 57 — Vertical (9:16) tier camera placement — the "vv" feature > Catalog: [`TASKS.md`](../TASKS.md) — status and requirements live here. **Status:** ✅ Both units shipped 2026-10-21 (Unit 1 = the Live scene, Unit 2 = the Chat scene). Only the creator's hands-on check (slice 3) is outstanding. ## Why The vertical tier (1080×1920) is a centred **band crop** of the same 1920×1080 master every 16:9 tier uses: `OutputRect*` = x 656.25, y 0, w 607.5, h 1080. The default webcam sits at x≈1408 — **outside the cropped window entirely**, so in a vertical stream the creator is simply not in the picture. Switching tiers must not cost the creator their camera. ## The creator's locked table (2026-10-17) | mode | shape | size | position | |---|---|---|---| | 16:9 | as today | as today | as today | | **vv · Live** | circle **or** rect, the creator's choice | small tile | one of **six** spots: top/bottom × left/centre/right | | vv · Chat | rect only | normal, or enlarged to one 607×540 area | the same six spots; enlarged fills the top or the bottom area | | Starting / BRB / Ending | unchanged | unchanged | unchanged | Plus: each scene keeps its **own** vertical position, size and shape; switching back to 16:9 restores the desktop layout **exactly**; placement is set by drag with snap (like the socials) **and** by manual entry in the properties. ## Design (Unit 1) - **Geometry only — no render-path change.** The preview and the compositor read the element's own `X`/`Y`/`Width`/`Height` + `ClipShape`, so the tier switch swaps the live geometry: `WebcamSceneConfig.BeginVerticalLayout(...)` parks the 16:9 layout and brings the vertical one in; `EndVerticalLayout()` commits the vertical placement back to its stored slot and restores the parked 16:9 layout. - **Storage.** Seven additive columns on `WebcamSceneConfig` (`VerticalX/Y/Width/Height/ VerticalClipShape/VerticalRectWidth/VerticalRectHeight`), NULL = "this scene has no vertical placement yet". The X/Y/W/H/ClipShape columns stay the **16:9** layout, so a save never loses the desktop placement. - **The band and the six spots** (`Models/VerticalCameraLayout.cs`, pure math): the band splits into two 607×540 areas (top/bottom), each with three columns (left/centre/right). A tile snaps to the spot its **centre** falls in, inset 32 master px from the band's outer edge and never outside the band. Default tile: 270×152 master px (480×270 in the 1080×1920 output), bottom-right spot — the corner the 16:9 default webcam uses. The Live scene gets it automatically the first time the vertical tier is picked; the other scenes keep their 16:9 placement until the creator drags them into the band. - **One clamp, one choke point.** `SceneElement.X/Y/Width/Height` became `virtual` and the webcam constrains every write (drag, resize handle, typed Geometry fields) into the band — outside it the camera is invisible in the vertical stream. - **Manual entry.** The webcam's Layers properties gained a Geometry section (X/Y/W/H) bound to the **live** placement — the one the current tier shows. ## Design (Unit 2 — the Chat scene) - **Rect only, and the lock sits on the model.** `WebcamSceneConfig.VerticalShapeLocked` (set per scene by the VM) **overrides the `ClipShape` property**, so a locked camera cannot become Round by ANY writer — the toggle, the Shape button, the placement swap. The lock is cleared *before* the 16:9 layout comes back, so the desktop shape is restored. - **The circle is not offered.** `MainViewModel.CanToggleClipShape` is false for a Chat camera in the vertical tier → the Shape button in the webcam's properties disappears (not just disabled). - **Two sizes, snapped by the nearer one.** `VerticalCameraLayout.SizeFor(band, requestedWidth)` returns the small tile (270×152) or one whole area (607.5×540) — whichever is nearer the requested width, so the resize handle has two detents instead of any size in between. - **An enlarged camera fills the area its centre is in** — the top one or the bottom one (`VerticalCameraLayout.AreaFor`). - **The Chat camera is auto-tiled** like the Live one when the vertical tier is picked — otherwise the vertical chat stream has no camera at all. ## Slices (one integration test each) 1. ✅ **Unit 1 — the Live scene** (shipped 2026-10-21): the vertical tier brings the Live camera into the band as a small tile; dragging it to the top-right snaps it top-right inside the band; switching back to 16:9 restores the desktop layout exactly; both placements survive a save + reload. `ytLive.Tests/VerticalWebcamLayoutTests.cs` — the ONE test for the unit. 2. ✅ **Unit 2 — the Chat scene** (shipped 2026-10-21): in the vertical tier the Chat camera comes into the band as a small RECT tile; the circle option is not offered and cannot be set even on the model; enlarged it fills one whole 607×540 area — the top one or the bottom one, by where the camera is; switching back to 16:9 restores the desktop layout exactly and the circle option is offered again. `ytLive.Tests/VerticalChatCameraLayoutTests.cs` — the ONE test for the unit. 3. ☐ **Creator check** (needs the creator's hands): switch the dropdown to "Vertical 1080p60", confirm the camera tile lands inside the band and the Shape button toggles circle/rect in the vertical tier (and is gone in the Chat scene), enlarge the Chat camera to see it fill a whole area, then switch back and confirm the desktop layout is untouched. ## Notes - OBS cannot do this (no per-aspect layout storage — the maintainers' answer is a second scene fed as a source); Streamyard documents the same gap. Our per-scene, per-tier stored placement resolved on the tier change is the step past both. - **Research (Unit 2, 2026-10-21).** The "one 607×540 area" rule is the established vertical-stream layout: Streamlabs' vertical guide says "splitting the screen in half horizontally, placing the camera feed in the top half and the main content on the bottom (or vice versa) may be the bet", and that a just-chatting vertical wants the camera "to take up most of the screen" (streamlabs.com/content-hub/post/overlays-vertical-and-horizontal-streaming). Bloopbot's vertical overlay docs describe the same per-layer model we use at scene granularity: "move or resize a layer on Vertical and it stops being Auto-placed. It keeps the place you gave it, and the horizontal layout is not touched" (bloopbot.com/docs/vertical-overlays-twitch-dual-format). - ⚠️ **Landmine for the bottom area:** "about the bottom 560 px of the vertical video can be covered by Twitch's chat and player controls on phones" (Bloopbot, above) — the Chat camera's enlarged **bottom** area may be half-hidden by the platform chrome. TASK 53's safe-zone work decides that. - The vertical tier's output crop is TASK 53's business (safe zones, caption clearance); the camera tile is inside the band, but the band is not yet proven against TikTok/Shorts chrome.