Make the ScofTV screen a screen
One permanent rectangle that holds one thing at a time, and knows nothing about what.
The room had no screen. It had a list, and picking a row made that row become a video — the frame appeared where the button had been, the page reflowed, and the television only existed while something played.
Now the rectangle is the fixture. Idle it holds the guide; pick something and it holds that instead.
The split, which is the point
src/app/screen.tsx owns the rectangle and its furniture — title above, the
Stop control, the arrows that flank it, the status line beneath — and knows
nothing about what is in it. It has no state and it never retains a hidden
occupant. Anything medium-specific lives in whatever is planted.
scoftv/youtube-stage.tsx is the only file in the repository that knows what
YouTube is.
So an arcade can plant a canvas in the same screen, and a podcast room a waveform, without any of them touching each other.
What the privacy page made us do
Three sentences there are claims about this code, and each one decided something:
- "the page is a list of names and no request has left for Google" — so the guide is type only. YouTube's own thumbnails would be a request to Google before anything is picked, which is why there is no artwork on the tiles and why any future poster has to be a local file.
- "Pressing Stop removes the frame" — so the control keeps the visible word
Stop. A bare ✕ would have made that sentence false. The screen takes a
closeLabelthat defaults to "Stop" for exactly this reason. - "picking another show removes the one before it" — so the stage is keyed by
video id. Without the key React reuses the element and swaps its
src, which is a navigation rather than a removal.
Checked against the built page: the only YouTube string on it is the footer's
link to the channel, which is an <a href> and makes no request. No preload,
no script, no frame, no image.
Why the guide sits inside the screen rather than over it
An overlay above a playing show means a frame mounted underneath something opaque — invisible, possibly still audible. With one slot that state cannot be represented at all. It also deletes the modal machinery: no dialog role, no focus trap, no scroll lock, and Escape keeps a single meaning.
The cost, stated plainly: you cannot browse the guide while something plays. The arrows exist so you can move between shows without going back to it.
Not in this
Custom play, pause and scrub. Those need enablejsapi and a script from
www.youtube.com — a second Google origin the privacy page does not mention.
The seam is youtube-stage.tsx alone, so it stays one file plus a privacy edit
with updated moved, whenever somebody decides to pay that.
WALL_UPDATED deliberately did not move. Its comment defines it as the day
a show was added, removed or reordered. None were. Moving it would have put a
lastmod in the sitemap asserting the rack changed on a day it did not.
Still open
The idle screen is a rule and nothing else. The intention is a rotating library of images behind the guide — local files, never a Google host, or the first sentence above stops being true.