Name Every Timing Value
SHOULD: Hoist every delay, duration and easing into one named block and drive a multi-stage sequence with a single integer stage, not scattered magic numbers and boolean flags (`isCardVisible` / `isHeadingVisible` / `areRowsVisible`) — otherwise retuning the tempo means hunting five call sites and the heading silently starts arriving after the rows it introduces.
Hoist every delay, duration and easing into one named block and drive the sequence with a single integer
const TIMING = { cardAppear: 300, heading: 900, rows: 1500 } as const;
// then: stage >= 2 ? ... : ...Bad
Good
Why it matters
From Josh Puckett's Interface Craft. A multi-stage reveal wired as delay: 0.3 here, delay: 0.9 there, stagger: 0.2 inline in the JSX, sequenced by isCardVisible / isHeadingVisible / areRowsVisible, has no readable choreography: the order exists only in the author's head, and retuning it means hunting magic numbers across five call sites. The failure is concrete — change the tempo, miss one of those sites, and the heading now arrives after the rows it was supposed to introduce, a bug that survives code review precisely because no number is named.
The fix is two moves: hoist the values into one block (const TIMING = { cardAppear: 300, heading: 900, rows: 1500 }) and collapse the flags into one integer stage, so the JSX reads stage >= 2 ? ... : ... and the sequence is legible top to bottom. ADJACENT TO BUT DISTINCT FROM animations-emil-motion-cohesion: cohesion is about one shared motion vocabulary ACROSS the product, so that a dropdown here and a toast there feel like the same hand made them.
This is about one sequence, inside one component, being readable and tunable at all. You can be perfectly cohesive and still have an unmaintainable timeline; and a single well-named TIMING block does not, by itself, make the product coherent.