@wistia/kaleidoscope 0.0.4 → 0.0.5-beta.9bc2cb2b.87cc1df

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
 
2
2
  /*
3
- * @license @wistia/kaleidoscope v0.0.4
3
+ * @license @wistia/kaleidoscope v0.0.5-beta.9bc2cb2b.87cc1df
4
4
  *
5
5
  * Copyright (c) 2026, Wistia, Inc. and its affiliates.
6
6
  *
@@ -1345,4 +1345,4 @@ const getSlightAccentedBackgroundColor = (_backgroundColor, { shouldReturnWhiteF
1345
1345
  //#endregion
1346
1346
  export { getBrandLightBackgroundColor as a, ColorScale as c, Color as d, getBrandedColorScale as i, adjustColorForProperContrast as l, getHeavyAccentedBackgroundColor as n, getBrandDarkBackgroundColor as o, getColorLightnessClassification as r, getBestColorForText as s, getSlightAccentedBackgroundColor as t, colorContrastRatiosByShape as u };
1347
1347
 
1348
- //# sourceMappingURL=color-DeWiAUsP.js.map
1348
+ //# sourceMappingURL=color-CRvuCG8E.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"color-DeWiAUsP.js","names":["HEX_RADIX","WHITE","BLACK","ACHROMATIC_CHROMA","WHITE","BLACK","WHITE","ALMOST_BLACK","ALMOST_WHITE","FLARE"],"sources":["../src/private/clamp.ts","../src/private/colorSpace.ts","../src/private/parseColor.ts","../src/Color.ts","../src/colorContrastRatiosByShape.ts","../src/private/preciseContrast.ts","../src/adjustColorForProperContrast.ts","../src/ColorScale.ts","../src/getBestColorForText.ts","../src/getBrandDarkBackgroundColor.ts","../src/getBrandLightBackgroundColor.ts","../src/private/maxChroma.ts","../src/private/perceivedLightness.ts","../src/private/buildBrandedColorScale.ts","../src/getBrandedColorScale.ts","../src/getColorLightnessClassification.ts","../src/private/getAccentedBackgroundByLightness.ts","../src/private/getBackgroundAccentFromPrimaryColor.ts","../src/private/getAccentedBackground.ts","../src/getHeavyAccentedBackgroundColor.ts","../src/getSlightAccentedBackgroundColor.ts"],"sourcesContent":["/** Restrict `value` to the inclusive range between `min` and `max`. */\nexport const clamp = (value: number, min: number, max: number): number =>\n Math.min(Math.max(value, min), max);\n","// oxlint-disable id-length -- single-letter names mirror the color-space formulas\nimport type { Hsl, Lab, RgbTuple } from '../types';\nimport { clamp } from './clamp';\n\nconst D65_WHITE_POINT = { x: 0.95047, y: 1, z: 1.08883 };\n\nconst DEGREES_PER_RADIAN = 180 / Math.PI;\n\n/** Slack allowed on a linear channel before a color counts as out of gamut. */\nconst GAMUT_EPSILON = 1e-6;\n\n/** Enough halvings to place the gamut boundary well inside a single 0–255 step. */\nconst GAMUT_SEARCH_ITERATIONS = 25;\n\n// CIE standard constants: 216/24389 and 24389/27. Their product, 8, is the L* below\n// which the Lab transfer function stays linear.\nconst LAB_EPSILON = 216 / 24389;\nconst LAB_KAPPA = 24389 / 27;\nconst LAB_LINEAR_LIGHTNESS_THRESHOLD = 8;\n\n/** Gamma-decode a 0–255 sRGB channel into linear light. */\nconst linearize = (channel: number): number => {\n const normalized = channel / 255;\n return normalized <= 0.04045 ? normalized / 12.92 : ((normalized + 0.055) / 1.055) ** 2.4;\n};\n\n/**\n * Gamma-encode linear light back into a 0–255 sRGB channel. The sign is carried through\n * the exponent so that out-of-gamut Lab values produce a negative channel rather than NaN.\n * Inverse of linearize.\n */\nconst compand = (linear: number): number => {\n const magnitude = Math.abs(linear);\n const encoded =\n magnitude <= 0.0031308 ? magnitude * 12.92 : 1.055 * magnitude ** (1 / 2.4) - 0.055;\n return encoded * Math.sign(linear) * 255;\n};\n\nconst pivot = (value: number): number =>\n value > LAB_EPSILON ? Math.cbrt(value) : (LAB_KAPPA * value + 16) / 116;\n\nconst hueToChannel = (start: number, end: number, givenHue: number): number => {\n let hue = givenHue;\n if (hue < 0) {\n hue += 1;\n }\n if (hue > 1) {\n hue -= 1;\n }\n if (hue < 1 / 6) {\n return start + (end - start) * 6 * hue;\n }\n if (hue < 1 / 2) {\n return end;\n }\n if (hue < 2 / 3) {\n return start + (end - start) * (2 / 3 - hue) * 6;\n }\n return start;\n};\n\n/**\n * WCAG relative luminance (0–1).\n *\n * @see https://www.w3.org/WAI/GL/wiki/Relative_luminance\n */\nexport const relativeLuminance = (red: number, green: number, blue: number): number =>\n 0.2126 * linearize(red) + 0.7152 * linearize(green) + 0.0722 * linearize(blue);\n\nexport const rgbToHsl = (red: number, green: number, blue: number): Hsl => {\n const r = red / 255;\n const g = green / 255;\n const b = blue / 255;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const lightness = (max + min) / 2;\n const delta = max - min;\n\n if (delta === 0) {\n return { hue: 0, lightness: lightness * 100, saturation: 0 };\n }\n\n const saturation = lightness > 0.5 ? delta / (2 - max - min) : delta / (max + min);\n\n let hue: number;\n if (max === r) {\n hue = (g - b) / delta + (g < b ? 6 : 0);\n } else if (max === g) {\n hue = (b - r) / delta + 2;\n } else {\n hue = (r - g) / delta + 4;\n }\n\n return { hue: (hue / 6) * 360, lightness: lightness * 100, saturation: saturation * 100 };\n};\n\nexport const hslToRgb = ({ hue, lightness, saturation }: Hsl): RgbTuple => {\n const h = hue / 360;\n const s = saturation / 100;\n const l = lightness / 100;\n const end = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const start = 2 * l - end;\n\n return [\n hueToChannel(start, end, h + 1 / 3) * 255,\n hueToChannel(start, end, h) * 255,\n hueToChannel(start, end, h - 1 / 3) * 255,\n ];\n};\n\nexport const rgbToLab = (red: number, green: number, blue: number): Lab => {\n const r = linearize(red);\n const g = linearize(green);\n const b = linearize(blue);\n\n const x = (0.4124564 * r + 0.3575761 * g + 0.1804375 * b) / D65_WHITE_POINT.x;\n const y = (0.2126729 * r + 0.7151522 * g + 0.072175 * b) / D65_WHITE_POINT.y;\n const z = (0.0193339 * r + 0.119192 * g + 0.9503041 * b) / D65_WHITE_POINT.z;\n\n const fx = pivot(x);\n const fy = pivot(y);\n const fz = pivot(z);\n\n return { a: 500 * (fx - fy), b: 200 * (fy - fz), lightness: 116 * fy - 16 };\n};\n\n/**\n * OKLab in polar form: perceptual lightness (0–1), chroma (0 at gray, ~0.4 at the most\n * saturated sRGB colors) and hue in degrees. Unlike CIELAB, a fixed `hue` here reads as\n * one hue at every lightness — CIELAB's hue lines bend, which is why lightening a blue\n * along them walks it towards purple.\n *\n * @see https://bottosson.github.io/posts/oklab/\n */\nexport type Oklch = {\n readonly chroma: number;\n readonly hue: number;\n readonly lightness: number;\n};\n\nexport const rgbToOklch = (red: number, green: number, blue: number): Oklch => {\n const r = linearize(red);\n const g = linearize(green);\n const b = linearize(blue);\n\n const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);\n const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);\n const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);\n\n const aAxis = 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s;\n const bAxis = 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s;\n\n return {\n chroma: Math.hypot(aAxis, bAxis),\n hue: (Math.atan2(bAxis, aAxis) * DEGREES_PER_RADIAN + 360) % 360,\n lightness: 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,\n };\n};\n\n/** Linear-light sRGB, which runs 0–1 and goes outside that range when out of gamut. */\nconst oklchToLinearRgb = ({ chroma, hue, lightness }: Oklch): RgbTuple => {\n const radians = hue / DEGREES_PER_RADIAN;\n const aAxis = Math.cos(radians) * chroma;\n const bAxis = Math.sin(radians) * chroma;\n\n const l = (lightness + 0.3963377774 * aAxis + 0.2158037573 * bAxis) ** 3;\n const m = (lightness - 0.1055613458 * aAxis - 0.0638541728 * bAxis) ** 3;\n const s = (lightness - 0.0894841775 * aAxis - 1.291485548 * bAxis) ** 3;\n\n return [\n 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,\n -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,\n -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s,\n ];\n};\n\nconst fitsGamut = (oklch: Oklch): boolean =>\n oklchToLinearRgb(oklch).every(\n (channel) => channel >= -GAMUT_EPSILON && channel <= 1 + GAMUT_EPSILON,\n );\n\n/**\n * The most chroma this lightness and hue can hold inside sRGB, found by bisection. A hue\n * only gets so colorful before the gamut runs out, and that ceiling drops away sharply as\n * a color approaches white or black.\n */\nconst maximumChroma = (oklch: Oklch): number => {\n let low = 0;\n let high = oklch.chroma;\n\n for (let iteration = 0; iteration < GAMUT_SEARCH_ITERATIONS; iteration += 1) {\n const mid = (low + high) / 2;\n if (fitsGamut({ ...oklch, chroma: mid })) {\n low = mid;\n } else {\n high = mid;\n }\n }\n\n return low;\n};\n\n/**\n * Convert to sRGB, pulling chroma in until the color fits rather than clamping each\n * channel independently. Clamping is what bends the hue of an out-of-gamut color — a\n * lightened red whose red channel pins at 255 while green keeps climbing arrives at\n * yellow. Trading colorfulness for an exact hue and lightness keeps the family intact.\n */\nexport const oklchToRgb = (oklch: Oklch): RgbTuple => {\n const inGamut = fitsGamut(oklch) ? oklch : { ...oklch, chroma: maximumChroma(oklch) };\n const [red, green, blue] = oklchToLinearRgb(inGamut);\n\n return [compand(clamp(red, 0, 1)), compand(clamp(green, 0, 1)), compand(clamp(blue, 0, 1))];\n};\n\nexport const labToRgb = ({ a, b, lightness }: Lab): RgbTuple => {\n const fy = (lightness + 16) / 116;\n const fx = fy + a / 500;\n const fz = fy - b / 200;\n\n const x = (fx ** 3 > LAB_EPSILON ? fx ** 3 : (116 * fx - 16) / LAB_KAPPA) * D65_WHITE_POINT.x;\n const y =\n (lightness > LAB_LINEAR_LIGHTNESS_THRESHOLD ? fy ** 3 : lightness / LAB_KAPPA) *\n D65_WHITE_POINT.y;\n const z = (fz ** 3 > LAB_EPSILON ? fz ** 3 : (116 * fz - 16) / LAB_KAPPA) * D65_WHITE_POINT.z;\n\n return [\n compand(3.2404542 * x - 1.5371385 * y - 0.4985314 * z),\n compand(-0.969266 * x + 1.8760108 * y + 0.041556 * z),\n compand(0.0556434 * x - 0.2040259 * y + 1.0572252 * z),\n ];\n};\n","// oxlint-disable id-length -- r/g/b/a are the canonical names for color channels\nimport type { ColorInput, RgbaTuple } from '../types';\nimport { clamp } from './clamp';\n\nconst HEX_PATTERN = /^#?([\\da-f]{3,4}|[\\da-f]{6}|[\\da-f]{8})$/i;\nconst RGB_FUNCTION_PATTERN = /^rgba?\\(([^)]*)\\)$/i;\nconst NUMBER_PATTERN = /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)$/;\nconst PERCENTAGE_PATTERN = /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)%$/;\nconst SEPARATOR_PATTERN = /[\\s,]+/;\n\nconst MAX_CHANNEL = 255;\nconst HEX_RADIX = 16;\n\nconst toChannel = (value: number): number => clamp(value, 0, MAX_CHANNEL);\nconst toAlpha = (value: number): number => clamp(value, 0, 1);\n\n/**\n * Read a numeric token, where a percentage is taken as a fraction of `percentageOf`. A\n * channel is `128` or `50%` (of 255); an alpha is `0.5` or `50%` (of 1).\n */\nconst parseNumericToken = (token: string | undefined, percentageOf: number): number | null => {\n if (token === undefined) {\n return null;\n }\n if (PERCENTAGE_PATTERN.test(token)) {\n return (Number(token.slice(0, -1)) / 100) * percentageOf;\n }\n if (NUMBER_PATTERN.test(token)) {\n return Number(token);\n }\n return null;\n};\n\nconst parseChannelToken = (token: string | undefined): number | null => {\n const value = parseNumericToken(token, MAX_CHANNEL);\n return value === null ? null : toChannel(value);\n};\n\nconst parseAlphaToken = (token: string | undefined): number | null => {\n const value = parseNumericToken(token, 1);\n return value === null ? null : toAlpha(value);\n};\n\nconst parseHex = (value: string): RgbaTuple | null => {\n const match = HEX_PATTERN.exec(value);\n const digits = match?.[1];\n if (digits === undefined) {\n return null;\n }\n\n // #rgb and #rgba are shorthand for each digit repeated: #1a2 -> #11aa22\n const expanded = digits.length <= 4 ? digits.replaceAll(/./g, '$&$&') : digits;\n\n return [\n Number.parseInt(expanded.slice(0, 2), HEX_RADIX),\n Number.parseInt(expanded.slice(2, 4), HEX_RADIX),\n Number.parseInt(expanded.slice(4, 6), HEX_RADIX),\n expanded.length === 8 ? Number.parseInt(expanded.slice(6, 8), HEX_RADIX) / MAX_CHANNEL : 1,\n ];\n};\n\nconst parseRgbFunction = (value: string): RgbaTuple | null => {\n const match = RGB_FUNCTION_PATTERN.exec(value);\n const body = match?.[1];\n if (body === undefined) {\n return null;\n }\n\n // Modern syntax puts alpha behind a slash: rgb(41 73 229 / 50%)\n const [channelSource, alphaSource, ...extraSources] = body.split('/');\n if (channelSource === undefined || extraSources.length > 0) {\n return null;\n }\n\n const tokens = channelSource.trim().split(SEPARATOR_PATTERN).filter(Boolean);\n const alphaTokens = (alphaSource ?? '').trim().split(SEPARATOR_PATTERN).filter(Boolean);\n if (alphaTokens.length > 1) {\n return null;\n }\n\n const [redToken, greenToken, blueToken, legacyAlphaToken, ...extraTokens] = tokens;\n if (extraTokens.length > 0) {\n return null;\n }\n if (alphaSource !== undefined && legacyAlphaToken !== undefined) {\n return null;\n }\n\n const red = parseChannelToken(redToken);\n const green = parseChannelToken(greenToken);\n const blue = parseChannelToken(blueToken);\n if (red === null || green === null || blue === null) {\n return null;\n }\n\n const alphaToken = alphaTokens[0] ?? legacyAlphaToken;\n if (alphaToken === undefined) {\n return [red, green, blue, 1];\n }\n\n const alpha = parseAlphaToken(alphaToken);\n return alpha === null ? null : [red, green, blue, alpha];\n};\n\n/**\n * Read any supported color representation into RGBA channels, or `null` when the input\n * is not a color this package understands.\n */\nexport const parseColor = (input: ColorInput): RgbaTuple | null => {\n if (typeof input === 'string') {\n const trimmed = input.trim();\n return parseHex(trimmed) ?? parseRgbFunction(trimmed);\n }\n\n if (Array.isArray(input)) {\n const [red, green, blue, alpha = 1] = input;\n if (![red, green, blue, alpha].every((value) => Number.isFinite(value))) {\n return null;\n }\n return [toChannel(red), toChannel(green), toChannel(blue), toAlpha(alpha)];\n }\n\n const { r, g, b, a = 1 } = input;\n if (![r, g, b, a].every((value) => Number.isFinite(value))) {\n return null;\n }\n return [toChannel(r), toChannel(g), toChannel(b), toAlpha(a)];\n};\n","import type { Oklch } from './private/colorSpace';\nimport type { ColorInput, Hsl, InterpolationMode, Lab, RgbaTuple } from './types';\n// oxlint-disable id-length -- r/g/b/a are the canonical names for color channels\nimport { clamp } from './private/clamp';\nimport {\n hslToRgb,\n labToRgb,\n oklchToRgb,\n relativeLuminance,\n rgbToHsl,\n rgbToLab,\n rgbToOklch,\n} from './private/colorSpace';\nimport { parseColor } from './private/parseColor';\n\nconst HEX_RADIX = 16;\n\n/** The ends of the OKLab lightness axis: white and black. */\nconst MAX_LIGHTNESS = 1;\nconst MIN_LIGHTNESS = 0;\n\nconst DEFAULT_INTERPOLATION_MODE: InterpolationMode = 'oklch';\n\nconst WHITE = '#ffffff';\nconst BLACK = '#000000';\n\n/** Wistia brand blue (`#2949e5`) — what an unreadable input resolves to. */\nconst FALLBACK_CHANNELS: RgbaTuple = [41, 73, 229, 1];\n\nconst toHexPair = (channel: number): string =>\n Math.round(channel).toString(HEX_RADIX).padStart(2, '0');\n\n/**\n * Truncated rather than rounded, so a ratio can never climb across a WCAG threshold on\n * its way to one decimal — 4.4501 reports as 4.4, not as a passing 4.5.\n */\nconst truncateToTenth = (ratio: number): number => Math.floor(ratio * 10) / 10;\n\nconst interpolate = (from: number, to: number, ratio: number): number => from + (to - from) * ratio;\n\n/**\n * Interpolate through linear light rather than gamma-encoded sRGB, which keeps blends\n * between saturated colors from sagging through a muddy midpoint.\n */\nconst interpolateLinear = (from: number, to: number, ratio: number): number =>\n Math.sqrt(from ** 2 * (1 - ratio) + to ** 2 * ratio);\n\n/** Below this much chroma a color reads as gray, and its hue stops meaning anything. */\nconst ACHROMATIC_CHROMA = 1e-4;\n\nconst HALF_TURN = 180;\nconst FULL_TURN = 360;\n\n/**\n * Interpolate hue the short way round the wheel — blue to yellow crosses green or magenta,\n * never both. A gray has no hue of its own to offer, so it borrows the other end's rather\n * than dragging the blend through unrelated hues on the way to white or black.\n */\nconst interpolateHue = (from: Oklch, to: Oklch, ratio: number): number => {\n if (from.chroma < ACHROMATIC_CHROMA) {\n return to.hue;\n }\n if (to.chroma < ACHROMATIC_CHROMA) {\n return from.hue;\n }\n\n const difference = ((to.hue - from.hue + HALF_TURN + FULL_TURN) % FULL_TURN) - HALF_TURN;\n return from.hue + difference * ratio;\n};\n\n/**\n * An immutable sRGB color with transformation methods like lighten, darken, tint, shade.\n * Also includes methods to calculate contrast ratio against another color, relative luminance, etc.\n *\n * @example\n * ```ts\n * new Color('#2949e5').lighten(0.5).toHex(); // '#89aaff'\n * new Color('#2949e5').withAlpha(0.5).toRgba(); // 'rgba(41, 73, 229, 0.5)'\n * new Color('#2949e5').contrast('#ffffff'); // 6.6\n * ```\n */\nexport class Color {\n /**\n * Read `input` into a color, returning `null` when it cannot be parsed.\n */\n static parse(input: ColorInput): Color | null {\n const channels = parseColor(input);\n return channels === null ? null : new Color(channels);\n }\n\n static fromHsl(hsl: Hsl, alpha = 1): Color {\n const [red, green, blue] = hslToRgb(hsl);\n return new Color([red, green, blue, alpha]);\n }\n\n static fromLab(lab: Lab, alpha = 1): Color {\n const [red, green, blue] = labToRgb(lab);\n return new Color([red, green, blue, alpha]);\n }\n\n /** Red channel, 0–255. Kept unrounded so that chained operations don't accumulate error. */\n readonly r: number;\n\n /** Green channel, 0–255. Kept unrounded so that chained operations don't accumulate error. */\n readonly g: number;\n\n /** Blue channel, 0–255. Kept unrounded so that chained operations don't accumulate error. */\n readonly b: number;\n\n /** Alpha channel, 0–1. */\n readonly a: number;\n\n /**\n * @param input - any supported color representation. Input that cannot be read as a\n * color resolves to brand blue rather than failing, so a malformed value degrades to\n * a usable color instead of interrupting a render.\n */\n constructor(input: ColorInput) {\n const [red, green, blue, alpha] = parseColor(input) ?? FALLBACK_CHANNELS;\n this.r = red;\n this.g = green;\n this.b = blue;\n this.a = alpha;\n }\n\n /** `#rrggbb`. Alpha is dropped — use {@link Color.toHexWithAlpha} to keep it. */\n toHex(): string {\n return `#${toHexPair(this.r)}${toHexPair(this.g)}${toHexPair(this.b)}`;\n }\n\n /** `#rrggbbaa`. */\n toHexWithAlpha(): string {\n return `${this.toHex()}${toHexPair(this.a * 255)}`;\n }\n\n /** `rgb(41, 73, 229)`. */\n toRgb(): string {\n return `rgb(${Math.round(this.r)}, ${Math.round(this.g)}, ${Math.round(this.b)})`;\n }\n\n /** `rgba(41, 73, 229, 0.5)`. */\n toRgba(): string {\n return `rgba(${Math.round(this.r)}, ${Math.round(this.g)}, ${Math.round(this.b)}, ${this.a})`;\n }\n\n /** Rounded channels, ready to hand to another color library. */\n toRgbaTuple(): RgbaTuple {\n return [Math.round(this.r), Math.round(this.g), Math.round(this.b), this.a];\n }\n\n toHsl(): Hsl {\n return rgbToHsl(this.r, this.g, this.b);\n }\n\n toLab(): Lab {\n return rgbToLab(this.r, this.g, this.b);\n }\n\n /** Hex when fully opaque, `rgba()` otherwise, so the alpha is never silently lost. */\n toString(): string {\n return this.a === 1 ? this.toHex() : this.toRgba();\n }\n\n /**\n * WCAG relative luminance, from 0 (black) to 1 (white). Alpha is ignored — luminance\n * is only meaningful once a color has been composited onto a background.\n */\n luminance(): number {\n return relativeLuminance(this.r, this.g, this.b);\n }\n\n /**\n * WCAG contrast ratio against `other`, from 1 (identical) to 21 (black on white),\n * reported to one decimal place.\n *\n * @see {@link colorContrastRatiosByShape} for the ratio each kind of content needs\n */\n contrast(other: ColorInput): number {\n const ownLuminance = this.luminance();\n const otherLuminance = new Color(other).luminance();\n const lighter = Math.max(ownLuminance, otherLuminance);\n const darker = Math.min(ownLuminance, otherLuminance);\n return truncateToTenth((lighter + 0.05) / (darker + 0.05));\n }\n\n /**\n * Raise perceptual lightness `ratio` (0–1) of the way to white, holding the hue steady.\n *\n * The hue is held in OKLCh, so a lightened color stays recognizably itself: a blue\n * lightens to a paler blue instead of drifting purple, and a red that runs out of sRGB\n * gives up colorfulness rather than sliding towards orange. That is the difference from\n * {@link Color.tint}, which stirs white into the channels and lets the hue land where it\n * may.\n */\n lighten(ratio: number): Color {\n return this.#towardsLightness(MAX_LIGHTNESS, ratio);\n }\n\n /** Lower perceptual lightness `ratio` (0–1) of the way to black, holding the hue steady. */\n darken(ratio: number): Color {\n return this.#towardsLightness(MIN_LIGHTNESS, ratio);\n }\n\n /** Mix `ratio` (0–1) of white in. */\n tint(ratio: number, mode: InterpolationMode = DEFAULT_INTERPOLATION_MODE): Color {\n return this.blend(WHITE, ratio, mode);\n }\n\n /** Mix `ratio` (0–1) of black in. */\n shade(ratio: number, mode: InterpolationMode = DEFAULT_INTERPOLATION_MODE): Color {\n return this.blend(BLACK, ratio, mode);\n }\n\n /**\n * Mix towards `other`, where `ratio` 0 keeps this color and 1 returns `other`. Alpha is\n * always interpolated linearly, whichever `mode` the channels travel through.\n */\n blend(\n other: ColorInput,\n ratio = 0.5,\n mode: InterpolationMode = DEFAULT_INTERPOLATION_MODE,\n ): Color {\n const target = new Color(other);\n const amount = clamp(ratio, 0, 1);\n const alpha = interpolate(this.a, target.a, amount);\n\n if (mode === 'oklch') {\n const from = rgbToOklch(this.r, this.g, this.b);\n const to = rgbToOklch(target.r, target.g, target.b);\n const [red, green, blue] = oklchToRgb({\n chroma: interpolate(from.chroma, to.chroma, amount),\n hue: interpolateHue(from, to, amount),\n lightness: interpolate(from.lightness, to.lightness, amount),\n });\n\n return new Color([red, green, blue, alpha]);\n }\n\n if (mode === 'lab') {\n const from = this.toLab();\n const to = target.toLab();\n return Color.fromLab(\n {\n a: interpolate(from.a, to.a, amount),\n b: interpolate(from.b, to.b, amount),\n lightness: interpolate(from.lightness, to.lightness, amount),\n },\n alpha,\n );\n }\n\n const blendChannel = mode === 'lrgb' ? interpolateLinear : interpolate;\n return new Color([\n blendChannel(this.r, target.r, amount),\n blendChannel(this.g, target.g, amount),\n blendChannel(this.b, target.b, amount),\n alpha,\n ]);\n }\n\n /** Replace the alpha channel with `alpha` (0–1). */\n withAlpha(alpha: number): Color {\n return new Color([this.r, this.g, this.b, alpha]);\n }\n\n /**\n * Replace HSL lightness with `lightness` (0–100), leaving hue and saturation alone.\n * Use this to hit an absolute lightness; use {@link Color.lighten} to step relative to\n * where the color already is.\n */\n withLightness(lightness: number): Color {\n const { hue, saturation } = this.toHsl();\n return Color.fromHsl({ hue, lightness: clamp(lightness, 0, 100), saturation }, this.a);\n }\n\n /**\n * Travel `ratio` of the way to `target` along the OKLab lightness axis, keeping hue and\n * as much colorfulness as the sRGB gamut has room for at the lightness we arrive at.\n */\n #towardsLightness(target: number, ratio: number): Color {\n const { chroma, hue, lightness } = rgbToOklch(this.r, this.g, this.b);\n const [red, green, blue] = oklchToRgb({\n chroma,\n hue,\n lightness: interpolate(lightness, target, clamp(ratio, 0, 1)),\n });\n\n return new Color([red, green, blue, this.a]);\n }\n}\n","export const colorContrastRatiosByShape = {\n nonText: 3.0, // 3.0:1 - https://www.w3.org/TR/WCAG21/#non-text-contrast\n largeText: 3.0, // 3.0:1 - https://www.w3.org/TR/WCAG21/#contrast-minimum\n paragraphText: 4.5, // 4.5:1 - https://www.w3.org/TR/WCAG21/#contrast-minimum\n smallText: 5.5, // We're making this up, but it should be more than the paragraph text\n} as const;\n\n/** The kind of content a color has to be legible as, which sets the ratio it has to clear. */\nexport type ColorShape = keyof typeof colorContrastRatiosByShape;\n","import type { Color } from '../Color';\n\n/**\n * The WCAG contrast ratio between two colors at full precision, unlike\n * {@link Color.contrast}, which truncates to one decimal.\n *\n * Use this to compare two ratios against each other; use `Color.contrast` to decide\n * whether one clears a required ratio. Truncation is fine for the second and ruinous for\n * the first: near-identical ratios collapse to the same tenth and tie, which sends a\n * direction probe the long way round or ranks two candidates arbitrarily.\n */\nexport const preciseContrast = (color: Color, other: Color): number => {\n const ownLuminance = color.luminance();\n const otherLuminance = other.luminance();\n return (\n (Math.max(ownLuminance, otherLuminance) + 0.05) /\n (Math.min(ownLuminance, otherLuminance) + 0.05)\n );\n};\n","import type { ColorShape } from './colorContrastRatiosByShape';\nimport type { ColorInput } from './types';\nimport { Color } from './Color';\nimport { colorContrastRatiosByShape } from './colorContrastRatiosByShape';\nimport { clamp } from './private/clamp';\nimport { preciseContrast } from './private/preciseContrast';\n\nconst WHITE = '#ffffff';\nconst BLACK = '#000000';\n\n/** One HSL lightness percentage point — the step the search walks the foreground by. */\nconst LIGHTNESS_STEP = 1;\n\n/** How far to probe each way when deciding which direction gains contrast faster. */\nconst PROBE_RATIO = 0.1;\n\n/** HSL lightness bands where a color is close enough to an extreme to have nowhere to go. */\nconst NEARLY_BLACK_LIGHTNESS = 10;\nconst NEARLY_WHITE_LIGHTNESS = 80;\n\n/** Contrast of a color against itself, and the floor of the WCAG ratio. */\nconst MIN_CONTRAST = 1.0;\n\n/** The ends of the luminance range: the search has run out of room once it lands on one. */\nconst MAX_LUMINANCE = 1;\nconst MIN_LUMINANCE = 0;\n\n/**\n * Backstop on the search. Flipping direction at the extremes should always converge well\n * before this, so reaching it means something is wrong, not that the budget was tight.\n */\nconst MAX_ITERATIONS = 1000;\n\nexport type AdjustColorForProperContrastOptions = {\n /** What the foreground sits on. Never adjusted. */\n readonly backgroundColor: ColorInput;\n\n /** The color to nudge until it is legible. Returned untouched if it already is. */\n readonly foregroundColor: ColorInput;\n\n /** What the foreground is. Defaults to `paragraphText` (4.5:1). */\n readonly shape?: ColorShape;\n};\n\n/**\n * Walk `foregroundColor` towards white or black until it clears the contrast ratio\n * `shape` requires against `backgroundColor`.\n *\n * Hue is pinned for the whole walk, so the result still reads as the color you passed in\n * — a washed-out brand blue stays blue rather than drifting towards its neighbors. The\n * direction is whichever gains contrast faster, reversing if it hits an extreme with the\n * ratio still unmet. Text-grade ratios that can't be met either way settle on plain white\n * or black, since at that point nothing else beats them.\n *\n * @example\n * ```ts\n * // Already legible, so nothing moves.\n * adjustColorForProperContrast({\n * foregroundColor: '#2949e5',\n * backgroundColor: '#ffffff',\n * }).toHex(); // '#2949e5'\n *\n * // A brand blue on itself, darkened until it separates.\n * adjustColorForProperContrast({\n * foregroundColor: '#2949e5',\n * backgroundColor: '#2949e5',\n * shape: 'nonText',\n * }).toHex();\n * ```\n */\nexport const adjustColorForProperContrast = ({\n backgroundColor,\n foregroundColor,\n shape = 'paragraphText',\n}: AdjustColorForProperContrastOptions): Color => {\n const background = new Color(backgroundColor);\n const foreground = new Color(foregroundColor);\n const requiredContrast = colorContrastRatiosByShape[shape];\n\n const initialContrast = foreground.contrast(background);\n if (initialContrast >= requiredContrast) {\n return foreground;\n }\n\n const { hue, lightness: initialLightness } = foreground.toHsl();\n\n let shouldBeLighter =\n initialLightness < NEARLY_BLACK_LIGHTNESS ||\n preciseContrast(foreground.tint(PROBE_RATIO, 'rgb'), background) >\n preciseContrast(foreground.shade(PROBE_RATIO, 'rgb'), background);\n\n // A nearly-white foreground gains a sliver of contrast by lightening, but can never gain\n // enough — the only way out is down.\n if (initialLightness > NEARLY_WHITE_LIGHTNESS && initialContrast === MIN_CONTRAST) {\n shouldBeLighter = false;\n }\n\n let adjusted = foreground;\n\n for (let iteration = 0; iteration < MAX_ITERATIONS; iteration += 1) {\n if (adjusted.contrast(background) >= requiredContrast) {\n return adjusted;\n }\n\n const luminance = adjusted.luminance();\n // Out of room at white or black with the ratio still unmet. Nothing beats an extreme\n // at the stricter text ratios, so take it; the looser ones get a second pass back the\n // other way, which may land on a color truer to the original than an extreme would be.\n if (iteration > 0 && (luminance === MAX_LUMINANCE || luminance === MIN_LUMINANCE)) {\n if (requiredContrast > colorContrastRatiosByShape.nonText) {\n const white = new Color(WHITE);\n const black = new Color(BLACK);\n return white.contrast(background) > black.contrast(background) ? white : black;\n }\n\n shouldBeLighter = !shouldBeLighter;\n adjusted = foreground;\n }\n\n const { lightness, saturation } = adjusted.toHsl();\n const stepped = Color.fromHsl(\n {\n hue,\n lightness: clamp(lightness + (shouldBeLighter ? LIGHTNESS_STEP : -LIGHTNESS_STEP), 0, 100),\n saturation,\n },\n adjusted.a,\n );\n\n // Snap to the 8-bit color the caller will actually render. Color keeps channels\n // unrounded, so measuring contrast on them can clear the ratio by a hair that\n // rounding to hex then gives back, handing back a color that doesn't actually pass the required contrast.\n adjusted = new Color(stepped.toRgbaTuple());\n }\n\n // Never converged. Hand back the closest we got rather than interrupting a render.\n return adjusted;\n};\n","import type { ColorInput, InterpolationMode } from './types';\nimport { Color } from './Color';\nimport { clamp } from './private/clamp';\n\ntype Stop = {\n readonly color: Color;\n readonly position: number;\n};\n\nconst DEFAULT_DOMAIN: [number, number] = [0, 1];\nconst DEFAULT_MODE: InterpolationMode = 'lrgb';\nconst DEFAULT_PADDING: [number, number] = [0, 0];\n\n/** Ceiling on the binary search in `correctLightness` */\nconst MAX_LIGHTNESS_ITERATIONS = 20;\nconst LIGHTNESS_TOLERANCE = 0.01;\n\nexport type ColorScaleOptions = {\n /**\n * Quantize the scale into bands instead of leaving it continuous: a count of equally sized\n * classes across the domain, or explicit class breaks.\n */\n readonly classes?: number | number[];\n\n /**\n * Redistribute stops so that perceived lightness moves evenly from end to end. Worth\n * turning on for any scale a reader is meant to rank by eye.\n */\n readonly correctLightness?: boolean;\n\n /**\n * The input range, `[0, 1]` by default. Two values set the ends; supply one value per\n * color to pin each color to a position, or more than two to warp the scale.\n */\n readonly domain?: number[];\n\n /** Bias the scale towards one end. Above 1 favors the start, below 1 the end. */\n readonly gamma?: number;\n\n /** The color space blends travel through. */\n readonly mode?: InterpolationMode;\n\n /** Trim `[start, end]` fractions off the scale, dropping its most extreme colors. */\n readonly padding?: [number, number] | number;\n};\n\nconst toPaddingPair = (padding: ColorScaleOptions['padding']): [number, number] => {\n const pair: [number, number] =\n typeof padding === 'number' ? [padding, padding] : (padding ?? DEFAULT_PADDING);\n return [clamp(pair[0], 0, 1), clamp(pair[1], 0, 1)];\n};\n\nconst toClassBreaks = (\n classes: ColorScaleOptions['classes'],\n min: number,\n max: number,\n): number[] | null => {\n if (classes === undefined) {\n return null;\n }\n if (Array.isArray(classes)) {\n return classes.length === 0 ? null : classes;\n }\n if (classes < 1) {\n return [min, max];\n }\n return Array.from({ length: classes + 1 }, (_, index) => min + (index / classes) * (max - min));\n};\n\n/** The index of the class `value` falls into, or -1 when it sits below the first break. */\nconst toClassIndex = (value: number, breaks: number[]): number => {\n let index = 0;\n while (index < breaks.length - 1 && value >= (breaks[index] ?? Number.POSITIVE_INFINITY)) {\n index += 1;\n }\n return index - 1;\n};\n\n/**\n * A continuous scale between two or more colors — the chroma.js `scale` model, as an\n * immutable class. Every configuration method returns a new scale, so a configured scale\n * is safe to hold onto and share.\n *\n * @example\n * ```ts\n * const scale = new ColorScale(['#2949e5', '#ffffff']);\n * scale.at(0.5).toHex(); // the midpoint color\n * scale.colors(5).map((color) => color.toHex()); // five evenly spaced colors\n * scale.correctLightness().domain([0, 100]).at(72); // perceptually even, read in %\n * ```\n */\nexport class ColorScale {\n readonly #classBreaks: number[] | null;\n readonly #colors: [Color, ...Color[]];\n readonly #correctLightness: boolean;\n readonly #domainBreaks: number[] | null;\n readonly #domainOutputs: number[] | null;\n readonly #gamma: number;\n readonly #max: number;\n readonly #min: number;\n readonly #mode: InterpolationMode;\n readonly #options: ColorScaleOptions;\n readonly #padding: [number, number];\n readonly #sampleRange: [number, number];\n readonly #stops: [Stop, ...Stop[]];\n\n /**\n * @param colors - the colors the scale runs through; a single color makes a flat scale\n * @throws {TypeError} when `colors` is empty or `domain` has fewer than two values\n */\n constructor(colors: readonly ColorInput[], options: ColorScaleOptions = {}) {\n const [firstColor, ...remainingColors] = colors.map((color) => new Color(color));\n if (firstColor === undefined) {\n throw new TypeError('A color scale needs at least one color.');\n }\n\n // A lone color still has to interpolate against something, so it becomes both ends.\n this.#colors =\n remainingColors.length === 0 ? [firstColor, firstColor] : [firstColor, ...remainingColors];\n this.#options = options;\n this.#mode = options.mode ?? DEFAULT_MODE;\n this.#gamma = options.gamma ?? 1;\n this.#padding = toPaddingPair(options.padding);\n this.#correctLightness = options.correctLightness ?? false;\n\n const domain = options.domain ?? DEFAULT_DOMAIN;\n const min = domain[0];\n const max = domain.at(-1);\n if (min === undefined || max === undefined || domain.length < 2) {\n throw new TypeError('A color scale domain needs at least two values.');\n }\n this.#min = min;\n this.#max = max;\n\n const count = this.#colors.length;\n let positions: number[];\n let domainBreaks: number[] | null = null;\n let domainOutputs: number[] | null = null;\n\n if (domain.length === count && min !== max) {\n // One domain value per color pins each color to its own position.\n positions = domain.map((value) => (value - min) / (max - min));\n } else {\n positions = this.#colors.map((_, index) => index / (count - 1));\n\n if (domain.length > 2 && min !== max) {\n const breaks = domain.map((value) => (value - min) / (max - min));\n const outputs = domain.map((_, index) => index / (domain.length - 1));\n // Only warp the scale when the intermediate values aren't already evenly spaced.\n if (!breaks.every((value, index) => outputs[index] === value)) {\n domainBreaks = breaks;\n domainOutputs = outputs;\n }\n }\n }\n\n this.#domainBreaks = domainBreaks;\n this.#domainOutputs = domainOutputs;\n\n const [firstStopColor, ...remainingStopColors] = this.#colors;\n this.#stops = [\n { color: firstStopColor, position: positions[0] ?? 0 },\n ...remainingStopColors.map((color, index) => ({\n color,\n position: positions[index + 1] ?? 1,\n })),\n ];\n\n this.#classBreaks = toClassBreaks(options.classes, min, max);\n const firstBreak = this.#classBreaks?.[0];\n const lastBreak = this.#classBreaks?.at(-1);\n this.#sampleRange =\n firstBreak === undefined || lastBreak === undefined ? [min, max] : [firstBreak, lastBreak];\n }\n\n /** The color at `value`, read through the scale's domain, classes, gamma and padding. */\n at(value: number): Color {\n if (!Number.isFinite(value)) {\n throw new TypeError(`A color scale cannot be sampled at ${String(value)}.`);\n }\n return this.#colorAt(value, false);\n }\n\n /** `count` colors spread evenly across the domain. */\n colors(count: number): Color[] {\n if (!Number.isInteger(count) || count < 0) {\n throw new TypeError(`A color scale cannot produce ${String(count)} colors.`);\n }\n if (count === 0) {\n return [];\n }\n\n const [start, end] = this.#sampleRange;\n if (count === 1) {\n return [this.at(start + (end - start) / 2)];\n }\n\n const span = end - start;\n return Array.from({ length: count }, (_, index) =>\n this.at(start + (index / (count - 1)) * span),\n );\n }\n\n mode(mode: InterpolationMode): ColorScale {\n return this.#withOptions({ mode });\n }\n\n domain(domain: number[]): ColorScale {\n return this.#withOptions({ domain });\n }\n\n gamma(gamma: number): ColorScale {\n return this.#withOptions({ gamma });\n }\n\n padding(padding: [number, number] | number): ColorScale {\n return this.#withOptions({ padding });\n }\n\n correctLightness(correctLightness = true): ColorScale {\n return this.#withOptions({ correctLightness });\n }\n\n classes(classes: number | number[]): ColorScale {\n return this.#withOptions({ classes });\n }\n\n #withOptions(overrides: ColorScaleOptions): ColorScale {\n return new ColorScale(this.#colors, { ...this.#options, ...overrides });\n }\n\n #colorAt(value: number, bypassValueMapping: boolean): Color {\n let position = clamp(\n this.#mapDomain(bypassValueMapping ? value : this.#toPosition(value)),\n 0,\n 1,\n );\n\n if (!bypassValueMapping && this.#correctLightness) {\n position = this.#correctPosition(position);\n }\n\n if (this.#gamma !== 1) {\n position **= this.#gamma;\n }\n\n const [paddingStart, paddingEnd] = this.#padding;\n position = paddingStart + position * (1 - paddingStart - paddingEnd);\n\n return this.#interpolateAt(clamp(position, 0, 1));\n }\n\n /** Map a domain value onto the scale's unpadded 0–1 range. */\n #toPosition(value: number): number {\n const breaks = this.#classBreaks;\n if (breaks !== null && breaks.length > 2) {\n return toClassIndex(value, breaks) / (breaks.length - 2);\n }\n if (this.#max === this.#min) {\n return 1;\n }\n return (value - this.#min) / (this.#max - this.#min);\n }\n\n /** Warp the scale so that intermediate domain values land where the caller placed them. */\n #mapDomain(position: number): number {\n const breaks = this.#domainBreaks;\n const outputs = this.#domainOutputs;\n if (breaks === null || outputs === null || position <= 0 || position >= 1) {\n return position;\n }\n\n let index = 0;\n while (index < breaks.length - 2 && position >= (breaks[index + 1] ?? 1)) {\n index += 1;\n }\n\n const start = breaks[index] ?? 0;\n const end = breaks[index + 1] ?? 1;\n const outputStart = outputs[index] ?? 0;\n const outputEnd = outputs[index + 1] ?? 1;\n if (end === start) {\n return outputStart;\n }\n return outputStart + ((position - start) / (end - start)) * (outputEnd - outputStart);\n }\n\n /**\n * Nudge `position` until the color there carries the Lab lightness an evenly lit scale\n * would have, by bisecting between the ends.\n */\n #correctPosition(position: number): number {\n const startLightness = this.#colorAt(0, true).toLab().lightness;\n const endLightness = this.#colorAt(1, true).toLab().lightness;\n const isDescending = startLightness > endLightness;\n const idealLightness = startLightness + (endLightness - startLightness) * position;\n\n let low = 0;\n let high = 1;\n let corrected = position;\n let difference = this.#colorAt(corrected, true).toLab().lightness - idealLightness;\n\n for (\n let iteration = 0;\n iteration < MAX_LIGHTNESS_ITERATIONS && Math.abs(difference) > LIGHTNESS_TOLERANCE;\n iteration += 1\n ) {\n // Already lighter than ideal: search the darker half, and vice versa.\n if (isDescending === difference < 0) {\n high = corrected;\n corrected += (low - corrected) / 2;\n } else {\n low = corrected;\n corrected += (high - corrected) / 2;\n }\n difference = this.#colorAt(corrected, true).toLab().lightness - idealLightness;\n }\n\n return corrected;\n }\n\n #interpolateAt(position: number): Color {\n const stops = this.#stops;\n\n for (const [index, stop] of stops.entries()) {\n if (position <= stop.position) {\n return stop.color;\n }\n\n const next = stops[index + 1];\n if (next === undefined) {\n return stop.color;\n }\n\n if (position < next.position) {\n const ratio = (position - stop.position) / (next.position - stop.position);\n return stop.color.blend(next.color, ratio, this.#mode);\n }\n }\n\n return stops[0].color;\n }\n}\n","import type { ColorShape } from './colorContrastRatiosByShape';\nimport type { ColorInput } from './types';\nimport { Color } from './Color';\nimport { colorContrastRatiosByShape } from './colorContrastRatiosByShape';\nimport { preciseContrast } from './private/preciseContrast';\n\nconst WHITE = '#ffffff';\nconst BLACK = '#000000';\n\nexport type BestColorForTextOptions = {\n /** Always excluded from the result.*/\n readonly backgroundColor: ColorInput;\n\n /**\n * Colors that are part of the palette but should not be considered as candidates.\n * Useful in scenarios like the webinar pages color derivation logic, where we might include derived colors\n * in the palette used by some fields, like `lowEmphasisTextColor`, but we want to exclude the derived colors\n * from other fields, like `mainTextColor`.\n */\n readonly exclude?: readonly ColorInput[];\n\n /**\n * The colors to choose from. Black and white are included automatically, so an empty/absent palette\n * still yields whichever of the two has best contrast against `backgroundColor`.\n */\n readonly palette?: readonly ColorInput[];\n\n /** The type of text/shape that will use the resulting color. Defaults to `paragraphText` (4.5:1). */\n readonly shape?: ColorShape;\n};\n\n/**\n * Picks a color most suitable for a given text (or non-text) shape against the given background color.\n * Accepts an optional color palette, but white and black are always included as options in addition to the palette.\n * Also accepts a set of colors from the palette that should be excluded from consideration.\n *\n * @example\n * ```ts\n * getBestColorForText({ backgroundColor: '#2949e5' }).toHex(); // '#ffffff'\n * ```\n */\nexport const getBestColorForText = ({\n backgroundColor,\n exclude = [],\n palette = [],\n shape = 'paragraphText',\n}: BestColorForTextOptions): Color => {\n const background = new Color(backgroundColor);\n const requiredContrast = colorContrastRatiosByShape[shape];\n\n const excluded = new Set(\n // Always exclude the background color in addition to the colorsToExclude\n [...exclude, background]\n .map((color) => new Color(color).toHex())\n // If one of the excluded colors is black or white, don't exclude it.\n // We always need black and white as potential text color options.\n .filter((hex) => hex !== WHITE && hex !== BLACK),\n );\n\n const candidates = [\n ...new Map(\n [WHITE, BLACK, ...palette].map((color) => {\n const candidate = new Color(color);\n return [candidate.toHex(), candidate];\n }),\n ).values(),\n ].filter((color) => !excluded.has(color.toHex()));\n\n const white = new Color(WHITE);\n const black = new Color(BLACK);\n\n // Rank candidates in order of least contrast first, otherwise we would always return either black or white.\n const ranked = candidates\n .map((color) => ({ color, ratio: preciseContrast(color, background) }))\n .toSorted((one, two) => one.ratio - two.ratio);\n\n // Which side of the background text belongs on: light text on a dark background, dark\n // text on a light one. Settled by measuring both extremes rather than by a lightness\n // threshold, so the crossover falls where contrast actually flips, near luminance 0.18.\n //\n // Worth preferring because the WCAG ratio is symmetric and cannot say that dark-on-dark\n // and light-on-dark read differently at the same number. Without this, a background\n // around luminance 0.12 takes black at 3.3:1 — enough to clear largeText, and murky to\n // read — over a light candidate that costs nothing.\n\n // Optically, should the text be lighter or darker than the background?\n const prefersLighterText =\n preciseContrast(white, background) > preciseContrast(black, background);\n const backgroundLuminance = background.luminance();\n const isPreferredSide = (color: Color): boolean =>\n prefersLighterText\n ? color.luminance() >= backgroundLuminance\n : color.luminance() <= backgroundLuminance;\n\n const passing = ranked.filter(({ color }) => color.contrast(background) >= requiredContrast);\n\n // The least-contrasting passing candidate on the preferred side. There is always one\n // when anything passes at all: the preferred side is the one whose extreme contrasts\n // more, and both extremes are always in the pool. So falling through means nothing\n // cleared the ratio, and the most contrast on offer is that same extreme.\n return (\n passing.find(({ color }) => isPreferredSide(color))?.color ??\n (prefersLighterText ? white : black)\n );\n};\n","import type { ColorInput } from './types';\nimport { Color } from './Color';\n\nconst MAX_PAGE_SATURATION = 50;\n\nconst ALMOST_BLACK = 5;\nconst ALMOST_WHITE = 95;\nconst DESIRED_BACKGROUND_LIGHTNESS = 18;\nconst MINIMUM_CONTRAST_BETWEEN_PRIMARY_AND_BACKGROUND = 1.5;\nconst SEARCH_INCREMENT = 0.5;\n\nconst constructColorWithNewSaturationAndLightness = (\n primaryColor: Color,\n saturation: number,\n lightness: number,\n): Color => Color.fromHsl({ hue: primaryColor.toHsl().hue, lightness, saturation }, primaryColor.a);\n\n/**\n * Generates a dark background color from a given primary color, preserving the hue of the primary color.\n *\n * @example\n * ```ts\n * getBrandDarkBackgroundColor('#2949e5').toHex(); // '#242942'\n * ```\n *\n * @see {@link getBrandLightBackgroundColor} for the light counterpart\n */\nexport const getBrandDarkBackgroundColor = (_primaryColor: ColorInput): Color => {\n const primaryColor = new Color(_primaryColor);\n const { lightness: brandLightness, saturation } = primaryColor.toHsl();\n\n // If the color is close to black or white, zero out the saturation so\n // we end up with gray instead of red\n const hasNoUsableHue = brandLightness < ALMOST_BLACK || brandLightness > ALMOST_WHITE;\n const pageSaturation = hasNoUsableHue ? 0 : Math.min(MAX_PAGE_SATURATION, saturation);\n\n const initialBackgroundColorOption = constructColorWithNewSaturationAndLightness(\n primaryColor,\n pageSaturation,\n DESIRED_BACKGROUND_LIGHTNESS,\n );\n\n // If the initial background color option meets our desired contrast, just use it.\n if (\n initialBackgroundColorOption.contrast(primaryColor) >=\n MINIMUM_CONTRAST_BETWEEN_PRIMARY_AND_BACKGROUND\n ) {\n return initialBackgroundColorOption;\n }\n\n // Otherwise if the initial background color option did not have the desired contrast,\n // tweak the lightness until we get a color that does meet the desired contrast.\n // Return black if we run out of options.\n let backgroundColorWithIncreasedContrast = initialBackgroundColorOption;\n for (\n let pageLightness = DESIRED_BACKGROUND_LIGHTNESS;\n pageLightness >= 0;\n pageLightness -= SEARCH_INCREMENT\n ) {\n const candidate = constructColorWithNewSaturationAndLightness(\n primaryColor,\n pageSaturation,\n pageLightness,\n );\n if (\n candidate.contrast(primaryColor) > backgroundColorWithIncreasedContrast.contrast(primaryColor)\n ) {\n backgroundColorWithIncreasedContrast = candidate;\n }\n if (\n backgroundColorWithIncreasedContrast.contrast(primaryColor) >=\n MINIMUM_CONTRAST_BETWEEN_PRIMARY_AND_BACKGROUND\n ) {\n break;\n }\n }\n\n return backgroundColorWithIncreasedContrast;\n};\n","import type { ColorInput } from './types';\nimport { Color } from './Color';\n\n/** Enough saturation for the brand hue to register, for a primary that has barely any. */\nconst MIN_SATURATION = 5;\n\n/** HSL lightness bands where a primary is close enough to an extreme to have no usable hue. */\nconst ALMOST_BLACK = 5;\nconst ALMOST_WHITE = 95;\n\n/**\n *\n * Generates a light background color from a given primary color, preserving the hue of the primary color.\n *\n * @example\n * ```ts\n * getBrandLightBackgroundColor('#2949e5').toHex(); // '#ebeefd'\n * ```\n *\n * @see {@link getBrandDarkBackgroundColor} for the dark counterpart\n */\nexport const getBrandLightBackgroundColor = (_primaryColor: ColorInput): Color => {\n const primaryColor = new Color(_primaryColor);\n const { lightness, saturation } = primaryColor.toHsl();\n\n // If the new color is close to black or white, zero out the saturation so\n // we end up with gray instead of pink\n const hasNoHue = saturation === 0 || lightness < ALMOST_BLACK || lightness > ALMOST_WHITE;\n const targetSaturation = hasNoHue ? 0 : Math.max(MIN_SATURATION, saturation);\n\n // Make the current color *almost* white and then darken it just a bit\n // to get a nice looking light background color based on the primary color\n const derived = primaryColor.tint(0.95, 'rgb').shade(0.02, 'rgb');\n\n return Color.fromHsl({ ...derived.toHsl(), saturation: targetSaturation }, derived.a);\n};\n","import { oklchToRgb, rgbToOklch } from './colorSpace';\n\n/**\n * Below this a color has no perceptible hue.\n */\nexport const ACHROMATIC_CHROMA = 1e-4;\n\n/**\n * More chroma than sRGB holds anywhere. The widest point is magenta at 0.32\n */\nconst UNREACHABLE_CHROMA = 0.5;\n\n/**\n * The most chroma sRGB can hold at the given lightness and hue.\n *\n * Read from {@link oklchToRgb}, which already clamps by max chroma so that we don't have to\n * re-implement searching for max possible chroma.\n */\nexport const maxChroma = (lightness: number, hue: number): number => {\n const [red, green, blue] = oklchToRgb({ chroma: UNREACHABLE_CHROMA, hue, lightness });\n\n return rgbToOklch(red, green, blue).chroma;\n};\n","import type { Color } from '../Color';\n\n/**\n * Flare is the ambient light reflecting off a screen, as defined by WCAG guidelines.\n * See https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum\n */\nconst FLARE = 0.05;\nconst FLOOR = Math.cbrt(FLARE);\nconst SPAN = Math.cbrt(1 + FLARE) - FLOOR;\n\n/**\n * Get the perceived lightness of a color, with ambient lighting factored in according\n * to WCAG guidelines.\n */\nexport const perceivedLightness = (color: Color): number =>\n (Math.cbrt(color.luminance() + FLARE) - FLOOR) / SPAN;\n","import { Color } from '../Color';\nimport { ColorScale } from '../ColorScale';\nimport { getBrandDarkBackgroundColor } from '../getBrandDarkBackgroundColor';\nimport { getBrandLightBackgroundColor } from '../getBrandLightBackgroundColor';\nimport { clamp } from './clamp';\nimport { oklchToRgb, rgbToOklch } from './colorSpace';\nimport { ACHROMATIC_CHROMA, maxChroma } from './maxChroma';\nimport { perceivedLightness } from './perceivedLightness';\n\nexport const DEFAULT_COLOR_SCALE_STEPS = 12;\n\n/**\n * Using the primary color, derive the light/dark variants of the background color,\n * and use these three colors as all the fixed stops on the scale.\n * Including the primary color in addition to the two background extremes allows the scale\n * to maintain the vibrancy of the primary color.\n * Sort stops by luminance, just in case.\n */\nconst brandScaleStops = (primary: Color): Color[] => {\n const stops = [\n getBrandLightBackgroundColor(primary),\n primary,\n getBrandDarkBackgroundColor(primary),\n ];\n\n return stops.toSorted((one, two) => two.luminance() - one.luminance());\n};\n\nconst ARC_SAMPLES = 128;\n\nconst DEGREES_TO_RADIANS = Math.PI / 180;\n\n/**\n * How far apart two colors look: perceived lightness versus OKLab's chroma.\n *\n * We use perceptual distance rather than a lightness calculation because the color scale\n * can cover a lot of ground without changing lightness significantly. Between an almost white color\n * and a light yellow there is not much lightness difference, but there is actually enough\n * \"distance\" between the colors to perceive more than one step between them.\n *\n * Contrast ratio does not matter significantly here because these are background colors.\n */\nconst perceptualDistance = (one: Color, two: Color): number => {\n const from = rgbToOklch(one.r, one.g, one.b);\n const to = rgbToOklch(two.r, two.g, two.b);\n\n return Math.hypot(\n perceivedLightness(one) - perceivedLightness(two),\n from.chroma * Math.cos(from.hue * DEGREES_TO_RADIANS) -\n to.chroma * Math.cos(to.hue * DEGREES_TO_RADIANS),\n from.chroma * Math.sin(from.hue * DEGREES_TO_RADIANS) -\n to.chroma * Math.sin(to.hue * DEGREES_TO_RADIANS),\n );\n};\n\n/**\n * Maps between a position on the scale and how far along its length that position sits.\n */\nconst arcLength = (colorAt: (position: number) => Color) => {\n const points = Array.from({ length: ARC_SAMPLES + 1 }, (_, index) =>\n colorAt(index / ARC_SAMPLES),\n );\n const travelled = [0];\n for (let index = 1; index <= ARC_SAMPLES; index += 1) {\n const from = points[index - 1];\n const to = points[index];\n const step = from === undefined || to === undefined ? 0 : perceptualDistance(from, to);\n\n travelled.push((travelled[index - 1] ?? 0) + step);\n }\n const total = travelled.at(-1) ?? 0;\n\n return {\n distanceOf: (position: number): number => {\n if (total === 0) {\n return position;\n }\n const scaled = clamp(position, 0, 1) * ARC_SAMPLES;\n const lower = Math.min(Math.floor(scaled), ARC_SAMPLES - 1);\n const within = scaled - lower;\n const from = travelled[lower] ?? 0;\n const to = travelled[lower + 1] ?? total;\n\n return (from + (to - from) * within) / total;\n },\n positionAt: (distance: number): number => {\n if (total === 0) {\n return distance;\n }\n const target = clamp(distance, 0, 1) * total;\n for (let index = 1; index <= ARC_SAMPLES; index += 1) {\n const to = travelled[index] ?? total;\n if (to >= target) {\n const from = travelled[index - 1] ?? 0;\n const span = to - from;\n\n return (index - 1 + (span === 0 ? 0 : (target - from) / span)) / ARC_SAMPLES;\n }\n }\n\n return 1;\n },\n };\n};\n\nexport type BrandScaleOptions = {\n /** How many steps the scale is divided into. */\n readonly steps?: number;\n};\n\n// Where `color` falls on the color scale, as a position from 0–1.\nexport const positionOnScale = (scale: ColorScale, color: Color): number => {\n const target = color.luminance();\n let low = 0;\n let high = 1;\n\n for (let iteration = 0; iteration < 30; iteration += 1) {\n const middle = (low + high) / 2;\n if (scale.at(middle).luminance() > target) {\n low = middle;\n } else {\n high = middle;\n }\n }\n\n return (low + high) / 2;\n};\n\n/**\n * How colorful a color is as a share of the most sRGB allows at its lightness and hue.\n * 0 for a gray, 1 for a color that maxes out lightness/saturation.\n */\nconst gamutFraction = (color: Color): number => {\n const { chroma, hue, lightness } = rgbToOklch(color.r, color.g, color.b);\n const available = maxChroma(lightness, hue);\n\n return chroma < ACHROMATIC_CHROMA || available < ACHROMATIC_CHROMA\n ? 0\n : Math.min(1, chroma / available);\n};\n\ntype Anchor = {\n readonly fraction: number;\n readonly position: number;\n};\n\n/**\n * What fraction of the color gamut is represented by a given position\n */\nconst fractionAt = (anchors: readonly Anchor[], position: number): number => {\n const first = anchors.at(0);\n const last = anchors.at(-1);\n if (first === undefined || last === undefined) {\n return 0;\n }\n if (position <= first.position) {\n return first.fraction;\n }\n\n for (let index = 1; index < anchors.length; index += 1) {\n const previous = anchors[index - 1];\n const next = anchors[index];\n if (previous === undefined || next === undefined) {\n break;\n }\n if (position <= next.position) {\n const span = next.position - previous.position;\n const ratio = span === 0 ? 0 : (position - previous.position) / span;\n\n return previous.fraction + (next.fraction - previous.fraction) * ratio;\n }\n }\n\n return last.fraction;\n};\n\nexport type BrandedColorScale = {\n /** The color at a given position (0 - 1), from the scale. */\n readonly at: (position: number) => Color;\n /** The color at step `index` */\n readonly atStep: (index: number) => Color;\n readonly positionOf: (color: Color) => number;\n /** The step where the primary color falls. */\n readonly primaryStep: number;\n /** Where a given color falls, as a step index — fractional when it sits between two. */\n readonly stepOf: (color: Color) => number;\n readonly steps: number;\n};\n\n/**\n * Builds a color scale using the derived light/dark background colors based on the given primary color,\n * with the primary color slotted into the scale wherever it fits based on lightness.\n *\n * It's important to include the primary color in the scale because the light/dark derived background colors\n * do not have the same saturation as the primary color, and we want the scale to reflect the vibrancy\n * of the primary color.\n */\nexport const buildBrandedColorScale = (\n primary: Color,\n options: BrandScaleOptions = {},\n): BrandedColorScale => {\n const { steps = DEFAULT_COLOR_SCALE_STEPS } = options;\n const scale = new ColorScale(brandScaleStops(primary), { mode: 'oklch' });\n const stops = brandScaleStops(primary);\n const anchors = stops\n .map((stop) => ({ fraction: gamutFraction(stop), position: positionOnScale(scale, stop) }))\n .toSorted((one, two) => one.position - two.position);\n\n const colorAt = (position: number): Color => {\n const base = scale.at(position);\n const { hue, lightness } = rgbToOklch(base.r, base.g, base.b);\n const [red, green, blue] = oklchToRgb({\n chroma: fractionAt(anchors, position) * maxChroma(lightness, hue),\n hue,\n lightness,\n });\n\n return new Color([red, green, blue, base.a]);\n };\n\n const measured = arcLength(colorAt);\n\n const at = (distance: number): Color => colorAt(measured.positionAt(distance));\n const distanceOf = (color: Color): number => measured.distanceOf(positionOnScale(scale, color));\n\n const last = Math.max(0, steps - 1);\n const primaryDistance = distanceOf(primary);\n\n // The primary step should almost never be placed into either end of the scale.\n // This will only occur for primary colors that are truly extreme, like black or white.\n const ownsFirst = stops.at(0)?.toHex() === primary.toHex();\n const ownsLast = stops.at(-1)?.toHex() === primary.toHex();\n const lowest = ownsFirst ? 0 : Math.min(1, last);\n const highest = ownsLast ? last : Math.max(lowest, last - 1);\n const primaryStep = clamp(Math.round(primaryDistance * last), lowest, highest);\n\n const distanceOfStep = (index: number): number => {\n if (index === primaryStep) {\n return primaryDistance;\n }\n if (index < primaryStep) {\n return (index / primaryStep) * primaryDistance;\n }\n\n return primaryDistance + ((index - primaryStep) / (last - primaryStep)) * (1 - primaryDistance);\n };\n\n return {\n at,\n atStep: (index) => (index === primaryStep ? primary : at(distanceOfStep(index))),\n positionOf: distanceOf,\n primaryStep,\n stepOf: (color) => {\n const found = distanceOf(color);\n if (found <= primaryDistance) {\n return primaryDistance === 0 ? 0 : (found / primaryDistance) * primaryStep;\n }\n\n return (\n primaryStep + ((found - primaryDistance) / (1 - primaryDistance)) * (last - primaryStep)\n );\n },\n steps,\n };\n};\n","import type { ColorInput } from './types';\nimport { Color } from './Color';\nimport {\n buildBrandedColorScale,\n DEFAULT_COLOR_SCALE_STEPS,\n} from './private/buildBrandedColorScale';\n\nexport type BrandColorScaleOptions = {\n /** How many steps the scale is divided into. */\n readonly steps?: number;\n};\n\n/**\n * Builds a color scale using the derived light/dark background colors based on the given primary color,\n * with the primary color slotted into the scale wherever it fits based on lightness.\n *\n * It's important to include the primary color in the scale because the light/dark derived background colors\n * do not have the same saturation as the primary color, and we want the scale to reflect the vibrancy\n * of the primary color.\n *\n * @example\n * ```ts\n * getBrandedColorScale('#2949e5').map((color) => color.toHex());\n * // ['#ebeefd', '#d4dbfa', '#bdc8f7', '#a5b5f4', '#8da2f1', '#748eef',\n * // '#5b7aec', '#4263e8', '#2949e5', '#2539ba', '#213080', '#171f45']\n * // ^ the primary, at its own lightness\n * ```\n */\nexport const getBrandedColorScale = (\n primaryColor: ColorInput,\n { steps = DEFAULT_COLOR_SCALE_STEPS }: BrandColorScaleOptions = {},\n): Color[] => {\n const scale = buildBrandedColorScale(new Color(primaryColor), { steps });\n\n return Array.from({ length: steps }, (_, index) => scale.atStep(index));\n};\n","import type { ColorInput } from './types';\nimport { Color } from './Color';\n\nexport type ColorLightnessClassification = 'dark' | 'light' | 'midtone' | 'veryDark';\n\n/**\n * The WCAG value for typical ambient light causing flare on a screen\n * https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum\n */\nconst FLARE = 0.05;\n\n/**\n * Below this a background is close enough to black that there is no more visual\n * room to darken the color without reading as black.\n */\nconst VERY_DARK_MAX = 0.05;\n\n/**\n * This number represents the crossover where white stops having more contrast than black,\n * so any values with luminance greater than this value are no longer considered \"dark\".\n *\n * Don't round this number, otherwise we'll potentially classify some backgrounds as \"midtone\"\n * even though light content reads better on them, and we should always have light content on dark backgrounds.\n */\nconst DARK_MAX = Math.sqrt(FLARE * (1 + FLARE)) - FLARE;\n\n/** Above this a background is close enough to white that it needs no lightening at all. */\nconst LIGHT_MIN = 0.8;\n\n/**\n * Classify a color's lightness based on relative luminance.\n *\n * @example\n * ```ts\n * getColorLightnessClassification('#000000'); // 'veryDark'\n * getColorLightnessClassification('#2949e5'); // 'dark'\n * getColorLightnessClassification('#7f7f7f'); // 'midtone'\n * getColorLightnessClassification('#ffffff'); // 'light'\n * ```\n */\nexport const getColorLightnessClassification = (\n color: ColorInput,\n): ColorLightnessClassification => {\n const parsed = new Color(color);\n const luminance = parsed.luminance();\n\n if (luminance < VERY_DARK_MAX) {\n return 'veryDark';\n }\n if (luminance < DARK_MAX) {\n return 'dark';\n }\n\n return luminance < LIGHT_MIN ? 'midtone' : 'light';\n};\n","import type { getBackgroundAccentFromPrimaryColor } from './getBackgroundAccentFromPrimaryColor';\nimport { Color } from '../Color';\nimport { getColorLightnessClassification } from '../getColorLightnessClassification';\nimport { DEFAULT_COLOR_SCALE_STEPS } from './buildBrandedColorScale';\nimport { clamp } from './clamp';\nimport { oklchToRgb, rgbToOklch } from './colorSpace';\nimport { ACHROMATIC_CHROMA, maxChroma } from './maxChroma';\nimport { perceivedLightness } from './perceivedLightness';\n\n/**\n * Get the total distance between the lightest and darkest page background colors, measured in lightness.\n * This determines the actual step size we'll use, which correlates to the size of the step between colors\n * in a branded color scale.\n */\nconst MAX_BACKGROUND_LIGHTNESS = 0.95;\nconst MIN_BACKGROUND_LIGHTNESS = 0.09;\nconst STEP_SIZE_IN_LIGHTNESS =\n (MAX_BACKGROUND_LIGHTNESS - MIN_BACKGROUND_LIGHTNESS) / (DEFAULT_COLOR_SCALE_STEPS - 1);\n\n/**\n * Move the background color by the given distance to generate an accented background color.\n * This is used when no primary color has been provided, meaning the background color was not derived from the primary color.\n * The size of the steps used by this utility should match the size of the steps used in the\n * corresponding {@link getBackgroundAccentFromPrimaryColor} utility.\n */\nexport const getAccentedBackgroundByLightness = (\n backgroundColor: Color,\n distanceInSteps: number,\n): Color => {\n const { chroma, hue, lightness } = rgbToOklch(\n backgroundColor.r,\n backgroundColor.g,\n backgroundColor.b,\n );\n const maxPossibleChroma = maxChroma(lightness, hue);\n\n // If there is no perceptible chroma for this color or for the max possible chroma for this hue/lightness,\n // don't try to add any chroma into the result.\n const share =\n chroma < ACHROMATIC_CHROMA || maxPossibleChroma < ACHROMATIC_CHROMA\n ? 0\n : Math.min(1, chroma / maxPossibleChroma);\n\n const atLightness = (candidate: number): Color => {\n const [red, green, blue] = oklchToRgb({\n chroma: share * maxChroma(candidate, hue),\n hue,\n lightness: candidate,\n });\n\n return new Color([red, green, blue, backgroundColor.a]);\n };\n\n const band = getColorLightnessClassification(backgroundColor);\n const towards = band === 'dark' || band === 'veryDark' ? 1 : -1;\n const target = clamp(\n perceivedLightness(backgroundColor) + towards * distanceInSteps * STEP_SIZE_IN_LIGHTNESS,\n 0,\n 1,\n );\n\n let low = 0;\n let high = 1;\n for (let iteration = 0; iteration < 30; iteration += 1) {\n const middle = (low + high) / 2;\n if (perceivedLightness(atLightness(middle)) < target) {\n low = middle;\n } else {\n high = middle;\n }\n }\n\n return atLightness((low + high) / 2);\n};\n","import type { Color } from '../Color';\nimport { getColorLightnessClassification } from '../getColorLightnessClassification';\nimport { buildBrandedColorScale } from './buildBrandedColorScale';\nimport { clamp } from './clamp';\n\n/**\n * Using a branded color scale based on the primary color,\n * move the given background color by the given distance along the scale\n * to generate an accented version of the background color.\n */\nexport const getBackgroundAccentFromPrimaryColor = (\n backgroundColor: Color,\n stepDistance: number,\n primaryColor: Color,\n): Color => {\n const scale = buildBrandedColorScale(primaryColor);\n const last = scale.steps - 1;\n const colorLightnessClass = getColorLightnessClassification(backgroundColor);\n const towards =\n colorLightnessClass === 'dark' || colorLightnessClass === 'veryDark'\n ? -stepDistance\n : stepDistance;\n const from = clamp(Math.round(scale.stepOf(backgroundColor)), 0, last);\n\n return scale.atStep(clamp(from + towards, 0, last));\n};\n","import type { Color } from '../Color';\nimport { getAccentedBackgroundByLightness } from './getAccentedBackgroundByLightness';\nimport { getBackgroundAccentFromPrimaryColor } from './getBackgroundAccentFromPrimaryColor';\n\ntype AccentedBackgroundOptions = {\n readonly backgroundColor: Color;\n readonly primaryColor?: Color | undefined;\n readonly stepDistance: number;\n};\n\n/**\n * A background `distance` steps off `background`, always in the direction away from it:\n * darker when the background is light, lighter when it is dark.\n *\n * Gets a an accented color spaced apart from the given background color by the given distance.\n * If a primary color is included, we will derive the accent color using a color scale.\n */\nexport const getAccentedBackground = ({\n backgroundColor,\n stepDistance,\n primaryColor,\n}: AccentedBackgroundOptions): Color =>\n primaryColor === undefined\n ? getAccentedBackgroundByLightness(backgroundColor, stepDistance)\n : getBackgroundAccentFromPrimaryColor(backgroundColor, stepDistance, primaryColor);\n","import type { getBrandedColorScale } from './getBrandedColorScale';\nimport type { getSlightAccentedBackgroundColor } from './getSlightAccentedBackgroundColor';\nimport type { ColorInput } from './types';\nimport { Color } from './Color';\nimport { getAccentedBackground } from './private/getAccentedBackground';\n\nexport type HeavyAccentedBackgroundColorOptions = {\n readonly primaryColor?: ColorInput;\n};\n\n/**\n * Get an accented version of a background color that is a two steps lighter/darker.\n * Use this when the color contrast of the accented background color is not significant,\n * such as for card/panel background colors.\n * \n * Accepts an optional primary color, used when the background color has been derived from the primary color,\n * and we want the accented versions of the background color to come from the color scale, see {@link getBrandedColorScale}\n\n * See {@link getSlightAccentedBackgroundColor} for a single step away from the background color instead of two.\n\n *\n * @example\n * ```ts\n * getHeavyAccentedBackgroundColor('#f5f5f5').toHex(); // '#cbcbcb'\n * getHeavyAccentedBackgroundColor('#f5f5f5', { primaryColor: '#2949e5' }).toHex(); // '#adbbf5'\n * ```\n */\nexport const getHeavyAccentedBackgroundColor = (\n _backgroundColor: ColorInput,\n { primaryColor }: HeavyAccentedBackgroundColorOptions = {},\n): Color => {\n const backgroundColor = new Color(_backgroundColor);\n\n return getAccentedBackground({\n backgroundColor,\n stepDistance: 2,\n primaryColor: primaryColor === undefined ? undefined : new Color(primaryColor),\n });\n};\n","import type { getBrandedColorScale } from './getBrandedColorScale';\nimport type { getHeavyAccentedBackgroundColor } from './getHeavyAccentedBackgroundColor';\nimport type { ColorInput } from './types';\nimport { Color } from './Color';\nimport { getAccentedBackground } from './private/getAccentedBackground';\n\nconst WHITE = '#ffffff';\n\nexport type SlightAccentedBackgroundColorOptions = {\n readonly shouldReturnWhiteForWhiteBackground?: boolean;\n /**\n * Optional primary color, which is used when the background color is derived from the primary color,\n * so we'll calculate the accented background color using a color scale.\n */\n readonly primaryColor?: ColorInput;\n};\n\n/**\n * Get an accented version of a background color that is a single step lighter/darker.\n * Use this when the color contrast of the accented background color is not significant,\n * such as for card/panel background colors.\n * \n * Accepts an optional primary color, used when the background color has been derived from the primary color,\n * and we want the accented versions of the background color to come from the color scale, see {@link getBrandedColorScale}\n\n * See {@link getHeavyAccentedBackgroundColor} for two steps away from the background color instead of one.\n *\n * @example\n * ```ts\n * getSlightAccentedBackgroundColor('#f5f5f5').toHex(); // '#e0e0e0'\n * getSlightAccentedBackgroundColor('#f5f5f5', { primaryColor: '#2949e5' }).toHex(); // '#cdd5f9'\n * getSlightAccentedBackgroundColor('#ffffff', { shouldReturnWhiteForWhiteBackground: true }).toHex(); // '#ffffff'\n * ```\n */\nexport const getSlightAccentedBackgroundColor = (\n _backgroundColor: ColorInput,\n {\n shouldReturnWhiteForWhiteBackground = false,\n primaryColor,\n }: SlightAccentedBackgroundColorOptions = {},\n): Color => {\n const backgroundColor = new Color(_backgroundColor);\n\n if (shouldReturnWhiteForWhiteBackground && backgroundColor.toHex() === WHITE) {\n return backgroundColor;\n }\n\n return getAccentedBackground({\n backgroundColor,\n stepDistance: 1,\n primaryColor: primaryColor === undefined ? undefined : new Color(primaryColor),\n });\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"color-CRvuCG8E.js","names":["HEX_RADIX","WHITE","BLACK","ACHROMATIC_CHROMA","WHITE","BLACK","WHITE","ALMOST_BLACK","ALMOST_WHITE","FLARE"],"sources":["../src/private/clamp.ts","../src/private/colorSpace.ts","../src/private/parseColor.ts","../src/Color.ts","../src/colorContrastRatiosByShape.ts","../src/private/preciseContrast.ts","../src/adjustColorForProperContrast.ts","../src/ColorScale.ts","../src/getBestColorForText.ts","../src/getBrandDarkBackgroundColor.ts","../src/getBrandLightBackgroundColor.ts","../src/private/maxChroma.ts","../src/private/perceivedLightness.ts","../src/private/buildBrandedColorScale.ts","../src/getBrandedColorScale.ts","../src/getColorLightnessClassification.ts","../src/private/getAccentedBackgroundByLightness.ts","../src/private/getBackgroundAccentFromPrimaryColor.ts","../src/private/getAccentedBackground.ts","../src/getHeavyAccentedBackgroundColor.ts","../src/getSlightAccentedBackgroundColor.ts"],"sourcesContent":["/** Restrict `value` to the inclusive range between `min` and `max`. */\nexport const clamp = (value: number, min: number, max: number): number =>\n Math.min(Math.max(value, min), max);\n","// oxlint-disable id-length -- single-letter names mirror the color-space formulas\nimport type { Hsl, Lab, RgbTuple } from '../types';\nimport { clamp } from './clamp';\n\nconst D65_WHITE_POINT = { x: 0.95047, y: 1, z: 1.08883 };\n\nconst DEGREES_PER_RADIAN = 180 / Math.PI;\n\n/** Slack allowed on a linear channel before a color counts as out of gamut. */\nconst GAMUT_EPSILON = 1e-6;\n\n/** Enough halvings to place the gamut boundary well inside a single 0–255 step. */\nconst GAMUT_SEARCH_ITERATIONS = 25;\n\n// CIE standard constants: 216/24389 and 24389/27. Their product, 8, is the L* below\n// which the Lab transfer function stays linear.\nconst LAB_EPSILON = 216 / 24389;\nconst LAB_KAPPA = 24389 / 27;\nconst LAB_LINEAR_LIGHTNESS_THRESHOLD = 8;\n\n/** Gamma-decode a 0–255 sRGB channel into linear light. */\nconst linearize = (channel: number): number => {\n const normalized = channel / 255;\n return normalized <= 0.04045 ? normalized / 12.92 : ((normalized + 0.055) / 1.055) ** 2.4;\n};\n\n/**\n * Gamma-encode linear light back into a 0–255 sRGB channel. The sign is carried through\n * the exponent so that out-of-gamut Lab values produce a negative channel rather than NaN.\n * Inverse of linearize.\n */\nconst compand = (linear: number): number => {\n const magnitude = Math.abs(linear);\n const encoded =\n magnitude <= 0.0031308 ? magnitude * 12.92 : 1.055 * magnitude ** (1 / 2.4) - 0.055;\n return encoded * Math.sign(linear) * 255;\n};\n\nconst pivot = (value: number): number =>\n value > LAB_EPSILON ? Math.cbrt(value) : (LAB_KAPPA * value + 16) / 116;\n\nconst hueToChannel = (start: number, end: number, givenHue: number): number => {\n let hue = givenHue;\n if (hue < 0) {\n hue += 1;\n }\n if (hue > 1) {\n hue -= 1;\n }\n if (hue < 1 / 6) {\n return start + (end - start) * 6 * hue;\n }\n if (hue < 1 / 2) {\n return end;\n }\n if (hue < 2 / 3) {\n return start + (end - start) * (2 / 3 - hue) * 6;\n }\n return start;\n};\n\n/**\n * WCAG relative luminance (0–1).\n *\n * @see https://www.w3.org/WAI/GL/wiki/Relative_luminance\n */\nexport const relativeLuminance = (red: number, green: number, blue: number): number =>\n 0.2126 * linearize(red) + 0.7152 * linearize(green) + 0.0722 * linearize(blue);\n\nexport const rgbToHsl = (red: number, green: number, blue: number): Hsl => {\n const r = red / 255;\n const g = green / 255;\n const b = blue / 255;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const lightness = (max + min) / 2;\n const delta = max - min;\n\n if (delta === 0) {\n return { hue: 0, lightness: lightness * 100, saturation: 0 };\n }\n\n const saturation = lightness > 0.5 ? delta / (2 - max - min) : delta / (max + min);\n\n let hue: number;\n if (max === r) {\n hue = (g - b) / delta + (g < b ? 6 : 0);\n } else if (max === g) {\n hue = (b - r) / delta + 2;\n } else {\n hue = (r - g) / delta + 4;\n }\n\n return { hue: (hue / 6) * 360, lightness: lightness * 100, saturation: saturation * 100 };\n};\n\nexport const hslToRgb = ({ hue, lightness, saturation }: Hsl): RgbTuple => {\n const h = hue / 360;\n const s = saturation / 100;\n const l = lightness / 100;\n const end = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const start = 2 * l - end;\n\n return [\n hueToChannel(start, end, h + 1 / 3) * 255,\n hueToChannel(start, end, h) * 255,\n hueToChannel(start, end, h - 1 / 3) * 255,\n ];\n};\n\nexport const rgbToLab = (red: number, green: number, blue: number): Lab => {\n const r = linearize(red);\n const g = linearize(green);\n const b = linearize(blue);\n\n const x = (0.4124564 * r + 0.3575761 * g + 0.1804375 * b) / D65_WHITE_POINT.x;\n const y = (0.2126729 * r + 0.7151522 * g + 0.072175 * b) / D65_WHITE_POINT.y;\n const z = (0.0193339 * r + 0.119192 * g + 0.9503041 * b) / D65_WHITE_POINT.z;\n\n const fx = pivot(x);\n const fy = pivot(y);\n const fz = pivot(z);\n\n return { a: 500 * (fx - fy), b: 200 * (fy - fz), lightness: 116 * fy - 16 };\n};\n\n/**\n * OKLab in polar form: perceptual lightness (0–1), chroma (0 at gray, ~0.4 at the most\n * saturated sRGB colors) and hue in degrees. Unlike CIELAB, a fixed `hue` here reads as\n * one hue at every lightness — CIELAB's hue lines bend, which is why lightening a blue\n * along them walks it towards purple.\n *\n * @see https://bottosson.github.io/posts/oklab/\n */\nexport type Oklch = {\n readonly chroma: number;\n readonly hue: number;\n readonly lightness: number;\n};\n\nexport const rgbToOklch = (red: number, green: number, blue: number): Oklch => {\n const r = linearize(red);\n const g = linearize(green);\n const b = linearize(blue);\n\n const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);\n const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);\n const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);\n\n const aAxis = 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s;\n const bAxis = 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s;\n\n return {\n chroma: Math.hypot(aAxis, bAxis),\n hue: (Math.atan2(bAxis, aAxis) * DEGREES_PER_RADIAN + 360) % 360,\n lightness: 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,\n };\n};\n\n/** Linear-light sRGB, which runs 0–1 and goes outside that range when out of gamut. */\nconst oklchToLinearRgb = ({ chroma, hue, lightness }: Oklch): RgbTuple => {\n const radians = hue / DEGREES_PER_RADIAN;\n const aAxis = Math.cos(radians) * chroma;\n const bAxis = Math.sin(radians) * chroma;\n\n const l = (lightness + 0.3963377774 * aAxis + 0.2158037573 * bAxis) ** 3;\n const m = (lightness - 0.1055613458 * aAxis - 0.0638541728 * bAxis) ** 3;\n const s = (lightness - 0.0894841775 * aAxis - 1.291485548 * bAxis) ** 3;\n\n return [\n 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,\n -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,\n -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s,\n ];\n};\n\nconst fitsGamut = (oklch: Oklch): boolean =>\n oklchToLinearRgb(oklch).every(\n (channel) => channel >= -GAMUT_EPSILON && channel <= 1 + GAMUT_EPSILON,\n );\n\n/**\n * The most chroma this lightness and hue can hold inside sRGB, found by bisection. A hue\n * only gets so colorful before the gamut runs out, and that ceiling drops away sharply as\n * a color approaches white or black.\n */\nconst maximumChroma = (oklch: Oklch): number => {\n let low = 0;\n let high = oklch.chroma;\n\n for (let iteration = 0; iteration < GAMUT_SEARCH_ITERATIONS; iteration += 1) {\n const mid = (low + high) / 2;\n if (fitsGamut({ ...oklch, chroma: mid })) {\n low = mid;\n } else {\n high = mid;\n }\n }\n\n return low;\n};\n\n/**\n * Convert to sRGB, pulling chroma in until the color fits rather than clamping each\n * channel independently. Clamping is what bends the hue of an out-of-gamut color — a\n * lightened red whose red channel pins at 255 while green keeps climbing arrives at\n * yellow. Trading colorfulness for an exact hue and lightness keeps the family intact.\n */\nexport const oklchToRgb = (oklch: Oklch): RgbTuple => {\n const inGamut = fitsGamut(oklch) ? oklch : { ...oklch, chroma: maximumChroma(oklch) };\n const [red, green, blue] = oklchToLinearRgb(inGamut);\n\n return [compand(clamp(red, 0, 1)), compand(clamp(green, 0, 1)), compand(clamp(blue, 0, 1))];\n};\n\nexport const labToRgb = ({ a, b, lightness }: Lab): RgbTuple => {\n const fy = (lightness + 16) / 116;\n const fx = fy + a / 500;\n const fz = fy - b / 200;\n\n const x = (fx ** 3 > LAB_EPSILON ? fx ** 3 : (116 * fx - 16) / LAB_KAPPA) * D65_WHITE_POINT.x;\n const y =\n (lightness > LAB_LINEAR_LIGHTNESS_THRESHOLD ? fy ** 3 : lightness / LAB_KAPPA) *\n D65_WHITE_POINT.y;\n const z = (fz ** 3 > LAB_EPSILON ? fz ** 3 : (116 * fz - 16) / LAB_KAPPA) * D65_WHITE_POINT.z;\n\n return [\n compand(3.2404542 * x - 1.5371385 * y - 0.4985314 * z),\n compand(-0.969266 * x + 1.8760108 * y + 0.041556 * z),\n compand(0.0556434 * x - 0.2040259 * y + 1.0572252 * z),\n ];\n};\n","// oxlint-disable id-length -- r/g/b/a are the canonical names for color channels\nimport type { ColorInput, RgbaTuple } from '../types';\nimport { clamp } from './clamp';\n\nconst HEX_PATTERN = /^#?([\\da-f]{3,4}|[\\da-f]{6}|[\\da-f]{8})$/i;\nconst RGB_FUNCTION_PATTERN = /^rgba?\\(([^)]*)\\)$/i;\nconst NUMBER_PATTERN = /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)$/;\nconst PERCENTAGE_PATTERN = /^[+-]?(?:\\d+\\.?\\d*|\\.\\d+)%$/;\nconst SEPARATOR_PATTERN = /[\\s,]+/;\n\nconst MAX_CHANNEL = 255;\nconst HEX_RADIX = 16;\n\nconst toChannel = (value: number): number => clamp(value, 0, MAX_CHANNEL);\nconst toAlpha = (value: number): number => clamp(value, 0, 1);\n\n/**\n * Read a numeric token, where a percentage is taken as a fraction of `percentageOf`. A\n * channel is `128` or `50%` (of 255); an alpha is `0.5` or `50%` (of 1).\n */\nconst parseNumericToken = (token: string | undefined, percentageOf: number): number | null => {\n if (token === undefined) {\n return null;\n }\n if (PERCENTAGE_PATTERN.test(token)) {\n return (Number(token.slice(0, -1)) / 100) * percentageOf;\n }\n if (NUMBER_PATTERN.test(token)) {\n return Number(token);\n }\n return null;\n};\n\nconst parseChannelToken = (token: string | undefined): number | null => {\n const value = parseNumericToken(token, MAX_CHANNEL);\n return value === null ? null : toChannel(value);\n};\n\nconst parseAlphaToken = (token: string | undefined): number | null => {\n const value = parseNumericToken(token, 1);\n return value === null ? null : toAlpha(value);\n};\n\nconst parseHex = (value: string): RgbaTuple | null => {\n const match = HEX_PATTERN.exec(value);\n const digits = match?.[1];\n if (digits === undefined) {\n return null;\n }\n\n // #rgb and #rgba are shorthand for each digit repeated: #1a2 -> #11aa22\n const expanded = digits.length <= 4 ? digits.replaceAll(/./g, '$&$&') : digits;\n\n return [\n Number.parseInt(expanded.slice(0, 2), HEX_RADIX),\n Number.parseInt(expanded.slice(2, 4), HEX_RADIX),\n Number.parseInt(expanded.slice(4, 6), HEX_RADIX),\n expanded.length === 8 ? Number.parseInt(expanded.slice(6, 8), HEX_RADIX) / MAX_CHANNEL : 1,\n ];\n};\n\nconst parseRgbFunction = (value: string): RgbaTuple | null => {\n const match = RGB_FUNCTION_PATTERN.exec(value);\n const body = match?.[1];\n if (body === undefined) {\n return null;\n }\n\n // Modern syntax puts alpha behind a slash: rgb(41 73 229 / 50%)\n const [channelSource, alphaSource, ...extraSources] = body.split('/');\n if (channelSource === undefined || extraSources.length > 0) {\n return null;\n }\n\n const tokens = channelSource.trim().split(SEPARATOR_PATTERN).filter(Boolean);\n const alphaTokens = (alphaSource ?? '').trim().split(SEPARATOR_PATTERN).filter(Boolean);\n if (alphaTokens.length > 1) {\n return null;\n }\n\n const [redToken, greenToken, blueToken, legacyAlphaToken, ...extraTokens] = tokens;\n if (extraTokens.length > 0) {\n return null;\n }\n if (alphaSource !== undefined && legacyAlphaToken !== undefined) {\n return null;\n }\n\n const red = parseChannelToken(redToken);\n const green = parseChannelToken(greenToken);\n const blue = parseChannelToken(blueToken);\n if (red === null || green === null || blue === null) {\n return null;\n }\n\n const alphaToken = alphaTokens[0] ?? legacyAlphaToken;\n if (alphaToken === undefined) {\n return [red, green, blue, 1];\n }\n\n const alpha = parseAlphaToken(alphaToken);\n return alpha === null ? null : [red, green, blue, alpha];\n};\n\n/**\n * Read any supported color representation into RGBA channels, or `null` when the input\n * is not a color this package understands.\n */\nexport const parseColor = (input: ColorInput): RgbaTuple | null => {\n if (typeof input === 'string') {\n const trimmed = input.trim();\n return parseHex(trimmed) ?? parseRgbFunction(trimmed);\n }\n\n if (Array.isArray(input)) {\n const [red, green, blue, alpha = 1] = input;\n if (![red, green, blue, alpha].every((value) => Number.isFinite(value))) {\n return null;\n }\n return [toChannel(red), toChannel(green), toChannel(blue), toAlpha(alpha)];\n }\n\n const { r, g, b, a = 1 } = input;\n if (![r, g, b, a].every((value) => Number.isFinite(value))) {\n return null;\n }\n return [toChannel(r), toChannel(g), toChannel(b), toAlpha(a)];\n};\n","import type { Oklch } from './private/colorSpace';\nimport type { ColorInput, Hsl, InterpolationMode, Lab, RgbaTuple } from './types';\n// oxlint-disable id-length -- r/g/b/a are the canonical names for color channels\nimport { clamp } from './private/clamp';\nimport {\n hslToRgb,\n labToRgb,\n oklchToRgb,\n relativeLuminance,\n rgbToHsl,\n rgbToLab,\n rgbToOklch,\n} from './private/colorSpace';\nimport { parseColor } from './private/parseColor';\n\nconst HEX_RADIX = 16;\n\n/** The ends of the OKLab lightness axis: white and black. */\nconst MAX_LIGHTNESS = 1;\nconst MIN_LIGHTNESS = 0;\n\nconst DEFAULT_INTERPOLATION_MODE: InterpolationMode = 'oklch';\n\nconst WHITE = '#ffffff';\nconst BLACK = '#000000';\n\n/** Wistia brand blue (`#2949e5`) — what an unreadable input resolves to. */\nconst FALLBACK_CHANNELS: RgbaTuple = [41, 73, 229, 1];\n\nconst toHexPair = (channel: number): string =>\n Math.round(channel).toString(HEX_RADIX).padStart(2, '0');\n\n/**\n * Truncated rather than rounded, so a ratio can never climb across a WCAG threshold on\n * its way to one decimal — 4.4501 reports as 4.4, not as a passing 4.5.\n */\nconst truncateToTenth = (ratio: number): number => Math.floor(ratio * 10) / 10;\n\nconst interpolate = (from: number, to: number, ratio: number): number => from + (to - from) * ratio;\n\n/**\n * Interpolate through linear light rather than gamma-encoded sRGB, which keeps blends\n * between saturated colors from sagging through a muddy midpoint.\n */\nconst interpolateLinear = (from: number, to: number, ratio: number): number =>\n Math.sqrt(from ** 2 * (1 - ratio) + to ** 2 * ratio);\n\n/** Below this much chroma a color reads as gray, and its hue stops meaning anything. */\nconst ACHROMATIC_CHROMA = 1e-4;\n\nconst HALF_TURN = 180;\nconst FULL_TURN = 360;\n\n/**\n * Interpolate hue the short way round the wheel — blue to yellow crosses green or magenta,\n * never both. A gray has no hue of its own to offer, so it borrows the other end's rather\n * than dragging the blend through unrelated hues on the way to white or black.\n */\nconst interpolateHue = (from: Oklch, to: Oklch, ratio: number): number => {\n if (from.chroma < ACHROMATIC_CHROMA) {\n return to.hue;\n }\n if (to.chroma < ACHROMATIC_CHROMA) {\n return from.hue;\n }\n\n const difference = ((to.hue - from.hue + HALF_TURN + FULL_TURN) % FULL_TURN) - HALF_TURN;\n return from.hue + difference * ratio;\n};\n\n/**\n * An immutable sRGB color with transformation methods like lighten, darken, tint, shade.\n * Also includes methods to calculate contrast ratio against another color, relative luminance, etc.\n *\n * @example\n * ```ts\n * new Color('#2949e5').lighten(0.5).toHex(); // '#89aaff'\n * new Color('#2949e5').withAlpha(0.5).toRgba(); // 'rgba(41, 73, 229, 0.5)'\n * new Color('#2949e5').contrast('#ffffff'); // 6.6\n * ```\n */\nexport class Color {\n /**\n * Read `input` into a color, returning `null` when it cannot be parsed.\n */\n static parse(input: ColorInput): Color | null {\n const channels = parseColor(input);\n return channels === null ? null : new Color(channels);\n }\n\n static fromHsl(hsl: Hsl, alpha = 1): Color {\n const [red, green, blue] = hslToRgb(hsl);\n return new Color([red, green, blue, alpha]);\n }\n\n static fromLab(lab: Lab, alpha = 1): Color {\n const [red, green, blue] = labToRgb(lab);\n return new Color([red, green, blue, alpha]);\n }\n\n /** Red channel, 0–255. Kept unrounded so that chained operations don't accumulate error. */\n readonly r: number;\n\n /** Green channel, 0–255. Kept unrounded so that chained operations don't accumulate error. */\n readonly g: number;\n\n /** Blue channel, 0–255. Kept unrounded so that chained operations don't accumulate error. */\n readonly b: number;\n\n /** Alpha channel, 0–1. */\n readonly a: number;\n\n /**\n * @param input - any supported color representation. Input that cannot be read as a\n * color resolves to brand blue rather than failing, so a malformed value degrades to\n * a usable color instead of interrupting a render.\n */\n constructor(input: ColorInput) {\n const [red, green, blue, alpha] = parseColor(input) ?? FALLBACK_CHANNELS;\n this.r = red;\n this.g = green;\n this.b = blue;\n this.a = alpha;\n }\n\n /** `#rrggbb`. Alpha is dropped — use {@link Color.toHexWithAlpha} to keep it. */\n toHex(): string {\n return `#${toHexPair(this.r)}${toHexPair(this.g)}${toHexPair(this.b)}`;\n }\n\n /** `#rrggbbaa`. */\n toHexWithAlpha(): string {\n return `${this.toHex()}${toHexPair(this.a * 255)}`;\n }\n\n /** `rgb(41, 73, 229)`. */\n toRgb(): string {\n return `rgb(${Math.round(this.r)}, ${Math.round(this.g)}, ${Math.round(this.b)})`;\n }\n\n /** `rgba(41, 73, 229, 0.5)`. */\n toRgba(): string {\n return `rgba(${Math.round(this.r)}, ${Math.round(this.g)}, ${Math.round(this.b)}, ${this.a})`;\n }\n\n /** Rounded channels, ready to hand to another color library. */\n toRgbaTuple(): RgbaTuple {\n return [Math.round(this.r), Math.round(this.g), Math.round(this.b), this.a];\n }\n\n toHsl(): Hsl {\n return rgbToHsl(this.r, this.g, this.b);\n }\n\n toLab(): Lab {\n return rgbToLab(this.r, this.g, this.b);\n }\n\n /** Hex when fully opaque, `rgba()` otherwise, so the alpha is never silently lost. */\n toString(): string {\n return this.a === 1 ? this.toHex() : this.toRgba();\n }\n\n /**\n * WCAG relative luminance, from 0 (black) to 1 (white). Alpha is ignored — luminance\n * is only meaningful once a color has been composited onto a background.\n */\n luminance(): number {\n return relativeLuminance(this.r, this.g, this.b);\n }\n\n /**\n * WCAG contrast ratio against `other`, from 1 (identical) to 21 (black on white),\n * reported to one decimal place.\n *\n * @see {@link colorContrastRatiosByShape} for the ratio each kind of content needs\n */\n contrast(other: ColorInput): number {\n const ownLuminance = this.luminance();\n const otherLuminance = new Color(other).luminance();\n const lighter = Math.max(ownLuminance, otherLuminance);\n const darker = Math.min(ownLuminance, otherLuminance);\n return truncateToTenth((lighter + 0.05) / (darker + 0.05));\n }\n\n /**\n * Raise perceptual lightness `ratio` (0–1) of the way to white, holding the hue steady.\n *\n * The hue is held in OKLCh, so a lightened color stays recognizably itself: a blue\n * lightens to a paler blue instead of drifting purple, and a red that runs out of sRGB\n * gives up colorfulness rather than sliding towards orange. That is the difference from\n * {@link Color.tint}, which stirs white into the channels and lets the hue land where it\n * may.\n */\n lighten(ratio: number): Color {\n return this.#towardsLightness(MAX_LIGHTNESS, ratio);\n }\n\n /** Lower perceptual lightness `ratio` (0–1) of the way to black, holding the hue steady. */\n darken(ratio: number): Color {\n return this.#towardsLightness(MIN_LIGHTNESS, ratio);\n }\n\n /** Mix `ratio` (0–1) of white in. */\n tint(ratio: number, mode: InterpolationMode = DEFAULT_INTERPOLATION_MODE): Color {\n return this.blend(WHITE, ratio, mode);\n }\n\n /** Mix `ratio` (0–1) of black in. */\n shade(ratio: number, mode: InterpolationMode = DEFAULT_INTERPOLATION_MODE): Color {\n return this.blend(BLACK, ratio, mode);\n }\n\n /**\n * Mix towards `other`, where `ratio` 0 keeps this color and 1 returns `other`. Alpha is\n * always interpolated linearly, whichever `mode` the channels travel through.\n */\n blend(\n other: ColorInput,\n ratio = 0.5,\n mode: InterpolationMode = DEFAULT_INTERPOLATION_MODE,\n ): Color {\n const target = new Color(other);\n const amount = clamp(ratio, 0, 1);\n const alpha = interpolate(this.a, target.a, amount);\n\n if (mode === 'oklch') {\n const from = rgbToOklch(this.r, this.g, this.b);\n const to = rgbToOklch(target.r, target.g, target.b);\n const [red, green, blue] = oklchToRgb({\n chroma: interpolate(from.chroma, to.chroma, amount),\n hue: interpolateHue(from, to, amount),\n lightness: interpolate(from.lightness, to.lightness, amount),\n });\n\n return new Color([red, green, blue, alpha]);\n }\n\n if (mode === 'lab') {\n const from = this.toLab();\n const to = target.toLab();\n return Color.fromLab(\n {\n a: interpolate(from.a, to.a, amount),\n b: interpolate(from.b, to.b, amount),\n lightness: interpolate(from.lightness, to.lightness, amount),\n },\n alpha,\n );\n }\n\n const blendChannel = mode === 'lrgb' ? interpolateLinear : interpolate;\n return new Color([\n blendChannel(this.r, target.r, amount),\n blendChannel(this.g, target.g, amount),\n blendChannel(this.b, target.b, amount),\n alpha,\n ]);\n }\n\n /** Replace the alpha channel with `alpha` (0–1). */\n withAlpha(alpha: number): Color {\n return new Color([this.r, this.g, this.b, alpha]);\n }\n\n /**\n * Replace HSL lightness with `lightness` (0–100), leaving hue and saturation alone.\n * Use this to hit an absolute lightness; use {@link Color.lighten} to step relative to\n * where the color already is.\n */\n withLightness(lightness: number): Color {\n const { hue, saturation } = this.toHsl();\n return Color.fromHsl({ hue, lightness: clamp(lightness, 0, 100), saturation }, this.a);\n }\n\n /**\n * Travel `ratio` of the way to `target` along the OKLab lightness axis, keeping hue and\n * as much colorfulness as the sRGB gamut has room for at the lightness we arrive at.\n */\n #towardsLightness(target: number, ratio: number): Color {\n const { chroma, hue, lightness } = rgbToOklch(this.r, this.g, this.b);\n const [red, green, blue] = oklchToRgb({\n chroma,\n hue,\n lightness: interpolate(lightness, target, clamp(ratio, 0, 1)),\n });\n\n return new Color([red, green, blue, this.a]);\n }\n}\n","export const colorContrastRatiosByShape = {\n nonText: 3.0, // 3.0:1 - https://www.w3.org/TR/WCAG21/#non-text-contrast\n largeText: 3.0, // 3.0:1 - https://www.w3.org/TR/WCAG21/#contrast-minimum\n paragraphText: 4.5, // 4.5:1 - https://www.w3.org/TR/WCAG21/#contrast-minimum\n smallText: 5.5, // We're making this up, but it should be more than the paragraph text\n} as const;\n\n/** The kind of content a color has to be legible as, which sets the ratio it has to clear. */\nexport type ColorShape = keyof typeof colorContrastRatiosByShape;\n","import type { Color } from '../Color';\n\n/**\n * The WCAG contrast ratio between two colors at full precision, unlike\n * {@link Color.contrast}, which truncates to one decimal.\n *\n * Use this to compare two ratios against each other; use `Color.contrast` to decide\n * whether one clears a required ratio. Truncation is fine for the second and ruinous for\n * the first: near-identical ratios collapse to the same tenth and tie, which sends a\n * direction probe the long way round or ranks two candidates arbitrarily.\n */\nexport const preciseContrast = (color: Color, other: Color): number => {\n const ownLuminance = color.luminance();\n const otherLuminance = other.luminance();\n return (\n (Math.max(ownLuminance, otherLuminance) + 0.05) /\n (Math.min(ownLuminance, otherLuminance) + 0.05)\n );\n};\n","import type { ColorShape } from './colorContrastRatiosByShape';\nimport type { ColorInput } from './types';\nimport { Color } from './Color';\nimport { colorContrastRatiosByShape } from './colorContrastRatiosByShape';\nimport { clamp } from './private/clamp';\nimport { preciseContrast } from './private/preciseContrast';\n\nconst WHITE = '#ffffff';\nconst BLACK = '#000000';\n\n/** One HSL lightness percentage point — the step the search walks the foreground by. */\nconst LIGHTNESS_STEP = 1;\n\n/** How far to probe each way when deciding which direction gains contrast faster. */\nconst PROBE_RATIO = 0.1;\n\n/** HSL lightness bands where a color is close enough to an extreme to have nowhere to go. */\nconst NEARLY_BLACK_LIGHTNESS = 10;\nconst NEARLY_WHITE_LIGHTNESS = 80;\n\n/** Contrast of a color against itself, and the floor of the WCAG ratio. */\nconst MIN_CONTRAST = 1.0;\n\n/** The ends of the luminance range: the search has run out of room once it lands on one. */\nconst MAX_LUMINANCE = 1;\nconst MIN_LUMINANCE = 0;\n\n/**\n * Backstop on the search. Flipping direction at the extremes should always converge well\n * before this, so reaching it means something is wrong, not that the budget was tight.\n */\nconst MAX_ITERATIONS = 1000;\n\nexport type AdjustColorForProperContrastOptions = {\n /** What the foreground sits on. Never adjusted. */\n readonly backgroundColor: ColorInput;\n\n /** The color to nudge until it is legible. Returned untouched if it already is. */\n readonly foregroundColor: ColorInput;\n\n /** What the foreground is. Defaults to `paragraphText` (4.5:1). */\n readonly shape?: ColorShape;\n};\n\n/**\n * Walk `foregroundColor` towards white or black until it clears the contrast ratio\n * `shape` requires against `backgroundColor`.\n *\n * Hue is pinned for the whole walk, so the result still reads as the color you passed in\n * — a washed-out brand blue stays blue rather than drifting towards its neighbors. The\n * direction is whichever gains contrast faster, reversing if it hits an extreme with the\n * ratio still unmet. Text-grade ratios that can't be met either way settle on plain white\n * or black, since at that point nothing else beats them.\n *\n * @example\n * ```ts\n * // Already legible, so nothing moves.\n * adjustColorForProperContrast({\n * foregroundColor: '#2949e5',\n * backgroundColor: '#ffffff',\n * }).toHex(); // '#2949e5'\n *\n * // A brand blue on itself, darkened until it separates.\n * adjustColorForProperContrast({\n * foregroundColor: '#2949e5',\n * backgroundColor: '#2949e5',\n * shape: 'nonText',\n * }).toHex();\n * ```\n */\nexport const adjustColorForProperContrast = ({\n backgroundColor,\n foregroundColor,\n shape = 'paragraphText',\n}: AdjustColorForProperContrastOptions): Color => {\n const background = new Color(backgroundColor);\n const foreground = new Color(foregroundColor);\n const requiredContrast = colorContrastRatiosByShape[shape];\n\n const initialContrast = foreground.contrast(background);\n if (initialContrast >= requiredContrast) {\n return foreground;\n }\n\n const { hue, lightness: initialLightness } = foreground.toHsl();\n\n let shouldBeLighter =\n initialLightness < NEARLY_BLACK_LIGHTNESS ||\n preciseContrast(foreground.tint(PROBE_RATIO, 'rgb'), background) >\n preciseContrast(foreground.shade(PROBE_RATIO, 'rgb'), background);\n\n // A nearly-white foreground gains a sliver of contrast by lightening, but can never gain\n // enough — the only way out is down.\n if (initialLightness > NEARLY_WHITE_LIGHTNESS && initialContrast === MIN_CONTRAST) {\n shouldBeLighter = false;\n }\n\n let adjusted = foreground;\n\n for (let iteration = 0; iteration < MAX_ITERATIONS; iteration += 1) {\n if (adjusted.contrast(background) >= requiredContrast) {\n return adjusted;\n }\n\n const luminance = adjusted.luminance();\n // Out of room at white or black with the ratio still unmet. Nothing beats an extreme\n // at the stricter text ratios, so take it; the looser ones get a second pass back the\n // other way, which may land on a color truer to the original than an extreme would be.\n if (iteration > 0 && (luminance === MAX_LUMINANCE || luminance === MIN_LUMINANCE)) {\n if (requiredContrast > colorContrastRatiosByShape.nonText) {\n const white = new Color(WHITE);\n const black = new Color(BLACK);\n return white.contrast(background) > black.contrast(background) ? white : black;\n }\n\n shouldBeLighter = !shouldBeLighter;\n adjusted = foreground;\n }\n\n const { lightness, saturation } = adjusted.toHsl();\n const stepped = Color.fromHsl(\n {\n hue,\n lightness: clamp(lightness + (shouldBeLighter ? LIGHTNESS_STEP : -LIGHTNESS_STEP), 0, 100),\n saturation,\n },\n adjusted.a,\n );\n\n // Snap to the 8-bit color the caller will actually render. Color keeps channels\n // unrounded, so measuring contrast on them can clear the ratio by a hair that\n // rounding to hex then gives back, handing back a color that doesn't actually pass the required contrast.\n adjusted = new Color(stepped.toRgbaTuple());\n }\n\n // Never converged. Hand back the closest we got rather than interrupting a render.\n return adjusted;\n};\n","import type { ColorInput, InterpolationMode } from './types';\nimport { Color } from './Color';\nimport { clamp } from './private/clamp';\n\ntype Stop = {\n readonly color: Color;\n readonly position: number;\n};\n\nconst DEFAULT_DOMAIN: [number, number] = [0, 1];\nconst DEFAULT_MODE: InterpolationMode = 'lrgb';\nconst DEFAULT_PADDING: [number, number] = [0, 0];\n\n/** Ceiling on the binary search in `correctLightness` */\nconst MAX_LIGHTNESS_ITERATIONS = 20;\nconst LIGHTNESS_TOLERANCE = 0.01;\n\nexport type ColorScaleOptions = {\n /**\n * Quantize the scale into bands instead of leaving it continuous: a count of equally sized\n * classes across the domain, or explicit class breaks.\n */\n readonly classes?: number | number[];\n\n /**\n * Redistribute stops so that perceived lightness moves evenly from end to end. Worth\n * turning on for any scale a reader is meant to rank by eye.\n */\n readonly correctLightness?: boolean;\n\n /**\n * The input range, `[0, 1]` by default. Two values set the ends; supply one value per\n * color to pin each color to a position, or more than two to warp the scale.\n */\n readonly domain?: number[];\n\n /** Bias the scale towards one end. Above 1 favors the start, below 1 the end. */\n readonly gamma?: number;\n\n /** The color space blends travel through. */\n readonly mode?: InterpolationMode;\n\n /** Trim `[start, end]` fractions off the scale, dropping its most extreme colors. */\n readonly padding?: [number, number] | number;\n};\n\nconst toPaddingPair = (padding: ColorScaleOptions['padding']): [number, number] => {\n const pair: [number, number] =\n typeof padding === 'number' ? [padding, padding] : (padding ?? DEFAULT_PADDING);\n return [clamp(pair[0], 0, 1), clamp(pair[1], 0, 1)];\n};\n\nconst toClassBreaks = (\n classes: ColorScaleOptions['classes'],\n min: number,\n max: number,\n): number[] | null => {\n if (classes === undefined) {\n return null;\n }\n if (Array.isArray(classes)) {\n return classes.length === 0 ? null : classes;\n }\n if (classes < 1) {\n return [min, max];\n }\n return Array.from({ length: classes + 1 }, (_, index) => min + (index / classes) * (max - min));\n};\n\n/** The index of the class `value` falls into, or -1 when it sits below the first break. */\nconst toClassIndex = (value: number, breaks: number[]): number => {\n let index = 0;\n while (index < breaks.length - 1 && value >= (breaks[index] ?? Number.POSITIVE_INFINITY)) {\n index += 1;\n }\n return index - 1;\n};\n\n/**\n * A continuous scale between two or more colors — the chroma.js `scale` model, as an\n * immutable class. Every configuration method returns a new scale, so a configured scale\n * is safe to hold onto and share.\n *\n * @example\n * ```ts\n * const scale = new ColorScale(['#2949e5', '#ffffff']);\n * scale.at(0.5).toHex(); // the midpoint color\n * scale.colors(5).map((color) => color.toHex()); // five evenly spaced colors\n * scale.correctLightness().domain([0, 100]).at(72); // perceptually even, read in %\n * ```\n */\nexport class ColorScale {\n readonly #classBreaks: number[] | null;\n readonly #colors: [Color, ...Color[]];\n readonly #correctLightness: boolean;\n readonly #domainBreaks: number[] | null;\n readonly #domainOutputs: number[] | null;\n readonly #gamma: number;\n readonly #max: number;\n readonly #min: number;\n readonly #mode: InterpolationMode;\n readonly #options: ColorScaleOptions;\n readonly #padding: [number, number];\n readonly #sampleRange: [number, number];\n readonly #stops: [Stop, ...Stop[]];\n\n /**\n * @param colors - the colors the scale runs through; a single color makes a flat scale\n * @throws {TypeError} when `colors` is empty or `domain` has fewer than two values\n */\n constructor(colors: readonly ColorInput[], options: ColorScaleOptions = {}) {\n const [firstColor, ...remainingColors] = colors.map((color) => new Color(color));\n if (firstColor === undefined) {\n throw new TypeError('A color scale needs at least one color.');\n }\n\n // A lone color still has to interpolate against something, so it becomes both ends.\n this.#colors =\n remainingColors.length === 0 ? [firstColor, firstColor] : [firstColor, ...remainingColors];\n this.#options = options;\n this.#mode = options.mode ?? DEFAULT_MODE;\n this.#gamma = options.gamma ?? 1;\n this.#padding = toPaddingPair(options.padding);\n this.#correctLightness = options.correctLightness ?? false;\n\n const domain = options.domain ?? DEFAULT_DOMAIN;\n const min = domain[0];\n const max = domain.at(-1);\n if (min === undefined || max === undefined || domain.length < 2) {\n throw new TypeError('A color scale domain needs at least two values.');\n }\n this.#min = min;\n this.#max = max;\n\n const count = this.#colors.length;\n let positions: number[];\n let domainBreaks: number[] | null = null;\n let domainOutputs: number[] | null = null;\n\n if (domain.length === count && min !== max) {\n // One domain value per color pins each color to its own position.\n positions = domain.map((value) => (value - min) / (max - min));\n } else {\n positions = this.#colors.map((_, index) => index / (count - 1));\n\n if (domain.length > 2 && min !== max) {\n const breaks = domain.map((value) => (value - min) / (max - min));\n const outputs = domain.map((_, index) => index / (domain.length - 1));\n // Only warp the scale when the intermediate values aren't already evenly spaced.\n if (!breaks.every((value, index) => outputs[index] === value)) {\n domainBreaks = breaks;\n domainOutputs = outputs;\n }\n }\n }\n\n this.#domainBreaks = domainBreaks;\n this.#domainOutputs = domainOutputs;\n\n const [firstStopColor, ...remainingStopColors] = this.#colors;\n this.#stops = [\n { color: firstStopColor, position: positions[0] ?? 0 },\n ...remainingStopColors.map((color, index) => ({\n color,\n position: positions[index + 1] ?? 1,\n })),\n ];\n\n this.#classBreaks = toClassBreaks(options.classes, min, max);\n const firstBreak = this.#classBreaks?.[0];\n const lastBreak = this.#classBreaks?.at(-1);\n this.#sampleRange =\n firstBreak === undefined || lastBreak === undefined ? [min, max] : [firstBreak, lastBreak];\n }\n\n /** The color at `value`, read through the scale's domain, classes, gamma and padding. */\n at(value: number): Color {\n if (!Number.isFinite(value)) {\n throw new TypeError(`A color scale cannot be sampled at ${String(value)}.`);\n }\n return this.#colorAt(value, false);\n }\n\n /** `count` colors spread evenly across the domain. */\n colors(count: number): Color[] {\n if (!Number.isInteger(count) || count < 0) {\n throw new TypeError(`A color scale cannot produce ${String(count)} colors.`);\n }\n if (count === 0) {\n return [];\n }\n\n const [start, end] = this.#sampleRange;\n if (count === 1) {\n return [this.at(start + (end - start) / 2)];\n }\n\n const span = end - start;\n return Array.from({ length: count }, (_, index) =>\n this.at(start + (index / (count - 1)) * span),\n );\n }\n\n mode(mode: InterpolationMode): ColorScale {\n return this.#withOptions({ mode });\n }\n\n domain(domain: number[]): ColorScale {\n return this.#withOptions({ domain });\n }\n\n gamma(gamma: number): ColorScale {\n return this.#withOptions({ gamma });\n }\n\n padding(padding: [number, number] | number): ColorScale {\n return this.#withOptions({ padding });\n }\n\n correctLightness(correctLightness = true): ColorScale {\n return this.#withOptions({ correctLightness });\n }\n\n classes(classes: number | number[]): ColorScale {\n return this.#withOptions({ classes });\n }\n\n #withOptions(overrides: ColorScaleOptions): ColorScale {\n return new ColorScale(this.#colors, { ...this.#options, ...overrides });\n }\n\n #colorAt(value: number, bypassValueMapping: boolean): Color {\n let position = clamp(\n this.#mapDomain(bypassValueMapping ? value : this.#toPosition(value)),\n 0,\n 1,\n );\n\n if (!bypassValueMapping && this.#correctLightness) {\n position = this.#correctPosition(position);\n }\n\n if (this.#gamma !== 1) {\n position **= this.#gamma;\n }\n\n const [paddingStart, paddingEnd] = this.#padding;\n position = paddingStart + position * (1 - paddingStart - paddingEnd);\n\n return this.#interpolateAt(clamp(position, 0, 1));\n }\n\n /** Map a domain value onto the scale's unpadded 0–1 range. */\n #toPosition(value: number): number {\n const breaks = this.#classBreaks;\n if (breaks !== null && breaks.length > 2) {\n return toClassIndex(value, breaks) / (breaks.length - 2);\n }\n if (this.#max === this.#min) {\n return 1;\n }\n return (value - this.#min) / (this.#max - this.#min);\n }\n\n /** Warp the scale so that intermediate domain values land where the caller placed them. */\n #mapDomain(position: number): number {\n const breaks = this.#domainBreaks;\n const outputs = this.#domainOutputs;\n if (breaks === null || outputs === null || position <= 0 || position >= 1) {\n return position;\n }\n\n let index = 0;\n while (index < breaks.length - 2 && position >= (breaks[index + 1] ?? 1)) {\n index += 1;\n }\n\n const start = breaks[index] ?? 0;\n const end = breaks[index + 1] ?? 1;\n const outputStart = outputs[index] ?? 0;\n const outputEnd = outputs[index + 1] ?? 1;\n if (end === start) {\n return outputStart;\n }\n return outputStart + ((position - start) / (end - start)) * (outputEnd - outputStart);\n }\n\n /**\n * Nudge `position` until the color there carries the Lab lightness an evenly lit scale\n * would have, by bisecting between the ends.\n */\n #correctPosition(position: number): number {\n const startLightness = this.#colorAt(0, true).toLab().lightness;\n const endLightness = this.#colorAt(1, true).toLab().lightness;\n const isDescending = startLightness > endLightness;\n const idealLightness = startLightness + (endLightness - startLightness) * position;\n\n let low = 0;\n let high = 1;\n let corrected = position;\n let difference = this.#colorAt(corrected, true).toLab().lightness - idealLightness;\n\n for (\n let iteration = 0;\n iteration < MAX_LIGHTNESS_ITERATIONS && Math.abs(difference) > LIGHTNESS_TOLERANCE;\n iteration += 1\n ) {\n // Already lighter than ideal: search the darker half, and vice versa.\n if (isDescending === difference < 0) {\n high = corrected;\n corrected += (low - corrected) / 2;\n } else {\n low = corrected;\n corrected += (high - corrected) / 2;\n }\n difference = this.#colorAt(corrected, true).toLab().lightness - idealLightness;\n }\n\n return corrected;\n }\n\n #interpolateAt(position: number): Color {\n const stops = this.#stops;\n\n for (const [index, stop] of stops.entries()) {\n if (position <= stop.position) {\n return stop.color;\n }\n\n const next = stops[index + 1];\n if (next === undefined) {\n return stop.color;\n }\n\n if (position < next.position) {\n const ratio = (position - stop.position) / (next.position - stop.position);\n return stop.color.blend(next.color, ratio, this.#mode);\n }\n }\n\n return stops[0].color;\n }\n}\n","import type { ColorShape } from './colorContrastRatiosByShape';\nimport type { ColorInput } from './types';\nimport { Color } from './Color';\nimport { colorContrastRatiosByShape } from './colorContrastRatiosByShape';\nimport { preciseContrast } from './private/preciseContrast';\n\nconst WHITE = '#ffffff';\nconst BLACK = '#000000';\n\nexport type BestColorForTextOptions = {\n /** Always excluded from the result.*/\n readonly backgroundColor: ColorInput;\n\n /**\n * Colors that are part of the palette but should not be considered as candidates.\n * Useful in scenarios like the webinar pages color derivation logic, where we might include derived colors\n * in the palette used by some fields, like `lowEmphasisTextColor`, but we want to exclude the derived colors\n * from other fields, like `mainTextColor`.\n */\n readonly exclude?: readonly ColorInput[];\n\n /**\n * The colors to choose from. Black and white are included automatically, so an empty/absent palette\n * still yields whichever of the two has best contrast against `backgroundColor`.\n */\n readonly palette?: readonly ColorInput[];\n\n /** The type of text/shape that will use the resulting color. Defaults to `paragraphText` (4.5:1). */\n readonly shape?: ColorShape;\n};\n\n/**\n * Picks a color most suitable for a given text (or non-text) shape against the given background color.\n * Accepts an optional color palette, but white and black are always included as options in addition to the palette.\n * Also accepts a set of colors from the palette that should be excluded from consideration.\n *\n * @example\n * ```ts\n * getBestColorForText({ backgroundColor: '#2949e5' }).toHex(); // '#ffffff'\n * ```\n */\nexport const getBestColorForText = ({\n backgroundColor,\n exclude = [],\n palette = [],\n shape = 'paragraphText',\n}: BestColorForTextOptions): Color => {\n const background = new Color(backgroundColor);\n const requiredContrast = colorContrastRatiosByShape[shape];\n\n const excluded = new Set(\n // Always exclude the background color in addition to the colorsToExclude\n [...exclude, background]\n .map((color) => new Color(color).toHex())\n // If one of the excluded colors is black or white, don't exclude it.\n // We always need black and white as potential text color options.\n .filter((hex) => hex !== WHITE && hex !== BLACK),\n );\n\n const candidates = [\n ...new Map(\n [WHITE, BLACK, ...palette].map((color) => {\n const candidate = new Color(color);\n return [candidate.toHex(), candidate];\n }),\n ).values(),\n ].filter((color) => !excluded.has(color.toHex()));\n\n const white = new Color(WHITE);\n const black = new Color(BLACK);\n\n // Rank candidates in order of least contrast first, otherwise we would always return either black or white.\n const ranked = candidates\n .map((color) => ({ color, ratio: preciseContrast(color, background) }))\n .toSorted((one, two) => one.ratio - two.ratio);\n\n // Which side of the background text belongs on: light text on a dark background, dark\n // text on a light one. Settled by measuring both extremes rather than by a lightness\n // threshold, so the crossover falls where contrast actually flips, near luminance 0.18.\n //\n // Worth preferring because the WCAG ratio is symmetric and cannot say that dark-on-dark\n // and light-on-dark read differently at the same number. Without this, a background\n // around luminance 0.12 takes black at 3.3:1 — enough to clear largeText, and murky to\n // read — over a light candidate that costs nothing.\n\n // Optically, should the text be lighter or darker than the background?\n const prefersLighterText =\n preciseContrast(white, background) > preciseContrast(black, background);\n const backgroundLuminance = background.luminance();\n const isPreferredSide = (color: Color): boolean =>\n prefersLighterText\n ? color.luminance() >= backgroundLuminance\n : color.luminance() <= backgroundLuminance;\n\n const passing = ranked.filter(({ color }) => color.contrast(background) >= requiredContrast);\n\n // The least-contrasting passing candidate on the preferred side. There is always one\n // when anything passes at all: the preferred side is the one whose extreme contrasts\n // more, and both extremes are always in the pool. So falling through means nothing\n // cleared the ratio, and the most contrast on offer is that same extreme.\n return (\n passing.find(({ color }) => isPreferredSide(color))?.color ??\n (prefersLighterText ? white : black)\n );\n};\n","import type { ColorInput } from './types';\nimport { Color } from './Color';\n\nconst MAX_PAGE_SATURATION = 50;\n\nconst ALMOST_BLACK = 5;\nconst ALMOST_WHITE = 95;\nconst DESIRED_BACKGROUND_LIGHTNESS = 18;\nconst MINIMUM_CONTRAST_BETWEEN_PRIMARY_AND_BACKGROUND = 1.5;\nconst SEARCH_INCREMENT = 0.5;\n\nconst constructColorWithNewSaturationAndLightness = (\n primaryColor: Color,\n saturation: number,\n lightness: number,\n): Color => Color.fromHsl({ hue: primaryColor.toHsl().hue, lightness, saturation }, primaryColor.a);\n\n/**\n * Generates a dark background color from a given primary color, preserving the hue of the primary color.\n *\n * @example\n * ```ts\n * getBrandDarkBackgroundColor('#2949e5').toHex(); // '#242942'\n * ```\n *\n * @see {@link getBrandLightBackgroundColor} for the light counterpart\n */\nexport const getBrandDarkBackgroundColor = (_primaryColor: ColorInput): Color => {\n const primaryColor = new Color(_primaryColor);\n const { lightness: brandLightness, saturation } = primaryColor.toHsl();\n\n // If the color is close to black or white, zero out the saturation so\n // we end up with gray instead of red\n const hasNoUsableHue = brandLightness < ALMOST_BLACK || brandLightness > ALMOST_WHITE;\n const pageSaturation = hasNoUsableHue ? 0 : Math.min(MAX_PAGE_SATURATION, saturation);\n\n const initialBackgroundColorOption = constructColorWithNewSaturationAndLightness(\n primaryColor,\n pageSaturation,\n DESIRED_BACKGROUND_LIGHTNESS,\n );\n\n // If the initial background color option meets our desired contrast, just use it.\n if (\n initialBackgroundColorOption.contrast(primaryColor) >=\n MINIMUM_CONTRAST_BETWEEN_PRIMARY_AND_BACKGROUND\n ) {\n return initialBackgroundColorOption;\n }\n\n // Otherwise if the initial background color option did not have the desired contrast,\n // tweak the lightness until we get a color that does meet the desired contrast.\n // Return black if we run out of options.\n let backgroundColorWithIncreasedContrast = initialBackgroundColorOption;\n for (\n let pageLightness = DESIRED_BACKGROUND_LIGHTNESS;\n pageLightness >= 0;\n pageLightness -= SEARCH_INCREMENT\n ) {\n const candidate = constructColorWithNewSaturationAndLightness(\n primaryColor,\n pageSaturation,\n pageLightness,\n );\n if (\n candidate.contrast(primaryColor) > backgroundColorWithIncreasedContrast.contrast(primaryColor)\n ) {\n backgroundColorWithIncreasedContrast = candidate;\n }\n if (\n backgroundColorWithIncreasedContrast.contrast(primaryColor) >=\n MINIMUM_CONTRAST_BETWEEN_PRIMARY_AND_BACKGROUND\n ) {\n break;\n }\n }\n\n return backgroundColorWithIncreasedContrast;\n};\n","import type { ColorInput } from './types';\nimport { Color } from './Color';\n\n/** Enough saturation for the brand hue to register, for a primary that has barely any. */\nconst MIN_SATURATION = 5;\n\n/** HSL lightness bands where a primary is close enough to an extreme to have no usable hue. */\nconst ALMOST_BLACK = 5;\nconst ALMOST_WHITE = 95;\n\n/**\n *\n * Generates a light background color from a given primary color, preserving the hue of the primary color.\n *\n * @example\n * ```ts\n * getBrandLightBackgroundColor('#2949e5').toHex(); // '#ebeefd'\n * ```\n *\n * @see {@link getBrandDarkBackgroundColor} for the dark counterpart\n */\nexport const getBrandLightBackgroundColor = (_primaryColor: ColorInput): Color => {\n const primaryColor = new Color(_primaryColor);\n const { lightness, saturation } = primaryColor.toHsl();\n\n // If the new color is close to black or white, zero out the saturation so\n // we end up with gray instead of pink\n const hasNoHue = saturation === 0 || lightness < ALMOST_BLACK || lightness > ALMOST_WHITE;\n const targetSaturation = hasNoHue ? 0 : Math.max(MIN_SATURATION, saturation);\n\n // Make the current color *almost* white and then darken it just a bit\n // to get a nice looking light background color based on the primary color\n const derived = primaryColor.tint(0.95, 'rgb').shade(0.02, 'rgb');\n\n return Color.fromHsl({ ...derived.toHsl(), saturation: targetSaturation }, derived.a);\n};\n","import { oklchToRgb, rgbToOklch } from './colorSpace';\n\n/**\n * Below this a color has no perceptible hue.\n */\nexport const ACHROMATIC_CHROMA = 1e-4;\n\n/**\n * More chroma than sRGB holds anywhere. The widest point is magenta at 0.32\n */\nconst UNREACHABLE_CHROMA = 0.5;\n\n/**\n * The most chroma sRGB can hold at the given lightness and hue.\n *\n * Read from {@link oklchToRgb}, which already clamps by max chroma so that we don't have to\n * re-implement searching for max possible chroma.\n */\nexport const maxChroma = (lightness: number, hue: number): number => {\n const [red, green, blue] = oklchToRgb({ chroma: UNREACHABLE_CHROMA, hue, lightness });\n\n return rgbToOklch(red, green, blue).chroma;\n};\n","import type { Color } from '../Color';\n\n/**\n * Flare is the ambient light reflecting off a screen, as defined by WCAG guidelines.\n * See https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum\n */\nconst FLARE = 0.05;\nconst FLOOR = Math.cbrt(FLARE);\nconst SPAN = Math.cbrt(1 + FLARE) - FLOOR;\n\n/**\n * Get the perceived lightness of a color, with ambient lighting factored in according\n * to WCAG guidelines.\n */\nexport const perceivedLightness = (color: Color): number =>\n (Math.cbrt(color.luminance() + FLARE) - FLOOR) / SPAN;\n","import { Color } from '../Color';\nimport { ColorScale } from '../ColorScale';\nimport { getBrandDarkBackgroundColor } from '../getBrandDarkBackgroundColor';\nimport { getBrandLightBackgroundColor } from '../getBrandLightBackgroundColor';\nimport { clamp } from './clamp';\nimport { oklchToRgb, rgbToOklch } from './colorSpace';\nimport { ACHROMATIC_CHROMA, maxChroma } from './maxChroma';\nimport { perceivedLightness } from './perceivedLightness';\n\nexport const DEFAULT_COLOR_SCALE_STEPS = 12;\n\n/**\n * Using the primary color, derive the light/dark variants of the background color,\n * and use these three colors as all the fixed stops on the scale.\n * Including the primary color in addition to the two background extremes allows the scale\n * to maintain the vibrancy of the primary color.\n * Sort stops by luminance, just in case.\n */\nconst brandScaleStops = (primary: Color): Color[] => {\n const stops = [\n getBrandLightBackgroundColor(primary),\n primary,\n getBrandDarkBackgroundColor(primary),\n ];\n\n return stops.toSorted((one, two) => two.luminance() - one.luminance());\n};\n\nconst ARC_SAMPLES = 128;\n\nconst DEGREES_TO_RADIANS = Math.PI / 180;\n\n/**\n * How far apart two colors look: perceived lightness versus OKLab's chroma.\n *\n * We use perceptual distance rather than a lightness calculation because the color scale\n * can cover a lot of ground without changing lightness significantly. Between an almost white color\n * and a light yellow there is not much lightness difference, but there is actually enough\n * \"distance\" between the colors to perceive more than one step between them.\n *\n * Contrast ratio does not matter significantly here because these are background colors.\n */\nconst perceptualDistance = (one: Color, two: Color): number => {\n const from = rgbToOklch(one.r, one.g, one.b);\n const to = rgbToOklch(two.r, two.g, two.b);\n\n return Math.hypot(\n perceivedLightness(one) - perceivedLightness(two),\n from.chroma * Math.cos(from.hue * DEGREES_TO_RADIANS) -\n to.chroma * Math.cos(to.hue * DEGREES_TO_RADIANS),\n from.chroma * Math.sin(from.hue * DEGREES_TO_RADIANS) -\n to.chroma * Math.sin(to.hue * DEGREES_TO_RADIANS),\n );\n};\n\n/**\n * Maps between a position on the scale and how far along its length that position sits.\n */\nconst arcLength = (colorAt: (position: number) => Color) => {\n const points = Array.from({ length: ARC_SAMPLES + 1 }, (_, index) =>\n colorAt(index / ARC_SAMPLES),\n );\n const travelled = [0];\n for (let index = 1; index <= ARC_SAMPLES; index += 1) {\n const from = points[index - 1];\n const to = points[index];\n const step = from === undefined || to === undefined ? 0 : perceptualDistance(from, to);\n\n travelled.push((travelled[index - 1] ?? 0) + step);\n }\n const total = travelled.at(-1) ?? 0;\n\n return {\n distanceOf: (position: number): number => {\n if (total === 0) {\n return position;\n }\n const scaled = clamp(position, 0, 1) * ARC_SAMPLES;\n const lower = Math.min(Math.floor(scaled), ARC_SAMPLES - 1);\n const within = scaled - lower;\n const from = travelled[lower] ?? 0;\n const to = travelled[lower + 1] ?? total;\n\n return (from + (to - from) * within) / total;\n },\n positionAt: (distance: number): number => {\n if (total === 0) {\n return distance;\n }\n const target = clamp(distance, 0, 1) * total;\n for (let index = 1; index <= ARC_SAMPLES; index += 1) {\n const to = travelled[index] ?? total;\n if (to >= target) {\n const from = travelled[index - 1] ?? 0;\n const span = to - from;\n\n return (index - 1 + (span === 0 ? 0 : (target - from) / span)) / ARC_SAMPLES;\n }\n }\n\n return 1;\n },\n };\n};\n\nexport type BrandScaleOptions = {\n /** How many steps the scale is divided into. */\n readonly steps?: number;\n};\n\n// Where `color` falls on the color scale, as a position from 0–1.\nexport const positionOnScale = (scale: ColorScale, color: Color): number => {\n const target = color.luminance();\n let low = 0;\n let high = 1;\n\n for (let iteration = 0; iteration < 30; iteration += 1) {\n const middle = (low + high) / 2;\n if (scale.at(middle).luminance() > target) {\n low = middle;\n } else {\n high = middle;\n }\n }\n\n return (low + high) / 2;\n};\n\n/**\n * How colorful a color is as a share of the most sRGB allows at its lightness and hue.\n * 0 for a gray, 1 for a color that maxes out lightness/saturation.\n */\nconst gamutFraction = (color: Color): number => {\n const { chroma, hue, lightness } = rgbToOklch(color.r, color.g, color.b);\n const available = maxChroma(lightness, hue);\n\n return chroma < ACHROMATIC_CHROMA || available < ACHROMATIC_CHROMA\n ? 0\n : Math.min(1, chroma / available);\n};\n\ntype Anchor = {\n readonly fraction: number;\n readonly position: number;\n};\n\n/**\n * What fraction of the color gamut is represented by a given position\n */\nconst fractionAt = (anchors: readonly Anchor[], position: number): number => {\n const first = anchors.at(0);\n const last = anchors.at(-1);\n if (first === undefined || last === undefined) {\n return 0;\n }\n if (position <= first.position) {\n return first.fraction;\n }\n\n for (let index = 1; index < anchors.length; index += 1) {\n const previous = anchors[index - 1];\n const next = anchors[index];\n if (previous === undefined || next === undefined) {\n break;\n }\n if (position <= next.position) {\n const span = next.position - previous.position;\n const ratio = span === 0 ? 0 : (position - previous.position) / span;\n\n return previous.fraction + (next.fraction - previous.fraction) * ratio;\n }\n }\n\n return last.fraction;\n};\n\nexport type BrandedColorScale = {\n /** The color at a given position (0 - 1), from the scale. */\n readonly at: (position: number) => Color;\n /** The color at step `index` */\n readonly atStep: (index: number) => Color;\n readonly positionOf: (color: Color) => number;\n /** The step where the primary color falls. */\n readonly primaryStep: number;\n /** Where a given color falls, as a step index — fractional when it sits between two. */\n readonly stepOf: (color: Color) => number;\n readonly steps: number;\n};\n\n/**\n * Builds a color scale using the derived light/dark background colors based on the given primary color,\n * with the primary color slotted into the scale wherever it fits based on lightness.\n *\n * It's important to include the primary color in the scale because the light/dark derived background colors\n * do not have the same saturation as the primary color, and we want the scale to reflect the vibrancy\n * of the primary color.\n */\nexport const buildBrandedColorScale = (\n primary: Color,\n options: BrandScaleOptions = {},\n): BrandedColorScale => {\n const { steps = DEFAULT_COLOR_SCALE_STEPS } = options;\n const scale = new ColorScale(brandScaleStops(primary), { mode: 'oklch' });\n const stops = brandScaleStops(primary);\n const anchors = stops\n .map((stop) => ({ fraction: gamutFraction(stop), position: positionOnScale(scale, stop) }))\n .toSorted((one, two) => one.position - two.position);\n\n const colorAt = (position: number): Color => {\n const base = scale.at(position);\n const { hue, lightness } = rgbToOklch(base.r, base.g, base.b);\n const [red, green, blue] = oklchToRgb({\n chroma: fractionAt(anchors, position) * maxChroma(lightness, hue),\n hue,\n lightness,\n });\n\n return new Color([red, green, blue, base.a]);\n };\n\n const measured = arcLength(colorAt);\n\n const at = (distance: number): Color => colorAt(measured.positionAt(distance));\n const distanceOf = (color: Color): number => measured.distanceOf(positionOnScale(scale, color));\n\n const last = Math.max(0, steps - 1);\n const primaryDistance = distanceOf(primary);\n\n // The primary step should almost never be placed into either end of the scale.\n // This will only occur for primary colors that are truly extreme, like black or white.\n const ownsFirst = stops.at(0)?.toHex() === primary.toHex();\n const ownsLast = stops.at(-1)?.toHex() === primary.toHex();\n const lowest = ownsFirst ? 0 : Math.min(1, last);\n const highest = ownsLast ? last : Math.max(lowest, last - 1);\n const primaryStep = clamp(Math.round(primaryDistance * last), lowest, highest);\n\n const distanceOfStep = (index: number): number => {\n if (index === primaryStep) {\n return primaryDistance;\n }\n if (index < primaryStep) {\n return (index / primaryStep) * primaryDistance;\n }\n\n return primaryDistance + ((index - primaryStep) / (last - primaryStep)) * (1 - primaryDistance);\n };\n\n return {\n at,\n atStep: (index) => (index === primaryStep ? primary : at(distanceOfStep(index))),\n positionOf: distanceOf,\n primaryStep,\n stepOf: (color) => {\n const found = distanceOf(color);\n if (found <= primaryDistance) {\n return primaryDistance === 0 ? 0 : (found / primaryDistance) * primaryStep;\n }\n\n return (\n primaryStep + ((found - primaryDistance) / (1 - primaryDistance)) * (last - primaryStep)\n );\n },\n steps,\n };\n};\n","import type { ColorInput } from './types';\nimport { Color } from './Color';\nimport {\n buildBrandedColorScale,\n DEFAULT_COLOR_SCALE_STEPS,\n} from './private/buildBrandedColorScale';\n\nexport type BrandColorScaleOptions = {\n /** How many steps the scale is divided into. */\n readonly steps?: number;\n};\n\n/**\n * Builds a color scale using the derived light/dark background colors based on the given primary color,\n * with the primary color slotted into the scale wherever it fits based on lightness.\n *\n * It's important to include the primary color in the scale because the light/dark derived background colors\n * do not have the same saturation as the primary color, and we want the scale to reflect the vibrancy\n * of the primary color.\n *\n * @example\n * ```ts\n * getBrandedColorScale('#2949e5').map((color) => color.toHex());\n * // ['#ebeefd', '#d4dbfa', '#bdc8f7', '#a5b5f4', '#8da2f1', '#748eef',\n * // '#5b7aec', '#4263e8', '#2949e5', '#2539ba', '#213080', '#171f45']\n * // ^ the primary, at its own lightness\n * ```\n */\nexport const getBrandedColorScale = (\n primaryColor: ColorInput,\n { steps = DEFAULT_COLOR_SCALE_STEPS }: BrandColorScaleOptions = {},\n): Color[] => {\n const scale = buildBrandedColorScale(new Color(primaryColor), { steps });\n\n return Array.from({ length: steps }, (_, index) => scale.atStep(index));\n};\n","import type { ColorInput } from './types';\nimport { Color } from './Color';\n\nexport type ColorLightnessClassification = 'dark' | 'light' | 'midtone' | 'veryDark';\n\n/**\n * The WCAG value for typical ambient light causing flare on a screen\n * https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum\n */\nconst FLARE = 0.05;\n\n/**\n * Below this a background is close enough to black that there is no more visual\n * room to darken the color without reading as black.\n */\nconst VERY_DARK_MAX = 0.05;\n\n/**\n * This number represents the crossover where white stops having more contrast than black,\n * so any values with luminance greater than this value are no longer considered \"dark\".\n *\n * Don't round this number, otherwise we'll potentially classify some backgrounds as \"midtone\"\n * even though light content reads better on them, and we should always have light content on dark backgrounds.\n */\nconst DARK_MAX = Math.sqrt(FLARE * (1 + FLARE)) - FLARE;\n\n/** Above this a background is close enough to white that it needs no lightening at all. */\nconst LIGHT_MIN = 0.8;\n\n/**\n * Classify a color's lightness based on relative luminance.\n *\n * @example\n * ```ts\n * getColorLightnessClassification('#000000'); // 'veryDark'\n * getColorLightnessClassification('#2949e5'); // 'dark'\n * getColorLightnessClassification('#7f7f7f'); // 'midtone'\n * getColorLightnessClassification('#ffffff'); // 'light'\n * ```\n */\nexport const getColorLightnessClassification = (\n color: ColorInput,\n): ColorLightnessClassification => {\n const parsed = new Color(color);\n const luminance = parsed.luminance();\n\n if (luminance < VERY_DARK_MAX) {\n return 'veryDark';\n }\n if (luminance < DARK_MAX) {\n return 'dark';\n }\n\n return luminance < LIGHT_MIN ? 'midtone' : 'light';\n};\n","import type { getBackgroundAccentFromPrimaryColor } from './getBackgroundAccentFromPrimaryColor';\nimport { Color } from '../Color';\nimport { getColorLightnessClassification } from '../getColorLightnessClassification';\nimport { DEFAULT_COLOR_SCALE_STEPS } from './buildBrandedColorScale';\nimport { clamp } from './clamp';\nimport { oklchToRgb, rgbToOklch } from './colorSpace';\nimport { ACHROMATIC_CHROMA, maxChroma } from './maxChroma';\nimport { perceivedLightness } from './perceivedLightness';\n\n/**\n * Get the total distance between the lightest and darkest page background colors, measured in lightness.\n * This determines the actual step size we'll use, which correlates to the size of the step between colors\n * in a branded color scale.\n */\nconst MAX_BACKGROUND_LIGHTNESS = 0.95;\nconst MIN_BACKGROUND_LIGHTNESS = 0.09;\nconst STEP_SIZE_IN_LIGHTNESS =\n (MAX_BACKGROUND_LIGHTNESS - MIN_BACKGROUND_LIGHTNESS) / (DEFAULT_COLOR_SCALE_STEPS - 1);\n\n/**\n * Move the background color by the given distance to generate an accented background color.\n * This is used when no primary color has been provided, meaning the background color was not derived from the primary color.\n * The size of the steps used by this utility should match the size of the steps used in the\n * corresponding {@link getBackgroundAccentFromPrimaryColor} utility.\n */\nexport const getAccentedBackgroundByLightness = (\n backgroundColor: Color,\n distanceInSteps: number,\n): Color => {\n const { chroma, hue, lightness } = rgbToOklch(\n backgroundColor.r,\n backgroundColor.g,\n backgroundColor.b,\n );\n const maxPossibleChroma = maxChroma(lightness, hue);\n\n // If there is no perceptible chroma for this color or for the max possible chroma for this hue/lightness,\n // don't try to add any chroma into the result.\n const share =\n chroma < ACHROMATIC_CHROMA || maxPossibleChroma < ACHROMATIC_CHROMA\n ? 0\n : Math.min(1, chroma / maxPossibleChroma);\n\n const atLightness = (candidate: number): Color => {\n const [red, green, blue] = oklchToRgb({\n chroma: share * maxChroma(candidate, hue),\n hue,\n lightness: candidate,\n });\n\n return new Color([red, green, blue, backgroundColor.a]);\n };\n\n const band = getColorLightnessClassification(backgroundColor);\n const towards = band === 'dark' || band === 'veryDark' ? 1 : -1;\n const target = clamp(\n perceivedLightness(backgroundColor) + towards * distanceInSteps * STEP_SIZE_IN_LIGHTNESS,\n 0,\n 1,\n );\n\n let low = 0;\n let high = 1;\n for (let iteration = 0; iteration < 30; iteration += 1) {\n const middle = (low + high) / 2;\n if (perceivedLightness(atLightness(middle)) < target) {\n low = middle;\n } else {\n high = middle;\n }\n }\n\n return atLightness((low + high) / 2);\n};\n","import type { Color } from '../Color';\nimport { getColorLightnessClassification } from '../getColorLightnessClassification';\nimport { buildBrandedColorScale } from './buildBrandedColorScale';\nimport { clamp } from './clamp';\n\n/**\n * Using a branded color scale based on the primary color,\n * move the given background color by the given distance along the scale\n * to generate an accented version of the background color.\n */\nexport const getBackgroundAccentFromPrimaryColor = (\n backgroundColor: Color,\n stepDistance: number,\n primaryColor: Color,\n): Color => {\n const scale = buildBrandedColorScale(primaryColor);\n const last = scale.steps - 1;\n const colorLightnessClass = getColorLightnessClassification(backgroundColor);\n const towards =\n colorLightnessClass === 'dark' || colorLightnessClass === 'veryDark'\n ? -stepDistance\n : stepDistance;\n const from = clamp(Math.round(scale.stepOf(backgroundColor)), 0, last);\n\n return scale.atStep(clamp(from + towards, 0, last));\n};\n","import type { Color } from '../Color';\nimport { getAccentedBackgroundByLightness } from './getAccentedBackgroundByLightness';\nimport { getBackgroundAccentFromPrimaryColor } from './getBackgroundAccentFromPrimaryColor';\n\ntype AccentedBackgroundOptions = {\n readonly backgroundColor: Color;\n readonly primaryColor?: Color | undefined;\n readonly stepDistance: number;\n};\n\n/**\n * A background `distance` steps off `background`, always in the direction away from it:\n * darker when the background is light, lighter when it is dark.\n *\n * Gets a an accented color spaced apart from the given background color by the given distance.\n * If a primary color is included, we will derive the accent color using a color scale.\n */\nexport const getAccentedBackground = ({\n backgroundColor,\n stepDistance,\n primaryColor,\n}: AccentedBackgroundOptions): Color =>\n primaryColor === undefined\n ? getAccentedBackgroundByLightness(backgroundColor, stepDistance)\n : getBackgroundAccentFromPrimaryColor(backgroundColor, stepDistance, primaryColor);\n","import type { getBrandedColorScale } from './getBrandedColorScale';\nimport type { getSlightAccentedBackgroundColor } from './getSlightAccentedBackgroundColor';\nimport type { ColorInput } from './types';\nimport { Color } from './Color';\nimport { getAccentedBackground } from './private/getAccentedBackground';\n\nexport type HeavyAccentedBackgroundColorOptions = {\n readonly primaryColor?: ColorInput;\n};\n\n/**\n * Get an accented version of a background color that is a two steps lighter/darker.\n * Use this when the color contrast of the accented background color is not significant,\n * such as for card/panel background colors.\n * \n * Accepts an optional primary color, used when the background color has been derived from the primary color,\n * and we want the accented versions of the background color to come from the color scale, see {@link getBrandedColorScale}\n\n * See {@link getSlightAccentedBackgroundColor} for a single step away from the background color instead of two.\n\n *\n * @example\n * ```ts\n * getHeavyAccentedBackgroundColor('#f5f5f5').toHex(); // '#cbcbcb'\n * getHeavyAccentedBackgroundColor('#f5f5f5', { primaryColor: '#2949e5' }).toHex(); // '#adbbf5'\n * ```\n */\nexport const getHeavyAccentedBackgroundColor = (\n _backgroundColor: ColorInput,\n { primaryColor }: HeavyAccentedBackgroundColorOptions = {},\n): Color => {\n const backgroundColor = new Color(_backgroundColor);\n\n return getAccentedBackground({\n backgroundColor,\n stepDistance: 2,\n primaryColor: primaryColor === undefined ? undefined : new Color(primaryColor),\n });\n};\n","import type { getBrandedColorScale } from './getBrandedColorScale';\nimport type { getHeavyAccentedBackgroundColor } from './getHeavyAccentedBackgroundColor';\nimport type { ColorInput } from './types';\nimport { Color } from './Color';\nimport { getAccentedBackground } from './private/getAccentedBackground';\n\nconst WHITE = '#ffffff';\n\nexport type SlightAccentedBackgroundColorOptions = {\n readonly shouldReturnWhiteForWhiteBackground?: boolean;\n /**\n * Optional primary color, which is used when the background color is derived from the primary color,\n * so we'll calculate the accented background color using a color scale.\n */\n readonly primaryColor?: ColorInput;\n};\n\n/**\n * Get an accented version of a background color that is a single step lighter/darker.\n * Use this when the color contrast of the accented background color is not significant,\n * such as for card/panel background colors.\n * \n * Accepts an optional primary color, used when the background color has been derived from the primary color,\n * and we want the accented versions of the background color to come from the color scale, see {@link getBrandedColorScale}\n\n * See {@link getHeavyAccentedBackgroundColor} for two steps away from the background color instead of one.\n *\n * @example\n * ```ts\n * getSlightAccentedBackgroundColor('#f5f5f5').toHex(); // '#e0e0e0'\n * getSlightAccentedBackgroundColor('#f5f5f5', { primaryColor: '#2949e5' }).toHex(); // '#cdd5f9'\n * getSlightAccentedBackgroundColor('#ffffff', { shouldReturnWhiteForWhiteBackground: true }).toHex(); // '#ffffff'\n * ```\n */\nexport const getSlightAccentedBackgroundColor = (\n _backgroundColor: ColorInput,\n {\n shouldReturnWhiteForWhiteBackground = false,\n primaryColor,\n }: SlightAccentedBackgroundColorOptions = {},\n): Color => {\n const backgroundColor = new Color(_backgroundColor);\n\n if (shouldReturnWhiteForWhiteBackground && backgroundColor.toHex() === WHITE) {\n return backgroundColor;\n }\n\n return getAccentedBackground({\n backgroundColor,\n stepDistance: 1,\n primaryColor: primaryColor === undefined ? undefined : new Color(primaryColor),\n });\n};\n"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
1
 
2
2
  /*
3
- * @license @wistia/kaleidoscope v0.0.4
3
+ * @license @wistia/kaleidoscope v0.0.5-beta.9bc2cb2b.87cc1df
4
4
  *
5
5
  * Copyright (c) 2026, Wistia, Inc. and its affiliates.
6
6
  *
7
7
  * This source code is unlicensed, all rights reserved.
8
8
  */
9
9
 
10
- import { a as getBrandLightBackgroundColor, c as ColorScale, d as Color, i as getBrandedColorScale, l as adjustColorForProperContrast, n as getHeavyAccentedBackgroundColor, o as getBrandDarkBackgroundColor, r as getColorLightnessClassification, s as getBestColorForText, t as getSlightAccentedBackgroundColor, u as colorContrastRatiosByShape } from "../color-DeWiAUsP.js";
10
+ import { a as getBrandLightBackgroundColor, c as ColorScale, d as Color, i as getBrandedColorScale, l as adjustColorForProperContrast, n as getHeavyAccentedBackgroundColor, o as getBrandDarkBackgroundColor, r as getColorLightnessClassification, s as getBestColorForText, t as getSlightAccentedBackgroundColor, u as colorContrastRatiosByShape } from "../color-CRvuCG8E.js";
11
11
  export { Color, ColorScale, adjustColorForProperContrast, colorContrastRatiosByShape, getBestColorForText, getBrandDarkBackgroundColor, getBrandLightBackgroundColor, getBrandedColorScale, getColorLightnessClassification, getHeavyAccentedBackgroundColor, getSlightAccentedBackgroundColor };
@@ -0,0 +1,3 @@
1
+
2
+ import { a as OPAQUE_BRIGHT, c as BUILT_IN_STYLES, i as OPAQUE_HEAVY, n as OPAQUE_MEDIUM, o as GLASS_LIGHT, r as OPAQUE_LIGHT, s as GLASS_DARK, t as OPAQUE_MINIMAL } from "../styleRegistry-CPdlhiQH.js";
3
+ export { BUILT_IN_STYLES, GLASS_DARK, GLASS_LIGHT, OPAQUE_BRIGHT, OPAQUE_HEAVY, OPAQUE_LIGHT, OPAQUE_MEDIUM, OPAQUE_MINIMAL };
@@ -0,0 +1,11 @@
1
+
2
+ /*
3
+ * @license @wistia/kaleidoscope v0.0.5-beta.9bc2cb2b.87cc1df
4
+ *
5
+ * Copyright (c) 2026, Wistia, Inc. and its affiliates.
6
+ *
7
+ * This source code is unlicensed, all rights reserved.
8
+ */
9
+
10
+ import { a as OPAQUE_HEAVY, c as GLASS_DARK, i as OPAQUE_LIGHT, n as OPAQUE_MINIMAL, o as OPAQUE_BRIGHT, r as OPAQUE_MEDIUM, s as GLASS_LIGHT, t as BUILT_IN_STYLES } from "../styleRegistry-D22k0xRZ.js";
11
+ export { BUILT_IN_STYLES, GLASS_DARK, GLASS_LIGHT, OPAQUE_BRIGHT, OPAQUE_HEAVY, OPAQUE_LIGHT, OPAQUE_MEDIUM, OPAQUE_MINIMAL };
@@ -1,60 +1,3 @@
1
1
 
2
- import { n as StyleDocument } from "../index-CG6dL9XZ.js";
3
- //#region src/validateStyleDocument/issues.d.ts
4
- /** One thing wrong with a document, addressed well enough to fix without hunting. */
5
- type StyleDocumentIssue = {
6
- readonly message: string;
7
- readonly path: string;
8
- };
9
- /**
10
- * Everything a check found, split by what it costs.
11
- *
12
- * An **error** is blocking and fails style validation
13
- * A **warning** is not blocking and only produces a warning message
14
- */
15
- type StyleDocumentReport = {
16
- readonly errors: readonly StyleDocumentIssue[];
17
- readonly warnings: readonly StyleDocumentIssue[];
18
- };
19
- //#endregion
20
- //#region src/validateStyleDocument/validateStyleDocument.d.ts
21
- /**
22
- * Structural validation for a Style document, based on the schema.
23
- *
24
- * @param input a parsed Style document, of unknown shape
25
- * @returns every problem found, split into errors, which make the document invalid, and
26
- * warnings, which do not
27
- *
28
- * @example
29
- * ```ts
30
- * const { errors, warnings } = checkStyleDocument(doc);
31
- * for (const { path, message } of warnings) {
32
- * console.warn(`${path}: ${message}`);
33
- * }
34
- * if (errors.length > 0) {
35
- * throw new Error(errors.map(({ path, message }) => `${path}: ${message}`).join('\n'));
36
- * }
37
- * ```
38
- */
39
- export declare const checkStyleDocument: (input: unknown) => StyleDocumentReport;
40
- /**
41
- * What makes a document invalid, and nothing else.
42
- *
43
- * Empty means the document is safe to render, so a caller can drop a document on a non-empty
44
- * result without reading it — the reason warnings are a separate channel rather than entries
45
- * here with a severity on them. Nothing inert should ever cost a customer their Style.
46
- *
47
- * @example
48
- * ```ts
49
- * const issues = validateStyleDocument(doc);
50
- * if (issues.length > 0) {
51
- * throw new Error(issues.map(({ path, message }) => `${path}: ${message}`).join('\n'));
52
- * }
53
- * ```
54
- */
55
- export declare const validateStyleDocument: (input: unknown) => readonly StyleDocumentIssue[];
56
- /** Whether a value is a valid Style document. */
57
- export declare const isStyleDocument: (input: unknown) => input is StyleDocument;
58
- //#endregion
59
- export type { StyleDocumentIssue, StyleDocumentReport };
60
- //# sourceMappingURL=validate.d.ts.map
2
+ import { a as StyleDocumentReport, i as StyleDocumentIssue, n as isStyleDocument, r as validateStyleDocument, t as checkStyleDocument } from "../validate-V28YRNxt.js";
3
+ export { type StyleDocumentIssue, type StyleDocumentReport, checkStyleDocument, isStyleDocument, validateStyleDocument };