better hsl implementation