- HlsPlayer: drive onPlaying from the <video> element's own `playing` event on
BOTH the hls.js and Safari-native paths instead of MANIFEST_PARSED, which
fires before any media has decoded (an HttpLiveStreamingDirect manifest
always parses, even over a black video). MANIFEST_PARSED now only kicks
play(). Restore `void video.play().catch(...)` at both call sites and stub
HTMLMediaElement.prototype.play in setupTests.ts instead, so the `?.` that
existed only to survive jsdom is gone from production code.
- HlsPlayer.test.tsx: assert the auto-recovery guard against hls.js's own
startLoad()/recoverMediaError(), not just loadSource's call count.
- ChannelPreviewPanel: reuse existing ctv-* classes (ctv-channels-error,
ctv-settings-warn-callout, ctv-detail-actions, ctv-detail-infogrid) instead
of five undefined ctv-preview-* classes; add the two genuinely new rules
(ctv-preview-video max-width, spacing tweaks) to shell.css.
- Add an exported ChannelPreviewAvailability union (web/src/api/channels.ts)
so a typo like 'ForcedHLSOnly' fails to compile instead of silently
disabling a branch forever; use it in ChannelPreviewPanel's prop type and
at the ChannelsScreen comparison sites.