b0130a66ea
Groups, Pledges, and Campaigns each shipped a different author treatment in their card footers: groups used a raw <img> with no fallback, campaigns had no avatar at all, and pledges localized the 'by X' string while the others left it as a hardcoded English literal. Extract AuthorByline as the canonical author element. It uses the shadcn Avatar primitive (initials fallback), resolves the display name through the centralized getDisplayName helper, and links to the author's profile via useProfileUrl. The 'by Name' label is sourced from the shared common.byAuthor i18n key so every surface ships the same translated string in every locale. Inside a card, the byline renders as a <button> that navigates and stops propagation so the outer card <Link> keeps wrapping the whole card without nesting <a> inside <a>. CampaignCard also picks up a localized donor count via the new common.donors plural key, replacing the inline English 'donor' / 'donors' ternary.