const AVATAR_BACKGROUNDS = [ "#B9DED4", "#C6D8F0", "#D7C9ED", "#EEC8D4", "#EBCDB6", "#E4DBAB", "#CADDAD", "#ADDCDD", "#BCD0E6", "#DCC8DA", "#D9D4BF", "#C3DCCD", ] as const; /** Colores estables al normalizar mayúsculas, espacios y acentos del nombre. */ export function getInitialsAvatarAppearance(name: string) { const displayName = name.normalize("NFC").trim().replace(/\s+/gu, " "); const words = displayName.match(/[\p{L}\p{N}]+/gu) ?? []; const firstWord = words[0] ?? ""; const initials = words.length === 1 && firstWord === firstWord.toUpperCase() && firstWord !== firstWord.toLowerCase() && Array.from(firstWord).length <= 3 ? firstWord : words .slice(0, 2) .map((word) => Array.from(word)[0] ?? "") .join("") .toUpperCase(); const colorKey = displayName.normalize("NFKD").replace(/\p{M}/gu, "").toLowerCase(); let hash = 0; for (const character of colorKey) { hash = (Math.imul(hash, 31) + (character.codePointAt(0) ?? 0)) >>> 0; } return { initials: initials || "?", background: AVATAR_BACKGROUNDS[hash % AVATAR_BACKGROUNDS.length] ?? AVATAR_BACKGROUNDS[0], foreground: "#223C4B", }; }