- Shipped
- September 9, 2026 at 3:23 AM UTC
- Author
- Kamo
- Commit
- 5185627
The felt's turn clock ran off a 200ms setInterval writing a fraction into React. That is an honest way to build a bar that must track a server deadline, and it is wrong in the one place it matters most: Chrome throttles a hidden tab's timers to one wake-up a minute, so a table behind another tab — or in a minimized window — showed a clock that had simply stopped. Nobody watches a clock they cannot see, which is why it survived this long. Split by what each half actually is: - The DRAIN is continuous, so it is a CSS animation whose duration is the whole allowance and whose animation-delay is negative by the elapsed time. The browser starts it part-played and the compositor runs it from there — exact across every re-render, unthrottled behind a hidden tab, and costing no renders at all. Measured in Chrome against a frozen clock: a thirty-second allowance read at 15s elapsed draws a stroke-dashoffset of 0.537, at 24s it draws 0.837. - PRESSURE is three moments, so it is three timeouts that set state rather than a poll asking five times a second whether anything has happened. Plus one at the deadline itself, because the arrival of a deadline has to BE a state change — compared during render it never fires, since nothing re-renders when it passes. - The seconds NUMBER is the one thing that genuinely needs a tick, because CSS cannot render a number. One hertz instead of five, and only where a number is actually on screen. The keyframes are parameterless — `pathLength: 1` normalises the ring so one rule drains a 16px clock and a 44px one, and the bar scales rather than resizing so it never touches layout. That is what lets them live in the shared stylesheet, which is what lets the reduced-motion guard see them at all. Reduced motion keeps the drain and takes its smoothness: twelve discrete steps rather than a glide. Every other reset in that block cancels, and this one must not — for a countdown, movement and information are the same thing, and freezing it hides the deadline and times the player out. Pinned by a test rather than a comment, mirroring the one that keeps the lamp visible. Two things worth naming for whoever is here next: The reduced-motion guard finds animations by scanning for `animation:` and walking back to the enclosing JSX tag. Writing the drain as `animationName` in a style object made it invisible to that scan — no enforcement, silently, for ever — and building the shorthand inside a helper would have hidden it just as well. It is written out in the tag on purpose. And `clockStages` derives the stage boundaries BY WALKING `clockPressure` rather than restating `critical <= 3` beside it. A poll asks what the pressure is now; a timer needs to know when it changes; those are one fact in two shapes, and the copy that goes untested is always the newer one. The turn clock's AUDIO keeps its own ramp, which is now said out loud in both places instead of being two sets of numbers a reader has to guess about. Found by projects-81, who could not take it while three of us were in these files.