The thing you are keeping an eye on should get out of the way — by itself.
Picture-in-picture solved one problem and created another. You pinned the call, the build log, the dashboard, the video — and now it sits exactly where the button is. So you drag it. Then it is over the thing you need to read. So you drag it again. Then the page scrolls, the layout changes, and it is in front of the next button.
This project is about that second problem: a floating window that knows it is in the way, and moves itself, dissolves, or disappears for you — and comes back when you want it, without you hunting for it.
These are the cases the design is built around. If a feature does not serve one of them, it is not in scope.
| Case | What happens today |
|---|---|
A. On and off, and settings |
The control is buried in a menu, or it is a browser button you have to find before you can make it stop. Turning it on or off has to be one action, available from the toolbar, a keystroke, or the window itself. |
B. It covers the thing you need |
You are typing into a field, or copying text, and the floating window is over it. You move the window, then lose where the field was. Or the window is semi-transparent over text you cannot read anyway. |
C. It chases you down the page |
The GitHub review flow, in full: pin something, scroll to approve, move it off the approve button, get to the review comment box and it is over the text, move it and the CI status is hidden, move it and it is back over commit. Every move is a decision you did not want to make. |
Case C is the one nobody else solves — every picture-in-picture implementation makes you the collision-avoidance system. That is the whole product.
Behaviour is described in full in the interaction model; the short version:
| Behaviour | What you get |
|---|---|
Nudge |
When the pointer, the caret or the focused field approaches, the window slides clear of it — toward the nearest free edge, not to a fixed corner. |
Chip |
Hover it and it shrinks to a small tab for a settable moment, then restores on its own, or on click. Useful when you need the space for a second. |
Fling |
Throw it to another part of the screen (or another monitor). It settles, stays out of the way, and comes back when clicked or when a timer expires. |
Banish |
Throw it off-screen entirely for a set period. A thin sliver remains at the edge so it can be brought back before the timer. |
Ghost |
Ultra-transparent, either always or only while the pointer is near, so you can read what is underneath. Down to invisible, with the audio still running. |
Click-through |
While ghosted, clicks pass through to the page underneath. Hold a modifier (or tap a key) to grab the window itself again. This is what makes "read through it, then click the thing behind it" work. |
One action, always |
On, off and every setting are reachable from the toolbar, a single keystroke, and the window’s own handle. No menu archaeology. |
Keyboard-first |
Every behaviour above has a keyboard equivalent. Hover is a convenience, never the only way in — otherwise it is unusable without a mouse, and unreachable for anyone with a tremor. |
The behaviours split across two delivery vehicles because browsers and operating systems allow different amounts of control. Details, and the honest limits of each, are in the mechanisms section.
-
A userscript for the page you are on: an in-page float that can host a video, a panel or a document, with every behaviour above under full control. Works in Tampermonkey-class managers, in Firefox, Chrome and Edge, on Windows and Linux, with no install and no permissions.
-
An app for a real, OS-level always-on-top window: true transparency, true click-through, and windows that live above other applications rather than above the page. This is where "float it over Excel while you work in Word" becomes possible.
Both are written in AffineScript, and the app is built on gossamer, the estate’s resource-safe desktop shell. Why that is the right split, what gossamer still needs, and what AffineScript’s userscript target must add are recorded in ADR-0004.
A browser cannot move, fade or click-through its own picture-in-picture window: that window belongs to the browser and the OS. So the choreography has to live in one of the two vehicles above. Saying that plainly is more useful than pretending a toggle can do it.
|
Important
|
Pre-alpha. Nothing is usable yet. No userscript has been published, no app has been built, and this repository is still mostly scaffolding: it was minted from the RSR template on 2026-10-31 and the identity fields are partly unassigned. The one thing that is real is the specification work below, because that is where the design risk is. |
What exists today:
-
this README — the problem and the behaviour;
-
the interaction model — states, triggers, settings, accessibility parity, what each platform can actually do;
-
the implementation language analysis — why the interim is plain JavaScript, why ReScript is not an option, and what AffineScript needs before it can take over;
-
the technical statement of conformance — the measurable definition of done, kept out of this document on purpose.
The most useful contribution right now is a collision report: which site, which page, which control the floating window covered, and what you had to do about it. That is the raw material the avoidance rules are built from. Open an issue with the URL pattern and the element you were reaching for.
Code, configuration and scripts are Mozilla Public License 2.0
(MPL-2.0); prose documentation is CC-BY-SA-4.0. Both texts live in
LICENSES/, and per-file SPDX-License-Identifier headers are authoritative.