Ada
designs algorithms in her sleep
← nope · like →A Tinder-style card stack — drag horizontally, watch the top card translate AND rotate (one source MotionValue drives both via useTransform), and a LIKE / NOPE badge fades in on the relevant side. Release past the 140px distance threshold OR with > 650 px/s velocity flings the card off screen and the stack springs forward. Anything weaker snaps back.
useMotionValue for the top card's horizontal offset, three useTransforms on top of it: rotation maps [-200, 0, 200] → [-18°, 0°, 18°], and the LIKE / NOPE
badge opacities ramp in over the 40–140px gutter. One source, four visuals, can't
desync.Math.sign(info.offset.x) with info.velocity.x as the fallback for fast flicks with sub-threshold distance.deck = deck.slice(1) drops it and the {#each} block re-keys the remaining cards forward.designs algorithms in her sleep
← nope · like →A bottom sheet that follows your finger as you pull it down. Past 120px OR with downward velocity > 700 px/s, it commits to dismiss. Otherwise it springs back. pan gives you offset + velocity; you decide what to do with them.
onPan fires every frame with info.offset and info.velocity. We clamp offset to >= 0 so the sheet only follows
downward drags, and write it straight into a motion value the transform reads.onPanEnd is the distance OR velocity pattern: pulled more than 120px past origin or still moving downward faster than 700px/s ⇒ dismiss. Either condition
alone fires the close. This is how a real sheet feels — slow pull works, fast flick also
works.useTransform of the same sheet offset — at 0px it's
fully opaque, at 300px it's transparent. One source value drives both the sheet position
and the dimmer, so the visuals can't desync.Pull down past 120px, or flick downward at > 700 px/s. The release decision combines both — fast flicks commit even when distance is short.