Client-side color analysis utilities for extracting dominant colors from images and selecting accessible badge/background colors based on WCAG contrast ratios. ## Key Components ### Types & Constants - **`ColorPalette`** — Interface representing a named color with `hex` and `rgb` tuple fields. - **`DESIGN_PALETTE`** — Three-entry design system palette: `yellow`, `black`, and `gray`. ### Functions | Function | Description | |---|---| | `hexToRgb(hex)` | Converts a hex color string (with shorthand support) to an RGB tuple. | | `getContrastRatio(color1, color2)` | Returns the WCAG contrast ratio between two RGB colors. | | `pickReadableTextColor(bgHex)` | Returns `'dark'` or `'light'` based on which foreground has better contrast against the given background hex. | | `extractDominantColor(canvas)` | Samples ~1000 pixels in a grid pattern and bucket-quantizes (step 32) to find the most frequent color. | | `getBestContrastColor(imageColor)` | Picks the `DESIGN_PALETTE` entry with the highest contrast against a given RGB color; falls back to `black` if no entry meets 3:1. | | `analyzeImageColor(imageSrc)` | Loads an image via canvas (scaled to max 100px), extracts its dominant color, and resolves with the best-contrast palette entry. | | `extractImageEdgeColorAsync(imageUrl)` | Samples a 15% edge band of an image (scaled to max 50px) and returns the average dominant edge color as a hex string. Used for email/card background fills. | ## Usage Example ```typescript import { pickReadableTextColor, analyzeImageColor, extractImageEdgeColorAsync, } from './color-analysis'; // Choose a text theme for a dynamic banner background const theme = pickReadableTextColor('#FFC008'); // → 'dark' // Resolve a badge color from a product image const paletteColor = await analyzeImageColor('https://cdn.example.com/product.png'); console.log(paletteColor.name); // e.g. 'yellow' // Fill background color behind an image in an email template const edgeHex = await extractImageEdgeColorAsync('https://cdn.example.com/hero.jpg'); console.log(edgeHex); // e.g. '#1a1a1a' ``` > **Note:** `analyzeImageColor` and `extractImageEdgeColorAsync` are browser-only (they depend on `HTMLCanvasElement` and `document`). `extractImageEdgeColorAsync` returns `#000000` in SSR/Node environments.