Four kinds of waiting were wearing one gold shimmer
In Scenri the same gold shimmer meant a page loading, a picture decoding, a library downloading and a picture being made. I split it into two signals, and designed the slow one against a stand-in engine that took 30 seconds a picture.

In this story5 sections
Open a shot in Scenri, ask for a refinement, and in September the whole open picture would start to shimmer gold. Not the new picture. The entire stage. A CSS rule that boxed the shimmer in had been deleted in an earlier rewrite, so it spread over everything behind it.
That bug was the way in. The real problem was that one gold shimmer was being asked to say four different things.
One signal, four meanings
The same gold shimmer, and two copies of it, stood for:
- a page of data on its way
- a picture that exists and is decoding
- the library downloading on a first run
- a picture being generated
Those are not the same kind of waiting. Three of them are the app catching up with something that already exists. The fourth is the product doing its work. If they all look the same, the person cannot tell a slow load from a picture in progress. And gold, which also marks a picture you have kept, was being spent on loading.
The shimmer also cost more than it looked. It moved by animating background-position, which repaints every tile on every frame on the main thread. A wall of 48 waiting tiles, traced for four seconds, produced about 18,000 to 19,600 paint events and about 245 ms of main-thread painting.
Give each kind of waiting its own signal
PR #268 split it in two, and wrote the rule into the design doc: waiting never wears gold.
Placeholder is for things that exist and have not painted. It is the surface's own ground, in the exact box the thing will take, and it is still. Only if it is still there after 800 ms does a faint breath come up, ink at 5%, opacity only. A fast load never shows motion. A slow one never looks dead.
Rendering is for a picture being made, and only there. It is a slow dithered swirl in quiet ink, the page's text colour at 22%, drawn inside the box of the picture it stands for: the feed tile, the strip tile, the stage's waiting box, the Refining chip. Never a whole stage or page. Beside it, an elapsed clock, never a percentage, because a generation has no honest percentage.
Moving is what tells the two apart. If it moves, something is being made.
- Paint events, 48 waiting tiles over 4 s
- 0from 18,000+
- Per frame to draw the swirl
- 0.2 ms
- Layout shift, cold load of Products
- 0.0009from 0.1247
The swirl is drawn on a small canvas at the resolution of its dots and scaled up, so each dot is a crisp square. Every canvas shares one frame loop, and one off screen is skipped.
Prototype the wait at real duration
A generation with a real engine costs the user money or quota, and takes a while. That is exactly why it is hard to design: you cannot afford to sit through hundreds of them to judge how the wait feels, and on a fast fake engine the wait is gone before you see it.
Scenri already has a demo engine for tests: it answers quickly with a drawn placeholder and costs nothing. For this work it was slowed down instead. The lane I designed on ran it with a 30 second delay per picture, a 3 second stagger between the pictures in a batch, and a new switch, SCENRI_DEMO_PHOTOS, so it answered with real photographs from the library rather than flat stand-ins.
That changed what I could see. At 30 seconds the question is not "does it animate" but "is it still calm at second 25". With real photographs, the landing could be judged on real pictures, which is where the last part of the design came from:
- After Generate the swirl dithers in over 600 ms. Only its density rises.
- When the picture arrives, the swirl brakes to a stop over 900 ms and its dots gather into the picture's own tones, then the picture develops through that grain.
- A refinement plays that landing backwards: the picture goes back into its grain and becomes the next swirl, in place.
Several looks were built for this and compared on the same lane before one was chosen. None of it cost a single real generation.
Reduced motion is a design, not a switch
Every one of these has a reduced-motion answer, decided at the same time. The placeholder is flat. The swirl draws one frame and holds it while the clock keeps counting. A finished picture simply appears.
How I design a wait now
- List every state in which the user is waiting, and what is actually happening in each.
- Split them by meaning: catching up with something that exists, or making something new.
- Give each meaning one signal, and let nothing else borrow it. Keep the brand colour out of it.
- Show nothing for fast waits. Delay any motion until the wait is long enough to need reassurance.
- Keep the signal inside the box of the thing it stands for.
- Build a stand-in engine that takes as long as the real one, and design against that.
- Measure the paint cost of a full wall of waiting tiles, not one.



