export type GalleryColorFamily = | "black" | "blue" | "green" | "light" | "orange" | "purple" | "red" | "yellow"; function hexToRgb(hex: string) { const normalized = hex.trim().replace(/^#/, ""); if (!/^[0-9a-f]{6}$/i.test(normalized)) { return null; } return { r: parseInt(normalized.slice(0, 2), 16), g: parseInt(normalized.slice(2, 4), 16), b: parseInt(normalized.slice(4, 6), 16), }; } export function getGalleryColorFamily( color: string | null | undefined, ): GalleryColorFamily | null { if (!color) { return null; } const rgb = hexToRgb(color); if (!rgb) { return null; } const { r, g, b } = rgb; const max = Math.max(r, g, b); const min = Math.min(r, g, b); const lightness = (max + min) / 510; if (lightness > 0.78) { return "light"; } if (lightness < 0.2) { return "black"; } const delta = max - min; if (delta < 24) { return lightness > 0.52 ? "light" : "black"; } let hue = 0; if (max === r) { hue = ((g - b) / delta) % 6; } else if (max === g) { hue = (b - r) / delta + 2; } else { hue = (r - g) / delta + 4; } hue = Math.round(hue * 60); if (hue < 0) { hue += 360; } if (hue < 18 || hue >= 345) { return "red"; } if (hue < 45) { return "orange"; } if (hue < 70) { return "yellow"; } if (hue < 170) { return "green"; } if (hue < 255) { return "blue"; } if (hue < 345) { return "purple"; } return null; }