proNew345 lines · framer-motion
Device Mockup Carousel
A coverflow of phones, every screen drawn live. A full-width Cards section showing a coverflow carousel of hand-drawn phone mockups. The active device is centered and large; neighbours peek in at reduced scale and opacity. Each screen is a distinct CSS/SVG composition — no screenshots, no logos.
- Use it for
- Showing a family of app screens, product surfaces or feature states side by side, when you don't have (or don't want) real screenshots.
- Themes
- Light + dark
- License
- Commercial use
Live
Cards
One shell, every surface
Every screen here is generated live. Swap the count, the pace, or let it drift on its own.
Signal
tsx
"use client";
import * as React from "react";
import { motion, useReducedMotion } from "framer-motion";
import { cn } from "@/lib/utils";
function useReducedMotionSafe() {
const prefersReduced = useReducedMotion();
const [mounted, setMounted] = React.useState(false);
React.useEffect(() => setMounted(true), []);
return mounted ? !!prefersReduced : false;
}
/**
* Full-width "Cards" section: a coverflow-style carousel of hand-drawn phone
* mockups, each screen filled with a distinct, entirely generated CSS/SVG
* composition (no photography, no app logos). The active device sits centered
* and large; its neighbours peek in from the sides at reduced scale/opacity.
*/
export interface DeviceMockupCarouselProps {
eyebrow?: string;The rest is in Pro.
Full source, the rebuild prompt and registry install unlock with Pro or Lifetime.
Get ProHow it behaves
- →Phone chassis (rounded frame, notch, screen cut-out) is pure CSS; each screen's content is one of 4 generated layouts (stat tiles + sparkline, chat bubbles, album art + waveform, list rows) recoloured per slide from the design-system accent tokens.
- →Slide offset from the active index is computed as a shortest signed distance around the loop, then mapped to a pixel translateX (measured via ResizeObserver on the stage, so it scales with container width), a scale (1 / 0.8 / 0.62) and an opacity (1 / 0.55 / 0.22) by distance.
- →Framer Motion animates x/scale/opacity with a spring on every index change; useReducedMotion collapses that to a 0ms transition.
- →On viewports under ~560px wide only the immediate neighbours are shown (the second ring is hidden) so nothing overflows the viewport; the stage itself is overflow-x-hidden.
- →Autoplay advances one slide on an interval and is skipped entirely when prefers-reduced-motion is on; it also pauses for as long as the carousel region is hovered or contains focus, and the interval/listeners are cleared on unmount or when any of its inputs change.
- →count slices the built-in slide list down to 4-6 cards; the active index wraps back into range if it shrinks.
Accessibility
- ✓The carousel is a `role="region"` with `aria-roledescription="carousel"` and an `aria-label`; it is keyboard-focusable and ArrowLeft/ArrowRight navigate it from anywhere inside.
- ✓Prev/Next are real `<button>`s with `aria-label`; dot indicators are buttons labelled `Go to slide N` with `aria-current="true"` on the active one.
- ✓Only the centered, active phone is exposed to assistive tech; the partially visible neighbours are marked `aria-hidden` since their content duplicates slides reachable via Prev/Next.
- ✓Honours prefers-reduced-motion.