REFERENCE
- Gallery page: https://magpui.com/en/i/like-notification-avatar-stack-5a830c
- First frame (image): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/like-notification-avatar-stack-5a830c/shot.jpg
- Clip (mp4): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/like-notification-avatar-stack-5a830c/clip.mp4
- Original post: https://x.com/desdivj/status/2116132632966860847 by @desdivj
Before building, download the first frame and look at it. If ffmpeg is available, download the clip and extract frames (ffmpeg -i clip.mp4 -vf fps=2 frame-%02d.png), then study the motion frame by frame. Match what you see; the text below describes it, the frames are the truth.
BUILD: Build a notifications list row for likes, shown in a mobile social app feed. Each row has a pink heart on the left, a horizontal stack of 6-7 small circular avatars, a headline like "Name and 98 others liked your post", a relative timestamp, a one-line excerpt of the post, and a square post thumbnail on the right. When a new like arrives (after a pull-to-refresh or a live event), the top row updates in place: the new person's avatar pops in at the front of the stack with a brief pink ring, the existing avatars slide one slot to the right and the last one fades out, while the headline crossfades to the new name with the count bumped by one and the timestamp resets. It should feel quick, soft and satisfying, not flashy.
DESIGN SYSTEM: White page #FFFFFF, rows separated by generous vertical padding (16-20px) with no dividers. Top bar: centered title in a semibold sans around 17px, small user avatar on the left, settings icon on the right; below it a segmented tab row (All, Priority, Mentions) with 15px medium labels and a 2px #111111 underline under the active tab. Heart icon #FF1F7A, 20px. Avatars 24px circles with a 2px white border, overlapping by about -4px or sitting with 2px gaps; fallback avatars as solid color circles with a white initial (e.g. #F26B1D). Headline 15px, bold name #111111, regular rest #111111; meta and excerpt 14px #6B6B6B. Thumbnail 48px square, radius 8px. Line height ~1.35.
MOTION: Pull-to-refresh: a small arrow turns into a spinner (rotate, 800ms linear loop). New like: the incoming avatar enters at slot 0 from scale 0.4 and opacity 0 to scale 1, 320ms cubic-bezier(0.34,1.56,0.64,1); a pink ring (#FF1F7A, 2px) draws around it and fades out over 500ms with a 120ms delay. Other avatars translateX by one slot width with 30ms stagger, 280ms cubic-bezier(0.22,1,0.36,1); the last avatar fades and scales to 0.8 over 200ms. Headline: old text fades and blurs out (opacity 1 to 0, blur 0 to 4px, translateY 0 to -4px) in 160ms while the new text enters from translateY 4px, 220ms cubic-bezier(0.22,1,0.36,1); the count digits roll like an odometer. Timestamp swaps with a 150ms crossfade.
SECTIONS: Parts: top bar, tabs, notification rows (heart, avatar stack, headline, timestamp, excerpt, thumbnail), reply rows below. States per row: idle, refreshing (spinner above the list), new like arriving, settled; hover or pressed state on a row lightens the background to #F7F7F7.
IMPLEMENTATION: React with Motion (Framer Motion): render the avatar stack with AnimatePresence and layout animations keyed by user id so shifts are automatic; use AnimatePresence mode popLayout for the headline swap and a small per-digit rolling counter. CSS only is possible but layout animations make the reorder trivial. prefers-reduced-motion: swap avatars and text instantly with a simple 120ms opacity fade, no ring or roll. Accessibility: announce new likes through an aria-live polite region; rows are focusable links with a visible focus ring. Keep it cheap: animate only transform, opacity and filter, cap the stack at 7 avatars.
ADAPT TO THE PROJECT: Reuse the project's existing design tokens, components and fonts; map every color to the closest existing token. Never copy logos, brand names, photos or illustrations from the original; use placeholder avatars and thumbnails.
SUCCESS CHECK:
- Triggering a new like makes the new avatar pop in at the front with a pink ring while the others slide right and the last one fades out.
- The headline name, count and timestamp update with a smooth crossfade and rolling digits, with no layout jump.
- With reduced motion enabled the update is an instant swap with a short fade, and the change is announced to screen readers.