(int) round( $a * $weight + $b * ( 1 - $weight ) ); return self::to_hex( $mix( $r1, $r2 ), $mix( $g1, $g2 ), $mix( $b1, $b2 ) ); } /** Light background tint for a role badge, derived from its accent color. */ public static function tint( string $hex ): string { return self::mix( $hex, '#ffffff', 0.10 ); } /** Darker, more legible text shade for a role badge. */ public static function shade( string $hex ): string { return self::mix( $hex, '#000000', 0.65 ); } private static function to_rgb( string $hex ): array { $hex = ltrim( $hex, '#' ); if ( 3 === strlen( $hex ) ) { $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; } return [ hexdec( substr( $hex, 0, 2 ) ), hexdec( substr( $hex, 2, 2 ) ), hexdec( substr( $hex, 4, 2 ) ), ]; } private static function to_hex( int $r, int $g, int $b ): string { $clamp = static fn( int $v ): int => max( 0, min( 255, $v ) ); return sprintf( '#%02x%02x%02x', $clamp( $r ), $clamp( $g ), $clamp( $b ) ); } }