The interior display refuses programmatic rotation
(UISceneErrorDomain 101: "The current windowing mode does not allow for
programmatic changes to interface orientation"), so the rotate/fullscreen
button did nothing there and the failure was swallowed.
- OrientationManager tracks `canRotateProgrammatically` (from the hinge
state, cleared when a geometry request is refused) and is @Observable.
- The fullscreen button takes the iPad path when rotation is unavailable:
details toggle in portrait, floating panel toggle in landscape, icon
follows the panel state; orientation lock is hidden. The refused request
itself falls back to the details toggle. Accelerometer-driven rotation
requests are gated the same way.
- Corner layout gate is size-only on iOS (≥900×600 including safe areas,
so the status bar toggling with the layout can't oscillate it); the
layout-mode setting is exposed on foldables via a hinge presence check.
- Corner layout on iPhone always hides the status bar (the interior's
landscape bar is a ~57pt column) and pads by the live top inset only,
instead of the transient 82pt inset seen while unfolding.
- The player hosting controller nudges its safe area after size
transitions so fold/unfold doesn't leave SwiftUI with stale insets.
Observe the foldable hinge with `onHingeChange` (iOS 27.1): while it is
partially open and the portrait panel is hidden, the video is fitted to
the upper half of the screen and every control (title bar, center
controls, side sliders, bottom bar) moves to the lower half. Pinch to
fill is disabled in that state. `YATTEE_FORCE_TABLETOP=1` in the launch
environment forces the layout on simulators without a hinge control.
The exterior display has a vertical status bar with a trailing safe
area inset, which squeezed the fullscreen portrait player into the
content width. The video and controls layers now span the full window
width (shifted under the leading inset, like the existing vertical
handling) and the controls pad their edges by the sheet's actual
asymmetric horizontal insets instead of the symmetric max.
Requires the iOS 27.1 SDK (Xcode 27.1).