Skip to content

Put the setup walkthrough on the site, and stop apologising for the relay - #59

Merged
karngyan merged 3 commits into
mainfrom
video-walkthrough
Aug 11, 2026
Merged

Put the setup walkthrough on the site, and stop apologising for the relay#59
karngyan merged 3 commits into
mainfrom
video-walkthrough

Conversation

@karngyan

@karngyan karngyan commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Puts the 8:51 setup walkthrough on the site, and retires the status copy that said the relay might not work.

The video

Mux, public playback, no signed tokens. Rendered with kino, the player this project's author wrote, through @karnstack/kino/mux. Accent is passed as var(--primary) rather than a literal colour: kino assigns the prop straight to --kino-accent on its own root, so the header's theme toggle moves the scrubber along with everything else.

An English subtitle track is attached to the asset itself, so captions come from Mux and cost this repo nothing.

Where it goes

Inside the existing Install section on the landing page, between the claim and the install command, and at the top of /docs/setup ahead of any instruction.

No fifth section on the landing page. The four were a considered cut down from seven, and Install is where the live objection sits: at the moment somebody is about to pipe a script into their shell, the question is whether this actually works. Every other window on that page is a drawing. This is the one artefact that is not.

What it costs

/docs/setup and / load 327 kB gzipped, up from about 101 kB. kino and the Mux streaming engine are 212 kB of that.

That is a real tripling and it is deliberate. An earlier version of this branch deferred the engine behind a poster and a play button, which cost 2 kB up front instead of 212 kB. It was removed because it made opening the video take two clicks: the first swapped the picture for the real player, the second started it, and the first bought the viewer nothing. If a video is worth putting on a page it is worth loading. If the landing page number becomes a problem, the answer is to keep the player on /docs/setup and drop it from /, not to bring the facade back.

No autoPlay, and why that matters

Passing kino's autoPlay played two audio tracks a beat apart, and the first one could not be stopped by anything on the page.

kino builds its <mux-video> inside a mount effect and sets autoplay on the element there, while its teardown calls remove(), which detaches an element without pausing it. React invokes a mount effect twice in development, so the sequence is: element created and started, element detached but still playing, second element created and attached. Patching document.createElement to count and clicking play once gave {"created": 2, "attached": 1}. The orphan was unreachable because every control talks to the provider that owned it, which had been thrown away.

Not passing autoPlay means nothing ever starts the orphan. The leak itself is kino's and is being fixed there separately. The viewer presses play, which is what they came to do.

Status copy

README.md and the Remote section of the landing page both claimed the relay had not been through its manual end-to-end gate and should be treated as ready to try rather than ready to rely on. That is no longer true, and the video on the same page disproves it: a relay deployed to a real Cloudflare account with a real token, a phone paired across a different network, and a second machine joined to the same relay.

Both now say it is released, name v0.5.1, and state that it is 0.x so commands and config can still change between versions. That last part is a plain fact rather than an apology.

Two other matches for the old wording were left alone on purpose:

  • docs/RELAY.md release gate section is the standing checklist itself, which is a process and still true.
  • The plan file under docs/superpowers/plans/ is a historical record.

Verification

  • pnpm run lint (tsc --noEmit) clean.
  • pnpm run build green: 6 routes prerendered, check-pages and check-prose pass.
  • The custom element registers on import and every route here is prerendered to static HTML at build time. All six still prerender, so the static import is safe.
  • Playback, both themes, both pages, confirmed in a browser.

🤖 Generated with Claude Code

karngyan and others added 3 commits August 12, 2026 01:56
…elay

The page argued with drawings. Every window on it is one: the fleet, the
switcher, the relay transcript. Drawings argue well and prove nothing, and
the question live at the moment somebody is about to pipe a script into a
shell is not "how does it work", it is "does this actually work". So the
recording goes in the Install section, between the claim and the command,
and on /docs/setup it goes first, ahead of a single instruction, because
somebody who opened that page wants to know what they are in for before
they start.

It opens on a click, not on arrival. Two reasons, both load bearing. The
routes here are prerendered to static HTML, and the Mux engine registers a
custom element that has nothing to render on a server, so gating it on a
click puts it out of that reach by construction: no mounted flag, no
ClientOnly, the state starts false on both sides and the first render
matches. And the engine is 217 kB gzipped against a page whose whole
bundle is 101 kB, on a video nine minutes long that nobody arrived to
watch. What is served instead is a real button around a real frame, which
is also what a reader with no JavaScript keeps. Eager cost is 2.2 kB
gzipped; the engine is fetched when a mouse reaches the card.

The player is @karnstack/kino. Its accent is handed over as
var(--primary) rather than as a colour, since kino assigns the prop
straight to --kino-accent, so the value resolves inside whichever theme
the page is wearing and the header's toggle moves the scrubber with
everything else. The closed card is drawn to kino's own measurements, the
same 76px control and the same easing, so opening the video swaps a
control for its twin in the same place.

The Status copy was also a version behind. It said the relay had not been
through its manual end-to-end gate, which the recording it now sits next
to is: a real Cloudflare account, a phone paired from another network, a
second machine joined. v0.5.1 is released and installable. What stays is
that it is 0.x, said as a fact rather than as an apology.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The closed card had grown a copy of kino's play button, drawn from
measurements quoted out of kino's stylesheet: max(76px,9cqw) across, a
max(32px,3.8cqw) triangle in it, kino's easing curve, and a container
query on the panel so the cqw halves resolved against the same width.
The point was that opening the video swapped a control for its twin in
the same spot.

It is not worth what it costs. Those lengths belong to a package this
file does not own, so the twin drifts apart the first time either side
moves, and nothing fails when it does. The card also stacked its own
blur-up under the poster, which is the job kino's placeholder prop
already does once the player mounts.

What stays is the part that earns its keep: the engine is 218 kB
gzipped against a site whose whole bundle is 101 kB, so it is still
fetched on a click rather than on arrival, which also keeps the custom
element out of a build that prerenders every route. A poster and a
plain play button stand in until then. 142 lines to 84.
Opening the walkthrough took two clicks. The first swapped a poster and
a hand-drawn play button for kino, the second started it, and the first
one bought nothing a viewer wanted. It was there to defer the streaming
engine, and it paid for that with the one interaction the section exists
for.

So the player is imported and rendered like any other component, and the
facade is gone. /docs/setup and / carry 327 kB gzipped where they carried
101 kB, and that is the honest price of putting a video on a page: if it
is worth being there it is worth loading. The prerender does not mind.
The custom element registers on import, every route here is rendered to
static HTML at build time, and all six still prerender.

Also drops autoPlay, which caused two audio tracks to play a beat apart.
kino builds its <mux-video> in a mount effect and sets autoplay on the
element there, while its teardown calls remove(), which detaches an
element without pausing it. React runs a mount effect twice in
development, so the first element was left detached, playing, and
unreachable, with no control on the page able to stop it because the
provider that owned it was gone. Measured two created against one
attached. The leak is still kino's to fix; nothing here starts it now.
The viewer presses play, which is what they came to do.
@karngyan
karngyan merged commit f5e9773 into main Aug 11, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant