Retour au catalogue
Mobile App Features
Features list avec mockup phone a cote, style split layout.
mobile-appmedium Both Responsive a11y
minimalcorporatesaasuniversalsplit
Theme
"use client";
import { motion } from "framer-motion";
import { Zap, Shield, Bell, CloudOff, RefreshCw, Lock } from "lucide-react";
import type { LucideIcon } from "lucide-react";
interface Feature {
icon: string;
title: string;
description: string;
}
interface MobileAppFeaturesProps {
title?: string;
titleAccent?: string;
description?: string;
features?: Feature[];
screenColor?: string;
}
const EASE = [0.16, 1, 0.3, 1] as const;
const ICON_MAP: Record<string, LucideIcon> = {
zap: Zap,
shield: Shield,
bell: Bell,
cloud: CloudOff,
refresh: RefreshCw,
lock: Lock,
};
export default function MobileAppFeatures({
title = "Tout ce dont vous avez besoin",
titleAccent = "au bout des doigts",
description = "Des fonctionnalites pensees pour simplifier votre quotidien.",
features = [],
screenColor = "var(--color-accent-subtle)",
}: MobileAppFeaturesProps) {
const defaultFeatures: Feature[] = features.length
? features
: [
{ icon: "zap", title: "Ultra rapide", description: "Temps de chargement inferieur a une seconde." },
{ icon: "shield", title: "Securise", description: "Chiffrement de bout en bout pour vos donnees." },
{ icon: "bell", title: "Notifications", description: "Restez informe en temps reel." },
{ icon: "cloud", title: "Mode hors-ligne", description: "Fonctionne meme sans connexion." },
{ icon: "refresh", title: "Sync automatique", description: "Vos donnees toujours a jour." },
{ icon: "lock", title: "Vie privee", description: "Aucune donnee revendue a des tiers." },
];
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: "grid",
gridTemplateColumns: "1fr 1fr",
gap: "4rem",
alignItems: "center",
}}
>
{/* Phone mockup */}
<motion.div
initial={{ opacity: 0, x: -40 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.7, ease: EASE }}
style={{ display: "flex", justifyContent: "center" }}
>
<div
style={{
width: 260,
height: 520,
borderRadius: 36,
border: "3px solid var(--color-border)",
background: "var(--color-background-card)",
padding: 10,
boxShadow: "0 20px 50px rgba(0,0,0,0.12)",
}}
>
<div
style={{
width: "100%",
height: "100%",
borderRadius: 26,
background: screenColor,
}}
/>
</div>
</motion.div>
{/* Features list */}
<div>
<motion.h2
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, ease: EASE }}
style={{
fontFamily: "var(--font-sans)",
fontSize: "clamp(1.75rem, 3.5vw, 2.75rem)",
fontWeight: 700,
lineHeight: 1.15,
letterSpacing: "-0.02em",
color: "var(--color-foreground)",
marginBottom: "0.75rem",
}}
>
{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.06, ease: EASE }}
style={{
fontSize: "1.0625rem",
lineHeight: 1.7,
color: "var(--color-foreground-muted)",
marginBottom: "2rem",
}}
>
{description}
</motion.p>
<div style={{ display: "grid", gap: "1.25rem" }}>
{defaultFeatures.map((feat, i) => {
const Icon = ICON_MAP[feat.icon] ?? Zap;
return (
<motion.div
key={feat.title}
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.45, delay: 0.12 + i * 0.06, ease: EASE }}
style={{ display: "flex", gap: "1rem", alignItems: "flex-start" }}
>
<div
style={{
width: 40,
height: 40,
borderRadius: "var(--radius-md)",
background: "var(--color-accent-subtle)",
display: "flex",
alignItems: "center",
justifyContent: "center",
flexShrink: 0,
}}
>
<Icon style={{ width: 20, height: 20, color: "var(--color-accent)" }} />
</div>
<div>
<h3
style={{
fontFamily: "var(--font-sans)",
fontSize: "0.9375rem",
fontWeight: 600,
color: "var(--color-foreground)",
marginBottom: "0.25rem",
}}
>
{feat.title}
</h3>
<p style={{ fontSize: "0.875rem", lineHeight: 1.6, color: "var(--color-foreground-muted)" }}>
{feat.description}
</p>
</div>
</motion.div>
);
})}
</div>
</div>
</div>
</section>
);
}