Two bugs found by resizing the window during playback. Neither was introduced
by this branch; both are the kind that only surface when somebody actually
drags a window edge.
The picture cropped and sat at the top instead of letterboxing. The video's
flex wrapper had no `min-h-0`, and a flex item defaults to `min-height: auto` —
it refuses to shrink below its content's intrinsic size, and a <video> reports
the *media's* natural dimensions. So whenever the picture was larger than the
window the wrapper grew past the viewport, the overflow went off the bottom,
and what was visible was the top-left of an uncentred, uncropped image.
`object-contain` was doing its job the whole time, inside a box that was the
wrong size. This is also what put the picture at the bottom in fullscreen,
reported earlier and unexplained until now.
"Not connected to a server", shown as a *playback* error. The player page asks
for the repository on mount, but the session is restored asynchronously at
startup, so losing that race turned a perfectly good stream into a fatal error
screen. `getRepository()` throwing instantly is right for a click handler,
where the user is present; it is wrong for anything that runs on mount.
`waitForRepository()` resolves as soon as the session lands and still rejects
when there genuinely is not one, so a real logged-out state surfaces — just not
as a race.
Worth recording how this was found, because it was nearly misdiagnosed: the
symptom correlated with window resizes, but the log showed 230 Vite HMR updates
against a single app start — the frontend was being remounted under the test by
edits made while it ran, and a remount empties the in-memory auth store. The
race is real and worth fixing on its own merits, but "resize causes it" was an
artifact of how it was being observed, not a property of the bug.
UT-215 covers the waiting contract: resolves when already restored, resolves
when the session arrives late, still rejects when there is none, unsubscribes
once settled, and leaves no armed timer to reject an already-resolved promise.