UI widgets

Video modal

A watch-video dialog with real player chrome: a clearing overlay, glass control pills, a loading ring, a seek bar that reads the clock honestly. Point it at your own <video src> and it plays that; give it nothing and it falls back to a drawn clip so the page never shows a broken frame.

The dialog is the product. role="dialog" and aria-modal, focus moved in on open and handed back to the trigger on close, everything behind it inert, Esc to close, and a scroll lock that compensates for the scrollbar so the page underneath does not jump. Press H to hide the control panel.

01

Three presets, one engine

Each card owns its own instance, bound to its own trigger — so focus returns to the button you actually pressed. The control panel drives whichever preset is selected.

02

Which media path is running

There is no clip file in this folder and nothing to fetch, so the demo bakes one in the browser: an animated canvas is captured with captureStream and encoded by MediaRecorder into a blob the <video> element can actually play. Where that pair is missing or refuses, the engine runs its canvas path instead and says so. In your build you pass a real src and the video path is the only one you ever see.

starting…
03

Dialog audit

Measured on the page, not asserted in a README. Open a dialog and this block records where focus was, where it went, where it came back to, whether the background scroll locked, and how many pixels the page behind shifted while it did.

What the engine wires up
  • Focus lands on the close control — initialFocus moves it to play or the dialog.
  • Tab and Shift+Tab cycle inside the dialog and nowhere else.
  • Every body child except the dialog gets inert and aria-hidden.
  • Scroll locks on <html>; the scrollbar width is added back as padding.
  • Fixed furniture marked data-scroll-lock-pad is padded too — the panel is.
  • Space or K play-pause, arrows seek 5s, M mute, F full screen.
  • Reduced motion: no fade, no scale — the dialog is simply there, then not.