← back to the dust

Screensaver

How to run the dust full screen, and an honest look at what packaging it as a PWA would and would not buy — including the one part of the idea that does not work at all.

Run it full screen

The page has no chrome of its own, so a browser in full screen is already most of the way there. F11 on Windows and Linux, ⌃⌘F on macOS. On a phone, add it to the Home Screen and it opens without the browser bars.

Every part of the look is a URL switch, so a particular feel can be bookmarked:

switchrangedoes
glow0–1twinkle around the pointer. Never moves the mark.
wake0–1pushes grains aside. Bends the K while the pointer is over it.
pull0–1draws grains in until they knot and brighten.
radius0.01–1how far any of that reaches.
tide0–1the unattended cycle. 0 makes it pointer-driven only.
attack / releasesecshow fast it gathers, how slowly it lets go.
etausecshow long a burst of movement keeps working.
grainsNdensity. Lower it on a tired machine.
travelsecshow long the grains take to fly to the index title.
spread0–0.95how staggered their departures are.
arc0–0.5how far they bow off a straight line.
dim / shrink0–3 / 0–1how much a grain fades and narrows as the mark shrinks.

Add .mouse or .touch to any of them to set one input type only. A few worth trying:

/?travel=3&spread=0.9        the index transition, slow and loose
/?travel=0.4&spread=0&arc=0  the same trip as one rigid move
/?tide=0.4&glow=0.35          calmer: rarely forms, barely reacts
/?glow=0.9&radius=0.35        heavier fairy dust under the cursor
/?wake=0.7                    the K bends away from the pointer
/?pull=0.5                    grains gather into a bright knot
/?grains=25000                lighter on the fans

Press d on the page for a readout of grain count, frame rate and every switch.

Two things worth building

Neither needs a PWA, and both matter more than one.

Screen wake lock

A screensaver that lets the screen sleep is not a screensaver. navigator.wakeLock.request('screen') holds it awake. It needs a user gesture and a visible document, and the lock drops when the tab is hidden, so it has to be re-acquired on visibilitychange. This is the single biggest quality win available, and it works on a plain web page.

Battery manners

WebGL at 60fps will drain a laptop or phone. Halving the frame rate and cutting grains when the battery is discharging and low costs nothing visually — grains is already a switch.

What a PWA actually gets you

Worth separating two things that sound the same.

A real screensaver is an OS component the system starts when the machine goes idle — .scr on Windows, .saver on macOS. The web cannot register as one. No API, no permission, no workaround.

A fullscreen page you leave open is what a PWA gets you. That is most of the fun, and worth having — but it should be called what it is.

a PWA giveswhy it matters here
standalone windowno browser chrome — the thing that makes it feel like an app
an iconthe reason anyone opens it a second time
offlinetrivial: the page is one file that fetches nothing
somewhere to iteratea settings screen for the switches above

If a genuine screensaver is ever wanted, that is a native wrapper around this same page — Electron emitting a .scr, or a small .saver hosting a web view. Different project, same index.html.

Could we reward people for installing it?

The idea: give out a little KBAR to anyone who installs the PWA. It is a nice idea and the mechanism it assumes does not exist.

Installation cannot be verified

Every signal the platform offers is a value produced on the claimant's own device:

signalwhy it proves nothing
beforeinstallprompta JS object, in a browser the claimant controls
appinstalledan event they can dispatch themselves
display-mode: standalonetrivially true for anyone who wants it to be
getInstalledRelatedApps()see below — it is not what it looks like

getInstalledRelatedApps() looks like the answer and is not. Its Digital Asset Links check binds the app to the site, so that other websites cannot probe what you have installed. It is an anti-fingerprinting measure. There is no signature, nothing for a server to verify, and the result still arrives as a value on the claimant's machine.

The attack is not clever: open devtools, watch the claim request, replay it. No client-side check survives that, because the client is the adversary.

The one signal that is expensive to fake

A Web Push subscription, verified by using it. The endpoint is issued by the browser vendor's push service, not by the page, so the server can push a nonce and require the client to echo it. That proves a real browser, really reachable.

Two things make it stronger: on iOS, Web Push only works once the page is on the Home Screen, so there a live subscription really is install evidence; and pushing again at day 7 and only paying if it still answers turns install, claim, uninstall into keep it for a week — which is what you wanted to pay for anyway.

The cost is a notification permission prompt on a novelty page, which most people will decline.

Hack angles

anglecostmitigation
Replay the claimnear zeroserver-issued single-use token
Farm browser profileslow — the real attackper-wallet cap + wallet history
Sybil walletsscriptablewallet must predate the campaign
Rotate IPscheaprate limit only; never IP as identity
Install, claim, uninstallzerodelayed re-check, or accept it

WalletConnect is worth having, but it proves control of a key at claim time — not personhood, not uniqueness. It is a payment rail and a de-duplication key. The account-history requirement is what does the anti-sybil work.

The short version. Spend the effort on a fixed total budget and an established-wallet requirement, and ship.

A cap — "first 200 wallets, then it stops" — is the only control that bounds the downside absolutely; everything else is probabilistic. Requiring the wallet to predate the campaign is a single mirror-node read and turns mint a key, claim into have been here before, which is exactly who the reward is for.

At that scale the worst realistic outcome is that some existing community members get a slightly larger share than intended. Building push verification to protect a few hundred KBAR would cost more than the KBAR.

On copying

Anyone can read the source and reskin it — one unminified file, and the K is two SVG shapes. That is fine and not worth defending. If someone puts their own letter in it, nothing is lost and the idea travels.

The one thing to watch is the reverse: swapping in someone else's logo, which is their trademark and not ours to animate. Fine as a private experiment, not under a KPAY address.