How the Swipe card enters
Round 1: the cause, Today from the real app, and three entrances for a tab switch. The door's entrance stays as it is.
Owner, Oct 10: "When you go to the Swipe page the card springs in way too quickly." Tap Explore then Swipe on any phone below, or play them all at once. Slow motion runs at a quarter speed.
Today
From ios/review at 25717998 on the Saga Smoke D simulator against staging, signed in as the smoke account, recorded at 30 fps. Switching to Swipe takes one of three paths, and only one of them springs:
- The deck is already there and you left it open: a cut. The card is just there; only the tab pill slides.
- The deck is already there and you left it folded (after a swipe): the card shows up at its folded size, then shrinks to 92% while the logo row and the bottom buttons come back. This is
openUp()on focus, now onFOLD(460 ms, ease-in-out). Before last night it ran 420 ms onCHISEL, which is faster at the start, so last night's change made this path slower and softer. - The deck mounts as you arrive: the first visit when Swipe opens on a remembered mode, the first visit after more than a minute in the background, after Done on Found it, or after a mode change. The deck deals in from below the screen on
SPRING.card(damping 16, stiffness 180). That spring's damping ratio is 0.6: the card covers a whole screen height, passes its resting place at about 205 ms, goes about 90 pt too far at 290 ms, and settles at about 550 ms. This is the spring.
Cause: swipe.tsx:246, dealY.set(withSpring(0, SPRING.card)), with dealY starting at the screen height (swipe.tsx:243). It came in with the door on Oct 6 (a6540c72, then a SlideInDown on the same spring; 19460d40 made it a held transform). It's on master too, so last night's fold change didn't cause it and it isn't a regression. It shows up when the deck is fresh, which is often right after you come back to the app and tap Swipe.



SPRING.sheet (damping ratio 0.82, a 1% settle) while the door fades; the logo carves in after. 67 ms per frame.
Today, live
Paths 3 and 2 with their real numbers. The curve under each phone is the card's travel against time (0 to 800 ms); the dashed line is where the card rests, so anything above it is overshoot.
- if (dealsIn && deck.status === "ready") dealY.set(withSpring(0, SPRING.card)); + if (dealsIn && deck.status === "ready") dealY.set(withSpring(0, { duration: 560, dampingRatio: 1 }));
The tab-switch entrance
One entrance for every arrival by tab, whether the deck is fresh or already there. It replaces the deal from below (path 3) and the shrink from folded (path 2): on focus the fold resets with no animation while the card is hidden, then the entrance runs. Each one starts on the frame the tab pill starts moving and the tab bar grows back (FOLD, 460 ms), so they land together. The door keeps its lift and land. There's no haptic, because the tab tap already ticks. With Reduce Motion the card is just there, as the deal is today.
| A · Rise and settle | B · Dealt from the hand | C · Develops in place | |
|---|---|---|---|
| Motion | Rises 44 pt into place and grows from 88% to 92%, fading in over the first 200 ms. The card behind follows 60 ms later. | Starts small at the Swipe tab, tilted −6°, and travels up to its place while it straightens. The card behind fans 4° and tucks back. | Stays where it rests. The poster sharpens and lights up from 1.03× to its size, and the two cards behind fan out ±4° and tuck back under it. |
| Timing | 480 ms, settle curve bezier(0.22, 1, 0.36, 1) | 560 ms, bezier(0.16, 1, 0.3, 1) | 500 ms, the FOLD curve |
| Overshoot | None | None | None |
| With the tab bar | Lands 20 ms after the bar. | Comes out of the Swipe tab, so the bar is where it starts. Lands 100 ms after the bar. | Lands 40 ms after the bar. Nothing travels, so the bar is the only thing moving across the screen. |
| Web and Android | Transform and opacity only: the same on all three. | Transform and opacity only: the same on all three. | Web uses a CSS blur. Native has no cheap animated blur, so it runs a dark veil and the scale without the blur (expo-blur on a full card costs frames on Android). |
| Cost | Small. dealY becomes an entrance value set on focus and on mount; openUp() on focus sets folding without timing. | Small to medium. The tab's position is measured for the start point; the tilt needs the card's shadow to turn with it. | Medium. Two cards behind need to be drawn during the fan (today only one is mounted), and the veil adds a layer over the poster. |
| What it drops | The sense of a fresh deal on a fresh deck: every arrival looks the same. | Restraint: travel and tilt on every tab switch can get tiring by the tenth time. | A clear direction: nothing comes from anywhere, which reads as a page load more than a card. |
My recommendation
A, Rise and settle. It speaks the door's language (the card lifts into its place on a curve with no bounce), it's small enough to feel right on the tenth tab switch, and it costs the least: transform and opacity on all three platforms, landing with the tab bar. It also gets rid of the folded shrink, so every arrival looks the same. B is the most playful and would suit a fresh deck if you want the deal back for that moment only. C is the quietest but costs the most on native.