Retour au catalogue
Careers Culture
Section culture d'entreprise avec valeurs en cards et photos placeholder en grille asymetrique.
careersmedium Both Responsive a11y
minimalcorporateelegantsaasuniversalagencygrid
Theme
"use client";
import { motion } from "framer-motion";
import { Heart, Users, Sparkles, Target } from "lucide-react";
import type { LucideIcon } from "lucide-react";
interface Value {
icon: string;
title: string;
description: string;
}
interface CareersCultureProps {
title?: string;
titleAccent?: string;
description?: string;
values?: Value[];
photoColors?: string[];
}
const EASE = [0.16, 1, 0.3, 1] as const;
const ICON_MAP: Record<string, LucideIcon> = {
heart: Heart,
users: Users,
sparkles: Sparkles,
target: Target,
};
export default function CareersCulture({
title = "Notre culture",
titleAccent = "d'entreprise",
description = "Ce qui nous rassemble et nous fait avancer chaque jour.",
values = [],
photoColors = [],
}: CareersCultureProps) {
const defaultValues: Value[] = values.length
? values
: [
{ icon: "heart", title: "Bienveillance", description: "Un environnement ou chacun se sent ecoute et respecte." },
{ icon: "sparkles", title: "Innovation", description: "Nous encourageons les idees nouvelles et l'experimentation." },
{ icon: "users", title: "Collaboration", description: "Le travail d'equipe est au coeur de chaque projet." },
{ icon: "target", title: "Impact", description: "Chaque contribution compte et fait avancer notre mission." },
];
const defaultColors = photoColors.length
? photoColors
: ["var(--color-accent-subtle)", "var(--color-background-alt)", "var(--color-accent-subtle)"];
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)",
}}
>
{/* Header */}
<div style={{ textAlign: "center", maxWidth: "600px", margin: "0 auto 3rem" }}>
<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(2rem, 4vw, 3rem)",
fontWeight: 700,
lineHeight: 1.1,
letterSpacing: "-0.02em",
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.08, ease: EASE }}
style={{ fontSize: "1.0625rem", lineHeight: 1.7, color: "var(--color-foreground-muted)" }}
>
{description}
</motion.p>
</div>
{/* Photo placeholders */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.12, ease: EASE }}
style={{
display: "grid",
gridTemplateColumns: "2fr 1fr 1fr",
gap: "1rem",
marginBottom: "3rem",
height: 240,
}}
>
{defaultColors.map((color, i) => (
<div
key={i}
style={{
borderRadius: "var(--radius-lg)",
background: color,
border: "1px solid var(--color-border)",
}}
/>
))}
</motion.div>
{/* Values grid */}
<div
style={{
display: "grid",
gridTemplateColumns: "repeat(auto-fill, minmax(240px, 1fr))",
gap: "1.25rem",
}}
>
{defaultValues.map((val, i) => {
const Icon = ICON_MAP[val.icon] ?? Heart;
return (
<motion.div
key={val.title}
initial={{ opacity: 0, y: 16 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.45, delay: 0.2 + i * 0.06, ease: EASE }}
style={{
padding: "1.5rem",
borderRadius: "var(--radius-lg)",
border: "1px solid var(--color-border)",
background: "var(--color-background-card)",
}}
>
<div
style={{
width: 40,
height: 40,
borderRadius: "var(--radius-md)",
background: "var(--color-accent-subtle)",
display: "flex",
alignItems: "center",
justifyContent: "center",
marginBottom: "1rem",
}}
>
<Icon style={{ width: 20, height: 20, color: "var(--color-accent)" }} />
</div>
<h3
style={{
fontFamily: "var(--font-sans)",
fontSize: "1rem",
fontWeight: 600,
color: "var(--color-foreground)",
marginBottom: "0.5rem",
}}
>
{val.title}
</h3>
<p style={{ fontSize: "0.875rem", lineHeight: 1.6, color: "var(--color-foreground-muted)" }}>
{val.description}
</p>
</motion.div>
);
})}
</div>
</div>
</section>
);
}