Repository Public MIT
1import type { LucideIcon } from "lucide-react";2import type { ReactNode } from "react";3import { cn } from "@/lib/utils";45interface PageHeaderProps {6 icon?: LucideIcon;7 eyebrow?: string;8 title: ReactNode;9 description?: ReactNode;10 actions?: ReactNode;11 className?: string;12}1314/** En-tête standard des pages secondaires (Showcase, Marchés, Docs…). */15export function PageHeader({ icon: Icon, eyebrow, title, description, actions, className }: PageHeaderProps) {16 return (17 <div className={cn("flex flex-col gap-4 md:flex-row md:items-end md:justify-between", className)}>18 <div className="flex items-start gap-4 min-w-0">19 {Icon && (20 <span className="mt-0.5 grid h-11 w-11 shrink-0 place-items-center rounded-2xl bg-brand-soft text-primary ring-1 ring-primary/20">21 <Icon className="h-5 w-5" />22 </span>23 )}24 <div className="min-w-0">25 {eyebrow && <p className="mb-1 text-[11px] font-semibold uppercase tracking-[0.14em] text-primary">{eyebrow}</p>}26 <h1 className="font-display text-2xl md:text-[1.9rem] font-extrabold tracking-tight leading-tight text-balance">{title}</h1>27 {description && <p className="mt-1.5 max-w-2xl text-sm md:text-[15px] text-muted-foreground text-pretty">{description}</p>}28 </div>29 </div>30 {actions && <div className="flex shrink-0 flex-wrap items-center gap-2">{actions}</div>}31 </div>32 );33}3435export function PageContainer({ children, className, size = "lg" }: { children: ReactNode; className?: string; size?: "md" | "lg" | "xl" | "full" }) {36 const max = size === "md" ? "max-w-4xl" : size === "lg" ? "max-w-6xl" : size === "xl" ? "max-w-[88rem]" : "max-w-none";37 return <div className={cn("mx-auto w-full px-4 sm:px-6 lg:px-8 py-6 md:py-10", max, className)}>{children}</div>;38}39