Frontend for the channel-explore feature:
- ChannelPage: banner/avatar/stats header, Subscribe/unsubscribe, an "exploring" badge
while browsing an un-subscribed channel, Videos/About tabs. Reuses Feed scoped to the
channel (scope=all + source=all so the per-user ephemeral videos show). Auto-ingests
recent uploads on first visit (background, with a loading note) + "Load more from
YouTube" to page deeper; skipped for demo / already-subscribed channels.
- App: openChannel/closeChannel as a Back-aware sub-view (history.state._chan, mirrors the
YT-search _yt pattern); ChannelPage takes over the content column, nav rail stays.
- ChannelLink/cards/player: the channel name now opens our channel page (onChannelFilter →
onOpenChannel); the in-card "only this channel" filter button is dropped (the page
subsumes it). PlayerModal channel-name wiring follows in the next commit.
- api: channelDetail + exploreChannel; ChannelDetail/ExploreResult types.
- i18n EN/HU/DE: channel namespace, explore_cleanup scheduler labels, explore config group,
channels_explore quota label.
Render only the visible rows via @tanstack/react-virtual (useVirtualizer
against the app's <main> scroll container, per-row dynamic measurement),
so the DOM no longer accumulates every loaded card. A ResizeObserver keeps
the responsive grid column count in sync and chunks cards into virtualized
rows; the list view virtualizes single-card rows. Infinite scroll now
triggers from the virtual range and pages via next_cursor instead of
offset; feed/count drops its unused paging args.