Retour au catalogue
Mobile App Device
Mockup de telephone centre avec ecran placeholder, texte descriptif, stats et badges store.
mobile-appmedium Both Responsive a11y
minimalcorporatesaasuniversalcentered
Theme
"use client";
import { motion } from "framer-motion";
import { Star, Download } from "lucide-react";
interface MobileAppDeviceProps {
title?: string;
titleAccent?: string;
description?: string;
badge?: string;
rating?: string;
downloads?: string;
appStoreCta?: string;
playStoreCta?: string;
screenColor?: string;
}
const EASE = [0.16, 1, 0.3, 1] as const;
export default function MobileAppDevice({
title = "Votre application mobile",
titleAccent = "intuitive",
description = "Une experience mobile fluide et performante.",
badge = "Disponible maintenant",
rating = "4.9",
downloads = "100k+",
appStoreCta = "App Store",
playStoreCta = "Google Play",
screenColor = "var(--color-accent-subtle)",
}: MobileAppDeviceProps) {
return (
<section
style={{
position: "relative",
overflow: "hidden",
paddingTop: "var(--section-padding-y-lg)",
paddingBottom: "var(--section-padding-y-lg)",
background: "var(--color-background)",
}}
>
<div
style={{
width: "100%",
maxWidth: "var(--container-max-width)",
margin: "0 auto",
padding: "0 var(--container-padding-x)",
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: "3rem",
}}
>
{/* Text content */}
<div style={{ textAlign: "center", maxWidth: "600px" }}>
{badge && (
<motion.span
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.4, ease: EASE }}
style={{
display: "inline-block",
padding: "0.5rem 1.25rem",
borderRadius: "var(--radius-full)",
border: "1px solid var(--color-accent-border)",
background: "var(--color-accent-subtle)",
fontSize: "0.8125rem",
fontWeight: 500,
color: "var(--color-foreground-muted)",
marginBottom: "1.5rem",
}}
>
{badge}
</motion.span>
)}
<motion.h2
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.06, ease: EASE }}
style={{
fontFamily: "var(--font-sans)",
fontSize: "clamp(2rem, 4vw, 3.5rem)",
fontWeight: 700,
lineHeight: 1.1,
letterSpacing: "-0.03em",
color: "var(--color-foreground)",
marginBottom: "1rem",
}}
>
{title}{" "}
<em
style={{
fontFamily: "var(--font-serif)",
fontStyle: "italic",
fontWeight: 400,
color: "var(--color-accent)",
}}
>
{titleAccent}
</em>
</motion.h2>
<motion.p
initial={{ opacity: 0, y: 12 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.12, ease: EASE }}
style={{
fontSize: "1.125rem",
lineHeight: 1.7,
color: "var(--color-foreground-muted)",
marginBottom: "1.5rem",
}}
>
{description}
</motion.p>
{/* Stats row */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5, delay: 0.18, ease: EASE }}
style={{ display: "flex", justifyContent: "center", gap: "2rem", marginBottom: "1.5rem" }}
>
<div style={{ display: "flex", alignItems: "center", gap: "0.375rem", color: "var(--color-foreground-muted)", fontSize: "0.875rem" }}>
<Star style={{ width: 16, height: 16, color: "var(--color-accent)" }} />
<span style={{ fontWeight: 600, color: "var(--color-foreground)" }}>{rating}</span> note
</div>
<div style={{ display: "flex", alignItems: "center", gap: "0.375rem", color: "var(--color-foreground-muted)", fontSize: "0.875rem" }}>
<Download style={{ width: 16, height: 16, color: "var(--color-accent)" }} />
<span style={{ fontWeight: 600, color: "var(--color-foreground)" }}>{downloads}</span> telechargements
</div>
</motion.div>
{/* Store buttons */}
<motion.div
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.45, delay: 0.24, ease: EASE }}
style={{ display: "flex", justifyContent: "center", gap: "0.75rem", flexWrap: "wrap" }}
>
{[appStoreCta, playStoreCta].map((label) => (
<a
key={label}
href="#"
style={{
display: "inline-flex",
alignItems: "center",
gap: "8px",
padding: "0.75rem 1.75rem",
borderRadius: "var(--radius-md)",
background: "var(--color-foreground)",
color: "var(--color-background)",
fontWeight: 600,
fontSize: "0.875rem",
textDecoration: "none",
}}
>
{label}
</a>
))}
</motion.div>
</div>
{/* Phone mockup */}
<motion.div
initial={{ opacity: 0, y: 40 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.7, delay: 0.3, ease: EASE }}
style={{
width: 280,
height: 560,
borderRadius: 40,
border: `3px solid var(--color-border)`,
background: "var(--color-background-card)",
padding: 12,
boxShadow: "0 24px 60px rgba(0,0,0,0.15)",
}}
>
{/* Notch */}
<div
style={{
width: 120,
height: 28,
borderRadius: "0 0 16px 16px",
background: "var(--color-background-card)",
margin: "0 auto",
position: "relative",
top: -12,
zIndex: 2,
border: `2px solid var(--color-border)`,
borderTop: "none",
}}
/>
{/* Screen placeholder */}
<div
style={{
width: "100%",
height: "calc(100% - 20px)",
borderRadius: 28,
background: screenColor,
marginTop: -8,
}}
/>
</motion.div>
</div>
</section>
);
}