From 6671908e2ec40d74873836e31ba4da458c59c0d4 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 22 May 2026 16:30:45 -0500 Subject: [PATCH] Use white text on saturated brand-primary buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The contrastForeground() helper relied on isDarkTheme(), which only treats a color as dark when its luminance < 0.2. The default orange primary (24 100% 50%) has luminance ~0.31, so it was classified as a light background and got dark text — black letters on orange buttons throughout the site. Same problem hit most saturated mid-lightness brand colors (red, blue, purple, green). Raise the threshold to 0.55 so saturated mid-lightness colors get white text while genuinely light pastels (pink theme, sunset, light mode background) still get dark text. --- src/lib/colorUtils.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/lib/colorUtils.ts b/src/lib/colorUtils.ts index ece2d117..8ed60594 100644 --- a/src/lib/colorUtils.ts +++ b/src/lib/colorUtils.ts @@ -150,10 +150,19 @@ function darken(hsl: string, amount: number): string { return formatHsl(h, s, Math.max(0, l - amount)); } -/** Get a contrast foreground (white or dark) for a given background. */ +/** Get a contrast foreground (white or dark) for a given background. + * + * Picks white text when the background's relative luminance is below ~0.55 + * (covers most saturated brand colors — orange, red, blue, purple, green — at + * mid lightness), and dark text only for genuinely light backgrounds (pale + * pastels, white). The previous threshold (luminance < 0.2 = dark) classified + * almost every saturated mid-lightness color as "light" and painted dark text + * on top, which looks washed-out on the orange brand primary. */ function contrastForeground(bgHsl: string): string { - const dark = isDarkTheme(bgHsl); - return dark ? '0 0% 100%' : '222.2 84% 4.9%'; + const { h, s, l } = parseHsl(bgHsl); + const [r, g, b] = hslToRgb(h, s, l); + const luminance = getLuminance(r, g, b); + return luminance < 0.55 ? '0 0% 100%' : '222.2 84% 4.9%'; } // ─── Auto-Derive Full Token Set from Core Colors ──────────────────────