export type RgbTuple = readonly [number, number, number]; export interface AccentVariables { "--nodedc-accent-rgb": string; "--nodedc-on-accent-rgb": string; } function clampChannel(value: number): number { return Math.max(0, Math.min(255, Math.round(value))); } function linearChannel(channel: number): number { const normalized = clampChannel(channel) / 255; return normalized <= 0.04045 ? normalized / 12.92 : ((normalized + 0.055) / 1.055) ** 2.4; } export function relativeLuminance(rgb: RgbTuple): number { const [red, green, blue] = rgb.map(linearChannel) as [number, number, number]; return red * 0.2126 + green * 0.7152 + blue * 0.0722; } export function readableTextRgb(rgb: RgbTuple): RgbTuple { return relativeLuminance(rgb) > 0.46 ? [11, 17, 23] : [247, 248, 244]; } export function rgbTuple(value: RgbTuple): string { return value.map(clampChannel).join(" "); } export function createAccentVariables(accent: RgbTuple): AccentVariables { return { "--nodedc-accent-rgb": rgbTuple(accent), "--nodedc-on-accent-rgb": rgbTuple(readableTextRgb(accent)), }; }