diff --git a/src/components/MemberCard.tsx b/src/components/MemberCard.tsx index 8e299d2..cee61ec 100644 --- a/src/components/MemberCard.tsx +++ b/src/components/MemberCard.tsx @@ -21,11 +21,32 @@ const STRIPE_WARM = const STRIPE_COOL = "repeating-linear-gradient(45deg,#eef0ec,#eef0ec 12px,#e2e8e6 12px,#e2e8e6 24px)"; +/** + * Hauteurs figées des deux blocs de texte : une description longue ne doit pas + * étirer la carte (donc toute la rangée de la grille). Titre et description + * sont tronqués en fin de ligne et occupent toujours la même place, ce qui + * aligne les cartes entre elles quel que soit le texte saisi par l'adhérent. + */ +const TITLE_LINE = 1.25; +const TITLE_LINES = 2; +const DESC_FONT = 13; +const DESC_LINE = 1.5; +const DESC_LINES = 4; + +const clampLines = (lines: number) => + ({ + display: "-webkit-box", + WebkitLineClamp: lines, + WebkitBoxOrient: "vertical" as const, + overflow: "hidden", + }) as const; + /** * Carte d'un adhérent dans une grille (annuaire, page métier). Composant sans * état : il se rend aussi bien côté serveur que dans le filtre client. */ export function MemberCard({ m, index = 0 }: { m: MemberCardData; index?: number }) { + const location = [m.address, m.city].filter(Boolean).join(" · "); return (
-

+

{m.name}

-

+

{m.description}

+
- - {[m.address, m.city].filter(Boolean).join(" · ")} + + {location}