diff --git a/Dalamud/Interface/ColorHelpers.cs b/Dalamud/Interface/ColorHelpers.cs
new file mode 100644
index 000000000..71f959292
--- /dev/null
+++ b/Dalamud/Interface/ColorHelpers.cs
@@ -0,0 +1,261 @@
+using System;
+using System.Numerics;
+
+namespace Dalamud.Interface;
+
+///
+/// Class containing various methods for manipulating colors.
+///
+public static class ColorHelpers
+{
+ ///
+ /// Pack a vector4 color into a uint for use in ImGui APIs.
+ ///
+ /// The color to pack.
+ /// The packed color.
+ public static uint RgbaVector4ToUint(Vector4 color)
+ {
+ var r = (byte)(color.X * 255);
+ var g = (byte)(color.Y * 255);
+ var b = (byte)(color.Z * 255);
+ var a = (byte)(color.W * 255);
+
+ return (uint)((a << 24) | (b << 16) | (g << 8) | r);
+ }
+
+ ///
+ /// Convert a RGBA color in the range of 0.f to 1.f to a uint.
+ ///
+ /// The color to pack.
+ /// The packed color.
+ public static Vector4 RgbaUintToVector4(uint color)
+ {
+ var r = (color & 0x000000FF) / 255f;
+ var g = ((color & 0x0000FF00) >> 8) / 255f;
+ var b = ((color & 0x00FF0000) >> 16) / 255f;
+ var a = ((color & 0xFF000000) >> 24) / 255f;
+
+ return new Vector4(r, g, b, a);
+ }
+
+ ///
+ /// Convert a RGBA color in the range of 0.f to 1.f to a HSV color.
+ ///
+ /// The color to convert.
+ /// The color in a HSV representation.
+ public static HsvaColor RgbaToHsv(Vector4 color)
+ {
+ var r = color.X;
+ var g = color.Y;
+ var b = color.Z;
+
+ var max = Math.Max(r, Math.Max(g, b));
+ var min = Math.Min(r, Math.Min(g, b));
+
+ var h = max;
+ var s = max;
+ var v = max;
+
+ var d = max - min;
+ s = max == 0 ? 0 : d / max;
+
+ if (max == min)
+ {
+ h = 0; // achromatic
+ }
+ else
+ {
+ if (max == r)
+ {
+ h = ((g - b) / d) + (g < b ? 6 : 0);
+ }
+ else if (max == g)
+ {
+ h = ((b - r) / d) + 2;
+ }
+ else if (max == b)
+ {
+ h = ((r - g) / d) + 4;
+ }
+
+ h /= 6;
+ }
+
+ return new HsvaColor(h, s, v, color.W);
+ }
+
+ ///
+ /// Convert a HSV color to a RGBA color in the range of 0.f to 1.f.
+ ///
+ /// The color to convert.
+ /// The RGB color.
+ public static Vector4 HsvToRgb(HsvaColor hsv)
+ {
+ var h = hsv.H;
+ var s = hsv.S;
+ var v = hsv.V;
+
+ var r = 0f;
+ var g = 0f;
+ var b = 0f;
+
+ var i = (int)Math.Floor(h * 6);
+ var f = (h * 6) - i;
+ var p = v * (1 - s);
+ var q = v * (1 - (f * s));
+ var t = v * (1 - ((1 - f) * s));
+
+ switch (i % 6)
+ {
+ case 0:
+ r = v;
+ g = t;
+ b = p;
+ break;
+
+ case 1:
+ r = q;
+ g = v;
+ b = p;
+ break;
+
+ case 2:
+ r = p;
+ g = v;
+ b = t;
+ break;
+
+ case 3:
+ r = p;
+ g = q;
+ b = v;
+ break;
+
+ case 4:
+ r = t;
+ g = p;
+ b = v;
+ break;
+
+ case 5:
+ r = v;
+ g = p;
+ b = q;
+ break;
+ }
+
+ return new Vector4(r, g, b, hsv.A);
+ }
+
+ ///
+ /// Lighten a color.
+ ///
+ /// The color to lighten.
+ /// The amount to lighten.
+ /// The lightened color.
+ public static Vector4 Lighten(this Vector4 color, float amount)
+ {
+ var hsv = RgbaToHsv(color);
+ hsv.V += amount;
+ return HsvToRgb(hsv);
+ }
+
+ ///
+ /// Lighten a color.
+ ///
+ /// The color to lighten.
+ /// The amount to lighten.
+ /// The lightened color.
+ public static uint Lighten(uint color, float amount)
+ => RgbaVector4ToUint(Lighten(RgbaUintToVector4(color), amount));
+
+ ///
+ /// Darken a color.
+ ///
+ /// The color to lighten.
+ /// The amount to lighten.
+ /// The darkened color.
+ public static Vector4 Darken(this Vector4 color, float amount)
+ {
+ var hsv = RgbaToHsv(color);
+ hsv.V -= amount;
+ return HsvToRgb(hsv);
+ }
+
+ ///
+ /// Darken a color.
+ ///
+ /// The color to lighten.
+ /// The amount to lighten.
+ /// The darkened color.
+ public static uint Darken(uint color, float amount)
+ => RgbaVector4ToUint(Darken(RgbaUintToVector4(color), amount));
+
+ ///
+ /// Saturate a color.
+ ///
+ /// The color to lighten.
+ /// The amount to lighten.
+ /// The saturated color.
+ public static Vector4 Saturate(this Vector4 color, float amount)
+ {
+ var hsv = RgbaToHsv(color);
+ hsv.S += amount;
+ return HsvToRgb(hsv);
+ }
+
+ ///
+ /// Saturate a color.
+ ///
+ /// The color to lighten.
+ /// The amount to lighten.
+ /// The saturated color.
+ public static uint Saturate(uint color, float amount)
+ => RgbaVector4ToUint(Saturate(RgbaUintToVector4(color), amount));
+
+ ///
+ /// Desaturate a color.
+ ///
+ /// The color to lighten.
+ /// The amount to lighten.
+ /// The desaturated color.
+ public static Vector4 Desaturate(this Vector4 color, float amount)
+ {
+ var hsv = RgbaToHsv(color);
+ hsv.S -= amount;
+ return HsvToRgb(hsv);
+ }
+
+ ///
+ /// Desaturate a color.
+ ///
+ /// The color to lighten.
+ /// The amount to lighten.
+ /// The desaturated color.
+ public static uint Desaturate(uint color, float amount)
+ => RgbaVector4ToUint(Desaturate(RgbaUintToVector4(color), amount));
+
+ ///
+ /// Fade a color.
+ ///
+ /// The color to lighten.
+ /// The amount to lighten.
+ /// The faded color.
+ public static Vector4 Fade(this Vector4 color, float amount)
+ {
+ var hsv = RgbaToHsv(color);
+ hsv.A -= amount;
+ return HsvToRgb(hsv);
+ }
+
+ ///
+ /// Fade a color.
+ ///
+ /// The color to lighten.
+ /// The amount to lighten.
+ /// The faded color.
+ public static uint Fade(uint color, float amount)
+ => RgbaVector4ToUint(Fade(RgbaUintToVector4(color), amount));
+
+ public record struct HsvaColor(float H, float S, float V, float A);
+}