Retour au catalogue
Mega Footer Magazine
Footer style magazine avec colonnes editoriales, articles recents et mise en page typographique.
mega-footermedium Both Responsive a11y
editorialelegantagencyportfoliogrid
Theme
"use client";
import { motion } from "framer-motion";
import { ArrowUpRight, Newspaper } from "lucide-react";
interface FooterLink {
label: string;
href: string;
}
interface FooterColumn {
title: string;
links: FooterLink[];
}
interface RecentArticle {
title: string;
date: string;
href: string;
}
interface MegaFooterMagazineProps {
companyName?: string;
tagline?: string;
columns?: FooterColumn[];
recentArticles?: RecentArticle[];
copyright?: string;
}
const EASE = [0.16, 1, 0.3, 1] as const;
export default function MegaFooterMagazine({
companyName = "Revue Digitale",
tagline = "L'actualite tech et design, chaque semaine.",
columns = [],
recentArticles = [],
copyright = "2026 Revue Digitale. Tous droits reserves.",
}: MegaFooterMagazineProps) {
return (
<footer
style={{
paddingTop: "var(--section-padding-y)",
paddingBottom: "2rem",
background: "var(--color-background-alt)",
borderTop: "1px solid var(--color-border)",
}}
>
<div
style={{
maxWidth: "var(--container-max-width)",
margin: "0 auto",
padding: "0 var(--container-padding-x)",
}}
>
{/* Top: masthead-style branding */}
<motion.div
initial={{ opacity: 0, y: 16 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5, ease: EASE }}
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
flexWrap: "wrap",
gap: "1rem",
paddingBottom: "2rem",
borderBottom: "2px solid var(--color-foreground)",
marginBottom: "2.5rem",
}}
>
<div style={{ display: "flex", alignItems: "center", gap: "0.75rem" }}>
<Newspaper
style={{ width: 28, height: 28, color: "var(--color-foreground)" }}
/>
<h2
style={{
fontSize: "clamp(1.5rem, 3vw, 2rem)",
fontWeight: 800,
color: "var(--color-foreground)",
letterSpacing: "-0.02em",
textTransform: "uppercase",
}}
>
{companyName}
</h2>
</div>
<p
style={{
fontSize: "0.875rem",
color: "var(--color-foreground-muted)",
fontStyle: "italic",
}}
>
{tagline}
</p>
</motion.div>
{/* Content grid: columns + recent articles */}
<div
style={{
display: "grid",
gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))",
gap: "2.5rem",
marginBottom: "3rem",
}}
>
{/* Link columns */}
{columns.map((column, ci) => (
<motion.div
key={ci}
initial={{ opacity: 0, y: 12 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.4, delay: 0.05 * ci, ease: EASE }}
>
<h3
style={{
fontSize: "0.6875rem",
fontWeight: 700,
textTransform: "uppercase",
letterSpacing: "0.12em",
color: "var(--color-foreground)",
marginBottom: "1rem",
paddingBottom: "0.5rem",
borderBottom: "1px solid var(--color-border)",
}}
>
{column.title}
</h3>
<ul style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: "0.625rem" }}>
{column.links.map((link, li) => (
<li key={li}>
<a
href={link.href}
style={{
fontSize: "0.875rem",
color: "var(--color-foreground-muted)",
textDecoration: "none",
transition: "color 0.2s",
}}
onMouseEnter={(e) => (e.currentTarget.style.color = "var(--color-accent)")}
onMouseLeave={(e) => (e.currentTarget.style.color = "var(--color-foreground-muted)")}
>
{link.label}
</a>
</li>
))}
</ul>
</motion.div>
))}
{/* Recent articles column */}
{recentArticles.length > 0 && (
<motion.div
initial={{ opacity: 0, y: 12 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.4, delay: 0.15, ease: EASE }}
style={{ gridColumn: "span 1" }}
>
<h3
style={{
fontSize: "0.6875rem",
fontWeight: 700,
textTransform: "uppercase",
letterSpacing: "0.12em",
color: "var(--color-foreground)",
marginBottom: "1rem",
paddingBottom: "0.5rem",
borderBottom: "1px solid var(--color-border)",
}}
>
Articles recents
</h3>
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
{recentArticles.map((article, ai) => (
<a
key={ai}
href={article.href}
style={{
display: "block",
textDecoration: "none",
paddingBottom: ai < recentArticles.length - 1 ? "1rem" : 0,
borderBottom:
ai < recentArticles.length - 1
? "1px solid var(--color-border)"
: "none",
}}
>
<p
style={{
fontSize: "0.875rem",
fontWeight: 600,
color: "var(--color-foreground)",
lineHeight: 1.4,
marginBottom: "0.25rem",
}}
>
{article.title}
<ArrowUpRight
style={{
display: "inline",
width: 14,
height: 14,
marginLeft: 4,
verticalAlign: "middle",
color: "var(--color-accent)",
}}
/>
</p>
<span
style={{
fontSize: "0.75rem",
color: "var(--color-foreground-muted)",
}}
>
{article.date}
</span>
</a>
))}
</div>
</motion.div>
)}
</div>
{/* Bottom bar */}
<div
style={{
borderTop: "1px solid var(--color-border)",
paddingTop: "1.5rem",
textAlign: "center",
}}
>
<p style={{ fontSize: "0.75rem", color: "var(--color-foreground-muted)" }}>
{copyright}
</p>
</div>
</div>
</footer>
);
}