From a5ba6ddbb767a21a82e5b8b78ff1a0fd6073aa2d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Tue, 6 Jun 2023 11:19:05 +0200
Subject: [PATCH 01/38] Version bump.

---
 Cargo.toml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Cargo.toml b/Cargo.toml
index 1120cd7c..89310a57 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cssparser"
-version = "0.31.1"
+version = "0.31.2"
 authors = [ "Simon Sapin <simon.sapin@exyr.org>" ]
 
 description = "Rust implementation of CSS Syntax Level 3"

From 2fd15ba4ab0c0ae8e4cba37209c6a8f94ae0d15d Mon Sep 17 00:00:00 2001
From: Martin Robinson <mrobinson@igalia.com>
Date: Tue, 11 Jul 2023 11:38:09 +0200
Subject: [PATCH 02/38] Enable the GitHub merge queue (#349)

---
 .github/workflows/main.yml | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 6b8f1460..47282234 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -2,10 +2,12 @@ name: CI
 
 on:
   push:
-    branches: [auto]
+    branches: [master]
   pull_request:
   workflow_dispatch:
-
+  merge_group:
+    types: [checks_requested]
+    
 jobs:
   linux-ci:
     name: Linux
@@ -49,7 +51,7 @@ jobs:
         working-directory: macros
 
   build_result:
-    name: homu build finished
+    name: Result
     runs-on: ubuntu-latest
     needs:
       - "linux-ci"

From a09f28312a1605518088e072d8131f0858925037 Mon Sep 17 00:00:00 2001
From: Tiaan Louw <tiaanl@gmail.com>
Date: Mon, 24 Jul 2023 13:22:29 +0200
Subject: [PATCH 03/38] Enhance modern component serialization with inf and nan
 support (#351)

* Enhance component serialization with inf and nan support

Modern syntax colors support NaN and infinity values. These values are
now allowed, where previously for some lab/lch/oklab/oklch components,
NaN values were truncated to 0.0.

NaN and infinity now also correctly serializes to calc(NaN) and
calc(infinity) respectively.

* Do not clamp or adjust any values when parsing color.
---
 src/color.rs                                  |  104 +-
 .../color4_lab_lch_oklab_oklch.json           | 3872 ++++++++---------
 .../make_color4_lab_lch_oklab_oklch.py        |   16 +-
 3 files changed, 2026 insertions(+), 1966 deletions(-)

diff --git a/src/color.rs b/src/color.rs
index 7c4f4e77..d114c3fc 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -16,16 +16,6 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
 
 const OPAQUE: f32 = 1.0;
 
-fn serialize_none_or<T>(dest: &mut impl fmt::Write, value: &Option<T>) -> fmt::Result
-where
-    T: ToCss,
-{
-    match value {
-        Some(v) => v.to_css(dest),
-        None => dest.write_str("none"),
-    }
-}
-
 /// Serialize the alpha copmonent of a color according to the specification.
 /// <https://drafts.csswg.org/css-color-4/#serializing-alpha-values>
 #[inline]
@@ -55,6 +45,34 @@ pub fn serialize_color_alpha(
     rounded_alpha.to_css(dest)
 }
 
+/// A [`ModernComponent`] can serialize to `none`, `nan`, `infinity` and
+/// floating point values.
+struct ModernComponent<'a>(&'a Option<f32>);
+
+impl<'a> ToCss for ModernComponent<'a> {
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
+    where
+        W: fmt::Write,
+    {
+        if let Some(value) = self.0 {
+            if value.is_finite() {
+                value.to_css(dest)
+            } else if value.is_nan() {
+                dest.write_str("calc(NaN)")
+            } else {
+                debug_assert!(value.is_infinite());
+                if value.is_sign_negative() {
+                    dest.write_str("calc(-infinity)")
+                } else {
+                    dest.write_str("calc(infinity)")
+                }
+            }
+        } else {
+            dest.write_str("none")
+        }
+    }
+}
+
 // Guaratees hue in [0..360)
 fn normalize_hue(hue: f32) -> f32 {
     // <https://drafts.csswg.org/css-values/#angles>
@@ -363,11 +381,11 @@ macro_rules! impl_lab_like {
             {
                 dest.write_str($fname)?;
                 dest.write_str("(")?;
-                serialize_none_or(dest, &self.lightness)?;
+                ModernComponent(&self.lightness).to_css(dest)?;
                 dest.write_char(' ')?;
-                serialize_none_or(dest, &self.a)?;
+                ModernComponent(&self.a).to_css(dest)?;
                 dest.write_char(' ')?;
-                serialize_none_or(dest, &self.b)?;
+                ModernComponent(&self.b).to_css(dest)?;
                 serialize_color_alpha(dest, self.alpha, false)?;
                 dest.write_char(')')
             }
@@ -454,11 +472,11 @@ macro_rules! impl_lch_like {
             {
                 dest.write_str($fname)?;
                 dest.write_str("(")?;
-                serialize_none_or(dest, &self.lightness)?;
+                ModernComponent(&self.lightness).to_css(dest)?;
                 dest.write_char(' ')?;
-                serialize_none_or(dest, &self.chroma)?;
+                ModernComponent(&self.chroma).to_css(dest)?;
                 dest.write_char(' ')?;
-                serialize_none_or(dest, &self.hue)?;
+                ModernComponent(&self.hue).to_css(dest)?;
                 serialize_color_alpha(dest, self.alpha, false)?;
                 dest.write_char(')')
             }
@@ -579,11 +597,11 @@ impl ToCss for ColorFunction {
         dest.write_str("color(")?;
         self.color_space.to_css(dest)?;
         dest.write_char(' ')?;
-        serialize_none_or(dest, &self.c1)?;
+        ModernComponent(&self.c1).to_css(dest)?;
         dest.write_char(' ')?;
-        serialize_none_or(dest, &self.c2)?;
+        ModernComponent(&self.c2).to_css(dest)?;
         dest.write_char(' ')?;
-        serialize_none_or(dest, &self.c3)?;
+        ModernComponent(&self.c3).to_css(dest)?;
 
         serialize_color_alpha(dest, self.alpha, false)?;
 
@@ -1495,7 +1513,7 @@ where
         P::parse_number_or_percentage,
     )?;
 
-    let lightness = lightness.map(|l| l.value(lightness_range).max(0.0));
+    let lightness = lightness.map(|l| l.value(lightness_range));
     let a = a.map(|a| a.value(a_b_range));
     let b = b.map(|b| b.value(a_b_range));
 
@@ -1521,8 +1539,8 @@ where
         P::parse_angle_or_number,
     )?;
 
-    let lightness = lightness.map(|l| l.value(lightness_range).max(0.0));
-    let chroma = chroma.map(|c| c.value(chroma_range).max(0.0));
+    let lightness = lightness.map(|l| l.value(lightness_range));
+    let chroma = chroma.map(|c| c.value(chroma_range));
     let hue = hue.map(|h| normalize_hue(h.degrees()));
 
     Ok(into_color(lightness, chroma, hue, alpha))
@@ -1591,3 +1609,45 @@ where
 
     Ok((r1, r2, r3, alpha))
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn serialize_modern_components() {
+        // None.
+        assert_eq!(ModernComponent(&None).to_css_string(), "none".to_string());
+
+        // Finite values.
+        assert_eq!(
+            ModernComponent(&Some(10.0)).to_css_string(),
+            "10".to_string()
+        );
+        assert_eq!(
+            ModernComponent(&Some(-10.0)).to_css_string(),
+            "-10".to_string()
+        );
+        assert_eq!(ModernComponent(&Some(0.0)).to_css_string(), "0".to_string());
+        assert_eq!(
+            ModernComponent(&Some(-0.0)).to_css_string(),
+            "0".to_string()
+        );
+
+        // Infinite values.
+        assert_eq!(
+            ModernComponent(&Some(f32::INFINITY)).to_css_string(),
+            "calc(infinity)".to_string()
+        );
+        assert_eq!(
+            ModernComponent(&Some(f32::NEG_INFINITY)).to_css_string(),
+            "calc(-infinity)".to_string()
+        );
+
+        // NaN.
+        assert_eq!(
+            ModernComponent(&Some(f32::NAN)).to_css_string(),
+            "calc(NaN)".to_string()
+        );
+    }
+}
diff --git a/src/css-parsing-tests/color4_lab_lch_oklab_oklch.json b/src/css-parsing-tests/color4_lab_lch_oklab_oklch.json
index 8199d6f8..ad9e3fb4 100644
--- a/src/css-parsing-tests/color4_lab_lch_oklab_oklch.json
+++ b/src/css-parsing-tests/color4_lab_lch_oklab_oklch.json
@@ -23,14 +23,14 @@
 "lab(110% 0% 0% / 0.2)", "lab(110 0 0 / 0.2)",
 "lab(110 0 0 / 1)", "lab(110 0 0)",
 "lab(110% 0% 0% / 1)", "lab(110 0 0)",
-"lab(-10 0 0)", "lab(0 0 0)",
-"lab(-10% 0% 0%)", "lab(0 0 0)",
-"lab(-10 0 0 / 0)", "lab(0 0 0 / 0)",
-"lab(-10% 0% 0% / 0)", "lab(0 0 0 / 0)",
-"lab(-10 0 0 / 0.2)", "lab(0 0 0 / 0.2)",
-"lab(-10% 0% 0% / 0.2)", "lab(0 0 0 / 0.2)",
-"lab(-10 0 0 / 1)", "lab(0 0 0)",
-"lab(-10% 0% 0% / 1)", "lab(0 0 0)",
+"lab(-10 0 0)", "lab(-10 0 0)",
+"lab(-10% 0% 0%)", "lab(-10 0 0)",
+"lab(-10 0 0 / 0)", "lab(-10 0 0 / 0)",
+"lab(-10% 0% 0% / 0)", "lab(-10 0 0 / 0)",
+"lab(-10 0 0 / 0.2)", "lab(-10 0 0 / 0.2)",
+"lab(-10% 0% 0% / 0.2)", "lab(-10 0 0 / 0.2)",
+"lab(-10 0 0 / 1)", "lab(-10 0 0)",
+"lab(-10% 0% 0% / 1)", "lab(-10 0 0)",
 "lab(0 10 0)", "lab(0 10 0)",
 "lab(0% 10% 0%)", "lab(0 12.5 0)",
 "lab(0 10 0 / 0)", "lab(0 10 0 / 0)",
@@ -55,14 +55,14 @@
 "lab(110% 10% 0% / 0.2)", "lab(110 12.5 0 / 0.2)",
 "lab(110 10 0 / 1)", "lab(110 10 0)",
 "lab(110% 10% 0% / 1)", "lab(110 12.5 0)",
-"lab(-10 10 0)", "lab(0 10 0)",
-"lab(-10% 10% 0%)", "lab(0 12.5 0)",
-"lab(-10 10 0 / 0)", "lab(0 10 0 / 0)",
-"lab(-10% 10% 0% / 0)", "lab(0 12.5 0 / 0)",
-"lab(-10 10 0 / 0.2)", "lab(0 10 0 / 0.2)",
-"lab(-10% 10% 0% / 0.2)", "lab(0 12.5 0 / 0.2)",
-"lab(-10 10 0 / 1)", "lab(0 10 0)",
-"lab(-10% 10% 0% / 1)", "lab(0 12.5 0)",
+"lab(-10 10 0)", "lab(-10 10 0)",
+"lab(-10% 10% 0%)", "lab(-10 12.5 0)",
+"lab(-10 10 0 / 0)", "lab(-10 10 0 / 0)",
+"lab(-10% 10% 0% / 0)", "lab(-10 12.5 0 / 0)",
+"lab(-10 10 0 / 0.2)", "lab(-10 10 0 / 0.2)",
+"lab(-10% 10% 0% / 0.2)", "lab(-10 12.5 0 / 0.2)",
+"lab(-10 10 0 / 1)", "lab(-10 10 0)",
+"lab(-10% 10% 0% / 1)", "lab(-10 12.5 0)",
 "lab(0 110 0)", "lab(0 110 0)",
 "lab(0% 110% 0%)", "lab(0 137.5 0)",
 "lab(0 110 0 / 0)", "lab(0 110 0 / 0)",
@@ -87,14 +87,14 @@
 "lab(110% 110% 0% / 0.2)", "lab(110 137.5 0 / 0.2)",
 "lab(110 110 0 / 1)", "lab(110 110 0)",
 "lab(110% 110% 0% / 1)", "lab(110 137.5 0)",
-"lab(-10 110 0)", "lab(0 110 0)",
-"lab(-10% 110% 0%)", "lab(0 137.5 0)",
-"lab(-10 110 0 / 0)", "lab(0 110 0 / 0)",
-"lab(-10% 110% 0% / 0)", "lab(0 137.5 0 / 0)",
-"lab(-10 110 0 / 0.2)", "lab(0 110 0 / 0.2)",
-"lab(-10% 110% 0% / 0.2)", "lab(0 137.5 0 / 0.2)",
-"lab(-10 110 0 / 1)", "lab(0 110 0)",
-"lab(-10% 110% 0% / 1)", "lab(0 137.5 0)",
+"lab(-10 110 0)", "lab(-10 110 0)",
+"lab(-10% 110% 0%)", "lab(-10 137.5 0)",
+"lab(-10 110 0 / 0)", "lab(-10 110 0 / 0)",
+"lab(-10% 110% 0% / 0)", "lab(-10 137.5 0 / 0)",
+"lab(-10 110 0 / 0.2)", "lab(-10 110 0 / 0.2)",
+"lab(-10% 110% 0% / 0.2)", "lab(-10 137.5 0 / 0.2)",
+"lab(-10 110 0 / 1)", "lab(-10 110 0)",
+"lab(-10% 110% 0% / 1)", "lab(-10 137.5 0)",
 "lab(0 -10 0)", "lab(0 -10 0)",
 "lab(0% -10% 0%)", "lab(0 -12.5 0)",
 "lab(0 -10 0 / 0)", "lab(0 -10 0 / 0)",
@@ -119,14 +119,14 @@
 "lab(110% -10% 0% / 0.2)", "lab(110 -12.5 0 / 0.2)",
 "lab(110 -10 0 / 1)", "lab(110 -10 0)",
 "lab(110% -10% 0% / 1)", "lab(110 -12.5 0)",
-"lab(-10 -10 0)", "lab(0 -10 0)",
-"lab(-10% -10% 0%)", "lab(0 -12.5 0)",
-"lab(-10 -10 0 / 0)", "lab(0 -10 0 / 0)",
-"lab(-10% -10% 0% / 0)", "lab(0 -12.5 0 / 0)",
-"lab(-10 -10 0 / 0.2)", "lab(0 -10 0 / 0.2)",
-"lab(-10% -10% 0% / 0.2)", "lab(0 -12.5 0 / 0.2)",
-"lab(-10 -10 0 / 1)", "lab(0 -10 0)",
-"lab(-10% -10% 0% / 1)", "lab(0 -12.5 0)",
+"lab(-10 -10 0)", "lab(-10 -10 0)",
+"lab(-10% -10% 0%)", "lab(-10 -12.5 0)",
+"lab(-10 -10 0 / 0)", "lab(-10 -10 0 / 0)",
+"lab(-10% -10% 0% / 0)", "lab(-10 -12.5 0 / 0)",
+"lab(-10 -10 0 / 0.2)", "lab(-10 -10 0 / 0.2)",
+"lab(-10% -10% 0% / 0.2)", "lab(-10 -12.5 0 / 0.2)",
+"lab(-10 -10 0 / 1)", "lab(-10 -10 0)",
+"lab(-10% -10% 0% / 1)", "lab(-10 -12.5 0)",
 "lab(0 0 10)", "lab(0 0 10)",
 "lab(0% 0% 10%)", "lab(0 0 12.5)",
 "lab(0 0 10 / 0)", "lab(0 0 10 / 0)",
@@ -151,14 +151,14 @@
 "lab(110% 0% 10% / 0.2)", "lab(110 0 12.5 / 0.2)",
 "lab(110 0 10 / 1)", "lab(110 0 10)",
 "lab(110% 0% 10% / 1)", "lab(110 0 12.5)",
-"lab(-10 0 10)", "lab(0 0 10)",
-"lab(-10% 0% 10%)", "lab(0 0 12.5)",
-"lab(-10 0 10 / 0)", "lab(0 0 10 / 0)",
-"lab(-10% 0% 10% / 0)", "lab(0 0 12.5 / 0)",
-"lab(-10 0 10 / 0.2)", "lab(0 0 10 / 0.2)",
-"lab(-10% 0% 10% / 0.2)", "lab(0 0 12.5 / 0.2)",
-"lab(-10 0 10 / 1)", "lab(0 0 10)",
-"lab(-10% 0% 10% / 1)", "lab(0 0 12.5)",
+"lab(-10 0 10)", "lab(-10 0 10)",
+"lab(-10% 0% 10%)", "lab(-10 0 12.5)",
+"lab(-10 0 10 / 0)", "lab(-10 0 10 / 0)",
+"lab(-10% 0% 10% / 0)", "lab(-10 0 12.5 / 0)",
+"lab(-10 0 10 / 0.2)", "lab(-10 0 10 / 0.2)",
+"lab(-10% 0% 10% / 0.2)", "lab(-10 0 12.5 / 0.2)",
+"lab(-10 0 10 / 1)", "lab(-10 0 10)",
+"lab(-10% 0% 10% / 1)", "lab(-10 0 12.5)",
 "lab(0 10 10)", "lab(0 10 10)",
 "lab(0% 10% 10%)", "lab(0 12.5 12.5)",
 "lab(0 10 10 / 0)", "lab(0 10 10 / 0)",
@@ -183,14 +183,14 @@
 "lab(110% 10% 10% / 0.2)", "lab(110 12.5 12.5 / 0.2)",
 "lab(110 10 10 / 1)", "lab(110 10 10)",
 "lab(110% 10% 10% / 1)", "lab(110 12.5 12.5)",
-"lab(-10 10 10)", "lab(0 10 10)",
-"lab(-10% 10% 10%)", "lab(0 12.5 12.5)",
-"lab(-10 10 10 / 0)", "lab(0 10 10 / 0)",
-"lab(-10% 10% 10% / 0)", "lab(0 12.5 12.5 / 0)",
-"lab(-10 10 10 / 0.2)", "lab(0 10 10 / 0.2)",
-"lab(-10% 10% 10% / 0.2)", "lab(0 12.5 12.5 / 0.2)",
-"lab(-10 10 10 / 1)", "lab(0 10 10)",
-"lab(-10% 10% 10% / 1)", "lab(0 12.5 12.5)",
+"lab(-10 10 10)", "lab(-10 10 10)",
+"lab(-10% 10% 10%)", "lab(-10 12.5 12.5)",
+"lab(-10 10 10 / 0)", "lab(-10 10 10 / 0)",
+"lab(-10% 10% 10% / 0)", "lab(-10 12.5 12.5 / 0)",
+"lab(-10 10 10 / 0.2)", "lab(-10 10 10 / 0.2)",
+"lab(-10% 10% 10% / 0.2)", "lab(-10 12.5 12.5 / 0.2)",
+"lab(-10 10 10 / 1)", "lab(-10 10 10)",
+"lab(-10% 10% 10% / 1)", "lab(-10 12.5 12.5)",
 "lab(0 110 10)", "lab(0 110 10)",
 "lab(0% 110% 10%)", "lab(0 137.5 12.5)",
 "lab(0 110 10 / 0)", "lab(0 110 10 / 0)",
@@ -215,14 +215,14 @@
 "lab(110% 110% 10% / 0.2)", "lab(110 137.5 12.5 / 0.2)",
 "lab(110 110 10 / 1)", "lab(110 110 10)",
 "lab(110% 110% 10% / 1)", "lab(110 137.5 12.5)",
-"lab(-10 110 10)", "lab(0 110 10)",
-"lab(-10% 110% 10%)", "lab(0 137.5 12.5)",
-"lab(-10 110 10 / 0)", "lab(0 110 10 / 0)",
-"lab(-10% 110% 10% / 0)", "lab(0 137.5 12.5 / 0)",
-"lab(-10 110 10 / 0.2)", "lab(0 110 10 / 0.2)",
-"lab(-10% 110% 10% / 0.2)", "lab(0 137.5 12.5 / 0.2)",
-"lab(-10 110 10 / 1)", "lab(0 110 10)",
-"lab(-10% 110% 10% / 1)", "lab(0 137.5 12.5)",
+"lab(-10 110 10)", "lab(-10 110 10)",
+"lab(-10% 110% 10%)", "lab(-10 137.5 12.5)",
+"lab(-10 110 10 / 0)", "lab(-10 110 10 / 0)",
+"lab(-10% 110% 10% / 0)", "lab(-10 137.5 12.5 / 0)",
+"lab(-10 110 10 / 0.2)", "lab(-10 110 10 / 0.2)",
+"lab(-10% 110% 10% / 0.2)", "lab(-10 137.5 12.5 / 0.2)",
+"lab(-10 110 10 / 1)", "lab(-10 110 10)",
+"lab(-10% 110% 10% / 1)", "lab(-10 137.5 12.5)",
 "lab(0 -10 10)", "lab(0 -10 10)",
 "lab(0% -10% 10%)", "lab(0 -12.5 12.5)",
 "lab(0 -10 10 / 0)", "lab(0 -10 10 / 0)",
@@ -247,14 +247,14 @@
 "lab(110% -10% 10% / 0.2)", "lab(110 -12.5 12.5 / 0.2)",
 "lab(110 -10 10 / 1)", "lab(110 -10 10)",
 "lab(110% -10% 10% / 1)", "lab(110 -12.5 12.5)",
-"lab(-10 -10 10)", "lab(0 -10 10)",
-"lab(-10% -10% 10%)", "lab(0 -12.5 12.5)",
-"lab(-10 -10 10 / 0)", "lab(0 -10 10 / 0)",
-"lab(-10% -10% 10% / 0)", "lab(0 -12.5 12.5 / 0)",
-"lab(-10 -10 10 / 0.2)", "lab(0 -10 10 / 0.2)",
-"lab(-10% -10% 10% / 0.2)", "lab(0 -12.5 12.5 / 0.2)",
-"lab(-10 -10 10 / 1)", "lab(0 -10 10)",
-"lab(-10% -10% 10% / 1)", "lab(0 -12.5 12.5)",
+"lab(-10 -10 10)", "lab(-10 -10 10)",
+"lab(-10% -10% 10%)", "lab(-10 -12.5 12.5)",
+"lab(-10 -10 10 / 0)", "lab(-10 -10 10 / 0)",
+"lab(-10% -10% 10% / 0)", "lab(-10 -12.5 12.5 / 0)",
+"lab(-10 -10 10 / 0.2)", "lab(-10 -10 10 / 0.2)",
+"lab(-10% -10% 10% / 0.2)", "lab(-10 -12.5 12.5 / 0.2)",
+"lab(-10 -10 10 / 1)", "lab(-10 -10 10)",
+"lab(-10% -10% 10% / 1)", "lab(-10 -12.5 12.5)",
 "lab(0 0 110)", "lab(0 0 110)",
 "lab(0% 0% 110%)", "lab(0 0 137.5)",
 "lab(0 0 110 / 0)", "lab(0 0 110 / 0)",
@@ -279,14 +279,14 @@
 "lab(110% 0% 110% / 0.2)", "lab(110 0 137.5 / 0.2)",
 "lab(110 0 110 / 1)", "lab(110 0 110)",
 "lab(110% 0% 110% / 1)", "lab(110 0 137.5)",
-"lab(-10 0 110)", "lab(0 0 110)",
-"lab(-10% 0% 110%)", "lab(0 0 137.5)",
-"lab(-10 0 110 / 0)", "lab(0 0 110 / 0)",
-"lab(-10% 0% 110% / 0)", "lab(0 0 137.5 / 0)",
-"lab(-10 0 110 / 0.2)", "lab(0 0 110 / 0.2)",
-"lab(-10% 0% 110% / 0.2)", "lab(0 0 137.5 / 0.2)",
-"lab(-10 0 110 / 1)", "lab(0 0 110)",
-"lab(-10% 0% 110% / 1)", "lab(0 0 137.5)",
+"lab(-10 0 110)", "lab(-10 0 110)",
+"lab(-10% 0% 110%)", "lab(-10 0 137.5)",
+"lab(-10 0 110 / 0)", "lab(-10 0 110 / 0)",
+"lab(-10% 0% 110% / 0)", "lab(-10 0 137.5 / 0)",
+"lab(-10 0 110 / 0.2)", "lab(-10 0 110 / 0.2)",
+"lab(-10% 0% 110% / 0.2)", "lab(-10 0 137.5 / 0.2)",
+"lab(-10 0 110 / 1)", "lab(-10 0 110)",
+"lab(-10% 0% 110% / 1)", "lab(-10 0 137.5)",
 "lab(0 10 110)", "lab(0 10 110)",
 "lab(0% 10% 110%)", "lab(0 12.5 137.5)",
 "lab(0 10 110 / 0)", "lab(0 10 110 / 0)",
@@ -311,14 +311,14 @@
 "lab(110% 10% 110% / 0.2)", "lab(110 12.5 137.5 / 0.2)",
 "lab(110 10 110 / 1)", "lab(110 10 110)",
 "lab(110% 10% 110% / 1)", "lab(110 12.5 137.5)",
-"lab(-10 10 110)", "lab(0 10 110)",
-"lab(-10% 10% 110%)", "lab(0 12.5 137.5)",
-"lab(-10 10 110 / 0)", "lab(0 10 110 / 0)",
-"lab(-10% 10% 110% / 0)", "lab(0 12.5 137.5 / 0)",
-"lab(-10 10 110 / 0.2)", "lab(0 10 110 / 0.2)",
-"lab(-10% 10% 110% / 0.2)", "lab(0 12.5 137.5 / 0.2)",
-"lab(-10 10 110 / 1)", "lab(0 10 110)",
-"lab(-10% 10% 110% / 1)", "lab(0 12.5 137.5)",
+"lab(-10 10 110)", "lab(-10 10 110)",
+"lab(-10% 10% 110%)", "lab(-10 12.5 137.5)",
+"lab(-10 10 110 / 0)", "lab(-10 10 110 / 0)",
+"lab(-10% 10% 110% / 0)", "lab(-10 12.5 137.5 / 0)",
+"lab(-10 10 110 / 0.2)", "lab(-10 10 110 / 0.2)",
+"lab(-10% 10% 110% / 0.2)", "lab(-10 12.5 137.5 / 0.2)",
+"lab(-10 10 110 / 1)", "lab(-10 10 110)",
+"lab(-10% 10% 110% / 1)", "lab(-10 12.5 137.5)",
 "lab(0 110 110)", "lab(0 110 110)",
 "lab(0% 110% 110%)", "lab(0 137.5 137.5)",
 "lab(0 110 110 / 0)", "lab(0 110 110 / 0)",
@@ -343,14 +343,14 @@
 "lab(110% 110% 110% / 0.2)", "lab(110 137.5 137.5 / 0.2)",
 "lab(110 110 110 / 1)", "lab(110 110 110)",
 "lab(110% 110% 110% / 1)", "lab(110 137.5 137.5)",
-"lab(-10 110 110)", "lab(0 110 110)",
-"lab(-10% 110% 110%)", "lab(0 137.5 137.5)",
-"lab(-10 110 110 / 0)", "lab(0 110 110 / 0)",
-"lab(-10% 110% 110% / 0)", "lab(0 137.5 137.5 / 0)",
-"lab(-10 110 110 / 0.2)", "lab(0 110 110 / 0.2)",
-"lab(-10% 110% 110% / 0.2)", "lab(0 137.5 137.5 / 0.2)",
-"lab(-10 110 110 / 1)", "lab(0 110 110)",
-"lab(-10% 110% 110% / 1)", "lab(0 137.5 137.5)",
+"lab(-10 110 110)", "lab(-10 110 110)",
+"lab(-10% 110% 110%)", "lab(-10 137.5 137.5)",
+"lab(-10 110 110 / 0)", "lab(-10 110 110 / 0)",
+"lab(-10% 110% 110% / 0)", "lab(-10 137.5 137.5 / 0)",
+"lab(-10 110 110 / 0.2)", "lab(-10 110 110 / 0.2)",
+"lab(-10% 110% 110% / 0.2)", "lab(-10 137.5 137.5 / 0.2)",
+"lab(-10 110 110 / 1)", "lab(-10 110 110)",
+"lab(-10% 110% 110% / 1)", "lab(-10 137.5 137.5)",
 "lab(0 -10 110)", "lab(0 -10 110)",
 "lab(0% -10% 110%)", "lab(0 -12.5 137.5)",
 "lab(0 -10 110 / 0)", "lab(0 -10 110 / 0)",
@@ -375,14 +375,14 @@
 "lab(110% -10% 110% / 0.2)", "lab(110 -12.5 137.5 / 0.2)",
 "lab(110 -10 110 / 1)", "lab(110 -10 110)",
 "lab(110% -10% 110% / 1)", "lab(110 -12.5 137.5)",
-"lab(-10 -10 110)", "lab(0 -10 110)",
-"lab(-10% -10% 110%)", "lab(0 -12.5 137.5)",
-"lab(-10 -10 110 / 0)", "lab(0 -10 110 / 0)",
-"lab(-10% -10% 110% / 0)", "lab(0 -12.5 137.5 / 0)",
-"lab(-10 -10 110 / 0.2)", "lab(0 -10 110 / 0.2)",
-"lab(-10% -10% 110% / 0.2)", "lab(0 -12.5 137.5 / 0.2)",
-"lab(-10 -10 110 / 1)", "lab(0 -10 110)",
-"lab(-10% -10% 110% / 1)", "lab(0 -12.5 137.5)",
+"lab(-10 -10 110)", "lab(-10 -10 110)",
+"lab(-10% -10% 110%)", "lab(-10 -12.5 137.5)",
+"lab(-10 -10 110 / 0)", "lab(-10 -10 110 / 0)",
+"lab(-10% -10% 110% / 0)", "lab(-10 -12.5 137.5 / 0)",
+"lab(-10 -10 110 / 0.2)", "lab(-10 -10 110 / 0.2)",
+"lab(-10% -10% 110% / 0.2)", "lab(-10 -12.5 137.5 / 0.2)",
+"lab(-10 -10 110 / 1)", "lab(-10 -10 110)",
+"lab(-10% -10% 110% / 1)", "lab(-10 -12.5 137.5)",
 "lab(0 0 -10)", "lab(0 0 -10)",
 "lab(0% 0% -10%)", "lab(0 0 -12.5)",
 "lab(0 0 -10 / 0)", "lab(0 0 -10 / 0)",
@@ -407,14 +407,14 @@
 "lab(110% 0% -10% / 0.2)", "lab(110 0 -12.5 / 0.2)",
 "lab(110 0 -10 / 1)", "lab(110 0 -10)",
 "lab(110% 0% -10% / 1)", "lab(110 0 -12.5)",
-"lab(-10 0 -10)", "lab(0 0 -10)",
-"lab(-10% 0% -10%)", "lab(0 0 -12.5)",
-"lab(-10 0 -10 / 0)", "lab(0 0 -10 / 0)",
-"lab(-10% 0% -10% / 0)", "lab(0 0 -12.5 / 0)",
-"lab(-10 0 -10 / 0.2)", "lab(0 0 -10 / 0.2)",
-"lab(-10% 0% -10% / 0.2)", "lab(0 0 -12.5 / 0.2)",
-"lab(-10 0 -10 / 1)", "lab(0 0 -10)",
-"lab(-10% 0% -10% / 1)", "lab(0 0 -12.5)",
+"lab(-10 0 -10)", "lab(-10 0 -10)",
+"lab(-10% 0% -10%)", "lab(-10 0 -12.5)",
+"lab(-10 0 -10 / 0)", "lab(-10 0 -10 / 0)",
+"lab(-10% 0% -10% / 0)", "lab(-10 0 -12.5 / 0)",
+"lab(-10 0 -10 / 0.2)", "lab(-10 0 -10 / 0.2)",
+"lab(-10% 0% -10% / 0.2)", "lab(-10 0 -12.5 / 0.2)",
+"lab(-10 0 -10 / 1)", "lab(-10 0 -10)",
+"lab(-10% 0% -10% / 1)", "lab(-10 0 -12.5)",
 "lab(0 10 -10)", "lab(0 10 -10)",
 "lab(0% 10% -10%)", "lab(0 12.5 -12.5)",
 "lab(0 10 -10 / 0)", "lab(0 10 -10 / 0)",
@@ -439,14 +439,14 @@
 "lab(110% 10% -10% / 0.2)", "lab(110 12.5 -12.5 / 0.2)",
 "lab(110 10 -10 / 1)", "lab(110 10 -10)",
 "lab(110% 10% -10% / 1)", "lab(110 12.5 -12.5)",
-"lab(-10 10 -10)", "lab(0 10 -10)",
-"lab(-10% 10% -10%)", "lab(0 12.5 -12.5)",
-"lab(-10 10 -10 / 0)", "lab(0 10 -10 / 0)",
-"lab(-10% 10% -10% / 0)", "lab(0 12.5 -12.5 / 0)",
-"lab(-10 10 -10 / 0.2)", "lab(0 10 -10 / 0.2)",
-"lab(-10% 10% -10% / 0.2)", "lab(0 12.5 -12.5 / 0.2)",
-"lab(-10 10 -10 / 1)", "lab(0 10 -10)",
-"lab(-10% 10% -10% / 1)", "lab(0 12.5 -12.5)",
+"lab(-10 10 -10)", "lab(-10 10 -10)",
+"lab(-10% 10% -10%)", "lab(-10 12.5 -12.5)",
+"lab(-10 10 -10 / 0)", "lab(-10 10 -10 / 0)",
+"lab(-10% 10% -10% / 0)", "lab(-10 12.5 -12.5 / 0)",
+"lab(-10 10 -10 / 0.2)", "lab(-10 10 -10 / 0.2)",
+"lab(-10% 10% -10% / 0.2)", "lab(-10 12.5 -12.5 / 0.2)",
+"lab(-10 10 -10 / 1)", "lab(-10 10 -10)",
+"lab(-10% 10% -10% / 1)", "lab(-10 12.5 -12.5)",
 "lab(0 110 -10)", "lab(0 110 -10)",
 "lab(0% 110% -10%)", "lab(0 137.5 -12.5)",
 "lab(0 110 -10 / 0)", "lab(0 110 -10 / 0)",
@@ -471,14 +471,14 @@
 "lab(110% 110% -10% / 0.2)", "lab(110 137.5 -12.5 / 0.2)",
 "lab(110 110 -10 / 1)", "lab(110 110 -10)",
 "lab(110% 110% -10% / 1)", "lab(110 137.5 -12.5)",
-"lab(-10 110 -10)", "lab(0 110 -10)",
-"lab(-10% 110% -10%)", "lab(0 137.5 -12.5)",
-"lab(-10 110 -10 / 0)", "lab(0 110 -10 / 0)",
-"lab(-10% 110% -10% / 0)", "lab(0 137.5 -12.5 / 0)",
-"lab(-10 110 -10 / 0.2)", "lab(0 110 -10 / 0.2)",
-"lab(-10% 110% -10% / 0.2)", "lab(0 137.5 -12.5 / 0.2)",
-"lab(-10 110 -10 / 1)", "lab(0 110 -10)",
-"lab(-10% 110% -10% / 1)", "lab(0 137.5 -12.5)",
+"lab(-10 110 -10)", "lab(-10 110 -10)",
+"lab(-10% 110% -10%)", "lab(-10 137.5 -12.5)",
+"lab(-10 110 -10 / 0)", "lab(-10 110 -10 / 0)",
+"lab(-10% 110% -10% / 0)", "lab(-10 137.5 -12.5 / 0)",
+"lab(-10 110 -10 / 0.2)", "lab(-10 110 -10 / 0.2)",
+"lab(-10% 110% -10% / 0.2)", "lab(-10 137.5 -12.5 / 0.2)",
+"lab(-10 110 -10 / 1)", "lab(-10 110 -10)",
+"lab(-10% 110% -10% / 1)", "lab(-10 137.5 -12.5)",
 "lab(0 -10 -10)", "lab(0 -10 -10)",
 "lab(0% -10% -10%)", "lab(0 -12.5 -12.5)",
 "lab(0 -10 -10 / 0)", "lab(0 -10 -10 / 0)",
@@ -503,14 +503,14 @@
 "lab(110% -10% -10% / 0.2)", "lab(110 -12.5 -12.5 / 0.2)",
 "lab(110 -10 -10 / 1)", "lab(110 -10 -10)",
 "lab(110% -10% -10% / 1)", "lab(110 -12.5 -12.5)",
-"lab(-10 -10 -10)", "lab(0 -10 -10)",
-"lab(-10% -10% -10%)", "lab(0 -12.5 -12.5)",
-"lab(-10 -10 -10 / 0)", "lab(0 -10 -10 / 0)",
-"lab(-10% -10% -10% / 0)", "lab(0 -12.5 -12.5 / 0)",
-"lab(-10 -10 -10 / 0.2)", "lab(0 -10 -10 / 0.2)",
-"lab(-10% -10% -10% / 0.2)", "lab(0 -12.5 -12.5 / 0.2)",
-"lab(-10 -10 -10 / 1)", "lab(0 -10 -10)",
-"lab(-10% -10% -10% / 1)", "lab(0 -12.5 -12.5)",
+"lab(-10 -10 -10)", "lab(-10 -10 -10)",
+"lab(-10% -10% -10%)", "lab(-10 -12.5 -12.5)",
+"lab(-10 -10 -10 / 0)", "lab(-10 -10 -10 / 0)",
+"lab(-10% -10% -10% / 0)", "lab(-10 -12.5 -12.5 / 0)",
+"lab(-10 -10 -10 / 0.2)", "lab(-10 -10 -10 / 0.2)",
+"lab(-10% -10% -10% / 0.2)", "lab(-10 -12.5 -12.5 / 0.2)",
+"lab(-10 -10 -10 / 1)", "lab(-10 -10 -10)",
+"lab(-10% -10% -10% / 1)", "lab(-10 -12.5 -12.5)",
 "oklab(0 0 0)", "oklab(0 0 0)",
 "oklab(0% 0% 0%)", "oklab(0 0 0)",
 "oklab(0 0 0 / 0)", "oklab(0 0 0 / 0)",
@@ -535,14 +535,14 @@
 "oklab(110% 0% 0% / 0.2)", "oklab(1.1 0 0 / 0.2)",
 "oklab(110 0 0 / 1)", "oklab(110 0 0)",
 "oklab(110% 0% 0% / 1)", "oklab(1.1 0 0)",
-"oklab(-10 0 0)", "oklab(0 0 0)",
-"oklab(-10% 0% 0%)", "oklab(0 0 0)",
-"oklab(-10 0 0 / 0)", "oklab(0 0 0 / 0)",
-"oklab(-10% 0% 0% / 0)", "oklab(0 0 0 / 0)",
-"oklab(-10 0 0 / 0.2)", "oklab(0 0 0 / 0.2)",
-"oklab(-10% 0% 0% / 0.2)", "oklab(0 0 0 / 0.2)",
-"oklab(-10 0 0 / 1)", "oklab(0 0 0)",
-"oklab(-10% 0% 0% / 1)", "oklab(0 0 0)",
+"oklab(-10 0 0)", "oklab(-10 0 0)",
+"oklab(-10% 0% 0%)", "oklab(-0.1 0 0)",
+"oklab(-10 0 0 / 0)", "oklab(-10 0 0 / 0)",
+"oklab(-10% 0% 0% / 0)", "oklab(-0.1 0 0 / 0)",
+"oklab(-10 0 0 / 0.2)", "oklab(-10 0 0 / 0.2)",
+"oklab(-10% 0% 0% / 0.2)", "oklab(-0.1 0 0 / 0.2)",
+"oklab(-10 0 0 / 1)", "oklab(-10 0 0)",
+"oklab(-10% 0% 0% / 1)", "oklab(-0.1 0 0)",
 "oklab(0 10 0)", "oklab(0 10 0)",
 "oklab(0% 10% 0%)", "oklab(0 0.04 0)",
 "oklab(0 10 0 / 0)", "oklab(0 10 0 / 0)",
@@ -567,14 +567,14 @@
 "oklab(110% 10% 0% / 0.2)", "oklab(1.1 0.04 0 / 0.2)",
 "oklab(110 10 0 / 1)", "oklab(110 10 0)",
 "oklab(110% 10% 0% / 1)", "oklab(1.1 0.04 0)",
-"oklab(-10 10 0)", "oklab(0 10 0)",
-"oklab(-10% 10% 0%)", "oklab(0 0.04 0)",
-"oklab(-10 10 0 / 0)", "oklab(0 10 0 / 0)",
-"oklab(-10% 10% 0% / 0)", "oklab(0 0.04 0 / 0)",
-"oklab(-10 10 0 / 0.2)", "oklab(0 10 0 / 0.2)",
-"oklab(-10% 10% 0% / 0.2)", "oklab(0 0.04 0 / 0.2)",
-"oklab(-10 10 0 / 1)", "oklab(0 10 0)",
-"oklab(-10% 10% 0% / 1)", "oklab(0 0.04 0)",
+"oklab(-10 10 0)", "oklab(-10 10 0)",
+"oklab(-10% 10% 0%)", "oklab(-0.1 0.04 0)",
+"oklab(-10 10 0 / 0)", "oklab(-10 10 0 / 0)",
+"oklab(-10% 10% 0% / 0)", "oklab(-0.1 0.04 0 / 0)",
+"oklab(-10 10 0 / 0.2)", "oklab(-10 10 0 / 0.2)",
+"oklab(-10% 10% 0% / 0.2)", "oklab(-0.1 0.04 0 / 0.2)",
+"oklab(-10 10 0 / 1)", "oklab(-10 10 0)",
+"oklab(-10% 10% 0% / 1)", "oklab(-0.1 0.04 0)",
 "oklab(0 110 0)", "oklab(0 110 0)",
 "oklab(0% 110% 0%)", "oklab(0 0.44 0)",
 "oklab(0 110 0 / 0)", "oklab(0 110 0 / 0)",
@@ -599,14 +599,14 @@
 "oklab(110% 110% 0% / 0.2)", "oklab(1.1 0.44 0 / 0.2)",
 "oklab(110 110 0 / 1)", "oklab(110 110 0)",
 "oklab(110% 110% 0% / 1)", "oklab(1.1 0.44 0)",
-"oklab(-10 110 0)", "oklab(0 110 0)",
-"oklab(-10% 110% 0%)", "oklab(0 0.44 0)",
-"oklab(-10 110 0 / 0)", "oklab(0 110 0 / 0)",
-"oklab(-10% 110% 0% / 0)", "oklab(0 0.44 0 / 0)",
-"oklab(-10 110 0 / 0.2)", "oklab(0 110 0 / 0.2)",
-"oklab(-10% 110% 0% / 0.2)", "oklab(0 0.44 0 / 0.2)",
-"oklab(-10 110 0 / 1)", "oklab(0 110 0)",
-"oklab(-10% 110% 0% / 1)", "oklab(0 0.44 0)",
+"oklab(-10 110 0)", "oklab(-10 110 0)",
+"oklab(-10% 110% 0%)", "oklab(-0.1 0.44 0)",
+"oklab(-10 110 0 / 0)", "oklab(-10 110 0 / 0)",
+"oklab(-10% 110% 0% / 0)", "oklab(-0.1 0.44 0 / 0)",
+"oklab(-10 110 0 / 0.2)", "oklab(-10 110 0 / 0.2)",
+"oklab(-10% 110% 0% / 0.2)", "oklab(-0.1 0.44 0 / 0.2)",
+"oklab(-10 110 0 / 1)", "oklab(-10 110 0)",
+"oklab(-10% 110% 0% / 1)", "oklab(-0.1 0.44 0)",
 "oklab(0 -10 0)", "oklab(0 -10 0)",
 "oklab(0% -10% 0%)", "oklab(0 -0.04 0)",
 "oklab(0 -10 0 / 0)", "oklab(0 -10 0 / 0)",
@@ -631,14 +631,14 @@
 "oklab(110% -10% 0% / 0.2)", "oklab(1.1 -0.04 0 / 0.2)",
 "oklab(110 -10 0 / 1)", "oklab(110 -10 0)",
 "oklab(110% -10% 0% / 1)", "oklab(1.1 -0.04 0)",
-"oklab(-10 -10 0)", "oklab(0 -10 0)",
-"oklab(-10% -10% 0%)", "oklab(0 -0.04 0)",
-"oklab(-10 -10 0 / 0)", "oklab(0 -10 0 / 0)",
-"oklab(-10% -10% 0% / 0)", "oklab(0 -0.04 0 / 0)",
-"oklab(-10 -10 0 / 0.2)", "oklab(0 -10 0 / 0.2)",
-"oklab(-10% -10% 0% / 0.2)", "oklab(0 -0.04 0 / 0.2)",
-"oklab(-10 -10 0 / 1)", "oklab(0 -10 0)",
-"oklab(-10% -10% 0% / 1)", "oklab(0 -0.04 0)",
+"oklab(-10 -10 0)", "oklab(-10 -10 0)",
+"oklab(-10% -10% 0%)", "oklab(-0.1 -0.04 0)",
+"oklab(-10 -10 0 / 0)", "oklab(-10 -10 0 / 0)",
+"oklab(-10% -10% 0% / 0)", "oklab(-0.1 -0.04 0 / 0)",
+"oklab(-10 -10 0 / 0.2)", "oklab(-10 -10 0 / 0.2)",
+"oklab(-10% -10% 0% / 0.2)", "oklab(-0.1 -0.04 0 / 0.2)",
+"oklab(-10 -10 0 / 1)", "oklab(-10 -10 0)",
+"oklab(-10% -10% 0% / 1)", "oklab(-0.1 -0.04 0)",
 "oklab(0 0 10)", "oklab(0 0 10)",
 "oklab(0% 0% 10%)", "oklab(0 0 0.04)",
 "oklab(0 0 10 / 0)", "oklab(0 0 10 / 0)",
@@ -663,14 +663,14 @@
 "oklab(110% 0% 10% / 0.2)", "oklab(1.1 0 0.04 / 0.2)",
 "oklab(110 0 10 / 1)", "oklab(110 0 10)",
 "oklab(110% 0% 10% / 1)", "oklab(1.1 0 0.04)",
-"oklab(-10 0 10)", "oklab(0 0 10)",
-"oklab(-10% 0% 10%)", "oklab(0 0 0.04)",
-"oklab(-10 0 10 / 0)", "oklab(0 0 10 / 0)",
-"oklab(-10% 0% 10% / 0)", "oklab(0 0 0.04 / 0)",
-"oklab(-10 0 10 / 0.2)", "oklab(0 0 10 / 0.2)",
-"oklab(-10% 0% 10% / 0.2)", "oklab(0 0 0.04 / 0.2)",
-"oklab(-10 0 10 / 1)", "oklab(0 0 10)",
-"oklab(-10% 0% 10% / 1)", "oklab(0 0 0.04)",
+"oklab(-10 0 10)", "oklab(-10 0 10)",
+"oklab(-10% 0% 10%)", "oklab(-0.1 0 0.04)",
+"oklab(-10 0 10 / 0)", "oklab(-10 0 10 / 0)",
+"oklab(-10% 0% 10% / 0)", "oklab(-0.1 0 0.04 / 0)",
+"oklab(-10 0 10 / 0.2)", "oklab(-10 0 10 / 0.2)",
+"oklab(-10% 0% 10% / 0.2)", "oklab(-0.1 0 0.04 / 0.2)",
+"oklab(-10 0 10 / 1)", "oklab(-10 0 10)",
+"oklab(-10% 0% 10% / 1)", "oklab(-0.1 0 0.04)",
 "oklab(0 10 10)", "oklab(0 10 10)",
 "oklab(0% 10% 10%)", "oklab(0 0.04 0.04)",
 "oklab(0 10 10 / 0)", "oklab(0 10 10 / 0)",
@@ -695,14 +695,14 @@
 "oklab(110% 10% 10% / 0.2)", "oklab(1.1 0.04 0.04 / 0.2)",
 "oklab(110 10 10 / 1)", "oklab(110 10 10)",
 "oklab(110% 10% 10% / 1)", "oklab(1.1 0.04 0.04)",
-"oklab(-10 10 10)", "oklab(0 10 10)",
-"oklab(-10% 10% 10%)", "oklab(0 0.04 0.04)",
-"oklab(-10 10 10 / 0)", "oklab(0 10 10 / 0)",
-"oklab(-10% 10% 10% / 0)", "oklab(0 0.04 0.04 / 0)",
-"oklab(-10 10 10 / 0.2)", "oklab(0 10 10 / 0.2)",
-"oklab(-10% 10% 10% / 0.2)", "oklab(0 0.04 0.04 / 0.2)",
-"oklab(-10 10 10 / 1)", "oklab(0 10 10)",
-"oklab(-10% 10% 10% / 1)", "oklab(0 0.04 0.04)",
+"oklab(-10 10 10)", "oklab(-10 10 10)",
+"oklab(-10% 10% 10%)", "oklab(-0.1 0.04 0.04)",
+"oklab(-10 10 10 / 0)", "oklab(-10 10 10 / 0)",
+"oklab(-10% 10% 10% / 0)", "oklab(-0.1 0.04 0.04 / 0)",
+"oklab(-10 10 10 / 0.2)", "oklab(-10 10 10 / 0.2)",
+"oklab(-10% 10% 10% / 0.2)", "oklab(-0.1 0.04 0.04 / 0.2)",
+"oklab(-10 10 10 / 1)", "oklab(-10 10 10)",
+"oklab(-10% 10% 10% / 1)", "oklab(-0.1 0.04 0.04)",
 "oklab(0 110 10)", "oklab(0 110 10)",
 "oklab(0% 110% 10%)", "oklab(0 0.44 0.04)",
 "oklab(0 110 10 / 0)", "oklab(0 110 10 / 0)",
@@ -727,14 +727,14 @@
 "oklab(110% 110% 10% / 0.2)", "oklab(1.1 0.44 0.04 / 0.2)",
 "oklab(110 110 10 / 1)", "oklab(110 110 10)",
 "oklab(110% 110% 10% / 1)", "oklab(1.1 0.44 0.04)",
-"oklab(-10 110 10)", "oklab(0 110 10)",
-"oklab(-10% 110% 10%)", "oklab(0 0.44 0.04)",
-"oklab(-10 110 10 / 0)", "oklab(0 110 10 / 0)",
-"oklab(-10% 110% 10% / 0)", "oklab(0 0.44 0.04 / 0)",
-"oklab(-10 110 10 / 0.2)", "oklab(0 110 10 / 0.2)",
-"oklab(-10% 110% 10% / 0.2)", "oklab(0 0.44 0.04 / 0.2)",
-"oklab(-10 110 10 / 1)", "oklab(0 110 10)",
-"oklab(-10% 110% 10% / 1)", "oklab(0 0.44 0.04)",
+"oklab(-10 110 10)", "oklab(-10 110 10)",
+"oklab(-10% 110% 10%)", "oklab(-0.1 0.44 0.04)",
+"oklab(-10 110 10 / 0)", "oklab(-10 110 10 / 0)",
+"oklab(-10% 110% 10% / 0)", "oklab(-0.1 0.44 0.04 / 0)",
+"oklab(-10 110 10 / 0.2)", "oklab(-10 110 10 / 0.2)",
+"oklab(-10% 110% 10% / 0.2)", "oklab(-0.1 0.44 0.04 / 0.2)",
+"oklab(-10 110 10 / 1)", "oklab(-10 110 10)",
+"oklab(-10% 110% 10% / 1)", "oklab(-0.1 0.44 0.04)",
 "oklab(0 -10 10)", "oklab(0 -10 10)",
 "oklab(0% -10% 10%)", "oklab(0 -0.04 0.04)",
 "oklab(0 -10 10 / 0)", "oklab(0 -10 10 / 0)",
@@ -759,14 +759,14 @@
 "oklab(110% -10% 10% / 0.2)", "oklab(1.1 -0.04 0.04 / 0.2)",
 "oklab(110 -10 10 / 1)", "oklab(110 -10 10)",
 "oklab(110% -10% 10% / 1)", "oklab(1.1 -0.04 0.04)",
-"oklab(-10 -10 10)", "oklab(0 -10 10)",
-"oklab(-10% -10% 10%)", "oklab(0 -0.04 0.04)",
-"oklab(-10 -10 10 / 0)", "oklab(0 -10 10 / 0)",
-"oklab(-10% -10% 10% / 0)", "oklab(0 -0.04 0.04 / 0)",
-"oklab(-10 -10 10 / 0.2)", "oklab(0 -10 10 / 0.2)",
-"oklab(-10% -10% 10% / 0.2)", "oklab(0 -0.04 0.04 / 0.2)",
-"oklab(-10 -10 10 / 1)", "oklab(0 -10 10)",
-"oklab(-10% -10% 10% / 1)", "oklab(0 -0.04 0.04)",
+"oklab(-10 -10 10)", "oklab(-10 -10 10)",
+"oklab(-10% -10% 10%)", "oklab(-0.1 -0.04 0.04)",
+"oklab(-10 -10 10 / 0)", "oklab(-10 -10 10 / 0)",
+"oklab(-10% -10% 10% / 0)", "oklab(-0.1 -0.04 0.04 / 0)",
+"oklab(-10 -10 10 / 0.2)", "oklab(-10 -10 10 / 0.2)",
+"oklab(-10% -10% 10% / 0.2)", "oklab(-0.1 -0.04 0.04 / 0.2)",
+"oklab(-10 -10 10 / 1)", "oklab(-10 -10 10)",
+"oklab(-10% -10% 10% / 1)", "oklab(-0.1 -0.04 0.04)",
 "oklab(0 0 110)", "oklab(0 0 110)",
 "oklab(0% 0% 110%)", "oklab(0 0 0.44)",
 "oklab(0 0 110 / 0)", "oklab(0 0 110 / 0)",
@@ -791,14 +791,14 @@
 "oklab(110% 0% 110% / 0.2)", "oklab(1.1 0 0.44 / 0.2)",
 "oklab(110 0 110 / 1)", "oklab(110 0 110)",
 "oklab(110% 0% 110% / 1)", "oklab(1.1 0 0.44)",
-"oklab(-10 0 110)", "oklab(0 0 110)",
-"oklab(-10% 0% 110%)", "oklab(0 0 0.44)",
-"oklab(-10 0 110 / 0)", "oklab(0 0 110 / 0)",
-"oklab(-10% 0% 110% / 0)", "oklab(0 0 0.44 / 0)",
-"oklab(-10 0 110 / 0.2)", "oklab(0 0 110 / 0.2)",
-"oklab(-10% 0% 110% / 0.2)", "oklab(0 0 0.44 / 0.2)",
-"oklab(-10 0 110 / 1)", "oklab(0 0 110)",
-"oklab(-10% 0% 110% / 1)", "oklab(0 0 0.44)",
+"oklab(-10 0 110)", "oklab(-10 0 110)",
+"oklab(-10% 0% 110%)", "oklab(-0.1 0 0.44)",
+"oklab(-10 0 110 / 0)", "oklab(-10 0 110 / 0)",
+"oklab(-10% 0% 110% / 0)", "oklab(-0.1 0 0.44 / 0)",
+"oklab(-10 0 110 / 0.2)", "oklab(-10 0 110 / 0.2)",
+"oklab(-10% 0% 110% / 0.2)", "oklab(-0.1 0 0.44 / 0.2)",
+"oklab(-10 0 110 / 1)", "oklab(-10 0 110)",
+"oklab(-10% 0% 110% / 1)", "oklab(-0.1 0 0.44)",
 "oklab(0 10 110)", "oklab(0 10 110)",
 "oklab(0% 10% 110%)", "oklab(0 0.04 0.44)",
 "oklab(0 10 110 / 0)", "oklab(0 10 110 / 0)",
@@ -823,14 +823,14 @@
 "oklab(110% 10% 110% / 0.2)", "oklab(1.1 0.04 0.44 / 0.2)",
 "oklab(110 10 110 / 1)", "oklab(110 10 110)",
 "oklab(110% 10% 110% / 1)", "oklab(1.1 0.04 0.44)",
-"oklab(-10 10 110)", "oklab(0 10 110)",
-"oklab(-10% 10% 110%)", "oklab(0 0.04 0.44)",
-"oklab(-10 10 110 / 0)", "oklab(0 10 110 / 0)",
-"oklab(-10% 10% 110% / 0)", "oklab(0 0.04 0.44 / 0)",
-"oklab(-10 10 110 / 0.2)", "oklab(0 10 110 / 0.2)",
-"oklab(-10% 10% 110% / 0.2)", "oklab(0 0.04 0.44 / 0.2)",
-"oklab(-10 10 110 / 1)", "oklab(0 10 110)",
-"oklab(-10% 10% 110% / 1)", "oklab(0 0.04 0.44)",
+"oklab(-10 10 110)", "oklab(-10 10 110)",
+"oklab(-10% 10% 110%)", "oklab(-0.1 0.04 0.44)",
+"oklab(-10 10 110 / 0)", "oklab(-10 10 110 / 0)",
+"oklab(-10% 10% 110% / 0)", "oklab(-0.1 0.04 0.44 / 0)",
+"oklab(-10 10 110 / 0.2)", "oklab(-10 10 110 / 0.2)",
+"oklab(-10% 10% 110% / 0.2)", "oklab(-0.1 0.04 0.44 / 0.2)",
+"oklab(-10 10 110 / 1)", "oklab(-10 10 110)",
+"oklab(-10% 10% 110% / 1)", "oklab(-0.1 0.04 0.44)",
 "oklab(0 110 110)", "oklab(0 110 110)",
 "oklab(0% 110% 110%)", "oklab(0 0.44 0.44)",
 "oklab(0 110 110 / 0)", "oklab(0 110 110 / 0)",
@@ -855,14 +855,14 @@
 "oklab(110% 110% 110% / 0.2)", "oklab(1.1 0.44 0.44 / 0.2)",
 "oklab(110 110 110 / 1)", "oklab(110 110 110)",
 "oklab(110% 110% 110% / 1)", "oklab(1.1 0.44 0.44)",
-"oklab(-10 110 110)", "oklab(0 110 110)",
-"oklab(-10% 110% 110%)", "oklab(0 0.44 0.44)",
-"oklab(-10 110 110 / 0)", "oklab(0 110 110 / 0)",
-"oklab(-10% 110% 110% / 0)", "oklab(0 0.44 0.44 / 0)",
-"oklab(-10 110 110 / 0.2)", "oklab(0 110 110 / 0.2)",
-"oklab(-10% 110% 110% / 0.2)", "oklab(0 0.44 0.44 / 0.2)",
-"oklab(-10 110 110 / 1)", "oklab(0 110 110)",
-"oklab(-10% 110% 110% / 1)", "oklab(0 0.44 0.44)",
+"oklab(-10 110 110)", "oklab(-10 110 110)",
+"oklab(-10% 110% 110%)", "oklab(-0.1 0.44 0.44)",
+"oklab(-10 110 110 / 0)", "oklab(-10 110 110 / 0)",
+"oklab(-10% 110% 110% / 0)", "oklab(-0.1 0.44 0.44 / 0)",
+"oklab(-10 110 110 / 0.2)", "oklab(-10 110 110 / 0.2)",
+"oklab(-10% 110% 110% / 0.2)", "oklab(-0.1 0.44 0.44 / 0.2)",
+"oklab(-10 110 110 / 1)", "oklab(-10 110 110)",
+"oklab(-10% 110% 110% / 1)", "oklab(-0.1 0.44 0.44)",
 "oklab(0 -10 110)", "oklab(0 -10 110)",
 "oklab(0% -10% 110%)", "oklab(0 -0.04 0.44)",
 "oklab(0 -10 110 / 0)", "oklab(0 -10 110 / 0)",
@@ -887,14 +887,14 @@
 "oklab(110% -10% 110% / 0.2)", "oklab(1.1 -0.04 0.44 / 0.2)",
 "oklab(110 -10 110 / 1)", "oklab(110 -10 110)",
 "oklab(110% -10% 110% / 1)", "oklab(1.1 -0.04 0.44)",
-"oklab(-10 -10 110)", "oklab(0 -10 110)",
-"oklab(-10% -10% 110%)", "oklab(0 -0.04 0.44)",
-"oklab(-10 -10 110 / 0)", "oklab(0 -10 110 / 0)",
-"oklab(-10% -10% 110% / 0)", "oklab(0 -0.04 0.44 / 0)",
-"oklab(-10 -10 110 / 0.2)", "oklab(0 -10 110 / 0.2)",
-"oklab(-10% -10% 110% / 0.2)", "oklab(0 -0.04 0.44 / 0.2)",
-"oklab(-10 -10 110 / 1)", "oklab(0 -10 110)",
-"oklab(-10% -10% 110% / 1)", "oklab(0 -0.04 0.44)",
+"oklab(-10 -10 110)", "oklab(-10 -10 110)",
+"oklab(-10% -10% 110%)", "oklab(-0.1 -0.04 0.44)",
+"oklab(-10 -10 110 / 0)", "oklab(-10 -10 110 / 0)",
+"oklab(-10% -10% 110% / 0)", "oklab(-0.1 -0.04 0.44 / 0)",
+"oklab(-10 -10 110 / 0.2)", "oklab(-10 -10 110 / 0.2)",
+"oklab(-10% -10% 110% / 0.2)", "oklab(-0.1 -0.04 0.44 / 0.2)",
+"oklab(-10 -10 110 / 1)", "oklab(-10 -10 110)",
+"oklab(-10% -10% 110% / 1)", "oklab(-0.1 -0.04 0.44)",
 "oklab(0 0 -10)", "oklab(0 0 -10)",
 "oklab(0% 0% -10%)", "oklab(0 0 -0.04)",
 "oklab(0 0 -10 / 0)", "oklab(0 0 -10 / 0)",
@@ -919,14 +919,14 @@
 "oklab(110% 0% -10% / 0.2)", "oklab(1.1 0 -0.04 / 0.2)",
 "oklab(110 0 -10 / 1)", "oklab(110 0 -10)",
 "oklab(110% 0% -10% / 1)", "oklab(1.1 0 -0.04)",
-"oklab(-10 0 -10)", "oklab(0 0 -10)",
-"oklab(-10% 0% -10%)", "oklab(0 0 -0.04)",
-"oklab(-10 0 -10 / 0)", "oklab(0 0 -10 / 0)",
-"oklab(-10% 0% -10% / 0)", "oklab(0 0 -0.04 / 0)",
-"oklab(-10 0 -10 / 0.2)", "oklab(0 0 -10 / 0.2)",
-"oklab(-10% 0% -10% / 0.2)", "oklab(0 0 -0.04 / 0.2)",
-"oklab(-10 0 -10 / 1)", "oklab(0 0 -10)",
-"oklab(-10% 0% -10% / 1)", "oklab(0 0 -0.04)",
+"oklab(-10 0 -10)", "oklab(-10 0 -10)",
+"oklab(-10% 0% -10%)", "oklab(-0.1 0 -0.04)",
+"oklab(-10 0 -10 / 0)", "oklab(-10 0 -10 / 0)",
+"oklab(-10% 0% -10% / 0)", "oklab(-0.1 0 -0.04 / 0)",
+"oklab(-10 0 -10 / 0.2)", "oklab(-10 0 -10 / 0.2)",
+"oklab(-10% 0% -10% / 0.2)", "oklab(-0.1 0 -0.04 / 0.2)",
+"oklab(-10 0 -10 / 1)", "oklab(-10 0 -10)",
+"oklab(-10% 0% -10% / 1)", "oklab(-0.1 0 -0.04)",
 "oklab(0 10 -10)", "oklab(0 10 -10)",
 "oklab(0% 10% -10%)", "oklab(0 0.04 -0.04)",
 "oklab(0 10 -10 / 0)", "oklab(0 10 -10 / 0)",
@@ -951,14 +951,14 @@
 "oklab(110% 10% -10% / 0.2)", "oklab(1.1 0.04 -0.04 / 0.2)",
 "oklab(110 10 -10 / 1)", "oklab(110 10 -10)",
 "oklab(110% 10% -10% / 1)", "oklab(1.1 0.04 -0.04)",
-"oklab(-10 10 -10)", "oklab(0 10 -10)",
-"oklab(-10% 10% -10%)", "oklab(0 0.04 -0.04)",
-"oklab(-10 10 -10 / 0)", "oklab(0 10 -10 / 0)",
-"oklab(-10% 10% -10% / 0)", "oklab(0 0.04 -0.04 / 0)",
-"oklab(-10 10 -10 / 0.2)", "oklab(0 10 -10 / 0.2)",
-"oklab(-10% 10% -10% / 0.2)", "oklab(0 0.04 -0.04 / 0.2)",
-"oklab(-10 10 -10 / 1)", "oklab(0 10 -10)",
-"oklab(-10% 10% -10% / 1)", "oklab(0 0.04 -0.04)",
+"oklab(-10 10 -10)", "oklab(-10 10 -10)",
+"oklab(-10% 10% -10%)", "oklab(-0.1 0.04 -0.04)",
+"oklab(-10 10 -10 / 0)", "oklab(-10 10 -10 / 0)",
+"oklab(-10% 10% -10% / 0)", "oklab(-0.1 0.04 -0.04 / 0)",
+"oklab(-10 10 -10 / 0.2)", "oklab(-10 10 -10 / 0.2)",
+"oklab(-10% 10% -10% / 0.2)", "oklab(-0.1 0.04 -0.04 / 0.2)",
+"oklab(-10 10 -10 / 1)", "oklab(-10 10 -10)",
+"oklab(-10% 10% -10% / 1)", "oklab(-0.1 0.04 -0.04)",
 "oklab(0 110 -10)", "oklab(0 110 -10)",
 "oklab(0% 110% -10%)", "oklab(0 0.44 -0.04)",
 "oklab(0 110 -10 / 0)", "oklab(0 110 -10 / 0)",
@@ -983,14 +983,14 @@
 "oklab(110% 110% -10% / 0.2)", "oklab(1.1 0.44 -0.04 / 0.2)",
 "oklab(110 110 -10 / 1)", "oklab(110 110 -10)",
 "oklab(110% 110% -10% / 1)", "oklab(1.1 0.44 -0.04)",
-"oklab(-10 110 -10)", "oklab(0 110 -10)",
-"oklab(-10% 110% -10%)", "oklab(0 0.44 -0.04)",
-"oklab(-10 110 -10 / 0)", "oklab(0 110 -10 / 0)",
-"oklab(-10% 110% -10% / 0)", "oklab(0 0.44 -0.04 / 0)",
-"oklab(-10 110 -10 / 0.2)", "oklab(0 110 -10 / 0.2)",
-"oklab(-10% 110% -10% / 0.2)", "oklab(0 0.44 -0.04 / 0.2)",
-"oklab(-10 110 -10 / 1)", "oklab(0 110 -10)",
-"oklab(-10% 110% -10% / 1)", "oklab(0 0.44 -0.04)",
+"oklab(-10 110 -10)", "oklab(-10 110 -10)",
+"oklab(-10% 110% -10%)", "oklab(-0.1 0.44 -0.04)",
+"oklab(-10 110 -10 / 0)", "oklab(-10 110 -10 / 0)",
+"oklab(-10% 110% -10% / 0)", "oklab(-0.1 0.44 -0.04 / 0)",
+"oklab(-10 110 -10 / 0.2)", "oklab(-10 110 -10 / 0.2)",
+"oklab(-10% 110% -10% / 0.2)", "oklab(-0.1 0.44 -0.04 / 0.2)",
+"oklab(-10 110 -10 / 1)", "oklab(-10 110 -10)",
+"oklab(-10% 110% -10% / 1)", "oklab(-0.1 0.44 -0.04)",
 "oklab(0 -10 -10)", "oklab(0 -10 -10)",
 "oklab(0% -10% -10%)", "oklab(0 -0.04 -0.04)",
 "oklab(0 -10 -10 / 0)", "oklab(0 -10 -10 / 0)",
@@ -1015,14 +1015,14 @@
 "oklab(110% -10% -10% / 0.2)", "oklab(1.1 -0.04 -0.04 / 0.2)",
 "oklab(110 -10 -10 / 1)", "oklab(110 -10 -10)",
 "oklab(110% -10% -10% / 1)", "oklab(1.1 -0.04 -0.04)",
-"oklab(-10 -10 -10)", "oklab(0 -10 -10)",
-"oklab(-10% -10% -10%)", "oklab(0 -0.04 -0.04)",
-"oklab(-10 -10 -10 / 0)", "oklab(0 -10 -10 / 0)",
-"oklab(-10% -10% -10% / 0)", "oklab(0 -0.04 -0.04 / 0)",
-"oklab(-10 -10 -10 / 0.2)", "oklab(0 -10 -10 / 0.2)",
-"oklab(-10% -10% -10% / 0.2)", "oklab(0 -0.04 -0.04 / 0.2)",
-"oklab(-10 -10 -10 / 1)", "oklab(0 -10 -10)",
-"oklab(-10% -10% -10% / 1)", "oklab(0 -0.04 -0.04)",
+"oklab(-10 -10 -10)", "oklab(-10 -10 -10)",
+"oklab(-10% -10% -10%)", "oklab(-0.1 -0.04 -0.04)",
+"oklab(-10 -10 -10 / 0)", "oklab(-10 -10 -10 / 0)",
+"oklab(-10% -10% -10% / 0)", "oklab(-0.1 -0.04 -0.04 / 0)",
+"oklab(-10 -10 -10 / 0.2)", "oklab(-10 -10 -10 / 0.2)",
+"oklab(-10% -10% -10% / 0.2)", "oklab(-0.1 -0.04 -0.04 / 0.2)",
+"oklab(-10 -10 -10 / 1)", "oklab(-10 -10 -10)",
+"oklab(-10% -10% -10% / 1)", "oklab(-0.1 -0.04 -0.04)",
 "lch(0 0 0)", "lch(0 0 0)",
 "lch(0% 0% 0deg)", "lch(0 0 0)",
 "lch(0 0 0 / 0)", "lch(0 0 0 / 0)",
@@ -1047,14 +1047,14 @@
 "lch(110% 0% 0deg / 0.2)", "lch(110 0 0 / 0.2)",
 "lch(110 0 0 / 1)", "lch(110 0 0)",
 "lch(110% 0% 0deg / 1)", "lch(110 0 0)",
-"lch(-10 0 0)", "lch(0 0 0)",
-"lch(-10% 0% 0deg)", "lch(0 0 0)",
-"lch(-10 0 0 / 0)", "lch(0 0 0 / 0)",
-"lch(-10% 0% 0deg / 0)", "lch(0 0 0 / 0)",
-"lch(-10 0 0 / 0.2)", "lch(0 0 0 / 0.2)",
-"lch(-10% 0% 0deg / 0.2)", "lch(0 0 0 / 0.2)",
-"lch(-10 0 0 / 1)", "lch(0 0 0)",
-"lch(-10% 0% 0deg / 1)", "lch(0 0 0)",
+"lch(-10 0 0)", "lch(-10 0 0)",
+"lch(-10% 0% 0deg)", "lch(-10 0 0)",
+"lch(-10 0 0 / 0)", "lch(-10 0 0 / 0)",
+"lch(-10% 0% 0deg / 0)", "lch(-10 0 0 / 0)",
+"lch(-10 0 0 / 0.2)", "lch(-10 0 0 / 0.2)",
+"lch(-10% 0% 0deg / 0.2)", "lch(-10 0 0 / 0.2)",
+"lch(-10 0 0 / 1)", "lch(-10 0 0)",
+"lch(-10% 0% 0deg / 1)", "lch(-10 0 0)",
 "lch(0 10 0)", "lch(0 10 0)",
 "lch(0% 10% 0deg)", "lch(0 15 0)",
 "lch(0 10 0 / 0)", "lch(0 10 0 / 0)",
@@ -1079,14 +1079,14 @@
 "lch(110% 10% 0deg / 0.2)", "lch(110 15 0 / 0.2)",
 "lch(110 10 0 / 1)", "lch(110 10 0)",
 "lch(110% 10% 0deg / 1)", "lch(110 15 0)",
-"lch(-10 10 0)", "lch(0 10 0)",
-"lch(-10% 10% 0deg)", "lch(0 15 0)",
-"lch(-10 10 0 / 0)", "lch(0 10 0 / 0)",
-"lch(-10% 10% 0deg / 0)", "lch(0 15 0 / 0)",
-"lch(-10 10 0 / 0.2)", "lch(0 10 0 / 0.2)",
-"lch(-10% 10% 0deg / 0.2)", "lch(0 15 0 / 0.2)",
-"lch(-10 10 0 / 1)", "lch(0 10 0)",
-"lch(-10% 10% 0deg / 1)", "lch(0 15 0)",
+"lch(-10 10 0)", "lch(-10 10 0)",
+"lch(-10% 10% 0deg)", "lch(-10 15 0)",
+"lch(-10 10 0 / 0)", "lch(-10 10 0 / 0)",
+"lch(-10% 10% 0deg / 0)", "lch(-10 15 0 / 0)",
+"lch(-10 10 0 / 0.2)", "lch(-10 10 0 / 0.2)",
+"lch(-10% 10% 0deg / 0.2)", "lch(-10 15 0 / 0.2)",
+"lch(-10 10 0 / 1)", "lch(-10 10 0)",
+"lch(-10% 10% 0deg / 1)", "lch(-10 15 0)",
 "lch(0 110 0)", "lch(0 110 0)",
 "lch(0% 110% 0deg)", "lch(0 165 0)",
 "lch(0 110 0 / 0)", "lch(0 110 0 / 0)",
@@ -1111,46 +1111,46 @@
 "lch(110% 110% 0deg / 0.2)", "lch(110 165 0 / 0.2)",
 "lch(110 110 0 / 1)", "lch(110 110 0)",
 "lch(110% 110% 0deg / 1)", "lch(110 165 0)",
-"lch(-10 110 0)", "lch(0 110 0)",
-"lch(-10% 110% 0deg)", "lch(0 165 0)",
-"lch(-10 110 0 / 0)", "lch(0 110 0 / 0)",
-"lch(-10% 110% 0deg / 0)", "lch(0 165 0 / 0)",
-"lch(-10 110 0 / 0.2)", "lch(0 110 0 / 0.2)",
-"lch(-10% 110% 0deg / 0.2)", "lch(0 165 0 / 0.2)",
-"lch(-10 110 0 / 1)", "lch(0 110 0)",
-"lch(-10% 110% 0deg / 1)", "lch(0 165 0)",
-"lch(0 -10 0)", "lch(0 0 0)",
-"lch(0% -10% 0deg)", "lch(0 0 0)",
-"lch(0 -10 0 / 0)", "lch(0 0 0 / 0)",
-"lch(0% -10% 0deg / 0)", "lch(0 0 0 / 0)",
-"lch(0 -10 0 / 0.2)", "lch(0 0 0 / 0.2)",
-"lch(0% -10% 0deg / 0.2)", "lch(0 0 0 / 0.2)",
-"lch(0 -10 0 / 1)", "lch(0 0 0)",
-"lch(0% -10% 0deg / 1)", "lch(0 0 0)",
-"lch(10 -10 0)", "lch(10 0 0)",
-"lch(10% -10% 0deg)", "lch(10 0 0)",
-"lch(10 -10 0 / 0)", "lch(10 0 0 / 0)",
-"lch(10% -10% 0deg / 0)", "lch(10 0 0 / 0)",
-"lch(10 -10 0 / 0.2)", "lch(10 0 0 / 0.2)",
-"lch(10% -10% 0deg / 0.2)", "lch(10 0 0 / 0.2)",
-"lch(10 -10 0 / 1)", "lch(10 0 0)",
-"lch(10% -10% 0deg / 1)", "lch(10 0 0)",
-"lch(110 -10 0)", "lch(110 0 0)",
-"lch(110% -10% 0deg)", "lch(110 0 0)",
-"lch(110 -10 0 / 0)", "lch(110 0 0 / 0)",
-"lch(110% -10% 0deg / 0)", "lch(110 0 0 / 0)",
-"lch(110 -10 0 / 0.2)", "lch(110 0 0 / 0.2)",
-"lch(110% -10% 0deg / 0.2)", "lch(110 0 0 / 0.2)",
-"lch(110 -10 0 / 1)", "lch(110 0 0)",
-"lch(110% -10% 0deg / 1)", "lch(110 0 0)",
-"lch(-10 -10 0)", "lch(0 0 0)",
-"lch(-10% -10% 0deg)", "lch(0 0 0)",
-"lch(-10 -10 0 / 0)", "lch(0 0 0 / 0)",
-"lch(-10% -10% 0deg / 0)", "lch(0 0 0 / 0)",
-"lch(-10 -10 0 / 0.2)", "lch(0 0 0 / 0.2)",
-"lch(-10% -10% 0deg / 0.2)", "lch(0 0 0 / 0.2)",
-"lch(-10 -10 0 / 1)", "lch(0 0 0)",
-"lch(-10% -10% 0deg / 1)", "lch(0 0 0)",
+"lch(-10 110 0)", "lch(-10 110 0)",
+"lch(-10% 110% 0deg)", "lch(-10 165 0)",
+"lch(-10 110 0 / 0)", "lch(-10 110 0 / 0)",
+"lch(-10% 110% 0deg / 0)", "lch(-10 165 0 / 0)",
+"lch(-10 110 0 / 0.2)", "lch(-10 110 0 / 0.2)",
+"lch(-10% 110% 0deg / 0.2)", "lch(-10 165 0 / 0.2)",
+"lch(-10 110 0 / 1)", "lch(-10 110 0)",
+"lch(-10% 110% 0deg / 1)", "lch(-10 165 0)",
+"lch(0 -10 0)", "lch(0 -10 0)",
+"lch(0% -10% 0deg)", "lch(0 -15 0)",
+"lch(0 -10 0 / 0)", "lch(0 -10 0 / 0)",
+"lch(0% -10% 0deg / 0)", "lch(0 -15 0 / 0)",
+"lch(0 -10 0 / 0.2)", "lch(0 -10 0 / 0.2)",
+"lch(0% -10% 0deg / 0.2)", "lch(0 -15 0 / 0.2)",
+"lch(0 -10 0 / 1)", "lch(0 -10 0)",
+"lch(0% -10% 0deg / 1)", "lch(0 -15 0)",
+"lch(10 -10 0)", "lch(10 -10 0)",
+"lch(10% -10% 0deg)", "lch(10 -15 0)",
+"lch(10 -10 0 / 0)", "lch(10 -10 0 / 0)",
+"lch(10% -10% 0deg / 0)", "lch(10 -15 0 / 0)",
+"lch(10 -10 0 / 0.2)", "lch(10 -10 0 / 0.2)",
+"lch(10% -10% 0deg / 0.2)", "lch(10 -15 0 / 0.2)",
+"lch(10 -10 0 / 1)", "lch(10 -10 0)",
+"lch(10% -10% 0deg / 1)", "lch(10 -15 0)",
+"lch(110 -10 0)", "lch(110 -10 0)",
+"lch(110% -10% 0deg)", "lch(110 -15 0)",
+"lch(110 -10 0 / 0)", "lch(110 -10 0 / 0)",
+"lch(110% -10% 0deg / 0)", "lch(110 -15 0 / 0)",
+"lch(110 -10 0 / 0.2)", "lch(110 -10 0 / 0.2)",
+"lch(110% -10% 0deg / 0.2)", "lch(110 -15 0 / 0.2)",
+"lch(110 -10 0 / 1)", "lch(110 -10 0)",
+"lch(110% -10% 0deg / 1)", "lch(110 -15 0)",
+"lch(-10 -10 0)", "lch(-10 -10 0)",
+"lch(-10% -10% 0deg)", "lch(-10 -15 0)",
+"lch(-10 -10 0 / 0)", "lch(-10 -10 0 / 0)",
+"lch(-10% -10% 0deg / 0)", "lch(-10 -15 0 / 0)",
+"lch(-10 -10 0 / 0.2)", "lch(-10 -10 0 / 0.2)",
+"lch(-10% -10% 0deg / 0.2)", "lch(-10 -15 0 / 0.2)",
+"lch(-10 -10 0 / 1)", "lch(-10 -10 0)",
+"lch(-10% -10% 0deg / 1)", "lch(-10 -15 0)",
 "lch(0 0 30)", "lch(0 0 30)",
 "lch(0% 0% 30deg)", "lch(0 0 30)",
 "lch(0 0 30 / 0)", "lch(0 0 30 / 0)",
@@ -1175,14 +1175,14 @@
 "lch(110% 0% 30deg / 0.2)", "lch(110 0 30 / 0.2)",
 "lch(110 0 30 / 1)", "lch(110 0 30)",
 "lch(110% 0% 30deg / 1)", "lch(110 0 30)",
-"lch(-10 0 30)", "lch(0 0 30)",
-"lch(-10% 0% 30deg)", "lch(0 0 30)",
-"lch(-10 0 30 / 0)", "lch(0 0 30 / 0)",
-"lch(-10% 0% 30deg / 0)", "lch(0 0 30 / 0)",
-"lch(-10 0 30 / 0.2)", "lch(0 0 30 / 0.2)",
-"lch(-10% 0% 30deg / 0.2)", "lch(0 0 30 / 0.2)",
-"lch(-10 0 30 / 1)", "lch(0 0 30)",
-"lch(-10% 0% 30deg / 1)", "lch(0 0 30)",
+"lch(-10 0 30)", "lch(-10 0 30)",
+"lch(-10% 0% 30deg)", "lch(-10 0 30)",
+"lch(-10 0 30 / 0)", "lch(-10 0 30 / 0)",
+"lch(-10% 0% 30deg / 0)", "lch(-10 0 30 / 0)",
+"lch(-10 0 30 / 0.2)", "lch(-10 0 30 / 0.2)",
+"lch(-10% 0% 30deg / 0.2)", "lch(-10 0 30 / 0.2)",
+"lch(-10 0 30 / 1)", "lch(-10 0 30)",
+"lch(-10% 0% 30deg / 1)", "lch(-10 0 30)",
 "lch(0 10 30)", "lch(0 10 30)",
 "lch(0% 10% 30deg)", "lch(0 15 30)",
 "lch(0 10 30 / 0)", "lch(0 10 30 / 0)",
@@ -1207,14 +1207,14 @@
 "lch(110% 10% 30deg / 0.2)", "lch(110 15 30 / 0.2)",
 "lch(110 10 30 / 1)", "lch(110 10 30)",
 "lch(110% 10% 30deg / 1)", "lch(110 15 30)",
-"lch(-10 10 30)", "lch(0 10 30)",
-"lch(-10% 10% 30deg)", "lch(0 15 30)",
-"lch(-10 10 30 / 0)", "lch(0 10 30 / 0)",
-"lch(-10% 10% 30deg / 0)", "lch(0 15 30 / 0)",
-"lch(-10 10 30 / 0.2)", "lch(0 10 30 / 0.2)",
-"lch(-10% 10% 30deg / 0.2)", "lch(0 15 30 / 0.2)",
-"lch(-10 10 30 / 1)", "lch(0 10 30)",
-"lch(-10% 10% 30deg / 1)", "lch(0 15 30)",
+"lch(-10 10 30)", "lch(-10 10 30)",
+"lch(-10% 10% 30deg)", "lch(-10 15 30)",
+"lch(-10 10 30 / 0)", "lch(-10 10 30 / 0)",
+"lch(-10% 10% 30deg / 0)", "lch(-10 15 30 / 0)",
+"lch(-10 10 30 / 0.2)", "lch(-10 10 30 / 0.2)",
+"lch(-10% 10% 30deg / 0.2)", "lch(-10 15 30 / 0.2)",
+"lch(-10 10 30 / 1)", "lch(-10 10 30)",
+"lch(-10% 10% 30deg / 1)", "lch(-10 15 30)",
 "lch(0 110 30)", "lch(0 110 30)",
 "lch(0% 110% 30deg)", "lch(0 165 30)",
 "lch(0 110 30 / 0)", "lch(0 110 30 / 0)",
@@ -1239,46 +1239,46 @@
 "lch(110% 110% 30deg / 0.2)", "lch(110 165 30 / 0.2)",
 "lch(110 110 30 / 1)", "lch(110 110 30)",
 "lch(110% 110% 30deg / 1)", "lch(110 165 30)",
-"lch(-10 110 30)", "lch(0 110 30)",
-"lch(-10% 110% 30deg)", "lch(0 165 30)",
-"lch(-10 110 30 / 0)", "lch(0 110 30 / 0)",
-"lch(-10% 110% 30deg / 0)", "lch(0 165 30 / 0)",
-"lch(-10 110 30 / 0.2)", "lch(0 110 30 / 0.2)",
-"lch(-10% 110% 30deg / 0.2)", "lch(0 165 30 / 0.2)",
-"lch(-10 110 30 / 1)", "lch(0 110 30)",
-"lch(-10% 110% 30deg / 1)", "lch(0 165 30)",
-"lch(0 -10 30)", "lch(0 0 30)",
-"lch(0% -10% 30deg)", "lch(0 0 30)",
-"lch(0 -10 30 / 0)", "lch(0 0 30 / 0)",
-"lch(0% -10% 30deg / 0)", "lch(0 0 30 / 0)",
-"lch(0 -10 30 / 0.2)", "lch(0 0 30 / 0.2)",
-"lch(0% -10% 30deg / 0.2)", "lch(0 0 30 / 0.2)",
-"lch(0 -10 30 / 1)", "lch(0 0 30)",
-"lch(0% -10% 30deg / 1)", "lch(0 0 30)",
-"lch(10 -10 30)", "lch(10 0 30)",
-"lch(10% -10% 30deg)", "lch(10 0 30)",
-"lch(10 -10 30 / 0)", "lch(10 0 30 / 0)",
-"lch(10% -10% 30deg / 0)", "lch(10 0 30 / 0)",
-"lch(10 -10 30 / 0.2)", "lch(10 0 30 / 0.2)",
-"lch(10% -10% 30deg / 0.2)", "lch(10 0 30 / 0.2)",
-"lch(10 -10 30 / 1)", "lch(10 0 30)",
-"lch(10% -10% 30deg / 1)", "lch(10 0 30)",
-"lch(110 -10 30)", "lch(110 0 30)",
-"lch(110% -10% 30deg)", "lch(110 0 30)",
-"lch(110 -10 30 / 0)", "lch(110 0 30 / 0)",
-"lch(110% -10% 30deg / 0)", "lch(110 0 30 / 0)",
-"lch(110 -10 30 / 0.2)", "lch(110 0 30 / 0.2)",
-"lch(110% -10% 30deg / 0.2)", "lch(110 0 30 / 0.2)",
-"lch(110 -10 30 / 1)", "lch(110 0 30)",
-"lch(110% -10% 30deg / 1)", "lch(110 0 30)",
-"lch(-10 -10 30)", "lch(0 0 30)",
-"lch(-10% -10% 30deg)", "lch(0 0 30)",
-"lch(-10 -10 30 / 0)", "lch(0 0 30 / 0)",
-"lch(-10% -10% 30deg / 0)", "lch(0 0 30 / 0)",
-"lch(-10 -10 30 / 0.2)", "lch(0 0 30 / 0.2)",
-"lch(-10% -10% 30deg / 0.2)", "lch(0 0 30 / 0.2)",
-"lch(-10 -10 30 / 1)", "lch(0 0 30)",
-"lch(-10% -10% 30deg / 1)", "lch(0 0 30)",
+"lch(-10 110 30)", "lch(-10 110 30)",
+"lch(-10% 110% 30deg)", "lch(-10 165 30)",
+"lch(-10 110 30 / 0)", "lch(-10 110 30 / 0)",
+"lch(-10% 110% 30deg / 0)", "lch(-10 165 30 / 0)",
+"lch(-10 110 30 / 0.2)", "lch(-10 110 30 / 0.2)",
+"lch(-10% 110% 30deg / 0.2)", "lch(-10 165 30 / 0.2)",
+"lch(-10 110 30 / 1)", "lch(-10 110 30)",
+"lch(-10% 110% 30deg / 1)", "lch(-10 165 30)",
+"lch(0 -10 30)", "lch(0 -10 30)",
+"lch(0% -10% 30deg)", "lch(0 -15 30)",
+"lch(0 -10 30 / 0)", "lch(0 -10 30 / 0)",
+"lch(0% -10% 30deg / 0)", "lch(0 -15 30 / 0)",
+"lch(0 -10 30 / 0.2)", "lch(0 -10 30 / 0.2)",
+"lch(0% -10% 30deg / 0.2)", "lch(0 -15 30 / 0.2)",
+"lch(0 -10 30 / 1)", "lch(0 -10 30)",
+"lch(0% -10% 30deg / 1)", "lch(0 -15 30)",
+"lch(10 -10 30)", "lch(10 -10 30)",
+"lch(10% -10% 30deg)", "lch(10 -15 30)",
+"lch(10 -10 30 / 0)", "lch(10 -10 30 / 0)",
+"lch(10% -10% 30deg / 0)", "lch(10 -15 30 / 0)",
+"lch(10 -10 30 / 0.2)", "lch(10 -10 30 / 0.2)",
+"lch(10% -10% 30deg / 0.2)", "lch(10 -15 30 / 0.2)",
+"lch(10 -10 30 / 1)", "lch(10 -10 30)",
+"lch(10% -10% 30deg / 1)", "lch(10 -15 30)",
+"lch(110 -10 30)", "lch(110 -10 30)",
+"lch(110% -10% 30deg)", "lch(110 -15 30)",
+"lch(110 -10 30 / 0)", "lch(110 -10 30 / 0)",
+"lch(110% -10% 30deg / 0)", "lch(110 -15 30 / 0)",
+"lch(110 -10 30 / 0.2)", "lch(110 -10 30 / 0.2)",
+"lch(110% -10% 30deg / 0.2)", "lch(110 -15 30 / 0.2)",
+"lch(110 -10 30 / 1)", "lch(110 -10 30)",
+"lch(110% -10% 30deg / 1)", "lch(110 -15 30)",
+"lch(-10 -10 30)", "lch(-10 -10 30)",
+"lch(-10% -10% 30deg)", "lch(-10 -15 30)",
+"lch(-10 -10 30 / 0)", "lch(-10 -10 30 / 0)",
+"lch(-10% -10% 30deg / 0)", "lch(-10 -15 30 / 0)",
+"lch(-10 -10 30 / 0.2)", "lch(-10 -10 30 / 0.2)",
+"lch(-10% -10% 30deg / 0.2)", "lch(-10 -15 30 / 0.2)",
+"lch(-10 -10 30 / 1)", "lch(-10 -10 30)",
+"lch(-10% -10% 30deg / 1)", "lch(-10 -15 30)",
 "lch(0 0 60)", "lch(0 0 60)",
 "lch(0% 0% 60deg)", "lch(0 0 60)",
 "lch(0 0 60 / 0)", "lch(0 0 60 / 0)",
@@ -1303,14 +1303,14 @@
 "lch(110% 0% 60deg / 0.2)", "lch(110 0 60 / 0.2)",
 "lch(110 0 60 / 1)", "lch(110 0 60)",
 "lch(110% 0% 60deg / 1)", "lch(110 0 60)",
-"lch(-10 0 60)", "lch(0 0 60)",
-"lch(-10% 0% 60deg)", "lch(0 0 60)",
-"lch(-10 0 60 / 0)", "lch(0 0 60 / 0)",
-"lch(-10% 0% 60deg / 0)", "lch(0 0 60 / 0)",
-"lch(-10 0 60 / 0.2)", "lch(0 0 60 / 0.2)",
-"lch(-10% 0% 60deg / 0.2)", "lch(0 0 60 / 0.2)",
-"lch(-10 0 60 / 1)", "lch(0 0 60)",
-"lch(-10% 0% 60deg / 1)", "lch(0 0 60)",
+"lch(-10 0 60)", "lch(-10 0 60)",
+"lch(-10% 0% 60deg)", "lch(-10 0 60)",
+"lch(-10 0 60 / 0)", "lch(-10 0 60 / 0)",
+"lch(-10% 0% 60deg / 0)", "lch(-10 0 60 / 0)",
+"lch(-10 0 60 / 0.2)", "lch(-10 0 60 / 0.2)",
+"lch(-10% 0% 60deg / 0.2)", "lch(-10 0 60 / 0.2)",
+"lch(-10 0 60 / 1)", "lch(-10 0 60)",
+"lch(-10% 0% 60deg / 1)", "lch(-10 0 60)",
 "lch(0 10 60)", "lch(0 10 60)",
 "lch(0% 10% 60deg)", "lch(0 15 60)",
 "lch(0 10 60 / 0)", "lch(0 10 60 / 0)",
@@ -1335,14 +1335,14 @@
 "lch(110% 10% 60deg / 0.2)", "lch(110 15 60 / 0.2)",
 "lch(110 10 60 / 1)", "lch(110 10 60)",
 "lch(110% 10% 60deg / 1)", "lch(110 15 60)",
-"lch(-10 10 60)", "lch(0 10 60)",
-"lch(-10% 10% 60deg)", "lch(0 15 60)",
-"lch(-10 10 60 / 0)", "lch(0 10 60 / 0)",
-"lch(-10% 10% 60deg / 0)", "lch(0 15 60 / 0)",
-"lch(-10 10 60 / 0.2)", "lch(0 10 60 / 0.2)",
-"lch(-10% 10% 60deg / 0.2)", "lch(0 15 60 / 0.2)",
-"lch(-10 10 60 / 1)", "lch(0 10 60)",
-"lch(-10% 10% 60deg / 1)", "lch(0 15 60)",
+"lch(-10 10 60)", "lch(-10 10 60)",
+"lch(-10% 10% 60deg)", "lch(-10 15 60)",
+"lch(-10 10 60 / 0)", "lch(-10 10 60 / 0)",
+"lch(-10% 10% 60deg / 0)", "lch(-10 15 60 / 0)",
+"lch(-10 10 60 / 0.2)", "lch(-10 10 60 / 0.2)",
+"lch(-10% 10% 60deg / 0.2)", "lch(-10 15 60 / 0.2)",
+"lch(-10 10 60 / 1)", "lch(-10 10 60)",
+"lch(-10% 10% 60deg / 1)", "lch(-10 15 60)",
 "lch(0 110 60)", "lch(0 110 60)",
 "lch(0% 110% 60deg)", "lch(0 165 60)",
 "lch(0 110 60 / 0)", "lch(0 110 60 / 0)",
@@ -1367,46 +1367,46 @@
 "lch(110% 110% 60deg / 0.2)", "lch(110 165 60 / 0.2)",
 "lch(110 110 60 / 1)", "lch(110 110 60)",
 "lch(110% 110% 60deg / 1)", "lch(110 165 60)",
-"lch(-10 110 60)", "lch(0 110 60)",
-"lch(-10% 110% 60deg)", "lch(0 165 60)",
-"lch(-10 110 60 / 0)", "lch(0 110 60 / 0)",
-"lch(-10% 110% 60deg / 0)", "lch(0 165 60 / 0)",
-"lch(-10 110 60 / 0.2)", "lch(0 110 60 / 0.2)",
-"lch(-10% 110% 60deg / 0.2)", "lch(0 165 60 / 0.2)",
-"lch(-10 110 60 / 1)", "lch(0 110 60)",
-"lch(-10% 110% 60deg / 1)", "lch(0 165 60)",
-"lch(0 -10 60)", "lch(0 0 60)",
-"lch(0% -10% 60deg)", "lch(0 0 60)",
-"lch(0 -10 60 / 0)", "lch(0 0 60 / 0)",
-"lch(0% -10% 60deg / 0)", "lch(0 0 60 / 0)",
-"lch(0 -10 60 / 0.2)", "lch(0 0 60 / 0.2)",
-"lch(0% -10% 60deg / 0.2)", "lch(0 0 60 / 0.2)",
-"lch(0 -10 60 / 1)", "lch(0 0 60)",
-"lch(0% -10% 60deg / 1)", "lch(0 0 60)",
-"lch(10 -10 60)", "lch(10 0 60)",
-"lch(10% -10% 60deg)", "lch(10 0 60)",
-"lch(10 -10 60 / 0)", "lch(10 0 60 / 0)",
-"lch(10% -10% 60deg / 0)", "lch(10 0 60 / 0)",
-"lch(10 -10 60 / 0.2)", "lch(10 0 60 / 0.2)",
-"lch(10% -10% 60deg / 0.2)", "lch(10 0 60 / 0.2)",
-"lch(10 -10 60 / 1)", "lch(10 0 60)",
-"lch(10% -10% 60deg / 1)", "lch(10 0 60)",
-"lch(110 -10 60)", "lch(110 0 60)",
-"lch(110% -10% 60deg)", "lch(110 0 60)",
-"lch(110 -10 60 / 0)", "lch(110 0 60 / 0)",
-"lch(110% -10% 60deg / 0)", "lch(110 0 60 / 0)",
-"lch(110 -10 60 / 0.2)", "lch(110 0 60 / 0.2)",
-"lch(110% -10% 60deg / 0.2)", "lch(110 0 60 / 0.2)",
-"lch(110 -10 60 / 1)", "lch(110 0 60)",
-"lch(110% -10% 60deg / 1)", "lch(110 0 60)",
-"lch(-10 -10 60)", "lch(0 0 60)",
-"lch(-10% -10% 60deg)", "lch(0 0 60)",
-"lch(-10 -10 60 / 0)", "lch(0 0 60 / 0)",
-"lch(-10% -10% 60deg / 0)", "lch(0 0 60 / 0)",
-"lch(-10 -10 60 / 0.2)", "lch(0 0 60 / 0.2)",
-"lch(-10% -10% 60deg / 0.2)", "lch(0 0 60 / 0.2)",
-"lch(-10 -10 60 / 1)", "lch(0 0 60)",
-"lch(-10% -10% 60deg / 1)", "lch(0 0 60)",
+"lch(-10 110 60)", "lch(-10 110 60)",
+"lch(-10% 110% 60deg)", "lch(-10 165 60)",
+"lch(-10 110 60 / 0)", "lch(-10 110 60 / 0)",
+"lch(-10% 110% 60deg / 0)", "lch(-10 165 60 / 0)",
+"lch(-10 110 60 / 0.2)", "lch(-10 110 60 / 0.2)",
+"lch(-10% 110% 60deg / 0.2)", "lch(-10 165 60 / 0.2)",
+"lch(-10 110 60 / 1)", "lch(-10 110 60)",
+"lch(-10% 110% 60deg / 1)", "lch(-10 165 60)",
+"lch(0 -10 60)", "lch(0 -10 60)",
+"lch(0% -10% 60deg)", "lch(0 -15 60)",
+"lch(0 -10 60 / 0)", "lch(0 -10 60 / 0)",
+"lch(0% -10% 60deg / 0)", "lch(0 -15 60 / 0)",
+"lch(0 -10 60 / 0.2)", "lch(0 -10 60 / 0.2)",
+"lch(0% -10% 60deg / 0.2)", "lch(0 -15 60 / 0.2)",
+"lch(0 -10 60 / 1)", "lch(0 -10 60)",
+"lch(0% -10% 60deg / 1)", "lch(0 -15 60)",
+"lch(10 -10 60)", "lch(10 -10 60)",
+"lch(10% -10% 60deg)", "lch(10 -15 60)",
+"lch(10 -10 60 / 0)", "lch(10 -10 60 / 0)",
+"lch(10% -10% 60deg / 0)", "lch(10 -15 60 / 0)",
+"lch(10 -10 60 / 0.2)", "lch(10 -10 60 / 0.2)",
+"lch(10% -10% 60deg / 0.2)", "lch(10 -15 60 / 0.2)",
+"lch(10 -10 60 / 1)", "lch(10 -10 60)",
+"lch(10% -10% 60deg / 1)", "lch(10 -15 60)",
+"lch(110 -10 60)", "lch(110 -10 60)",
+"lch(110% -10% 60deg)", "lch(110 -15 60)",
+"lch(110 -10 60 / 0)", "lch(110 -10 60 / 0)",
+"lch(110% -10% 60deg / 0)", "lch(110 -15 60 / 0)",
+"lch(110 -10 60 / 0.2)", "lch(110 -10 60 / 0.2)",
+"lch(110% -10% 60deg / 0.2)", "lch(110 -15 60 / 0.2)",
+"lch(110 -10 60 / 1)", "lch(110 -10 60)",
+"lch(110% -10% 60deg / 1)", "lch(110 -15 60)",
+"lch(-10 -10 60)", "lch(-10 -10 60)",
+"lch(-10% -10% 60deg)", "lch(-10 -15 60)",
+"lch(-10 -10 60 / 0)", "lch(-10 -10 60 / 0)",
+"lch(-10% -10% 60deg / 0)", "lch(-10 -15 60 / 0)",
+"lch(-10 -10 60 / 0.2)", "lch(-10 -10 60 / 0.2)",
+"lch(-10% -10% 60deg / 0.2)", "lch(-10 -15 60 / 0.2)",
+"lch(-10 -10 60 / 1)", "lch(-10 -10 60)",
+"lch(-10% -10% 60deg / 1)", "lch(-10 -15 60)",
 "lch(0 0 90)", "lch(0 0 90)",
 "lch(0% 0% 90deg)", "lch(0 0 90)",
 "lch(0 0 90 / 0)", "lch(0 0 90 / 0)",
@@ -1431,14 +1431,14 @@
 "lch(110% 0% 90deg / 0.2)", "lch(110 0 90 / 0.2)",
 "lch(110 0 90 / 1)", "lch(110 0 90)",
 "lch(110% 0% 90deg / 1)", "lch(110 0 90)",
-"lch(-10 0 90)", "lch(0 0 90)",
-"lch(-10% 0% 90deg)", "lch(0 0 90)",
-"lch(-10 0 90 / 0)", "lch(0 0 90 / 0)",
-"lch(-10% 0% 90deg / 0)", "lch(0 0 90 / 0)",
-"lch(-10 0 90 / 0.2)", "lch(0 0 90 / 0.2)",
-"lch(-10% 0% 90deg / 0.2)", "lch(0 0 90 / 0.2)",
-"lch(-10 0 90 / 1)", "lch(0 0 90)",
-"lch(-10% 0% 90deg / 1)", "lch(0 0 90)",
+"lch(-10 0 90)", "lch(-10 0 90)",
+"lch(-10% 0% 90deg)", "lch(-10 0 90)",
+"lch(-10 0 90 / 0)", "lch(-10 0 90 / 0)",
+"lch(-10% 0% 90deg / 0)", "lch(-10 0 90 / 0)",
+"lch(-10 0 90 / 0.2)", "lch(-10 0 90 / 0.2)",
+"lch(-10% 0% 90deg / 0.2)", "lch(-10 0 90 / 0.2)",
+"lch(-10 0 90 / 1)", "lch(-10 0 90)",
+"lch(-10% 0% 90deg / 1)", "lch(-10 0 90)",
 "lch(0 10 90)", "lch(0 10 90)",
 "lch(0% 10% 90deg)", "lch(0 15 90)",
 "lch(0 10 90 / 0)", "lch(0 10 90 / 0)",
@@ -1463,14 +1463,14 @@
 "lch(110% 10% 90deg / 0.2)", "lch(110 15 90 / 0.2)",
 "lch(110 10 90 / 1)", "lch(110 10 90)",
 "lch(110% 10% 90deg / 1)", "lch(110 15 90)",
-"lch(-10 10 90)", "lch(0 10 90)",
-"lch(-10% 10% 90deg)", "lch(0 15 90)",
-"lch(-10 10 90 / 0)", "lch(0 10 90 / 0)",
-"lch(-10% 10% 90deg / 0)", "lch(0 15 90 / 0)",
-"lch(-10 10 90 / 0.2)", "lch(0 10 90 / 0.2)",
-"lch(-10% 10% 90deg / 0.2)", "lch(0 15 90 / 0.2)",
-"lch(-10 10 90 / 1)", "lch(0 10 90)",
-"lch(-10% 10% 90deg / 1)", "lch(0 15 90)",
+"lch(-10 10 90)", "lch(-10 10 90)",
+"lch(-10% 10% 90deg)", "lch(-10 15 90)",
+"lch(-10 10 90 / 0)", "lch(-10 10 90 / 0)",
+"lch(-10% 10% 90deg / 0)", "lch(-10 15 90 / 0)",
+"lch(-10 10 90 / 0.2)", "lch(-10 10 90 / 0.2)",
+"lch(-10% 10% 90deg / 0.2)", "lch(-10 15 90 / 0.2)",
+"lch(-10 10 90 / 1)", "lch(-10 10 90)",
+"lch(-10% 10% 90deg / 1)", "lch(-10 15 90)",
 "lch(0 110 90)", "lch(0 110 90)",
 "lch(0% 110% 90deg)", "lch(0 165 90)",
 "lch(0 110 90 / 0)", "lch(0 110 90 / 0)",
@@ -1495,46 +1495,46 @@
 "lch(110% 110% 90deg / 0.2)", "lch(110 165 90 / 0.2)",
 "lch(110 110 90 / 1)", "lch(110 110 90)",
 "lch(110% 110% 90deg / 1)", "lch(110 165 90)",
-"lch(-10 110 90)", "lch(0 110 90)",
-"lch(-10% 110% 90deg)", "lch(0 165 90)",
-"lch(-10 110 90 / 0)", "lch(0 110 90 / 0)",
-"lch(-10% 110% 90deg / 0)", "lch(0 165 90 / 0)",
-"lch(-10 110 90 / 0.2)", "lch(0 110 90 / 0.2)",
-"lch(-10% 110% 90deg / 0.2)", "lch(0 165 90 / 0.2)",
-"lch(-10 110 90 / 1)", "lch(0 110 90)",
-"lch(-10% 110% 90deg / 1)", "lch(0 165 90)",
-"lch(0 -10 90)", "lch(0 0 90)",
-"lch(0% -10% 90deg)", "lch(0 0 90)",
-"lch(0 -10 90 / 0)", "lch(0 0 90 / 0)",
-"lch(0% -10% 90deg / 0)", "lch(0 0 90 / 0)",
-"lch(0 -10 90 / 0.2)", "lch(0 0 90 / 0.2)",
-"lch(0% -10% 90deg / 0.2)", "lch(0 0 90 / 0.2)",
-"lch(0 -10 90 / 1)", "lch(0 0 90)",
-"lch(0% -10% 90deg / 1)", "lch(0 0 90)",
-"lch(10 -10 90)", "lch(10 0 90)",
-"lch(10% -10% 90deg)", "lch(10 0 90)",
-"lch(10 -10 90 / 0)", "lch(10 0 90 / 0)",
-"lch(10% -10% 90deg / 0)", "lch(10 0 90 / 0)",
-"lch(10 -10 90 / 0.2)", "lch(10 0 90 / 0.2)",
-"lch(10% -10% 90deg / 0.2)", "lch(10 0 90 / 0.2)",
-"lch(10 -10 90 / 1)", "lch(10 0 90)",
-"lch(10% -10% 90deg / 1)", "lch(10 0 90)",
-"lch(110 -10 90)", "lch(110 0 90)",
-"lch(110% -10% 90deg)", "lch(110 0 90)",
-"lch(110 -10 90 / 0)", "lch(110 0 90 / 0)",
-"lch(110% -10% 90deg / 0)", "lch(110 0 90 / 0)",
-"lch(110 -10 90 / 0.2)", "lch(110 0 90 / 0.2)",
-"lch(110% -10% 90deg / 0.2)", "lch(110 0 90 / 0.2)",
-"lch(110 -10 90 / 1)", "lch(110 0 90)",
-"lch(110% -10% 90deg / 1)", "lch(110 0 90)",
-"lch(-10 -10 90)", "lch(0 0 90)",
-"lch(-10% -10% 90deg)", "lch(0 0 90)",
-"lch(-10 -10 90 / 0)", "lch(0 0 90 / 0)",
-"lch(-10% -10% 90deg / 0)", "lch(0 0 90 / 0)",
-"lch(-10 -10 90 / 0.2)", "lch(0 0 90 / 0.2)",
-"lch(-10% -10% 90deg / 0.2)", "lch(0 0 90 / 0.2)",
-"lch(-10 -10 90 / 1)", "lch(0 0 90)",
-"lch(-10% -10% 90deg / 1)", "lch(0 0 90)",
+"lch(-10 110 90)", "lch(-10 110 90)",
+"lch(-10% 110% 90deg)", "lch(-10 165 90)",
+"lch(-10 110 90 / 0)", "lch(-10 110 90 / 0)",
+"lch(-10% 110% 90deg / 0)", "lch(-10 165 90 / 0)",
+"lch(-10 110 90 / 0.2)", "lch(-10 110 90 / 0.2)",
+"lch(-10% 110% 90deg / 0.2)", "lch(-10 165 90 / 0.2)",
+"lch(-10 110 90 / 1)", "lch(-10 110 90)",
+"lch(-10% 110% 90deg / 1)", "lch(-10 165 90)",
+"lch(0 -10 90)", "lch(0 -10 90)",
+"lch(0% -10% 90deg)", "lch(0 -15 90)",
+"lch(0 -10 90 / 0)", "lch(0 -10 90 / 0)",
+"lch(0% -10% 90deg / 0)", "lch(0 -15 90 / 0)",
+"lch(0 -10 90 / 0.2)", "lch(0 -10 90 / 0.2)",
+"lch(0% -10% 90deg / 0.2)", "lch(0 -15 90 / 0.2)",
+"lch(0 -10 90 / 1)", "lch(0 -10 90)",
+"lch(0% -10% 90deg / 1)", "lch(0 -15 90)",
+"lch(10 -10 90)", "lch(10 -10 90)",
+"lch(10% -10% 90deg)", "lch(10 -15 90)",
+"lch(10 -10 90 / 0)", "lch(10 -10 90 / 0)",
+"lch(10% -10% 90deg / 0)", "lch(10 -15 90 / 0)",
+"lch(10 -10 90 / 0.2)", "lch(10 -10 90 / 0.2)",
+"lch(10% -10% 90deg / 0.2)", "lch(10 -15 90 / 0.2)",
+"lch(10 -10 90 / 1)", "lch(10 -10 90)",
+"lch(10% -10% 90deg / 1)", "lch(10 -15 90)",
+"lch(110 -10 90)", "lch(110 -10 90)",
+"lch(110% -10% 90deg)", "lch(110 -15 90)",
+"lch(110 -10 90 / 0)", "lch(110 -10 90 / 0)",
+"lch(110% -10% 90deg / 0)", "lch(110 -15 90 / 0)",
+"lch(110 -10 90 / 0.2)", "lch(110 -10 90 / 0.2)",
+"lch(110% -10% 90deg / 0.2)", "lch(110 -15 90 / 0.2)",
+"lch(110 -10 90 / 1)", "lch(110 -10 90)",
+"lch(110% -10% 90deg / 1)", "lch(110 -15 90)",
+"lch(-10 -10 90)", "lch(-10 -10 90)",
+"lch(-10% -10% 90deg)", "lch(-10 -15 90)",
+"lch(-10 -10 90 / 0)", "lch(-10 -10 90 / 0)",
+"lch(-10% -10% 90deg / 0)", "lch(-10 -15 90 / 0)",
+"lch(-10 -10 90 / 0.2)", "lch(-10 -10 90 / 0.2)",
+"lch(-10% -10% 90deg / 0.2)", "lch(-10 -15 90 / 0.2)",
+"lch(-10 -10 90 / 1)", "lch(-10 -10 90)",
+"lch(-10% -10% 90deg / 1)", "lch(-10 -15 90)",
 "lch(0 0 120)", "lch(0 0 120)",
 "lch(0% 0% 120deg)", "lch(0 0 120)",
 "lch(0 0 120 / 0)", "lch(0 0 120 / 0)",
@@ -1559,14 +1559,14 @@
 "lch(110% 0% 120deg / 0.2)", "lch(110 0 120 / 0.2)",
 "lch(110 0 120 / 1)", "lch(110 0 120)",
 "lch(110% 0% 120deg / 1)", "lch(110 0 120)",
-"lch(-10 0 120)", "lch(0 0 120)",
-"lch(-10% 0% 120deg)", "lch(0 0 120)",
-"lch(-10 0 120 / 0)", "lch(0 0 120 / 0)",
-"lch(-10% 0% 120deg / 0)", "lch(0 0 120 / 0)",
-"lch(-10 0 120 / 0.2)", "lch(0 0 120 / 0.2)",
-"lch(-10% 0% 120deg / 0.2)", "lch(0 0 120 / 0.2)",
-"lch(-10 0 120 / 1)", "lch(0 0 120)",
-"lch(-10% 0% 120deg / 1)", "lch(0 0 120)",
+"lch(-10 0 120)", "lch(-10 0 120)",
+"lch(-10% 0% 120deg)", "lch(-10 0 120)",
+"lch(-10 0 120 / 0)", "lch(-10 0 120 / 0)",
+"lch(-10% 0% 120deg / 0)", "lch(-10 0 120 / 0)",
+"lch(-10 0 120 / 0.2)", "lch(-10 0 120 / 0.2)",
+"lch(-10% 0% 120deg / 0.2)", "lch(-10 0 120 / 0.2)",
+"lch(-10 0 120 / 1)", "lch(-10 0 120)",
+"lch(-10% 0% 120deg / 1)", "lch(-10 0 120)",
 "lch(0 10 120)", "lch(0 10 120)",
 "lch(0% 10% 120deg)", "lch(0 15 120)",
 "lch(0 10 120 / 0)", "lch(0 10 120 / 0)",
@@ -1591,14 +1591,14 @@
 "lch(110% 10% 120deg / 0.2)", "lch(110 15 120 / 0.2)",
 "lch(110 10 120 / 1)", "lch(110 10 120)",
 "lch(110% 10% 120deg / 1)", "lch(110 15 120)",
-"lch(-10 10 120)", "lch(0 10 120)",
-"lch(-10% 10% 120deg)", "lch(0 15 120)",
-"lch(-10 10 120 / 0)", "lch(0 10 120 / 0)",
-"lch(-10% 10% 120deg / 0)", "lch(0 15 120 / 0)",
-"lch(-10 10 120 / 0.2)", "lch(0 10 120 / 0.2)",
-"lch(-10% 10% 120deg / 0.2)", "lch(0 15 120 / 0.2)",
-"lch(-10 10 120 / 1)", "lch(0 10 120)",
-"lch(-10% 10% 120deg / 1)", "lch(0 15 120)",
+"lch(-10 10 120)", "lch(-10 10 120)",
+"lch(-10% 10% 120deg)", "lch(-10 15 120)",
+"lch(-10 10 120 / 0)", "lch(-10 10 120 / 0)",
+"lch(-10% 10% 120deg / 0)", "lch(-10 15 120 / 0)",
+"lch(-10 10 120 / 0.2)", "lch(-10 10 120 / 0.2)",
+"lch(-10% 10% 120deg / 0.2)", "lch(-10 15 120 / 0.2)",
+"lch(-10 10 120 / 1)", "lch(-10 10 120)",
+"lch(-10% 10% 120deg / 1)", "lch(-10 15 120)",
 "lch(0 110 120)", "lch(0 110 120)",
 "lch(0% 110% 120deg)", "lch(0 165 120)",
 "lch(0 110 120 / 0)", "lch(0 110 120 / 0)",
@@ -1623,46 +1623,46 @@
 "lch(110% 110% 120deg / 0.2)", "lch(110 165 120 / 0.2)",
 "lch(110 110 120 / 1)", "lch(110 110 120)",
 "lch(110% 110% 120deg / 1)", "lch(110 165 120)",
-"lch(-10 110 120)", "lch(0 110 120)",
-"lch(-10% 110% 120deg)", "lch(0 165 120)",
-"lch(-10 110 120 / 0)", "lch(0 110 120 / 0)",
-"lch(-10% 110% 120deg / 0)", "lch(0 165 120 / 0)",
-"lch(-10 110 120 / 0.2)", "lch(0 110 120 / 0.2)",
-"lch(-10% 110% 120deg / 0.2)", "lch(0 165 120 / 0.2)",
-"lch(-10 110 120 / 1)", "lch(0 110 120)",
-"lch(-10% 110% 120deg / 1)", "lch(0 165 120)",
-"lch(0 -10 120)", "lch(0 0 120)",
-"lch(0% -10% 120deg)", "lch(0 0 120)",
-"lch(0 -10 120 / 0)", "lch(0 0 120 / 0)",
-"lch(0% -10% 120deg / 0)", "lch(0 0 120 / 0)",
-"lch(0 -10 120 / 0.2)", "lch(0 0 120 / 0.2)",
-"lch(0% -10% 120deg / 0.2)", "lch(0 0 120 / 0.2)",
-"lch(0 -10 120 / 1)", "lch(0 0 120)",
-"lch(0% -10% 120deg / 1)", "lch(0 0 120)",
-"lch(10 -10 120)", "lch(10 0 120)",
-"lch(10% -10% 120deg)", "lch(10 0 120)",
-"lch(10 -10 120 / 0)", "lch(10 0 120 / 0)",
-"lch(10% -10% 120deg / 0)", "lch(10 0 120 / 0)",
-"lch(10 -10 120 / 0.2)", "lch(10 0 120 / 0.2)",
-"lch(10% -10% 120deg / 0.2)", "lch(10 0 120 / 0.2)",
-"lch(10 -10 120 / 1)", "lch(10 0 120)",
-"lch(10% -10% 120deg / 1)", "lch(10 0 120)",
-"lch(110 -10 120)", "lch(110 0 120)",
-"lch(110% -10% 120deg)", "lch(110 0 120)",
-"lch(110 -10 120 / 0)", "lch(110 0 120 / 0)",
-"lch(110% -10% 120deg / 0)", "lch(110 0 120 / 0)",
-"lch(110 -10 120 / 0.2)", "lch(110 0 120 / 0.2)",
-"lch(110% -10% 120deg / 0.2)", "lch(110 0 120 / 0.2)",
-"lch(110 -10 120 / 1)", "lch(110 0 120)",
-"lch(110% -10% 120deg / 1)", "lch(110 0 120)",
-"lch(-10 -10 120)", "lch(0 0 120)",
-"lch(-10% -10% 120deg)", "lch(0 0 120)",
-"lch(-10 -10 120 / 0)", "lch(0 0 120 / 0)",
-"lch(-10% -10% 120deg / 0)", "lch(0 0 120 / 0)",
-"lch(-10 -10 120 / 0.2)", "lch(0 0 120 / 0.2)",
-"lch(-10% -10% 120deg / 0.2)", "lch(0 0 120 / 0.2)",
-"lch(-10 -10 120 / 1)", "lch(0 0 120)",
-"lch(-10% -10% 120deg / 1)", "lch(0 0 120)",
+"lch(-10 110 120)", "lch(-10 110 120)",
+"lch(-10% 110% 120deg)", "lch(-10 165 120)",
+"lch(-10 110 120 / 0)", "lch(-10 110 120 / 0)",
+"lch(-10% 110% 120deg / 0)", "lch(-10 165 120 / 0)",
+"lch(-10 110 120 / 0.2)", "lch(-10 110 120 / 0.2)",
+"lch(-10% 110% 120deg / 0.2)", "lch(-10 165 120 / 0.2)",
+"lch(-10 110 120 / 1)", "lch(-10 110 120)",
+"lch(-10% 110% 120deg / 1)", "lch(-10 165 120)",
+"lch(0 -10 120)", "lch(0 -10 120)",
+"lch(0% -10% 120deg)", "lch(0 -15 120)",
+"lch(0 -10 120 / 0)", "lch(0 -10 120 / 0)",
+"lch(0% -10% 120deg / 0)", "lch(0 -15 120 / 0)",
+"lch(0 -10 120 / 0.2)", "lch(0 -10 120 / 0.2)",
+"lch(0% -10% 120deg / 0.2)", "lch(0 -15 120 / 0.2)",
+"lch(0 -10 120 / 1)", "lch(0 -10 120)",
+"lch(0% -10% 120deg / 1)", "lch(0 -15 120)",
+"lch(10 -10 120)", "lch(10 -10 120)",
+"lch(10% -10% 120deg)", "lch(10 -15 120)",
+"lch(10 -10 120 / 0)", "lch(10 -10 120 / 0)",
+"lch(10% -10% 120deg / 0)", "lch(10 -15 120 / 0)",
+"lch(10 -10 120 / 0.2)", "lch(10 -10 120 / 0.2)",
+"lch(10% -10% 120deg / 0.2)", "lch(10 -15 120 / 0.2)",
+"lch(10 -10 120 / 1)", "lch(10 -10 120)",
+"lch(10% -10% 120deg / 1)", "lch(10 -15 120)",
+"lch(110 -10 120)", "lch(110 -10 120)",
+"lch(110% -10% 120deg)", "lch(110 -15 120)",
+"lch(110 -10 120 / 0)", "lch(110 -10 120 / 0)",
+"lch(110% -10% 120deg / 0)", "lch(110 -15 120 / 0)",
+"lch(110 -10 120 / 0.2)", "lch(110 -10 120 / 0.2)",
+"lch(110% -10% 120deg / 0.2)", "lch(110 -15 120 / 0.2)",
+"lch(110 -10 120 / 1)", "lch(110 -10 120)",
+"lch(110% -10% 120deg / 1)", "lch(110 -15 120)",
+"lch(-10 -10 120)", "lch(-10 -10 120)",
+"lch(-10% -10% 120deg)", "lch(-10 -15 120)",
+"lch(-10 -10 120 / 0)", "lch(-10 -10 120 / 0)",
+"lch(-10% -10% 120deg / 0)", "lch(-10 -15 120 / 0)",
+"lch(-10 -10 120 / 0.2)", "lch(-10 -10 120 / 0.2)",
+"lch(-10% -10% 120deg / 0.2)", "lch(-10 -15 120 / 0.2)",
+"lch(-10 -10 120 / 1)", "lch(-10 -10 120)",
+"lch(-10% -10% 120deg / 1)", "lch(-10 -15 120)",
 "lch(0 0 180)", "lch(0 0 180)",
 "lch(0% 0% 180deg)", "lch(0 0 180)",
 "lch(0 0 180 / 0)", "lch(0 0 180 / 0)",
@@ -1687,14 +1687,14 @@
 "lch(110% 0% 180deg / 0.2)", "lch(110 0 180 / 0.2)",
 "lch(110 0 180 / 1)", "lch(110 0 180)",
 "lch(110% 0% 180deg / 1)", "lch(110 0 180)",
-"lch(-10 0 180)", "lch(0 0 180)",
-"lch(-10% 0% 180deg)", "lch(0 0 180)",
-"lch(-10 0 180 / 0)", "lch(0 0 180 / 0)",
-"lch(-10% 0% 180deg / 0)", "lch(0 0 180 / 0)",
-"lch(-10 0 180 / 0.2)", "lch(0 0 180 / 0.2)",
-"lch(-10% 0% 180deg / 0.2)", "lch(0 0 180 / 0.2)",
-"lch(-10 0 180 / 1)", "lch(0 0 180)",
-"lch(-10% 0% 180deg / 1)", "lch(0 0 180)",
+"lch(-10 0 180)", "lch(-10 0 180)",
+"lch(-10% 0% 180deg)", "lch(-10 0 180)",
+"lch(-10 0 180 / 0)", "lch(-10 0 180 / 0)",
+"lch(-10% 0% 180deg / 0)", "lch(-10 0 180 / 0)",
+"lch(-10 0 180 / 0.2)", "lch(-10 0 180 / 0.2)",
+"lch(-10% 0% 180deg / 0.2)", "lch(-10 0 180 / 0.2)",
+"lch(-10 0 180 / 1)", "lch(-10 0 180)",
+"lch(-10% 0% 180deg / 1)", "lch(-10 0 180)",
 "lch(0 10 180)", "lch(0 10 180)",
 "lch(0% 10% 180deg)", "lch(0 15 180)",
 "lch(0 10 180 / 0)", "lch(0 10 180 / 0)",
@@ -1719,14 +1719,14 @@
 "lch(110% 10% 180deg / 0.2)", "lch(110 15 180 / 0.2)",
 "lch(110 10 180 / 1)", "lch(110 10 180)",
 "lch(110% 10% 180deg / 1)", "lch(110 15 180)",
-"lch(-10 10 180)", "lch(0 10 180)",
-"lch(-10% 10% 180deg)", "lch(0 15 180)",
-"lch(-10 10 180 / 0)", "lch(0 10 180 / 0)",
-"lch(-10% 10% 180deg / 0)", "lch(0 15 180 / 0)",
-"lch(-10 10 180 / 0.2)", "lch(0 10 180 / 0.2)",
-"lch(-10% 10% 180deg / 0.2)", "lch(0 15 180 / 0.2)",
-"lch(-10 10 180 / 1)", "lch(0 10 180)",
-"lch(-10% 10% 180deg / 1)", "lch(0 15 180)",
+"lch(-10 10 180)", "lch(-10 10 180)",
+"lch(-10% 10% 180deg)", "lch(-10 15 180)",
+"lch(-10 10 180 / 0)", "lch(-10 10 180 / 0)",
+"lch(-10% 10% 180deg / 0)", "lch(-10 15 180 / 0)",
+"lch(-10 10 180 / 0.2)", "lch(-10 10 180 / 0.2)",
+"lch(-10% 10% 180deg / 0.2)", "lch(-10 15 180 / 0.2)",
+"lch(-10 10 180 / 1)", "lch(-10 10 180)",
+"lch(-10% 10% 180deg / 1)", "lch(-10 15 180)",
 "lch(0 110 180)", "lch(0 110 180)",
 "lch(0% 110% 180deg)", "lch(0 165 180)",
 "lch(0 110 180 / 0)", "lch(0 110 180 / 0)",
@@ -1751,46 +1751,46 @@
 "lch(110% 110% 180deg / 0.2)", "lch(110 165 180 / 0.2)",
 "lch(110 110 180 / 1)", "lch(110 110 180)",
 "lch(110% 110% 180deg / 1)", "lch(110 165 180)",
-"lch(-10 110 180)", "lch(0 110 180)",
-"lch(-10% 110% 180deg)", "lch(0 165 180)",
-"lch(-10 110 180 / 0)", "lch(0 110 180 / 0)",
-"lch(-10% 110% 180deg / 0)", "lch(0 165 180 / 0)",
-"lch(-10 110 180 / 0.2)", "lch(0 110 180 / 0.2)",
-"lch(-10% 110% 180deg / 0.2)", "lch(0 165 180 / 0.2)",
-"lch(-10 110 180 / 1)", "lch(0 110 180)",
-"lch(-10% 110% 180deg / 1)", "lch(0 165 180)",
-"lch(0 -10 180)", "lch(0 0 180)",
-"lch(0% -10% 180deg)", "lch(0 0 180)",
-"lch(0 -10 180 / 0)", "lch(0 0 180 / 0)",
-"lch(0% -10% 180deg / 0)", "lch(0 0 180 / 0)",
-"lch(0 -10 180 / 0.2)", "lch(0 0 180 / 0.2)",
-"lch(0% -10% 180deg / 0.2)", "lch(0 0 180 / 0.2)",
-"lch(0 -10 180 / 1)", "lch(0 0 180)",
-"lch(0% -10% 180deg / 1)", "lch(0 0 180)",
-"lch(10 -10 180)", "lch(10 0 180)",
-"lch(10% -10% 180deg)", "lch(10 0 180)",
-"lch(10 -10 180 / 0)", "lch(10 0 180 / 0)",
-"lch(10% -10% 180deg / 0)", "lch(10 0 180 / 0)",
-"lch(10 -10 180 / 0.2)", "lch(10 0 180 / 0.2)",
-"lch(10% -10% 180deg / 0.2)", "lch(10 0 180 / 0.2)",
-"lch(10 -10 180 / 1)", "lch(10 0 180)",
-"lch(10% -10% 180deg / 1)", "lch(10 0 180)",
-"lch(110 -10 180)", "lch(110 0 180)",
-"lch(110% -10% 180deg)", "lch(110 0 180)",
-"lch(110 -10 180 / 0)", "lch(110 0 180 / 0)",
-"lch(110% -10% 180deg / 0)", "lch(110 0 180 / 0)",
-"lch(110 -10 180 / 0.2)", "lch(110 0 180 / 0.2)",
-"lch(110% -10% 180deg / 0.2)", "lch(110 0 180 / 0.2)",
-"lch(110 -10 180 / 1)", "lch(110 0 180)",
-"lch(110% -10% 180deg / 1)", "lch(110 0 180)",
-"lch(-10 -10 180)", "lch(0 0 180)",
-"lch(-10% -10% 180deg)", "lch(0 0 180)",
-"lch(-10 -10 180 / 0)", "lch(0 0 180 / 0)",
-"lch(-10% -10% 180deg / 0)", "lch(0 0 180 / 0)",
-"lch(-10 -10 180 / 0.2)", "lch(0 0 180 / 0.2)",
-"lch(-10% -10% 180deg / 0.2)", "lch(0 0 180 / 0.2)",
-"lch(-10 -10 180 / 1)", "lch(0 0 180)",
-"lch(-10% -10% 180deg / 1)", "lch(0 0 180)",
+"lch(-10 110 180)", "lch(-10 110 180)",
+"lch(-10% 110% 180deg)", "lch(-10 165 180)",
+"lch(-10 110 180 / 0)", "lch(-10 110 180 / 0)",
+"lch(-10% 110% 180deg / 0)", "lch(-10 165 180 / 0)",
+"lch(-10 110 180 / 0.2)", "lch(-10 110 180 / 0.2)",
+"lch(-10% 110% 180deg / 0.2)", "lch(-10 165 180 / 0.2)",
+"lch(-10 110 180 / 1)", "lch(-10 110 180)",
+"lch(-10% 110% 180deg / 1)", "lch(-10 165 180)",
+"lch(0 -10 180)", "lch(0 -10 180)",
+"lch(0% -10% 180deg)", "lch(0 -15 180)",
+"lch(0 -10 180 / 0)", "lch(0 -10 180 / 0)",
+"lch(0% -10% 180deg / 0)", "lch(0 -15 180 / 0)",
+"lch(0 -10 180 / 0.2)", "lch(0 -10 180 / 0.2)",
+"lch(0% -10% 180deg / 0.2)", "lch(0 -15 180 / 0.2)",
+"lch(0 -10 180 / 1)", "lch(0 -10 180)",
+"lch(0% -10% 180deg / 1)", "lch(0 -15 180)",
+"lch(10 -10 180)", "lch(10 -10 180)",
+"lch(10% -10% 180deg)", "lch(10 -15 180)",
+"lch(10 -10 180 / 0)", "lch(10 -10 180 / 0)",
+"lch(10% -10% 180deg / 0)", "lch(10 -15 180 / 0)",
+"lch(10 -10 180 / 0.2)", "lch(10 -10 180 / 0.2)",
+"lch(10% -10% 180deg / 0.2)", "lch(10 -15 180 / 0.2)",
+"lch(10 -10 180 / 1)", "lch(10 -10 180)",
+"lch(10% -10% 180deg / 1)", "lch(10 -15 180)",
+"lch(110 -10 180)", "lch(110 -10 180)",
+"lch(110% -10% 180deg)", "lch(110 -15 180)",
+"lch(110 -10 180 / 0)", "lch(110 -10 180 / 0)",
+"lch(110% -10% 180deg / 0)", "lch(110 -15 180 / 0)",
+"lch(110 -10 180 / 0.2)", "lch(110 -10 180 / 0.2)",
+"lch(110% -10% 180deg / 0.2)", "lch(110 -15 180 / 0.2)",
+"lch(110 -10 180 / 1)", "lch(110 -10 180)",
+"lch(110% -10% 180deg / 1)", "lch(110 -15 180)",
+"lch(-10 -10 180)", "lch(-10 -10 180)",
+"lch(-10% -10% 180deg)", "lch(-10 -15 180)",
+"lch(-10 -10 180 / 0)", "lch(-10 -10 180 / 0)",
+"lch(-10% -10% 180deg / 0)", "lch(-10 -15 180 / 0)",
+"lch(-10 -10 180 / 0.2)", "lch(-10 -10 180 / 0.2)",
+"lch(-10% -10% 180deg / 0.2)", "lch(-10 -15 180 / 0.2)",
+"lch(-10 -10 180 / 1)", "lch(-10 -10 180)",
+"lch(-10% -10% 180deg / 1)", "lch(-10 -15 180)",
 "lch(0 0 210)", "lch(0 0 210)",
 "lch(0% 0% 210deg)", "lch(0 0 210)",
 "lch(0 0 210 / 0)", "lch(0 0 210 / 0)",
@@ -1815,14 +1815,14 @@
 "lch(110% 0% 210deg / 0.2)", "lch(110 0 210 / 0.2)",
 "lch(110 0 210 / 1)", "lch(110 0 210)",
 "lch(110% 0% 210deg / 1)", "lch(110 0 210)",
-"lch(-10 0 210)", "lch(0 0 210)",
-"lch(-10% 0% 210deg)", "lch(0 0 210)",
-"lch(-10 0 210 / 0)", "lch(0 0 210 / 0)",
-"lch(-10% 0% 210deg / 0)", "lch(0 0 210 / 0)",
-"lch(-10 0 210 / 0.2)", "lch(0 0 210 / 0.2)",
-"lch(-10% 0% 210deg / 0.2)", "lch(0 0 210 / 0.2)",
-"lch(-10 0 210 / 1)", "lch(0 0 210)",
-"lch(-10% 0% 210deg / 1)", "lch(0 0 210)",
+"lch(-10 0 210)", "lch(-10 0 210)",
+"lch(-10% 0% 210deg)", "lch(-10 0 210)",
+"lch(-10 0 210 / 0)", "lch(-10 0 210 / 0)",
+"lch(-10% 0% 210deg / 0)", "lch(-10 0 210 / 0)",
+"lch(-10 0 210 / 0.2)", "lch(-10 0 210 / 0.2)",
+"lch(-10% 0% 210deg / 0.2)", "lch(-10 0 210 / 0.2)",
+"lch(-10 0 210 / 1)", "lch(-10 0 210)",
+"lch(-10% 0% 210deg / 1)", "lch(-10 0 210)",
 "lch(0 10 210)", "lch(0 10 210)",
 "lch(0% 10% 210deg)", "lch(0 15 210)",
 "lch(0 10 210 / 0)", "lch(0 10 210 / 0)",
@@ -1847,14 +1847,14 @@
 "lch(110% 10% 210deg / 0.2)", "lch(110 15 210 / 0.2)",
 "lch(110 10 210 / 1)", "lch(110 10 210)",
 "lch(110% 10% 210deg / 1)", "lch(110 15 210)",
-"lch(-10 10 210)", "lch(0 10 210)",
-"lch(-10% 10% 210deg)", "lch(0 15 210)",
-"lch(-10 10 210 / 0)", "lch(0 10 210 / 0)",
-"lch(-10% 10% 210deg / 0)", "lch(0 15 210 / 0)",
-"lch(-10 10 210 / 0.2)", "lch(0 10 210 / 0.2)",
-"lch(-10% 10% 210deg / 0.2)", "lch(0 15 210 / 0.2)",
-"lch(-10 10 210 / 1)", "lch(0 10 210)",
-"lch(-10% 10% 210deg / 1)", "lch(0 15 210)",
+"lch(-10 10 210)", "lch(-10 10 210)",
+"lch(-10% 10% 210deg)", "lch(-10 15 210)",
+"lch(-10 10 210 / 0)", "lch(-10 10 210 / 0)",
+"lch(-10% 10% 210deg / 0)", "lch(-10 15 210 / 0)",
+"lch(-10 10 210 / 0.2)", "lch(-10 10 210 / 0.2)",
+"lch(-10% 10% 210deg / 0.2)", "lch(-10 15 210 / 0.2)",
+"lch(-10 10 210 / 1)", "lch(-10 10 210)",
+"lch(-10% 10% 210deg / 1)", "lch(-10 15 210)",
 "lch(0 110 210)", "lch(0 110 210)",
 "lch(0% 110% 210deg)", "lch(0 165 210)",
 "lch(0 110 210 / 0)", "lch(0 110 210 / 0)",
@@ -1879,46 +1879,46 @@
 "lch(110% 110% 210deg / 0.2)", "lch(110 165 210 / 0.2)",
 "lch(110 110 210 / 1)", "lch(110 110 210)",
 "lch(110% 110% 210deg / 1)", "lch(110 165 210)",
-"lch(-10 110 210)", "lch(0 110 210)",
-"lch(-10% 110% 210deg)", "lch(0 165 210)",
-"lch(-10 110 210 / 0)", "lch(0 110 210 / 0)",
-"lch(-10% 110% 210deg / 0)", "lch(0 165 210 / 0)",
-"lch(-10 110 210 / 0.2)", "lch(0 110 210 / 0.2)",
-"lch(-10% 110% 210deg / 0.2)", "lch(0 165 210 / 0.2)",
-"lch(-10 110 210 / 1)", "lch(0 110 210)",
-"lch(-10% 110% 210deg / 1)", "lch(0 165 210)",
-"lch(0 -10 210)", "lch(0 0 210)",
-"lch(0% -10% 210deg)", "lch(0 0 210)",
-"lch(0 -10 210 / 0)", "lch(0 0 210 / 0)",
-"lch(0% -10% 210deg / 0)", "lch(0 0 210 / 0)",
-"lch(0 -10 210 / 0.2)", "lch(0 0 210 / 0.2)",
-"lch(0% -10% 210deg / 0.2)", "lch(0 0 210 / 0.2)",
-"lch(0 -10 210 / 1)", "lch(0 0 210)",
-"lch(0% -10% 210deg / 1)", "lch(0 0 210)",
-"lch(10 -10 210)", "lch(10 0 210)",
-"lch(10% -10% 210deg)", "lch(10 0 210)",
-"lch(10 -10 210 / 0)", "lch(10 0 210 / 0)",
-"lch(10% -10% 210deg / 0)", "lch(10 0 210 / 0)",
-"lch(10 -10 210 / 0.2)", "lch(10 0 210 / 0.2)",
-"lch(10% -10% 210deg / 0.2)", "lch(10 0 210 / 0.2)",
-"lch(10 -10 210 / 1)", "lch(10 0 210)",
-"lch(10% -10% 210deg / 1)", "lch(10 0 210)",
-"lch(110 -10 210)", "lch(110 0 210)",
-"lch(110% -10% 210deg)", "lch(110 0 210)",
-"lch(110 -10 210 / 0)", "lch(110 0 210 / 0)",
-"lch(110% -10% 210deg / 0)", "lch(110 0 210 / 0)",
-"lch(110 -10 210 / 0.2)", "lch(110 0 210 / 0.2)",
-"lch(110% -10% 210deg / 0.2)", "lch(110 0 210 / 0.2)",
-"lch(110 -10 210 / 1)", "lch(110 0 210)",
-"lch(110% -10% 210deg / 1)", "lch(110 0 210)",
-"lch(-10 -10 210)", "lch(0 0 210)",
-"lch(-10% -10% 210deg)", "lch(0 0 210)",
-"lch(-10 -10 210 / 0)", "lch(0 0 210 / 0)",
-"lch(-10% -10% 210deg / 0)", "lch(0 0 210 / 0)",
-"lch(-10 -10 210 / 0.2)", "lch(0 0 210 / 0.2)",
-"lch(-10% -10% 210deg / 0.2)", "lch(0 0 210 / 0.2)",
-"lch(-10 -10 210 / 1)", "lch(0 0 210)",
-"lch(-10% -10% 210deg / 1)", "lch(0 0 210)",
+"lch(-10 110 210)", "lch(-10 110 210)",
+"lch(-10% 110% 210deg)", "lch(-10 165 210)",
+"lch(-10 110 210 / 0)", "lch(-10 110 210 / 0)",
+"lch(-10% 110% 210deg / 0)", "lch(-10 165 210 / 0)",
+"lch(-10 110 210 / 0.2)", "lch(-10 110 210 / 0.2)",
+"lch(-10% 110% 210deg / 0.2)", "lch(-10 165 210 / 0.2)",
+"lch(-10 110 210 / 1)", "lch(-10 110 210)",
+"lch(-10% 110% 210deg / 1)", "lch(-10 165 210)",
+"lch(0 -10 210)", "lch(0 -10 210)",
+"lch(0% -10% 210deg)", "lch(0 -15 210)",
+"lch(0 -10 210 / 0)", "lch(0 -10 210 / 0)",
+"lch(0% -10% 210deg / 0)", "lch(0 -15 210 / 0)",
+"lch(0 -10 210 / 0.2)", "lch(0 -10 210 / 0.2)",
+"lch(0% -10% 210deg / 0.2)", "lch(0 -15 210 / 0.2)",
+"lch(0 -10 210 / 1)", "lch(0 -10 210)",
+"lch(0% -10% 210deg / 1)", "lch(0 -15 210)",
+"lch(10 -10 210)", "lch(10 -10 210)",
+"lch(10% -10% 210deg)", "lch(10 -15 210)",
+"lch(10 -10 210 / 0)", "lch(10 -10 210 / 0)",
+"lch(10% -10% 210deg / 0)", "lch(10 -15 210 / 0)",
+"lch(10 -10 210 / 0.2)", "lch(10 -10 210 / 0.2)",
+"lch(10% -10% 210deg / 0.2)", "lch(10 -15 210 / 0.2)",
+"lch(10 -10 210 / 1)", "lch(10 -10 210)",
+"lch(10% -10% 210deg / 1)", "lch(10 -15 210)",
+"lch(110 -10 210)", "lch(110 -10 210)",
+"lch(110% -10% 210deg)", "lch(110 -15 210)",
+"lch(110 -10 210 / 0)", "lch(110 -10 210 / 0)",
+"lch(110% -10% 210deg / 0)", "lch(110 -15 210 / 0)",
+"lch(110 -10 210 / 0.2)", "lch(110 -10 210 / 0.2)",
+"lch(110% -10% 210deg / 0.2)", "lch(110 -15 210 / 0.2)",
+"lch(110 -10 210 / 1)", "lch(110 -10 210)",
+"lch(110% -10% 210deg / 1)", "lch(110 -15 210)",
+"lch(-10 -10 210)", "lch(-10 -10 210)",
+"lch(-10% -10% 210deg)", "lch(-10 -15 210)",
+"lch(-10 -10 210 / 0)", "lch(-10 -10 210 / 0)",
+"lch(-10% -10% 210deg / 0)", "lch(-10 -15 210 / 0)",
+"lch(-10 -10 210 / 0.2)", "lch(-10 -10 210 / 0.2)",
+"lch(-10% -10% 210deg / 0.2)", "lch(-10 -15 210 / 0.2)",
+"lch(-10 -10 210 / 1)", "lch(-10 -10 210)",
+"lch(-10% -10% 210deg / 1)", "lch(-10 -15 210)",
 "lch(0 0 240)", "lch(0 0 240)",
 "lch(0% 0% 240deg)", "lch(0 0 240)",
 "lch(0 0 240 / 0)", "lch(0 0 240 / 0)",
@@ -1943,14 +1943,14 @@
 "lch(110% 0% 240deg / 0.2)", "lch(110 0 240 / 0.2)",
 "lch(110 0 240 / 1)", "lch(110 0 240)",
 "lch(110% 0% 240deg / 1)", "lch(110 0 240)",
-"lch(-10 0 240)", "lch(0 0 240)",
-"lch(-10% 0% 240deg)", "lch(0 0 240)",
-"lch(-10 0 240 / 0)", "lch(0 0 240 / 0)",
-"lch(-10% 0% 240deg / 0)", "lch(0 0 240 / 0)",
-"lch(-10 0 240 / 0.2)", "lch(0 0 240 / 0.2)",
-"lch(-10% 0% 240deg / 0.2)", "lch(0 0 240 / 0.2)",
-"lch(-10 0 240 / 1)", "lch(0 0 240)",
-"lch(-10% 0% 240deg / 1)", "lch(0 0 240)",
+"lch(-10 0 240)", "lch(-10 0 240)",
+"lch(-10% 0% 240deg)", "lch(-10 0 240)",
+"lch(-10 0 240 / 0)", "lch(-10 0 240 / 0)",
+"lch(-10% 0% 240deg / 0)", "lch(-10 0 240 / 0)",
+"lch(-10 0 240 / 0.2)", "lch(-10 0 240 / 0.2)",
+"lch(-10% 0% 240deg / 0.2)", "lch(-10 0 240 / 0.2)",
+"lch(-10 0 240 / 1)", "lch(-10 0 240)",
+"lch(-10% 0% 240deg / 1)", "lch(-10 0 240)",
 "lch(0 10 240)", "lch(0 10 240)",
 "lch(0% 10% 240deg)", "lch(0 15 240)",
 "lch(0 10 240 / 0)", "lch(0 10 240 / 0)",
@@ -1975,14 +1975,14 @@
 "lch(110% 10% 240deg / 0.2)", "lch(110 15 240 / 0.2)",
 "lch(110 10 240 / 1)", "lch(110 10 240)",
 "lch(110% 10% 240deg / 1)", "lch(110 15 240)",
-"lch(-10 10 240)", "lch(0 10 240)",
-"lch(-10% 10% 240deg)", "lch(0 15 240)",
-"lch(-10 10 240 / 0)", "lch(0 10 240 / 0)",
-"lch(-10% 10% 240deg / 0)", "lch(0 15 240 / 0)",
-"lch(-10 10 240 / 0.2)", "lch(0 10 240 / 0.2)",
-"lch(-10% 10% 240deg / 0.2)", "lch(0 15 240 / 0.2)",
-"lch(-10 10 240 / 1)", "lch(0 10 240)",
-"lch(-10% 10% 240deg / 1)", "lch(0 15 240)",
+"lch(-10 10 240)", "lch(-10 10 240)",
+"lch(-10% 10% 240deg)", "lch(-10 15 240)",
+"lch(-10 10 240 / 0)", "lch(-10 10 240 / 0)",
+"lch(-10% 10% 240deg / 0)", "lch(-10 15 240 / 0)",
+"lch(-10 10 240 / 0.2)", "lch(-10 10 240 / 0.2)",
+"lch(-10% 10% 240deg / 0.2)", "lch(-10 15 240 / 0.2)",
+"lch(-10 10 240 / 1)", "lch(-10 10 240)",
+"lch(-10% 10% 240deg / 1)", "lch(-10 15 240)",
 "lch(0 110 240)", "lch(0 110 240)",
 "lch(0% 110% 240deg)", "lch(0 165 240)",
 "lch(0 110 240 / 0)", "lch(0 110 240 / 0)",
@@ -2007,46 +2007,46 @@
 "lch(110% 110% 240deg / 0.2)", "lch(110 165 240 / 0.2)",
 "lch(110 110 240 / 1)", "lch(110 110 240)",
 "lch(110% 110% 240deg / 1)", "lch(110 165 240)",
-"lch(-10 110 240)", "lch(0 110 240)",
-"lch(-10% 110% 240deg)", "lch(0 165 240)",
-"lch(-10 110 240 / 0)", "lch(0 110 240 / 0)",
-"lch(-10% 110% 240deg / 0)", "lch(0 165 240 / 0)",
-"lch(-10 110 240 / 0.2)", "lch(0 110 240 / 0.2)",
-"lch(-10% 110% 240deg / 0.2)", "lch(0 165 240 / 0.2)",
-"lch(-10 110 240 / 1)", "lch(0 110 240)",
-"lch(-10% 110% 240deg / 1)", "lch(0 165 240)",
-"lch(0 -10 240)", "lch(0 0 240)",
-"lch(0% -10% 240deg)", "lch(0 0 240)",
-"lch(0 -10 240 / 0)", "lch(0 0 240 / 0)",
-"lch(0% -10% 240deg / 0)", "lch(0 0 240 / 0)",
-"lch(0 -10 240 / 0.2)", "lch(0 0 240 / 0.2)",
-"lch(0% -10% 240deg / 0.2)", "lch(0 0 240 / 0.2)",
-"lch(0 -10 240 / 1)", "lch(0 0 240)",
-"lch(0% -10% 240deg / 1)", "lch(0 0 240)",
-"lch(10 -10 240)", "lch(10 0 240)",
-"lch(10% -10% 240deg)", "lch(10 0 240)",
-"lch(10 -10 240 / 0)", "lch(10 0 240 / 0)",
-"lch(10% -10% 240deg / 0)", "lch(10 0 240 / 0)",
-"lch(10 -10 240 / 0.2)", "lch(10 0 240 / 0.2)",
-"lch(10% -10% 240deg / 0.2)", "lch(10 0 240 / 0.2)",
-"lch(10 -10 240 / 1)", "lch(10 0 240)",
-"lch(10% -10% 240deg / 1)", "lch(10 0 240)",
-"lch(110 -10 240)", "lch(110 0 240)",
-"lch(110% -10% 240deg)", "lch(110 0 240)",
-"lch(110 -10 240 / 0)", "lch(110 0 240 / 0)",
-"lch(110% -10% 240deg / 0)", "lch(110 0 240 / 0)",
-"lch(110 -10 240 / 0.2)", "lch(110 0 240 / 0.2)",
-"lch(110% -10% 240deg / 0.2)", "lch(110 0 240 / 0.2)",
-"lch(110 -10 240 / 1)", "lch(110 0 240)",
-"lch(110% -10% 240deg / 1)", "lch(110 0 240)",
-"lch(-10 -10 240)", "lch(0 0 240)",
-"lch(-10% -10% 240deg)", "lch(0 0 240)",
-"lch(-10 -10 240 / 0)", "lch(0 0 240 / 0)",
-"lch(-10% -10% 240deg / 0)", "lch(0 0 240 / 0)",
-"lch(-10 -10 240 / 0.2)", "lch(0 0 240 / 0.2)",
-"lch(-10% -10% 240deg / 0.2)", "lch(0 0 240 / 0.2)",
-"lch(-10 -10 240 / 1)", "lch(0 0 240)",
-"lch(-10% -10% 240deg / 1)", "lch(0 0 240)",
+"lch(-10 110 240)", "lch(-10 110 240)",
+"lch(-10% 110% 240deg)", "lch(-10 165 240)",
+"lch(-10 110 240 / 0)", "lch(-10 110 240 / 0)",
+"lch(-10% 110% 240deg / 0)", "lch(-10 165 240 / 0)",
+"lch(-10 110 240 / 0.2)", "lch(-10 110 240 / 0.2)",
+"lch(-10% 110% 240deg / 0.2)", "lch(-10 165 240 / 0.2)",
+"lch(-10 110 240 / 1)", "lch(-10 110 240)",
+"lch(-10% 110% 240deg / 1)", "lch(-10 165 240)",
+"lch(0 -10 240)", "lch(0 -10 240)",
+"lch(0% -10% 240deg)", "lch(0 -15 240)",
+"lch(0 -10 240 / 0)", "lch(0 -10 240 / 0)",
+"lch(0% -10% 240deg / 0)", "lch(0 -15 240 / 0)",
+"lch(0 -10 240 / 0.2)", "lch(0 -10 240 / 0.2)",
+"lch(0% -10% 240deg / 0.2)", "lch(0 -15 240 / 0.2)",
+"lch(0 -10 240 / 1)", "lch(0 -10 240)",
+"lch(0% -10% 240deg / 1)", "lch(0 -15 240)",
+"lch(10 -10 240)", "lch(10 -10 240)",
+"lch(10% -10% 240deg)", "lch(10 -15 240)",
+"lch(10 -10 240 / 0)", "lch(10 -10 240 / 0)",
+"lch(10% -10% 240deg / 0)", "lch(10 -15 240 / 0)",
+"lch(10 -10 240 / 0.2)", "lch(10 -10 240 / 0.2)",
+"lch(10% -10% 240deg / 0.2)", "lch(10 -15 240 / 0.2)",
+"lch(10 -10 240 / 1)", "lch(10 -10 240)",
+"lch(10% -10% 240deg / 1)", "lch(10 -15 240)",
+"lch(110 -10 240)", "lch(110 -10 240)",
+"lch(110% -10% 240deg)", "lch(110 -15 240)",
+"lch(110 -10 240 / 0)", "lch(110 -10 240 / 0)",
+"lch(110% -10% 240deg / 0)", "lch(110 -15 240 / 0)",
+"lch(110 -10 240 / 0.2)", "lch(110 -10 240 / 0.2)",
+"lch(110% -10% 240deg / 0.2)", "lch(110 -15 240 / 0.2)",
+"lch(110 -10 240 / 1)", "lch(110 -10 240)",
+"lch(110% -10% 240deg / 1)", "lch(110 -15 240)",
+"lch(-10 -10 240)", "lch(-10 -10 240)",
+"lch(-10% -10% 240deg)", "lch(-10 -15 240)",
+"lch(-10 -10 240 / 0)", "lch(-10 -10 240 / 0)",
+"lch(-10% -10% 240deg / 0)", "lch(-10 -15 240 / 0)",
+"lch(-10 -10 240 / 0.2)", "lch(-10 -10 240 / 0.2)",
+"lch(-10% -10% 240deg / 0.2)", "lch(-10 -15 240 / 0.2)",
+"lch(-10 -10 240 / 1)", "lch(-10 -10 240)",
+"lch(-10% -10% 240deg / 1)", "lch(-10 -15 240)",
 "lch(0 0 270)", "lch(0 0 270)",
 "lch(0% 0% 270deg)", "lch(0 0 270)",
 "lch(0 0 270 / 0)", "lch(0 0 270 / 0)",
@@ -2071,14 +2071,14 @@
 "lch(110% 0% 270deg / 0.2)", "lch(110 0 270 / 0.2)",
 "lch(110 0 270 / 1)", "lch(110 0 270)",
 "lch(110% 0% 270deg / 1)", "lch(110 0 270)",
-"lch(-10 0 270)", "lch(0 0 270)",
-"lch(-10% 0% 270deg)", "lch(0 0 270)",
-"lch(-10 0 270 / 0)", "lch(0 0 270 / 0)",
-"lch(-10% 0% 270deg / 0)", "lch(0 0 270 / 0)",
-"lch(-10 0 270 / 0.2)", "lch(0 0 270 / 0.2)",
-"lch(-10% 0% 270deg / 0.2)", "lch(0 0 270 / 0.2)",
-"lch(-10 0 270 / 1)", "lch(0 0 270)",
-"lch(-10% 0% 270deg / 1)", "lch(0 0 270)",
+"lch(-10 0 270)", "lch(-10 0 270)",
+"lch(-10% 0% 270deg)", "lch(-10 0 270)",
+"lch(-10 0 270 / 0)", "lch(-10 0 270 / 0)",
+"lch(-10% 0% 270deg / 0)", "lch(-10 0 270 / 0)",
+"lch(-10 0 270 / 0.2)", "lch(-10 0 270 / 0.2)",
+"lch(-10% 0% 270deg / 0.2)", "lch(-10 0 270 / 0.2)",
+"lch(-10 0 270 / 1)", "lch(-10 0 270)",
+"lch(-10% 0% 270deg / 1)", "lch(-10 0 270)",
 "lch(0 10 270)", "lch(0 10 270)",
 "lch(0% 10% 270deg)", "lch(0 15 270)",
 "lch(0 10 270 / 0)", "lch(0 10 270 / 0)",
@@ -2103,14 +2103,14 @@
 "lch(110% 10% 270deg / 0.2)", "lch(110 15 270 / 0.2)",
 "lch(110 10 270 / 1)", "lch(110 10 270)",
 "lch(110% 10% 270deg / 1)", "lch(110 15 270)",
-"lch(-10 10 270)", "lch(0 10 270)",
-"lch(-10% 10% 270deg)", "lch(0 15 270)",
-"lch(-10 10 270 / 0)", "lch(0 10 270 / 0)",
-"lch(-10% 10% 270deg / 0)", "lch(0 15 270 / 0)",
-"lch(-10 10 270 / 0.2)", "lch(0 10 270 / 0.2)",
-"lch(-10% 10% 270deg / 0.2)", "lch(0 15 270 / 0.2)",
-"lch(-10 10 270 / 1)", "lch(0 10 270)",
-"lch(-10% 10% 270deg / 1)", "lch(0 15 270)",
+"lch(-10 10 270)", "lch(-10 10 270)",
+"lch(-10% 10% 270deg)", "lch(-10 15 270)",
+"lch(-10 10 270 / 0)", "lch(-10 10 270 / 0)",
+"lch(-10% 10% 270deg / 0)", "lch(-10 15 270 / 0)",
+"lch(-10 10 270 / 0.2)", "lch(-10 10 270 / 0.2)",
+"lch(-10% 10% 270deg / 0.2)", "lch(-10 15 270 / 0.2)",
+"lch(-10 10 270 / 1)", "lch(-10 10 270)",
+"lch(-10% 10% 270deg / 1)", "lch(-10 15 270)",
 "lch(0 110 270)", "lch(0 110 270)",
 "lch(0% 110% 270deg)", "lch(0 165 270)",
 "lch(0 110 270 / 0)", "lch(0 110 270 / 0)",
@@ -2135,46 +2135,46 @@
 "lch(110% 110% 270deg / 0.2)", "lch(110 165 270 / 0.2)",
 "lch(110 110 270 / 1)", "lch(110 110 270)",
 "lch(110% 110% 270deg / 1)", "lch(110 165 270)",
-"lch(-10 110 270)", "lch(0 110 270)",
-"lch(-10% 110% 270deg)", "lch(0 165 270)",
-"lch(-10 110 270 / 0)", "lch(0 110 270 / 0)",
-"lch(-10% 110% 270deg / 0)", "lch(0 165 270 / 0)",
-"lch(-10 110 270 / 0.2)", "lch(0 110 270 / 0.2)",
-"lch(-10% 110% 270deg / 0.2)", "lch(0 165 270 / 0.2)",
-"lch(-10 110 270 / 1)", "lch(0 110 270)",
-"lch(-10% 110% 270deg / 1)", "lch(0 165 270)",
-"lch(0 -10 270)", "lch(0 0 270)",
-"lch(0% -10% 270deg)", "lch(0 0 270)",
-"lch(0 -10 270 / 0)", "lch(0 0 270 / 0)",
-"lch(0% -10% 270deg / 0)", "lch(0 0 270 / 0)",
-"lch(0 -10 270 / 0.2)", "lch(0 0 270 / 0.2)",
-"lch(0% -10% 270deg / 0.2)", "lch(0 0 270 / 0.2)",
-"lch(0 -10 270 / 1)", "lch(0 0 270)",
-"lch(0% -10% 270deg / 1)", "lch(0 0 270)",
-"lch(10 -10 270)", "lch(10 0 270)",
-"lch(10% -10% 270deg)", "lch(10 0 270)",
-"lch(10 -10 270 / 0)", "lch(10 0 270 / 0)",
-"lch(10% -10% 270deg / 0)", "lch(10 0 270 / 0)",
-"lch(10 -10 270 / 0.2)", "lch(10 0 270 / 0.2)",
-"lch(10% -10% 270deg / 0.2)", "lch(10 0 270 / 0.2)",
-"lch(10 -10 270 / 1)", "lch(10 0 270)",
-"lch(10% -10% 270deg / 1)", "lch(10 0 270)",
-"lch(110 -10 270)", "lch(110 0 270)",
-"lch(110% -10% 270deg)", "lch(110 0 270)",
-"lch(110 -10 270 / 0)", "lch(110 0 270 / 0)",
-"lch(110% -10% 270deg / 0)", "lch(110 0 270 / 0)",
-"lch(110 -10 270 / 0.2)", "lch(110 0 270 / 0.2)",
-"lch(110% -10% 270deg / 0.2)", "lch(110 0 270 / 0.2)",
-"lch(110 -10 270 / 1)", "lch(110 0 270)",
-"lch(110% -10% 270deg / 1)", "lch(110 0 270)",
-"lch(-10 -10 270)", "lch(0 0 270)",
-"lch(-10% -10% 270deg)", "lch(0 0 270)",
-"lch(-10 -10 270 / 0)", "lch(0 0 270 / 0)",
-"lch(-10% -10% 270deg / 0)", "lch(0 0 270 / 0)",
-"lch(-10 -10 270 / 0.2)", "lch(0 0 270 / 0.2)",
-"lch(-10% -10% 270deg / 0.2)", "lch(0 0 270 / 0.2)",
-"lch(-10 -10 270 / 1)", "lch(0 0 270)",
-"lch(-10% -10% 270deg / 1)", "lch(0 0 270)",
+"lch(-10 110 270)", "lch(-10 110 270)",
+"lch(-10% 110% 270deg)", "lch(-10 165 270)",
+"lch(-10 110 270 / 0)", "lch(-10 110 270 / 0)",
+"lch(-10% 110% 270deg / 0)", "lch(-10 165 270 / 0)",
+"lch(-10 110 270 / 0.2)", "lch(-10 110 270 / 0.2)",
+"lch(-10% 110% 270deg / 0.2)", "lch(-10 165 270 / 0.2)",
+"lch(-10 110 270 / 1)", "lch(-10 110 270)",
+"lch(-10% 110% 270deg / 1)", "lch(-10 165 270)",
+"lch(0 -10 270)", "lch(0 -10 270)",
+"lch(0% -10% 270deg)", "lch(0 -15 270)",
+"lch(0 -10 270 / 0)", "lch(0 -10 270 / 0)",
+"lch(0% -10% 270deg / 0)", "lch(0 -15 270 / 0)",
+"lch(0 -10 270 / 0.2)", "lch(0 -10 270 / 0.2)",
+"lch(0% -10% 270deg / 0.2)", "lch(0 -15 270 / 0.2)",
+"lch(0 -10 270 / 1)", "lch(0 -10 270)",
+"lch(0% -10% 270deg / 1)", "lch(0 -15 270)",
+"lch(10 -10 270)", "lch(10 -10 270)",
+"lch(10% -10% 270deg)", "lch(10 -15 270)",
+"lch(10 -10 270 / 0)", "lch(10 -10 270 / 0)",
+"lch(10% -10% 270deg / 0)", "lch(10 -15 270 / 0)",
+"lch(10 -10 270 / 0.2)", "lch(10 -10 270 / 0.2)",
+"lch(10% -10% 270deg / 0.2)", "lch(10 -15 270 / 0.2)",
+"lch(10 -10 270 / 1)", "lch(10 -10 270)",
+"lch(10% -10% 270deg / 1)", "lch(10 -15 270)",
+"lch(110 -10 270)", "lch(110 -10 270)",
+"lch(110% -10% 270deg)", "lch(110 -15 270)",
+"lch(110 -10 270 / 0)", "lch(110 -10 270 / 0)",
+"lch(110% -10% 270deg / 0)", "lch(110 -15 270 / 0)",
+"lch(110 -10 270 / 0.2)", "lch(110 -10 270 / 0.2)",
+"lch(110% -10% 270deg / 0.2)", "lch(110 -15 270 / 0.2)",
+"lch(110 -10 270 / 1)", "lch(110 -10 270)",
+"lch(110% -10% 270deg / 1)", "lch(110 -15 270)",
+"lch(-10 -10 270)", "lch(-10 -10 270)",
+"lch(-10% -10% 270deg)", "lch(-10 -15 270)",
+"lch(-10 -10 270 / 0)", "lch(-10 -10 270 / 0)",
+"lch(-10% -10% 270deg / 0)", "lch(-10 -15 270 / 0)",
+"lch(-10 -10 270 / 0.2)", "lch(-10 -10 270 / 0.2)",
+"lch(-10% -10% 270deg / 0.2)", "lch(-10 -15 270 / 0.2)",
+"lch(-10 -10 270 / 1)", "lch(-10 -10 270)",
+"lch(-10% -10% 270deg / 1)", "lch(-10 -15 270)",
 "lch(0 0 300)", "lch(0 0 300)",
 "lch(0% 0% 300deg)", "lch(0 0 300)",
 "lch(0 0 300 / 0)", "lch(0 0 300 / 0)",
@@ -2199,14 +2199,14 @@
 "lch(110% 0% 300deg / 0.2)", "lch(110 0 300 / 0.2)",
 "lch(110 0 300 / 1)", "lch(110 0 300)",
 "lch(110% 0% 300deg / 1)", "lch(110 0 300)",
-"lch(-10 0 300)", "lch(0 0 300)",
-"lch(-10% 0% 300deg)", "lch(0 0 300)",
-"lch(-10 0 300 / 0)", "lch(0 0 300 / 0)",
-"lch(-10% 0% 300deg / 0)", "lch(0 0 300 / 0)",
-"lch(-10 0 300 / 0.2)", "lch(0 0 300 / 0.2)",
-"lch(-10% 0% 300deg / 0.2)", "lch(0 0 300 / 0.2)",
-"lch(-10 0 300 / 1)", "lch(0 0 300)",
-"lch(-10% 0% 300deg / 1)", "lch(0 0 300)",
+"lch(-10 0 300)", "lch(-10 0 300)",
+"lch(-10% 0% 300deg)", "lch(-10 0 300)",
+"lch(-10 0 300 / 0)", "lch(-10 0 300 / 0)",
+"lch(-10% 0% 300deg / 0)", "lch(-10 0 300 / 0)",
+"lch(-10 0 300 / 0.2)", "lch(-10 0 300 / 0.2)",
+"lch(-10% 0% 300deg / 0.2)", "lch(-10 0 300 / 0.2)",
+"lch(-10 0 300 / 1)", "lch(-10 0 300)",
+"lch(-10% 0% 300deg / 1)", "lch(-10 0 300)",
 "lch(0 10 300)", "lch(0 10 300)",
 "lch(0% 10% 300deg)", "lch(0 15 300)",
 "lch(0 10 300 / 0)", "lch(0 10 300 / 0)",
@@ -2231,14 +2231,14 @@
 "lch(110% 10% 300deg / 0.2)", "lch(110 15 300 / 0.2)",
 "lch(110 10 300 / 1)", "lch(110 10 300)",
 "lch(110% 10% 300deg / 1)", "lch(110 15 300)",
-"lch(-10 10 300)", "lch(0 10 300)",
-"lch(-10% 10% 300deg)", "lch(0 15 300)",
-"lch(-10 10 300 / 0)", "lch(0 10 300 / 0)",
-"lch(-10% 10% 300deg / 0)", "lch(0 15 300 / 0)",
-"lch(-10 10 300 / 0.2)", "lch(0 10 300 / 0.2)",
-"lch(-10% 10% 300deg / 0.2)", "lch(0 15 300 / 0.2)",
-"lch(-10 10 300 / 1)", "lch(0 10 300)",
-"lch(-10% 10% 300deg / 1)", "lch(0 15 300)",
+"lch(-10 10 300)", "lch(-10 10 300)",
+"lch(-10% 10% 300deg)", "lch(-10 15 300)",
+"lch(-10 10 300 / 0)", "lch(-10 10 300 / 0)",
+"lch(-10% 10% 300deg / 0)", "lch(-10 15 300 / 0)",
+"lch(-10 10 300 / 0.2)", "lch(-10 10 300 / 0.2)",
+"lch(-10% 10% 300deg / 0.2)", "lch(-10 15 300 / 0.2)",
+"lch(-10 10 300 / 1)", "lch(-10 10 300)",
+"lch(-10% 10% 300deg / 1)", "lch(-10 15 300)",
 "lch(0 110 300)", "lch(0 110 300)",
 "lch(0% 110% 300deg)", "lch(0 165 300)",
 "lch(0 110 300 / 0)", "lch(0 110 300 / 0)",
@@ -2263,46 +2263,46 @@
 "lch(110% 110% 300deg / 0.2)", "lch(110 165 300 / 0.2)",
 "lch(110 110 300 / 1)", "lch(110 110 300)",
 "lch(110% 110% 300deg / 1)", "lch(110 165 300)",
-"lch(-10 110 300)", "lch(0 110 300)",
-"lch(-10% 110% 300deg)", "lch(0 165 300)",
-"lch(-10 110 300 / 0)", "lch(0 110 300 / 0)",
-"lch(-10% 110% 300deg / 0)", "lch(0 165 300 / 0)",
-"lch(-10 110 300 / 0.2)", "lch(0 110 300 / 0.2)",
-"lch(-10% 110% 300deg / 0.2)", "lch(0 165 300 / 0.2)",
-"lch(-10 110 300 / 1)", "lch(0 110 300)",
-"lch(-10% 110% 300deg / 1)", "lch(0 165 300)",
-"lch(0 -10 300)", "lch(0 0 300)",
-"lch(0% -10% 300deg)", "lch(0 0 300)",
-"lch(0 -10 300 / 0)", "lch(0 0 300 / 0)",
-"lch(0% -10% 300deg / 0)", "lch(0 0 300 / 0)",
-"lch(0 -10 300 / 0.2)", "lch(0 0 300 / 0.2)",
-"lch(0% -10% 300deg / 0.2)", "lch(0 0 300 / 0.2)",
-"lch(0 -10 300 / 1)", "lch(0 0 300)",
-"lch(0% -10% 300deg / 1)", "lch(0 0 300)",
-"lch(10 -10 300)", "lch(10 0 300)",
-"lch(10% -10% 300deg)", "lch(10 0 300)",
-"lch(10 -10 300 / 0)", "lch(10 0 300 / 0)",
-"lch(10% -10% 300deg / 0)", "lch(10 0 300 / 0)",
-"lch(10 -10 300 / 0.2)", "lch(10 0 300 / 0.2)",
-"lch(10% -10% 300deg / 0.2)", "lch(10 0 300 / 0.2)",
-"lch(10 -10 300 / 1)", "lch(10 0 300)",
-"lch(10% -10% 300deg / 1)", "lch(10 0 300)",
-"lch(110 -10 300)", "lch(110 0 300)",
-"lch(110% -10% 300deg)", "lch(110 0 300)",
-"lch(110 -10 300 / 0)", "lch(110 0 300 / 0)",
-"lch(110% -10% 300deg / 0)", "lch(110 0 300 / 0)",
-"lch(110 -10 300 / 0.2)", "lch(110 0 300 / 0.2)",
-"lch(110% -10% 300deg / 0.2)", "lch(110 0 300 / 0.2)",
-"lch(110 -10 300 / 1)", "lch(110 0 300)",
-"lch(110% -10% 300deg / 1)", "lch(110 0 300)",
-"lch(-10 -10 300)", "lch(0 0 300)",
-"lch(-10% -10% 300deg)", "lch(0 0 300)",
-"lch(-10 -10 300 / 0)", "lch(0 0 300 / 0)",
-"lch(-10% -10% 300deg / 0)", "lch(0 0 300 / 0)",
-"lch(-10 -10 300 / 0.2)", "lch(0 0 300 / 0.2)",
-"lch(-10% -10% 300deg / 0.2)", "lch(0 0 300 / 0.2)",
-"lch(-10 -10 300 / 1)", "lch(0 0 300)",
-"lch(-10% -10% 300deg / 1)", "lch(0 0 300)",
+"lch(-10 110 300)", "lch(-10 110 300)",
+"lch(-10% 110% 300deg)", "lch(-10 165 300)",
+"lch(-10 110 300 / 0)", "lch(-10 110 300 / 0)",
+"lch(-10% 110% 300deg / 0)", "lch(-10 165 300 / 0)",
+"lch(-10 110 300 / 0.2)", "lch(-10 110 300 / 0.2)",
+"lch(-10% 110% 300deg / 0.2)", "lch(-10 165 300 / 0.2)",
+"lch(-10 110 300 / 1)", "lch(-10 110 300)",
+"lch(-10% 110% 300deg / 1)", "lch(-10 165 300)",
+"lch(0 -10 300)", "lch(0 -10 300)",
+"lch(0% -10% 300deg)", "lch(0 -15 300)",
+"lch(0 -10 300 / 0)", "lch(0 -10 300 / 0)",
+"lch(0% -10% 300deg / 0)", "lch(0 -15 300 / 0)",
+"lch(0 -10 300 / 0.2)", "lch(0 -10 300 / 0.2)",
+"lch(0% -10% 300deg / 0.2)", "lch(0 -15 300 / 0.2)",
+"lch(0 -10 300 / 1)", "lch(0 -10 300)",
+"lch(0% -10% 300deg / 1)", "lch(0 -15 300)",
+"lch(10 -10 300)", "lch(10 -10 300)",
+"lch(10% -10% 300deg)", "lch(10 -15 300)",
+"lch(10 -10 300 / 0)", "lch(10 -10 300 / 0)",
+"lch(10% -10% 300deg / 0)", "lch(10 -15 300 / 0)",
+"lch(10 -10 300 / 0.2)", "lch(10 -10 300 / 0.2)",
+"lch(10% -10% 300deg / 0.2)", "lch(10 -15 300 / 0.2)",
+"lch(10 -10 300 / 1)", "lch(10 -10 300)",
+"lch(10% -10% 300deg / 1)", "lch(10 -15 300)",
+"lch(110 -10 300)", "lch(110 -10 300)",
+"lch(110% -10% 300deg)", "lch(110 -15 300)",
+"lch(110 -10 300 / 0)", "lch(110 -10 300 / 0)",
+"lch(110% -10% 300deg / 0)", "lch(110 -15 300 / 0)",
+"lch(110 -10 300 / 0.2)", "lch(110 -10 300 / 0.2)",
+"lch(110% -10% 300deg / 0.2)", "lch(110 -15 300 / 0.2)",
+"lch(110 -10 300 / 1)", "lch(110 -10 300)",
+"lch(110% -10% 300deg / 1)", "lch(110 -15 300)",
+"lch(-10 -10 300)", "lch(-10 -10 300)",
+"lch(-10% -10% 300deg)", "lch(-10 -15 300)",
+"lch(-10 -10 300 / 0)", "lch(-10 -10 300 / 0)",
+"lch(-10% -10% 300deg / 0)", "lch(-10 -15 300 / 0)",
+"lch(-10 -10 300 / 0.2)", "lch(-10 -10 300 / 0.2)",
+"lch(-10% -10% 300deg / 0.2)", "lch(-10 -15 300 / 0.2)",
+"lch(-10 -10 300 / 1)", "lch(-10 -10 300)",
+"lch(-10% -10% 300deg / 1)", "lch(-10 -15 300)",
 "lch(0 0 330)", "lch(0 0 330)",
 "lch(0% 0% 330deg)", "lch(0 0 330)",
 "lch(0 0 330 / 0)", "lch(0 0 330 / 0)",
@@ -2327,14 +2327,14 @@
 "lch(110% 0% 330deg / 0.2)", "lch(110 0 330 / 0.2)",
 "lch(110 0 330 / 1)", "lch(110 0 330)",
 "lch(110% 0% 330deg / 1)", "lch(110 0 330)",
-"lch(-10 0 330)", "lch(0 0 330)",
-"lch(-10% 0% 330deg)", "lch(0 0 330)",
-"lch(-10 0 330 / 0)", "lch(0 0 330 / 0)",
-"lch(-10% 0% 330deg / 0)", "lch(0 0 330 / 0)",
-"lch(-10 0 330 / 0.2)", "lch(0 0 330 / 0.2)",
-"lch(-10% 0% 330deg / 0.2)", "lch(0 0 330 / 0.2)",
-"lch(-10 0 330 / 1)", "lch(0 0 330)",
-"lch(-10% 0% 330deg / 1)", "lch(0 0 330)",
+"lch(-10 0 330)", "lch(-10 0 330)",
+"lch(-10% 0% 330deg)", "lch(-10 0 330)",
+"lch(-10 0 330 / 0)", "lch(-10 0 330 / 0)",
+"lch(-10% 0% 330deg / 0)", "lch(-10 0 330 / 0)",
+"lch(-10 0 330 / 0.2)", "lch(-10 0 330 / 0.2)",
+"lch(-10% 0% 330deg / 0.2)", "lch(-10 0 330 / 0.2)",
+"lch(-10 0 330 / 1)", "lch(-10 0 330)",
+"lch(-10% 0% 330deg / 1)", "lch(-10 0 330)",
 "lch(0 10 330)", "lch(0 10 330)",
 "lch(0% 10% 330deg)", "lch(0 15 330)",
 "lch(0 10 330 / 0)", "lch(0 10 330 / 0)",
@@ -2359,14 +2359,14 @@
 "lch(110% 10% 330deg / 0.2)", "lch(110 15 330 / 0.2)",
 "lch(110 10 330 / 1)", "lch(110 10 330)",
 "lch(110% 10% 330deg / 1)", "lch(110 15 330)",
-"lch(-10 10 330)", "lch(0 10 330)",
-"lch(-10% 10% 330deg)", "lch(0 15 330)",
-"lch(-10 10 330 / 0)", "lch(0 10 330 / 0)",
-"lch(-10% 10% 330deg / 0)", "lch(0 15 330 / 0)",
-"lch(-10 10 330 / 0.2)", "lch(0 10 330 / 0.2)",
-"lch(-10% 10% 330deg / 0.2)", "lch(0 15 330 / 0.2)",
-"lch(-10 10 330 / 1)", "lch(0 10 330)",
-"lch(-10% 10% 330deg / 1)", "lch(0 15 330)",
+"lch(-10 10 330)", "lch(-10 10 330)",
+"lch(-10% 10% 330deg)", "lch(-10 15 330)",
+"lch(-10 10 330 / 0)", "lch(-10 10 330 / 0)",
+"lch(-10% 10% 330deg / 0)", "lch(-10 15 330 / 0)",
+"lch(-10 10 330 / 0.2)", "lch(-10 10 330 / 0.2)",
+"lch(-10% 10% 330deg / 0.2)", "lch(-10 15 330 / 0.2)",
+"lch(-10 10 330 / 1)", "lch(-10 10 330)",
+"lch(-10% 10% 330deg / 1)", "lch(-10 15 330)",
 "lch(0 110 330)", "lch(0 110 330)",
 "lch(0% 110% 330deg)", "lch(0 165 330)",
 "lch(0 110 330 / 0)", "lch(0 110 330 / 0)",
@@ -2391,46 +2391,46 @@
 "lch(110% 110% 330deg / 0.2)", "lch(110 165 330 / 0.2)",
 "lch(110 110 330 / 1)", "lch(110 110 330)",
 "lch(110% 110% 330deg / 1)", "lch(110 165 330)",
-"lch(-10 110 330)", "lch(0 110 330)",
-"lch(-10% 110% 330deg)", "lch(0 165 330)",
-"lch(-10 110 330 / 0)", "lch(0 110 330 / 0)",
-"lch(-10% 110% 330deg / 0)", "lch(0 165 330 / 0)",
-"lch(-10 110 330 / 0.2)", "lch(0 110 330 / 0.2)",
-"lch(-10% 110% 330deg / 0.2)", "lch(0 165 330 / 0.2)",
-"lch(-10 110 330 / 1)", "lch(0 110 330)",
-"lch(-10% 110% 330deg / 1)", "lch(0 165 330)",
-"lch(0 -10 330)", "lch(0 0 330)",
-"lch(0% -10% 330deg)", "lch(0 0 330)",
-"lch(0 -10 330 / 0)", "lch(0 0 330 / 0)",
-"lch(0% -10% 330deg / 0)", "lch(0 0 330 / 0)",
-"lch(0 -10 330 / 0.2)", "lch(0 0 330 / 0.2)",
-"lch(0% -10% 330deg / 0.2)", "lch(0 0 330 / 0.2)",
-"lch(0 -10 330 / 1)", "lch(0 0 330)",
-"lch(0% -10% 330deg / 1)", "lch(0 0 330)",
-"lch(10 -10 330)", "lch(10 0 330)",
-"lch(10% -10% 330deg)", "lch(10 0 330)",
-"lch(10 -10 330 / 0)", "lch(10 0 330 / 0)",
-"lch(10% -10% 330deg / 0)", "lch(10 0 330 / 0)",
-"lch(10 -10 330 / 0.2)", "lch(10 0 330 / 0.2)",
-"lch(10% -10% 330deg / 0.2)", "lch(10 0 330 / 0.2)",
-"lch(10 -10 330 / 1)", "lch(10 0 330)",
-"lch(10% -10% 330deg / 1)", "lch(10 0 330)",
-"lch(110 -10 330)", "lch(110 0 330)",
-"lch(110% -10% 330deg)", "lch(110 0 330)",
-"lch(110 -10 330 / 0)", "lch(110 0 330 / 0)",
-"lch(110% -10% 330deg / 0)", "lch(110 0 330 / 0)",
-"lch(110 -10 330 / 0.2)", "lch(110 0 330 / 0.2)",
-"lch(110% -10% 330deg / 0.2)", "lch(110 0 330 / 0.2)",
-"lch(110 -10 330 / 1)", "lch(110 0 330)",
-"lch(110% -10% 330deg / 1)", "lch(110 0 330)",
-"lch(-10 -10 330)", "lch(0 0 330)",
-"lch(-10% -10% 330deg)", "lch(0 0 330)",
-"lch(-10 -10 330 / 0)", "lch(0 0 330 / 0)",
-"lch(-10% -10% 330deg / 0)", "lch(0 0 330 / 0)",
-"lch(-10 -10 330 / 0.2)", "lch(0 0 330 / 0.2)",
-"lch(-10% -10% 330deg / 0.2)", "lch(0 0 330 / 0.2)",
-"lch(-10 -10 330 / 1)", "lch(0 0 330)",
-"lch(-10% -10% 330deg / 1)", "lch(0 0 330)",
+"lch(-10 110 330)", "lch(-10 110 330)",
+"lch(-10% 110% 330deg)", "lch(-10 165 330)",
+"lch(-10 110 330 / 0)", "lch(-10 110 330 / 0)",
+"lch(-10% 110% 330deg / 0)", "lch(-10 165 330 / 0)",
+"lch(-10 110 330 / 0.2)", "lch(-10 110 330 / 0.2)",
+"lch(-10% 110% 330deg / 0.2)", "lch(-10 165 330 / 0.2)",
+"lch(-10 110 330 / 1)", "lch(-10 110 330)",
+"lch(-10% 110% 330deg / 1)", "lch(-10 165 330)",
+"lch(0 -10 330)", "lch(0 -10 330)",
+"lch(0% -10% 330deg)", "lch(0 -15 330)",
+"lch(0 -10 330 / 0)", "lch(0 -10 330 / 0)",
+"lch(0% -10% 330deg / 0)", "lch(0 -15 330 / 0)",
+"lch(0 -10 330 / 0.2)", "lch(0 -10 330 / 0.2)",
+"lch(0% -10% 330deg / 0.2)", "lch(0 -15 330 / 0.2)",
+"lch(0 -10 330 / 1)", "lch(0 -10 330)",
+"lch(0% -10% 330deg / 1)", "lch(0 -15 330)",
+"lch(10 -10 330)", "lch(10 -10 330)",
+"lch(10% -10% 330deg)", "lch(10 -15 330)",
+"lch(10 -10 330 / 0)", "lch(10 -10 330 / 0)",
+"lch(10% -10% 330deg / 0)", "lch(10 -15 330 / 0)",
+"lch(10 -10 330 / 0.2)", "lch(10 -10 330 / 0.2)",
+"lch(10% -10% 330deg / 0.2)", "lch(10 -15 330 / 0.2)",
+"lch(10 -10 330 / 1)", "lch(10 -10 330)",
+"lch(10% -10% 330deg / 1)", "lch(10 -15 330)",
+"lch(110 -10 330)", "lch(110 -10 330)",
+"lch(110% -10% 330deg)", "lch(110 -15 330)",
+"lch(110 -10 330 / 0)", "lch(110 -10 330 / 0)",
+"lch(110% -10% 330deg / 0)", "lch(110 -15 330 / 0)",
+"lch(110 -10 330 / 0.2)", "lch(110 -10 330 / 0.2)",
+"lch(110% -10% 330deg / 0.2)", "lch(110 -15 330 / 0.2)",
+"lch(110 -10 330 / 1)", "lch(110 -10 330)",
+"lch(110% -10% 330deg / 1)", "lch(110 -15 330)",
+"lch(-10 -10 330)", "lch(-10 -10 330)",
+"lch(-10% -10% 330deg)", "lch(-10 -15 330)",
+"lch(-10 -10 330 / 0)", "lch(-10 -10 330 / 0)",
+"lch(-10% -10% 330deg / 0)", "lch(-10 -15 330 / 0)",
+"lch(-10 -10 330 / 0.2)", "lch(-10 -10 330 / 0.2)",
+"lch(-10% -10% 330deg / 0.2)", "lch(-10 -15 330 / 0.2)",
+"lch(-10 -10 330 / 1)", "lch(-10 -10 330)",
+"lch(-10% -10% 330deg / 1)", "lch(-10 -15 330)",
 "lch(0 0 360)", "lch(0 0 0)",
 "lch(0% 0% 360deg)", "lch(0 0 0)",
 "lch(0 0 360 / 0)", "lch(0 0 0 / 0)",
@@ -2455,14 +2455,14 @@
 "lch(110% 0% 360deg / 0.2)", "lch(110 0 0 / 0.2)",
 "lch(110 0 360 / 1)", "lch(110 0 0)",
 "lch(110% 0% 360deg / 1)", "lch(110 0 0)",
-"lch(-10 0 360)", "lch(0 0 0)",
-"lch(-10% 0% 360deg)", "lch(0 0 0)",
-"lch(-10 0 360 / 0)", "lch(0 0 0 / 0)",
-"lch(-10% 0% 360deg / 0)", "lch(0 0 0 / 0)",
-"lch(-10 0 360 / 0.2)", "lch(0 0 0 / 0.2)",
-"lch(-10% 0% 360deg / 0.2)", "lch(0 0 0 / 0.2)",
-"lch(-10 0 360 / 1)", "lch(0 0 0)",
-"lch(-10% 0% 360deg / 1)", "lch(0 0 0)",
+"lch(-10 0 360)", "lch(-10 0 0)",
+"lch(-10% 0% 360deg)", "lch(-10 0 0)",
+"lch(-10 0 360 / 0)", "lch(-10 0 0 / 0)",
+"lch(-10% 0% 360deg / 0)", "lch(-10 0 0 / 0)",
+"lch(-10 0 360 / 0.2)", "lch(-10 0 0 / 0.2)",
+"lch(-10% 0% 360deg / 0.2)", "lch(-10 0 0 / 0.2)",
+"lch(-10 0 360 / 1)", "lch(-10 0 0)",
+"lch(-10% 0% 360deg / 1)", "lch(-10 0 0)",
 "lch(0 10 360)", "lch(0 10 0)",
 "lch(0% 10% 360deg)", "lch(0 15 0)",
 "lch(0 10 360 / 0)", "lch(0 10 0 / 0)",
@@ -2487,14 +2487,14 @@
 "lch(110% 10% 360deg / 0.2)", "lch(110 15 0 / 0.2)",
 "lch(110 10 360 / 1)", "lch(110 10 0)",
 "lch(110% 10% 360deg / 1)", "lch(110 15 0)",
-"lch(-10 10 360)", "lch(0 10 0)",
-"lch(-10% 10% 360deg)", "lch(0 15 0)",
-"lch(-10 10 360 / 0)", "lch(0 10 0 / 0)",
-"lch(-10% 10% 360deg / 0)", "lch(0 15 0 / 0)",
-"lch(-10 10 360 / 0.2)", "lch(0 10 0 / 0.2)",
-"lch(-10% 10% 360deg / 0.2)", "lch(0 15 0 / 0.2)",
-"lch(-10 10 360 / 1)", "lch(0 10 0)",
-"lch(-10% 10% 360deg / 1)", "lch(0 15 0)",
+"lch(-10 10 360)", "lch(-10 10 0)",
+"lch(-10% 10% 360deg)", "lch(-10 15 0)",
+"lch(-10 10 360 / 0)", "lch(-10 10 0 / 0)",
+"lch(-10% 10% 360deg / 0)", "lch(-10 15 0 / 0)",
+"lch(-10 10 360 / 0.2)", "lch(-10 10 0 / 0.2)",
+"lch(-10% 10% 360deg / 0.2)", "lch(-10 15 0 / 0.2)",
+"lch(-10 10 360 / 1)", "lch(-10 10 0)",
+"lch(-10% 10% 360deg / 1)", "lch(-10 15 0)",
 "lch(0 110 360)", "lch(0 110 0)",
 "lch(0% 110% 360deg)", "lch(0 165 0)",
 "lch(0 110 360 / 0)", "lch(0 110 0 / 0)",
@@ -2519,46 +2519,46 @@
 "lch(110% 110% 360deg / 0.2)", "lch(110 165 0 / 0.2)",
 "lch(110 110 360 / 1)", "lch(110 110 0)",
 "lch(110% 110% 360deg / 1)", "lch(110 165 0)",
-"lch(-10 110 360)", "lch(0 110 0)",
-"lch(-10% 110% 360deg)", "lch(0 165 0)",
-"lch(-10 110 360 / 0)", "lch(0 110 0 / 0)",
-"lch(-10% 110% 360deg / 0)", "lch(0 165 0 / 0)",
-"lch(-10 110 360 / 0.2)", "lch(0 110 0 / 0.2)",
-"lch(-10% 110% 360deg / 0.2)", "lch(0 165 0 / 0.2)",
-"lch(-10 110 360 / 1)", "lch(0 110 0)",
-"lch(-10% 110% 360deg / 1)", "lch(0 165 0)",
-"lch(0 -10 360)", "lch(0 0 0)",
-"lch(0% -10% 360deg)", "lch(0 0 0)",
-"lch(0 -10 360 / 0)", "lch(0 0 0 / 0)",
-"lch(0% -10% 360deg / 0)", "lch(0 0 0 / 0)",
-"lch(0 -10 360 / 0.2)", "lch(0 0 0 / 0.2)",
-"lch(0% -10% 360deg / 0.2)", "lch(0 0 0 / 0.2)",
-"lch(0 -10 360 / 1)", "lch(0 0 0)",
-"lch(0% -10% 360deg / 1)", "lch(0 0 0)",
-"lch(10 -10 360)", "lch(10 0 0)",
-"lch(10% -10% 360deg)", "lch(10 0 0)",
-"lch(10 -10 360 / 0)", "lch(10 0 0 / 0)",
-"lch(10% -10% 360deg / 0)", "lch(10 0 0 / 0)",
-"lch(10 -10 360 / 0.2)", "lch(10 0 0 / 0.2)",
-"lch(10% -10% 360deg / 0.2)", "lch(10 0 0 / 0.2)",
-"lch(10 -10 360 / 1)", "lch(10 0 0)",
-"lch(10% -10% 360deg / 1)", "lch(10 0 0)",
-"lch(110 -10 360)", "lch(110 0 0)",
-"lch(110% -10% 360deg)", "lch(110 0 0)",
-"lch(110 -10 360 / 0)", "lch(110 0 0 / 0)",
-"lch(110% -10% 360deg / 0)", "lch(110 0 0 / 0)",
-"lch(110 -10 360 / 0.2)", "lch(110 0 0 / 0.2)",
-"lch(110% -10% 360deg / 0.2)", "lch(110 0 0 / 0.2)",
-"lch(110 -10 360 / 1)", "lch(110 0 0)",
-"lch(110% -10% 360deg / 1)", "lch(110 0 0)",
-"lch(-10 -10 360)", "lch(0 0 0)",
-"lch(-10% -10% 360deg)", "lch(0 0 0)",
-"lch(-10 -10 360 / 0)", "lch(0 0 0 / 0)",
-"lch(-10% -10% 360deg / 0)", "lch(0 0 0 / 0)",
-"lch(-10 -10 360 / 0.2)", "lch(0 0 0 / 0.2)",
-"lch(-10% -10% 360deg / 0.2)", "lch(0 0 0 / 0.2)",
-"lch(-10 -10 360 / 1)", "lch(0 0 0)",
-"lch(-10% -10% 360deg / 1)", "lch(0 0 0)",
+"lch(-10 110 360)", "lch(-10 110 0)",
+"lch(-10% 110% 360deg)", "lch(-10 165 0)",
+"lch(-10 110 360 / 0)", "lch(-10 110 0 / 0)",
+"lch(-10% 110% 360deg / 0)", "lch(-10 165 0 / 0)",
+"lch(-10 110 360 / 0.2)", "lch(-10 110 0 / 0.2)",
+"lch(-10% 110% 360deg / 0.2)", "lch(-10 165 0 / 0.2)",
+"lch(-10 110 360 / 1)", "lch(-10 110 0)",
+"lch(-10% 110% 360deg / 1)", "lch(-10 165 0)",
+"lch(0 -10 360)", "lch(0 -10 0)",
+"lch(0% -10% 360deg)", "lch(0 -15 0)",
+"lch(0 -10 360 / 0)", "lch(0 -10 0 / 0)",
+"lch(0% -10% 360deg / 0)", "lch(0 -15 0 / 0)",
+"lch(0 -10 360 / 0.2)", "lch(0 -10 0 / 0.2)",
+"lch(0% -10% 360deg / 0.2)", "lch(0 -15 0 / 0.2)",
+"lch(0 -10 360 / 1)", "lch(0 -10 0)",
+"lch(0% -10% 360deg / 1)", "lch(0 -15 0)",
+"lch(10 -10 360)", "lch(10 -10 0)",
+"lch(10% -10% 360deg)", "lch(10 -15 0)",
+"lch(10 -10 360 / 0)", "lch(10 -10 0 / 0)",
+"lch(10% -10% 360deg / 0)", "lch(10 -15 0 / 0)",
+"lch(10 -10 360 / 0.2)", "lch(10 -10 0 / 0.2)",
+"lch(10% -10% 360deg / 0.2)", "lch(10 -15 0 / 0.2)",
+"lch(10 -10 360 / 1)", "lch(10 -10 0)",
+"lch(10% -10% 360deg / 1)", "lch(10 -15 0)",
+"lch(110 -10 360)", "lch(110 -10 0)",
+"lch(110% -10% 360deg)", "lch(110 -15 0)",
+"lch(110 -10 360 / 0)", "lch(110 -10 0 / 0)",
+"lch(110% -10% 360deg / 0)", "lch(110 -15 0 / 0)",
+"lch(110 -10 360 / 0.2)", "lch(110 -10 0 / 0.2)",
+"lch(110% -10% 360deg / 0.2)", "lch(110 -15 0 / 0.2)",
+"lch(110 -10 360 / 1)", "lch(110 -10 0)",
+"lch(110% -10% 360deg / 1)", "lch(110 -15 0)",
+"lch(-10 -10 360)", "lch(-10 -10 0)",
+"lch(-10% -10% 360deg)", "lch(-10 -15 0)",
+"lch(-10 -10 360 / 0)", "lch(-10 -10 0 / 0)",
+"lch(-10% -10% 360deg / 0)", "lch(-10 -15 0 / 0)",
+"lch(-10 -10 360 / 0.2)", "lch(-10 -10 0 / 0.2)",
+"lch(-10% -10% 360deg / 0.2)", "lch(-10 -15 0 / 0.2)",
+"lch(-10 -10 360 / 1)", "lch(-10 -10 0)",
+"lch(-10% -10% 360deg / 1)", "lch(-10 -15 0)",
 "lch(0 0 380)", "lch(0 0 20)",
 "lch(0% 0% 380deg)", "lch(0 0 20)",
 "lch(0 0 380 / 0)", "lch(0 0 20 / 0)",
@@ -2583,14 +2583,14 @@
 "lch(110% 0% 380deg / 0.2)", "lch(110 0 20 / 0.2)",
 "lch(110 0 380 / 1)", "lch(110 0 20)",
 "lch(110% 0% 380deg / 1)", "lch(110 0 20)",
-"lch(-10 0 380)", "lch(0 0 20)",
-"lch(-10% 0% 380deg)", "lch(0 0 20)",
-"lch(-10 0 380 / 0)", "lch(0 0 20 / 0)",
-"lch(-10% 0% 380deg / 0)", "lch(0 0 20 / 0)",
-"lch(-10 0 380 / 0.2)", "lch(0 0 20 / 0.2)",
-"lch(-10% 0% 380deg / 0.2)", "lch(0 0 20 / 0.2)",
-"lch(-10 0 380 / 1)", "lch(0 0 20)",
-"lch(-10% 0% 380deg / 1)", "lch(0 0 20)",
+"lch(-10 0 380)", "lch(-10 0 20)",
+"lch(-10% 0% 380deg)", "lch(-10 0 20)",
+"lch(-10 0 380 / 0)", "lch(-10 0 20 / 0)",
+"lch(-10% 0% 380deg / 0)", "lch(-10 0 20 / 0)",
+"lch(-10 0 380 / 0.2)", "lch(-10 0 20 / 0.2)",
+"lch(-10% 0% 380deg / 0.2)", "lch(-10 0 20 / 0.2)",
+"lch(-10 0 380 / 1)", "lch(-10 0 20)",
+"lch(-10% 0% 380deg / 1)", "lch(-10 0 20)",
 "lch(0 10 380)", "lch(0 10 20)",
 "lch(0% 10% 380deg)", "lch(0 15 20)",
 "lch(0 10 380 / 0)", "lch(0 10 20 / 0)",
@@ -2615,14 +2615,14 @@
 "lch(110% 10% 380deg / 0.2)", "lch(110 15 20 / 0.2)",
 "lch(110 10 380 / 1)", "lch(110 10 20)",
 "lch(110% 10% 380deg / 1)", "lch(110 15 20)",
-"lch(-10 10 380)", "lch(0 10 20)",
-"lch(-10% 10% 380deg)", "lch(0 15 20)",
-"lch(-10 10 380 / 0)", "lch(0 10 20 / 0)",
-"lch(-10% 10% 380deg / 0)", "lch(0 15 20 / 0)",
-"lch(-10 10 380 / 0.2)", "lch(0 10 20 / 0.2)",
-"lch(-10% 10% 380deg / 0.2)", "lch(0 15 20 / 0.2)",
-"lch(-10 10 380 / 1)", "lch(0 10 20)",
-"lch(-10% 10% 380deg / 1)", "lch(0 15 20)",
+"lch(-10 10 380)", "lch(-10 10 20)",
+"lch(-10% 10% 380deg)", "lch(-10 15 20)",
+"lch(-10 10 380 / 0)", "lch(-10 10 20 / 0)",
+"lch(-10% 10% 380deg / 0)", "lch(-10 15 20 / 0)",
+"lch(-10 10 380 / 0.2)", "lch(-10 10 20 / 0.2)",
+"lch(-10% 10% 380deg / 0.2)", "lch(-10 15 20 / 0.2)",
+"lch(-10 10 380 / 1)", "lch(-10 10 20)",
+"lch(-10% 10% 380deg / 1)", "lch(-10 15 20)",
 "lch(0 110 380)", "lch(0 110 20)",
 "lch(0% 110% 380deg)", "lch(0 165 20)",
 "lch(0 110 380 / 0)", "lch(0 110 20 / 0)",
@@ -2647,46 +2647,46 @@
 "lch(110% 110% 380deg / 0.2)", "lch(110 165 20 / 0.2)",
 "lch(110 110 380 / 1)", "lch(110 110 20)",
 "lch(110% 110% 380deg / 1)", "lch(110 165 20)",
-"lch(-10 110 380)", "lch(0 110 20)",
-"lch(-10% 110% 380deg)", "lch(0 165 20)",
-"lch(-10 110 380 / 0)", "lch(0 110 20 / 0)",
-"lch(-10% 110% 380deg / 0)", "lch(0 165 20 / 0)",
-"lch(-10 110 380 / 0.2)", "lch(0 110 20 / 0.2)",
-"lch(-10% 110% 380deg / 0.2)", "lch(0 165 20 / 0.2)",
-"lch(-10 110 380 / 1)", "lch(0 110 20)",
-"lch(-10% 110% 380deg / 1)", "lch(0 165 20)",
-"lch(0 -10 380)", "lch(0 0 20)",
-"lch(0% -10% 380deg)", "lch(0 0 20)",
-"lch(0 -10 380 / 0)", "lch(0 0 20 / 0)",
-"lch(0% -10% 380deg / 0)", "lch(0 0 20 / 0)",
-"lch(0 -10 380 / 0.2)", "lch(0 0 20 / 0.2)",
-"lch(0% -10% 380deg / 0.2)", "lch(0 0 20 / 0.2)",
-"lch(0 -10 380 / 1)", "lch(0 0 20)",
-"lch(0% -10% 380deg / 1)", "lch(0 0 20)",
-"lch(10 -10 380)", "lch(10 0 20)",
-"lch(10% -10% 380deg)", "lch(10 0 20)",
-"lch(10 -10 380 / 0)", "lch(10 0 20 / 0)",
-"lch(10% -10% 380deg / 0)", "lch(10 0 20 / 0)",
-"lch(10 -10 380 / 0.2)", "lch(10 0 20 / 0.2)",
-"lch(10% -10% 380deg / 0.2)", "lch(10 0 20 / 0.2)",
-"lch(10 -10 380 / 1)", "lch(10 0 20)",
-"lch(10% -10% 380deg / 1)", "lch(10 0 20)",
-"lch(110 -10 380)", "lch(110 0 20)",
-"lch(110% -10% 380deg)", "lch(110 0 20)",
-"lch(110 -10 380 / 0)", "lch(110 0 20 / 0)",
-"lch(110% -10% 380deg / 0)", "lch(110 0 20 / 0)",
-"lch(110 -10 380 / 0.2)", "lch(110 0 20 / 0.2)",
-"lch(110% -10% 380deg / 0.2)", "lch(110 0 20 / 0.2)",
-"lch(110 -10 380 / 1)", "lch(110 0 20)",
-"lch(110% -10% 380deg / 1)", "lch(110 0 20)",
-"lch(-10 -10 380)", "lch(0 0 20)",
-"lch(-10% -10% 380deg)", "lch(0 0 20)",
-"lch(-10 -10 380 / 0)", "lch(0 0 20 / 0)",
-"lch(-10% -10% 380deg / 0)", "lch(0 0 20 / 0)",
-"lch(-10 -10 380 / 0.2)", "lch(0 0 20 / 0.2)",
-"lch(-10% -10% 380deg / 0.2)", "lch(0 0 20 / 0.2)",
-"lch(-10 -10 380 / 1)", "lch(0 0 20)",
-"lch(-10% -10% 380deg / 1)", "lch(0 0 20)",
+"lch(-10 110 380)", "lch(-10 110 20)",
+"lch(-10% 110% 380deg)", "lch(-10 165 20)",
+"lch(-10 110 380 / 0)", "lch(-10 110 20 / 0)",
+"lch(-10% 110% 380deg / 0)", "lch(-10 165 20 / 0)",
+"lch(-10 110 380 / 0.2)", "lch(-10 110 20 / 0.2)",
+"lch(-10% 110% 380deg / 0.2)", "lch(-10 165 20 / 0.2)",
+"lch(-10 110 380 / 1)", "lch(-10 110 20)",
+"lch(-10% 110% 380deg / 1)", "lch(-10 165 20)",
+"lch(0 -10 380)", "lch(0 -10 20)",
+"lch(0% -10% 380deg)", "lch(0 -15 20)",
+"lch(0 -10 380 / 0)", "lch(0 -10 20 / 0)",
+"lch(0% -10% 380deg / 0)", "lch(0 -15 20 / 0)",
+"lch(0 -10 380 / 0.2)", "lch(0 -10 20 / 0.2)",
+"lch(0% -10% 380deg / 0.2)", "lch(0 -15 20 / 0.2)",
+"lch(0 -10 380 / 1)", "lch(0 -10 20)",
+"lch(0% -10% 380deg / 1)", "lch(0 -15 20)",
+"lch(10 -10 380)", "lch(10 -10 20)",
+"lch(10% -10% 380deg)", "lch(10 -15 20)",
+"lch(10 -10 380 / 0)", "lch(10 -10 20 / 0)",
+"lch(10% -10% 380deg / 0)", "lch(10 -15 20 / 0)",
+"lch(10 -10 380 / 0.2)", "lch(10 -10 20 / 0.2)",
+"lch(10% -10% 380deg / 0.2)", "lch(10 -15 20 / 0.2)",
+"lch(10 -10 380 / 1)", "lch(10 -10 20)",
+"lch(10% -10% 380deg / 1)", "lch(10 -15 20)",
+"lch(110 -10 380)", "lch(110 -10 20)",
+"lch(110% -10% 380deg)", "lch(110 -15 20)",
+"lch(110 -10 380 / 0)", "lch(110 -10 20 / 0)",
+"lch(110% -10% 380deg / 0)", "lch(110 -15 20 / 0)",
+"lch(110 -10 380 / 0.2)", "lch(110 -10 20 / 0.2)",
+"lch(110% -10% 380deg / 0.2)", "lch(110 -15 20 / 0.2)",
+"lch(110 -10 380 / 1)", "lch(110 -10 20)",
+"lch(110% -10% 380deg / 1)", "lch(110 -15 20)",
+"lch(-10 -10 380)", "lch(-10 -10 20)",
+"lch(-10% -10% 380deg)", "lch(-10 -15 20)",
+"lch(-10 -10 380 / 0)", "lch(-10 -10 20 / 0)",
+"lch(-10% -10% 380deg / 0)", "lch(-10 -15 20 / 0)",
+"lch(-10 -10 380 / 0.2)", "lch(-10 -10 20 / 0.2)",
+"lch(-10% -10% 380deg / 0.2)", "lch(-10 -15 20 / 0.2)",
+"lch(-10 -10 380 / 1)", "lch(-10 -10 20)",
+"lch(-10% -10% 380deg / 1)", "lch(-10 -15 20)",
 "lch(0 0 700)", "lch(0 0 340)",
 "lch(0% 0% 700deg)", "lch(0 0 340)",
 "lch(0 0 700 / 0)", "lch(0 0 340 / 0)",
@@ -2711,14 +2711,14 @@
 "lch(110% 0% 700deg / 0.2)", "lch(110 0 340 / 0.2)",
 "lch(110 0 700 / 1)", "lch(110 0 340)",
 "lch(110% 0% 700deg / 1)", "lch(110 0 340)",
-"lch(-10 0 700)", "lch(0 0 340)",
-"lch(-10% 0% 700deg)", "lch(0 0 340)",
-"lch(-10 0 700 / 0)", "lch(0 0 340 / 0)",
-"lch(-10% 0% 700deg / 0)", "lch(0 0 340 / 0)",
-"lch(-10 0 700 / 0.2)", "lch(0 0 340 / 0.2)",
-"lch(-10% 0% 700deg / 0.2)", "lch(0 0 340 / 0.2)",
-"lch(-10 0 700 / 1)", "lch(0 0 340)",
-"lch(-10% 0% 700deg / 1)", "lch(0 0 340)",
+"lch(-10 0 700)", "lch(-10 0 340)",
+"lch(-10% 0% 700deg)", "lch(-10 0 340)",
+"lch(-10 0 700 / 0)", "lch(-10 0 340 / 0)",
+"lch(-10% 0% 700deg / 0)", "lch(-10 0 340 / 0)",
+"lch(-10 0 700 / 0.2)", "lch(-10 0 340 / 0.2)",
+"lch(-10% 0% 700deg / 0.2)", "lch(-10 0 340 / 0.2)",
+"lch(-10 0 700 / 1)", "lch(-10 0 340)",
+"lch(-10% 0% 700deg / 1)", "lch(-10 0 340)",
 "lch(0 10 700)", "lch(0 10 340)",
 "lch(0% 10% 700deg)", "lch(0 15 340)",
 "lch(0 10 700 / 0)", "lch(0 10 340 / 0)",
@@ -2743,14 +2743,14 @@
 "lch(110% 10% 700deg / 0.2)", "lch(110 15 340 / 0.2)",
 "lch(110 10 700 / 1)", "lch(110 10 340)",
 "lch(110% 10% 700deg / 1)", "lch(110 15 340)",
-"lch(-10 10 700)", "lch(0 10 340)",
-"lch(-10% 10% 700deg)", "lch(0 15 340)",
-"lch(-10 10 700 / 0)", "lch(0 10 340 / 0)",
-"lch(-10% 10% 700deg / 0)", "lch(0 15 340 / 0)",
-"lch(-10 10 700 / 0.2)", "lch(0 10 340 / 0.2)",
-"lch(-10% 10% 700deg / 0.2)", "lch(0 15 340 / 0.2)",
-"lch(-10 10 700 / 1)", "lch(0 10 340)",
-"lch(-10% 10% 700deg / 1)", "lch(0 15 340)",
+"lch(-10 10 700)", "lch(-10 10 340)",
+"lch(-10% 10% 700deg)", "lch(-10 15 340)",
+"lch(-10 10 700 / 0)", "lch(-10 10 340 / 0)",
+"lch(-10% 10% 700deg / 0)", "lch(-10 15 340 / 0)",
+"lch(-10 10 700 / 0.2)", "lch(-10 10 340 / 0.2)",
+"lch(-10% 10% 700deg / 0.2)", "lch(-10 15 340 / 0.2)",
+"lch(-10 10 700 / 1)", "lch(-10 10 340)",
+"lch(-10% 10% 700deg / 1)", "lch(-10 15 340)",
 "lch(0 110 700)", "lch(0 110 340)",
 "lch(0% 110% 700deg)", "lch(0 165 340)",
 "lch(0 110 700 / 0)", "lch(0 110 340 / 0)",
@@ -2775,46 +2775,46 @@
 "lch(110% 110% 700deg / 0.2)", "lch(110 165 340 / 0.2)",
 "lch(110 110 700 / 1)", "lch(110 110 340)",
 "lch(110% 110% 700deg / 1)", "lch(110 165 340)",
-"lch(-10 110 700)", "lch(0 110 340)",
-"lch(-10% 110% 700deg)", "lch(0 165 340)",
-"lch(-10 110 700 / 0)", "lch(0 110 340 / 0)",
-"lch(-10% 110% 700deg / 0)", "lch(0 165 340 / 0)",
-"lch(-10 110 700 / 0.2)", "lch(0 110 340 / 0.2)",
-"lch(-10% 110% 700deg / 0.2)", "lch(0 165 340 / 0.2)",
-"lch(-10 110 700 / 1)", "lch(0 110 340)",
-"lch(-10% 110% 700deg / 1)", "lch(0 165 340)",
-"lch(0 -10 700)", "lch(0 0 340)",
-"lch(0% -10% 700deg)", "lch(0 0 340)",
-"lch(0 -10 700 / 0)", "lch(0 0 340 / 0)",
-"lch(0% -10% 700deg / 0)", "lch(0 0 340 / 0)",
-"lch(0 -10 700 / 0.2)", "lch(0 0 340 / 0.2)",
-"lch(0% -10% 700deg / 0.2)", "lch(0 0 340 / 0.2)",
-"lch(0 -10 700 / 1)", "lch(0 0 340)",
-"lch(0% -10% 700deg / 1)", "lch(0 0 340)",
-"lch(10 -10 700)", "lch(10 0 340)",
-"lch(10% -10% 700deg)", "lch(10 0 340)",
-"lch(10 -10 700 / 0)", "lch(10 0 340 / 0)",
-"lch(10% -10% 700deg / 0)", "lch(10 0 340 / 0)",
-"lch(10 -10 700 / 0.2)", "lch(10 0 340 / 0.2)",
-"lch(10% -10% 700deg / 0.2)", "lch(10 0 340 / 0.2)",
-"lch(10 -10 700 / 1)", "lch(10 0 340)",
-"lch(10% -10% 700deg / 1)", "lch(10 0 340)",
-"lch(110 -10 700)", "lch(110 0 340)",
-"lch(110% -10% 700deg)", "lch(110 0 340)",
-"lch(110 -10 700 / 0)", "lch(110 0 340 / 0)",
-"lch(110% -10% 700deg / 0)", "lch(110 0 340 / 0)",
-"lch(110 -10 700 / 0.2)", "lch(110 0 340 / 0.2)",
-"lch(110% -10% 700deg / 0.2)", "lch(110 0 340 / 0.2)",
-"lch(110 -10 700 / 1)", "lch(110 0 340)",
-"lch(110% -10% 700deg / 1)", "lch(110 0 340)",
-"lch(-10 -10 700)", "lch(0 0 340)",
-"lch(-10% -10% 700deg)", "lch(0 0 340)",
-"lch(-10 -10 700 / 0)", "lch(0 0 340 / 0)",
-"lch(-10% -10% 700deg / 0)", "lch(0 0 340 / 0)",
-"lch(-10 -10 700 / 0.2)", "lch(0 0 340 / 0.2)",
-"lch(-10% -10% 700deg / 0.2)", "lch(0 0 340 / 0.2)",
-"lch(-10 -10 700 / 1)", "lch(0 0 340)",
-"lch(-10% -10% 700deg / 1)", "lch(0 0 340)",
+"lch(-10 110 700)", "lch(-10 110 340)",
+"lch(-10% 110% 700deg)", "lch(-10 165 340)",
+"lch(-10 110 700 / 0)", "lch(-10 110 340 / 0)",
+"lch(-10% 110% 700deg / 0)", "lch(-10 165 340 / 0)",
+"lch(-10 110 700 / 0.2)", "lch(-10 110 340 / 0.2)",
+"lch(-10% 110% 700deg / 0.2)", "lch(-10 165 340 / 0.2)",
+"lch(-10 110 700 / 1)", "lch(-10 110 340)",
+"lch(-10% 110% 700deg / 1)", "lch(-10 165 340)",
+"lch(0 -10 700)", "lch(0 -10 340)",
+"lch(0% -10% 700deg)", "lch(0 -15 340)",
+"lch(0 -10 700 / 0)", "lch(0 -10 340 / 0)",
+"lch(0% -10% 700deg / 0)", "lch(0 -15 340 / 0)",
+"lch(0 -10 700 / 0.2)", "lch(0 -10 340 / 0.2)",
+"lch(0% -10% 700deg / 0.2)", "lch(0 -15 340 / 0.2)",
+"lch(0 -10 700 / 1)", "lch(0 -10 340)",
+"lch(0% -10% 700deg / 1)", "lch(0 -15 340)",
+"lch(10 -10 700)", "lch(10 -10 340)",
+"lch(10% -10% 700deg)", "lch(10 -15 340)",
+"lch(10 -10 700 / 0)", "lch(10 -10 340 / 0)",
+"lch(10% -10% 700deg / 0)", "lch(10 -15 340 / 0)",
+"lch(10 -10 700 / 0.2)", "lch(10 -10 340 / 0.2)",
+"lch(10% -10% 700deg / 0.2)", "lch(10 -15 340 / 0.2)",
+"lch(10 -10 700 / 1)", "lch(10 -10 340)",
+"lch(10% -10% 700deg / 1)", "lch(10 -15 340)",
+"lch(110 -10 700)", "lch(110 -10 340)",
+"lch(110% -10% 700deg)", "lch(110 -15 340)",
+"lch(110 -10 700 / 0)", "lch(110 -10 340 / 0)",
+"lch(110% -10% 700deg / 0)", "lch(110 -15 340 / 0)",
+"lch(110 -10 700 / 0.2)", "lch(110 -10 340 / 0.2)",
+"lch(110% -10% 700deg / 0.2)", "lch(110 -15 340 / 0.2)",
+"lch(110 -10 700 / 1)", "lch(110 -10 340)",
+"lch(110% -10% 700deg / 1)", "lch(110 -15 340)",
+"lch(-10 -10 700)", "lch(-10 -10 340)",
+"lch(-10% -10% 700deg)", "lch(-10 -15 340)",
+"lch(-10 -10 700 / 0)", "lch(-10 -10 340 / 0)",
+"lch(-10% -10% 700deg / 0)", "lch(-10 -15 340 / 0)",
+"lch(-10 -10 700 / 0.2)", "lch(-10 -10 340 / 0.2)",
+"lch(-10% -10% 700deg / 0.2)", "lch(-10 -15 340 / 0.2)",
+"lch(-10 -10 700 / 1)", "lch(-10 -10 340)",
+"lch(-10% -10% 700deg / 1)", "lch(-10 -15 340)",
 "lch(0 0 -20)", "lch(0 0 340)",
 "lch(0% 0% -20deg)", "lch(0 0 340)",
 "lch(0 0 -20 / 0)", "lch(0 0 340 / 0)",
@@ -2839,14 +2839,14 @@
 "lch(110% 0% -20deg / 0.2)", "lch(110 0 340 / 0.2)",
 "lch(110 0 -20 / 1)", "lch(110 0 340)",
 "lch(110% 0% -20deg / 1)", "lch(110 0 340)",
-"lch(-10 0 -20)", "lch(0 0 340)",
-"lch(-10% 0% -20deg)", "lch(0 0 340)",
-"lch(-10 0 -20 / 0)", "lch(0 0 340 / 0)",
-"lch(-10% 0% -20deg / 0)", "lch(0 0 340 / 0)",
-"lch(-10 0 -20 / 0.2)", "lch(0 0 340 / 0.2)",
-"lch(-10% 0% -20deg / 0.2)", "lch(0 0 340 / 0.2)",
-"lch(-10 0 -20 / 1)", "lch(0 0 340)",
-"lch(-10% 0% -20deg / 1)", "lch(0 0 340)",
+"lch(-10 0 -20)", "lch(-10 0 340)",
+"lch(-10% 0% -20deg)", "lch(-10 0 340)",
+"lch(-10 0 -20 / 0)", "lch(-10 0 340 / 0)",
+"lch(-10% 0% -20deg / 0)", "lch(-10 0 340 / 0)",
+"lch(-10 0 -20 / 0.2)", "lch(-10 0 340 / 0.2)",
+"lch(-10% 0% -20deg / 0.2)", "lch(-10 0 340 / 0.2)",
+"lch(-10 0 -20 / 1)", "lch(-10 0 340)",
+"lch(-10% 0% -20deg / 1)", "lch(-10 0 340)",
 "lch(0 10 -20)", "lch(0 10 340)",
 "lch(0% 10% -20deg)", "lch(0 15 340)",
 "lch(0 10 -20 / 0)", "lch(0 10 340 / 0)",
@@ -2871,14 +2871,14 @@
 "lch(110% 10% -20deg / 0.2)", "lch(110 15 340 / 0.2)",
 "lch(110 10 -20 / 1)", "lch(110 10 340)",
 "lch(110% 10% -20deg / 1)", "lch(110 15 340)",
-"lch(-10 10 -20)", "lch(0 10 340)",
-"lch(-10% 10% -20deg)", "lch(0 15 340)",
-"lch(-10 10 -20 / 0)", "lch(0 10 340 / 0)",
-"lch(-10% 10% -20deg / 0)", "lch(0 15 340 / 0)",
-"lch(-10 10 -20 / 0.2)", "lch(0 10 340 / 0.2)",
-"lch(-10% 10% -20deg / 0.2)", "lch(0 15 340 / 0.2)",
-"lch(-10 10 -20 / 1)", "lch(0 10 340)",
-"lch(-10% 10% -20deg / 1)", "lch(0 15 340)",
+"lch(-10 10 -20)", "lch(-10 10 340)",
+"lch(-10% 10% -20deg)", "lch(-10 15 340)",
+"lch(-10 10 -20 / 0)", "lch(-10 10 340 / 0)",
+"lch(-10% 10% -20deg / 0)", "lch(-10 15 340 / 0)",
+"lch(-10 10 -20 / 0.2)", "lch(-10 10 340 / 0.2)",
+"lch(-10% 10% -20deg / 0.2)", "lch(-10 15 340 / 0.2)",
+"lch(-10 10 -20 / 1)", "lch(-10 10 340)",
+"lch(-10% 10% -20deg / 1)", "lch(-10 15 340)",
 "lch(0 110 -20)", "lch(0 110 340)",
 "lch(0% 110% -20deg)", "lch(0 165 340)",
 "lch(0 110 -20 / 0)", "lch(0 110 340 / 0)",
@@ -2903,46 +2903,46 @@
 "lch(110% 110% -20deg / 0.2)", "lch(110 165 340 / 0.2)",
 "lch(110 110 -20 / 1)", "lch(110 110 340)",
 "lch(110% 110% -20deg / 1)", "lch(110 165 340)",
-"lch(-10 110 -20)", "lch(0 110 340)",
-"lch(-10% 110% -20deg)", "lch(0 165 340)",
-"lch(-10 110 -20 / 0)", "lch(0 110 340 / 0)",
-"lch(-10% 110% -20deg / 0)", "lch(0 165 340 / 0)",
-"lch(-10 110 -20 / 0.2)", "lch(0 110 340 / 0.2)",
-"lch(-10% 110% -20deg / 0.2)", "lch(0 165 340 / 0.2)",
-"lch(-10 110 -20 / 1)", "lch(0 110 340)",
-"lch(-10% 110% -20deg / 1)", "lch(0 165 340)",
-"lch(0 -10 -20)", "lch(0 0 340)",
-"lch(0% -10% -20deg)", "lch(0 0 340)",
-"lch(0 -10 -20 / 0)", "lch(0 0 340 / 0)",
-"lch(0% -10% -20deg / 0)", "lch(0 0 340 / 0)",
-"lch(0 -10 -20 / 0.2)", "lch(0 0 340 / 0.2)",
-"lch(0% -10% -20deg / 0.2)", "lch(0 0 340 / 0.2)",
-"lch(0 -10 -20 / 1)", "lch(0 0 340)",
-"lch(0% -10% -20deg / 1)", "lch(0 0 340)",
-"lch(10 -10 -20)", "lch(10 0 340)",
-"lch(10% -10% -20deg)", "lch(10 0 340)",
-"lch(10 -10 -20 / 0)", "lch(10 0 340 / 0)",
-"lch(10% -10% -20deg / 0)", "lch(10 0 340 / 0)",
-"lch(10 -10 -20 / 0.2)", "lch(10 0 340 / 0.2)",
-"lch(10% -10% -20deg / 0.2)", "lch(10 0 340 / 0.2)",
-"lch(10 -10 -20 / 1)", "lch(10 0 340)",
-"lch(10% -10% -20deg / 1)", "lch(10 0 340)",
-"lch(110 -10 -20)", "lch(110 0 340)",
-"lch(110% -10% -20deg)", "lch(110 0 340)",
-"lch(110 -10 -20 / 0)", "lch(110 0 340 / 0)",
-"lch(110% -10% -20deg / 0)", "lch(110 0 340 / 0)",
-"lch(110 -10 -20 / 0.2)", "lch(110 0 340 / 0.2)",
-"lch(110% -10% -20deg / 0.2)", "lch(110 0 340 / 0.2)",
-"lch(110 -10 -20 / 1)", "lch(110 0 340)",
-"lch(110% -10% -20deg / 1)", "lch(110 0 340)",
-"lch(-10 -10 -20)", "lch(0 0 340)",
-"lch(-10% -10% -20deg)", "lch(0 0 340)",
-"lch(-10 -10 -20 / 0)", "lch(0 0 340 / 0)",
-"lch(-10% -10% -20deg / 0)", "lch(0 0 340 / 0)",
-"lch(-10 -10 -20 / 0.2)", "lch(0 0 340 / 0.2)",
-"lch(-10% -10% -20deg / 0.2)", "lch(0 0 340 / 0.2)",
-"lch(-10 -10 -20 / 1)", "lch(0 0 340)",
-"lch(-10% -10% -20deg / 1)", "lch(0 0 340)",
+"lch(-10 110 -20)", "lch(-10 110 340)",
+"lch(-10% 110% -20deg)", "lch(-10 165 340)",
+"lch(-10 110 -20 / 0)", "lch(-10 110 340 / 0)",
+"lch(-10% 110% -20deg / 0)", "lch(-10 165 340 / 0)",
+"lch(-10 110 -20 / 0.2)", "lch(-10 110 340 / 0.2)",
+"lch(-10% 110% -20deg / 0.2)", "lch(-10 165 340 / 0.2)",
+"lch(-10 110 -20 / 1)", "lch(-10 110 340)",
+"lch(-10% 110% -20deg / 1)", "lch(-10 165 340)",
+"lch(0 -10 -20)", "lch(0 -10 340)",
+"lch(0% -10% -20deg)", "lch(0 -15 340)",
+"lch(0 -10 -20 / 0)", "lch(0 -10 340 / 0)",
+"lch(0% -10% -20deg / 0)", "lch(0 -15 340 / 0)",
+"lch(0 -10 -20 / 0.2)", "lch(0 -10 340 / 0.2)",
+"lch(0% -10% -20deg / 0.2)", "lch(0 -15 340 / 0.2)",
+"lch(0 -10 -20 / 1)", "lch(0 -10 340)",
+"lch(0% -10% -20deg / 1)", "lch(0 -15 340)",
+"lch(10 -10 -20)", "lch(10 -10 340)",
+"lch(10% -10% -20deg)", "lch(10 -15 340)",
+"lch(10 -10 -20 / 0)", "lch(10 -10 340 / 0)",
+"lch(10% -10% -20deg / 0)", "lch(10 -15 340 / 0)",
+"lch(10 -10 -20 / 0.2)", "lch(10 -10 340 / 0.2)",
+"lch(10% -10% -20deg / 0.2)", "lch(10 -15 340 / 0.2)",
+"lch(10 -10 -20 / 1)", "lch(10 -10 340)",
+"lch(10% -10% -20deg / 1)", "lch(10 -15 340)",
+"lch(110 -10 -20)", "lch(110 -10 340)",
+"lch(110% -10% -20deg)", "lch(110 -15 340)",
+"lch(110 -10 -20 / 0)", "lch(110 -10 340 / 0)",
+"lch(110% -10% -20deg / 0)", "lch(110 -15 340 / 0)",
+"lch(110 -10 -20 / 0.2)", "lch(110 -10 340 / 0.2)",
+"lch(110% -10% -20deg / 0.2)", "lch(110 -15 340 / 0.2)",
+"lch(110 -10 -20 / 1)", "lch(110 -10 340)",
+"lch(110% -10% -20deg / 1)", "lch(110 -15 340)",
+"lch(-10 -10 -20)", "lch(-10 -10 340)",
+"lch(-10% -10% -20deg)", "lch(-10 -15 340)",
+"lch(-10 -10 -20 / 0)", "lch(-10 -10 340 / 0)",
+"lch(-10% -10% -20deg / 0)", "lch(-10 -15 340 / 0)",
+"lch(-10 -10 -20 / 0.2)", "lch(-10 -10 340 / 0.2)",
+"lch(-10% -10% -20deg / 0.2)", "lch(-10 -15 340 / 0.2)",
+"lch(-10 -10 -20 / 1)", "lch(-10 -10 340)",
+"lch(-10% -10% -20deg / 1)", "lch(-10 -15 340)",
 "oklch(0 0 0)", "oklch(0 0 0)",
 "oklch(0% 0% 0deg)", "oklch(0 0 0)",
 "oklch(0 0 0 / 0)", "oklch(0 0 0 / 0)",
@@ -2967,14 +2967,14 @@
 "oklch(110% 0% 0deg / 0.2)", "oklch(1.1 0 0 / 0.2)",
 "oklch(110 0 0 / 1)", "oklch(110 0 0)",
 "oklch(110% 0% 0deg / 1)", "oklch(1.1 0 0)",
-"oklch(-10 0 0)", "oklch(0 0 0)",
-"oklch(-10% 0% 0deg)", "oklch(0 0 0)",
-"oklch(-10 0 0 / 0)", "oklch(0 0 0 / 0)",
-"oklch(-10% 0% 0deg / 0)", "oklch(0 0 0 / 0)",
-"oklch(-10 0 0 / 0.2)", "oklch(0 0 0 / 0.2)",
-"oklch(-10% 0% 0deg / 0.2)", "oklch(0 0 0 / 0.2)",
-"oklch(-10 0 0 / 1)", "oklch(0 0 0)",
-"oklch(-10% 0% 0deg / 1)", "oklch(0 0 0)",
+"oklch(-10 0 0)", "oklch(-10 0 0)",
+"oklch(-10% 0% 0deg)", "oklch(-0.1 0 0)",
+"oklch(-10 0 0 / 0)", "oklch(-10 0 0 / 0)",
+"oklch(-10% 0% 0deg / 0)", "oklch(-0.1 0 0 / 0)",
+"oklch(-10 0 0 / 0.2)", "oklch(-10 0 0 / 0.2)",
+"oklch(-10% 0% 0deg / 0.2)", "oklch(-0.1 0 0 / 0.2)",
+"oklch(-10 0 0 / 1)", "oklch(-10 0 0)",
+"oklch(-10% 0% 0deg / 1)", "oklch(-0.1 0 0)",
 "oklch(0 10 0)", "oklch(0 10 0)",
 "oklch(0% 10% 0deg)", "oklch(0 0.04 0)",
 "oklch(0 10 0 / 0)", "oklch(0 10 0 / 0)",
@@ -2999,14 +2999,14 @@
 "oklch(110% 10% 0deg / 0.2)", "oklch(1.1 0.04 0 / 0.2)",
 "oklch(110 10 0 / 1)", "oklch(110 10 0)",
 "oklch(110% 10% 0deg / 1)", "oklch(1.1 0.04 0)",
-"oklch(-10 10 0)", "oklch(0 10 0)",
-"oklch(-10% 10% 0deg)", "oklch(0 0.04 0)",
-"oklch(-10 10 0 / 0)", "oklch(0 10 0 / 0)",
-"oklch(-10% 10% 0deg / 0)", "oklch(0 0.04 0 / 0)",
-"oklch(-10 10 0 / 0.2)", "oklch(0 10 0 / 0.2)",
-"oklch(-10% 10% 0deg / 0.2)", "oklch(0 0.04 0 / 0.2)",
-"oklch(-10 10 0 / 1)", "oklch(0 10 0)",
-"oklch(-10% 10% 0deg / 1)", "oklch(0 0.04 0)",
+"oklch(-10 10 0)", "oklch(-10 10 0)",
+"oklch(-10% 10% 0deg)", "oklch(-0.1 0.04 0)",
+"oklch(-10 10 0 / 0)", "oklch(-10 10 0 / 0)",
+"oklch(-10% 10% 0deg / 0)", "oklch(-0.1 0.04 0 / 0)",
+"oklch(-10 10 0 / 0.2)", "oklch(-10 10 0 / 0.2)",
+"oklch(-10% 10% 0deg / 0.2)", "oklch(-0.1 0.04 0 / 0.2)",
+"oklch(-10 10 0 / 1)", "oklch(-10 10 0)",
+"oklch(-10% 10% 0deg / 1)", "oklch(-0.1 0.04 0)",
 "oklch(0 110 0)", "oklch(0 110 0)",
 "oklch(0% 110% 0deg)", "oklch(0 0.44 0)",
 "oklch(0 110 0 / 0)", "oklch(0 110 0 / 0)",
@@ -3031,46 +3031,46 @@
 "oklch(110% 110% 0deg / 0.2)", "oklch(1.1 0.44 0 / 0.2)",
 "oklch(110 110 0 / 1)", "oklch(110 110 0)",
 "oklch(110% 110% 0deg / 1)", "oklch(1.1 0.44 0)",
-"oklch(-10 110 0)", "oklch(0 110 0)",
-"oklch(-10% 110% 0deg)", "oklch(0 0.44 0)",
-"oklch(-10 110 0 / 0)", "oklch(0 110 0 / 0)",
-"oklch(-10% 110% 0deg / 0)", "oklch(0 0.44 0 / 0)",
-"oklch(-10 110 0 / 0.2)", "oklch(0 110 0 / 0.2)",
-"oklch(-10% 110% 0deg / 0.2)", "oklch(0 0.44 0 / 0.2)",
-"oklch(-10 110 0 / 1)", "oklch(0 110 0)",
-"oklch(-10% 110% 0deg / 1)", "oklch(0 0.44 0)",
-"oklch(0 -10 0)", "oklch(0 0 0)",
-"oklch(0% -10% 0deg)", "oklch(0 0 0)",
-"oklch(0 -10 0 / 0)", "oklch(0 0 0 / 0)",
-"oklch(0% -10% 0deg / 0)", "oklch(0 0 0 / 0)",
-"oklch(0 -10 0 / 0.2)", "oklch(0 0 0 / 0.2)",
-"oklch(0% -10% 0deg / 0.2)", "oklch(0 0 0 / 0.2)",
-"oklch(0 -10 0 / 1)", "oklch(0 0 0)",
-"oklch(0% -10% 0deg / 1)", "oklch(0 0 0)",
-"oklch(10 -10 0)", "oklch(10 0 0)",
-"oklch(10% -10% 0deg)", "oklch(0.1 0 0)",
-"oklch(10 -10 0 / 0)", "oklch(10 0 0 / 0)",
-"oklch(10% -10% 0deg / 0)", "oklch(0.1 0 0 / 0)",
-"oklch(10 -10 0 / 0.2)", "oklch(10 0 0 / 0.2)",
-"oklch(10% -10% 0deg / 0.2)", "oklch(0.1 0 0 / 0.2)",
-"oklch(10 -10 0 / 1)", "oklch(10 0 0)",
-"oklch(10% -10% 0deg / 1)", "oklch(0.1 0 0)",
-"oklch(110 -10 0)", "oklch(110 0 0)",
-"oklch(110% -10% 0deg)", "oklch(1.1 0 0)",
-"oklch(110 -10 0 / 0)", "oklch(110 0 0 / 0)",
-"oklch(110% -10% 0deg / 0)", "oklch(1.1 0 0 / 0)",
-"oklch(110 -10 0 / 0.2)", "oklch(110 0 0 / 0.2)",
-"oklch(110% -10% 0deg / 0.2)", "oklch(1.1 0 0 / 0.2)",
-"oklch(110 -10 0 / 1)", "oklch(110 0 0)",
-"oklch(110% -10% 0deg / 1)", "oklch(1.1 0 0)",
-"oklch(-10 -10 0)", "oklch(0 0 0)",
-"oklch(-10% -10% 0deg)", "oklch(0 0 0)",
-"oklch(-10 -10 0 / 0)", "oklch(0 0 0 / 0)",
-"oklch(-10% -10% 0deg / 0)", "oklch(0 0 0 / 0)",
-"oklch(-10 -10 0 / 0.2)", "oklch(0 0 0 / 0.2)",
-"oklch(-10% -10% 0deg / 0.2)", "oklch(0 0 0 / 0.2)",
-"oklch(-10 -10 0 / 1)", "oklch(0 0 0)",
-"oklch(-10% -10% 0deg / 1)", "oklch(0 0 0)",
+"oklch(-10 110 0)", "oklch(-10 110 0)",
+"oklch(-10% 110% 0deg)", "oklch(-0.1 0.44 0)",
+"oklch(-10 110 0 / 0)", "oklch(-10 110 0 / 0)",
+"oklch(-10% 110% 0deg / 0)", "oklch(-0.1 0.44 0 / 0)",
+"oklch(-10 110 0 / 0.2)", "oklch(-10 110 0 / 0.2)",
+"oklch(-10% 110% 0deg / 0.2)", "oklch(-0.1 0.44 0 / 0.2)",
+"oklch(-10 110 0 / 1)", "oklch(-10 110 0)",
+"oklch(-10% 110% 0deg / 1)", "oklch(-0.1 0.44 0)",
+"oklch(0 -10 0)", "oklch(0 -10 0)",
+"oklch(0% -10% 0deg)", "oklch(0 -0.04 0)",
+"oklch(0 -10 0 / 0)", "oklch(0 -10 0 / 0)",
+"oklch(0% -10% 0deg / 0)", "oklch(0 -0.04 0 / 0)",
+"oklch(0 -10 0 / 0.2)", "oklch(0 -10 0 / 0.2)",
+"oklch(0% -10% 0deg / 0.2)", "oklch(0 -0.04 0 / 0.2)",
+"oklch(0 -10 0 / 1)", "oklch(0 -10 0)",
+"oklch(0% -10% 0deg / 1)", "oklch(0 -0.04 0)",
+"oklch(10 -10 0)", "oklch(10 -10 0)",
+"oklch(10% -10% 0deg)", "oklch(0.1 -0.04 0)",
+"oklch(10 -10 0 / 0)", "oklch(10 -10 0 / 0)",
+"oklch(10% -10% 0deg / 0)", "oklch(0.1 -0.04 0 / 0)",
+"oklch(10 -10 0 / 0.2)", "oklch(10 -10 0 / 0.2)",
+"oklch(10% -10% 0deg / 0.2)", "oklch(0.1 -0.04 0 / 0.2)",
+"oklch(10 -10 0 / 1)", "oklch(10 -10 0)",
+"oklch(10% -10% 0deg / 1)", "oklch(0.1 -0.04 0)",
+"oklch(110 -10 0)", "oklch(110 -10 0)",
+"oklch(110% -10% 0deg)", "oklch(1.1 -0.04 0)",
+"oklch(110 -10 0 / 0)", "oklch(110 -10 0 / 0)",
+"oklch(110% -10% 0deg / 0)", "oklch(1.1 -0.04 0 / 0)",
+"oklch(110 -10 0 / 0.2)", "oklch(110 -10 0 / 0.2)",
+"oklch(110% -10% 0deg / 0.2)", "oklch(1.1 -0.04 0 / 0.2)",
+"oklch(110 -10 0 / 1)", "oklch(110 -10 0)",
+"oklch(110% -10% 0deg / 1)", "oklch(1.1 -0.04 0)",
+"oklch(-10 -10 0)", "oklch(-10 -10 0)",
+"oklch(-10% -10% 0deg)", "oklch(-0.1 -0.04 0)",
+"oklch(-10 -10 0 / 0)", "oklch(-10 -10 0 / 0)",
+"oklch(-10% -10% 0deg / 0)", "oklch(-0.1 -0.04 0 / 0)",
+"oklch(-10 -10 0 / 0.2)", "oklch(-10 -10 0 / 0.2)",
+"oklch(-10% -10% 0deg / 0.2)", "oklch(-0.1 -0.04 0 / 0.2)",
+"oklch(-10 -10 0 / 1)", "oklch(-10 -10 0)",
+"oklch(-10% -10% 0deg / 1)", "oklch(-0.1 -0.04 0)",
 "oklch(0 0 30)", "oklch(0 0 30)",
 "oklch(0% 0% 30deg)", "oklch(0 0 30)",
 "oklch(0 0 30 / 0)", "oklch(0 0 30 / 0)",
@@ -3095,14 +3095,14 @@
 "oklch(110% 0% 30deg / 0.2)", "oklch(1.1 0 30 / 0.2)",
 "oklch(110 0 30 / 1)", "oklch(110 0 30)",
 "oklch(110% 0% 30deg / 1)", "oklch(1.1 0 30)",
-"oklch(-10 0 30)", "oklch(0 0 30)",
-"oklch(-10% 0% 30deg)", "oklch(0 0 30)",
-"oklch(-10 0 30 / 0)", "oklch(0 0 30 / 0)",
-"oklch(-10% 0% 30deg / 0)", "oklch(0 0 30 / 0)",
-"oklch(-10 0 30 / 0.2)", "oklch(0 0 30 / 0.2)",
-"oklch(-10% 0% 30deg / 0.2)", "oklch(0 0 30 / 0.2)",
-"oklch(-10 0 30 / 1)", "oklch(0 0 30)",
-"oklch(-10% 0% 30deg / 1)", "oklch(0 0 30)",
+"oklch(-10 0 30)", "oklch(-10 0 30)",
+"oklch(-10% 0% 30deg)", "oklch(-0.1 0 30)",
+"oklch(-10 0 30 / 0)", "oklch(-10 0 30 / 0)",
+"oklch(-10% 0% 30deg / 0)", "oklch(-0.1 0 30 / 0)",
+"oklch(-10 0 30 / 0.2)", "oklch(-10 0 30 / 0.2)",
+"oklch(-10% 0% 30deg / 0.2)", "oklch(-0.1 0 30 / 0.2)",
+"oklch(-10 0 30 / 1)", "oklch(-10 0 30)",
+"oklch(-10% 0% 30deg / 1)", "oklch(-0.1 0 30)",
 "oklch(0 10 30)", "oklch(0 10 30)",
 "oklch(0% 10% 30deg)", "oklch(0 0.04 30)",
 "oklch(0 10 30 / 0)", "oklch(0 10 30 / 0)",
@@ -3127,14 +3127,14 @@
 "oklch(110% 10% 30deg / 0.2)", "oklch(1.1 0.04 30 / 0.2)",
 "oklch(110 10 30 / 1)", "oklch(110 10 30)",
 "oklch(110% 10% 30deg / 1)", "oklch(1.1 0.04 30)",
-"oklch(-10 10 30)", "oklch(0 10 30)",
-"oklch(-10% 10% 30deg)", "oklch(0 0.04 30)",
-"oklch(-10 10 30 / 0)", "oklch(0 10 30 / 0)",
-"oklch(-10% 10% 30deg / 0)", "oklch(0 0.04 30 / 0)",
-"oklch(-10 10 30 / 0.2)", "oklch(0 10 30 / 0.2)",
-"oklch(-10% 10% 30deg / 0.2)", "oklch(0 0.04 30 / 0.2)",
-"oklch(-10 10 30 / 1)", "oklch(0 10 30)",
-"oklch(-10% 10% 30deg / 1)", "oklch(0 0.04 30)",
+"oklch(-10 10 30)", "oklch(-10 10 30)",
+"oklch(-10% 10% 30deg)", "oklch(-0.1 0.04 30)",
+"oklch(-10 10 30 / 0)", "oklch(-10 10 30 / 0)",
+"oklch(-10% 10% 30deg / 0)", "oklch(-0.1 0.04 30 / 0)",
+"oklch(-10 10 30 / 0.2)", "oklch(-10 10 30 / 0.2)",
+"oklch(-10% 10% 30deg / 0.2)", "oklch(-0.1 0.04 30 / 0.2)",
+"oklch(-10 10 30 / 1)", "oklch(-10 10 30)",
+"oklch(-10% 10% 30deg / 1)", "oklch(-0.1 0.04 30)",
 "oklch(0 110 30)", "oklch(0 110 30)",
 "oklch(0% 110% 30deg)", "oklch(0 0.44 30)",
 "oklch(0 110 30 / 0)", "oklch(0 110 30 / 0)",
@@ -3159,46 +3159,46 @@
 "oklch(110% 110% 30deg / 0.2)", "oklch(1.1 0.44 30 / 0.2)",
 "oklch(110 110 30 / 1)", "oklch(110 110 30)",
 "oklch(110% 110% 30deg / 1)", "oklch(1.1 0.44 30)",
-"oklch(-10 110 30)", "oklch(0 110 30)",
-"oklch(-10% 110% 30deg)", "oklch(0 0.44 30)",
-"oklch(-10 110 30 / 0)", "oklch(0 110 30 / 0)",
-"oklch(-10% 110% 30deg / 0)", "oklch(0 0.44 30 / 0)",
-"oklch(-10 110 30 / 0.2)", "oklch(0 110 30 / 0.2)",
-"oklch(-10% 110% 30deg / 0.2)", "oklch(0 0.44 30 / 0.2)",
-"oklch(-10 110 30 / 1)", "oklch(0 110 30)",
-"oklch(-10% 110% 30deg / 1)", "oklch(0 0.44 30)",
-"oklch(0 -10 30)", "oklch(0 0 30)",
-"oklch(0% -10% 30deg)", "oklch(0 0 30)",
-"oklch(0 -10 30 / 0)", "oklch(0 0 30 / 0)",
-"oklch(0% -10% 30deg / 0)", "oklch(0 0 30 / 0)",
-"oklch(0 -10 30 / 0.2)", "oklch(0 0 30 / 0.2)",
-"oklch(0% -10% 30deg / 0.2)", "oklch(0 0 30 / 0.2)",
-"oklch(0 -10 30 / 1)", "oklch(0 0 30)",
-"oklch(0% -10% 30deg / 1)", "oklch(0 0 30)",
-"oklch(10 -10 30)", "oklch(10 0 30)",
-"oklch(10% -10% 30deg)", "oklch(0.1 0 30)",
-"oklch(10 -10 30 / 0)", "oklch(10 0 30 / 0)",
-"oklch(10% -10% 30deg / 0)", "oklch(0.1 0 30 / 0)",
-"oklch(10 -10 30 / 0.2)", "oklch(10 0 30 / 0.2)",
-"oklch(10% -10% 30deg / 0.2)", "oklch(0.1 0 30 / 0.2)",
-"oklch(10 -10 30 / 1)", "oklch(10 0 30)",
-"oklch(10% -10% 30deg / 1)", "oklch(0.1 0 30)",
-"oklch(110 -10 30)", "oklch(110 0 30)",
-"oklch(110% -10% 30deg)", "oklch(1.1 0 30)",
-"oklch(110 -10 30 / 0)", "oklch(110 0 30 / 0)",
-"oklch(110% -10% 30deg / 0)", "oklch(1.1 0 30 / 0)",
-"oklch(110 -10 30 / 0.2)", "oklch(110 0 30 / 0.2)",
-"oklch(110% -10% 30deg / 0.2)", "oklch(1.1 0 30 / 0.2)",
-"oklch(110 -10 30 / 1)", "oklch(110 0 30)",
-"oklch(110% -10% 30deg / 1)", "oklch(1.1 0 30)",
-"oklch(-10 -10 30)", "oklch(0 0 30)",
-"oklch(-10% -10% 30deg)", "oklch(0 0 30)",
-"oklch(-10 -10 30 / 0)", "oklch(0 0 30 / 0)",
-"oklch(-10% -10% 30deg / 0)", "oklch(0 0 30 / 0)",
-"oklch(-10 -10 30 / 0.2)", "oklch(0 0 30 / 0.2)",
-"oklch(-10% -10% 30deg / 0.2)", "oklch(0 0 30 / 0.2)",
-"oklch(-10 -10 30 / 1)", "oklch(0 0 30)",
-"oklch(-10% -10% 30deg / 1)", "oklch(0 0 30)",
+"oklch(-10 110 30)", "oklch(-10 110 30)",
+"oklch(-10% 110% 30deg)", "oklch(-0.1 0.44 30)",
+"oklch(-10 110 30 / 0)", "oklch(-10 110 30 / 0)",
+"oklch(-10% 110% 30deg / 0)", "oklch(-0.1 0.44 30 / 0)",
+"oklch(-10 110 30 / 0.2)", "oklch(-10 110 30 / 0.2)",
+"oklch(-10% 110% 30deg / 0.2)", "oklch(-0.1 0.44 30 / 0.2)",
+"oklch(-10 110 30 / 1)", "oklch(-10 110 30)",
+"oklch(-10% 110% 30deg / 1)", "oklch(-0.1 0.44 30)",
+"oklch(0 -10 30)", "oklch(0 -10 30)",
+"oklch(0% -10% 30deg)", "oklch(0 -0.04 30)",
+"oklch(0 -10 30 / 0)", "oklch(0 -10 30 / 0)",
+"oklch(0% -10% 30deg / 0)", "oklch(0 -0.04 30 / 0)",
+"oklch(0 -10 30 / 0.2)", "oklch(0 -10 30 / 0.2)",
+"oklch(0% -10% 30deg / 0.2)", "oklch(0 -0.04 30 / 0.2)",
+"oklch(0 -10 30 / 1)", "oklch(0 -10 30)",
+"oklch(0% -10% 30deg / 1)", "oklch(0 -0.04 30)",
+"oklch(10 -10 30)", "oklch(10 -10 30)",
+"oklch(10% -10% 30deg)", "oklch(0.1 -0.04 30)",
+"oklch(10 -10 30 / 0)", "oklch(10 -10 30 / 0)",
+"oklch(10% -10% 30deg / 0)", "oklch(0.1 -0.04 30 / 0)",
+"oklch(10 -10 30 / 0.2)", "oklch(10 -10 30 / 0.2)",
+"oklch(10% -10% 30deg / 0.2)", "oklch(0.1 -0.04 30 / 0.2)",
+"oklch(10 -10 30 / 1)", "oklch(10 -10 30)",
+"oklch(10% -10% 30deg / 1)", "oklch(0.1 -0.04 30)",
+"oklch(110 -10 30)", "oklch(110 -10 30)",
+"oklch(110% -10% 30deg)", "oklch(1.1 -0.04 30)",
+"oklch(110 -10 30 / 0)", "oklch(110 -10 30 / 0)",
+"oklch(110% -10% 30deg / 0)", "oklch(1.1 -0.04 30 / 0)",
+"oklch(110 -10 30 / 0.2)", "oklch(110 -10 30 / 0.2)",
+"oklch(110% -10% 30deg / 0.2)", "oklch(1.1 -0.04 30 / 0.2)",
+"oklch(110 -10 30 / 1)", "oklch(110 -10 30)",
+"oklch(110% -10% 30deg / 1)", "oklch(1.1 -0.04 30)",
+"oklch(-10 -10 30)", "oklch(-10 -10 30)",
+"oklch(-10% -10% 30deg)", "oklch(-0.1 -0.04 30)",
+"oklch(-10 -10 30 / 0)", "oklch(-10 -10 30 / 0)",
+"oklch(-10% -10% 30deg / 0)", "oklch(-0.1 -0.04 30 / 0)",
+"oklch(-10 -10 30 / 0.2)", "oklch(-10 -10 30 / 0.2)",
+"oklch(-10% -10% 30deg / 0.2)", "oklch(-0.1 -0.04 30 / 0.2)",
+"oklch(-10 -10 30 / 1)", "oklch(-10 -10 30)",
+"oklch(-10% -10% 30deg / 1)", "oklch(-0.1 -0.04 30)",
 "oklch(0 0 60)", "oklch(0 0 60)",
 "oklch(0% 0% 60deg)", "oklch(0 0 60)",
 "oklch(0 0 60 / 0)", "oklch(0 0 60 / 0)",
@@ -3223,14 +3223,14 @@
 "oklch(110% 0% 60deg / 0.2)", "oklch(1.1 0 60 / 0.2)",
 "oklch(110 0 60 / 1)", "oklch(110 0 60)",
 "oklch(110% 0% 60deg / 1)", "oklch(1.1 0 60)",
-"oklch(-10 0 60)", "oklch(0 0 60)",
-"oklch(-10% 0% 60deg)", "oklch(0 0 60)",
-"oklch(-10 0 60 / 0)", "oklch(0 0 60 / 0)",
-"oklch(-10% 0% 60deg / 0)", "oklch(0 0 60 / 0)",
-"oklch(-10 0 60 / 0.2)", "oklch(0 0 60 / 0.2)",
-"oklch(-10% 0% 60deg / 0.2)", "oklch(0 0 60 / 0.2)",
-"oklch(-10 0 60 / 1)", "oklch(0 0 60)",
-"oklch(-10% 0% 60deg / 1)", "oklch(0 0 60)",
+"oklch(-10 0 60)", "oklch(-10 0 60)",
+"oklch(-10% 0% 60deg)", "oklch(-0.1 0 60)",
+"oklch(-10 0 60 / 0)", "oklch(-10 0 60 / 0)",
+"oklch(-10% 0% 60deg / 0)", "oklch(-0.1 0 60 / 0)",
+"oklch(-10 0 60 / 0.2)", "oklch(-10 0 60 / 0.2)",
+"oklch(-10% 0% 60deg / 0.2)", "oklch(-0.1 0 60 / 0.2)",
+"oklch(-10 0 60 / 1)", "oklch(-10 0 60)",
+"oklch(-10% 0% 60deg / 1)", "oklch(-0.1 0 60)",
 "oklch(0 10 60)", "oklch(0 10 60)",
 "oklch(0% 10% 60deg)", "oklch(0 0.04 60)",
 "oklch(0 10 60 / 0)", "oklch(0 10 60 / 0)",
@@ -3255,14 +3255,14 @@
 "oklch(110% 10% 60deg / 0.2)", "oklch(1.1 0.04 60 / 0.2)",
 "oklch(110 10 60 / 1)", "oklch(110 10 60)",
 "oklch(110% 10% 60deg / 1)", "oklch(1.1 0.04 60)",
-"oklch(-10 10 60)", "oklch(0 10 60)",
-"oklch(-10% 10% 60deg)", "oklch(0 0.04 60)",
-"oklch(-10 10 60 / 0)", "oklch(0 10 60 / 0)",
-"oklch(-10% 10% 60deg / 0)", "oklch(0 0.04 60 / 0)",
-"oklch(-10 10 60 / 0.2)", "oklch(0 10 60 / 0.2)",
-"oklch(-10% 10% 60deg / 0.2)", "oklch(0 0.04 60 / 0.2)",
-"oklch(-10 10 60 / 1)", "oklch(0 10 60)",
-"oklch(-10% 10% 60deg / 1)", "oklch(0 0.04 60)",
+"oklch(-10 10 60)", "oklch(-10 10 60)",
+"oklch(-10% 10% 60deg)", "oklch(-0.1 0.04 60)",
+"oklch(-10 10 60 / 0)", "oklch(-10 10 60 / 0)",
+"oklch(-10% 10% 60deg / 0)", "oklch(-0.1 0.04 60 / 0)",
+"oklch(-10 10 60 / 0.2)", "oklch(-10 10 60 / 0.2)",
+"oklch(-10% 10% 60deg / 0.2)", "oklch(-0.1 0.04 60 / 0.2)",
+"oklch(-10 10 60 / 1)", "oklch(-10 10 60)",
+"oklch(-10% 10% 60deg / 1)", "oklch(-0.1 0.04 60)",
 "oklch(0 110 60)", "oklch(0 110 60)",
 "oklch(0% 110% 60deg)", "oklch(0 0.44 60)",
 "oklch(0 110 60 / 0)", "oklch(0 110 60 / 0)",
@@ -3287,46 +3287,46 @@
 "oklch(110% 110% 60deg / 0.2)", "oklch(1.1 0.44 60 / 0.2)",
 "oklch(110 110 60 / 1)", "oklch(110 110 60)",
 "oklch(110% 110% 60deg / 1)", "oklch(1.1 0.44 60)",
-"oklch(-10 110 60)", "oklch(0 110 60)",
-"oklch(-10% 110% 60deg)", "oklch(0 0.44 60)",
-"oklch(-10 110 60 / 0)", "oklch(0 110 60 / 0)",
-"oklch(-10% 110% 60deg / 0)", "oklch(0 0.44 60 / 0)",
-"oklch(-10 110 60 / 0.2)", "oklch(0 110 60 / 0.2)",
-"oklch(-10% 110% 60deg / 0.2)", "oklch(0 0.44 60 / 0.2)",
-"oklch(-10 110 60 / 1)", "oklch(0 110 60)",
-"oklch(-10% 110% 60deg / 1)", "oklch(0 0.44 60)",
-"oklch(0 -10 60)", "oklch(0 0 60)",
-"oklch(0% -10% 60deg)", "oklch(0 0 60)",
-"oklch(0 -10 60 / 0)", "oklch(0 0 60 / 0)",
-"oklch(0% -10% 60deg / 0)", "oklch(0 0 60 / 0)",
-"oklch(0 -10 60 / 0.2)", "oklch(0 0 60 / 0.2)",
-"oklch(0% -10% 60deg / 0.2)", "oklch(0 0 60 / 0.2)",
-"oklch(0 -10 60 / 1)", "oklch(0 0 60)",
-"oklch(0% -10% 60deg / 1)", "oklch(0 0 60)",
-"oklch(10 -10 60)", "oklch(10 0 60)",
-"oklch(10% -10% 60deg)", "oklch(0.1 0 60)",
-"oklch(10 -10 60 / 0)", "oklch(10 0 60 / 0)",
-"oklch(10% -10% 60deg / 0)", "oklch(0.1 0 60 / 0)",
-"oklch(10 -10 60 / 0.2)", "oklch(10 0 60 / 0.2)",
-"oklch(10% -10% 60deg / 0.2)", "oklch(0.1 0 60 / 0.2)",
-"oklch(10 -10 60 / 1)", "oklch(10 0 60)",
-"oklch(10% -10% 60deg / 1)", "oklch(0.1 0 60)",
-"oklch(110 -10 60)", "oklch(110 0 60)",
-"oklch(110% -10% 60deg)", "oklch(1.1 0 60)",
-"oklch(110 -10 60 / 0)", "oklch(110 0 60 / 0)",
-"oklch(110% -10% 60deg / 0)", "oklch(1.1 0 60 / 0)",
-"oklch(110 -10 60 / 0.2)", "oklch(110 0 60 / 0.2)",
-"oklch(110% -10% 60deg / 0.2)", "oklch(1.1 0 60 / 0.2)",
-"oklch(110 -10 60 / 1)", "oklch(110 0 60)",
-"oklch(110% -10% 60deg / 1)", "oklch(1.1 0 60)",
-"oklch(-10 -10 60)", "oklch(0 0 60)",
-"oklch(-10% -10% 60deg)", "oklch(0 0 60)",
-"oklch(-10 -10 60 / 0)", "oklch(0 0 60 / 0)",
-"oklch(-10% -10% 60deg / 0)", "oklch(0 0 60 / 0)",
-"oklch(-10 -10 60 / 0.2)", "oklch(0 0 60 / 0.2)",
-"oklch(-10% -10% 60deg / 0.2)", "oklch(0 0 60 / 0.2)",
-"oklch(-10 -10 60 / 1)", "oklch(0 0 60)",
-"oklch(-10% -10% 60deg / 1)", "oklch(0 0 60)",
+"oklch(-10 110 60)", "oklch(-10 110 60)",
+"oklch(-10% 110% 60deg)", "oklch(-0.1 0.44 60)",
+"oklch(-10 110 60 / 0)", "oklch(-10 110 60 / 0)",
+"oklch(-10% 110% 60deg / 0)", "oklch(-0.1 0.44 60 / 0)",
+"oklch(-10 110 60 / 0.2)", "oklch(-10 110 60 / 0.2)",
+"oklch(-10% 110% 60deg / 0.2)", "oklch(-0.1 0.44 60 / 0.2)",
+"oklch(-10 110 60 / 1)", "oklch(-10 110 60)",
+"oklch(-10% 110% 60deg / 1)", "oklch(-0.1 0.44 60)",
+"oklch(0 -10 60)", "oklch(0 -10 60)",
+"oklch(0% -10% 60deg)", "oklch(0 -0.04 60)",
+"oklch(0 -10 60 / 0)", "oklch(0 -10 60 / 0)",
+"oklch(0% -10% 60deg / 0)", "oklch(0 -0.04 60 / 0)",
+"oklch(0 -10 60 / 0.2)", "oklch(0 -10 60 / 0.2)",
+"oklch(0% -10% 60deg / 0.2)", "oklch(0 -0.04 60 / 0.2)",
+"oklch(0 -10 60 / 1)", "oklch(0 -10 60)",
+"oklch(0% -10% 60deg / 1)", "oklch(0 -0.04 60)",
+"oklch(10 -10 60)", "oklch(10 -10 60)",
+"oklch(10% -10% 60deg)", "oklch(0.1 -0.04 60)",
+"oklch(10 -10 60 / 0)", "oklch(10 -10 60 / 0)",
+"oklch(10% -10% 60deg / 0)", "oklch(0.1 -0.04 60 / 0)",
+"oklch(10 -10 60 / 0.2)", "oklch(10 -10 60 / 0.2)",
+"oklch(10% -10% 60deg / 0.2)", "oklch(0.1 -0.04 60 / 0.2)",
+"oklch(10 -10 60 / 1)", "oklch(10 -10 60)",
+"oklch(10% -10% 60deg / 1)", "oklch(0.1 -0.04 60)",
+"oklch(110 -10 60)", "oklch(110 -10 60)",
+"oklch(110% -10% 60deg)", "oklch(1.1 -0.04 60)",
+"oklch(110 -10 60 / 0)", "oklch(110 -10 60 / 0)",
+"oklch(110% -10% 60deg / 0)", "oklch(1.1 -0.04 60 / 0)",
+"oklch(110 -10 60 / 0.2)", "oklch(110 -10 60 / 0.2)",
+"oklch(110% -10% 60deg / 0.2)", "oklch(1.1 -0.04 60 / 0.2)",
+"oklch(110 -10 60 / 1)", "oklch(110 -10 60)",
+"oklch(110% -10% 60deg / 1)", "oklch(1.1 -0.04 60)",
+"oklch(-10 -10 60)", "oklch(-10 -10 60)",
+"oklch(-10% -10% 60deg)", "oklch(-0.1 -0.04 60)",
+"oklch(-10 -10 60 / 0)", "oklch(-10 -10 60 / 0)",
+"oklch(-10% -10% 60deg / 0)", "oklch(-0.1 -0.04 60 / 0)",
+"oklch(-10 -10 60 / 0.2)", "oklch(-10 -10 60 / 0.2)",
+"oklch(-10% -10% 60deg / 0.2)", "oklch(-0.1 -0.04 60 / 0.2)",
+"oklch(-10 -10 60 / 1)", "oklch(-10 -10 60)",
+"oklch(-10% -10% 60deg / 1)", "oklch(-0.1 -0.04 60)",
 "oklch(0 0 90)", "oklch(0 0 90)",
 "oklch(0% 0% 90deg)", "oklch(0 0 90)",
 "oklch(0 0 90 / 0)", "oklch(0 0 90 / 0)",
@@ -3351,14 +3351,14 @@
 "oklch(110% 0% 90deg / 0.2)", "oklch(1.1 0 90 / 0.2)",
 "oklch(110 0 90 / 1)", "oklch(110 0 90)",
 "oklch(110% 0% 90deg / 1)", "oklch(1.1 0 90)",
-"oklch(-10 0 90)", "oklch(0 0 90)",
-"oklch(-10% 0% 90deg)", "oklch(0 0 90)",
-"oklch(-10 0 90 / 0)", "oklch(0 0 90 / 0)",
-"oklch(-10% 0% 90deg / 0)", "oklch(0 0 90 / 0)",
-"oklch(-10 0 90 / 0.2)", "oklch(0 0 90 / 0.2)",
-"oklch(-10% 0% 90deg / 0.2)", "oklch(0 0 90 / 0.2)",
-"oklch(-10 0 90 / 1)", "oklch(0 0 90)",
-"oklch(-10% 0% 90deg / 1)", "oklch(0 0 90)",
+"oklch(-10 0 90)", "oklch(-10 0 90)",
+"oklch(-10% 0% 90deg)", "oklch(-0.1 0 90)",
+"oklch(-10 0 90 / 0)", "oklch(-10 0 90 / 0)",
+"oklch(-10% 0% 90deg / 0)", "oklch(-0.1 0 90 / 0)",
+"oklch(-10 0 90 / 0.2)", "oklch(-10 0 90 / 0.2)",
+"oklch(-10% 0% 90deg / 0.2)", "oklch(-0.1 0 90 / 0.2)",
+"oklch(-10 0 90 / 1)", "oklch(-10 0 90)",
+"oklch(-10% 0% 90deg / 1)", "oklch(-0.1 0 90)",
 "oklch(0 10 90)", "oklch(0 10 90)",
 "oklch(0% 10% 90deg)", "oklch(0 0.04 90)",
 "oklch(0 10 90 / 0)", "oklch(0 10 90 / 0)",
@@ -3383,14 +3383,14 @@
 "oklch(110% 10% 90deg / 0.2)", "oklch(1.1 0.04 90 / 0.2)",
 "oklch(110 10 90 / 1)", "oklch(110 10 90)",
 "oklch(110% 10% 90deg / 1)", "oklch(1.1 0.04 90)",
-"oklch(-10 10 90)", "oklch(0 10 90)",
-"oklch(-10% 10% 90deg)", "oklch(0 0.04 90)",
-"oklch(-10 10 90 / 0)", "oklch(0 10 90 / 0)",
-"oklch(-10% 10% 90deg / 0)", "oklch(0 0.04 90 / 0)",
-"oklch(-10 10 90 / 0.2)", "oklch(0 10 90 / 0.2)",
-"oklch(-10% 10% 90deg / 0.2)", "oklch(0 0.04 90 / 0.2)",
-"oklch(-10 10 90 / 1)", "oklch(0 10 90)",
-"oklch(-10% 10% 90deg / 1)", "oklch(0 0.04 90)",
+"oklch(-10 10 90)", "oklch(-10 10 90)",
+"oklch(-10% 10% 90deg)", "oklch(-0.1 0.04 90)",
+"oklch(-10 10 90 / 0)", "oklch(-10 10 90 / 0)",
+"oklch(-10% 10% 90deg / 0)", "oklch(-0.1 0.04 90 / 0)",
+"oklch(-10 10 90 / 0.2)", "oklch(-10 10 90 / 0.2)",
+"oklch(-10% 10% 90deg / 0.2)", "oklch(-0.1 0.04 90 / 0.2)",
+"oklch(-10 10 90 / 1)", "oklch(-10 10 90)",
+"oklch(-10% 10% 90deg / 1)", "oklch(-0.1 0.04 90)",
 "oklch(0 110 90)", "oklch(0 110 90)",
 "oklch(0% 110% 90deg)", "oklch(0 0.44 90)",
 "oklch(0 110 90 / 0)", "oklch(0 110 90 / 0)",
@@ -3415,46 +3415,46 @@
 "oklch(110% 110% 90deg / 0.2)", "oklch(1.1 0.44 90 / 0.2)",
 "oklch(110 110 90 / 1)", "oklch(110 110 90)",
 "oklch(110% 110% 90deg / 1)", "oklch(1.1 0.44 90)",
-"oklch(-10 110 90)", "oklch(0 110 90)",
-"oklch(-10% 110% 90deg)", "oklch(0 0.44 90)",
-"oklch(-10 110 90 / 0)", "oklch(0 110 90 / 0)",
-"oklch(-10% 110% 90deg / 0)", "oklch(0 0.44 90 / 0)",
-"oklch(-10 110 90 / 0.2)", "oklch(0 110 90 / 0.2)",
-"oklch(-10% 110% 90deg / 0.2)", "oklch(0 0.44 90 / 0.2)",
-"oklch(-10 110 90 / 1)", "oklch(0 110 90)",
-"oklch(-10% 110% 90deg / 1)", "oklch(0 0.44 90)",
-"oklch(0 -10 90)", "oklch(0 0 90)",
-"oklch(0% -10% 90deg)", "oklch(0 0 90)",
-"oklch(0 -10 90 / 0)", "oklch(0 0 90 / 0)",
-"oklch(0% -10% 90deg / 0)", "oklch(0 0 90 / 0)",
-"oklch(0 -10 90 / 0.2)", "oklch(0 0 90 / 0.2)",
-"oklch(0% -10% 90deg / 0.2)", "oklch(0 0 90 / 0.2)",
-"oklch(0 -10 90 / 1)", "oklch(0 0 90)",
-"oklch(0% -10% 90deg / 1)", "oklch(0 0 90)",
-"oklch(10 -10 90)", "oklch(10 0 90)",
-"oklch(10% -10% 90deg)", "oklch(0.1 0 90)",
-"oklch(10 -10 90 / 0)", "oklch(10 0 90 / 0)",
-"oklch(10% -10% 90deg / 0)", "oklch(0.1 0 90 / 0)",
-"oklch(10 -10 90 / 0.2)", "oklch(10 0 90 / 0.2)",
-"oklch(10% -10% 90deg / 0.2)", "oklch(0.1 0 90 / 0.2)",
-"oklch(10 -10 90 / 1)", "oklch(10 0 90)",
-"oklch(10% -10% 90deg / 1)", "oklch(0.1 0 90)",
-"oklch(110 -10 90)", "oklch(110 0 90)",
-"oklch(110% -10% 90deg)", "oklch(1.1 0 90)",
-"oklch(110 -10 90 / 0)", "oklch(110 0 90 / 0)",
-"oklch(110% -10% 90deg / 0)", "oklch(1.1 0 90 / 0)",
-"oklch(110 -10 90 / 0.2)", "oklch(110 0 90 / 0.2)",
-"oklch(110% -10% 90deg / 0.2)", "oklch(1.1 0 90 / 0.2)",
-"oklch(110 -10 90 / 1)", "oklch(110 0 90)",
-"oklch(110% -10% 90deg / 1)", "oklch(1.1 0 90)",
-"oklch(-10 -10 90)", "oklch(0 0 90)",
-"oklch(-10% -10% 90deg)", "oklch(0 0 90)",
-"oklch(-10 -10 90 / 0)", "oklch(0 0 90 / 0)",
-"oklch(-10% -10% 90deg / 0)", "oklch(0 0 90 / 0)",
-"oklch(-10 -10 90 / 0.2)", "oklch(0 0 90 / 0.2)",
-"oklch(-10% -10% 90deg / 0.2)", "oklch(0 0 90 / 0.2)",
-"oklch(-10 -10 90 / 1)", "oklch(0 0 90)",
-"oklch(-10% -10% 90deg / 1)", "oklch(0 0 90)",
+"oklch(-10 110 90)", "oklch(-10 110 90)",
+"oklch(-10% 110% 90deg)", "oklch(-0.1 0.44 90)",
+"oklch(-10 110 90 / 0)", "oklch(-10 110 90 / 0)",
+"oklch(-10% 110% 90deg / 0)", "oklch(-0.1 0.44 90 / 0)",
+"oklch(-10 110 90 / 0.2)", "oklch(-10 110 90 / 0.2)",
+"oklch(-10% 110% 90deg / 0.2)", "oklch(-0.1 0.44 90 / 0.2)",
+"oklch(-10 110 90 / 1)", "oklch(-10 110 90)",
+"oklch(-10% 110% 90deg / 1)", "oklch(-0.1 0.44 90)",
+"oklch(0 -10 90)", "oklch(0 -10 90)",
+"oklch(0% -10% 90deg)", "oklch(0 -0.04 90)",
+"oklch(0 -10 90 / 0)", "oklch(0 -10 90 / 0)",
+"oklch(0% -10% 90deg / 0)", "oklch(0 -0.04 90 / 0)",
+"oklch(0 -10 90 / 0.2)", "oklch(0 -10 90 / 0.2)",
+"oklch(0% -10% 90deg / 0.2)", "oklch(0 -0.04 90 / 0.2)",
+"oklch(0 -10 90 / 1)", "oklch(0 -10 90)",
+"oklch(0% -10% 90deg / 1)", "oklch(0 -0.04 90)",
+"oklch(10 -10 90)", "oklch(10 -10 90)",
+"oklch(10% -10% 90deg)", "oklch(0.1 -0.04 90)",
+"oklch(10 -10 90 / 0)", "oklch(10 -10 90 / 0)",
+"oklch(10% -10% 90deg / 0)", "oklch(0.1 -0.04 90 / 0)",
+"oklch(10 -10 90 / 0.2)", "oklch(10 -10 90 / 0.2)",
+"oklch(10% -10% 90deg / 0.2)", "oklch(0.1 -0.04 90 / 0.2)",
+"oklch(10 -10 90 / 1)", "oklch(10 -10 90)",
+"oklch(10% -10% 90deg / 1)", "oklch(0.1 -0.04 90)",
+"oklch(110 -10 90)", "oklch(110 -10 90)",
+"oklch(110% -10% 90deg)", "oklch(1.1 -0.04 90)",
+"oklch(110 -10 90 / 0)", "oklch(110 -10 90 / 0)",
+"oklch(110% -10% 90deg / 0)", "oklch(1.1 -0.04 90 / 0)",
+"oklch(110 -10 90 / 0.2)", "oklch(110 -10 90 / 0.2)",
+"oklch(110% -10% 90deg / 0.2)", "oklch(1.1 -0.04 90 / 0.2)",
+"oklch(110 -10 90 / 1)", "oklch(110 -10 90)",
+"oklch(110% -10% 90deg / 1)", "oklch(1.1 -0.04 90)",
+"oklch(-10 -10 90)", "oklch(-10 -10 90)",
+"oklch(-10% -10% 90deg)", "oklch(-0.1 -0.04 90)",
+"oklch(-10 -10 90 / 0)", "oklch(-10 -10 90 / 0)",
+"oklch(-10% -10% 90deg / 0)", "oklch(-0.1 -0.04 90 / 0)",
+"oklch(-10 -10 90 / 0.2)", "oklch(-10 -10 90 / 0.2)",
+"oklch(-10% -10% 90deg / 0.2)", "oklch(-0.1 -0.04 90 / 0.2)",
+"oklch(-10 -10 90 / 1)", "oklch(-10 -10 90)",
+"oklch(-10% -10% 90deg / 1)", "oklch(-0.1 -0.04 90)",
 "oklch(0 0 120)", "oklch(0 0 120)",
 "oklch(0% 0% 120deg)", "oklch(0 0 120)",
 "oklch(0 0 120 / 0)", "oklch(0 0 120 / 0)",
@@ -3479,14 +3479,14 @@
 "oklch(110% 0% 120deg / 0.2)", "oklch(1.1 0 120 / 0.2)",
 "oklch(110 0 120 / 1)", "oklch(110 0 120)",
 "oklch(110% 0% 120deg / 1)", "oklch(1.1 0 120)",
-"oklch(-10 0 120)", "oklch(0 0 120)",
-"oklch(-10% 0% 120deg)", "oklch(0 0 120)",
-"oklch(-10 0 120 / 0)", "oklch(0 0 120 / 0)",
-"oklch(-10% 0% 120deg / 0)", "oklch(0 0 120 / 0)",
-"oklch(-10 0 120 / 0.2)", "oklch(0 0 120 / 0.2)",
-"oklch(-10% 0% 120deg / 0.2)", "oklch(0 0 120 / 0.2)",
-"oklch(-10 0 120 / 1)", "oklch(0 0 120)",
-"oklch(-10% 0% 120deg / 1)", "oklch(0 0 120)",
+"oklch(-10 0 120)", "oklch(-10 0 120)",
+"oklch(-10% 0% 120deg)", "oklch(-0.1 0 120)",
+"oklch(-10 0 120 / 0)", "oklch(-10 0 120 / 0)",
+"oklch(-10% 0% 120deg / 0)", "oklch(-0.1 0 120 / 0)",
+"oklch(-10 0 120 / 0.2)", "oklch(-10 0 120 / 0.2)",
+"oklch(-10% 0% 120deg / 0.2)", "oklch(-0.1 0 120 / 0.2)",
+"oklch(-10 0 120 / 1)", "oklch(-10 0 120)",
+"oklch(-10% 0% 120deg / 1)", "oklch(-0.1 0 120)",
 "oklch(0 10 120)", "oklch(0 10 120)",
 "oklch(0% 10% 120deg)", "oklch(0 0.04 120)",
 "oklch(0 10 120 / 0)", "oklch(0 10 120 / 0)",
@@ -3511,14 +3511,14 @@
 "oklch(110% 10% 120deg / 0.2)", "oklch(1.1 0.04 120 / 0.2)",
 "oklch(110 10 120 / 1)", "oklch(110 10 120)",
 "oklch(110% 10% 120deg / 1)", "oklch(1.1 0.04 120)",
-"oklch(-10 10 120)", "oklch(0 10 120)",
-"oklch(-10% 10% 120deg)", "oklch(0 0.04 120)",
-"oklch(-10 10 120 / 0)", "oklch(0 10 120 / 0)",
-"oklch(-10% 10% 120deg / 0)", "oklch(0 0.04 120 / 0)",
-"oklch(-10 10 120 / 0.2)", "oklch(0 10 120 / 0.2)",
-"oklch(-10% 10% 120deg / 0.2)", "oklch(0 0.04 120 / 0.2)",
-"oklch(-10 10 120 / 1)", "oklch(0 10 120)",
-"oklch(-10% 10% 120deg / 1)", "oklch(0 0.04 120)",
+"oklch(-10 10 120)", "oklch(-10 10 120)",
+"oklch(-10% 10% 120deg)", "oklch(-0.1 0.04 120)",
+"oklch(-10 10 120 / 0)", "oklch(-10 10 120 / 0)",
+"oklch(-10% 10% 120deg / 0)", "oklch(-0.1 0.04 120 / 0)",
+"oklch(-10 10 120 / 0.2)", "oklch(-10 10 120 / 0.2)",
+"oklch(-10% 10% 120deg / 0.2)", "oklch(-0.1 0.04 120 / 0.2)",
+"oklch(-10 10 120 / 1)", "oklch(-10 10 120)",
+"oklch(-10% 10% 120deg / 1)", "oklch(-0.1 0.04 120)",
 "oklch(0 110 120)", "oklch(0 110 120)",
 "oklch(0% 110% 120deg)", "oklch(0 0.44 120)",
 "oklch(0 110 120 / 0)", "oklch(0 110 120 / 0)",
@@ -3543,46 +3543,46 @@
 "oklch(110% 110% 120deg / 0.2)", "oklch(1.1 0.44 120 / 0.2)",
 "oklch(110 110 120 / 1)", "oklch(110 110 120)",
 "oklch(110% 110% 120deg / 1)", "oklch(1.1 0.44 120)",
-"oklch(-10 110 120)", "oklch(0 110 120)",
-"oklch(-10% 110% 120deg)", "oklch(0 0.44 120)",
-"oklch(-10 110 120 / 0)", "oklch(0 110 120 / 0)",
-"oklch(-10% 110% 120deg / 0)", "oklch(0 0.44 120 / 0)",
-"oklch(-10 110 120 / 0.2)", "oklch(0 110 120 / 0.2)",
-"oklch(-10% 110% 120deg / 0.2)", "oklch(0 0.44 120 / 0.2)",
-"oklch(-10 110 120 / 1)", "oklch(0 110 120)",
-"oklch(-10% 110% 120deg / 1)", "oklch(0 0.44 120)",
-"oklch(0 -10 120)", "oklch(0 0 120)",
-"oklch(0% -10% 120deg)", "oklch(0 0 120)",
-"oklch(0 -10 120 / 0)", "oklch(0 0 120 / 0)",
-"oklch(0% -10% 120deg / 0)", "oklch(0 0 120 / 0)",
-"oklch(0 -10 120 / 0.2)", "oklch(0 0 120 / 0.2)",
-"oklch(0% -10% 120deg / 0.2)", "oklch(0 0 120 / 0.2)",
-"oklch(0 -10 120 / 1)", "oklch(0 0 120)",
-"oklch(0% -10% 120deg / 1)", "oklch(0 0 120)",
-"oklch(10 -10 120)", "oklch(10 0 120)",
-"oklch(10% -10% 120deg)", "oklch(0.1 0 120)",
-"oklch(10 -10 120 / 0)", "oklch(10 0 120 / 0)",
-"oklch(10% -10% 120deg / 0)", "oklch(0.1 0 120 / 0)",
-"oklch(10 -10 120 / 0.2)", "oklch(10 0 120 / 0.2)",
-"oklch(10% -10% 120deg / 0.2)", "oklch(0.1 0 120 / 0.2)",
-"oklch(10 -10 120 / 1)", "oklch(10 0 120)",
-"oklch(10% -10% 120deg / 1)", "oklch(0.1 0 120)",
-"oklch(110 -10 120)", "oklch(110 0 120)",
-"oklch(110% -10% 120deg)", "oklch(1.1 0 120)",
-"oklch(110 -10 120 / 0)", "oklch(110 0 120 / 0)",
-"oklch(110% -10% 120deg / 0)", "oklch(1.1 0 120 / 0)",
-"oklch(110 -10 120 / 0.2)", "oklch(110 0 120 / 0.2)",
-"oklch(110% -10% 120deg / 0.2)", "oklch(1.1 0 120 / 0.2)",
-"oklch(110 -10 120 / 1)", "oklch(110 0 120)",
-"oklch(110% -10% 120deg / 1)", "oklch(1.1 0 120)",
-"oklch(-10 -10 120)", "oklch(0 0 120)",
-"oklch(-10% -10% 120deg)", "oklch(0 0 120)",
-"oklch(-10 -10 120 / 0)", "oklch(0 0 120 / 0)",
-"oklch(-10% -10% 120deg / 0)", "oklch(0 0 120 / 0)",
-"oklch(-10 -10 120 / 0.2)", "oklch(0 0 120 / 0.2)",
-"oklch(-10% -10% 120deg / 0.2)", "oklch(0 0 120 / 0.2)",
-"oklch(-10 -10 120 / 1)", "oklch(0 0 120)",
-"oklch(-10% -10% 120deg / 1)", "oklch(0 0 120)",
+"oklch(-10 110 120)", "oklch(-10 110 120)",
+"oklch(-10% 110% 120deg)", "oklch(-0.1 0.44 120)",
+"oklch(-10 110 120 / 0)", "oklch(-10 110 120 / 0)",
+"oklch(-10% 110% 120deg / 0)", "oklch(-0.1 0.44 120 / 0)",
+"oklch(-10 110 120 / 0.2)", "oklch(-10 110 120 / 0.2)",
+"oklch(-10% 110% 120deg / 0.2)", "oklch(-0.1 0.44 120 / 0.2)",
+"oklch(-10 110 120 / 1)", "oklch(-10 110 120)",
+"oklch(-10% 110% 120deg / 1)", "oklch(-0.1 0.44 120)",
+"oklch(0 -10 120)", "oklch(0 -10 120)",
+"oklch(0% -10% 120deg)", "oklch(0 -0.04 120)",
+"oklch(0 -10 120 / 0)", "oklch(0 -10 120 / 0)",
+"oklch(0% -10% 120deg / 0)", "oklch(0 -0.04 120 / 0)",
+"oklch(0 -10 120 / 0.2)", "oklch(0 -10 120 / 0.2)",
+"oklch(0% -10% 120deg / 0.2)", "oklch(0 -0.04 120 / 0.2)",
+"oklch(0 -10 120 / 1)", "oklch(0 -10 120)",
+"oklch(0% -10% 120deg / 1)", "oklch(0 -0.04 120)",
+"oklch(10 -10 120)", "oklch(10 -10 120)",
+"oklch(10% -10% 120deg)", "oklch(0.1 -0.04 120)",
+"oklch(10 -10 120 / 0)", "oklch(10 -10 120 / 0)",
+"oklch(10% -10% 120deg / 0)", "oklch(0.1 -0.04 120 / 0)",
+"oklch(10 -10 120 / 0.2)", "oklch(10 -10 120 / 0.2)",
+"oklch(10% -10% 120deg / 0.2)", "oklch(0.1 -0.04 120 / 0.2)",
+"oklch(10 -10 120 / 1)", "oklch(10 -10 120)",
+"oklch(10% -10% 120deg / 1)", "oklch(0.1 -0.04 120)",
+"oklch(110 -10 120)", "oklch(110 -10 120)",
+"oklch(110% -10% 120deg)", "oklch(1.1 -0.04 120)",
+"oklch(110 -10 120 / 0)", "oklch(110 -10 120 / 0)",
+"oklch(110% -10% 120deg / 0)", "oklch(1.1 -0.04 120 / 0)",
+"oklch(110 -10 120 / 0.2)", "oklch(110 -10 120 / 0.2)",
+"oklch(110% -10% 120deg / 0.2)", "oklch(1.1 -0.04 120 / 0.2)",
+"oklch(110 -10 120 / 1)", "oklch(110 -10 120)",
+"oklch(110% -10% 120deg / 1)", "oklch(1.1 -0.04 120)",
+"oklch(-10 -10 120)", "oklch(-10 -10 120)",
+"oklch(-10% -10% 120deg)", "oklch(-0.1 -0.04 120)",
+"oklch(-10 -10 120 / 0)", "oklch(-10 -10 120 / 0)",
+"oklch(-10% -10% 120deg / 0)", "oklch(-0.1 -0.04 120 / 0)",
+"oklch(-10 -10 120 / 0.2)", "oklch(-10 -10 120 / 0.2)",
+"oklch(-10% -10% 120deg / 0.2)", "oklch(-0.1 -0.04 120 / 0.2)",
+"oklch(-10 -10 120 / 1)", "oklch(-10 -10 120)",
+"oklch(-10% -10% 120deg / 1)", "oklch(-0.1 -0.04 120)",
 "oklch(0 0 180)", "oklch(0 0 180)",
 "oklch(0% 0% 180deg)", "oklch(0 0 180)",
 "oklch(0 0 180 / 0)", "oklch(0 0 180 / 0)",
@@ -3607,14 +3607,14 @@
 "oklch(110% 0% 180deg / 0.2)", "oklch(1.1 0 180 / 0.2)",
 "oklch(110 0 180 / 1)", "oklch(110 0 180)",
 "oklch(110% 0% 180deg / 1)", "oklch(1.1 0 180)",
-"oklch(-10 0 180)", "oklch(0 0 180)",
-"oklch(-10% 0% 180deg)", "oklch(0 0 180)",
-"oklch(-10 0 180 / 0)", "oklch(0 0 180 / 0)",
-"oklch(-10% 0% 180deg / 0)", "oklch(0 0 180 / 0)",
-"oklch(-10 0 180 / 0.2)", "oklch(0 0 180 / 0.2)",
-"oklch(-10% 0% 180deg / 0.2)", "oklch(0 0 180 / 0.2)",
-"oklch(-10 0 180 / 1)", "oklch(0 0 180)",
-"oklch(-10% 0% 180deg / 1)", "oklch(0 0 180)",
+"oklch(-10 0 180)", "oklch(-10 0 180)",
+"oklch(-10% 0% 180deg)", "oklch(-0.1 0 180)",
+"oklch(-10 0 180 / 0)", "oklch(-10 0 180 / 0)",
+"oklch(-10% 0% 180deg / 0)", "oklch(-0.1 0 180 / 0)",
+"oklch(-10 0 180 / 0.2)", "oklch(-10 0 180 / 0.2)",
+"oklch(-10% 0% 180deg / 0.2)", "oklch(-0.1 0 180 / 0.2)",
+"oklch(-10 0 180 / 1)", "oklch(-10 0 180)",
+"oklch(-10% 0% 180deg / 1)", "oklch(-0.1 0 180)",
 "oklch(0 10 180)", "oklch(0 10 180)",
 "oklch(0% 10% 180deg)", "oklch(0 0.04 180)",
 "oklch(0 10 180 / 0)", "oklch(0 10 180 / 0)",
@@ -3639,14 +3639,14 @@
 "oklch(110% 10% 180deg / 0.2)", "oklch(1.1 0.04 180 / 0.2)",
 "oklch(110 10 180 / 1)", "oklch(110 10 180)",
 "oklch(110% 10% 180deg / 1)", "oklch(1.1 0.04 180)",
-"oklch(-10 10 180)", "oklch(0 10 180)",
-"oklch(-10% 10% 180deg)", "oklch(0 0.04 180)",
-"oklch(-10 10 180 / 0)", "oklch(0 10 180 / 0)",
-"oklch(-10% 10% 180deg / 0)", "oklch(0 0.04 180 / 0)",
-"oklch(-10 10 180 / 0.2)", "oklch(0 10 180 / 0.2)",
-"oklch(-10% 10% 180deg / 0.2)", "oklch(0 0.04 180 / 0.2)",
-"oklch(-10 10 180 / 1)", "oklch(0 10 180)",
-"oklch(-10% 10% 180deg / 1)", "oklch(0 0.04 180)",
+"oklch(-10 10 180)", "oklch(-10 10 180)",
+"oklch(-10% 10% 180deg)", "oklch(-0.1 0.04 180)",
+"oklch(-10 10 180 / 0)", "oklch(-10 10 180 / 0)",
+"oklch(-10% 10% 180deg / 0)", "oklch(-0.1 0.04 180 / 0)",
+"oklch(-10 10 180 / 0.2)", "oklch(-10 10 180 / 0.2)",
+"oklch(-10% 10% 180deg / 0.2)", "oklch(-0.1 0.04 180 / 0.2)",
+"oklch(-10 10 180 / 1)", "oklch(-10 10 180)",
+"oklch(-10% 10% 180deg / 1)", "oklch(-0.1 0.04 180)",
 "oklch(0 110 180)", "oklch(0 110 180)",
 "oklch(0% 110% 180deg)", "oklch(0 0.44 180)",
 "oklch(0 110 180 / 0)", "oklch(0 110 180 / 0)",
@@ -3671,46 +3671,46 @@
 "oklch(110% 110% 180deg / 0.2)", "oklch(1.1 0.44 180 / 0.2)",
 "oklch(110 110 180 / 1)", "oklch(110 110 180)",
 "oklch(110% 110% 180deg / 1)", "oklch(1.1 0.44 180)",
-"oklch(-10 110 180)", "oklch(0 110 180)",
-"oklch(-10% 110% 180deg)", "oklch(0 0.44 180)",
-"oklch(-10 110 180 / 0)", "oklch(0 110 180 / 0)",
-"oklch(-10% 110% 180deg / 0)", "oklch(0 0.44 180 / 0)",
-"oklch(-10 110 180 / 0.2)", "oklch(0 110 180 / 0.2)",
-"oklch(-10% 110% 180deg / 0.2)", "oklch(0 0.44 180 / 0.2)",
-"oklch(-10 110 180 / 1)", "oklch(0 110 180)",
-"oklch(-10% 110% 180deg / 1)", "oklch(0 0.44 180)",
-"oklch(0 -10 180)", "oklch(0 0 180)",
-"oklch(0% -10% 180deg)", "oklch(0 0 180)",
-"oklch(0 -10 180 / 0)", "oklch(0 0 180 / 0)",
-"oklch(0% -10% 180deg / 0)", "oklch(0 0 180 / 0)",
-"oklch(0 -10 180 / 0.2)", "oklch(0 0 180 / 0.2)",
-"oklch(0% -10% 180deg / 0.2)", "oklch(0 0 180 / 0.2)",
-"oklch(0 -10 180 / 1)", "oklch(0 0 180)",
-"oklch(0% -10% 180deg / 1)", "oklch(0 0 180)",
-"oklch(10 -10 180)", "oklch(10 0 180)",
-"oklch(10% -10% 180deg)", "oklch(0.1 0 180)",
-"oklch(10 -10 180 / 0)", "oklch(10 0 180 / 0)",
-"oklch(10% -10% 180deg / 0)", "oklch(0.1 0 180 / 0)",
-"oklch(10 -10 180 / 0.2)", "oklch(10 0 180 / 0.2)",
-"oklch(10% -10% 180deg / 0.2)", "oklch(0.1 0 180 / 0.2)",
-"oklch(10 -10 180 / 1)", "oklch(10 0 180)",
-"oklch(10% -10% 180deg / 1)", "oklch(0.1 0 180)",
-"oklch(110 -10 180)", "oklch(110 0 180)",
-"oklch(110% -10% 180deg)", "oklch(1.1 0 180)",
-"oklch(110 -10 180 / 0)", "oklch(110 0 180 / 0)",
-"oklch(110% -10% 180deg / 0)", "oklch(1.1 0 180 / 0)",
-"oklch(110 -10 180 / 0.2)", "oklch(110 0 180 / 0.2)",
-"oklch(110% -10% 180deg / 0.2)", "oklch(1.1 0 180 / 0.2)",
-"oklch(110 -10 180 / 1)", "oklch(110 0 180)",
-"oklch(110% -10% 180deg / 1)", "oklch(1.1 0 180)",
-"oklch(-10 -10 180)", "oklch(0 0 180)",
-"oklch(-10% -10% 180deg)", "oklch(0 0 180)",
-"oklch(-10 -10 180 / 0)", "oklch(0 0 180 / 0)",
-"oklch(-10% -10% 180deg / 0)", "oklch(0 0 180 / 0)",
-"oklch(-10 -10 180 / 0.2)", "oklch(0 0 180 / 0.2)",
-"oklch(-10% -10% 180deg / 0.2)", "oklch(0 0 180 / 0.2)",
-"oklch(-10 -10 180 / 1)", "oklch(0 0 180)",
-"oklch(-10% -10% 180deg / 1)", "oklch(0 0 180)",
+"oklch(-10 110 180)", "oklch(-10 110 180)",
+"oklch(-10% 110% 180deg)", "oklch(-0.1 0.44 180)",
+"oklch(-10 110 180 / 0)", "oklch(-10 110 180 / 0)",
+"oklch(-10% 110% 180deg / 0)", "oklch(-0.1 0.44 180 / 0)",
+"oklch(-10 110 180 / 0.2)", "oklch(-10 110 180 / 0.2)",
+"oklch(-10% 110% 180deg / 0.2)", "oklch(-0.1 0.44 180 / 0.2)",
+"oklch(-10 110 180 / 1)", "oklch(-10 110 180)",
+"oklch(-10% 110% 180deg / 1)", "oklch(-0.1 0.44 180)",
+"oklch(0 -10 180)", "oklch(0 -10 180)",
+"oklch(0% -10% 180deg)", "oklch(0 -0.04 180)",
+"oklch(0 -10 180 / 0)", "oklch(0 -10 180 / 0)",
+"oklch(0% -10% 180deg / 0)", "oklch(0 -0.04 180 / 0)",
+"oklch(0 -10 180 / 0.2)", "oklch(0 -10 180 / 0.2)",
+"oklch(0% -10% 180deg / 0.2)", "oklch(0 -0.04 180 / 0.2)",
+"oklch(0 -10 180 / 1)", "oklch(0 -10 180)",
+"oklch(0% -10% 180deg / 1)", "oklch(0 -0.04 180)",
+"oklch(10 -10 180)", "oklch(10 -10 180)",
+"oklch(10% -10% 180deg)", "oklch(0.1 -0.04 180)",
+"oklch(10 -10 180 / 0)", "oklch(10 -10 180 / 0)",
+"oklch(10% -10% 180deg / 0)", "oklch(0.1 -0.04 180 / 0)",
+"oklch(10 -10 180 / 0.2)", "oklch(10 -10 180 / 0.2)",
+"oklch(10% -10% 180deg / 0.2)", "oklch(0.1 -0.04 180 / 0.2)",
+"oklch(10 -10 180 / 1)", "oklch(10 -10 180)",
+"oklch(10% -10% 180deg / 1)", "oklch(0.1 -0.04 180)",
+"oklch(110 -10 180)", "oklch(110 -10 180)",
+"oklch(110% -10% 180deg)", "oklch(1.1 -0.04 180)",
+"oklch(110 -10 180 / 0)", "oklch(110 -10 180 / 0)",
+"oklch(110% -10% 180deg / 0)", "oklch(1.1 -0.04 180 / 0)",
+"oklch(110 -10 180 / 0.2)", "oklch(110 -10 180 / 0.2)",
+"oklch(110% -10% 180deg / 0.2)", "oklch(1.1 -0.04 180 / 0.2)",
+"oklch(110 -10 180 / 1)", "oklch(110 -10 180)",
+"oklch(110% -10% 180deg / 1)", "oklch(1.1 -0.04 180)",
+"oklch(-10 -10 180)", "oklch(-10 -10 180)",
+"oklch(-10% -10% 180deg)", "oklch(-0.1 -0.04 180)",
+"oklch(-10 -10 180 / 0)", "oklch(-10 -10 180 / 0)",
+"oklch(-10% -10% 180deg / 0)", "oklch(-0.1 -0.04 180 / 0)",
+"oklch(-10 -10 180 / 0.2)", "oklch(-10 -10 180 / 0.2)",
+"oklch(-10% -10% 180deg / 0.2)", "oklch(-0.1 -0.04 180 / 0.2)",
+"oklch(-10 -10 180 / 1)", "oklch(-10 -10 180)",
+"oklch(-10% -10% 180deg / 1)", "oklch(-0.1 -0.04 180)",
 "oklch(0 0 210)", "oklch(0 0 210)",
 "oklch(0% 0% 210deg)", "oklch(0 0 210)",
 "oklch(0 0 210 / 0)", "oklch(0 0 210 / 0)",
@@ -3735,14 +3735,14 @@
 "oklch(110% 0% 210deg / 0.2)", "oklch(1.1 0 210 / 0.2)",
 "oklch(110 0 210 / 1)", "oklch(110 0 210)",
 "oklch(110% 0% 210deg / 1)", "oklch(1.1 0 210)",
-"oklch(-10 0 210)", "oklch(0 0 210)",
-"oklch(-10% 0% 210deg)", "oklch(0 0 210)",
-"oklch(-10 0 210 / 0)", "oklch(0 0 210 / 0)",
-"oklch(-10% 0% 210deg / 0)", "oklch(0 0 210 / 0)",
-"oklch(-10 0 210 / 0.2)", "oklch(0 0 210 / 0.2)",
-"oklch(-10% 0% 210deg / 0.2)", "oklch(0 0 210 / 0.2)",
-"oklch(-10 0 210 / 1)", "oklch(0 0 210)",
-"oklch(-10% 0% 210deg / 1)", "oklch(0 0 210)",
+"oklch(-10 0 210)", "oklch(-10 0 210)",
+"oklch(-10% 0% 210deg)", "oklch(-0.1 0 210)",
+"oklch(-10 0 210 / 0)", "oklch(-10 0 210 / 0)",
+"oklch(-10% 0% 210deg / 0)", "oklch(-0.1 0 210 / 0)",
+"oklch(-10 0 210 / 0.2)", "oklch(-10 0 210 / 0.2)",
+"oklch(-10% 0% 210deg / 0.2)", "oklch(-0.1 0 210 / 0.2)",
+"oklch(-10 0 210 / 1)", "oklch(-10 0 210)",
+"oklch(-10% 0% 210deg / 1)", "oklch(-0.1 0 210)",
 "oklch(0 10 210)", "oklch(0 10 210)",
 "oklch(0% 10% 210deg)", "oklch(0 0.04 210)",
 "oklch(0 10 210 / 0)", "oklch(0 10 210 / 0)",
@@ -3767,14 +3767,14 @@
 "oklch(110% 10% 210deg / 0.2)", "oklch(1.1 0.04 210 / 0.2)",
 "oklch(110 10 210 / 1)", "oklch(110 10 210)",
 "oklch(110% 10% 210deg / 1)", "oklch(1.1 0.04 210)",
-"oklch(-10 10 210)", "oklch(0 10 210)",
-"oklch(-10% 10% 210deg)", "oklch(0 0.04 210)",
-"oklch(-10 10 210 / 0)", "oklch(0 10 210 / 0)",
-"oklch(-10% 10% 210deg / 0)", "oklch(0 0.04 210 / 0)",
-"oklch(-10 10 210 / 0.2)", "oklch(0 10 210 / 0.2)",
-"oklch(-10% 10% 210deg / 0.2)", "oklch(0 0.04 210 / 0.2)",
-"oklch(-10 10 210 / 1)", "oklch(0 10 210)",
-"oklch(-10% 10% 210deg / 1)", "oklch(0 0.04 210)",
+"oklch(-10 10 210)", "oklch(-10 10 210)",
+"oklch(-10% 10% 210deg)", "oklch(-0.1 0.04 210)",
+"oklch(-10 10 210 / 0)", "oklch(-10 10 210 / 0)",
+"oklch(-10% 10% 210deg / 0)", "oklch(-0.1 0.04 210 / 0)",
+"oklch(-10 10 210 / 0.2)", "oklch(-10 10 210 / 0.2)",
+"oklch(-10% 10% 210deg / 0.2)", "oklch(-0.1 0.04 210 / 0.2)",
+"oklch(-10 10 210 / 1)", "oklch(-10 10 210)",
+"oklch(-10% 10% 210deg / 1)", "oklch(-0.1 0.04 210)",
 "oklch(0 110 210)", "oklch(0 110 210)",
 "oklch(0% 110% 210deg)", "oklch(0 0.44 210)",
 "oklch(0 110 210 / 0)", "oklch(0 110 210 / 0)",
@@ -3799,46 +3799,46 @@
 "oklch(110% 110% 210deg / 0.2)", "oklch(1.1 0.44 210 / 0.2)",
 "oklch(110 110 210 / 1)", "oklch(110 110 210)",
 "oklch(110% 110% 210deg / 1)", "oklch(1.1 0.44 210)",
-"oklch(-10 110 210)", "oklch(0 110 210)",
-"oklch(-10% 110% 210deg)", "oklch(0 0.44 210)",
-"oklch(-10 110 210 / 0)", "oklch(0 110 210 / 0)",
-"oklch(-10% 110% 210deg / 0)", "oklch(0 0.44 210 / 0)",
-"oklch(-10 110 210 / 0.2)", "oklch(0 110 210 / 0.2)",
-"oklch(-10% 110% 210deg / 0.2)", "oklch(0 0.44 210 / 0.2)",
-"oklch(-10 110 210 / 1)", "oklch(0 110 210)",
-"oklch(-10% 110% 210deg / 1)", "oklch(0 0.44 210)",
-"oklch(0 -10 210)", "oklch(0 0 210)",
-"oklch(0% -10% 210deg)", "oklch(0 0 210)",
-"oklch(0 -10 210 / 0)", "oklch(0 0 210 / 0)",
-"oklch(0% -10% 210deg / 0)", "oklch(0 0 210 / 0)",
-"oklch(0 -10 210 / 0.2)", "oklch(0 0 210 / 0.2)",
-"oklch(0% -10% 210deg / 0.2)", "oklch(0 0 210 / 0.2)",
-"oklch(0 -10 210 / 1)", "oklch(0 0 210)",
-"oklch(0% -10% 210deg / 1)", "oklch(0 0 210)",
-"oklch(10 -10 210)", "oklch(10 0 210)",
-"oklch(10% -10% 210deg)", "oklch(0.1 0 210)",
-"oklch(10 -10 210 / 0)", "oklch(10 0 210 / 0)",
-"oklch(10% -10% 210deg / 0)", "oklch(0.1 0 210 / 0)",
-"oklch(10 -10 210 / 0.2)", "oklch(10 0 210 / 0.2)",
-"oklch(10% -10% 210deg / 0.2)", "oklch(0.1 0 210 / 0.2)",
-"oklch(10 -10 210 / 1)", "oklch(10 0 210)",
-"oklch(10% -10% 210deg / 1)", "oklch(0.1 0 210)",
-"oklch(110 -10 210)", "oklch(110 0 210)",
-"oklch(110% -10% 210deg)", "oklch(1.1 0 210)",
-"oklch(110 -10 210 / 0)", "oklch(110 0 210 / 0)",
-"oklch(110% -10% 210deg / 0)", "oklch(1.1 0 210 / 0)",
-"oklch(110 -10 210 / 0.2)", "oklch(110 0 210 / 0.2)",
-"oklch(110% -10% 210deg / 0.2)", "oklch(1.1 0 210 / 0.2)",
-"oklch(110 -10 210 / 1)", "oklch(110 0 210)",
-"oklch(110% -10% 210deg / 1)", "oklch(1.1 0 210)",
-"oklch(-10 -10 210)", "oklch(0 0 210)",
-"oklch(-10% -10% 210deg)", "oklch(0 0 210)",
-"oklch(-10 -10 210 / 0)", "oklch(0 0 210 / 0)",
-"oklch(-10% -10% 210deg / 0)", "oklch(0 0 210 / 0)",
-"oklch(-10 -10 210 / 0.2)", "oklch(0 0 210 / 0.2)",
-"oklch(-10% -10% 210deg / 0.2)", "oklch(0 0 210 / 0.2)",
-"oklch(-10 -10 210 / 1)", "oklch(0 0 210)",
-"oklch(-10% -10% 210deg / 1)", "oklch(0 0 210)",
+"oklch(-10 110 210)", "oklch(-10 110 210)",
+"oklch(-10% 110% 210deg)", "oklch(-0.1 0.44 210)",
+"oklch(-10 110 210 / 0)", "oklch(-10 110 210 / 0)",
+"oklch(-10% 110% 210deg / 0)", "oklch(-0.1 0.44 210 / 0)",
+"oklch(-10 110 210 / 0.2)", "oklch(-10 110 210 / 0.2)",
+"oklch(-10% 110% 210deg / 0.2)", "oklch(-0.1 0.44 210 / 0.2)",
+"oklch(-10 110 210 / 1)", "oklch(-10 110 210)",
+"oklch(-10% 110% 210deg / 1)", "oklch(-0.1 0.44 210)",
+"oklch(0 -10 210)", "oklch(0 -10 210)",
+"oklch(0% -10% 210deg)", "oklch(0 -0.04 210)",
+"oklch(0 -10 210 / 0)", "oklch(0 -10 210 / 0)",
+"oklch(0% -10% 210deg / 0)", "oklch(0 -0.04 210 / 0)",
+"oklch(0 -10 210 / 0.2)", "oklch(0 -10 210 / 0.2)",
+"oklch(0% -10% 210deg / 0.2)", "oklch(0 -0.04 210 / 0.2)",
+"oklch(0 -10 210 / 1)", "oklch(0 -10 210)",
+"oklch(0% -10% 210deg / 1)", "oklch(0 -0.04 210)",
+"oklch(10 -10 210)", "oklch(10 -10 210)",
+"oklch(10% -10% 210deg)", "oklch(0.1 -0.04 210)",
+"oklch(10 -10 210 / 0)", "oklch(10 -10 210 / 0)",
+"oklch(10% -10% 210deg / 0)", "oklch(0.1 -0.04 210 / 0)",
+"oklch(10 -10 210 / 0.2)", "oklch(10 -10 210 / 0.2)",
+"oklch(10% -10% 210deg / 0.2)", "oklch(0.1 -0.04 210 / 0.2)",
+"oklch(10 -10 210 / 1)", "oklch(10 -10 210)",
+"oklch(10% -10% 210deg / 1)", "oklch(0.1 -0.04 210)",
+"oklch(110 -10 210)", "oklch(110 -10 210)",
+"oklch(110% -10% 210deg)", "oklch(1.1 -0.04 210)",
+"oklch(110 -10 210 / 0)", "oklch(110 -10 210 / 0)",
+"oklch(110% -10% 210deg / 0)", "oklch(1.1 -0.04 210 / 0)",
+"oklch(110 -10 210 / 0.2)", "oklch(110 -10 210 / 0.2)",
+"oklch(110% -10% 210deg / 0.2)", "oklch(1.1 -0.04 210 / 0.2)",
+"oklch(110 -10 210 / 1)", "oklch(110 -10 210)",
+"oklch(110% -10% 210deg / 1)", "oklch(1.1 -0.04 210)",
+"oklch(-10 -10 210)", "oklch(-10 -10 210)",
+"oklch(-10% -10% 210deg)", "oklch(-0.1 -0.04 210)",
+"oklch(-10 -10 210 / 0)", "oklch(-10 -10 210 / 0)",
+"oklch(-10% -10% 210deg / 0)", "oklch(-0.1 -0.04 210 / 0)",
+"oklch(-10 -10 210 / 0.2)", "oklch(-10 -10 210 / 0.2)",
+"oklch(-10% -10% 210deg / 0.2)", "oklch(-0.1 -0.04 210 / 0.2)",
+"oklch(-10 -10 210 / 1)", "oklch(-10 -10 210)",
+"oklch(-10% -10% 210deg / 1)", "oklch(-0.1 -0.04 210)",
 "oklch(0 0 240)", "oklch(0 0 240)",
 "oklch(0% 0% 240deg)", "oklch(0 0 240)",
 "oklch(0 0 240 / 0)", "oklch(0 0 240 / 0)",
@@ -3863,14 +3863,14 @@
 "oklch(110% 0% 240deg / 0.2)", "oklch(1.1 0 240 / 0.2)",
 "oklch(110 0 240 / 1)", "oklch(110 0 240)",
 "oklch(110% 0% 240deg / 1)", "oklch(1.1 0 240)",
-"oklch(-10 0 240)", "oklch(0 0 240)",
-"oklch(-10% 0% 240deg)", "oklch(0 0 240)",
-"oklch(-10 0 240 / 0)", "oklch(0 0 240 / 0)",
-"oklch(-10% 0% 240deg / 0)", "oklch(0 0 240 / 0)",
-"oklch(-10 0 240 / 0.2)", "oklch(0 0 240 / 0.2)",
-"oklch(-10% 0% 240deg / 0.2)", "oklch(0 0 240 / 0.2)",
-"oklch(-10 0 240 / 1)", "oklch(0 0 240)",
-"oklch(-10% 0% 240deg / 1)", "oklch(0 0 240)",
+"oklch(-10 0 240)", "oklch(-10 0 240)",
+"oklch(-10% 0% 240deg)", "oklch(-0.1 0 240)",
+"oklch(-10 0 240 / 0)", "oklch(-10 0 240 / 0)",
+"oklch(-10% 0% 240deg / 0)", "oklch(-0.1 0 240 / 0)",
+"oklch(-10 0 240 / 0.2)", "oklch(-10 0 240 / 0.2)",
+"oklch(-10% 0% 240deg / 0.2)", "oklch(-0.1 0 240 / 0.2)",
+"oklch(-10 0 240 / 1)", "oklch(-10 0 240)",
+"oklch(-10% 0% 240deg / 1)", "oklch(-0.1 0 240)",
 "oklch(0 10 240)", "oklch(0 10 240)",
 "oklch(0% 10% 240deg)", "oklch(0 0.04 240)",
 "oklch(0 10 240 / 0)", "oklch(0 10 240 / 0)",
@@ -3895,14 +3895,14 @@
 "oklch(110% 10% 240deg / 0.2)", "oklch(1.1 0.04 240 / 0.2)",
 "oklch(110 10 240 / 1)", "oklch(110 10 240)",
 "oklch(110% 10% 240deg / 1)", "oklch(1.1 0.04 240)",
-"oklch(-10 10 240)", "oklch(0 10 240)",
-"oklch(-10% 10% 240deg)", "oklch(0 0.04 240)",
-"oklch(-10 10 240 / 0)", "oklch(0 10 240 / 0)",
-"oklch(-10% 10% 240deg / 0)", "oklch(0 0.04 240 / 0)",
-"oklch(-10 10 240 / 0.2)", "oklch(0 10 240 / 0.2)",
-"oklch(-10% 10% 240deg / 0.2)", "oklch(0 0.04 240 / 0.2)",
-"oklch(-10 10 240 / 1)", "oklch(0 10 240)",
-"oklch(-10% 10% 240deg / 1)", "oklch(0 0.04 240)",
+"oklch(-10 10 240)", "oklch(-10 10 240)",
+"oklch(-10% 10% 240deg)", "oklch(-0.1 0.04 240)",
+"oklch(-10 10 240 / 0)", "oklch(-10 10 240 / 0)",
+"oklch(-10% 10% 240deg / 0)", "oklch(-0.1 0.04 240 / 0)",
+"oklch(-10 10 240 / 0.2)", "oklch(-10 10 240 / 0.2)",
+"oklch(-10% 10% 240deg / 0.2)", "oklch(-0.1 0.04 240 / 0.2)",
+"oklch(-10 10 240 / 1)", "oklch(-10 10 240)",
+"oklch(-10% 10% 240deg / 1)", "oklch(-0.1 0.04 240)",
 "oklch(0 110 240)", "oklch(0 110 240)",
 "oklch(0% 110% 240deg)", "oklch(0 0.44 240)",
 "oklch(0 110 240 / 0)", "oklch(0 110 240 / 0)",
@@ -3927,46 +3927,46 @@
 "oklch(110% 110% 240deg / 0.2)", "oklch(1.1 0.44 240 / 0.2)",
 "oklch(110 110 240 / 1)", "oklch(110 110 240)",
 "oklch(110% 110% 240deg / 1)", "oklch(1.1 0.44 240)",
-"oklch(-10 110 240)", "oklch(0 110 240)",
-"oklch(-10% 110% 240deg)", "oklch(0 0.44 240)",
-"oklch(-10 110 240 / 0)", "oklch(0 110 240 / 0)",
-"oklch(-10% 110% 240deg / 0)", "oklch(0 0.44 240 / 0)",
-"oklch(-10 110 240 / 0.2)", "oklch(0 110 240 / 0.2)",
-"oklch(-10% 110% 240deg / 0.2)", "oklch(0 0.44 240 / 0.2)",
-"oklch(-10 110 240 / 1)", "oklch(0 110 240)",
-"oklch(-10% 110% 240deg / 1)", "oklch(0 0.44 240)",
-"oklch(0 -10 240)", "oklch(0 0 240)",
-"oklch(0% -10% 240deg)", "oklch(0 0 240)",
-"oklch(0 -10 240 / 0)", "oklch(0 0 240 / 0)",
-"oklch(0% -10% 240deg / 0)", "oklch(0 0 240 / 0)",
-"oklch(0 -10 240 / 0.2)", "oklch(0 0 240 / 0.2)",
-"oklch(0% -10% 240deg / 0.2)", "oklch(0 0 240 / 0.2)",
-"oklch(0 -10 240 / 1)", "oklch(0 0 240)",
-"oklch(0% -10% 240deg / 1)", "oklch(0 0 240)",
-"oklch(10 -10 240)", "oklch(10 0 240)",
-"oklch(10% -10% 240deg)", "oklch(0.1 0 240)",
-"oklch(10 -10 240 / 0)", "oklch(10 0 240 / 0)",
-"oklch(10% -10% 240deg / 0)", "oklch(0.1 0 240 / 0)",
-"oklch(10 -10 240 / 0.2)", "oklch(10 0 240 / 0.2)",
-"oklch(10% -10% 240deg / 0.2)", "oklch(0.1 0 240 / 0.2)",
-"oklch(10 -10 240 / 1)", "oklch(10 0 240)",
-"oklch(10% -10% 240deg / 1)", "oklch(0.1 0 240)",
-"oklch(110 -10 240)", "oklch(110 0 240)",
-"oklch(110% -10% 240deg)", "oklch(1.1 0 240)",
-"oklch(110 -10 240 / 0)", "oklch(110 0 240 / 0)",
-"oklch(110% -10% 240deg / 0)", "oklch(1.1 0 240 / 0)",
-"oklch(110 -10 240 / 0.2)", "oklch(110 0 240 / 0.2)",
-"oklch(110% -10% 240deg / 0.2)", "oklch(1.1 0 240 / 0.2)",
-"oklch(110 -10 240 / 1)", "oklch(110 0 240)",
-"oklch(110% -10% 240deg / 1)", "oklch(1.1 0 240)",
-"oklch(-10 -10 240)", "oklch(0 0 240)",
-"oklch(-10% -10% 240deg)", "oklch(0 0 240)",
-"oklch(-10 -10 240 / 0)", "oklch(0 0 240 / 0)",
-"oklch(-10% -10% 240deg / 0)", "oklch(0 0 240 / 0)",
-"oklch(-10 -10 240 / 0.2)", "oklch(0 0 240 / 0.2)",
-"oklch(-10% -10% 240deg / 0.2)", "oklch(0 0 240 / 0.2)",
-"oklch(-10 -10 240 / 1)", "oklch(0 0 240)",
-"oklch(-10% -10% 240deg / 1)", "oklch(0 0 240)",
+"oklch(-10 110 240)", "oklch(-10 110 240)",
+"oklch(-10% 110% 240deg)", "oklch(-0.1 0.44 240)",
+"oklch(-10 110 240 / 0)", "oklch(-10 110 240 / 0)",
+"oklch(-10% 110% 240deg / 0)", "oklch(-0.1 0.44 240 / 0)",
+"oklch(-10 110 240 / 0.2)", "oklch(-10 110 240 / 0.2)",
+"oklch(-10% 110% 240deg / 0.2)", "oklch(-0.1 0.44 240 / 0.2)",
+"oklch(-10 110 240 / 1)", "oklch(-10 110 240)",
+"oklch(-10% 110% 240deg / 1)", "oklch(-0.1 0.44 240)",
+"oklch(0 -10 240)", "oklch(0 -10 240)",
+"oklch(0% -10% 240deg)", "oklch(0 -0.04 240)",
+"oklch(0 -10 240 / 0)", "oklch(0 -10 240 / 0)",
+"oklch(0% -10% 240deg / 0)", "oklch(0 -0.04 240 / 0)",
+"oklch(0 -10 240 / 0.2)", "oklch(0 -10 240 / 0.2)",
+"oklch(0% -10% 240deg / 0.2)", "oklch(0 -0.04 240 / 0.2)",
+"oklch(0 -10 240 / 1)", "oklch(0 -10 240)",
+"oklch(0% -10% 240deg / 1)", "oklch(0 -0.04 240)",
+"oklch(10 -10 240)", "oklch(10 -10 240)",
+"oklch(10% -10% 240deg)", "oklch(0.1 -0.04 240)",
+"oklch(10 -10 240 / 0)", "oklch(10 -10 240 / 0)",
+"oklch(10% -10% 240deg / 0)", "oklch(0.1 -0.04 240 / 0)",
+"oklch(10 -10 240 / 0.2)", "oklch(10 -10 240 / 0.2)",
+"oklch(10% -10% 240deg / 0.2)", "oklch(0.1 -0.04 240 / 0.2)",
+"oklch(10 -10 240 / 1)", "oklch(10 -10 240)",
+"oklch(10% -10% 240deg / 1)", "oklch(0.1 -0.04 240)",
+"oklch(110 -10 240)", "oklch(110 -10 240)",
+"oklch(110% -10% 240deg)", "oklch(1.1 -0.04 240)",
+"oklch(110 -10 240 / 0)", "oklch(110 -10 240 / 0)",
+"oklch(110% -10% 240deg / 0)", "oklch(1.1 -0.04 240 / 0)",
+"oklch(110 -10 240 / 0.2)", "oklch(110 -10 240 / 0.2)",
+"oklch(110% -10% 240deg / 0.2)", "oklch(1.1 -0.04 240 / 0.2)",
+"oklch(110 -10 240 / 1)", "oklch(110 -10 240)",
+"oklch(110% -10% 240deg / 1)", "oklch(1.1 -0.04 240)",
+"oklch(-10 -10 240)", "oklch(-10 -10 240)",
+"oklch(-10% -10% 240deg)", "oklch(-0.1 -0.04 240)",
+"oklch(-10 -10 240 / 0)", "oklch(-10 -10 240 / 0)",
+"oklch(-10% -10% 240deg / 0)", "oklch(-0.1 -0.04 240 / 0)",
+"oklch(-10 -10 240 / 0.2)", "oklch(-10 -10 240 / 0.2)",
+"oklch(-10% -10% 240deg / 0.2)", "oklch(-0.1 -0.04 240 / 0.2)",
+"oklch(-10 -10 240 / 1)", "oklch(-10 -10 240)",
+"oklch(-10% -10% 240deg / 1)", "oklch(-0.1 -0.04 240)",
 "oklch(0 0 270)", "oklch(0 0 270)",
 "oklch(0% 0% 270deg)", "oklch(0 0 270)",
 "oklch(0 0 270 / 0)", "oklch(0 0 270 / 0)",
@@ -3991,14 +3991,14 @@
 "oklch(110% 0% 270deg / 0.2)", "oklch(1.1 0 270 / 0.2)",
 "oklch(110 0 270 / 1)", "oklch(110 0 270)",
 "oklch(110% 0% 270deg / 1)", "oklch(1.1 0 270)",
-"oklch(-10 0 270)", "oklch(0 0 270)",
-"oklch(-10% 0% 270deg)", "oklch(0 0 270)",
-"oklch(-10 0 270 / 0)", "oklch(0 0 270 / 0)",
-"oklch(-10% 0% 270deg / 0)", "oklch(0 0 270 / 0)",
-"oklch(-10 0 270 / 0.2)", "oklch(0 0 270 / 0.2)",
-"oklch(-10% 0% 270deg / 0.2)", "oklch(0 0 270 / 0.2)",
-"oklch(-10 0 270 / 1)", "oklch(0 0 270)",
-"oklch(-10% 0% 270deg / 1)", "oklch(0 0 270)",
+"oklch(-10 0 270)", "oklch(-10 0 270)",
+"oklch(-10% 0% 270deg)", "oklch(-0.1 0 270)",
+"oklch(-10 0 270 / 0)", "oklch(-10 0 270 / 0)",
+"oklch(-10% 0% 270deg / 0)", "oklch(-0.1 0 270 / 0)",
+"oklch(-10 0 270 / 0.2)", "oklch(-10 0 270 / 0.2)",
+"oklch(-10% 0% 270deg / 0.2)", "oklch(-0.1 0 270 / 0.2)",
+"oklch(-10 0 270 / 1)", "oklch(-10 0 270)",
+"oklch(-10% 0% 270deg / 1)", "oklch(-0.1 0 270)",
 "oklch(0 10 270)", "oklch(0 10 270)",
 "oklch(0% 10% 270deg)", "oklch(0 0.04 270)",
 "oklch(0 10 270 / 0)", "oklch(0 10 270 / 0)",
@@ -4023,14 +4023,14 @@
 "oklch(110% 10% 270deg / 0.2)", "oklch(1.1 0.04 270 / 0.2)",
 "oklch(110 10 270 / 1)", "oklch(110 10 270)",
 "oklch(110% 10% 270deg / 1)", "oklch(1.1 0.04 270)",
-"oklch(-10 10 270)", "oklch(0 10 270)",
-"oklch(-10% 10% 270deg)", "oklch(0 0.04 270)",
-"oklch(-10 10 270 / 0)", "oklch(0 10 270 / 0)",
-"oklch(-10% 10% 270deg / 0)", "oklch(0 0.04 270 / 0)",
-"oklch(-10 10 270 / 0.2)", "oklch(0 10 270 / 0.2)",
-"oklch(-10% 10% 270deg / 0.2)", "oklch(0 0.04 270 / 0.2)",
-"oklch(-10 10 270 / 1)", "oklch(0 10 270)",
-"oklch(-10% 10% 270deg / 1)", "oklch(0 0.04 270)",
+"oklch(-10 10 270)", "oklch(-10 10 270)",
+"oklch(-10% 10% 270deg)", "oklch(-0.1 0.04 270)",
+"oklch(-10 10 270 / 0)", "oklch(-10 10 270 / 0)",
+"oklch(-10% 10% 270deg / 0)", "oklch(-0.1 0.04 270 / 0)",
+"oklch(-10 10 270 / 0.2)", "oklch(-10 10 270 / 0.2)",
+"oklch(-10% 10% 270deg / 0.2)", "oklch(-0.1 0.04 270 / 0.2)",
+"oklch(-10 10 270 / 1)", "oklch(-10 10 270)",
+"oklch(-10% 10% 270deg / 1)", "oklch(-0.1 0.04 270)",
 "oklch(0 110 270)", "oklch(0 110 270)",
 "oklch(0% 110% 270deg)", "oklch(0 0.44 270)",
 "oklch(0 110 270 / 0)", "oklch(0 110 270 / 0)",
@@ -4055,46 +4055,46 @@
 "oklch(110% 110% 270deg / 0.2)", "oklch(1.1 0.44 270 / 0.2)",
 "oklch(110 110 270 / 1)", "oklch(110 110 270)",
 "oklch(110% 110% 270deg / 1)", "oklch(1.1 0.44 270)",
-"oklch(-10 110 270)", "oklch(0 110 270)",
-"oklch(-10% 110% 270deg)", "oklch(0 0.44 270)",
-"oklch(-10 110 270 / 0)", "oklch(0 110 270 / 0)",
-"oklch(-10% 110% 270deg / 0)", "oklch(0 0.44 270 / 0)",
-"oklch(-10 110 270 / 0.2)", "oklch(0 110 270 / 0.2)",
-"oklch(-10% 110% 270deg / 0.2)", "oklch(0 0.44 270 / 0.2)",
-"oklch(-10 110 270 / 1)", "oklch(0 110 270)",
-"oklch(-10% 110% 270deg / 1)", "oklch(0 0.44 270)",
-"oklch(0 -10 270)", "oklch(0 0 270)",
-"oklch(0% -10% 270deg)", "oklch(0 0 270)",
-"oklch(0 -10 270 / 0)", "oklch(0 0 270 / 0)",
-"oklch(0% -10% 270deg / 0)", "oklch(0 0 270 / 0)",
-"oklch(0 -10 270 / 0.2)", "oklch(0 0 270 / 0.2)",
-"oklch(0% -10% 270deg / 0.2)", "oklch(0 0 270 / 0.2)",
-"oklch(0 -10 270 / 1)", "oklch(0 0 270)",
-"oklch(0% -10% 270deg / 1)", "oklch(0 0 270)",
-"oklch(10 -10 270)", "oklch(10 0 270)",
-"oklch(10% -10% 270deg)", "oklch(0.1 0 270)",
-"oklch(10 -10 270 / 0)", "oklch(10 0 270 / 0)",
-"oklch(10% -10% 270deg / 0)", "oklch(0.1 0 270 / 0)",
-"oklch(10 -10 270 / 0.2)", "oklch(10 0 270 / 0.2)",
-"oklch(10% -10% 270deg / 0.2)", "oklch(0.1 0 270 / 0.2)",
-"oklch(10 -10 270 / 1)", "oklch(10 0 270)",
-"oklch(10% -10% 270deg / 1)", "oklch(0.1 0 270)",
-"oklch(110 -10 270)", "oklch(110 0 270)",
-"oklch(110% -10% 270deg)", "oklch(1.1 0 270)",
-"oklch(110 -10 270 / 0)", "oklch(110 0 270 / 0)",
-"oklch(110% -10% 270deg / 0)", "oklch(1.1 0 270 / 0)",
-"oklch(110 -10 270 / 0.2)", "oklch(110 0 270 / 0.2)",
-"oklch(110% -10% 270deg / 0.2)", "oklch(1.1 0 270 / 0.2)",
-"oklch(110 -10 270 / 1)", "oklch(110 0 270)",
-"oklch(110% -10% 270deg / 1)", "oklch(1.1 0 270)",
-"oklch(-10 -10 270)", "oklch(0 0 270)",
-"oklch(-10% -10% 270deg)", "oklch(0 0 270)",
-"oklch(-10 -10 270 / 0)", "oklch(0 0 270 / 0)",
-"oklch(-10% -10% 270deg / 0)", "oklch(0 0 270 / 0)",
-"oklch(-10 -10 270 / 0.2)", "oklch(0 0 270 / 0.2)",
-"oklch(-10% -10% 270deg / 0.2)", "oklch(0 0 270 / 0.2)",
-"oklch(-10 -10 270 / 1)", "oklch(0 0 270)",
-"oklch(-10% -10% 270deg / 1)", "oklch(0 0 270)",
+"oklch(-10 110 270)", "oklch(-10 110 270)",
+"oklch(-10% 110% 270deg)", "oklch(-0.1 0.44 270)",
+"oklch(-10 110 270 / 0)", "oklch(-10 110 270 / 0)",
+"oklch(-10% 110% 270deg / 0)", "oklch(-0.1 0.44 270 / 0)",
+"oklch(-10 110 270 / 0.2)", "oklch(-10 110 270 / 0.2)",
+"oklch(-10% 110% 270deg / 0.2)", "oklch(-0.1 0.44 270 / 0.2)",
+"oklch(-10 110 270 / 1)", "oklch(-10 110 270)",
+"oklch(-10% 110% 270deg / 1)", "oklch(-0.1 0.44 270)",
+"oklch(0 -10 270)", "oklch(0 -10 270)",
+"oklch(0% -10% 270deg)", "oklch(0 -0.04 270)",
+"oklch(0 -10 270 / 0)", "oklch(0 -10 270 / 0)",
+"oklch(0% -10% 270deg / 0)", "oklch(0 -0.04 270 / 0)",
+"oklch(0 -10 270 / 0.2)", "oklch(0 -10 270 / 0.2)",
+"oklch(0% -10% 270deg / 0.2)", "oklch(0 -0.04 270 / 0.2)",
+"oklch(0 -10 270 / 1)", "oklch(0 -10 270)",
+"oklch(0% -10% 270deg / 1)", "oklch(0 -0.04 270)",
+"oklch(10 -10 270)", "oklch(10 -10 270)",
+"oklch(10% -10% 270deg)", "oklch(0.1 -0.04 270)",
+"oklch(10 -10 270 / 0)", "oklch(10 -10 270 / 0)",
+"oklch(10% -10% 270deg / 0)", "oklch(0.1 -0.04 270 / 0)",
+"oklch(10 -10 270 / 0.2)", "oklch(10 -10 270 / 0.2)",
+"oklch(10% -10% 270deg / 0.2)", "oklch(0.1 -0.04 270 / 0.2)",
+"oklch(10 -10 270 / 1)", "oklch(10 -10 270)",
+"oklch(10% -10% 270deg / 1)", "oklch(0.1 -0.04 270)",
+"oklch(110 -10 270)", "oklch(110 -10 270)",
+"oklch(110% -10% 270deg)", "oklch(1.1 -0.04 270)",
+"oklch(110 -10 270 / 0)", "oklch(110 -10 270 / 0)",
+"oklch(110% -10% 270deg / 0)", "oklch(1.1 -0.04 270 / 0)",
+"oklch(110 -10 270 / 0.2)", "oklch(110 -10 270 / 0.2)",
+"oklch(110% -10% 270deg / 0.2)", "oklch(1.1 -0.04 270 / 0.2)",
+"oklch(110 -10 270 / 1)", "oklch(110 -10 270)",
+"oklch(110% -10% 270deg / 1)", "oklch(1.1 -0.04 270)",
+"oklch(-10 -10 270)", "oklch(-10 -10 270)",
+"oklch(-10% -10% 270deg)", "oklch(-0.1 -0.04 270)",
+"oklch(-10 -10 270 / 0)", "oklch(-10 -10 270 / 0)",
+"oklch(-10% -10% 270deg / 0)", "oklch(-0.1 -0.04 270 / 0)",
+"oklch(-10 -10 270 / 0.2)", "oklch(-10 -10 270 / 0.2)",
+"oklch(-10% -10% 270deg / 0.2)", "oklch(-0.1 -0.04 270 / 0.2)",
+"oklch(-10 -10 270 / 1)", "oklch(-10 -10 270)",
+"oklch(-10% -10% 270deg / 1)", "oklch(-0.1 -0.04 270)",
 "oklch(0 0 300)", "oklch(0 0 300)",
 "oklch(0% 0% 300deg)", "oklch(0 0 300)",
 "oklch(0 0 300 / 0)", "oklch(0 0 300 / 0)",
@@ -4119,14 +4119,14 @@
 "oklch(110% 0% 300deg / 0.2)", "oklch(1.1 0 300 / 0.2)",
 "oklch(110 0 300 / 1)", "oklch(110 0 300)",
 "oklch(110% 0% 300deg / 1)", "oklch(1.1 0 300)",
-"oklch(-10 0 300)", "oklch(0 0 300)",
-"oklch(-10% 0% 300deg)", "oklch(0 0 300)",
-"oklch(-10 0 300 / 0)", "oklch(0 0 300 / 0)",
-"oklch(-10% 0% 300deg / 0)", "oklch(0 0 300 / 0)",
-"oklch(-10 0 300 / 0.2)", "oklch(0 0 300 / 0.2)",
-"oklch(-10% 0% 300deg / 0.2)", "oklch(0 0 300 / 0.2)",
-"oklch(-10 0 300 / 1)", "oklch(0 0 300)",
-"oklch(-10% 0% 300deg / 1)", "oklch(0 0 300)",
+"oklch(-10 0 300)", "oklch(-10 0 300)",
+"oklch(-10% 0% 300deg)", "oklch(-0.1 0 300)",
+"oklch(-10 0 300 / 0)", "oklch(-10 0 300 / 0)",
+"oklch(-10% 0% 300deg / 0)", "oklch(-0.1 0 300 / 0)",
+"oklch(-10 0 300 / 0.2)", "oklch(-10 0 300 / 0.2)",
+"oklch(-10% 0% 300deg / 0.2)", "oklch(-0.1 0 300 / 0.2)",
+"oklch(-10 0 300 / 1)", "oklch(-10 0 300)",
+"oklch(-10% 0% 300deg / 1)", "oklch(-0.1 0 300)",
 "oklch(0 10 300)", "oklch(0 10 300)",
 "oklch(0% 10% 300deg)", "oklch(0 0.04 300)",
 "oklch(0 10 300 / 0)", "oklch(0 10 300 / 0)",
@@ -4151,14 +4151,14 @@
 "oklch(110% 10% 300deg / 0.2)", "oklch(1.1 0.04 300 / 0.2)",
 "oklch(110 10 300 / 1)", "oklch(110 10 300)",
 "oklch(110% 10% 300deg / 1)", "oklch(1.1 0.04 300)",
-"oklch(-10 10 300)", "oklch(0 10 300)",
-"oklch(-10% 10% 300deg)", "oklch(0 0.04 300)",
-"oklch(-10 10 300 / 0)", "oklch(0 10 300 / 0)",
-"oklch(-10% 10% 300deg / 0)", "oklch(0 0.04 300 / 0)",
-"oklch(-10 10 300 / 0.2)", "oklch(0 10 300 / 0.2)",
-"oklch(-10% 10% 300deg / 0.2)", "oklch(0 0.04 300 / 0.2)",
-"oklch(-10 10 300 / 1)", "oklch(0 10 300)",
-"oklch(-10% 10% 300deg / 1)", "oklch(0 0.04 300)",
+"oklch(-10 10 300)", "oklch(-10 10 300)",
+"oklch(-10% 10% 300deg)", "oklch(-0.1 0.04 300)",
+"oklch(-10 10 300 / 0)", "oklch(-10 10 300 / 0)",
+"oklch(-10% 10% 300deg / 0)", "oklch(-0.1 0.04 300 / 0)",
+"oklch(-10 10 300 / 0.2)", "oklch(-10 10 300 / 0.2)",
+"oklch(-10% 10% 300deg / 0.2)", "oklch(-0.1 0.04 300 / 0.2)",
+"oklch(-10 10 300 / 1)", "oklch(-10 10 300)",
+"oklch(-10% 10% 300deg / 1)", "oklch(-0.1 0.04 300)",
 "oklch(0 110 300)", "oklch(0 110 300)",
 "oklch(0% 110% 300deg)", "oklch(0 0.44 300)",
 "oklch(0 110 300 / 0)", "oklch(0 110 300 / 0)",
@@ -4183,46 +4183,46 @@
 "oklch(110% 110% 300deg / 0.2)", "oklch(1.1 0.44 300 / 0.2)",
 "oklch(110 110 300 / 1)", "oklch(110 110 300)",
 "oklch(110% 110% 300deg / 1)", "oklch(1.1 0.44 300)",
-"oklch(-10 110 300)", "oklch(0 110 300)",
-"oklch(-10% 110% 300deg)", "oklch(0 0.44 300)",
-"oklch(-10 110 300 / 0)", "oklch(0 110 300 / 0)",
-"oklch(-10% 110% 300deg / 0)", "oklch(0 0.44 300 / 0)",
-"oklch(-10 110 300 / 0.2)", "oklch(0 110 300 / 0.2)",
-"oklch(-10% 110% 300deg / 0.2)", "oklch(0 0.44 300 / 0.2)",
-"oklch(-10 110 300 / 1)", "oklch(0 110 300)",
-"oklch(-10% 110% 300deg / 1)", "oklch(0 0.44 300)",
-"oklch(0 -10 300)", "oklch(0 0 300)",
-"oklch(0% -10% 300deg)", "oklch(0 0 300)",
-"oklch(0 -10 300 / 0)", "oklch(0 0 300 / 0)",
-"oklch(0% -10% 300deg / 0)", "oklch(0 0 300 / 0)",
-"oklch(0 -10 300 / 0.2)", "oklch(0 0 300 / 0.2)",
-"oklch(0% -10% 300deg / 0.2)", "oklch(0 0 300 / 0.2)",
-"oklch(0 -10 300 / 1)", "oklch(0 0 300)",
-"oklch(0% -10% 300deg / 1)", "oklch(0 0 300)",
-"oklch(10 -10 300)", "oklch(10 0 300)",
-"oklch(10% -10% 300deg)", "oklch(0.1 0 300)",
-"oklch(10 -10 300 / 0)", "oklch(10 0 300 / 0)",
-"oklch(10% -10% 300deg / 0)", "oklch(0.1 0 300 / 0)",
-"oklch(10 -10 300 / 0.2)", "oklch(10 0 300 / 0.2)",
-"oklch(10% -10% 300deg / 0.2)", "oklch(0.1 0 300 / 0.2)",
-"oklch(10 -10 300 / 1)", "oklch(10 0 300)",
-"oklch(10% -10% 300deg / 1)", "oklch(0.1 0 300)",
-"oklch(110 -10 300)", "oklch(110 0 300)",
-"oklch(110% -10% 300deg)", "oklch(1.1 0 300)",
-"oklch(110 -10 300 / 0)", "oklch(110 0 300 / 0)",
-"oklch(110% -10% 300deg / 0)", "oklch(1.1 0 300 / 0)",
-"oklch(110 -10 300 / 0.2)", "oklch(110 0 300 / 0.2)",
-"oklch(110% -10% 300deg / 0.2)", "oklch(1.1 0 300 / 0.2)",
-"oklch(110 -10 300 / 1)", "oklch(110 0 300)",
-"oklch(110% -10% 300deg / 1)", "oklch(1.1 0 300)",
-"oklch(-10 -10 300)", "oklch(0 0 300)",
-"oklch(-10% -10% 300deg)", "oklch(0 0 300)",
-"oklch(-10 -10 300 / 0)", "oklch(0 0 300 / 0)",
-"oklch(-10% -10% 300deg / 0)", "oklch(0 0 300 / 0)",
-"oklch(-10 -10 300 / 0.2)", "oklch(0 0 300 / 0.2)",
-"oklch(-10% -10% 300deg / 0.2)", "oklch(0 0 300 / 0.2)",
-"oklch(-10 -10 300 / 1)", "oklch(0 0 300)",
-"oklch(-10% -10% 300deg / 1)", "oklch(0 0 300)",
+"oklch(-10 110 300)", "oklch(-10 110 300)",
+"oklch(-10% 110% 300deg)", "oklch(-0.1 0.44 300)",
+"oklch(-10 110 300 / 0)", "oklch(-10 110 300 / 0)",
+"oklch(-10% 110% 300deg / 0)", "oklch(-0.1 0.44 300 / 0)",
+"oklch(-10 110 300 / 0.2)", "oklch(-10 110 300 / 0.2)",
+"oklch(-10% 110% 300deg / 0.2)", "oklch(-0.1 0.44 300 / 0.2)",
+"oklch(-10 110 300 / 1)", "oklch(-10 110 300)",
+"oklch(-10% 110% 300deg / 1)", "oklch(-0.1 0.44 300)",
+"oklch(0 -10 300)", "oklch(0 -10 300)",
+"oklch(0% -10% 300deg)", "oklch(0 -0.04 300)",
+"oklch(0 -10 300 / 0)", "oklch(0 -10 300 / 0)",
+"oklch(0% -10% 300deg / 0)", "oklch(0 -0.04 300 / 0)",
+"oklch(0 -10 300 / 0.2)", "oklch(0 -10 300 / 0.2)",
+"oklch(0% -10% 300deg / 0.2)", "oklch(0 -0.04 300 / 0.2)",
+"oklch(0 -10 300 / 1)", "oklch(0 -10 300)",
+"oklch(0% -10% 300deg / 1)", "oklch(0 -0.04 300)",
+"oklch(10 -10 300)", "oklch(10 -10 300)",
+"oklch(10% -10% 300deg)", "oklch(0.1 -0.04 300)",
+"oklch(10 -10 300 / 0)", "oklch(10 -10 300 / 0)",
+"oklch(10% -10% 300deg / 0)", "oklch(0.1 -0.04 300 / 0)",
+"oklch(10 -10 300 / 0.2)", "oklch(10 -10 300 / 0.2)",
+"oklch(10% -10% 300deg / 0.2)", "oklch(0.1 -0.04 300 / 0.2)",
+"oklch(10 -10 300 / 1)", "oklch(10 -10 300)",
+"oklch(10% -10% 300deg / 1)", "oklch(0.1 -0.04 300)",
+"oklch(110 -10 300)", "oklch(110 -10 300)",
+"oklch(110% -10% 300deg)", "oklch(1.1 -0.04 300)",
+"oklch(110 -10 300 / 0)", "oklch(110 -10 300 / 0)",
+"oklch(110% -10% 300deg / 0)", "oklch(1.1 -0.04 300 / 0)",
+"oklch(110 -10 300 / 0.2)", "oklch(110 -10 300 / 0.2)",
+"oklch(110% -10% 300deg / 0.2)", "oklch(1.1 -0.04 300 / 0.2)",
+"oklch(110 -10 300 / 1)", "oklch(110 -10 300)",
+"oklch(110% -10% 300deg / 1)", "oklch(1.1 -0.04 300)",
+"oklch(-10 -10 300)", "oklch(-10 -10 300)",
+"oklch(-10% -10% 300deg)", "oklch(-0.1 -0.04 300)",
+"oklch(-10 -10 300 / 0)", "oklch(-10 -10 300 / 0)",
+"oklch(-10% -10% 300deg / 0)", "oklch(-0.1 -0.04 300 / 0)",
+"oklch(-10 -10 300 / 0.2)", "oklch(-10 -10 300 / 0.2)",
+"oklch(-10% -10% 300deg / 0.2)", "oklch(-0.1 -0.04 300 / 0.2)",
+"oklch(-10 -10 300 / 1)", "oklch(-10 -10 300)",
+"oklch(-10% -10% 300deg / 1)", "oklch(-0.1 -0.04 300)",
 "oklch(0 0 330)", "oklch(0 0 330)",
 "oklch(0% 0% 330deg)", "oklch(0 0 330)",
 "oklch(0 0 330 / 0)", "oklch(0 0 330 / 0)",
@@ -4247,14 +4247,14 @@
 "oklch(110% 0% 330deg / 0.2)", "oklch(1.1 0 330 / 0.2)",
 "oklch(110 0 330 / 1)", "oklch(110 0 330)",
 "oklch(110% 0% 330deg / 1)", "oklch(1.1 0 330)",
-"oklch(-10 0 330)", "oklch(0 0 330)",
-"oklch(-10% 0% 330deg)", "oklch(0 0 330)",
-"oklch(-10 0 330 / 0)", "oklch(0 0 330 / 0)",
-"oklch(-10% 0% 330deg / 0)", "oklch(0 0 330 / 0)",
-"oklch(-10 0 330 / 0.2)", "oklch(0 0 330 / 0.2)",
-"oklch(-10% 0% 330deg / 0.2)", "oklch(0 0 330 / 0.2)",
-"oklch(-10 0 330 / 1)", "oklch(0 0 330)",
-"oklch(-10% 0% 330deg / 1)", "oklch(0 0 330)",
+"oklch(-10 0 330)", "oklch(-10 0 330)",
+"oklch(-10% 0% 330deg)", "oklch(-0.1 0 330)",
+"oklch(-10 0 330 / 0)", "oklch(-10 0 330 / 0)",
+"oklch(-10% 0% 330deg / 0)", "oklch(-0.1 0 330 / 0)",
+"oklch(-10 0 330 / 0.2)", "oklch(-10 0 330 / 0.2)",
+"oklch(-10% 0% 330deg / 0.2)", "oklch(-0.1 0 330 / 0.2)",
+"oklch(-10 0 330 / 1)", "oklch(-10 0 330)",
+"oklch(-10% 0% 330deg / 1)", "oklch(-0.1 0 330)",
 "oklch(0 10 330)", "oklch(0 10 330)",
 "oklch(0% 10% 330deg)", "oklch(0 0.04 330)",
 "oklch(0 10 330 / 0)", "oklch(0 10 330 / 0)",
@@ -4279,14 +4279,14 @@
 "oklch(110% 10% 330deg / 0.2)", "oklch(1.1 0.04 330 / 0.2)",
 "oklch(110 10 330 / 1)", "oklch(110 10 330)",
 "oklch(110% 10% 330deg / 1)", "oklch(1.1 0.04 330)",
-"oklch(-10 10 330)", "oklch(0 10 330)",
-"oklch(-10% 10% 330deg)", "oklch(0 0.04 330)",
-"oklch(-10 10 330 / 0)", "oklch(0 10 330 / 0)",
-"oklch(-10% 10% 330deg / 0)", "oklch(0 0.04 330 / 0)",
-"oklch(-10 10 330 / 0.2)", "oklch(0 10 330 / 0.2)",
-"oklch(-10% 10% 330deg / 0.2)", "oklch(0 0.04 330 / 0.2)",
-"oklch(-10 10 330 / 1)", "oklch(0 10 330)",
-"oklch(-10% 10% 330deg / 1)", "oklch(0 0.04 330)",
+"oklch(-10 10 330)", "oklch(-10 10 330)",
+"oklch(-10% 10% 330deg)", "oklch(-0.1 0.04 330)",
+"oklch(-10 10 330 / 0)", "oklch(-10 10 330 / 0)",
+"oklch(-10% 10% 330deg / 0)", "oklch(-0.1 0.04 330 / 0)",
+"oklch(-10 10 330 / 0.2)", "oklch(-10 10 330 / 0.2)",
+"oklch(-10% 10% 330deg / 0.2)", "oklch(-0.1 0.04 330 / 0.2)",
+"oklch(-10 10 330 / 1)", "oklch(-10 10 330)",
+"oklch(-10% 10% 330deg / 1)", "oklch(-0.1 0.04 330)",
 "oklch(0 110 330)", "oklch(0 110 330)",
 "oklch(0% 110% 330deg)", "oklch(0 0.44 330)",
 "oklch(0 110 330 / 0)", "oklch(0 110 330 / 0)",
@@ -4311,46 +4311,46 @@
 "oklch(110% 110% 330deg / 0.2)", "oklch(1.1 0.44 330 / 0.2)",
 "oklch(110 110 330 / 1)", "oklch(110 110 330)",
 "oklch(110% 110% 330deg / 1)", "oklch(1.1 0.44 330)",
-"oklch(-10 110 330)", "oklch(0 110 330)",
-"oklch(-10% 110% 330deg)", "oklch(0 0.44 330)",
-"oklch(-10 110 330 / 0)", "oklch(0 110 330 / 0)",
-"oklch(-10% 110% 330deg / 0)", "oklch(0 0.44 330 / 0)",
-"oklch(-10 110 330 / 0.2)", "oklch(0 110 330 / 0.2)",
-"oklch(-10% 110% 330deg / 0.2)", "oklch(0 0.44 330 / 0.2)",
-"oklch(-10 110 330 / 1)", "oklch(0 110 330)",
-"oklch(-10% 110% 330deg / 1)", "oklch(0 0.44 330)",
-"oklch(0 -10 330)", "oklch(0 0 330)",
-"oklch(0% -10% 330deg)", "oklch(0 0 330)",
-"oklch(0 -10 330 / 0)", "oklch(0 0 330 / 0)",
-"oklch(0% -10% 330deg / 0)", "oklch(0 0 330 / 0)",
-"oklch(0 -10 330 / 0.2)", "oklch(0 0 330 / 0.2)",
-"oklch(0% -10% 330deg / 0.2)", "oklch(0 0 330 / 0.2)",
-"oklch(0 -10 330 / 1)", "oklch(0 0 330)",
-"oklch(0% -10% 330deg / 1)", "oklch(0 0 330)",
-"oklch(10 -10 330)", "oklch(10 0 330)",
-"oklch(10% -10% 330deg)", "oklch(0.1 0 330)",
-"oklch(10 -10 330 / 0)", "oklch(10 0 330 / 0)",
-"oklch(10% -10% 330deg / 0)", "oklch(0.1 0 330 / 0)",
-"oklch(10 -10 330 / 0.2)", "oklch(10 0 330 / 0.2)",
-"oklch(10% -10% 330deg / 0.2)", "oklch(0.1 0 330 / 0.2)",
-"oklch(10 -10 330 / 1)", "oklch(10 0 330)",
-"oklch(10% -10% 330deg / 1)", "oklch(0.1 0 330)",
-"oklch(110 -10 330)", "oklch(110 0 330)",
-"oklch(110% -10% 330deg)", "oklch(1.1 0 330)",
-"oklch(110 -10 330 / 0)", "oklch(110 0 330 / 0)",
-"oklch(110% -10% 330deg / 0)", "oklch(1.1 0 330 / 0)",
-"oklch(110 -10 330 / 0.2)", "oklch(110 0 330 / 0.2)",
-"oklch(110% -10% 330deg / 0.2)", "oklch(1.1 0 330 / 0.2)",
-"oklch(110 -10 330 / 1)", "oklch(110 0 330)",
-"oklch(110% -10% 330deg / 1)", "oklch(1.1 0 330)",
-"oklch(-10 -10 330)", "oklch(0 0 330)",
-"oklch(-10% -10% 330deg)", "oklch(0 0 330)",
-"oklch(-10 -10 330 / 0)", "oklch(0 0 330 / 0)",
-"oklch(-10% -10% 330deg / 0)", "oklch(0 0 330 / 0)",
-"oklch(-10 -10 330 / 0.2)", "oklch(0 0 330 / 0.2)",
-"oklch(-10% -10% 330deg / 0.2)", "oklch(0 0 330 / 0.2)",
-"oklch(-10 -10 330 / 1)", "oklch(0 0 330)",
-"oklch(-10% -10% 330deg / 1)", "oklch(0 0 330)",
+"oklch(-10 110 330)", "oklch(-10 110 330)",
+"oklch(-10% 110% 330deg)", "oklch(-0.1 0.44 330)",
+"oklch(-10 110 330 / 0)", "oklch(-10 110 330 / 0)",
+"oklch(-10% 110% 330deg / 0)", "oklch(-0.1 0.44 330 / 0)",
+"oklch(-10 110 330 / 0.2)", "oklch(-10 110 330 / 0.2)",
+"oklch(-10% 110% 330deg / 0.2)", "oklch(-0.1 0.44 330 / 0.2)",
+"oklch(-10 110 330 / 1)", "oklch(-10 110 330)",
+"oklch(-10% 110% 330deg / 1)", "oklch(-0.1 0.44 330)",
+"oklch(0 -10 330)", "oklch(0 -10 330)",
+"oklch(0% -10% 330deg)", "oklch(0 -0.04 330)",
+"oklch(0 -10 330 / 0)", "oklch(0 -10 330 / 0)",
+"oklch(0% -10% 330deg / 0)", "oklch(0 -0.04 330 / 0)",
+"oklch(0 -10 330 / 0.2)", "oklch(0 -10 330 / 0.2)",
+"oklch(0% -10% 330deg / 0.2)", "oklch(0 -0.04 330 / 0.2)",
+"oklch(0 -10 330 / 1)", "oklch(0 -10 330)",
+"oklch(0% -10% 330deg / 1)", "oklch(0 -0.04 330)",
+"oklch(10 -10 330)", "oklch(10 -10 330)",
+"oklch(10% -10% 330deg)", "oklch(0.1 -0.04 330)",
+"oklch(10 -10 330 / 0)", "oklch(10 -10 330 / 0)",
+"oklch(10% -10% 330deg / 0)", "oklch(0.1 -0.04 330 / 0)",
+"oklch(10 -10 330 / 0.2)", "oklch(10 -10 330 / 0.2)",
+"oklch(10% -10% 330deg / 0.2)", "oklch(0.1 -0.04 330 / 0.2)",
+"oklch(10 -10 330 / 1)", "oklch(10 -10 330)",
+"oklch(10% -10% 330deg / 1)", "oklch(0.1 -0.04 330)",
+"oklch(110 -10 330)", "oklch(110 -10 330)",
+"oklch(110% -10% 330deg)", "oklch(1.1 -0.04 330)",
+"oklch(110 -10 330 / 0)", "oklch(110 -10 330 / 0)",
+"oklch(110% -10% 330deg / 0)", "oklch(1.1 -0.04 330 / 0)",
+"oklch(110 -10 330 / 0.2)", "oklch(110 -10 330 / 0.2)",
+"oklch(110% -10% 330deg / 0.2)", "oklch(1.1 -0.04 330 / 0.2)",
+"oklch(110 -10 330 / 1)", "oklch(110 -10 330)",
+"oklch(110% -10% 330deg / 1)", "oklch(1.1 -0.04 330)",
+"oklch(-10 -10 330)", "oklch(-10 -10 330)",
+"oklch(-10% -10% 330deg)", "oklch(-0.1 -0.04 330)",
+"oklch(-10 -10 330 / 0)", "oklch(-10 -10 330 / 0)",
+"oklch(-10% -10% 330deg / 0)", "oklch(-0.1 -0.04 330 / 0)",
+"oklch(-10 -10 330 / 0.2)", "oklch(-10 -10 330 / 0.2)",
+"oklch(-10% -10% 330deg / 0.2)", "oklch(-0.1 -0.04 330 / 0.2)",
+"oklch(-10 -10 330 / 1)", "oklch(-10 -10 330)",
+"oklch(-10% -10% 330deg / 1)", "oklch(-0.1 -0.04 330)",
 "oklch(0 0 360)", "oklch(0 0 0)",
 "oklch(0% 0% 360deg)", "oklch(0 0 0)",
 "oklch(0 0 360 / 0)", "oklch(0 0 0 / 0)",
@@ -4375,14 +4375,14 @@
 "oklch(110% 0% 360deg / 0.2)", "oklch(1.1 0 0 / 0.2)",
 "oklch(110 0 360 / 1)", "oklch(110 0 0)",
 "oklch(110% 0% 360deg / 1)", "oklch(1.1 0 0)",
-"oklch(-10 0 360)", "oklch(0 0 0)",
-"oklch(-10% 0% 360deg)", "oklch(0 0 0)",
-"oklch(-10 0 360 / 0)", "oklch(0 0 0 / 0)",
-"oklch(-10% 0% 360deg / 0)", "oklch(0 0 0 / 0)",
-"oklch(-10 0 360 / 0.2)", "oklch(0 0 0 / 0.2)",
-"oklch(-10% 0% 360deg / 0.2)", "oklch(0 0 0 / 0.2)",
-"oklch(-10 0 360 / 1)", "oklch(0 0 0)",
-"oklch(-10% 0% 360deg / 1)", "oklch(0 0 0)",
+"oklch(-10 0 360)", "oklch(-10 0 0)",
+"oklch(-10% 0% 360deg)", "oklch(-0.1 0 0)",
+"oklch(-10 0 360 / 0)", "oklch(-10 0 0 / 0)",
+"oklch(-10% 0% 360deg / 0)", "oklch(-0.1 0 0 / 0)",
+"oklch(-10 0 360 / 0.2)", "oklch(-10 0 0 / 0.2)",
+"oklch(-10% 0% 360deg / 0.2)", "oklch(-0.1 0 0 / 0.2)",
+"oklch(-10 0 360 / 1)", "oklch(-10 0 0)",
+"oklch(-10% 0% 360deg / 1)", "oklch(-0.1 0 0)",
 "oklch(0 10 360)", "oklch(0 10 0)",
 "oklch(0% 10% 360deg)", "oklch(0 0.04 0)",
 "oklch(0 10 360 / 0)", "oklch(0 10 0 / 0)",
@@ -4407,14 +4407,14 @@
 "oklch(110% 10% 360deg / 0.2)", "oklch(1.1 0.04 0 / 0.2)",
 "oklch(110 10 360 / 1)", "oklch(110 10 0)",
 "oklch(110% 10% 360deg / 1)", "oklch(1.1 0.04 0)",
-"oklch(-10 10 360)", "oklch(0 10 0)",
-"oklch(-10% 10% 360deg)", "oklch(0 0.04 0)",
-"oklch(-10 10 360 / 0)", "oklch(0 10 0 / 0)",
-"oklch(-10% 10% 360deg / 0)", "oklch(0 0.04 0 / 0)",
-"oklch(-10 10 360 / 0.2)", "oklch(0 10 0 / 0.2)",
-"oklch(-10% 10% 360deg / 0.2)", "oklch(0 0.04 0 / 0.2)",
-"oklch(-10 10 360 / 1)", "oklch(0 10 0)",
-"oklch(-10% 10% 360deg / 1)", "oklch(0 0.04 0)",
+"oklch(-10 10 360)", "oklch(-10 10 0)",
+"oklch(-10% 10% 360deg)", "oklch(-0.1 0.04 0)",
+"oklch(-10 10 360 / 0)", "oklch(-10 10 0 / 0)",
+"oklch(-10% 10% 360deg / 0)", "oklch(-0.1 0.04 0 / 0)",
+"oklch(-10 10 360 / 0.2)", "oklch(-10 10 0 / 0.2)",
+"oklch(-10% 10% 360deg / 0.2)", "oklch(-0.1 0.04 0 / 0.2)",
+"oklch(-10 10 360 / 1)", "oklch(-10 10 0)",
+"oklch(-10% 10% 360deg / 1)", "oklch(-0.1 0.04 0)",
 "oklch(0 110 360)", "oklch(0 110 0)",
 "oklch(0% 110% 360deg)", "oklch(0 0.44 0)",
 "oklch(0 110 360 / 0)", "oklch(0 110 0 / 0)",
@@ -4439,46 +4439,46 @@
 "oklch(110% 110% 360deg / 0.2)", "oklch(1.1 0.44 0 / 0.2)",
 "oklch(110 110 360 / 1)", "oklch(110 110 0)",
 "oklch(110% 110% 360deg / 1)", "oklch(1.1 0.44 0)",
-"oklch(-10 110 360)", "oklch(0 110 0)",
-"oklch(-10% 110% 360deg)", "oklch(0 0.44 0)",
-"oklch(-10 110 360 / 0)", "oklch(0 110 0 / 0)",
-"oklch(-10% 110% 360deg / 0)", "oklch(0 0.44 0 / 0)",
-"oklch(-10 110 360 / 0.2)", "oklch(0 110 0 / 0.2)",
-"oklch(-10% 110% 360deg / 0.2)", "oklch(0 0.44 0 / 0.2)",
-"oklch(-10 110 360 / 1)", "oklch(0 110 0)",
-"oklch(-10% 110% 360deg / 1)", "oklch(0 0.44 0)",
-"oklch(0 -10 360)", "oklch(0 0 0)",
-"oklch(0% -10% 360deg)", "oklch(0 0 0)",
-"oklch(0 -10 360 / 0)", "oklch(0 0 0 / 0)",
-"oklch(0% -10% 360deg / 0)", "oklch(0 0 0 / 0)",
-"oklch(0 -10 360 / 0.2)", "oklch(0 0 0 / 0.2)",
-"oklch(0% -10% 360deg / 0.2)", "oklch(0 0 0 / 0.2)",
-"oklch(0 -10 360 / 1)", "oklch(0 0 0)",
-"oklch(0% -10% 360deg / 1)", "oklch(0 0 0)",
-"oklch(10 -10 360)", "oklch(10 0 0)",
-"oklch(10% -10% 360deg)", "oklch(0.1 0 0)",
-"oklch(10 -10 360 / 0)", "oklch(10 0 0 / 0)",
-"oklch(10% -10% 360deg / 0)", "oklch(0.1 0 0 / 0)",
-"oklch(10 -10 360 / 0.2)", "oklch(10 0 0 / 0.2)",
-"oklch(10% -10% 360deg / 0.2)", "oklch(0.1 0 0 / 0.2)",
-"oklch(10 -10 360 / 1)", "oklch(10 0 0)",
-"oklch(10% -10% 360deg / 1)", "oklch(0.1 0 0)",
-"oklch(110 -10 360)", "oklch(110 0 0)",
-"oklch(110% -10% 360deg)", "oklch(1.1 0 0)",
-"oklch(110 -10 360 / 0)", "oklch(110 0 0 / 0)",
-"oklch(110% -10% 360deg / 0)", "oklch(1.1 0 0 / 0)",
-"oklch(110 -10 360 / 0.2)", "oklch(110 0 0 / 0.2)",
-"oklch(110% -10% 360deg / 0.2)", "oklch(1.1 0 0 / 0.2)",
-"oklch(110 -10 360 / 1)", "oklch(110 0 0)",
-"oklch(110% -10% 360deg / 1)", "oklch(1.1 0 0)",
-"oklch(-10 -10 360)", "oklch(0 0 0)",
-"oklch(-10% -10% 360deg)", "oklch(0 0 0)",
-"oklch(-10 -10 360 / 0)", "oklch(0 0 0 / 0)",
-"oklch(-10% -10% 360deg / 0)", "oklch(0 0 0 / 0)",
-"oklch(-10 -10 360 / 0.2)", "oklch(0 0 0 / 0.2)",
-"oklch(-10% -10% 360deg / 0.2)", "oklch(0 0 0 / 0.2)",
-"oklch(-10 -10 360 / 1)", "oklch(0 0 0)",
-"oklch(-10% -10% 360deg / 1)", "oklch(0 0 0)",
+"oklch(-10 110 360)", "oklch(-10 110 0)",
+"oklch(-10% 110% 360deg)", "oklch(-0.1 0.44 0)",
+"oklch(-10 110 360 / 0)", "oklch(-10 110 0 / 0)",
+"oklch(-10% 110% 360deg / 0)", "oklch(-0.1 0.44 0 / 0)",
+"oklch(-10 110 360 / 0.2)", "oklch(-10 110 0 / 0.2)",
+"oklch(-10% 110% 360deg / 0.2)", "oklch(-0.1 0.44 0 / 0.2)",
+"oklch(-10 110 360 / 1)", "oklch(-10 110 0)",
+"oklch(-10% 110% 360deg / 1)", "oklch(-0.1 0.44 0)",
+"oklch(0 -10 360)", "oklch(0 -10 0)",
+"oklch(0% -10% 360deg)", "oklch(0 -0.04 0)",
+"oklch(0 -10 360 / 0)", "oklch(0 -10 0 / 0)",
+"oklch(0% -10% 360deg / 0)", "oklch(0 -0.04 0 / 0)",
+"oklch(0 -10 360 / 0.2)", "oklch(0 -10 0 / 0.2)",
+"oklch(0% -10% 360deg / 0.2)", "oklch(0 -0.04 0 / 0.2)",
+"oklch(0 -10 360 / 1)", "oklch(0 -10 0)",
+"oklch(0% -10% 360deg / 1)", "oklch(0 -0.04 0)",
+"oklch(10 -10 360)", "oklch(10 -10 0)",
+"oklch(10% -10% 360deg)", "oklch(0.1 -0.04 0)",
+"oklch(10 -10 360 / 0)", "oklch(10 -10 0 / 0)",
+"oklch(10% -10% 360deg / 0)", "oklch(0.1 -0.04 0 / 0)",
+"oklch(10 -10 360 / 0.2)", "oklch(10 -10 0 / 0.2)",
+"oklch(10% -10% 360deg / 0.2)", "oklch(0.1 -0.04 0 / 0.2)",
+"oklch(10 -10 360 / 1)", "oklch(10 -10 0)",
+"oklch(10% -10% 360deg / 1)", "oklch(0.1 -0.04 0)",
+"oklch(110 -10 360)", "oklch(110 -10 0)",
+"oklch(110% -10% 360deg)", "oklch(1.1 -0.04 0)",
+"oklch(110 -10 360 / 0)", "oklch(110 -10 0 / 0)",
+"oklch(110% -10% 360deg / 0)", "oklch(1.1 -0.04 0 / 0)",
+"oklch(110 -10 360 / 0.2)", "oklch(110 -10 0 / 0.2)",
+"oklch(110% -10% 360deg / 0.2)", "oklch(1.1 -0.04 0 / 0.2)",
+"oklch(110 -10 360 / 1)", "oklch(110 -10 0)",
+"oklch(110% -10% 360deg / 1)", "oklch(1.1 -0.04 0)",
+"oklch(-10 -10 360)", "oklch(-10 -10 0)",
+"oklch(-10% -10% 360deg)", "oklch(-0.1 -0.04 0)",
+"oklch(-10 -10 360 / 0)", "oklch(-10 -10 0 / 0)",
+"oklch(-10% -10% 360deg / 0)", "oklch(-0.1 -0.04 0 / 0)",
+"oklch(-10 -10 360 / 0.2)", "oklch(-10 -10 0 / 0.2)",
+"oklch(-10% -10% 360deg / 0.2)", "oklch(-0.1 -0.04 0 / 0.2)",
+"oklch(-10 -10 360 / 1)", "oklch(-10 -10 0)",
+"oklch(-10% -10% 360deg / 1)", "oklch(-0.1 -0.04 0)",
 "oklch(0 0 380)", "oklch(0 0 20)",
 "oklch(0% 0% 380deg)", "oklch(0 0 20)",
 "oklch(0 0 380 / 0)", "oklch(0 0 20 / 0)",
@@ -4503,14 +4503,14 @@
 "oklch(110% 0% 380deg / 0.2)", "oklch(1.1 0 20 / 0.2)",
 "oklch(110 0 380 / 1)", "oklch(110 0 20)",
 "oklch(110% 0% 380deg / 1)", "oklch(1.1 0 20)",
-"oklch(-10 0 380)", "oklch(0 0 20)",
-"oklch(-10% 0% 380deg)", "oklch(0 0 20)",
-"oklch(-10 0 380 / 0)", "oklch(0 0 20 / 0)",
-"oklch(-10% 0% 380deg / 0)", "oklch(0 0 20 / 0)",
-"oklch(-10 0 380 / 0.2)", "oklch(0 0 20 / 0.2)",
-"oklch(-10% 0% 380deg / 0.2)", "oklch(0 0 20 / 0.2)",
-"oklch(-10 0 380 / 1)", "oklch(0 0 20)",
-"oklch(-10% 0% 380deg / 1)", "oklch(0 0 20)",
+"oklch(-10 0 380)", "oklch(-10 0 20)",
+"oklch(-10% 0% 380deg)", "oklch(-0.1 0 20)",
+"oklch(-10 0 380 / 0)", "oklch(-10 0 20 / 0)",
+"oklch(-10% 0% 380deg / 0)", "oklch(-0.1 0 20 / 0)",
+"oklch(-10 0 380 / 0.2)", "oklch(-10 0 20 / 0.2)",
+"oklch(-10% 0% 380deg / 0.2)", "oklch(-0.1 0 20 / 0.2)",
+"oklch(-10 0 380 / 1)", "oklch(-10 0 20)",
+"oklch(-10% 0% 380deg / 1)", "oklch(-0.1 0 20)",
 "oklch(0 10 380)", "oklch(0 10 20)",
 "oklch(0% 10% 380deg)", "oklch(0 0.04 20)",
 "oklch(0 10 380 / 0)", "oklch(0 10 20 / 0)",
@@ -4535,14 +4535,14 @@
 "oklch(110% 10% 380deg / 0.2)", "oklch(1.1 0.04 20 / 0.2)",
 "oklch(110 10 380 / 1)", "oklch(110 10 20)",
 "oklch(110% 10% 380deg / 1)", "oklch(1.1 0.04 20)",
-"oklch(-10 10 380)", "oklch(0 10 20)",
-"oklch(-10% 10% 380deg)", "oklch(0 0.04 20)",
-"oklch(-10 10 380 / 0)", "oklch(0 10 20 / 0)",
-"oklch(-10% 10% 380deg / 0)", "oklch(0 0.04 20 / 0)",
-"oklch(-10 10 380 / 0.2)", "oklch(0 10 20 / 0.2)",
-"oklch(-10% 10% 380deg / 0.2)", "oklch(0 0.04 20 / 0.2)",
-"oklch(-10 10 380 / 1)", "oklch(0 10 20)",
-"oklch(-10% 10% 380deg / 1)", "oklch(0 0.04 20)",
+"oklch(-10 10 380)", "oklch(-10 10 20)",
+"oklch(-10% 10% 380deg)", "oklch(-0.1 0.04 20)",
+"oklch(-10 10 380 / 0)", "oklch(-10 10 20 / 0)",
+"oklch(-10% 10% 380deg / 0)", "oklch(-0.1 0.04 20 / 0)",
+"oklch(-10 10 380 / 0.2)", "oklch(-10 10 20 / 0.2)",
+"oklch(-10% 10% 380deg / 0.2)", "oklch(-0.1 0.04 20 / 0.2)",
+"oklch(-10 10 380 / 1)", "oklch(-10 10 20)",
+"oklch(-10% 10% 380deg / 1)", "oklch(-0.1 0.04 20)",
 "oklch(0 110 380)", "oklch(0 110 20)",
 "oklch(0% 110% 380deg)", "oklch(0 0.44 20)",
 "oklch(0 110 380 / 0)", "oklch(0 110 20 / 0)",
@@ -4567,46 +4567,46 @@
 "oklch(110% 110% 380deg / 0.2)", "oklch(1.1 0.44 20 / 0.2)",
 "oklch(110 110 380 / 1)", "oklch(110 110 20)",
 "oklch(110% 110% 380deg / 1)", "oklch(1.1 0.44 20)",
-"oklch(-10 110 380)", "oklch(0 110 20)",
-"oklch(-10% 110% 380deg)", "oklch(0 0.44 20)",
-"oklch(-10 110 380 / 0)", "oklch(0 110 20 / 0)",
-"oklch(-10% 110% 380deg / 0)", "oklch(0 0.44 20 / 0)",
-"oklch(-10 110 380 / 0.2)", "oklch(0 110 20 / 0.2)",
-"oklch(-10% 110% 380deg / 0.2)", "oklch(0 0.44 20 / 0.2)",
-"oklch(-10 110 380 / 1)", "oklch(0 110 20)",
-"oklch(-10% 110% 380deg / 1)", "oklch(0 0.44 20)",
-"oklch(0 -10 380)", "oklch(0 0 20)",
-"oklch(0% -10% 380deg)", "oklch(0 0 20)",
-"oklch(0 -10 380 / 0)", "oklch(0 0 20 / 0)",
-"oklch(0% -10% 380deg / 0)", "oklch(0 0 20 / 0)",
-"oklch(0 -10 380 / 0.2)", "oklch(0 0 20 / 0.2)",
-"oklch(0% -10% 380deg / 0.2)", "oklch(0 0 20 / 0.2)",
-"oklch(0 -10 380 / 1)", "oklch(0 0 20)",
-"oklch(0% -10% 380deg / 1)", "oklch(0 0 20)",
-"oklch(10 -10 380)", "oklch(10 0 20)",
-"oklch(10% -10% 380deg)", "oklch(0.1 0 20)",
-"oklch(10 -10 380 / 0)", "oklch(10 0 20 / 0)",
-"oklch(10% -10% 380deg / 0)", "oklch(0.1 0 20 / 0)",
-"oklch(10 -10 380 / 0.2)", "oklch(10 0 20 / 0.2)",
-"oklch(10% -10% 380deg / 0.2)", "oklch(0.1 0 20 / 0.2)",
-"oklch(10 -10 380 / 1)", "oklch(10 0 20)",
-"oklch(10% -10% 380deg / 1)", "oklch(0.1 0 20)",
-"oklch(110 -10 380)", "oklch(110 0 20)",
-"oklch(110% -10% 380deg)", "oklch(1.1 0 20)",
-"oklch(110 -10 380 / 0)", "oklch(110 0 20 / 0)",
-"oklch(110% -10% 380deg / 0)", "oklch(1.1 0 20 / 0)",
-"oklch(110 -10 380 / 0.2)", "oklch(110 0 20 / 0.2)",
-"oklch(110% -10% 380deg / 0.2)", "oklch(1.1 0 20 / 0.2)",
-"oklch(110 -10 380 / 1)", "oklch(110 0 20)",
-"oklch(110% -10% 380deg / 1)", "oklch(1.1 0 20)",
-"oklch(-10 -10 380)", "oklch(0 0 20)",
-"oklch(-10% -10% 380deg)", "oklch(0 0 20)",
-"oklch(-10 -10 380 / 0)", "oklch(0 0 20 / 0)",
-"oklch(-10% -10% 380deg / 0)", "oklch(0 0 20 / 0)",
-"oklch(-10 -10 380 / 0.2)", "oklch(0 0 20 / 0.2)",
-"oklch(-10% -10% 380deg / 0.2)", "oklch(0 0 20 / 0.2)",
-"oklch(-10 -10 380 / 1)", "oklch(0 0 20)",
-"oklch(-10% -10% 380deg / 1)", "oklch(0 0 20)",
+"oklch(-10 110 380)", "oklch(-10 110 20)",
+"oklch(-10% 110% 380deg)", "oklch(-0.1 0.44 20)",
+"oklch(-10 110 380 / 0)", "oklch(-10 110 20 / 0)",
+"oklch(-10% 110% 380deg / 0)", "oklch(-0.1 0.44 20 / 0)",
+"oklch(-10 110 380 / 0.2)", "oklch(-10 110 20 / 0.2)",
+"oklch(-10% 110% 380deg / 0.2)", "oklch(-0.1 0.44 20 / 0.2)",
+"oklch(-10 110 380 / 1)", "oklch(-10 110 20)",
+"oklch(-10% 110% 380deg / 1)", "oklch(-0.1 0.44 20)",
+"oklch(0 -10 380)", "oklch(0 -10 20)",
+"oklch(0% -10% 380deg)", "oklch(0 -0.04 20)",
+"oklch(0 -10 380 / 0)", "oklch(0 -10 20 / 0)",
+"oklch(0% -10% 380deg / 0)", "oklch(0 -0.04 20 / 0)",
+"oklch(0 -10 380 / 0.2)", "oklch(0 -10 20 / 0.2)",
+"oklch(0% -10% 380deg / 0.2)", "oklch(0 -0.04 20 / 0.2)",
+"oklch(0 -10 380 / 1)", "oklch(0 -10 20)",
+"oklch(0% -10% 380deg / 1)", "oklch(0 -0.04 20)",
+"oklch(10 -10 380)", "oklch(10 -10 20)",
+"oklch(10% -10% 380deg)", "oklch(0.1 -0.04 20)",
+"oklch(10 -10 380 / 0)", "oklch(10 -10 20 / 0)",
+"oklch(10% -10% 380deg / 0)", "oklch(0.1 -0.04 20 / 0)",
+"oklch(10 -10 380 / 0.2)", "oklch(10 -10 20 / 0.2)",
+"oklch(10% -10% 380deg / 0.2)", "oklch(0.1 -0.04 20 / 0.2)",
+"oklch(10 -10 380 / 1)", "oklch(10 -10 20)",
+"oklch(10% -10% 380deg / 1)", "oklch(0.1 -0.04 20)",
+"oklch(110 -10 380)", "oklch(110 -10 20)",
+"oklch(110% -10% 380deg)", "oklch(1.1 -0.04 20)",
+"oklch(110 -10 380 / 0)", "oklch(110 -10 20 / 0)",
+"oklch(110% -10% 380deg / 0)", "oklch(1.1 -0.04 20 / 0)",
+"oklch(110 -10 380 / 0.2)", "oklch(110 -10 20 / 0.2)",
+"oklch(110% -10% 380deg / 0.2)", "oklch(1.1 -0.04 20 / 0.2)",
+"oklch(110 -10 380 / 1)", "oklch(110 -10 20)",
+"oklch(110% -10% 380deg / 1)", "oklch(1.1 -0.04 20)",
+"oklch(-10 -10 380)", "oklch(-10 -10 20)",
+"oklch(-10% -10% 380deg)", "oklch(-0.1 -0.04 20)",
+"oklch(-10 -10 380 / 0)", "oklch(-10 -10 20 / 0)",
+"oklch(-10% -10% 380deg / 0)", "oklch(-0.1 -0.04 20 / 0)",
+"oklch(-10 -10 380 / 0.2)", "oklch(-10 -10 20 / 0.2)",
+"oklch(-10% -10% 380deg / 0.2)", "oklch(-0.1 -0.04 20 / 0.2)",
+"oklch(-10 -10 380 / 1)", "oklch(-10 -10 20)",
+"oklch(-10% -10% 380deg / 1)", "oklch(-0.1 -0.04 20)",
 "oklch(0 0 700)", "oklch(0 0 340)",
 "oklch(0% 0% 700deg)", "oklch(0 0 340)",
 "oklch(0 0 700 / 0)", "oklch(0 0 340 / 0)",
@@ -4631,14 +4631,14 @@
 "oklch(110% 0% 700deg / 0.2)", "oklch(1.1 0 340 / 0.2)",
 "oklch(110 0 700 / 1)", "oklch(110 0 340)",
 "oklch(110% 0% 700deg / 1)", "oklch(1.1 0 340)",
-"oklch(-10 0 700)", "oklch(0 0 340)",
-"oklch(-10% 0% 700deg)", "oklch(0 0 340)",
-"oklch(-10 0 700 / 0)", "oklch(0 0 340 / 0)",
-"oklch(-10% 0% 700deg / 0)", "oklch(0 0 340 / 0)",
-"oklch(-10 0 700 / 0.2)", "oklch(0 0 340 / 0.2)",
-"oklch(-10% 0% 700deg / 0.2)", "oklch(0 0 340 / 0.2)",
-"oklch(-10 0 700 / 1)", "oklch(0 0 340)",
-"oklch(-10% 0% 700deg / 1)", "oklch(0 0 340)",
+"oklch(-10 0 700)", "oklch(-10 0 340)",
+"oklch(-10% 0% 700deg)", "oklch(-0.1 0 340)",
+"oklch(-10 0 700 / 0)", "oklch(-10 0 340 / 0)",
+"oklch(-10% 0% 700deg / 0)", "oklch(-0.1 0 340 / 0)",
+"oklch(-10 0 700 / 0.2)", "oklch(-10 0 340 / 0.2)",
+"oklch(-10% 0% 700deg / 0.2)", "oklch(-0.1 0 340 / 0.2)",
+"oklch(-10 0 700 / 1)", "oklch(-10 0 340)",
+"oklch(-10% 0% 700deg / 1)", "oklch(-0.1 0 340)",
 "oklch(0 10 700)", "oklch(0 10 340)",
 "oklch(0% 10% 700deg)", "oklch(0 0.04 340)",
 "oklch(0 10 700 / 0)", "oklch(0 10 340 / 0)",
@@ -4663,14 +4663,14 @@
 "oklch(110% 10% 700deg / 0.2)", "oklch(1.1 0.04 340 / 0.2)",
 "oklch(110 10 700 / 1)", "oklch(110 10 340)",
 "oklch(110% 10% 700deg / 1)", "oklch(1.1 0.04 340)",
-"oklch(-10 10 700)", "oklch(0 10 340)",
-"oklch(-10% 10% 700deg)", "oklch(0 0.04 340)",
-"oklch(-10 10 700 / 0)", "oklch(0 10 340 / 0)",
-"oklch(-10% 10% 700deg / 0)", "oklch(0 0.04 340 / 0)",
-"oklch(-10 10 700 / 0.2)", "oklch(0 10 340 / 0.2)",
-"oklch(-10% 10% 700deg / 0.2)", "oklch(0 0.04 340 / 0.2)",
-"oklch(-10 10 700 / 1)", "oklch(0 10 340)",
-"oklch(-10% 10% 700deg / 1)", "oklch(0 0.04 340)",
+"oklch(-10 10 700)", "oklch(-10 10 340)",
+"oklch(-10% 10% 700deg)", "oklch(-0.1 0.04 340)",
+"oklch(-10 10 700 / 0)", "oklch(-10 10 340 / 0)",
+"oklch(-10% 10% 700deg / 0)", "oklch(-0.1 0.04 340 / 0)",
+"oklch(-10 10 700 / 0.2)", "oklch(-10 10 340 / 0.2)",
+"oklch(-10% 10% 700deg / 0.2)", "oklch(-0.1 0.04 340 / 0.2)",
+"oklch(-10 10 700 / 1)", "oklch(-10 10 340)",
+"oklch(-10% 10% 700deg / 1)", "oklch(-0.1 0.04 340)",
 "oklch(0 110 700)", "oklch(0 110 340)",
 "oklch(0% 110% 700deg)", "oklch(0 0.44 340)",
 "oklch(0 110 700 / 0)", "oklch(0 110 340 / 0)",
@@ -4695,46 +4695,46 @@
 "oklch(110% 110% 700deg / 0.2)", "oklch(1.1 0.44 340 / 0.2)",
 "oklch(110 110 700 / 1)", "oklch(110 110 340)",
 "oklch(110% 110% 700deg / 1)", "oklch(1.1 0.44 340)",
-"oklch(-10 110 700)", "oklch(0 110 340)",
-"oklch(-10% 110% 700deg)", "oklch(0 0.44 340)",
-"oklch(-10 110 700 / 0)", "oklch(0 110 340 / 0)",
-"oklch(-10% 110% 700deg / 0)", "oklch(0 0.44 340 / 0)",
-"oklch(-10 110 700 / 0.2)", "oklch(0 110 340 / 0.2)",
-"oklch(-10% 110% 700deg / 0.2)", "oklch(0 0.44 340 / 0.2)",
-"oklch(-10 110 700 / 1)", "oklch(0 110 340)",
-"oklch(-10% 110% 700deg / 1)", "oklch(0 0.44 340)",
-"oklch(0 -10 700)", "oklch(0 0 340)",
-"oklch(0% -10% 700deg)", "oklch(0 0 340)",
-"oklch(0 -10 700 / 0)", "oklch(0 0 340 / 0)",
-"oklch(0% -10% 700deg / 0)", "oklch(0 0 340 / 0)",
-"oklch(0 -10 700 / 0.2)", "oklch(0 0 340 / 0.2)",
-"oklch(0% -10% 700deg / 0.2)", "oklch(0 0 340 / 0.2)",
-"oklch(0 -10 700 / 1)", "oklch(0 0 340)",
-"oklch(0% -10% 700deg / 1)", "oklch(0 0 340)",
-"oklch(10 -10 700)", "oklch(10 0 340)",
-"oklch(10% -10% 700deg)", "oklch(0.1 0 340)",
-"oklch(10 -10 700 / 0)", "oklch(10 0 340 / 0)",
-"oklch(10% -10% 700deg / 0)", "oklch(0.1 0 340 / 0)",
-"oklch(10 -10 700 / 0.2)", "oklch(10 0 340 / 0.2)",
-"oklch(10% -10% 700deg / 0.2)", "oklch(0.1 0 340 / 0.2)",
-"oklch(10 -10 700 / 1)", "oklch(10 0 340)",
-"oklch(10% -10% 700deg / 1)", "oklch(0.1 0 340)",
-"oklch(110 -10 700)", "oklch(110 0 340)",
-"oklch(110% -10% 700deg)", "oklch(1.1 0 340)",
-"oklch(110 -10 700 / 0)", "oklch(110 0 340 / 0)",
-"oklch(110% -10% 700deg / 0)", "oklch(1.1 0 340 / 0)",
-"oklch(110 -10 700 / 0.2)", "oklch(110 0 340 / 0.2)",
-"oklch(110% -10% 700deg / 0.2)", "oklch(1.1 0 340 / 0.2)",
-"oklch(110 -10 700 / 1)", "oklch(110 0 340)",
-"oklch(110% -10% 700deg / 1)", "oklch(1.1 0 340)",
-"oklch(-10 -10 700)", "oklch(0 0 340)",
-"oklch(-10% -10% 700deg)", "oklch(0 0 340)",
-"oklch(-10 -10 700 / 0)", "oklch(0 0 340 / 0)",
-"oklch(-10% -10% 700deg / 0)", "oklch(0 0 340 / 0)",
-"oklch(-10 -10 700 / 0.2)", "oklch(0 0 340 / 0.2)",
-"oklch(-10% -10% 700deg / 0.2)", "oklch(0 0 340 / 0.2)",
-"oklch(-10 -10 700 / 1)", "oklch(0 0 340)",
-"oklch(-10% -10% 700deg / 1)", "oklch(0 0 340)",
+"oklch(-10 110 700)", "oklch(-10 110 340)",
+"oklch(-10% 110% 700deg)", "oklch(-0.1 0.44 340)",
+"oklch(-10 110 700 / 0)", "oklch(-10 110 340 / 0)",
+"oklch(-10% 110% 700deg / 0)", "oklch(-0.1 0.44 340 / 0)",
+"oklch(-10 110 700 / 0.2)", "oklch(-10 110 340 / 0.2)",
+"oklch(-10% 110% 700deg / 0.2)", "oklch(-0.1 0.44 340 / 0.2)",
+"oklch(-10 110 700 / 1)", "oklch(-10 110 340)",
+"oklch(-10% 110% 700deg / 1)", "oklch(-0.1 0.44 340)",
+"oklch(0 -10 700)", "oklch(0 -10 340)",
+"oklch(0% -10% 700deg)", "oklch(0 -0.04 340)",
+"oklch(0 -10 700 / 0)", "oklch(0 -10 340 / 0)",
+"oklch(0% -10% 700deg / 0)", "oklch(0 -0.04 340 / 0)",
+"oklch(0 -10 700 / 0.2)", "oklch(0 -10 340 / 0.2)",
+"oklch(0% -10% 700deg / 0.2)", "oklch(0 -0.04 340 / 0.2)",
+"oklch(0 -10 700 / 1)", "oklch(0 -10 340)",
+"oklch(0% -10% 700deg / 1)", "oklch(0 -0.04 340)",
+"oklch(10 -10 700)", "oklch(10 -10 340)",
+"oklch(10% -10% 700deg)", "oklch(0.1 -0.04 340)",
+"oklch(10 -10 700 / 0)", "oklch(10 -10 340 / 0)",
+"oklch(10% -10% 700deg / 0)", "oklch(0.1 -0.04 340 / 0)",
+"oklch(10 -10 700 / 0.2)", "oklch(10 -10 340 / 0.2)",
+"oklch(10% -10% 700deg / 0.2)", "oklch(0.1 -0.04 340 / 0.2)",
+"oklch(10 -10 700 / 1)", "oklch(10 -10 340)",
+"oklch(10% -10% 700deg / 1)", "oklch(0.1 -0.04 340)",
+"oklch(110 -10 700)", "oklch(110 -10 340)",
+"oklch(110% -10% 700deg)", "oklch(1.1 -0.04 340)",
+"oklch(110 -10 700 / 0)", "oklch(110 -10 340 / 0)",
+"oklch(110% -10% 700deg / 0)", "oklch(1.1 -0.04 340 / 0)",
+"oklch(110 -10 700 / 0.2)", "oklch(110 -10 340 / 0.2)",
+"oklch(110% -10% 700deg / 0.2)", "oklch(1.1 -0.04 340 / 0.2)",
+"oklch(110 -10 700 / 1)", "oklch(110 -10 340)",
+"oklch(110% -10% 700deg / 1)", "oklch(1.1 -0.04 340)",
+"oklch(-10 -10 700)", "oklch(-10 -10 340)",
+"oklch(-10% -10% 700deg)", "oklch(-0.1 -0.04 340)",
+"oklch(-10 -10 700 / 0)", "oklch(-10 -10 340 / 0)",
+"oklch(-10% -10% 700deg / 0)", "oklch(-0.1 -0.04 340 / 0)",
+"oklch(-10 -10 700 / 0.2)", "oklch(-10 -10 340 / 0.2)",
+"oklch(-10% -10% 700deg / 0.2)", "oklch(-0.1 -0.04 340 / 0.2)",
+"oklch(-10 -10 700 / 1)", "oklch(-10 -10 340)",
+"oklch(-10% -10% 700deg / 1)", "oklch(-0.1 -0.04 340)",
 "oklch(0 0 -20)", "oklch(0 0 340)",
 "oklch(0% 0% -20deg)", "oklch(0 0 340)",
 "oklch(0 0 -20 / 0)", "oklch(0 0 340 / 0)",
@@ -4759,14 +4759,14 @@
 "oklch(110% 0% -20deg / 0.2)", "oklch(1.1 0 340 / 0.2)",
 "oklch(110 0 -20 / 1)", "oklch(110 0 340)",
 "oklch(110% 0% -20deg / 1)", "oklch(1.1 0 340)",
-"oklch(-10 0 -20)", "oklch(0 0 340)",
-"oklch(-10% 0% -20deg)", "oklch(0 0 340)",
-"oklch(-10 0 -20 / 0)", "oklch(0 0 340 / 0)",
-"oklch(-10% 0% -20deg / 0)", "oklch(0 0 340 / 0)",
-"oklch(-10 0 -20 / 0.2)", "oklch(0 0 340 / 0.2)",
-"oklch(-10% 0% -20deg / 0.2)", "oklch(0 0 340 / 0.2)",
-"oklch(-10 0 -20 / 1)", "oklch(0 0 340)",
-"oklch(-10% 0% -20deg / 1)", "oklch(0 0 340)",
+"oklch(-10 0 -20)", "oklch(-10 0 340)",
+"oklch(-10% 0% -20deg)", "oklch(-0.1 0 340)",
+"oklch(-10 0 -20 / 0)", "oklch(-10 0 340 / 0)",
+"oklch(-10% 0% -20deg / 0)", "oklch(-0.1 0 340 / 0)",
+"oklch(-10 0 -20 / 0.2)", "oklch(-10 0 340 / 0.2)",
+"oklch(-10% 0% -20deg / 0.2)", "oklch(-0.1 0 340 / 0.2)",
+"oklch(-10 0 -20 / 1)", "oklch(-10 0 340)",
+"oklch(-10% 0% -20deg / 1)", "oklch(-0.1 0 340)",
 "oklch(0 10 -20)", "oklch(0 10 340)",
 "oklch(0% 10% -20deg)", "oklch(0 0.04 340)",
 "oklch(0 10 -20 / 0)", "oklch(0 10 340 / 0)",
@@ -4791,14 +4791,14 @@
 "oklch(110% 10% -20deg / 0.2)", "oklch(1.1 0.04 340 / 0.2)",
 "oklch(110 10 -20 / 1)", "oklch(110 10 340)",
 "oklch(110% 10% -20deg / 1)", "oklch(1.1 0.04 340)",
-"oklch(-10 10 -20)", "oklch(0 10 340)",
-"oklch(-10% 10% -20deg)", "oklch(0 0.04 340)",
-"oklch(-10 10 -20 / 0)", "oklch(0 10 340 / 0)",
-"oklch(-10% 10% -20deg / 0)", "oklch(0 0.04 340 / 0)",
-"oklch(-10 10 -20 / 0.2)", "oklch(0 10 340 / 0.2)",
-"oklch(-10% 10% -20deg / 0.2)", "oklch(0 0.04 340 / 0.2)",
-"oklch(-10 10 -20 / 1)", "oklch(0 10 340)",
-"oklch(-10% 10% -20deg / 1)", "oklch(0 0.04 340)",
+"oklch(-10 10 -20)", "oklch(-10 10 340)",
+"oklch(-10% 10% -20deg)", "oklch(-0.1 0.04 340)",
+"oklch(-10 10 -20 / 0)", "oklch(-10 10 340 / 0)",
+"oklch(-10% 10% -20deg / 0)", "oklch(-0.1 0.04 340 / 0)",
+"oklch(-10 10 -20 / 0.2)", "oklch(-10 10 340 / 0.2)",
+"oklch(-10% 10% -20deg / 0.2)", "oklch(-0.1 0.04 340 / 0.2)",
+"oklch(-10 10 -20 / 1)", "oklch(-10 10 340)",
+"oklch(-10% 10% -20deg / 1)", "oklch(-0.1 0.04 340)",
 "oklch(0 110 -20)", "oklch(0 110 340)",
 "oklch(0% 110% -20deg)", "oklch(0 0.44 340)",
 "oklch(0 110 -20 / 0)", "oklch(0 110 340 / 0)",
@@ -4823,44 +4823,44 @@
 "oklch(110% 110% -20deg / 0.2)", "oklch(1.1 0.44 340 / 0.2)",
 "oklch(110 110 -20 / 1)", "oklch(110 110 340)",
 "oklch(110% 110% -20deg / 1)", "oklch(1.1 0.44 340)",
-"oklch(-10 110 -20)", "oklch(0 110 340)",
-"oklch(-10% 110% -20deg)", "oklch(0 0.44 340)",
-"oklch(-10 110 -20 / 0)", "oklch(0 110 340 / 0)",
-"oklch(-10% 110% -20deg / 0)", "oklch(0 0.44 340 / 0)",
-"oklch(-10 110 -20 / 0.2)", "oklch(0 110 340 / 0.2)",
-"oklch(-10% 110% -20deg / 0.2)", "oklch(0 0.44 340 / 0.2)",
-"oklch(-10 110 -20 / 1)", "oklch(0 110 340)",
-"oklch(-10% 110% -20deg / 1)", "oklch(0 0.44 340)",
-"oklch(0 -10 -20)", "oklch(0 0 340)",
-"oklch(0% -10% -20deg)", "oklch(0 0 340)",
-"oklch(0 -10 -20 / 0)", "oklch(0 0 340 / 0)",
-"oklch(0% -10% -20deg / 0)", "oklch(0 0 340 / 0)",
-"oklch(0 -10 -20 / 0.2)", "oklch(0 0 340 / 0.2)",
-"oklch(0% -10% -20deg / 0.2)", "oklch(0 0 340 / 0.2)",
-"oklch(0 -10 -20 / 1)", "oklch(0 0 340)",
-"oklch(0% -10% -20deg / 1)", "oklch(0 0 340)",
-"oklch(10 -10 -20)", "oklch(10 0 340)",
-"oklch(10% -10% -20deg)", "oklch(0.1 0 340)",
-"oklch(10 -10 -20 / 0)", "oklch(10 0 340 / 0)",
-"oklch(10% -10% -20deg / 0)", "oklch(0.1 0 340 / 0)",
-"oklch(10 -10 -20 / 0.2)", "oklch(10 0 340 / 0.2)",
-"oklch(10% -10% -20deg / 0.2)", "oklch(0.1 0 340 / 0.2)",
-"oklch(10 -10 -20 / 1)", "oklch(10 0 340)",
-"oklch(10% -10% -20deg / 1)", "oklch(0.1 0 340)",
-"oklch(110 -10 -20)", "oklch(110 0 340)",
-"oklch(110% -10% -20deg)", "oklch(1.1 0 340)",
-"oklch(110 -10 -20 / 0)", "oklch(110 0 340 / 0)",
-"oklch(110% -10% -20deg / 0)", "oklch(1.1 0 340 / 0)",
-"oklch(110 -10 -20 / 0.2)", "oklch(110 0 340 / 0.2)",
-"oklch(110% -10% -20deg / 0.2)", "oklch(1.1 0 340 / 0.2)",
-"oklch(110 -10 -20 / 1)", "oklch(110 0 340)",
-"oklch(110% -10% -20deg / 1)", "oklch(1.1 0 340)",
-"oklch(-10 -10 -20)", "oklch(0 0 340)",
-"oklch(-10% -10% -20deg)", "oklch(0 0 340)",
-"oklch(-10 -10 -20 / 0)", "oklch(0 0 340 / 0)",
-"oklch(-10% -10% -20deg / 0)", "oklch(0 0 340 / 0)",
-"oklch(-10 -10 -20 / 0.2)", "oklch(0 0 340 / 0.2)",
-"oklch(-10% -10% -20deg / 0.2)", "oklch(0 0 340 / 0.2)",
-"oklch(-10 -10 -20 / 1)", "oklch(0 0 340)",
-"oklch(-10% -10% -20deg / 1)", "oklch(0 0 340)"
+"oklch(-10 110 -20)", "oklch(-10 110 340)",
+"oklch(-10% 110% -20deg)", "oklch(-0.1 0.44 340)",
+"oklch(-10 110 -20 / 0)", "oklch(-10 110 340 / 0)",
+"oklch(-10% 110% -20deg / 0)", "oklch(-0.1 0.44 340 / 0)",
+"oklch(-10 110 -20 / 0.2)", "oklch(-10 110 340 / 0.2)",
+"oklch(-10% 110% -20deg / 0.2)", "oklch(-0.1 0.44 340 / 0.2)",
+"oklch(-10 110 -20 / 1)", "oklch(-10 110 340)",
+"oklch(-10% 110% -20deg / 1)", "oklch(-0.1 0.44 340)",
+"oklch(0 -10 -20)", "oklch(0 -10 340)",
+"oklch(0% -10% -20deg)", "oklch(0 -0.04 340)",
+"oklch(0 -10 -20 / 0)", "oklch(0 -10 340 / 0)",
+"oklch(0% -10% -20deg / 0)", "oklch(0 -0.04 340 / 0)",
+"oklch(0 -10 -20 / 0.2)", "oklch(0 -10 340 / 0.2)",
+"oklch(0% -10% -20deg / 0.2)", "oklch(0 -0.04 340 / 0.2)",
+"oklch(0 -10 -20 / 1)", "oklch(0 -10 340)",
+"oklch(0% -10% -20deg / 1)", "oklch(0 -0.04 340)",
+"oklch(10 -10 -20)", "oklch(10 -10 340)",
+"oklch(10% -10% -20deg)", "oklch(0.1 -0.04 340)",
+"oklch(10 -10 -20 / 0)", "oklch(10 -10 340 / 0)",
+"oklch(10% -10% -20deg / 0)", "oklch(0.1 -0.04 340 / 0)",
+"oklch(10 -10 -20 / 0.2)", "oklch(10 -10 340 / 0.2)",
+"oklch(10% -10% -20deg / 0.2)", "oklch(0.1 -0.04 340 / 0.2)",
+"oklch(10 -10 -20 / 1)", "oklch(10 -10 340)",
+"oklch(10% -10% -20deg / 1)", "oklch(0.1 -0.04 340)",
+"oklch(110 -10 -20)", "oklch(110 -10 340)",
+"oklch(110% -10% -20deg)", "oklch(1.1 -0.04 340)",
+"oklch(110 -10 -20 / 0)", "oklch(110 -10 340 / 0)",
+"oklch(110% -10% -20deg / 0)", "oklch(1.1 -0.04 340 / 0)",
+"oklch(110 -10 -20 / 0.2)", "oklch(110 -10 340 / 0.2)",
+"oklch(110% -10% -20deg / 0.2)", "oklch(1.1 -0.04 340 / 0.2)",
+"oklch(110 -10 -20 / 1)", "oklch(110 -10 340)",
+"oklch(110% -10% -20deg / 1)", "oklch(1.1 -0.04 340)",
+"oklch(-10 -10 -20)", "oklch(-10 -10 340)",
+"oklch(-10% -10% -20deg)", "oklch(-0.1 -0.04 340)",
+"oklch(-10 -10 -20 / 0)", "oklch(-10 -10 340 / 0)",
+"oklch(-10% -10% -20deg / 0)", "oklch(-0.1 -0.04 340 / 0)",
+"oklch(-10 -10 -20 / 0.2)", "oklch(-10 -10 340 / 0.2)",
+"oklch(-10% -10% -20deg / 0.2)", "oklch(-0.1 -0.04 340 / 0.2)",
+"oklch(-10 -10 -20 / 1)", "oklch(-10 -10 340)",
+"oklch(-10% -10% -20deg / 1)", "oklch(-0.1 -0.04 340)"
 ]
diff --git a/src/css-parsing-tests/make_color4_lab_lch_oklab_oklch.py b/src/css-parsing-tests/make_color4_lab_lch_oklab_oklch.py
index 6b376ab2..69fb8f0e 100644
--- a/src/css-parsing-tests/make_color4_lab_lch_oklab_oklch.py
+++ b/src/css-parsing-tests/make_color4_lab_lch_oklab_oklch.py
@@ -2,19 +2,19 @@
 
 
 def lab(lightness, a, b, alpha=1):
-    return (max(0.0, lightness), a, b, alpha)
+    return (lightness, a, b, alpha)
 
 
 def labp(lightness, a, b, alpha=1):
-    return (max(0.0, lightness), a * 125.0 / 100.0, b * 125.0 / 100.0, alpha)
+    return (lightness, a * 125.0 / 100.0, b * 125.0 / 100.0, alpha)
 
 
 def oklab(lightness, a, b, alpha=1):
-    return (max(0.0, lightness), a, b, alpha)
+    return (lightness, a, b, alpha)
 
 
 def oklabp(lightness, a, b, alpha=1):
-    return (max(0.0, lightness / 100.0), a * 0.4 / 100.0, b * 0.4 / 100.0, alpha)
+    return (lightness / 100.0, a * 0.4 / 100.0, b * 0.4 / 100.0, alpha)
 
 
 def slab(name, lightness, a, b, alpha=1):
@@ -53,19 +53,19 @@ def calc_deg(deg):
 
 
 def lch(lightness, c, h, alpha=1):
-    return (max(lightness, 0.0), max(0.0, c), calc_deg(h), alpha)
+    return (lightness, c, calc_deg(h), alpha)
 
 
 def lchp(lightness, c, h, alpha=1):
-    return (max(lightness, 0.0), max(0.0, c * 150.0 / 100.0), calc_deg(h), alpha)
+    return (lightness, c * 150.0 / 100.0, calc_deg(h), alpha)
 
 
 def oklch(lightness, c, h, alpha=1):
-    return (max(lightness, 0.0), max(0.0, c), calc_deg(h), alpha)
+    return (lightness, c, calc_deg(h), alpha)
 
 
 def oklchp(lightness, c, h, alpha=1):
-    return (max(lightness, 0.0) / 100.0, max(0.0, c * 0.4 / 100.0), calc_deg(h), alpha)
+    return (lightness / 100.0, c * 0.4 / 100.0, calc_deg(h), alpha)
 
 
 def slch(name, lightness, c, h, alpha=1):

From a6b30d81ca92df6a62337213f4e0f6b2d2220061 Mon Sep 17 00:00:00 2001
From: Tiaan Louw <tiaanl@gmail.com>
Date: Mon, 24 Jul 2023 17:12:49 +0200
Subject: [PATCH 04/38] Rgba does not store Option as component (#352)

Legacy `rgb`/`rgba` syntax does not allow the "none" keyword and
although the modern `rgb`/`rgba` syntax does support it, it is
immediately converted to 0, because we never have to serialize back to
"none" keywords for `rgb`/`rgba`.

Also `RGBA` is now renamed to `Rgba` as per common rust naming
conventions now that it is not used directly in Gecko any more.
---
 src/color.rs | 141 ++++++++++++++++++++++++---------------------------
 src/lib.rs   |   2 +-
 src/tests.rs |  27 ++++------
 3 files changed, 79 insertions(+), 91 deletions(-)

diff --git a/src/color.rs b/src/color.rs
index d114c3fc..30a195e1 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -82,44 +82,34 @@ fn normalize_hue(hue: f32) -> f32 {
 
 /// A color with red, green, blue, and alpha components, in a byte each.
 #[derive(Clone, Copy, PartialEq, Debug)]
-pub struct RGBA {
+pub struct RgbaLegacy {
     /// The red component.
-    pub red: Option<u8>,
+    pub red: u8,
     /// The green component.
-    pub green: Option<u8>,
+    pub green: u8,
     /// The blue component.
-    pub blue: Option<u8>,
+    pub blue: u8,
     /// The alpha component.
-    pub alpha: Option<f32>,
+    pub alpha: f32,
 }
 
-impl RGBA {
+impl RgbaLegacy {
     /// Constructs a new RGBA value from float components. It expects the red,
     /// green, blue and alpha channels in that order, and all values will be
     /// clamped to the 0.0 ... 1.0 range.
     #[inline]
-    pub fn from_floats(
-        red: Option<f32>,
-        green: Option<f32>,
-        blue: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self {
+    pub fn from_floats(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
         Self::new(
-            red.map(clamp_unit_f32),
-            green.map(clamp_unit_f32),
-            blue.map(clamp_unit_f32),
-            alpha.map(|a| a.clamp(0.0, OPAQUE)),
+            clamp_unit_f32(red),
+            clamp_unit_f32(green),
+            clamp_unit_f32(blue),
+            alpha.clamp(0.0, OPAQUE),
         )
     }
 
     /// Same thing, but with `u8` values instead of floats in the 0 to 1 range.
     #[inline]
-    pub const fn new(
-        red: Option<u8>,
-        green: Option<u8>,
-        blue: Option<u8>,
-        alpha: Option<f32>,
-    ) -> Self {
+    pub const fn new(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
         Self {
             red,
             green,
@@ -130,7 +120,7 @@ impl RGBA {
 }
 
 #[cfg(feature = "serde")]
-impl Serialize for RGBA {
+impl Serialize for RgbaLegacy {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
@@ -140,32 +130,32 @@ impl Serialize for RGBA {
 }
 
 #[cfg(feature = "serde")]
-impl<'de> Deserialize<'de> for RGBA {
+impl<'de> Deserialize<'de> for RgbaLegacy {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
     where
         D: Deserializer<'de>,
     {
         let (r, g, b, a) = Deserialize::deserialize(deserializer)?;
-        Ok(RGBA::new(r, g, b, a))
+        Ok(RgbaLegacy::new(r, g, b, a))
     }
 }
 
-impl ToCss for RGBA {
+impl ToCss for RgbaLegacy {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
     where
         W: fmt::Write,
     {
-        let has_alpha = self.alpha.unwrap_or(0.0) != OPAQUE;
+        let has_alpha = self.alpha != OPAQUE;
 
         dest.write_str(if has_alpha { "rgba(" } else { "rgb(" })?;
-        self.red.unwrap_or(0).to_css(dest)?;
+        self.red.to_css(dest)?;
         dest.write_str(", ")?;
-        self.green.unwrap_or(0).to_css(dest)?;
+        self.green.to_css(dest)?;
         dest.write_str(", ")?;
-        self.blue.unwrap_or(0).to_css(dest)?;
+        self.blue.to_css(dest)?;
 
         // Legacy syntax does not allow none components.
-        serialize_color_alpha(dest, Some(self.alpha.unwrap_or(0.0)), true)?;
+        serialize_color_alpha(dest, Some(self.alpha), true)?;
 
         dest.write_char(')')
     }
@@ -213,7 +203,7 @@ impl ToCss for Hsl {
             self.lightness.unwrap_or(0.0),
         );
 
-        RGBA::from_floats(Some(red), Some(green), Some(blue), self.alpha).to_css(dest)
+        RgbaLegacy::from_floats(red, green, blue, self.alpha.unwrap_or(OPAQUE)).to_css(dest)
     }
 }
 
@@ -280,7 +270,7 @@ impl ToCss for Hwb {
             self.blackness.unwrap_or(0.0),
         );
 
-        RGBA::from_floats(Some(red), Some(green), Some(blue), self.alpha).to_css(dest)
+        RgbaLegacy::from_floats(red, green, blue, self.alpha.unwrap_or(OPAQUE)).to_css(dest)
     }
 }
 
@@ -621,7 +611,7 @@ pub enum Color {
     /// The 'currentcolor' keyword.
     CurrentColor,
     /// Specify sRGB colors directly by their red/green/blue/alpha chanels.
-    Rgba(RGBA),
+    Rgba(RgbaLegacy),
     /// Specifies a color in sRGB using hue, saturation and lightness components.
     Hsl(Hsl),
     /// Specifies a color in sRGB using hue, whiteness and blackness components.
@@ -812,7 +802,7 @@ pub trait FromParsedColor {
     fn from_current_color() -> Self;
 
     /// Construct a new color from red, green, blue and alpha components.
-    fn from_rgba(red: Option<u8>, green: Option<u8>, blue: Option<u8>, alpha: Option<f32>) -> Self;
+    fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self;
 
     /// Construct a new color from hue, saturation, lightness and alpha components.
     fn from_hsl(
@@ -876,28 +866,28 @@ where
 {
     Ok(match value.len() {
         8 => O::from_rgba(
-            Some(from_hex(value[0])? * 16 + from_hex(value[1])?),
-            Some(from_hex(value[2])? * 16 + from_hex(value[3])?),
-            Some(from_hex(value[4])? * 16 + from_hex(value[5])?),
-            Some((from_hex(value[6])? * 16 + from_hex(value[7])?) as f32 / 255.0),
+            from_hex(value[0])? * 16 + from_hex(value[1])?,
+            from_hex(value[2])? * 16 + from_hex(value[3])?,
+            from_hex(value[4])? * 16 + from_hex(value[5])?,
+            (from_hex(value[6])? * 16 + from_hex(value[7])?) as f32 / 255.0,
         ),
         6 => O::from_rgba(
-            Some(from_hex(value[0])? * 16 + from_hex(value[1])?),
-            Some(from_hex(value[2])? * 16 + from_hex(value[3])?),
-            Some(from_hex(value[4])? * 16 + from_hex(value[5])?),
-            Some(OPAQUE),
+            from_hex(value[0])? * 16 + from_hex(value[1])?,
+            from_hex(value[2])? * 16 + from_hex(value[3])?,
+            from_hex(value[4])? * 16 + from_hex(value[5])?,
+            OPAQUE,
         ),
         4 => O::from_rgba(
-            Some(from_hex(value[0])? * 17),
-            Some(from_hex(value[1])? * 17),
-            Some(from_hex(value[2])? * 17),
-            Some((from_hex(value[3])? * 17) as f32 / 255.0),
+            from_hex(value[0])? * 17,
+            from_hex(value[1])? * 17,
+            from_hex(value[2])? * 17,
+            (from_hex(value[3])? * 17) as f32 / 255.0,
         ),
         3 => O::from_rgba(
-            Some(from_hex(value[0])? * 17),
-            Some(from_hex(value[1])? * 17),
-            Some(from_hex(value[2])? * 17),
-            Some(OPAQUE),
+            from_hex(value[0])? * 17,
+            from_hex(value[1])? * 17,
+            from_hex(value[2])? * 17,
+            OPAQUE,
         ),
         _ => return Err(()),
     })
@@ -935,8 +925,8 @@ impl FromParsedColor for Color {
     }
 
     #[inline]
-    fn from_rgba(red: Option<u8>, green: Option<u8>, blue: Option<u8>, alpha: Option<f32>) -> Self {
-        Color::Rgba(RGBA::new(red, green, blue, alpha))
+    fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
+        Color::Rgba(RgbaLegacy::new(red, green, blue, alpha))
     }
 
     fn from_hsl(
@@ -1174,10 +1164,10 @@ where
     }
 
     match_ignore_ascii_case! { ident ,
-        "transparent" => Ok(Output::from_rgba(Some(0), Some(0), Some(0), Some(0.0))),
+        "transparent" => Ok(Output::from_rgba(0, 0, 0, 0.0)),
         "currentcolor" => Ok(Output::from_current_color()),
         _ => keyword(ident)
-            .map(|(r, g, b)| Output::from_rgba(Some(*r), Some(*g), Some(*b), Some(1.0)))
+            .map(|&(r, g, b)| Output::from_rgba(r, g, b, 1.0))
             .ok_or(()),
     }
 }
@@ -1327,47 +1317,50 @@ where
     // are parsing the legacy syntax.
     let is_legacy_syntax = maybe_red.is_some() && arguments.try_parse(|p| p.expect_comma()).is_ok();
 
-    let red: Option<u8>;
-    let green: Option<u8>;
-    let blue: Option<u8>;
-
-    let alpha = if is_legacy_syntax {
-        match maybe_red.unwrap() {
+    let (red, green, blue, alpha) = if is_legacy_syntax {
+        let (red, green, blue) = match maybe_red.unwrap() {
             NumberOrPercentage::Number { value } => {
-                red = Some(clamp_floor_256_f32(value));
-                green = Some(clamp_floor_256_f32(color_parser.parse_number(arguments)?));
+                let red = clamp_floor_256_f32(value);
+                let green = clamp_floor_256_f32(color_parser.parse_number(arguments)?);
                 arguments.expect_comma()?;
-                blue = Some(clamp_floor_256_f32(color_parser.parse_number(arguments)?));
+                let blue = clamp_floor_256_f32(color_parser.parse_number(arguments)?);
+                (red, green, blue)
             }
             NumberOrPercentage::Percentage { unit_value } => {
-                red = Some(clamp_unit_f32(unit_value));
-                green = Some(clamp_unit_f32(color_parser.parse_percentage(arguments)?));
+                let red = clamp_unit_f32(unit_value);
+                let green = clamp_unit_f32(color_parser.parse_percentage(arguments)?);
                 arguments.expect_comma()?;
-                blue = Some(clamp_unit_f32(color_parser.parse_percentage(arguments)?));
+                let blue = clamp_unit_f32(color_parser.parse_percentage(arguments)?);
+                (red, green, blue)
             }
-        }
+        };
 
-        Some(parse_legacy_alpha(color_parser, arguments)?)
+        let alpha = parse_legacy_alpha(color_parser, arguments)?;
+
+        (red, green, blue, alpha)
     } else {
         #[inline]
-        fn get_component_value(c: Option<NumberOrPercentage>) -> Option<u8> {
+        fn get_component_value(c: Option<NumberOrPercentage>) -> u8 {
             c.map(|c| match c {
                 NumberOrPercentage::Number { value } => clamp_floor_256_f32(value),
                 NumberOrPercentage::Percentage { unit_value } => clamp_unit_f32(unit_value),
             })
+            .unwrap_or(0)
         }
 
-        red = get_component_value(maybe_red);
+        let red = get_component_value(maybe_red);
 
-        green = get_component_value(parse_none_or(arguments, |p| {
+        let green = get_component_value(parse_none_or(arguments, |p| {
             color_parser.parse_number_or_percentage(p)
         })?);
 
-        blue = get_component_value(parse_none_or(arguments, |p| {
+        let blue = get_component_value(parse_none_or(arguments, |p| {
             color_parser.parse_number_or_percentage(p)
         })?);
 
-        parse_modern_alpha(color_parser, arguments)?
+        let alpha = parse_modern_alpha(color_parser, arguments)?.unwrap_or(0.0);
+
+        (red, green, blue, alpha)
     };
 
     Ok(P::Output::from_rgba(red, green, blue, alpha))
diff --git a/src/lib.rs b/src/lib.rs
index 7ab88e8f..74173cf6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -70,7 +70,7 @@ fn parse_border_spacing(_context: &ParserContext, input: &mut Parser)
 pub use crate::color::{
     hsl_to_rgb, hwb_to_rgb, parse_color_keyword, parse_color_with, parse_hash_color,
     serialize_color_alpha, AngleOrNumber, Color, ColorFunction, ColorParser, FromParsedColor, Hsl,
-    Hwb, Lab, Lch, NumberOrPercentage, Oklab, Oklch, PredefinedColorSpace, RGBA,
+    Hwb, Lab, Lch, NumberOrPercentage, Oklab, Oklch, PredefinedColorSpace, RgbaLegacy,
 };
 pub use crate::cow_rc_str::CowRcStr;
 pub use crate::from_bytes::{stylesheet_encoding, EncodingSupport};
diff --git a/src/tests.rs b/src/tests.rs
index e8f94a40..64e995e5 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -18,8 +18,8 @@ use super::{
     parse_important, parse_nth, parse_one_declaration, parse_one_rule, stylesheet_encoding,
     AtRuleParser, BasicParseError, BasicParseErrorKind, Color, CowRcStr, DeclarationParser,
     Delimiter, EncodingSupport, ParseError, ParseErrorKind, Parser, ParserInput, ParserState,
-    QualifiedRuleParser, RuleBodyItemParser, RuleBodyParser, SourceLocation, StyleSheetParser,
-    ToCss, Token, TokenSerializationType, UnicodeRange, RGBA,
+    QualifiedRuleParser, RgbaLegacy, RuleBodyItemParser, RuleBodyParser, SourceLocation,
+    StyleSheetParser, ToCss, Token, TokenSerializationType, UnicodeRange,
 };
 
 macro_rules! JArray {
@@ -592,19 +592,19 @@ fn serialize_current_color() {
 
 #[test]
 fn serialize_rgb_full_alpha() {
-    let c = Color::Rgba(RGBA::new(Some(255), Some(230), Some(204), Some(1.0)));
+    let c = Color::Rgba(RgbaLegacy::new(255, 230, 204, 1.0));
     assert_eq!(c.to_css_string(), "rgb(255, 230, 204)");
 }
 
 #[test]
 fn serialize_rgba() {
-    let c = Color::Rgba(RGBA::new(Some(26), Some(51), Some(77), Some(0.125)));
+    let c = Color::Rgba(RgbaLegacy::new(26, 51, 77, 0.125));
     assert_eq!(c.to_css_string(), "rgba(26, 51, 77, 0.125)");
 }
 
 #[test]
 fn serialize_rgba_two_digit_float_if_roundtrips() {
-    let c = Color::Rgba(RGBA::from_floats(Some(0.), Some(0.), Some(0.), Some(0.5)));
+    let c = Color::Rgba(RgbaLegacy::from_floats(0., 0., 0., 0.5));
     assert_eq!(c.to_css_string(), "rgba(0, 0, 0, 0.5)");
 }
 
@@ -1526,7 +1526,7 @@ fn generic_parser() {
     #[derive(Debug, PartialEq)]
     enum OutputType {
         CurrentColor,
-        Rgba(Option<u8>, Option<u8>, Option<u8>, Option<f32>),
+        Rgba(u8, u8, u8, f32),
         Hsl(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
         Hwb(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
         Lab(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
@@ -1547,12 +1547,7 @@ fn generic_parser() {
             OutputType::CurrentColor
         }
 
-        fn from_rgba(
-            red: Option<u8>,
-            green: Option<u8>,
-            blue: Option<u8>,
-            alpha: Option<f32>,
-        ) -> Self {
+        fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
             OutputType::Rgba(red, green, blue, alpha)
         }
 
@@ -1630,10 +1625,10 @@ fn generic_parser() {
     #[rustfmt::skip]
     const TESTS: &[(&str, OutputType)] = &[
         ("currentColor",                OutputType::CurrentColor),
-        ("rgb(1, 2, 3)",                OutputType::Rgba(Some(1), Some(2), Some(3), Some(1.0))),
-        ("rgba(1, 2, 3, 0.4)",          OutputType::Rgba(Some(1), Some(2), Some(3), Some(0.4))),
-        ("rgb(none none none / none)",  OutputType::Rgba(None, None, None, None)),
-        ("rgb(1 none 3 / none)",        OutputType::Rgba(Some(1), None, Some(3), None)),
+        ("rgb(1, 2, 3)",                OutputType::Rgba(1, 2, 3, 1.0)),
+        ("rgba(1, 2, 3, 0.4)",          OutputType::Rgba(1, 2, 3, 0.4)),
+        ("rgb(none none none / none)",  OutputType::Rgba(0, 0, 0, 0.0)),
+        ("rgb(1 none 3 / none)",        OutputType::Rgba(1, 0, 3, 0.0)),
 
         ("hsla(45deg, 20%, 30%, 0.4)",  OutputType::Hsl(Some(45.0), Some(0.2), Some(0.3), Some(0.4))),
         ("hsl(45deg none none)",        OutputType::Hsl(Some(45.0), None, None, Some(1.0))),

From dd17d007a6ea1fe1f8b1c77f7418988742a37fea Mon Sep 17 00:00:00 2001
From: Zach Hoffman <zach@zrhoffman.net>
Date: Wed, 26 Jul 2023 12:03:11 -0600
Subject: [PATCH 05/38] Run miri on CI (#350)

* Run miri on nightly

* Exclude tests under miri on CI that take over a minute to run
---
 .github/workflows/main.yml | 5 +++++
 Cargo.toml                 | 2 ++
 src/tests.rs               | 6 ++++++
 3 files changed, 13 insertions(+)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 47282234..49e91ad3 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -36,6 +36,7 @@ jobs:
           profile: minimal
           toolchain: ${{ matrix.toolchain }}
           override: true
+          components: ${{ matrix.toolchain == 'nightly' && 'miri,rust-src' || '' }}
 
       - name: Cargo build
         run: cargo build ${{ matrix.features }}
@@ -50,6 +51,10 @@ jobs:
         run: cargo build
         working-directory: macros
 
+      - name: Cargo miri test
+        if: "matrix.toolchain == 'nightly'"
+        run: cargo miri test --features skip_long_tests ${{ matrix.features }}
+
   build_result:
     name: Result
     runs-on: ubuntu-latest
diff --git a/Cargo.toml b/Cargo.toml
index 89310a57..f35bdc75 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -30,6 +30,8 @@ smallvec = "1.0"
 [features]
 bench = []
 dummy_match_byte = []
+# Useful for skipping tests when execution is slow, e.g., under miri
+skip_long_tests = []
 
 [workspace]
 members = [".", "./macros", "./procedural-masquerade"]
diff --git a/src/tests.rs b/src/tests.rs
index 64e995e5..fac0b6be 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -373,6 +373,7 @@ fn color3() {
     })
 }
 
+#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
 #[test]
 fn color3_hsl() {
     run_color_tests(include_str!("css-parsing-tests/color3_hsl.json"), |c| {
@@ -395,6 +396,7 @@ fn color3_keywords() {
     )
 }
 
+#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
 #[test]
 fn color4_hwb() {
     run_color_tests(include_str!("css-parsing-tests/color4_hwb.json"), |c| {
@@ -404,6 +406,7 @@ fn color4_hwb() {
     })
 }
 
+#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
 #[test]
 fn color4_lab_lch_oklab_oklch() {
     run_color_tests(
@@ -939,6 +942,7 @@ fn unquoted_url(b: &mut Bencher) {
     })
 }
 
+#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
 #[cfg(feature = "bench")]
 #[bench]
 fn numeric(b: &mut Bencher) {
@@ -953,6 +957,7 @@ fn numeric(b: &mut Bencher) {
 
 struct JsonParser;
 
+#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
 #[test]
 fn no_stack_overflow_multiple_nested_blocks() {
     let mut input: String = "{{".into();
@@ -1413,6 +1418,7 @@ fn parse_sourceurl_comments() {
     }
 }
 
+#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
 #[test]
 fn roundtrip_percentage_token() {
     fn test_roundtrip(value: &str) {

From 8ff38afa1fe9a9e843ec6a50d443d93a6446d307 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Wed, 2 Aug 2023 12:24:17 +0200
Subject: [PATCH 06/38] color: Expose named colors more directly.

This will allow me to remove some duplicated version of this from Gecko.

This changes the API of ascii_case_insensitive_phf_map, so needs to be a
breaking bump.
---
 Cargo.toml    |   2 +-
 src/color.rs  | 338 ++++++++++++++++++++++++++------------------------
 src/lib.rs    |   7 +-
 src/macros.rs |  31 +++--
 src/tests.rs  |   4 +-
 5 files changed, 203 insertions(+), 179 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index f35bdc75..d322168c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cssparser"
-version = "0.31.2"
+version = "0.32.0"
 authors = [ "Simon Sapin <simon.sapin@exyr.org>" ]
 
 description = "Rust implementation of CSS Syntax Level 3"
diff --git a/src/color.rs b/src/color.rs
index 30a195e1..6c6ae8e1 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -999,6 +999,178 @@ impl FromParsedColor for Color {
     }
 }
 
+ascii_case_insensitive_phf_map! {
+    named_colors -> (u8, u8, u8) = {
+        "black" => (0, 0, 0),
+        "silver" => (192, 192, 192),
+        "gray" => (128, 128, 128),
+        "white" => (255, 255, 255),
+        "maroon" => (128, 0, 0),
+        "red" => (255, 0, 0),
+        "purple" => (128, 0, 128),
+        "fuchsia" => (255, 0, 255),
+        "green" => (0, 128, 0),
+        "lime" => (0, 255, 0),
+        "olive" => (128, 128, 0),
+        "yellow" => (255, 255, 0),
+        "navy" => (0, 0, 128),
+        "blue" => (0, 0, 255),
+        "teal" => (0, 128, 128),
+        "aqua" => (0, 255, 255),
+
+        "aliceblue" => (240, 248, 255),
+        "antiquewhite" => (250, 235, 215),
+        "aquamarine" => (127, 255, 212),
+        "azure" => (240, 255, 255),
+        "beige" => (245, 245, 220),
+        "bisque" => (255, 228, 196),
+        "blanchedalmond" => (255, 235, 205),
+        "blueviolet" => (138, 43, 226),
+        "brown" => (165, 42, 42),
+        "burlywood" => (222, 184, 135),
+        "cadetblue" => (95, 158, 160),
+        "chartreuse" => (127, 255, 0),
+        "chocolate" => (210, 105, 30),
+        "coral" => (255, 127, 80),
+        "cornflowerblue" => (100, 149, 237),
+        "cornsilk" => (255, 248, 220),
+        "crimson" => (220, 20, 60),
+        "cyan" => (0, 255, 255),
+        "darkblue" => (0, 0, 139),
+        "darkcyan" => (0, 139, 139),
+        "darkgoldenrod" => (184, 134, 11),
+        "darkgray" => (169, 169, 169),
+        "darkgreen" => (0, 100, 0),
+        "darkgrey" => (169, 169, 169),
+        "darkkhaki" => (189, 183, 107),
+        "darkmagenta" => (139, 0, 139),
+        "darkolivegreen" => (85, 107, 47),
+        "darkorange" => (255, 140, 0),
+        "darkorchid" => (153, 50, 204),
+        "darkred" => (139, 0, 0),
+        "darksalmon" => (233, 150, 122),
+        "darkseagreen" => (143, 188, 143),
+        "darkslateblue" => (72, 61, 139),
+        "darkslategray" => (47, 79, 79),
+        "darkslategrey" => (47, 79, 79),
+        "darkturquoise" => (0, 206, 209),
+        "darkviolet" => (148, 0, 211),
+        "deeppink" => (255, 20, 147),
+        "deepskyblue" => (0, 191, 255),
+        "dimgray" => (105, 105, 105),
+        "dimgrey" => (105, 105, 105),
+        "dodgerblue" => (30, 144, 255),
+        "firebrick" => (178, 34, 34),
+        "floralwhite" => (255, 250, 240),
+        "forestgreen" => (34, 139, 34),
+        "gainsboro" => (220, 220, 220),
+        "ghostwhite" => (248, 248, 255),
+        "gold" => (255, 215, 0),
+        "goldenrod" => (218, 165, 32),
+        "greenyellow" => (173, 255, 47),
+        "grey" => (128, 128, 128),
+        "honeydew" => (240, 255, 240),
+        "hotpink" => (255, 105, 180),
+        "indianred" => (205, 92, 92),
+        "indigo" => (75, 0, 130),
+        "ivory" => (255, 255, 240),
+        "khaki" => (240, 230, 140),
+        "lavender" => (230, 230, 250),
+        "lavenderblush" => (255, 240, 245),
+        "lawngreen" => (124, 252, 0),
+        "lemonchiffon" => (255, 250, 205),
+        "lightblue" => (173, 216, 230),
+        "lightcoral" => (240, 128, 128),
+        "lightcyan" => (224, 255, 255),
+        "lightgoldenrodyellow" => (250, 250, 210),
+        "lightgray" => (211, 211, 211),
+        "lightgreen" => (144, 238, 144),
+        "lightgrey" => (211, 211, 211),
+        "lightpink" => (255, 182, 193),
+        "lightsalmon" => (255, 160, 122),
+        "lightseagreen" => (32, 178, 170),
+        "lightskyblue" => (135, 206, 250),
+        "lightslategray" => (119, 136, 153),
+        "lightslategrey" => (119, 136, 153),
+        "lightsteelblue" => (176, 196, 222),
+        "lightyellow" => (255, 255, 224),
+        "limegreen" => (50, 205, 50),
+        "linen" => (250, 240, 230),
+        "magenta" => (255, 0, 255),
+        "mediumaquamarine" => (102, 205, 170),
+        "mediumblue" => (0, 0, 205),
+        "mediumorchid" => (186, 85, 211),
+        "mediumpurple" => (147, 112, 219),
+        "mediumseagreen" => (60, 179, 113),
+        "mediumslateblue" => (123, 104, 238),
+        "mediumspringgreen" => (0, 250, 154),
+        "mediumturquoise" => (72, 209, 204),
+        "mediumvioletred" => (199, 21, 133),
+        "midnightblue" => (25, 25, 112),
+        "mintcream" => (245, 255, 250),
+        "mistyrose" => (255, 228, 225),
+        "moccasin" => (255, 228, 181),
+        "navajowhite" => (255, 222, 173),
+        "oldlace" => (253, 245, 230),
+        "olivedrab" => (107, 142, 35),
+        "orange" => (255, 165, 0),
+        "orangered" => (255, 69, 0),
+        "orchid" => (218, 112, 214),
+        "palegoldenrod" => (238, 232, 170),
+        "palegreen" => (152, 251, 152),
+        "paleturquoise" => (175, 238, 238),
+        "palevioletred" => (219, 112, 147),
+        "papayawhip" => (255, 239, 213),
+        "peachpuff" => (255, 218, 185),
+        "peru" => (205, 133, 63),
+        "pink" => (255, 192, 203),
+        "plum" => (221, 160, 221),
+        "powderblue" => (176, 224, 230),
+        "rebeccapurple" => (102, 51, 153),
+        "rosybrown" => (188, 143, 143),
+        "royalblue" => (65, 105, 225),
+        "saddlebrown" => (139, 69, 19),
+        "salmon" => (250, 128, 114),
+        "sandybrown" => (244, 164, 96),
+        "seagreen" => (46, 139, 87),
+        "seashell" => (255, 245, 238),
+        "sienna" => (160, 82, 45),
+        "skyblue" => (135, 206, 235),
+        "slateblue" => (106, 90, 205),
+        "slategray" => (112, 128, 144),
+        "slategrey" => (112, 128, 144),
+        "snow" => (255, 250, 250),
+        "springgreen" => (0, 255, 127),
+        "steelblue" => (70, 130, 180),
+        "tan" => (210, 180, 140),
+        "thistle" => (216, 191, 216),
+        "tomato" => (255, 99, 71),
+        "turquoise" => (64, 224, 208),
+        "violet" => (238, 130, 238),
+        "wheat" => (245, 222, 179),
+        "whitesmoke" => (245, 245, 245),
+        "yellowgreen" => (154, 205, 50),
+    }
+}
+
+/// Returns the named color with the given name.
+/// <https://drafts.csswg.org/css-color-4/#typedef-named-color>
+#[inline]
+pub fn parse_named_color<Output>(ident: &str) -> Result<Output, ()>
+where
+    Output: FromParsedColor,
+{
+    let &(r, g, b) = named_colors::get(ident).ok_or(())?;
+    Ok(Output::from_rgba(r, g, b, 1.0))
+}
+
+/// Returns an iterator over all named CSS colors.
+/// <https://drafts.csswg.org/css-color-4/#typedef-named-color>
+#[inline]
+pub fn all_named_colors() -> impl Iterator<Item = (&'static str, (u8, u8, u8))> {
+    named_colors::entries().map(|(k, v)| (*k, *v))
+}
+
 /// Return the named color with the given name.
 ///
 /// Matching is case-insensitive in the ASCII range.
@@ -1009,167 +1181,11 @@ pub fn parse_color_keyword<Output>(ident: &str) -> Result<Output, ()>
 where
     Output: FromParsedColor,
 {
-    ascii_case_insensitive_phf_map! {
-        keyword -> (u8, u8, u8) = {
-            "black" => (0, 0, 0),
-            "silver" => (192, 192, 192),
-            "gray" => (128, 128, 128),
-            "white" => (255, 255, 255),
-            "maroon" => (128, 0, 0),
-            "red" => (255, 0, 0),
-            "purple" => (128, 0, 128),
-            "fuchsia" => (255, 0, 255),
-            "green" => (0, 128, 0),
-            "lime" => (0, 255, 0),
-            "olive" => (128, 128, 0),
-            "yellow" => (255, 255, 0),
-            "navy" => (0, 0, 128),
-            "blue" => (0, 0, 255),
-            "teal" => (0, 128, 128),
-            "aqua" => (0, 255, 255),
-
-            "aliceblue" => (240, 248, 255),
-            "antiquewhite" => (250, 235, 215),
-            "aquamarine" => (127, 255, 212),
-            "azure" => (240, 255, 255),
-            "beige" => (245, 245, 220),
-            "bisque" => (255, 228, 196),
-            "blanchedalmond" => (255, 235, 205),
-            "blueviolet" => (138, 43, 226),
-            "brown" => (165, 42, 42),
-            "burlywood" => (222, 184, 135),
-            "cadetblue" => (95, 158, 160),
-            "chartreuse" => (127, 255, 0),
-            "chocolate" => (210, 105, 30),
-            "coral" => (255, 127, 80),
-            "cornflowerblue" => (100, 149, 237),
-            "cornsilk" => (255, 248, 220),
-            "crimson" => (220, 20, 60),
-            "cyan" => (0, 255, 255),
-            "darkblue" => (0, 0, 139),
-            "darkcyan" => (0, 139, 139),
-            "darkgoldenrod" => (184, 134, 11),
-            "darkgray" => (169, 169, 169),
-            "darkgreen" => (0, 100, 0),
-            "darkgrey" => (169, 169, 169),
-            "darkkhaki" => (189, 183, 107),
-            "darkmagenta" => (139, 0, 139),
-            "darkolivegreen" => (85, 107, 47),
-            "darkorange" => (255, 140, 0),
-            "darkorchid" => (153, 50, 204),
-            "darkred" => (139, 0, 0),
-            "darksalmon" => (233, 150, 122),
-            "darkseagreen" => (143, 188, 143),
-            "darkslateblue" => (72, 61, 139),
-            "darkslategray" => (47, 79, 79),
-            "darkslategrey" => (47, 79, 79),
-            "darkturquoise" => (0, 206, 209),
-            "darkviolet" => (148, 0, 211),
-            "deeppink" => (255, 20, 147),
-            "deepskyblue" => (0, 191, 255),
-            "dimgray" => (105, 105, 105),
-            "dimgrey" => (105, 105, 105),
-            "dodgerblue" => (30, 144, 255),
-            "firebrick" => (178, 34, 34),
-            "floralwhite" => (255, 250, 240),
-            "forestgreen" => (34, 139, 34),
-            "gainsboro" => (220, 220, 220),
-            "ghostwhite" => (248, 248, 255),
-            "gold" => (255, 215, 0),
-            "goldenrod" => (218, 165, 32),
-            "greenyellow" => (173, 255, 47),
-            "grey" => (128, 128, 128),
-            "honeydew" => (240, 255, 240),
-            "hotpink" => (255, 105, 180),
-            "indianred" => (205, 92, 92),
-            "indigo" => (75, 0, 130),
-            "ivory" => (255, 255, 240),
-            "khaki" => (240, 230, 140),
-            "lavender" => (230, 230, 250),
-            "lavenderblush" => (255, 240, 245),
-            "lawngreen" => (124, 252, 0),
-            "lemonchiffon" => (255, 250, 205),
-            "lightblue" => (173, 216, 230),
-            "lightcoral" => (240, 128, 128),
-            "lightcyan" => (224, 255, 255),
-            "lightgoldenrodyellow" => (250, 250, 210),
-            "lightgray" => (211, 211, 211),
-            "lightgreen" => (144, 238, 144),
-            "lightgrey" => (211, 211, 211),
-            "lightpink" => (255, 182, 193),
-            "lightsalmon" => (255, 160, 122),
-            "lightseagreen" => (32, 178, 170),
-            "lightskyblue" => (135, 206, 250),
-            "lightslategray" => (119, 136, 153),
-            "lightslategrey" => (119, 136, 153),
-            "lightsteelblue" => (176, 196, 222),
-            "lightyellow" => (255, 255, 224),
-            "limegreen" => (50, 205, 50),
-            "linen" => (250, 240, 230),
-            "magenta" => (255, 0, 255),
-            "mediumaquamarine" => (102, 205, 170),
-            "mediumblue" => (0, 0, 205),
-            "mediumorchid" => (186, 85, 211),
-            "mediumpurple" => (147, 112, 219),
-            "mediumseagreen" => (60, 179, 113),
-            "mediumslateblue" => (123, 104, 238),
-            "mediumspringgreen" => (0, 250, 154),
-            "mediumturquoise" => (72, 209, 204),
-            "mediumvioletred" => (199, 21, 133),
-            "midnightblue" => (25, 25, 112),
-            "mintcream" => (245, 255, 250),
-            "mistyrose" => (255, 228, 225),
-            "moccasin" => (255, 228, 181),
-            "navajowhite" => (255, 222, 173),
-            "oldlace" => (253, 245, 230),
-            "olivedrab" => (107, 142, 35),
-            "orange" => (255, 165, 0),
-            "orangered" => (255, 69, 0),
-            "orchid" => (218, 112, 214),
-            "palegoldenrod" => (238, 232, 170),
-            "palegreen" => (152, 251, 152),
-            "paleturquoise" => (175, 238, 238),
-            "palevioletred" => (219, 112, 147),
-            "papayawhip" => (255, 239, 213),
-            "peachpuff" => (255, 218, 185),
-            "peru" => (205, 133, 63),
-            "pink" => (255, 192, 203),
-            "plum" => (221, 160, 221),
-            "powderblue" => (176, 224, 230),
-            "rebeccapurple" => (102, 51, 153),
-            "rosybrown" => (188, 143, 143),
-            "royalblue" => (65, 105, 225),
-            "saddlebrown" => (139, 69, 19),
-            "salmon" => (250, 128, 114),
-            "sandybrown" => (244, 164, 96),
-            "seagreen" => (46, 139, 87),
-            "seashell" => (255, 245, 238),
-            "sienna" => (160, 82, 45),
-            "skyblue" => (135, 206, 235),
-            "slateblue" => (106, 90, 205),
-            "slategray" => (112, 128, 144),
-            "slategrey" => (112, 128, 144),
-            "snow" => (255, 250, 250),
-            "springgreen" => (0, 255, 127),
-            "steelblue" => (70, 130, 180),
-            "tan" => (210, 180, 140),
-            "thistle" => (216, 191, 216),
-            "tomato" => (255, 99, 71),
-            "turquoise" => (64, 224, 208),
-            "violet" => (238, 130, 238),
-            "wheat" => (245, 222, 179),
-            "whitesmoke" => (245, 245, 245),
-            "yellowgreen" => (154, 205, 50),
-        }
-    }
-
-    match_ignore_ascii_case! { ident ,
-        "transparent" => Ok(Output::from_rgba(0, 0, 0, 0.0)),
-        "currentcolor" => Ok(Output::from_current_color()),
-        _ => keyword(ident)
-            .map(|&(r, g, b)| Output::from_rgba(r, g, b, 1.0))
-            .ok_or(()),
-    }
+    Ok(match_ignore_ascii_case! { ident ,
+        "transparent" => Output::from_rgba(0, 0, 0, 0.0),
+        "currentcolor" => Output::from_current_color(),
+        _ => return parse_named_color(ident),
+    })
 }
 
 #[inline]
diff --git a/src/lib.rs b/src/lib.rs
index 74173cf6..143ec87b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -68,9 +68,10 @@ fn parse_border_spacing(_context: &ParserContext, input: &mut Parser)
 #![recursion_limit = "200"] // For color::parse_color_keyword
 
 pub use crate::color::{
-    hsl_to_rgb, hwb_to_rgb, parse_color_keyword, parse_color_with, parse_hash_color,
-    serialize_color_alpha, AngleOrNumber, Color, ColorFunction, ColorParser, FromParsedColor, Hsl,
-    Hwb, Lab, Lch, NumberOrPercentage, Oklab, Oklch, PredefinedColorSpace, RgbaLegacy,
+    all_named_colors, hsl_to_rgb, hwb_to_rgb, parse_color_keyword, parse_color_with,
+    parse_hash_color, parse_named_color, serialize_color_alpha, AngleOrNumber, Color,
+    ColorFunction, ColorParser, FromParsedColor, Hsl, Hwb, Lab, Lch, NumberOrPercentage, Oklab,
+    Oklch, PredefinedColorSpace, RgbaLegacy,
 };
 pub use crate::cow_rc_str::CowRcStr;
 pub use crate::from_bytes::{stylesheet_encoding, EncodingSupport};
diff --git a/src/macros.rs b/src/macros.rs
index 981af010..04b385ca 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -76,36 +76,43 @@ macro_rules! match_ignore_ascii_case {
 ///
 /// fn color_rgb(input: &str) -> Option<(u8, u8, u8)> {
 ///     cssparser::ascii_case_insensitive_phf_map! {
-///         keyword -> (u8, u8, u8) = {
+///         keywords -> (u8, u8, u8) = {
 ///             "red" => (255, 0, 0),
 ///             "green" => (0, 255, 0),
 ///             "blue" => (0, 0, 255),
 ///         }
 ///     }
-///     keyword(input).cloned()
+///     keywords::get(input).cloned()
 /// }
+/// ```
+///
+/// You can also iterate over the map entries by using `keywords::entries()`.
 #[macro_export]
 macro_rules! ascii_case_insensitive_phf_map {
     ($name: ident -> $ValueType: ty = { $( $key: tt => $value: expr ),+ }) => {
         ascii_case_insensitive_phf_map!($name -> $ValueType = { $( $key => $value, )+ })
     };
     ($name: ident -> $ValueType: ty = { $( $key: tt => $value: expr, )+ }) => {
-        pub fn $name(input: &str) -> Option<&'static $ValueType> {
-            // This dummy module works around a feature gate,
-            // see comment on the similar module in `match_ignore_ascii_case!` above.
-            mod _cssparser_internal {
-                $crate::_cssparser_internal_max_len! {
-                    $( $key )+
-                }
-            }
+        mod $name {
             use $crate::_cssparser_internal_phf as phf;
+            $crate::_cssparser_internal_max_len! {
+                $( $key )+
+            }
             static MAP: phf::Map<&'static str, $ValueType> = phf::phf_map! {
                 $(
                     $key => $value,
                 )*
             };
-            $crate::_cssparser_internal_to_lowercase!(input, _cssparser_internal::MAX_LENGTH => lowercase);
-            lowercase.and_then(|s| MAP.get(s))
+
+            #[allow(dead_code)]
+            pub fn entries() -> impl Iterator<Item = (&'static &'static str, &'static $ValueType)> {
+                MAP.entries()
+            }
+
+            pub fn get(input: &str) -> Option<&'static $ValueType> {
+                $crate::_cssparser_internal_to_lowercase!(input, MAX_LENGTH => lowercase);
+                MAP.get(lowercase?)
+            }
         }
     }
 }
diff --git a/src/tests.rs b/src/tests.rs
index fac0b6be..658c4a3a 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -1213,8 +1213,8 @@ fn procedural_masquerade_whitespace() {
             "  \t\n" => ()
         }
     }
-    assert_eq!(map("  \t\n"), Some(&()));
-    assert_eq!(map(" "), None);
+    assert_eq!(map::get("  \t\n"), Some(&()));
+    assert_eq!(map::get(" "), None);
 
     match_ignore_ascii_case! { "  \t\n",
         " " => panic!("1"),

From 0dd31403fb705d8d784ec8dbe8828cfa07b6dabc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Wed, 2 Aug 2023 15:16:08 +0200
Subject: [PATCH 07/38] macros: Keep the ability for
 ascii_case_insensitive_phf_map to reference custom types. (#354)

See https://github.com/rust-lang/rust/issues/114369. use super::*
wouldn't be enough.
---
 src/macros.rs | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/src/macros.rs b/src/macros.rs
index 04b385ca..fc4b77a1 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -93,24 +93,36 @@ macro_rules! ascii_case_insensitive_phf_map {
         ascii_case_insensitive_phf_map!($name -> $ValueType = { $( $key => $value, )+ })
     };
     ($name: ident -> $ValueType: ty = { $( $key: tt => $value: expr, )+ }) => {
-        mod $name {
-            use $crate::_cssparser_internal_phf as phf;
+        use $crate::_cssparser_internal_phf as phf;
+
+        // See macro above for context.
+        mod cssparser_internal {
             $crate::_cssparser_internal_max_len! {
                 $( $key )+
             }
-            static MAP: phf::Map<&'static str, $ValueType> = phf::phf_map! {
-                $(
-                    $key => $value,
-                )*
-            };
+        }
+
+        static MAP: phf::Map<&'static str, $ValueType> = phf::phf_map! {
+            $(
+                $key => $value,
+            )*
+        };
 
+        // While the obvious choice for this would be an inner module, it's not possible to
+        // reference from types from there, see:
+        // <https://github.com/rust-lang/rust/issues/114369>
+        //
+        // So we abuse a struct with static associated functions instead.
+        #[allow(non_camel_case_types)]
+        struct $name;
+        impl $name {
             #[allow(dead_code)]
-            pub fn entries() -> impl Iterator<Item = (&'static &'static str, &'static $ValueType)> {
+            fn entries() -> impl Iterator<Item = (&'static &'static str, &'static $ValueType)> {
                 MAP.entries()
             }
 
-            pub fn get(input: &str) -> Option<&'static $ValueType> {
-                $crate::_cssparser_internal_to_lowercase!(input, MAX_LENGTH => lowercase);
+            fn get(input: &str) -> Option<&'static $ValueType> {
+                $crate::_cssparser_internal_to_lowercase!(input, cssparser_internal::MAX_LENGTH => lowercase);
                 MAP.get(lowercase?)
             }
         }

From de0013137a833a4c29cb716da08d90da48d4ad22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Thu, 10 Aug 2023 15:13:47 +0200
Subject: [PATCH 08/38] parser: Remove the line-number-offset mechanism. (#355)

It can be implemented on top of the parser anyways, and after
bug 1847440 we won't use it anymore.
---
 src/parser.rs    |  9 ---------
 src/tests.rs     | 46 ----------------------------------------------
 src/tokenizer.rs |  9 ++-------
 3 files changed, 2 insertions(+), 62 deletions(-)

diff --git a/src/parser.rs b/src/parser.rs
index afc6281d..ec5eb97e 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -213,15 +213,6 @@ impl<'i> ParserInput<'i> {
         }
     }
 
-    /// Create a new input for a parser.  Line numbers in locations
-    /// are offset by the given value.
-    pub fn new_with_line_number_offset(input: &'i str, first_line_number: u32) -> ParserInput<'i> {
-        ParserInput {
-            tokenizer: Tokenizer::with_first_line_number(input, first_line_number),
-            cached_token: None,
-        }
-    }
-
     #[inline]
     fn cached_token_ref(&self) -> &Token<'i> {
         &self.cached_token.as_ref().unwrap().token
diff --git a/src/tests.rs b/src/tests.rs
index 658c4a3a..8dbee8a7 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -1288,52 +1288,6 @@ fn parser_maintains_current_line() {
     assert_eq!(parser.current_line(), "ident");
 }
 
-#[test]
-fn parser_with_line_number_offset() {
-    let mut input = ParserInput::new_with_line_number_offset("ident\nident", 72);
-    let mut parser = Parser::new(&mut input);
-    assert_eq!(
-        parser.current_source_location(),
-        SourceLocation {
-            line: 72,
-            column: 1
-        }
-    );
-    assert_eq!(
-        parser.next_including_whitespace_and_comments(),
-        Ok(&Token::Ident("ident".into()))
-    );
-    assert_eq!(
-        parser.current_source_location(),
-        SourceLocation {
-            line: 72,
-            column: 6
-        }
-    );
-    assert_eq!(
-        parser.next_including_whitespace_and_comments(),
-        Ok(&Token::WhiteSpace("\n".into()))
-    );
-    assert_eq!(
-        parser.current_source_location(),
-        SourceLocation {
-            line: 73,
-            column: 1
-        }
-    );
-    assert_eq!(
-        parser.next_including_whitespace_and_comments(),
-        Ok(&Token::Ident("ident".into()))
-    );
-    assert_eq!(
-        parser.current_source_location(),
-        SourceLocation {
-            line: 73,
-            column: 6
-        }
-    );
-}
-
 #[test]
 fn cdc_regression_test() {
     let mut input = ParserInput::new("-->x");
diff --git a/src/tokenizer.rs b/src/tokenizer.rs
index 4cc6c178..02e9dadd 100644
--- a/src/tokenizer.rs
+++ b/src/tokenizer.rs
@@ -230,16 +230,11 @@ enum SeenStatus {
 impl<'a> Tokenizer<'a> {
     #[inline]
     pub fn new(input: &str) -> Tokenizer {
-        Tokenizer::with_first_line_number(input, 0)
-    }
-
-    #[inline]
-    pub fn with_first_line_number(input: &str, first_line_number: u32) -> Tokenizer {
         Tokenizer {
             input,
             position: 0,
             current_line_start_position: 0,
-            current_line_number: first_line_number,
+            current_line_number: 0,
             var_or_env_functions: SeenStatus::DontCare,
             source_map_url: None,
             source_url: None,
@@ -541,7 +536,7 @@ impl SourcePosition {
 /// The line and column number for a given position within the input.
 #[derive(PartialEq, Eq, Debug, Clone, Copy)]
 pub struct SourceLocation {
-    /// The line number, starting at 0 for the first line, unless `with_first_line_number` was used.
+    /// The line number, starting at 0 for the first line.
     pub line: u32,
 
     /// The column number within a line, starting at 1 for first the character of the line.

From d320a8efc868c4c4c551f2ae622952d58c4d64ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Fri, 25 Aug 2023 21:44:07 +0200
Subject: [PATCH 09/38] tokenizer: Source positions are always at char
 boundaries, so avoid overhead when slicing. (#356)

These show up in profiles: https://share.firefox.dev/45Gh2s7
---
 src/tokenizer.rs | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/src/tokenizer.rs b/src/tokenizer.rs
index 02e9dadd..a3b70063 100644
--- a/src/tokenizer.rs
+++ b/src/tokenizer.rs
@@ -269,6 +269,7 @@ impl<'a> Tokenizer<'a> {
 
     #[inline]
     pub fn position(&self) -> SourcePosition {
+        debug_assert!(self.input.is_char_boundary(self.position));
         SourcePosition(self.position)
     }
 
@@ -308,24 +309,26 @@ impl<'a> Tokenizer<'a> {
     }
 
     #[inline]
-    pub fn slice_from(&self, start_pos: SourcePosition) -> &'a str {
-        &self.input[start_pos.0..self.position]
+    pub(crate) fn slice_from(&self, start_pos: SourcePosition) -> &'a str {
+        self.slice(start_pos..self.position())
     }
 
     #[inline]
-    pub fn slice(&self, range: Range<SourcePosition>) -> &'a str {
-        &self.input[range.start.0..range.end.0]
+    pub(crate) fn slice(&self, range: Range<SourcePosition>) -> &'a str {
+        debug_assert!(self.input.is_char_boundary(range.start.0));
+        debug_assert!(self.input.is_char_boundary(range.end.0));
+        unsafe { self.input.get_unchecked(range.start.0..range.end.0) }
     }
 
     pub fn current_source_line(&self) -> &'a str {
-        let current = self.position;
-        let start = self.input[0..current]
+        let current = self.position();
+        let start = self.slice(SourcePosition(0)..current)
             .rfind(|c| matches!(c, '\r' | '\n' | '\x0C'))
             .map_or(0, |start| start + 1);
-        let end = self.input[current..]
+        let end = self.slice(current..SourcePosition(self.input.len()))
             .find(|c| matches!(c, '\r' | '\n' | '\x0C'))
-            .map_or(self.input.len(), |end| current + end);
-        &self.input[start..end]
+            .map_or(self.input.len(), |end| current.0 + end);
+        self.slice(SourcePosition(start)..SourcePosition(end))
     }
 
     #[inline]
@@ -421,7 +424,7 @@ impl<'a> Tokenizer<'a> {
 
     #[inline]
     fn next_char(&self) -> char {
-        self.input[self.position..].chars().next().unwrap()
+        unsafe { self.input.get_unchecked(self.position().0..) }.chars().next().unwrap()
     }
 
     // Given that a newline has been seen, advance over the newline

From 9c53e4f5c591231ac5d4a3ed5983361dc10351db Mon Sep 17 00:00:00 2001
From: Tiaan Louw <tiaanl@gmail.com>
Date: Fri, 1 Sep 2023 10:51:46 +0200
Subject: [PATCH 10/38] Make NumberOrPercentage and AngleOrNumber getters
 public. (#357)

Because the structs are public it only make sense to make the getters
public as well.
---
 src/color.rs | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/color.rs b/src/color.rs
index 6c6ae8e1..477c40eb 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -669,14 +669,17 @@ pub enum NumberOrPercentage {
 }
 
 impl NumberOrPercentage {
-    fn unit_value(&self) -> f32 {
+    /// Return the value as a percentage.
+    pub fn unit_value(&self) -> f32 {
         match *self {
             NumberOrPercentage::Number { value } => value,
             NumberOrPercentage::Percentage { unit_value } => unit_value,
         }
     }
 
-    fn value(&self, percentage_basis: f32) -> f32 {
+    /// Return the value as a number with a percentage adjusted to the
+    /// `percentage_basis`.
+    pub fn value(&self, percentage_basis: f32) -> f32 {
         match *self {
             Self::Number { value } => value,
             Self::Percentage { unit_value } => unit_value * percentage_basis,
@@ -699,7 +702,9 @@ pub enum AngleOrNumber {
 }
 
 impl AngleOrNumber {
-    fn degrees(&self) -> f32 {
+    /// Return the angle in degrees. `AngleOrNumber::Number` is returned as
+    /// degrees, because it is the canonical unit.
+    pub fn degrees(&self) -> f32 {
         match *self {
             AngleOrNumber::Number { value } => value,
             AngleOrNumber::Angle { degrees } => degrees,

From d5631d8ebc15e3990b38f8122bfbea54037556e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Wed, 6 Sep 2023 13:53:19 +0200
Subject: [PATCH 11/38] parser: minor clean-ups.

---
 src/parser.rs                 | 2 +-
 src/rules_and_declarations.rs | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/parser.rs b/src/parser.rs
index ec5eb97e..9c91f523 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -347,7 +347,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
     #[inline]
     pub fn new(input: &'t mut ParserInput<'i>) -> Parser<'i, 't> {
         Parser {
-            input: input,
+            input,
             at_start_of: None,
             stop_before: Delimiter::None,
         }
diff --git a/src/rules_and_declarations.rs b/src/rules_and_declarations.rs
index 34ba8e98..4698561d 100644
--- a/src/rules_and_declarations.rs
+++ b/src/rules_and_declarations.rs
@@ -454,7 +454,7 @@ where
     P: AtRuleParser<'i, Error = E>,
 {
     let delimiters = Delimiter::Semicolon | Delimiter::CurlyBracketBlock;
-    let result = parse_until_before(input, delimiters, |input| parser.parse_prelude(name, input));
+    let result = input.parse_until_before(delimiters, |input| parser.parse_prelude(name, input));
     match result {
         Ok(prelude) => {
             let result = match input.next() {
@@ -488,7 +488,7 @@ fn parse_qualified_rule<'i, 't, P, E>(
 where
     P: QualifiedRuleParser<'i, Error = E>,
 {
-    let prelude = parse_until_before(input, delimiters, |input| parser.parse_prelude(input));
+    let prelude = input.parse_until_before(delimiters, |input| parser.parse_prelude(input));
     input.expect_curly_bracket_block()?;
     // Do this here so that we consume the `{` even if the prelude is `Err`.
     let prelude = prelude?;

From 88134d4a4e28adc557afac858b86a429024fbf60 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Mon, 11 Sep 2023 10:19:37 +0200
Subject: [PATCH 12/38] rules: Avoid tokenizing too much when nesting
 declarations that look like selectors. (#359)

This speeds up the test-case in Mozilla bug 1851814 to be ~5s to ~300ms
on a local opt build.

[1]: https://bugzilla.mozilla.org/show_bug.cgi?id=1851814
---
 src/parser.rs                 | 36 ++++++++++++++++++++++++++++++++---
 src/rules_and_declarations.rs | 23 ++++++++++++++++------
 2 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/src/parser.rs b/src/parser.rs
index 9c91f523..834ccf9a 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -39,6 +39,28 @@ impl ParserState {
     }
 }
 
+/// When parsing until a given token, sometimes the caller knows that parsing is going to restart
+/// at some earlier point, and consuming until we find a top level delimiter is just wasted work.
+///
+/// In that case, callers can pass ParseUntilErrorBehavior::Stop to avoid doing all that wasted
+/// work.
+///
+/// This is important for things like CSS nesting, where something like:
+///
+///   foo:is(..) {
+///     ...
+///   }
+///
+/// Would need to scan the whole {} block to find a semicolon, only for parsing getting restarted
+/// as a qualified rule later.
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum ParseUntilErrorBehavior {
+    /// Consume until we see the relevant delimiter or the end of the stream.
+    Consume,
+    /// Eagerly error.
+    Stop,
+}
+
 /// Details about a `BasicParseError`
 #[derive(Clone, Debug, PartialEq)]
 pub enum BasicParseErrorKind<'i> {
@@ -766,7 +788,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
     where
         F: for<'tt> FnOnce(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>>,
     {
-        parse_until_before(self, delimiters, parse)
+        parse_until_before(self, delimiters, ParseUntilErrorBehavior::Consume, parse)
     }
 
     /// Like `parse_until_before`, but also consume the delimiter token.
@@ -783,7 +805,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
     where
         F: for<'tt> FnOnce(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>>,
     {
-        parse_until_after(self, delimiters, parse)
+        parse_until_after(self, delimiters, ParseUntilErrorBehavior::Consume, parse)
     }
 
     /// Parse a <whitespace-token> and return its value.
@@ -1013,6 +1035,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
 pub fn parse_until_before<'i: 't, 't, F, T, E>(
     parser: &mut Parser<'i, 't>,
     delimiters: Delimiters,
+    error_behavior: ParseUntilErrorBehavior,
     parse: F,
 ) -> Result<T, ParseError<'i, E>>
 where
@@ -1028,6 +1051,9 @@ where
             stop_before: delimiters,
         };
         result = delimited_parser.parse_entirely(parse);
+        if error_behavior == ParseUntilErrorBehavior::Stop && result.is_err() {
+            return result;
+        }
         if let Some(block_type) = delimited_parser.at_start_of {
             consume_until_end_of_block(block_type, &mut delimited_parser.input.tokenizer);
         }
@@ -1051,12 +1077,16 @@ where
 pub fn parse_until_after<'i: 't, 't, F, T, E>(
     parser: &mut Parser<'i, 't>,
     delimiters: Delimiters,
+    error_behavior: ParseUntilErrorBehavior,
     parse: F,
 ) -> Result<T, ParseError<'i, E>>
 where
     F: for<'tt> FnOnce(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>>,
 {
-    let result = parser.parse_until_before(delimiters, parse);
+    let result = parse_until_before(parser, delimiters, error_behavior, parse);
+    if error_behavior == ParseUntilErrorBehavior::Stop && result.is_err() {
+        return result;
+    }
     let next_byte = parser.input.tokenizer.next_byte();
     if next_byte.is_some()
         && !parser
diff --git a/src/rules_and_declarations.rs b/src/rules_and_declarations.rs
index 4698561d..fb33a7d0 100644
--- a/src/rules_and_declarations.rs
+++ b/src/rules_and_declarations.rs
@@ -8,7 +8,7 @@ use super::{
     BasicParseError, BasicParseErrorKind, Delimiter, Delimiters, ParseError, Parser, Token,
 };
 use crate::cow_rc_str::CowRcStr;
-use crate::parser::{parse_nested_block, parse_until_after, parse_until_before, ParserState};
+use crate::parser::{parse_nested_block, parse_until_after, ParseUntilErrorBehavior, ParserState};
 
 /// Parse `!important`.
 ///
@@ -266,14 +266,25 @@ where
                 // that in a slightly more straight-forward way
                 Token::Ident(ref name) if self.parser.parse_declarations() => {
                     let name = name.clone();
+                    let parse_qualified = self.parser.parse_qualified();
                     let result = {
+                        let error_behavior = if parse_qualified {
+                            ParseUntilErrorBehavior::Stop
+                        } else {
+                            ParseUntilErrorBehavior::Consume
+                        };
                         let parser = &mut self.parser;
-                        parse_until_after(self.input, Delimiter::Semicolon, |input| {
-                            input.expect_colon()?;
-                            parser.parse_value(name, input)
-                        })
+                        parse_until_after(
+                            self.input,
+                            Delimiter::Semicolon,
+                            error_behavior,
+                            |input| {
+                                input.expect_colon()?;
+                                parser.parse_value(name, input)
+                            },
+                        )
                     };
-                    if result.is_err() && self.parser.parse_qualified() {
+                    if result.is_err() && parse_qualified {
                         self.input.reset(&start);
                         // We ignore the resulting error here. The property declaration parse error
                         // is likely to be more relevant.

From c97ba60e95090274307f24dbaee7bc737361d667 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Mon, 11 Sep 2023 10:28:44 +0200
Subject: [PATCH 13/38] serializer: Use match_byte in the serializer. (#361)

---
 src/serializer.rs | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/src/serializer.rs b/src/serializer.rs
index ec970d17..19f01456 100644
--- a/src/serializer.rs
+++ b/src/serializer.rs
@@ -2,6 +2,7 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+use crate::match_byte;
 use dtoa_short::{self, Notation};
 use itoa;
 use std::fmt::{self, Write};
@@ -226,11 +227,15 @@ where
 {
     let mut chunk_start = 0;
     for (i, b) in value.bytes().enumerate() {
-        let escaped = match b {
+        let escaped = match_byte! { b,
             b'0'..=b'9' | b'A'..=b'Z' | b'a'..=b'z' | b'_' | b'-' => continue,
-            _ if !b.is_ascii() => continue,
             b'\0' => Some("\u{FFFD}"),
-            _ => None,
+            b => {
+                if !b.is_ascii() {
+                    continue;
+                }
+                None
+            },
         };
         dest.write_str(&value[chunk_start..i])?;
         if let Some(escaped) = escaped {
@@ -251,7 +256,7 @@ where
 {
     let mut chunk_start = 0;
     for (i, b) in value.bytes().enumerate() {
-        let hex = match b {
+        let hex = match_byte! { b,
             b'\0'..=b' ' | b'\x7F' => true,
             b'(' | b')' | b'"' | b'\'' | b'\\' => false,
             _ => continue,
@@ -304,7 +309,7 @@ where
 {
     /// Wrap a text writer to create a `CssStringWriter`.
     pub fn new(inner: &'a mut W) -> CssStringWriter<'a, W> {
-        CssStringWriter { inner: inner }
+        CssStringWriter { inner }
     }
 }
 
@@ -315,7 +320,7 @@ where
     fn write_str(&mut self, s: &str) -> fmt::Result {
         let mut chunk_start = 0;
         for (i, b) in s.bytes().enumerate() {
-            let escaped = match b {
+            let escaped = match_byte! { b,
                 b'"' => Some("\\\""),
                 b'\\' => Some("\\\\"),
                 b'\0' => Some("\u{FFFD}"),

From 1ccc5779680bb777d1d7595ebdd62a0ba81f2aa8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Mon, 11 Sep 2023 10:35:42 +0200
Subject: [PATCH 14/38] parser: Use a lookup table for Delimiter::from_byte.
 (#358)

* parser: Use a lookup table for Delimiter::from_byte.

It's faster.

* tests: Add a benchmark for Delimiters::from_byte
---
 src/parser.rs | 24 +++++++++++++++---------
 src/tests.rs  | 14 +++++++++++++-
 2 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/src/parser.rs b/src/parser.rs
index 834ccf9a..dd7777a2 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -335,16 +335,22 @@ impl Delimiters {
     }
 
     #[inline]
-    fn from_byte(byte: Option<u8>) -> Delimiters {
+    pub(crate) fn from_byte(byte: Option<u8>) -> Delimiters {
+        const TABLE: [Delimiters; 256] = {
+            let mut table = [Delimiter::None; 256];
+            table[b';' as usize] = Delimiter::Semicolon;
+            table[b'!' as usize] = Delimiter::Bang;
+            table[b',' as usize] = Delimiter::Comma;
+            table[b'{' as usize] = Delimiter::CurlyBracketBlock;
+            table[b'}' as usize] = ClosingDelimiter::CloseCurlyBracket;
+            table[b']' as usize] = ClosingDelimiter::CloseSquareBracket;
+            table[b')' as usize] = ClosingDelimiter::CloseParenthesis;
+            table
+        };
+
         match byte {
-            Some(b';') => Delimiter::Semicolon,
-            Some(b'!') => Delimiter::Bang,
-            Some(b',') => Delimiter::Comma,
-            Some(b'{') => Delimiter::CurlyBracketBlock,
-            Some(b'}') => ClosingDelimiter::CloseCurlyBracket,
-            Some(b']') => ClosingDelimiter::CloseSquareBracket,
-            Some(b')') => ClosingDelimiter::CloseParenthesis,
-            _ => Delimiter::None,
+            None => Delimiter::None,
+            Some(b) => TABLE[b as usize],
         }
     }
 }
diff --git a/src/tests.rs b/src/tests.rs
index 8dbee8a7..ae17bd81 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -9,7 +9,7 @@ use encoding_rs;
 use serde_json::{self, json, Map, Value};
 
 use crate::color::{parse_color_with, FromParsedColor};
-use crate::{ColorParser, PredefinedColorSpace};
+use crate::{ColorParser, PredefinedColorSpace, Delimiters};
 
 #[cfg(feature = "bench")]
 use self::test::Bencher;
@@ -922,6 +922,18 @@ impl<'a> ToJson for CowRcStr<'a> {
     }
 }
 
+#[bench]
+#[cfg(feature = "bench")]
+fn delimiter_from_byte(b: &mut Bencher) {
+    b.iter(|| {
+        for _ in 0..1000 {
+            for i in 0..256 {
+                std::hint::black_box(Delimiters::from_byte(Some(i as u8)));
+            }
+        }
+    })
+}
+
 #[cfg(feature = "bench")]
 const BACKGROUND_IMAGE: &'static str = include_str!("big-data-url.css");
 

From eecbe57d68b969199f4d065d58a72b9b0161adec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Mon, 11 Sep 2023 14:28:48 +0200
Subject: [PATCH 15/38] Remove procedural-masquerade. (#362)

This crate is unused now that we have real proc macros.
---
 Cargo.toml                           |   2 +-
 procedural-masquerade/Cargo.toml     |  12 --
 procedural-masquerade/LICENSE-APACHE | 201 -------------------
 procedural-masquerade/LICENSE-MIT    |  25 ---
 procedural-masquerade/lib.rs         | 286 ---------------------------
 5 files changed, 1 insertion(+), 525 deletions(-)
 delete mode 100644 procedural-masquerade/Cargo.toml
 delete mode 100644 procedural-masquerade/LICENSE-APACHE
 delete mode 100644 procedural-masquerade/LICENSE-MIT
 delete mode 100644 procedural-masquerade/lib.rs

diff --git a/Cargo.toml b/Cargo.toml
index d322168c..4dc608d7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -34,4 +34,4 @@ dummy_match_byte = []
 skip_long_tests = []
 
 [workspace]
-members = [".", "./macros", "./procedural-masquerade"]
+members = [".", "./macros"]
diff --git a/procedural-masquerade/Cargo.toml b/procedural-masquerade/Cargo.toml
deleted file mode 100644
index 66638a31..00000000
--- a/procedural-masquerade/Cargo.toml
+++ /dev/null
@@ -1,12 +0,0 @@
-[package]
-name = "procedural-masquerade"
-version = "0.1.7"
-authors = ["Simon Sapin <simon.sapin@exyr.org>"]
-description = "macro_rules for making proc_macro_derive pretending to be proc_macro"
-documentation = "https://docs.rs/procedural-masquerade/"
-repository = "https://github.com/servo/rust-cssparser"
-license = "MIT OR Apache-2.0"
-
-[lib]
-path = "lib.rs"
-doctest = false
diff --git a/procedural-masquerade/LICENSE-APACHE b/procedural-masquerade/LICENSE-APACHE
deleted file mode 100644
index 16fe87b0..00000000
--- a/procedural-masquerade/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
-                              Apache License
-                        Version 2.0, January 2004
-                     http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
-   "License" shall mean the terms and conditions for use, reproduction,
-   and distribution as defined by Sections 1 through 9 of this document.
-
-   "Licensor" shall mean the copyright owner or entity authorized by
-   the copyright owner that is granting the License.
-
-   "Legal Entity" shall mean the union of the acting entity and all
-   other entities that control, are controlled by, or are under common
-   control with that entity. For the purposes of this definition,
-   "control" means (i) the power, direct or indirect, to cause the
-   direction or management of such entity, whether by contract or
-   otherwise, or (ii) ownership of fifty percent (50%) or more of the
-   outstanding shares, or (iii) beneficial ownership of such entity.
-
-   "You" (or "Your") shall mean an individual or Legal Entity
-   exercising permissions granted by this License.
-
-   "Source" form shall mean the preferred form for making modifications,
-   including but not limited to software source code, documentation
-   source, and configuration files.
-
-   "Object" form shall mean any form resulting from mechanical
-   transformation or translation of a Source form, including but
-   not limited to compiled object code, generated documentation,
-   and conversions to other media types.
-
-   "Work" shall mean the work of authorship, whether in Source or
-   Object form, made available under the License, as indicated by a
-   copyright notice that is included in or attached to the work
-   (an example is provided in the Appendix below).
-
-   "Derivative Works" shall mean any work, whether in Source or Object
-   form, that is based on (or derived from) the Work and for which the
-   editorial revisions, annotations, elaborations, or other modifications
-   represent, as a whole, an original work of authorship. For the purposes
-   of this License, Derivative Works shall not include works that remain
-   separable from, or merely link (or bind by name) to the interfaces of,
-   the Work and Derivative Works thereof.
-
-   "Contribution" shall mean any work of authorship, including
-   the original version of the Work and any modifications or additions
-   to that Work or Derivative Works thereof, that is intentionally
-   submitted to Licensor for inclusion in the Work by the copyright owner
-   or by an individual or Legal Entity authorized to submit on behalf of
-   the copyright owner. For the purposes of this definition, "submitted"
-   means any form of electronic, verbal, or written communication sent
-   to the Licensor or its representatives, including but not limited to
-   communication on electronic mailing lists, source code control systems,
-   and issue tracking systems that are managed by, or on behalf of, the
-   Licensor for the purpose of discussing and improving the Work, but
-   excluding communication that is conspicuously marked or otherwise
-   designated in writing by the copyright owner as "Not a Contribution."
-
-   "Contributor" shall mean Licensor and any individual or Legal Entity
-   on behalf of whom a Contribution has been received by Licensor and
-   subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
-   this License, each Contributor hereby grants to You a perpetual,
-   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-   copyright license to reproduce, prepare Derivative Works of,
-   publicly display, publicly perform, sublicense, and distribute the
-   Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
-   this License, each Contributor hereby grants to You a perpetual,
-   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-   (except as stated in this section) patent license to make, have made,
-   use, offer to sell, sell, import, and otherwise transfer the Work,
-   where such license applies only to those patent claims licensable
-   by such Contributor that are necessarily infringed by their
-   Contribution(s) alone or by combination of their Contribution(s)
-   with the Work to which such Contribution(s) was submitted. If You
-   institute patent litigation against any entity (including a
-   cross-claim or counterclaim in a lawsuit) alleging that the Work
-   or a Contribution incorporated within the Work constitutes direct
-   or contributory patent infringement, then any patent licenses
-   granted to You under this License for that Work shall terminate
-   as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
-   Work or Derivative Works thereof in any medium, with or without
-   modifications, and in Source or Object form, provided that You
-   meet the following conditions:
-
-   (a) You must give any other recipients of the Work or
-       Derivative Works a copy of this License; and
-
-   (b) You must cause any modified files to carry prominent notices
-       stating that You changed the files; and
-
-   (c) You must retain, in the Source form of any Derivative Works
-       that You distribute, all copyright, patent, trademark, and
-       attribution notices from the Source form of the Work,
-       excluding those notices that do not pertain to any part of
-       the Derivative Works; and
-
-   (d) If the Work includes a "NOTICE" text file as part of its
-       distribution, then any Derivative Works that You distribute must
-       include a readable copy of the attribution notices contained
-       within such NOTICE file, excluding those notices that do not
-       pertain to any part of the Derivative Works, in at least one
-       of the following places: within a NOTICE text file distributed
-       as part of the Derivative Works; within the Source form or
-       documentation, if provided along with the Derivative Works; or,
-       within a display generated by the Derivative Works, if and
-       wherever such third-party notices normally appear. The contents
-       of the NOTICE file are for informational purposes only and
-       do not modify the License. You may add Your own attribution
-       notices within Derivative Works that You distribute, alongside
-       or as an addendum to the NOTICE text from the Work, provided
-       that such additional attribution notices cannot be construed
-       as modifying the License.
-
-   You may add Your own copyright statement to Your modifications and
-   may provide additional or different license terms and conditions
-   for use, reproduction, or distribution of Your modifications, or
-   for any such Derivative Works as a whole, provided Your use,
-   reproduction, and distribution of the Work otherwise complies with
-   the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
-   any Contribution intentionally submitted for inclusion in the Work
-   by You to the Licensor shall be under the terms and conditions of
-   this License, without any additional terms or conditions.
-   Notwithstanding the above, nothing herein shall supersede or modify
-   the terms of any separate license agreement you may have executed
-   with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
-   names, trademarks, service marks, or product names of the Licensor,
-   except as required for reasonable and customary use in describing the
-   origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
-   agreed to in writing, Licensor provides the Work (and each
-   Contributor provides its Contributions) on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-   implied, including, without limitation, any warranties or conditions
-   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-   PARTICULAR PURPOSE. You are solely responsible for determining the
-   appropriateness of using or redistributing the Work and assume any
-   risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
-   whether in tort (including negligence), contract, or otherwise,
-   unless required by applicable law (such as deliberate and grossly
-   negligent acts) or agreed to in writing, shall any Contributor be
-   liable to You for damages, including any direct, indirect, special,
-   incidental, or consequential damages of any character arising as a
-   result of this License or out of the use or inability to use the
-   Work (including but not limited to damages for loss of goodwill,
-   work stoppage, computer failure or malfunction, or any and all
-   other commercial damages or losses), even if such Contributor
-   has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
-   the Work or Derivative Works thereof, You may choose to offer,
-   and charge a fee for, acceptance of support, warranty, indemnity,
-   or other liability obligations and/or rights consistent with this
-   License. However, in accepting such obligations, You may act only
-   on Your own behalf and on Your sole responsibility, not on behalf
-   of any other Contributor, and only if You agree to indemnify,
-   defend, and hold each Contributor harmless for any liability
-   incurred by, or claims asserted against, such Contributor by reason
-   of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
-   To apply the Apache License to your work, attach the following
-   boilerplate notice, with the fields enclosed by brackets "[]"
-   replaced with your own identifying information. (Don't include
-   the brackets!)  The text should be enclosed in the appropriate
-   comment syntax for the file format. We also recommend that a
-   file or class name and description of purpose be included on the
-   same "printed page" as the copyright notice for easier
-   identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/procedural-masquerade/LICENSE-MIT b/procedural-masquerade/LICENSE-MIT
deleted file mode 100644
index 72585696..00000000
--- a/procedural-masquerade/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c)
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/procedural-masquerade/lib.rs b/procedural-masquerade/lib.rs
deleted file mode 100644
index 85b61c6e..00000000
--- a/procedural-masquerade/lib.rs
+++ /dev/null
@@ -1,286 +0,0 @@
-//! # Custom `derive` pretending to be functional procedural macros on Rust 1.15
-//!
-//! This crate enables creating function-like macros (invoked as `foo!(...)`)
-//! with a procedural component,
-//! based on both custom `derive` (a.k.a. *Macros 1.1*) and `macro_rules!`.
-//!
-//! This convoluted mechanism enables such macros to run on stable Rust 1.15,
-//! even though functional procedural macros (a.k.a. *Macros 2.0*) are not available yet.
-//!
-//! A library defining such a macro needs two crates: a “normal” one, and a `proc-macro` one.
-//! In the example below we’ll call them `libfoo` and `libfoo-macros`, respectively.
-//!
-//! # Credits
-//!
-//! The trick that makes this crate work
-//! is based on an idea from [David Tolnay](https://github.com/dtolnay).
-//! Many thanks!
-//!
-//! # Example
-//!
-//! As a simple example, we’re going to re-implement the `stringify!` macro.
-//! This is useless since `stringify!` already exists in the standard library,
-//! and a bit absurd since this crate uses `stringify!` internally.
-//!
-//! Nevertheless, it serves as a simple example to demonstrate the use of this crate.
-//!
-//! ## The `proc-macro` crate
-//!
-//! The minimal `Cargo.toml` file is typical for Macros 1.1:
-//!
-//! ```toml
-//! [package]
-//! name = "libfoo-macros"
-//! version = "1.0.0"
-//!
-//! [lib]
-//! proc-macro = true
-//! ```
-//!
-//! In the code, we define the procedural part of our macro in a function.
-//! This function will not be used directly by end users,
-//! but it still needs to be re-exported to them
-//! (because of limitations in `macro_rules!`).
-//!
-//! To avoid name collisions, we include a long and explicit prefix in the function’s name.
-//!
-//! The function takes a string containing arbitrary Rust tokens,
-//! and returns a string that is parsed as *items*.
-//! The returned string can contain constants, statics, functions, `impl`s, etc.,
-//! but not expressions directly.
-//!
-//! ```rust
-//! #[macro_use] extern crate procedural_masquerade;
-//! extern crate proc_macro;
-//!
-//! define_proc_macros! {
-//!     #[allow(non_snake_case)]
-//!     pub fn foo_internal__stringify_const(input: &str) -> String {
-//!         format!("const STRINGIFIED: &'static str = {:?};", input)
-//!     }
-//! }
-//! ```
-//!
-//! A less trivial macro would probably use
-//! the [`syn`](https://github.com/dtolnay/syn/) crate to parse its input
-//! and the [`quote`](https://github.com/dtolnay/quote) crate to generate its output.
-//!
-//! ## The library crate
-//!
-//! ```toml
-//! [package]
-//! name = "libfoo"
-//! version = "1.0.0"
-//!
-//! [dependencies]
-//! libfoo-macros = {path = "./macros", version = "1.0"}
-//! ```
-//!
-//! ```rust
-//! #[macro_use] extern crate libfoo_macros;  // (1)
-//!
-//! pub use libfoo_macros::*;  // (2)
-//!
-//! define_invoke_proc_macro!(libfoo__invoke_proc_macro);  // (3)
-//!
-//! #[macro_export]
-//! macro_rules! foo_stringify {  // (4)
-//!     ( $( $tts: tt ) ) => {
-//!         {  // (5)
-//!             libfoo__invoke_proc_macro! {  // (6)
-//!                 foo_internal__stringify_const!( $( $tts ) )  // (7)
-//!             }
-//!             STRINGIFIED  // (8)
-//!         }
-//!     }
-//! }
-//! ```
-//!
-//! Let’s go trough the numbered lines one by one:
-//!
-//! 1. `libfoo` depends on `libfoo-macros`, and imports its macros.
-//! 2. Everything exported by `libfoo-macros` (which is one custom `derive`)
-//!    is re-exported to users of `libfoo`.
-//!    They’re not expected to use it directly,
-//!    but expansion of the `foo_stringify` macro needs it.
-//! 3. This macro invocation defines yet another macro, called `libfoo__invoke_proc_macro`,
-//!    which is also exported.
-//!    This indirection is necessary
-//!    because re-exporting `macro_rules!` macros doesn’t work currently,
-//!    and once again it is used by the expansion of `foo_stringify`.
-//!    Again, we use a long prefix to avoid name collisions.
-//! 4. Finally, we define the macro that we really want.
-//!    This one has a name that users will use.
-//! 5. The expansion of this macro will define some items,
-//!    whose names are not hygienic in `macro_rules`.
-//!    So we wrap everything in an extra `{…}` block to prevent these names for leaking.
-//! 6. Here we use the macro defined in (3),
-//!    which allows us to write something that look like invoking a functional procedural macro,
-//!    but really uses a custom `derive`.
-//!    This will define a type called `ProceduralMasqueradeDummyType`,
-//!    as a placeholder to use `derive`.
-//!    If `libfoo__invoke_proc_macro!` is to be used more than once,
-//!    each use needs to be nested in another block
-//!    so that the names of multiple dummy types don’t collide.
-//! 7. In addition to the dummy type,
-//!    the items returned by our procedural component are inserted here.
-//!    (In this case the `STRINGIFIED` constant.)
-//! 8. Finally, we write the expression that we want the macro to evaluate to.
-//!    This expression can use parts of `foo_stringify`’s input,
-//!    it can contain control-flow statements like `return` or `continue`,
-//!    and of course refer to procedurally-defined items.
-//!
-//! This macro can be used in an expression context.
-//! It expands to a block-expression that contains some items (as an implementation detail)
-//! and ends with another expression.
-//!
-//! ## For users
-//!
-//! Users of `libfoo` don’t need to worry about any of these implementation details.
-//! They can use the `foo_stringify` macro as if it were a simple `macro_rules` macro:
-//!
-//! ```rust
-//! #[macro_use] extern crate libfoo;
-//!
-//! fn main() {
-//!     do_something(foo_stringify!(1 + 2));
-//! }
-//!
-//! fn do_something(_: &str) { /* ... */ }
-//! ```
-//!
-//! # More
-//!
-//! To see a more complex example, look at
-//! [`cssparser`’s `src/macros.rs`](https://github.com/servo/rust-cssparser/blob/master/src/macros.rs)
-//! and
-//! [`cssparser-macros`’s `macros/lib.rs`](https://github.com/servo/rust-cssparser/blob/master/macros/lib.rs).
-
-/// This macro wraps `&str -> String` functions
-/// in custom `derive` implementations with `#[proc_macro_derive]`.
-///
-/// See crate documentation for details.
-#[macro_export]
-macro_rules! define_proc_macros {
-    (
-        $(
-            $( #[$attr:meta] )*
-            pub fn $proc_macro_name: ident ($input: ident : &str) -> String
-            $body: block
-        )+
-    ) => {
-        $(
-            $( #[$attr] )*
-            #[proc_macro_derive($proc_macro_name)]
-            pub fn $proc_macro_name(derive_input: ::proc_macro::TokenStream)
-                                    -> ::proc_macro::TokenStream {
-                fn wrapped($input: &str) -> String {
-                    $body
-                }
-
-                // syn uses a huge amount of stack in debug mode.
-                let derive_input_string = derive_input.to_string();
-                let handle =
-                    ::std::thread::Builder::new().stack_size(128 * 1024 * 1024).spawn(move || {
-                        wrapped($crate::_extract_input(&derive_input_string))
-                    }).unwrap();
-
-                handle.join().unwrap().parse().unwrap()
-            }
-        )+
-    }
-}
-
-/// Implementation detail of `define_proc_macros!`.
-///
-/// **This function is not part of the public API. It can change or be removed between any versions.**
-#[doc(hidden)]
-pub fn _extract_input(derive_input: &str) -> &str {
-    let mut input = derive_input;
-
-    for expected in &[
-        "#",
-        "[",
-        "allow",
-        "(",
-        "unused",
-        ")",
-        "]",
-        "enum",
-        "ProceduralMasqueradeDummyType",
-        "{",
-        "Input",
-        "=",
-        "(",
-        "0",
-        ",",
-        "stringify",
-        "!",
-        "(",
-    ] {
-        input = input.trim_start();
-        assert!(
-            input.starts_with(expected),
-            "expected prefix {:?} not found in {:?}",
-            expected,
-            derive_input
-        );
-        input = &input[expected.len()..];
-    }
-
-    for expected in [")", ")", ".", "0", ",", "}"].iter().rev() {
-        input = input.trim_end();
-        assert!(
-            input.ends_with(expected),
-            "expected suffix {:?} not found in {:?}",
-            expected,
-            derive_input
-        );
-        let end = input.len() - expected.len();
-        input = &input[..end];
-    }
-
-    input
-}
-
-/// This macro expands to the definition of another macro (whose name is given as a parameter).
-///
-/// See crate documentation for details.
-#[macro_export]
-macro_rules! define_invoke_proc_macro {
-    ($macro_name: ident) => {
-        /// Implementation detail of other macros in this crate.
-        #![rustfmt::skip]
-        #[doc(hidden)]
-        #[macro_export]
-        macro_rules! $macro_name {
-            ($proc_macro_name: ident ! $paren: tt) => {
-                #[derive($proc_macro_name)]
-                #[allow(unused)]
-                enum ProceduralMasqueradeDummyType {
-                    // The magic happens here.
-                    //
-                    // We use an `enum` with an explicit discriminant
-                    // because that is the only case where a type definition
-                    // can contain a (const) expression.
-                    //
-                    // `(0, "foo").0` evaluates to 0, with the `"foo"` part ignored.
-                    //
-                    // By the time the `#[proc_macro_derive]` function
-                    // implementing `#[derive($proc_macro_name)]` is called,
-                    // `$paren` has already been replaced with the input of this inner macro,
-                    // but `stringify!` has not been expanded yet.
-                    //
-                    // This how arbitrary tokens can be inserted
-                    // in the input to the `#[proc_macro_derive]` function.
-                    //
-                    // Later, `stringify!(...)` is expanded into a string literal
-                    // which is then ignored.
-                    // Using `stringify!` enables passing arbitrary tokens
-                    // rather than only what can be parsed as a const expression.
-                    Input = (0, stringify! $paren ).0,
-                }
-            }
-        }
-    };
-}

From b4522c6b8dc242b99c6e9c08c7c10298ef69e96b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Mon, 11 Sep 2023 15:16:49 +0200
Subject: [PATCH 16/38] color: Split most of the color parsing to a separate
 crate. (#363)

---
 .github/workflows/main.yml |    8 +
 Cargo.toml                 |    2 +-
 color/Cargo.toml           |   20 +
 color/lib.rs               | 1304 +++++++++++++++++++++++++++++++++
 color/tests.rs             |  401 +++++++++++
 src/color.rs               | 1400 ++----------------------------------
 src/lib.rs                 |    8 +-
 src/tests.rs               |  301 +-------
 8 files changed, 1790 insertions(+), 1654 deletions(-)
 create mode 100644 color/Cargo.toml
 create mode 100644 color/lib.rs
 create mode 100644 color/tests.rs

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 49e91ad3..0d3c0229 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -51,6 +51,14 @@ jobs:
         run: cargo build
         working-directory: macros
 
+      - name: Color build
+        run: cargo build
+        working-directory: color
+
+      - name: Color test
+        run: cargo test
+        working-directory: color
+
       - name: Cargo miri test
         if: "matrix.toolchain == 'nightly'"
         run: cargo miri test --features skip_long_tests ${{ matrix.features }}
diff --git a/Cargo.toml b/Cargo.toml
index 4dc608d7..aae87dcf 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -34,4 +34,4 @@ dummy_match_byte = []
 skip_long_tests = []
 
 [workspace]
-members = [".", "./macros"]
+members = [".", "./macros", "./color"]
diff --git a/color/Cargo.toml b/color/Cargo.toml
new file mode 100644
index 00000000..d3201a12
--- /dev/null
+++ b/color/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "cssparser-color"
+version = "0.1.0"
+authors = ["Emilio Cobos Álvarez <emilio@crisal.io>"]
+description = "Color implementation based on cssparser"
+documentation = "https://docs.rs/cssparser-color/"
+repository = "https://github.com/servo/rust-cssparser"
+license = "MPL-2.0"
+edition = "2021"
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+cssparser = { path = ".." }
+
+[dev-dependencies]
+serde_json = "1.0"
+difference = "2.0"
+encoding_rs = "0.8"
diff --git a/color/lib.rs b/color/lib.rs
new file mode 100644
index 00000000..1c52e38d
--- /dev/null
+++ b/color/lib.rs
@@ -0,0 +1,1304 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#![deny(missing_docs)]
+
+//! Fairly complete css-color implementation.
+//! Relative colors, color-mix, system colors, and other such things require better calc() support
+//! and integration.
+
+#[cfg(test)]
+mod tests;
+
+use cssparser::color::{
+    clamp_floor_256_f32, clamp_unit_f32, parse_hash_color, serialize_color_alpha,
+    PredefinedColorSpace, OPAQUE,
+};
+use cssparser::{match_ignore_ascii_case, CowRcStr, ParseError, Parser, ToCss, Token};
+#[cfg(feature = "serde")]
+use serde::{Deserialize, Deserializer, Serialize, Serializer};
+use std::f32::consts::PI;
+use std::fmt;
+use std::str::FromStr;
+
+/// Return the named color with the given name.
+///
+/// Matching is case-insensitive in the ASCII range.
+/// CSS escaping (if relevant) should be resolved before calling this function.
+/// (For example, the value of an `Ident` token is fine.)
+#[inline]
+pub fn parse_color_keyword<Output>(ident: &str) -> Result<Output, ()>
+where
+    Output: FromParsedColor,
+{
+    Ok(match_ignore_ascii_case! { ident ,
+        "transparent" => Output::from_rgba(0, 0, 0, 0.0),
+        "currentcolor" => Output::from_current_color(),
+        _ => {
+            let (r, g, b) = cssparser::color::parse_named_color(ident)?;
+            Output::from_rgba(r, g, b, OPAQUE)
+        }
+    })
+}
+
+/// Parse a CSS color using the specified [`ColorParser`] and return a new color
+/// value on success.
+pub fn parse_color_with<'i, 't, P>(
+    color_parser: &P,
+    input: &mut Parser<'i, 't>,
+) -> Result<P::Output, ParseError<'i, P::Error>>
+where
+    P: ColorParser<'i>,
+{
+    let location = input.current_source_location();
+    let token = input.next()?;
+    match *token {
+        Token::Hash(ref value) | Token::IDHash(ref value) => {
+            parse_hash_color(value.as_bytes()).map(|(r, g, b, a)| {
+                P::Output::from_rgba(r, g, b, a)
+            })
+        },
+        Token::Ident(ref value) => parse_color_keyword(value),
+        Token::Function(ref name) => {
+            let name = name.clone();
+            return input.parse_nested_block(|arguments| {
+                parse_color_function(color_parser, name, arguments)
+            });
+        }
+        _ => Err(()),
+    }
+    .map_err(|()| location.new_unexpected_token_error(token.clone()))
+}
+
+/// Parse one of the color functions: rgba(), lab(), color(), etc.
+#[inline]
+fn parse_color_function<'i, 't, P>(
+    color_parser: &P,
+    name: CowRcStr<'i>,
+    arguments: &mut Parser<'i, 't>,
+) -> Result<P::Output, ParseError<'i, P::Error>>
+where
+    P: ColorParser<'i>,
+{
+    let color = match_ignore_ascii_case! { &name,
+        "rgb" | "rgba" => parse_rgb(color_parser, arguments),
+
+        "hsl" | "hsla" => parse_hsl(color_parser, arguments),
+
+        "hwb" => parse_hwb(color_parser, arguments),
+
+        // for L: 0% = 0.0, 100% = 100.0
+        // for a and b: -100% = -125, 100% = 125
+        "lab" => parse_lab_like(color_parser, arguments, 100.0, 125.0, P::Output::from_lab),
+
+        // for L: 0% = 0.0, 100% = 100.0
+        // for C: 0% = 0, 100% = 150
+        "lch" => parse_lch_like(color_parser, arguments, 100.0, 150.0, P::Output::from_lch),
+
+        // for L: 0% = 0.0, 100% = 1.0
+        // for a and b: -100% = -0.4, 100% = 0.4
+        "oklab" => parse_lab_like(color_parser, arguments, 1.0, 0.4, P::Output::from_oklab),
+
+        // for L: 0% = 0.0, 100% = 1.0
+        // for C: 0% = 0.0 100% = 0.4
+        "oklch" => parse_lch_like(color_parser, arguments, 1.0, 0.4, P::Output::from_oklch),
+
+        "color" => parse_color_with_color_space(color_parser, arguments),
+
+        _ => return Err(arguments.new_unexpected_token_error(Token::Ident(name))),
+    }?;
+
+    arguments.expect_exhausted()?;
+
+    Ok(color)
+}
+
+/// Parse the alpha component by itself from either number or percentage,
+/// clipping the result to [0.0..1.0].
+#[inline]
+fn parse_alpha_component<'i, 't, P>(
+    color_parser: &P,
+    arguments: &mut Parser<'i, 't>,
+) -> Result<f32, ParseError<'i, P::Error>>
+where
+    P: ColorParser<'i>,
+{
+    Ok(color_parser
+        .parse_number_or_percentage(arguments)?
+        .unit_value()
+        .clamp(0.0, OPAQUE))
+}
+
+fn parse_legacy_alpha<'i, 't, P>(
+    color_parser: &P,
+    arguments: &mut Parser<'i, 't>,
+) -> Result<f32, ParseError<'i, P::Error>>
+where
+    P: ColorParser<'i>,
+{
+    Ok(if !arguments.is_exhausted() {
+        arguments.expect_comma()?;
+        parse_alpha_component(color_parser, arguments)?
+    } else {
+        OPAQUE
+    })
+}
+
+fn parse_modern_alpha<'i, 't, P>(
+    color_parser: &P,
+    arguments: &mut Parser<'i, 't>,
+) -> Result<Option<f32>, ParseError<'i, P::Error>>
+where
+    P: ColorParser<'i>,
+{
+    if !arguments.is_exhausted() {
+        arguments.expect_delim('/')?;
+        parse_none_or(arguments, |p| parse_alpha_component(color_parser, p))
+    } else {
+        Ok(Some(OPAQUE))
+    }
+}
+
+#[inline]
+fn parse_rgb<'i, 't, P>(
+    color_parser: &P,
+    arguments: &mut Parser<'i, 't>,
+) -> Result<P::Output, ParseError<'i, P::Error>>
+where
+    P: ColorParser<'i>,
+{
+    let maybe_red = parse_none_or(arguments, |p| color_parser.parse_number_or_percentage(p))?;
+
+    // If the first component is not "none" and is followed by a comma, then we
+    // are parsing the legacy syntax.
+    let is_legacy_syntax = maybe_red.is_some() && arguments.try_parse(|p| p.expect_comma()).is_ok();
+
+    let (red, green, blue, alpha) = if is_legacy_syntax {
+        let (red, green, blue) = match maybe_red.unwrap() {
+            NumberOrPercentage::Number { value } => {
+                let red = clamp_floor_256_f32(value);
+                let green = clamp_floor_256_f32(color_parser.parse_number(arguments)?);
+                arguments.expect_comma()?;
+                let blue = clamp_floor_256_f32(color_parser.parse_number(arguments)?);
+                (red, green, blue)
+            }
+            NumberOrPercentage::Percentage { unit_value } => {
+                let red = clamp_unit_f32(unit_value);
+                let green = clamp_unit_f32(color_parser.parse_percentage(arguments)?);
+                arguments.expect_comma()?;
+                let blue = clamp_unit_f32(color_parser.parse_percentage(arguments)?);
+                (red, green, blue)
+            }
+        };
+
+        let alpha = parse_legacy_alpha(color_parser, arguments)?;
+
+        (red, green, blue, alpha)
+    } else {
+        #[inline]
+        fn get_component_value(c: Option<NumberOrPercentage>) -> u8 {
+            c.map(|c| match c {
+                NumberOrPercentage::Number { value } => clamp_floor_256_f32(value),
+                NumberOrPercentage::Percentage { unit_value } => clamp_unit_f32(unit_value),
+            })
+            .unwrap_or(0)
+        }
+
+        let red = get_component_value(maybe_red);
+
+        let green = get_component_value(parse_none_or(arguments, |p| {
+            color_parser.parse_number_or_percentage(p)
+        })?);
+
+        let blue = get_component_value(parse_none_or(arguments, |p| {
+            color_parser.parse_number_or_percentage(p)
+        })?);
+
+        let alpha = parse_modern_alpha(color_parser, arguments)?.unwrap_or(0.0);
+
+        (red, green, blue, alpha)
+    };
+
+    Ok(P::Output::from_rgba(red, green, blue, alpha))
+}
+
+/// Parses hsl syntax.
+///
+/// <https://drafts.csswg.org/css-color/#the-hsl-notation>
+#[inline]
+fn parse_hsl<'i, 't, P>(
+    color_parser: &P,
+    arguments: &mut Parser<'i, 't>,
+) -> Result<P::Output, ParseError<'i, P::Error>>
+where
+    P: ColorParser<'i>,
+{
+    let maybe_hue = parse_none_or(arguments, |p| color_parser.parse_angle_or_number(p))?;
+
+    // If the hue is not "none" and is followed by a comma, then we are parsing
+    // the legacy syntax.
+    let is_legacy_syntax = maybe_hue.is_some() && arguments.try_parse(|p| p.expect_comma()).is_ok();
+
+    let saturation: Option<f32>;
+    let lightness: Option<f32>;
+
+    let alpha = if is_legacy_syntax {
+        saturation = Some(color_parser.parse_percentage(arguments)?);
+        arguments.expect_comma()?;
+        lightness = Some(color_parser.parse_percentage(arguments)?);
+        Some(parse_legacy_alpha(color_parser, arguments)?)
+    } else {
+        saturation = parse_none_or(arguments, |p| color_parser.parse_percentage(p))?;
+        lightness = parse_none_or(arguments, |p| color_parser.parse_percentage(p))?;
+
+        parse_modern_alpha(color_parser, arguments)?
+    };
+
+    let hue = maybe_hue.map(|h| normalize_hue(h.degrees()));
+    let saturation = saturation.map(|s| s.clamp(0.0, 1.0));
+    let lightness = lightness.map(|l| l.clamp(0.0, 1.0));
+
+    Ok(P::Output::from_hsl(hue, saturation, lightness, alpha))
+}
+
+/// Parses hwb syntax.
+///
+/// <https://drafts.csswg.org/css-color/#the-hbw-notation>
+#[inline]
+fn parse_hwb<'i, 't, P>(
+    color_parser: &P,
+    arguments: &mut Parser<'i, 't>,
+) -> Result<P::Output, ParseError<'i, P::Error>>
+where
+    P: ColorParser<'i>,
+{
+    let (hue, whiteness, blackness, alpha) = parse_components(
+        color_parser,
+        arguments,
+        P::parse_angle_or_number,
+        P::parse_percentage,
+        P::parse_percentage,
+    )?;
+
+    let hue = hue.map(|h| normalize_hue(h.degrees()));
+    let whiteness = whiteness.map(|w| w.clamp(0.0, 1.0));
+    let blackness = blackness.map(|b| b.clamp(0.0, 1.0));
+
+    Ok(P::Output::from_hwb(hue, whiteness, blackness, alpha))
+}
+
+/// <https://drafts.csswg.org/css-color-4/#hwb-to-rgb>
+#[inline]
+pub fn hwb_to_rgb(h: f32, w: f32, b: f32) -> (f32, f32, f32) {
+    if w + b >= 1.0 {
+        let gray = w / (w + b);
+        return (gray, gray, gray);
+    }
+
+    // hue is expected in the range [0..1].
+    let (mut red, mut green, mut blue) = hsl_to_rgb(h, 1.0, 0.5);
+    let x = 1.0 - w - b;
+    red = red * x + w;
+    green = green * x + w;
+    blue = blue * x + w;
+    (red, green, blue)
+}
+
+/// <https://drafts.csswg.org/css-color/#hsl-color>
+/// except with h pre-multiplied by 3, to avoid some rounding errors.
+#[inline]
+pub fn hsl_to_rgb(hue: f32, saturation: f32, lightness: f32) -> (f32, f32, f32) {
+    debug_assert!((0.0..=1.0).contains(&hue));
+
+    fn hue_to_rgb(m1: f32, m2: f32, mut h3: f32) -> f32 {
+        if h3 < 0. {
+            h3 += 3.
+        }
+        if h3 > 3. {
+            h3 -= 3.
+        }
+        if h3 * 2. < 1. {
+            m1 + (m2 - m1) * h3 * 2.
+        } else if h3 * 2. < 3. {
+            m2
+        } else if h3 < 2. {
+            m1 + (m2 - m1) * (2. - h3) * 2.
+        } else {
+            m1
+        }
+    }
+    let m2 = if lightness <= 0.5 {
+        lightness * (saturation + 1.)
+    } else {
+        lightness + saturation - lightness * saturation
+    };
+    let m1 = lightness * 2. - m2;
+    let hue_times_3 = hue * 3.;
+    let red = hue_to_rgb(m1, m2, hue_times_3 + 1.);
+    let green = hue_to_rgb(m1, m2, hue_times_3);
+    let blue = hue_to_rgb(m1, m2, hue_times_3 - 1.);
+    (red, green, blue)
+}
+
+type IntoColorFn<Output> =
+    fn(l: Option<f32>, a: Option<f32>, b: Option<f32>, alpha: Option<f32>) -> Output;
+
+#[inline]
+fn parse_lab_like<'i, 't, P>(
+    color_parser: &P,
+    arguments: &mut Parser<'i, 't>,
+    lightness_range: f32,
+    a_b_range: f32,
+    into_color: IntoColorFn<P::Output>,
+) -> Result<P::Output, ParseError<'i, P::Error>>
+where
+    P: ColorParser<'i>,
+{
+    let (lightness, a, b, alpha) = parse_components(
+        color_parser,
+        arguments,
+        P::parse_number_or_percentage,
+        P::parse_number_or_percentage,
+        P::parse_number_or_percentage,
+    )?;
+
+    let lightness = lightness.map(|l| l.value(lightness_range));
+    let a = a.map(|a| a.value(a_b_range));
+    let b = b.map(|b| b.value(a_b_range));
+
+    Ok(into_color(lightness, a, b, alpha))
+}
+
+#[inline]
+fn parse_lch_like<'i, 't, P>(
+    color_parser: &P,
+    arguments: &mut Parser<'i, 't>,
+    lightness_range: f32,
+    chroma_range: f32,
+    into_color: IntoColorFn<P::Output>,
+) -> Result<P::Output, ParseError<'i, P::Error>>
+where
+    P: ColorParser<'i>,
+{
+    let (lightness, chroma, hue, alpha) = parse_components(
+        color_parser,
+        arguments,
+        P::parse_number_or_percentage,
+        P::parse_number_or_percentage,
+        P::parse_angle_or_number,
+    )?;
+
+    let lightness = lightness.map(|l| l.value(lightness_range));
+    let chroma = chroma.map(|c| c.value(chroma_range));
+    let hue = hue.map(|h| normalize_hue(h.degrees()));
+
+    Ok(into_color(lightness, chroma, hue, alpha))
+}
+
+/// Parse the color() function.
+#[inline]
+fn parse_color_with_color_space<'i, 't, P>(
+    color_parser: &P,
+    arguments: &mut Parser<'i, 't>,
+) -> Result<P::Output, ParseError<'i, P::Error>>
+where
+    P: ColorParser<'i>,
+{
+    let color_space = {
+        let location = arguments.current_source_location();
+
+        let ident = arguments.expect_ident()?;
+        PredefinedColorSpace::from_str(ident)
+            .map_err(|_| location.new_unexpected_token_error(Token::Ident(ident.clone())))?
+    };
+
+    let (c1, c2, c3, alpha) = parse_components(
+        color_parser,
+        arguments,
+        P::parse_number_or_percentage,
+        P::parse_number_or_percentage,
+        P::parse_number_or_percentage,
+    )?;
+
+    let c1 = c1.map(|c| c.unit_value());
+    let c2 = c2.map(|c| c.unit_value());
+    let c3 = c3.map(|c| c.unit_value());
+
+    Ok(P::Output::from_color_function(
+        color_space,
+        c1,
+        c2,
+        c3,
+        alpha,
+    ))
+}
+
+type ComponentParseResult<'i, R1, R2, R3, Error> =
+    Result<(Option<R1>, Option<R2>, Option<R3>, Option<f32>), ParseError<'i, Error>>;
+
+/// Parse the color components and alpha with the modern [color-4] syntax.
+pub fn parse_components<'i, 't, P, F1, F2, F3, R1, R2, R3>(
+    color_parser: &P,
+    input: &mut Parser<'i, 't>,
+    f1: F1,
+    f2: F2,
+    f3: F3,
+) -> ComponentParseResult<'i, R1, R2, R3, P::Error>
+where
+    P: ColorParser<'i>,
+    F1: FnOnce(&P, &mut Parser<'i, 't>) -> Result<R1, ParseError<'i, P::Error>>,
+    F2: FnOnce(&P, &mut Parser<'i, 't>) -> Result<R2, ParseError<'i, P::Error>>,
+    F3: FnOnce(&P, &mut Parser<'i, 't>) -> Result<R3, ParseError<'i, P::Error>>,
+{
+    let r1 = parse_none_or(input, |p| f1(color_parser, p))?;
+    let r2 = parse_none_or(input, |p| f2(color_parser, p))?;
+    let r3 = parse_none_or(input, |p| f3(color_parser, p))?;
+
+    let alpha = parse_modern_alpha(color_parser, input)?;
+
+    Ok((r1, r2, r3, alpha))
+}
+
+fn parse_none_or<'i, 't, F, T, E>(input: &mut Parser<'i, 't>, thing: F) -> Result<Option<T>, E>
+where
+    F: FnOnce(&mut Parser<'i, 't>) -> Result<T, E>,
+{
+    match input.try_parse(|p| p.expect_ident_matching("none")) {
+        Ok(_) => Ok(None),
+        Err(_) => Ok(Some(thing(input)?)),
+    }
+}
+
+/// A [`ModernComponent`] can serialize to `none`, `nan`, `infinity` and
+/// floating point values.
+struct ModernComponent<'a>(&'a Option<f32>);
+
+impl<'a> ToCss for ModernComponent<'a> {
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
+    where
+        W: fmt::Write,
+    {
+        if let Some(value) = self.0 {
+            if value.is_finite() {
+                value.to_css(dest)
+            } else if value.is_nan() {
+                dest.write_str("calc(NaN)")
+            } else {
+                debug_assert!(value.is_infinite());
+                if value.is_sign_negative() {
+                    dest.write_str("calc(-infinity)")
+                } else {
+                    dest.write_str("calc(infinity)")
+                }
+            }
+        } else {
+            dest.write_str("none")
+        }
+    }
+}
+
+// Guaratees hue in [0..360)
+fn normalize_hue(hue: f32) -> f32 {
+    // <https://drafts.csswg.org/css-values/#angles>
+    // Subtract an integer before rounding, to avoid some rounding errors:
+    hue - 360.0 * (hue / 360.0).floor()
+}
+
+/// A color with red, green, blue, and alpha components, in a byte each.
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub struct RgbaLegacy {
+    /// The red component.
+    pub red: u8,
+    /// The green component.
+    pub green: u8,
+    /// The blue component.
+    pub blue: u8,
+    /// The alpha component.
+    pub alpha: f32,
+}
+
+impl RgbaLegacy {
+    /// Constructs a new RGBA value from float components. It expects the red,
+    /// green, blue and alpha channels in that order, and all values will be
+    /// clamped to the 0.0 ... 1.0 range.
+    #[inline]
+    pub fn from_floats(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
+        Self::new(
+            clamp_unit_f32(red),
+            clamp_unit_f32(green),
+            clamp_unit_f32(blue),
+            alpha.clamp(0.0, OPAQUE),
+        )
+    }
+
+    /// Same thing, but with `u8` values instead of floats in the 0 to 1 range.
+    #[inline]
+    pub const fn new(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
+        Self {
+            red,
+            green,
+            blue,
+            alpha,
+        }
+    }
+}
+
+#[cfg(feature = "serde")]
+impl Serialize for RgbaLegacy {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        (self.red, self.green, self.blue, self.alpha).serialize(serializer)
+    }
+}
+
+#[cfg(feature = "serde")]
+impl<'de> Deserialize<'de> for RgbaLegacy {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        let (r, g, b, a) = Deserialize::deserialize(deserializer)?;
+        Ok(RgbaLegacy::new(r, g, b, a))
+    }
+}
+
+impl ToCss for RgbaLegacy {
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
+    where
+        W: fmt::Write,
+    {
+        let has_alpha = self.alpha != OPAQUE;
+
+        dest.write_str(if has_alpha { "rgba(" } else { "rgb(" })?;
+        self.red.to_css(dest)?;
+        dest.write_str(", ")?;
+        self.green.to_css(dest)?;
+        dest.write_str(", ")?;
+        self.blue.to_css(dest)?;
+
+        // Legacy syntax does not allow none components.
+        serialize_color_alpha(dest, Some(self.alpha), true)?;
+
+        dest.write_char(')')
+    }
+}
+
+/// Color specified by hue, saturation and lightness components.
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub struct Hsl {
+    /// The hue component.
+    pub hue: Option<f32>,
+    /// The saturation component.
+    pub saturation: Option<f32>,
+    /// The lightness component.
+    pub lightness: Option<f32>,
+    /// The alpha component.
+    pub alpha: Option<f32>,
+}
+
+impl Hsl {
+    /// Construct a new HSL color from it's components.
+    pub fn new(
+        hue: Option<f32>,
+        saturation: Option<f32>,
+        lightness: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self {
+        Self {
+            hue,
+            saturation,
+            lightness,
+            alpha,
+        }
+    }
+}
+
+impl ToCss for Hsl {
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
+    where
+        W: fmt::Write,
+    {
+        // HSL serializes to RGB, so we have to convert it.
+        let (red, green, blue) = hsl_to_rgb(
+            self.hue.unwrap_or(0.0) / 360.0,
+            self.saturation.unwrap_or(0.0),
+            self.lightness.unwrap_or(0.0),
+        );
+
+        RgbaLegacy::from_floats(red, green, blue, self.alpha.unwrap_or(OPAQUE)).to_css(dest)
+    }
+}
+
+#[cfg(feature = "serde")]
+impl Serialize for Hsl {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        (self.hue, self.saturation, self.lightness, self.alpha).serialize(serializer)
+    }
+}
+
+#[cfg(feature = "serde")]
+impl<'de> Deserialize<'de> for Hsl {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        let (lightness, a, b, alpha) = Deserialize::deserialize(deserializer)?;
+        Ok(Self::new(lightness, a, b, alpha))
+    }
+}
+
+/// Color specified by hue, whiteness and blackness components.
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub struct Hwb {
+    /// The hue component.
+    pub hue: Option<f32>,
+    /// The whiteness component.
+    pub whiteness: Option<f32>,
+    /// The blackness component.
+    pub blackness: Option<f32>,
+    /// The alpha component.
+    pub alpha: Option<f32>,
+}
+
+impl Hwb {
+    /// Construct a new HWB color from it's components.
+    pub fn new(
+        hue: Option<f32>,
+        whiteness: Option<f32>,
+        blackness: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self {
+        Self {
+            hue,
+            whiteness,
+            blackness,
+            alpha,
+        }
+    }
+}
+
+impl ToCss for Hwb {
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
+    where
+        W: fmt::Write,
+    {
+        // HWB serializes to RGB, so we have to convert it.
+        let (red, green, blue) = hwb_to_rgb(
+            self.hue.unwrap_or(0.0) / 360.0,
+            self.whiteness.unwrap_or(0.0),
+            self.blackness.unwrap_or(0.0),
+        );
+
+        RgbaLegacy::from_floats(red, green, blue, self.alpha.unwrap_or(OPAQUE)).to_css(dest)
+    }
+}
+
+#[cfg(feature = "serde")]
+impl Serialize for Hwb {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        (self.hue, self.whiteness, self.blackness, self.alpha).serialize(serializer)
+    }
+}
+
+#[cfg(feature = "serde")]
+impl<'de> Deserialize<'de> for Hwb {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        let (lightness, whiteness, blackness, alpha) = Deserialize::deserialize(deserializer)?;
+        Ok(Self::new(lightness, whiteness, blackness, alpha))
+    }
+}
+
+// NOTE: LAB and OKLAB is not declared inside the [impl_lab_like] macro,
+// because it causes cbindgen to ignore them.
+
+/// Color specified by lightness, a- and b-axis components.
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub struct Lab {
+    /// The lightness component.
+    pub lightness: Option<f32>,
+    /// The a-axis component.
+    pub a: Option<f32>,
+    /// The b-axis component.
+    pub b: Option<f32>,
+    /// The alpha component.
+    pub alpha: Option<f32>,
+}
+
+/// Color specified by lightness, a- and b-axis components.
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub struct Oklab {
+    /// The lightness component.
+    pub lightness: Option<f32>,
+    /// The a-axis component.
+    pub a: Option<f32>,
+    /// The b-axis component.
+    pub b: Option<f32>,
+    /// The alpha component.
+    pub alpha: Option<f32>,
+}
+
+macro_rules! impl_lab_like {
+    ($cls:ident, $fname:literal) => {
+        impl $cls {
+            /// Construct a new Lab color format with lightness, a, b and alpha components.
+            pub fn new(
+                lightness: Option<f32>,
+                a: Option<f32>,
+                b: Option<f32>,
+                alpha: Option<f32>,
+            ) -> Self {
+                Self {
+                    lightness,
+                    a,
+                    b,
+                    alpha,
+                }
+            }
+        }
+
+        #[cfg(feature = "serde")]
+        impl Serialize for $cls {
+            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+            where
+                S: Serializer,
+            {
+                (self.lightness, self.a, self.b, self.alpha).serialize(serializer)
+            }
+        }
+
+        #[cfg(feature = "serde")]
+        impl<'de> Deserialize<'de> for $cls {
+            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+            where
+                D: Deserializer<'de>,
+            {
+                let (lightness, a, b, alpha) = Deserialize::deserialize(deserializer)?;
+                Ok(Self::new(lightness, a, b, alpha))
+            }
+        }
+
+        impl ToCss for $cls {
+            fn to_css<W>(&self, dest: &mut W) -> fmt::Result
+            where
+                W: fmt::Write,
+            {
+                dest.write_str($fname)?;
+                dest.write_str("(")?;
+                ModernComponent(&self.lightness).to_css(dest)?;
+                dest.write_char(' ')?;
+                ModernComponent(&self.a).to_css(dest)?;
+                dest.write_char(' ')?;
+                ModernComponent(&self.b).to_css(dest)?;
+                serialize_color_alpha(dest, self.alpha, false)?;
+                dest.write_char(')')
+            }
+        }
+    };
+}
+
+impl_lab_like!(Lab, "lab");
+impl_lab_like!(Oklab, "oklab");
+
+// NOTE: LCH and OKLCH is not declared inside the [impl_lch_like] macro,
+// because it causes cbindgen to ignore them.
+
+/// Color specified by lightness, chroma and hue components.
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub struct Lch {
+    /// The lightness component.
+    pub lightness: Option<f32>,
+    /// The chroma component.
+    pub chroma: Option<f32>,
+    /// The hue component.
+    pub hue: Option<f32>,
+    /// The alpha component.
+    pub alpha: Option<f32>,
+}
+
+/// Color specified by lightness, chroma and hue components.
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub struct Oklch {
+    /// The lightness component.
+    pub lightness: Option<f32>,
+    /// The chroma component.
+    pub chroma: Option<f32>,
+    /// The hue component.
+    pub hue: Option<f32>,
+    /// The alpha component.
+    pub alpha: Option<f32>,
+}
+
+macro_rules! impl_lch_like {
+    ($cls:ident, $fname:literal) => {
+        impl $cls {
+            /// Construct a new color with lightness, chroma and hue components.
+            pub fn new(
+                lightness: Option<f32>,
+                chroma: Option<f32>,
+                hue: Option<f32>,
+                alpha: Option<f32>,
+            ) -> Self {
+                Self {
+                    lightness,
+                    chroma,
+                    hue,
+                    alpha,
+                }
+            }
+        }
+
+        #[cfg(feature = "serde")]
+        impl Serialize for $cls {
+            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+            where
+                S: Serializer,
+            {
+                (self.lightness, self.chroma, self.hue, self.alpha).serialize(serializer)
+            }
+        }
+
+        #[cfg(feature = "serde")]
+        impl<'de> Deserialize<'de> for $cls {
+            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+            where
+                D: Deserializer<'de>,
+            {
+                let (lightness, chroma, hue, alpha) = Deserialize::deserialize(deserializer)?;
+                Ok(Self::new(lightness, chroma, hue, alpha))
+            }
+        }
+
+        impl ToCss for $cls {
+            fn to_css<W>(&self, dest: &mut W) -> fmt::Result
+            where
+                W: fmt::Write,
+            {
+                dest.write_str($fname)?;
+                dest.write_str("(")?;
+                ModernComponent(&self.lightness).to_css(dest)?;
+                dest.write_char(' ')?;
+                ModernComponent(&self.chroma).to_css(dest)?;
+                dest.write_char(' ')?;
+                ModernComponent(&self.hue).to_css(dest)?;
+                serialize_color_alpha(dest, self.alpha, false)?;
+                dest.write_char(')')
+            }
+        }
+    };
+}
+
+impl_lch_like!(Lch, "lch");
+impl_lch_like!(Oklch, "oklch");
+
+/// A color specified by the color() function.
+/// <https://drafts.csswg.org/css-color-4/#color-function>
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub struct ColorFunction {
+    /// The color space for this color.
+    pub color_space: PredefinedColorSpace,
+    /// The first component of the color.  Either red or x.
+    pub c1: Option<f32>,
+    /// The second component of the color.  Either green or y.
+    pub c2: Option<f32>,
+    /// The third component of the color.  Either blue or z.
+    pub c3: Option<f32>,
+    /// The alpha component of the color.
+    pub alpha: Option<f32>,
+}
+
+impl ColorFunction {
+    /// Construct a new color function definition with the given color space and
+    /// color components.
+    pub fn new(
+        color_space: PredefinedColorSpace,
+        c1: Option<f32>,
+        c2: Option<f32>,
+        c3: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self {
+        Self {
+            color_space,
+            c1,
+            c2,
+            c3,
+            alpha,
+        }
+    }
+}
+
+impl ToCss for ColorFunction {
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
+    where
+        W: fmt::Write,
+    {
+        dest.write_str("color(")?;
+        self.color_space.to_css(dest)?;
+        dest.write_char(' ')?;
+        ModernComponent(&self.c1).to_css(dest)?;
+        dest.write_char(' ')?;
+        ModernComponent(&self.c2).to_css(dest)?;
+        dest.write_char(' ')?;
+        ModernComponent(&self.c3).to_css(dest)?;
+
+        serialize_color_alpha(dest, self.alpha, false)?;
+
+        dest.write_char(')')
+    }
+}
+
+/// Describes one of the value <color> values according to the CSS
+/// specification.
+///
+/// Most components are `Option<_>`, so when the value is `None`, that component
+/// serializes to the "none" keyword.
+///
+/// <https://drafts.csswg.org/css-color-4/#color-type>
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub enum Color {
+    /// The 'currentcolor' keyword.
+    CurrentColor,
+    /// Specify sRGB colors directly by their red/green/blue/alpha chanels.
+    Rgba(RgbaLegacy),
+    /// Specifies a color in sRGB using hue, saturation and lightness components.
+    Hsl(Hsl),
+    /// Specifies a color in sRGB using hue, whiteness and blackness components.
+    Hwb(Hwb),
+    /// Specifies a CIELAB color by CIE Lightness and its a- and b-axis hue
+    /// coordinates (red/green-ness, and yellow/blue-ness) using the CIE LAB
+    /// rectangular coordinate model.
+    Lab(Lab),
+    /// Specifies a CIELAB color by CIE Lightness, Chroma, and hue using the
+    /// CIE LCH cylindrical coordinate model.
+    Lch(Lch),
+    /// Specifies an Oklab color by Oklab Lightness and its a- and b-axis hue
+    /// coordinates (red/green-ness, and yellow/blue-ness) using the Oklab
+    /// rectangular coordinate model.
+    Oklab(Oklab),
+    /// Specifies an Oklab color by Oklab Lightness, Chroma, and hue using
+    /// the OKLCH cylindrical coordinate model.
+    Oklch(Oklch),
+    /// Specifies a color in a predefined color space.
+    ColorFunction(ColorFunction),
+}
+
+impl ToCss for Color {
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
+    where
+        W: fmt::Write,
+    {
+        match *self {
+            Color::CurrentColor => dest.write_str("currentcolor"),
+            Color::Rgba(rgba) => rgba.to_css(dest),
+            Color::Hsl(hsl) => hsl.to_css(dest),
+            Color::Hwb(hwb) => hwb.to_css(dest),
+            Color::Lab(lab) => lab.to_css(dest),
+            Color::Lch(lch) => lch.to_css(dest),
+            Color::Oklab(lab) => lab.to_css(dest),
+            Color::Oklch(lch) => lch.to_css(dest),
+            Color::ColorFunction(color_function) => color_function.to_css(dest),
+        }
+    }
+}
+
+/// Either a number or a percentage.
+pub enum NumberOrPercentage {
+    /// `<number>`.
+    Number {
+        /// The numeric value parsed, as a float.
+        value: f32,
+    },
+    /// `<percentage>`
+    Percentage {
+        /// The value as a float, divided by 100 so that the nominal range is
+        /// 0.0 to 1.0.
+        unit_value: f32,
+    },
+}
+
+impl NumberOrPercentage {
+    /// Return the value as a percentage.
+    pub fn unit_value(&self) -> f32 {
+        match *self {
+            NumberOrPercentage::Number { value } => value,
+            NumberOrPercentage::Percentage { unit_value } => unit_value,
+        }
+    }
+
+    /// Return the value as a number with a percentage adjusted to the
+    /// `percentage_basis`.
+    pub fn value(&self, percentage_basis: f32) -> f32 {
+        match *self {
+            Self::Number { value } => value,
+            Self::Percentage { unit_value } => unit_value * percentage_basis,
+        }
+    }
+}
+
+/// Either an angle or a number.
+pub enum AngleOrNumber {
+    /// `<number>`.
+    Number {
+        /// The numeric value parsed, as a float.
+        value: f32,
+    },
+    /// `<angle>`
+    Angle {
+        /// The value as a number of degrees.
+        degrees: f32,
+    },
+}
+
+impl AngleOrNumber {
+    /// Return the angle in degrees. `AngleOrNumber::Number` is returned as
+    /// degrees, because it is the canonical unit.
+    pub fn degrees(&self) -> f32 {
+        match *self {
+            AngleOrNumber::Number { value } => value,
+            AngleOrNumber::Angle { degrees } => degrees,
+        }
+    }
+}
+
+/// A trait that can be used to hook into how `cssparser` parses color
+/// components, with the intention of implementing more complicated behavior.
+///
+/// For example, this is used by Servo to support calc() in color.
+pub trait ColorParser<'i> {
+    /// The type that the parser will construct on a successful parse.
+    type Output: FromParsedColor;
+
+    /// A custom error type that can be returned from the parsing functions.
+    type Error: 'i;
+
+    /// Parse an `<angle>` or `<number>`.
+    ///
+    /// Returns the result in degrees.
+    fn parse_angle_or_number<'t>(
+        &self,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<AngleOrNumber, ParseError<'i, Self::Error>> {
+        let location = input.current_source_location();
+        Ok(match *input.next()? {
+            Token::Number { value, .. } => AngleOrNumber::Number { value },
+            Token::Dimension {
+                value: v, ref unit, ..
+            } => {
+                let degrees = match_ignore_ascii_case! { unit,
+                    "deg" => v,
+                    "grad" => v * 360. / 400.,
+                    "rad" => v * 360. / (2. * PI),
+                    "turn" => v * 360.,
+                    _ => {
+                        return Err(location.new_unexpected_token_error(Token::Ident(unit.clone())))
+                    }
+                };
+
+                AngleOrNumber::Angle { degrees }
+            }
+            ref t => return Err(location.new_unexpected_token_error(t.clone())),
+        })
+    }
+
+    /// Parse a `<percentage>` value.
+    ///
+    /// Returns the result in a number from 0.0 to 1.0.
+    fn parse_percentage<'t>(
+        &self,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<f32, ParseError<'i, Self::Error>> {
+        input.expect_percentage().map_err(From::from)
+    }
+
+    /// Parse a `<number>` value.
+    fn parse_number<'t>(
+        &self,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<f32, ParseError<'i, Self::Error>> {
+        input.expect_number().map_err(From::from)
+    }
+
+    /// Parse a `<number>` value or a `<percentage>` value.
+    fn parse_number_or_percentage<'t>(
+        &self,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<NumberOrPercentage, ParseError<'i, Self::Error>> {
+        let location = input.current_source_location();
+        Ok(match *input.next()? {
+            Token::Number { value, .. } => NumberOrPercentage::Number { value },
+            Token::Percentage { unit_value, .. } => NumberOrPercentage::Percentage { unit_value },
+            ref t => return Err(location.new_unexpected_token_error(t.clone())),
+        })
+    }
+}
+
+/// Default implementation of a [`ColorParser`]
+pub struct DefaultColorParser;
+
+impl<'i> ColorParser<'i> for DefaultColorParser {
+    type Output = Color;
+    type Error = ();
+}
+
+impl Color {
+    /// Parse a <color> value, per CSS Color Module Level 3.
+    ///
+    /// FIXME(#2) Deprecated CSS2 System Colors are not supported yet.
+    pub fn parse<'i>(input: &mut Parser<'i, '_>) -> Result<Color, ParseError<'i, ()>> {
+        parse_color_with(&DefaultColorParser, input)
+    }
+}
+
+/// This trait is used by the [`ColorParser`] to construct colors of any type.
+pub trait FromParsedColor {
+    /// Construct a new color from the CSS `currentcolor` keyword.
+    fn from_current_color() -> Self;
+
+    /// Construct a new color from red, green, blue and alpha components.
+    fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self;
+
+    /// Construct a new color from hue, saturation, lightness and alpha components.
+    fn from_hsl(
+        hue: Option<f32>,
+        saturation: Option<f32>,
+        lightness: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self;
+
+    /// Construct a new color from hue, blackness, whiteness and alpha components.
+    fn from_hwb(
+        hue: Option<f32>,
+        whiteness: Option<f32>,
+        blackness: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self;
+
+    /// Construct a new color from the `lab` notation.
+    fn from_lab(lightness: Option<f32>, a: Option<f32>, b: Option<f32>, alpha: Option<f32>)
+        -> Self;
+
+    /// Construct a new color from the `lch` notation.
+    fn from_lch(
+        lightness: Option<f32>,
+        chroma: Option<f32>,
+        hue: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self;
+
+    /// Construct a new color from the `oklab` notation.
+    fn from_oklab(
+        lightness: Option<f32>,
+        a: Option<f32>,
+        b: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self;
+
+    /// Construct a new color from the `oklch` notation.
+    fn from_oklch(
+        lightness: Option<f32>,
+        chroma: Option<f32>,
+        hue: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self;
+
+    /// Construct a new color with a predefined color space.
+    fn from_color_function(
+        color_space: PredefinedColorSpace,
+        c1: Option<f32>,
+        c2: Option<f32>,
+        c3: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self;
+}
+
+impl FromParsedColor for Color {
+    #[inline]
+    fn from_current_color() -> Self {
+        Color::CurrentColor
+    }
+
+    #[inline]
+    fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
+        Color::Rgba(RgbaLegacy::new(red, green, blue, alpha))
+    }
+
+    fn from_hsl(
+        hue: Option<f32>,
+        saturation: Option<f32>,
+        lightness: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self {
+        Color::Hsl(Hsl::new(hue, saturation, lightness, alpha))
+    }
+
+    fn from_hwb(
+        hue: Option<f32>,
+        blackness: Option<f32>,
+        whiteness: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self {
+        Color::Hwb(Hwb::new(hue, blackness, whiteness, alpha))
+    }
+
+    #[inline]
+    fn from_lab(
+        lightness: Option<f32>,
+        a: Option<f32>,
+        b: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self {
+        Color::Lab(Lab::new(lightness, a, b, alpha))
+    }
+
+    #[inline]
+    fn from_lch(
+        lightness: Option<f32>,
+        chroma: Option<f32>,
+        hue: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self {
+        Color::Lch(Lch::new(lightness, chroma, hue, alpha))
+    }
+
+    #[inline]
+    fn from_oklab(
+        lightness: Option<f32>,
+        a: Option<f32>,
+        b: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self {
+        Color::Oklab(Oklab::new(lightness, a, b, alpha))
+    }
+
+    #[inline]
+    fn from_oklch(
+        lightness: Option<f32>,
+        chroma: Option<f32>,
+        hue: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self {
+        Color::Oklch(Oklch::new(lightness, chroma, hue, alpha))
+    }
+
+    #[inline]
+    fn from_color_function(
+        color_space: PredefinedColorSpace,
+        c1: Option<f32>,
+        c2: Option<f32>,
+        c3: Option<f32>,
+        alpha: Option<f32>,
+    ) -> Self {
+        Color::ColorFunction(ColorFunction::new(color_space, c1, c2, c3, alpha))
+    }
+}
diff --git a/color/tests.rs b/color/tests.rs
new file mode 100644
index 00000000..babb076b
--- /dev/null
+++ b/color/tests.rs
@@ -0,0 +1,401 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use super::*;
+use crate::{ColorParser, PredefinedColorSpace, Color, RgbaLegacy};
+use cssparser::{Parser, ParserInput};
+use serde_json::{self, json, Value};
+
+fn almost_equals(a: &Value, b: &Value) -> bool {
+    match (a, b) {
+        (&Value::Number(ref a), &Value::Number(ref b)) => {
+            let a = a.as_f64().unwrap();
+            let b = b.as_f64().unwrap();
+            (a - b).abs() <= a.abs() * 1e-6
+        }
+
+        (&Value::Bool(a), &Value::Bool(b)) => a == b,
+        (&Value::String(ref a), &Value::String(ref b)) => a == b,
+        (&Value::Array(ref a), &Value::Array(ref b)) => {
+            a.len() == b.len()
+                && a.iter()
+                    .zip(b.iter())
+                    .all(|(ref a, ref b)| almost_equals(*a, *b))
+        }
+        (&Value::Object(_), &Value::Object(_)) => panic!("Not implemented"),
+        (&Value::Null, &Value::Null) => true,
+        _ => false,
+    }
+}
+
+fn assert_json_eq(results: Value, expected: Value, message: &str) {
+    if !almost_equals(&results, &expected) {
+        println!(
+            "{}",
+            ::difference::Changeset::new(
+                &serde_json::to_string_pretty(&results).unwrap(),
+                &serde_json::to_string_pretty(&expected).unwrap(),
+                "\n",
+            )
+        );
+        panic!("{}", message)
+    }
+}
+
+
+fn run_raw_json_tests<F: Fn(Value, Value) -> ()>(json_data: &str, run: F) {
+    let items = match serde_json::from_str(json_data) {
+        Ok(Value::Array(items)) => items,
+        other => panic!("Invalid JSON: {:?}", other),
+    };
+    assert!(items.len() % 2 == 0);
+    let mut input = None;
+    for item in items.into_iter() {
+        match (&input, item) {
+            (&None, json_obj) => input = Some(json_obj),
+            (&Some(_), expected) => {
+                let input = input.take().unwrap();
+                run(input, expected)
+            }
+        };
+    }
+}
+
+fn run_json_tests<F: Fn(&mut Parser) -> Value>(json_data: &str, parse: F) {
+    run_raw_json_tests(json_data, |input, expected| match input {
+        Value::String(input) => {
+            let mut parse_input = ParserInput::new(&input);
+            let result = parse(&mut Parser::new(&mut parse_input));
+            assert_json_eq(result, expected, &input);
+        }
+        _ => panic!("Unexpected JSON"),
+    });
+}
+fn run_color_tests<F: Fn(Result<Color, ()>) -> Value>(json_data: &str, to_json: F) {
+    run_json_tests(json_data, |input| {
+        let result: Result<_, ParseError<()>> =
+            input.parse_entirely(|i| Color::parse(i).map_err(Into::into));
+        to_json(result.map_err(|_| ()))
+    });
+}
+
+#[test]
+fn color3() {
+    run_color_tests(include_str!("../src/css-parsing-tests/color3.json"), |c| {
+        c.ok()
+            .map(|v| v.to_css_string().to_json())
+            .unwrap_or(Value::Null)
+    })
+}
+
+#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
+#[test]
+fn color3_hsl() {
+    run_color_tests(include_str!("../src/css-parsing-tests/color3_hsl.json"), |c| {
+        c.ok()
+            .map(|v| v.to_css_string().to_json())
+            .unwrap_or(Value::Null)
+    })
+}
+
+/// color3_keywords.json is different: R, G and B are in 0..255 rather than 0..1
+#[test]
+fn color3_keywords() {
+    run_color_tests(
+        include_str!("../src/css-parsing-tests/color3_keywords.json"),
+        |c| {
+            c.ok()
+                .map(|v| v.to_css_string().to_json())
+                .unwrap_or(Value::Null)
+        },
+    )
+}
+
+#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
+#[test]
+fn color4_hwb() {
+    run_color_tests(include_str!("../src/css-parsing-tests/color4_hwb.json"), |c| {
+        c.ok()
+            .map(|v| v.to_css_string().to_json())
+            .unwrap_or(Value::Null)
+    })
+}
+
+#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
+#[test]
+fn color4_lab_lch_oklab_oklch() {
+    run_color_tests(
+        include_str!("../src/css-parsing-tests/color4_lab_lch_oklab_oklch.json"),
+        |c| {
+            c.ok()
+                .map(|v| v.to_css_string().to_json())
+                .unwrap_or(Value::Null)
+        },
+    )
+}
+
+#[test]
+fn color4_color_function() {
+    run_color_tests(
+        include_str!("../src/css-parsing-tests/color4_color_function.json"),
+        |c| {
+            c.ok()
+                .map(|v| v.to_css_string().to_json())
+                .unwrap_or(Value::Null)
+        },
+    )
+}
+
+macro_rules! parse_single_color {
+    ($i:expr) => {{
+        let input = $i;
+        let mut input = ParserInput::new(input);
+        let mut input = Parser::new(&mut input);
+        Color::parse(&mut input).map_err(Into::<ParseError<()>>::into)
+    }};
+}
+
+#[test]
+fn color4_invalid_color_space() {
+    let result = parse_single_color!("color(invalid 1 1 1)");
+    assert!(result.is_err());
+}
+
+#[test]
+fn serialize_current_color() {
+    let c = Color::CurrentColor;
+    assert!(c.to_css_string() == "currentcolor");
+}
+
+#[test]
+fn serialize_rgb_full_alpha() {
+    let c = Color::Rgba(RgbaLegacy::new(255, 230, 204, 1.0));
+    assert_eq!(c.to_css_string(), "rgb(255, 230, 204)");
+}
+
+#[test]
+fn serialize_rgba() {
+    let c = Color::Rgba(RgbaLegacy::new(26, 51, 77, 0.125));
+    assert_eq!(c.to_css_string(), "rgba(26, 51, 77, 0.125)");
+}
+
+#[test]
+fn serialize_rgba_two_digit_float_if_roundtrips() {
+    let c = Color::Rgba(RgbaLegacy::from_floats(0., 0., 0., 0.5));
+    assert_eq!(c.to_css_string(), "rgba(0, 0, 0, 0.5)");
+}
+
+trait ToJson {
+    fn to_json(&self) -> Value;
+}
+
+impl<T> ToJson for T
+where
+    T: Clone,
+    Value: From<T>,
+{
+    fn to_json(&self) -> Value {
+        Value::from(self.clone())
+    }
+}
+
+impl ToJson for Color {
+    fn to_json(&self) -> Value {
+        match *self {
+            Color::CurrentColor => "currentcolor".to_json(),
+            Color::Rgba(ref rgba) => {
+                json!([rgba.red, rgba.green, rgba.blue, rgba.alpha])
+            }
+            Color::Hsl(ref c) => json!([c.hue, c.saturation, c.lightness, c.alpha]),
+            Color::Hwb(ref c) => json!([c.hue, c.whiteness, c.blackness, c.alpha]),
+            Color::Lab(ref c) => json!([c.lightness, c.a, c.b, c.alpha]),
+            Color::Lch(ref c) => json!([c.lightness, c.chroma, c.hue, c.alpha]),
+            Color::Oklab(ref c) => json!([c.lightness, c.a, c.b, c.alpha]),
+            Color::Oklch(ref c) => json!([c.lightness, c.chroma, c.hue, c.alpha]),
+            Color::ColorFunction(ref c) => {
+                json!([c.color_space.as_str(), c.c1, c.c2, c.c3, c.alpha])
+            }
+        }
+    }
+}
+
+#[test]
+fn generic_parser() {
+    #[derive(Debug, PartialEq)]
+    enum OutputType {
+        CurrentColor,
+        Rgba(u8, u8, u8, f32),
+        Hsl(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
+        Hwb(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
+        Lab(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
+        Lch(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
+        Oklab(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
+        Oklch(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
+        ColorFunction(
+            PredefinedColorSpace,
+            Option<f32>,
+            Option<f32>,
+            Option<f32>,
+            Option<f32>,
+        ),
+    }
+
+    impl FromParsedColor for OutputType {
+        fn from_current_color() -> Self {
+            OutputType::CurrentColor
+        }
+
+        fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
+            OutputType::Rgba(red, green, blue, alpha)
+        }
+
+        fn from_hsl(
+            hue: Option<f32>,
+            saturation: Option<f32>,
+            lightness: Option<f32>,
+            alpha: Option<f32>,
+        ) -> Self {
+            OutputType::Hsl(hue, saturation, lightness, alpha)
+        }
+
+        fn from_hwb(
+            hue: Option<f32>,
+            blackness: Option<f32>,
+            whiteness: Option<f32>,
+            alpha: Option<f32>,
+        ) -> Self {
+            OutputType::Hwb(hue, blackness, whiteness, alpha)
+        }
+
+        fn from_lab(
+            lightness: Option<f32>,
+            a: Option<f32>,
+            b: Option<f32>,
+            alpha: Option<f32>,
+        ) -> Self {
+            OutputType::Lab(lightness, a, b, alpha)
+        }
+
+        fn from_lch(
+            lightness: Option<f32>,
+            chroma: Option<f32>,
+            hue: Option<f32>,
+            alpha: Option<f32>,
+        ) -> Self {
+            OutputType::Lch(lightness, chroma, hue, alpha)
+        }
+
+        fn from_oklab(
+            lightness: Option<f32>,
+            a: Option<f32>,
+            b: Option<f32>,
+            alpha: Option<f32>,
+        ) -> Self {
+            OutputType::Oklab(lightness, a, b, alpha)
+        }
+
+        fn from_oklch(
+            lightness: Option<f32>,
+            chroma: Option<f32>,
+            hue: Option<f32>,
+            alpha: Option<f32>,
+        ) -> Self {
+            OutputType::Oklch(lightness, chroma, hue, alpha)
+        }
+
+        fn from_color_function(
+            color_space: PredefinedColorSpace,
+            c1: Option<f32>,
+            c2: Option<f32>,
+            c3: Option<f32>,
+            alpha: Option<f32>,
+        ) -> Self {
+            OutputType::ColorFunction(color_space, c1, c2, c3, alpha)
+        }
+    }
+
+    struct TestColorParser;
+    impl<'i> ColorParser<'i> for TestColorParser {
+        type Output = OutputType;
+        type Error = ();
+    }
+
+    #[rustfmt::skip]
+    const TESTS: &[(&str, OutputType)] = &[
+        ("currentColor",                OutputType::CurrentColor),
+        ("rgb(1, 2, 3)",                OutputType::Rgba(1, 2, 3, 1.0)),
+        ("rgba(1, 2, 3, 0.4)",          OutputType::Rgba(1, 2, 3, 0.4)),
+        ("rgb(none none none / none)",  OutputType::Rgba(0, 0, 0, 0.0)),
+        ("rgb(1 none 3 / none)",        OutputType::Rgba(1, 0, 3, 0.0)),
+
+        ("hsla(45deg, 20%, 30%, 0.4)",  OutputType::Hsl(Some(45.0), Some(0.2), Some(0.3), Some(0.4))),
+        ("hsl(45deg none none)",        OutputType::Hsl(Some(45.0), None, None, Some(1.0))),
+        ("hsl(none 10% none / none)",   OutputType::Hsl(None, Some(0.1), None, None)),
+        ("hsl(120 100.0% 50.0%)",       OutputType::Hsl(Some(120.0), Some(1.0), Some(0.5), Some(1.0))),
+
+        ("hwb(45deg 20% 30% / 0.4)",    OutputType::Hwb(Some(45.0), Some(0.2), Some(0.3), Some(0.4))),
+
+        ("lab(100 20 30 / 0.4)",        OutputType::Lab(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
+        ("lch(100 20 30 / 0.4)",        OutputType::Lch(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
+
+        ("oklab(100 20 30 / 0.4)",      OutputType::Oklab(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
+        ("oklch(100 20 30 / 0.4)",      OutputType::Oklch(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
+
+        ("color(srgb 0.1 0.2 0.3 / 0.4)",           OutputType::ColorFunction(PredefinedColorSpace::Srgb, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
+        ("color(srgb none none none)",              OutputType::ColorFunction(PredefinedColorSpace::Srgb, None, None, None, Some(1.0))),
+        ("color(srgb none none none / none)",       OutputType::ColorFunction(PredefinedColorSpace::Srgb, None, None, None, None)),
+        ("color(srgb-linear 0.1 0.2 0.3 / 0.4)",    OutputType::ColorFunction(PredefinedColorSpace::SrgbLinear, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
+        ("color(display-p3 0.1 0.2 0.3 / 0.4)",     OutputType::ColorFunction(PredefinedColorSpace::DisplayP3, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
+        ("color(a98-rgb 0.1 0.2 0.3 / 0.4)",        OutputType::ColorFunction(PredefinedColorSpace::A98Rgb, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
+        ("color(prophoto-rgb 0.1 0.2 0.3 / 0.4)",   OutputType::ColorFunction(PredefinedColorSpace::ProphotoRgb, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
+        ("color(rec2020 0.1 0.2 0.3 / 0.4)",        OutputType::ColorFunction(PredefinedColorSpace::Rec2020, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
+        ("color(xyz-d50 0.1 0.2 0.3 / 0.4)",        OutputType::ColorFunction(PredefinedColorSpace::XyzD50, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
+        ("color(xyz-d65 0.1 0.2 0.3 / 0.4)",        OutputType::ColorFunction(PredefinedColorSpace::XyzD65, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
+    ];
+
+    for (input, expected) in TESTS {
+        let mut input = ParserInput::new(*input);
+        let mut input = Parser::new(&mut input);
+
+        let actual: OutputType = parse_color_with(&TestColorParser, &mut input).unwrap();
+        assert_eq!(actual, *expected);
+    }
+}
+
+#[test]
+fn serialize_modern_components() {
+    // None.
+    assert_eq!(ModernComponent(&None).to_css_string(), "none".to_string());
+
+    // Finite values.
+    assert_eq!(
+        ModernComponent(&Some(10.0)).to_css_string(),
+        "10".to_string()
+    );
+    assert_eq!(
+        ModernComponent(&Some(-10.0)).to_css_string(),
+        "-10".to_string()
+    );
+    assert_eq!(ModernComponent(&Some(0.0)).to_css_string(), "0".to_string());
+    assert_eq!(
+        ModernComponent(&Some(-0.0)).to_css_string(),
+        "0".to_string()
+    );
+
+    // Infinite values.
+    assert_eq!(
+        ModernComponent(&Some(f32::INFINITY)).to_css_string(),
+        "calc(infinity)".to_string()
+    );
+    assert_eq!(
+        ModernComponent(&Some(f32::NEG_INFINITY)).to_css_string(),
+        "calc(-infinity)".to_string()
+    );
+
+    // NaN.
+    assert_eq!(
+        ModernComponent(&Some(f32::NAN)).to_css_string(),
+        "calc(NaN)".to_string()
+    );
+}
diff --git a/src/color.rs b/src/color.rs
index 477c40eb..d5f9a5c0 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -2,19 +2,48 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+//! General color-parsing utilities, independent on the specific color storage and parsing
+//! implementation.
+//!
+//! For a more complete css-color implementation take a look at cssparser-color crate, or at
+//! Gecko's color module.
+
 // Allow text like <color> in docs.
 #![allow(rustdoc::invalid_html_tags)]
 
-use std::f32::consts::PI;
+/// The opaque alpha value of 1.0.
+pub const OPAQUE: f32 = 1.0;
+
+use crate::ToCss;
 use std::fmt;
 use std::str::FromStr;
 
-use super::{CowRcStr, ParseError, Parser, ToCss, Token};
-
-#[cfg(feature = "serde")]
-use serde::{Deserialize, Deserializer, Serialize, Serializer};
+/// Clamp a 0..1 number to a 0..255 range to u8.
+///
+/// Whilst scaling by 256 and flooring would provide
+/// an equal distribution of integers to percentage inputs,
+/// this is not what Gecko does so we instead multiply by 255
+/// and round (adding 0.5 and flooring is equivalent to rounding)
+///
+/// Chrome does something similar for the alpha value, but not
+/// the rgb values.
+///
+/// See <https://bugzilla.mozilla.org/show_bug.cgi?id=1340484>
+///
+/// Clamping to 256 and rounding after would let 1.0 map to 256, and
+/// `256.0_f32 as u8` is undefined behavior:
+///
+/// <https://github.com/rust-lang/rust/issues/10184>
+#[inline]
+pub fn clamp_unit_f32(val: f32) -> u8 {
+    clamp_floor_256_f32(val * 255.)
+}
 
-const OPAQUE: f32 = 1.0;
+/// Round and clamp a single number to a u8.
+#[inline]
+pub fn clamp_floor_256_f32(val: f32) -> u8 {
+    val.round().clamp(0., 255.) as u8
+}
 
 /// Serialize the alpha copmonent of a color according to the specification.
 /// <https://drafts.csswg.org/css-color-4/#serializing-alpha-values>
@@ -45,438 +74,6 @@ pub fn serialize_color_alpha(
     rounded_alpha.to_css(dest)
 }
 
-/// A [`ModernComponent`] can serialize to `none`, `nan`, `infinity` and
-/// floating point values.
-struct ModernComponent<'a>(&'a Option<f32>);
-
-impl<'a> ToCss for ModernComponent<'a> {
-    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
-    where
-        W: fmt::Write,
-    {
-        if let Some(value) = self.0 {
-            if value.is_finite() {
-                value.to_css(dest)
-            } else if value.is_nan() {
-                dest.write_str("calc(NaN)")
-            } else {
-                debug_assert!(value.is_infinite());
-                if value.is_sign_negative() {
-                    dest.write_str("calc(-infinity)")
-                } else {
-                    dest.write_str("calc(infinity)")
-                }
-            }
-        } else {
-            dest.write_str("none")
-        }
-    }
-}
-
-// Guaratees hue in [0..360)
-fn normalize_hue(hue: f32) -> f32 {
-    // <https://drafts.csswg.org/css-values/#angles>
-    // Subtract an integer before rounding, to avoid some rounding errors:
-    hue - 360.0 * (hue / 360.0).floor()
-}
-
-/// A color with red, green, blue, and alpha components, in a byte each.
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub struct RgbaLegacy {
-    /// The red component.
-    pub red: u8,
-    /// The green component.
-    pub green: u8,
-    /// The blue component.
-    pub blue: u8,
-    /// The alpha component.
-    pub alpha: f32,
-}
-
-impl RgbaLegacy {
-    /// Constructs a new RGBA value from float components. It expects the red,
-    /// green, blue and alpha channels in that order, and all values will be
-    /// clamped to the 0.0 ... 1.0 range.
-    #[inline]
-    pub fn from_floats(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
-        Self::new(
-            clamp_unit_f32(red),
-            clamp_unit_f32(green),
-            clamp_unit_f32(blue),
-            alpha.clamp(0.0, OPAQUE),
-        )
-    }
-
-    /// Same thing, but with `u8` values instead of floats in the 0 to 1 range.
-    #[inline]
-    pub const fn new(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
-        Self {
-            red,
-            green,
-            blue,
-            alpha,
-        }
-    }
-}
-
-#[cfg(feature = "serde")]
-impl Serialize for RgbaLegacy {
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: Serializer,
-    {
-        (self.red, self.green, self.blue, self.alpha).serialize(serializer)
-    }
-}
-
-#[cfg(feature = "serde")]
-impl<'de> Deserialize<'de> for RgbaLegacy {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        let (r, g, b, a) = Deserialize::deserialize(deserializer)?;
-        Ok(RgbaLegacy::new(r, g, b, a))
-    }
-}
-
-impl ToCss for RgbaLegacy {
-    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
-    where
-        W: fmt::Write,
-    {
-        let has_alpha = self.alpha != OPAQUE;
-
-        dest.write_str(if has_alpha { "rgba(" } else { "rgb(" })?;
-        self.red.to_css(dest)?;
-        dest.write_str(", ")?;
-        self.green.to_css(dest)?;
-        dest.write_str(", ")?;
-        self.blue.to_css(dest)?;
-
-        // Legacy syntax does not allow none components.
-        serialize_color_alpha(dest, Some(self.alpha), true)?;
-
-        dest.write_char(')')
-    }
-}
-
-/// Color specified by hue, saturation and lightness components.
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub struct Hsl {
-    /// The hue component.
-    pub hue: Option<f32>,
-    /// The saturation component.
-    pub saturation: Option<f32>,
-    /// The lightness component.
-    pub lightness: Option<f32>,
-    /// The alpha component.
-    pub alpha: Option<f32>,
-}
-
-impl Hsl {
-    /// Construct a new HSL color from it's components.
-    pub fn new(
-        hue: Option<f32>,
-        saturation: Option<f32>,
-        lightness: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self {
-        Self {
-            hue,
-            saturation,
-            lightness,
-            alpha,
-        }
-    }
-}
-
-impl ToCss for Hsl {
-    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
-    where
-        W: fmt::Write,
-    {
-        // HSL serializes to RGB, so we have to convert it.
-        let (red, green, blue) = hsl_to_rgb(
-            self.hue.unwrap_or(0.0) / 360.0,
-            self.saturation.unwrap_or(0.0),
-            self.lightness.unwrap_or(0.0),
-        );
-
-        RgbaLegacy::from_floats(red, green, blue, self.alpha.unwrap_or(OPAQUE)).to_css(dest)
-    }
-}
-
-#[cfg(feature = "serde")]
-impl Serialize for Hsl {
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: Serializer,
-    {
-        (self.hue, self.saturation, self.lightness, self.alpha).serialize(serializer)
-    }
-}
-
-#[cfg(feature = "serde")]
-impl<'de> Deserialize<'de> for Hsl {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        let (lightness, a, b, alpha) = Deserialize::deserialize(deserializer)?;
-        Ok(Self::new(lightness, a, b, alpha))
-    }
-}
-
-/// Color specified by hue, whiteness and blackness components.
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub struct Hwb {
-    /// The hue component.
-    pub hue: Option<f32>,
-    /// The whiteness component.
-    pub whiteness: Option<f32>,
-    /// The blackness component.
-    pub blackness: Option<f32>,
-    /// The alpha component.
-    pub alpha: Option<f32>,
-}
-
-impl Hwb {
-    /// Construct a new HWB color from it's components.
-    pub fn new(
-        hue: Option<f32>,
-        whiteness: Option<f32>,
-        blackness: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self {
-        Self {
-            hue,
-            whiteness,
-            blackness,
-            alpha,
-        }
-    }
-}
-
-impl ToCss for Hwb {
-    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
-    where
-        W: fmt::Write,
-    {
-        // HWB serializes to RGB, so we have to convert it.
-        let (red, green, blue) = hwb_to_rgb(
-            self.hue.unwrap_or(0.0) / 360.0,
-            self.whiteness.unwrap_or(0.0),
-            self.blackness.unwrap_or(0.0),
-        );
-
-        RgbaLegacy::from_floats(red, green, blue, self.alpha.unwrap_or(OPAQUE)).to_css(dest)
-    }
-}
-
-#[cfg(feature = "serde")]
-impl Serialize for Hwb {
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: Serializer,
-    {
-        (self.hue, self.whiteness, self.blackness, self.alpha).serialize(serializer)
-    }
-}
-
-#[cfg(feature = "serde")]
-impl<'de> Deserialize<'de> for Hwb {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        let (lightness, whiteness, blackness, alpha) = Deserialize::deserialize(deserializer)?;
-        Ok(Self::new(lightness, whiteness, blackness, alpha))
-    }
-}
-
-// NOTE: LAB and OKLAB is not declared inside the [impl_lab_like] macro,
-// because it causes cbindgen to ignore them.
-
-/// Color specified by lightness, a- and b-axis components.
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub struct Lab {
-    /// The lightness component.
-    pub lightness: Option<f32>,
-    /// The a-axis component.
-    pub a: Option<f32>,
-    /// The b-axis component.
-    pub b: Option<f32>,
-    /// The alpha component.
-    pub alpha: Option<f32>,
-}
-
-/// Color specified by lightness, a- and b-axis components.
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub struct Oklab {
-    /// The lightness component.
-    pub lightness: Option<f32>,
-    /// The a-axis component.
-    pub a: Option<f32>,
-    /// The b-axis component.
-    pub b: Option<f32>,
-    /// The alpha component.
-    pub alpha: Option<f32>,
-}
-
-macro_rules! impl_lab_like {
-    ($cls:ident, $fname:literal) => {
-        impl $cls {
-            /// Construct a new Lab color format with lightness, a, b and alpha components.
-            pub fn new(
-                lightness: Option<f32>,
-                a: Option<f32>,
-                b: Option<f32>,
-                alpha: Option<f32>,
-            ) -> Self {
-                Self {
-                    lightness,
-                    a,
-                    b,
-                    alpha,
-                }
-            }
-        }
-
-        #[cfg(feature = "serde")]
-        impl Serialize for $cls {
-            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-            where
-                S: Serializer,
-            {
-                (self.lightness, self.a, self.b, self.alpha).serialize(serializer)
-            }
-        }
-
-        #[cfg(feature = "serde")]
-        impl<'de> Deserialize<'de> for $cls {
-            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-            where
-                D: Deserializer<'de>,
-            {
-                let (lightness, a, b, alpha) = Deserialize::deserialize(deserializer)?;
-                Ok(Self::new(lightness, a, b, alpha))
-            }
-        }
-
-        impl ToCss for $cls {
-            fn to_css<W>(&self, dest: &mut W) -> fmt::Result
-            where
-                W: fmt::Write,
-            {
-                dest.write_str($fname)?;
-                dest.write_str("(")?;
-                ModernComponent(&self.lightness).to_css(dest)?;
-                dest.write_char(' ')?;
-                ModernComponent(&self.a).to_css(dest)?;
-                dest.write_char(' ')?;
-                ModernComponent(&self.b).to_css(dest)?;
-                serialize_color_alpha(dest, self.alpha, false)?;
-                dest.write_char(')')
-            }
-        }
-    };
-}
-
-impl_lab_like!(Lab, "lab");
-impl_lab_like!(Oklab, "oklab");
-
-// NOTE: LCH and OKLCH is not declared inside the [impl_lch_like] macro,
-// because it causes cbindgen to ignore them.
-
-/// Color specified by lightness, chroma and hue components.
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub struct Lch {
-    /// The lightness component.
-    pub lightness: Option<f32>,
-    /// The chroma component.
-    pub chroma: Option<f32>,
-    /// The hue component.
-    pub hue: Option<f32>,
-    /// The alpha component.
-    pub alpha: Option<f32>,
-}
-
-/// Color specified by lightness, chroma and hue components.
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub struct Oklch {
-    /// The lightness component.
-    pub lightness: Option<f32>,
-    /// The chroma component.
-    pub chroma: Option<f32>,
-    /// The hue component.
-    pub hue: Option<f32>,
-    /// The alpha component.
-    pub alpha: Option<f32>,
-}
-
-macro_rules! impl_lch_like {
-    ($cls:ident, $fname:literal) => {
-        impl $cls {
-            /// Construct a new color with lightness, chroma and hue components.
-            pub fn new(
-                lightness: Option<f32>,
-                chroma: Option<f32>,
-                hue: Option<f32>,
-                alpha: Option<f32>,
-            ) -> Self {
-                Self {
-                    lightness,
-                    chroma,
-                    hue,
-                    alpha,
-                }
-            }
-        }
-
-        #[cfg(feature = "serde")]
-        impl Serialize for $cls {
-            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-            where
-                S: Serializer,
-            {
-                (self.lightness, self.chroma, self.hue, self.alpha).serialize(serializer)
-            }
-        }
-
-        #[cfg(feature = "serde")]
-        impl<'de> Deserialize<'de> for $cls {
-            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-            where
-                D: Deserializer<'de>,
-            {
-                let (lightness, chroma, hue, alpha) = Deserialize::deserialize(deserializer)?;
-                Ok(Self::new(lightness, chroma, hue, alpha))
-            }
-        }
-
-        impl ToCss for $cls {
-            fn to_css<W>(&self, dest: &mut W) -> fmt::Result
-            where
-                W: fmt::Write,
-            {
-                dest.write_str($fname)?;
-                dest.write_str("(")?;
-                ModernComponent(&self.lightness).to_css(dest)?;
-                dest.write_char(' ')?;
-                ModernComponent(&self.chroma).to_css(dest)?;
-                dest.write_char(' ')?;
-                ModernComponent(&self.hue).to_css(dest)?;
-                serialize_color_alpha(dest, self.alpha, false)?;
-                dest.write_char(')')
-            }
-        }
-    };
-}
-
-impl_lch_like!(Lch, "lch");
-impl_lch_like!(Oklch, "oklch");
-
 /// A Predefined color space specified in:
 /// <https://drafts.csswg.org/css-color-4/#predefined>
 #[derive(Clone, Copy, PartialEq, Debug)]
@@ -543,352 +140,29 @@ impl ToCss for PredefinedColorSpace {
     }
 }
 
-/// A color specified by the color() function.
-/// <https://drafts.csswg.org/css-color-4/#color-function>
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub struct ColorFunction {
-    /// The color space for this color.
-    pub color_space: PredefinedColorSpace,
-    /// The first component of the color.  Either red or x.
-    pub c1: Option<f32>,
-    /// The second component of the color.  Either green or y.
-    pub c2: Option<f32>,
-    /// The third component of the color.  Either blue or z.
-    pub c3: Option<f32>,
-    /// The alpha component of the color.
-    pub alpha: Option<f32>,
-}
-
-impl ColorFunction {
-    /// Construct a new color function definition with the given color space and
-    /// color components.
-    pub fn new(
-        color_space: PredefinedColorSpace,
-        c1: Option<f32>,
-        c2: Option<f32>,
-        c3: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self {
-        Self {
-            color_space,
-            c1,
-            c2,
-            c3,
-            alpha,
-        }
-    }
-}
-
-impl ToCss for ColorFunction {
-    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
-    where
-        W: fmt::Write,
-    {
-        dest.write_str("color(")?;
-        self.color_space.to_css(dest)?;
-        dest.write_char(' ')?;
-        ModernComponent(&self.c1).to_css(dest)?;
-        dest.write_char(' ')?;
-        ModernComponent(&self.c2).to_css(dest)?;
-        dest.write_char(' ')?;
-        ModernComponent(&self.c3).to_css(dest)?;
-
-        serialize_color_alpha(dest, self.alpha, false)?;
-
-        dest.write_char(')')
-    }
-}
-
-/// Describes one of the value <color> values according to the CSS
-/// specification.
-///
-/// Most components are `Option<_>`, so when the value is `None`, that component
-/// serializes to the "none" keyword.
-///
-/// <https://drafts.csswg.org/css-color-4/#color-type>
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub enum Color {
-    /// The 'currentcolor' keyword.
-    CurrentColor,
-    /// Specify sRGB colors directly by their red/green/blue/alpha chanels.
-    Rgba(RgbaLegacy),
-    /// Specifies a color in sRGB using hue, saturation and lightness components.
-    Hsl(Hsl),
-    /// Specifies a color in sRGB using hue, whiteness and blackness components.
-    Hwb(Hwb),
-    /// Specifies a CIELAB color by CIE Lightness and its a- and b-axis hue
-    /// coordinates (red/green-ness, and yellow/blue-ness) using the CIE LAB
-    /// rectangular coordinate model.
-    Lab(Lab),
-    /// Specifies a CIELAB color by CIE Lightness, Chroma, and hue using the
-    /// CIE LCH cylindrical coordinate model.
-    Lch(Lch),
-    /// Specifies an Oklab color by Oklab Lightness and its a- and b-axis hue
-    /// coordinates (red/green-ness, and yellow/blue-ness) using the Oklab
-    /// rectangular coordinate model.
-    Oklab(Oklab),
-    /// Specifies an Oklab color by Oklab Lightness, Chroma, and hue using
-    /// the OKLCH cylindrical coordinate model.
-    Oklch(Oklch),
-    /// Specifies a color in a predefined color space.
-    ColorFunction(ColorFunction),
-}
-
-impl ToCss for Color {
-    fn to_css<W>(&self, dest: &mut W) -> fmt::Result
-    where
-        W: fmt::Write,
-    {
-        match *self {
-            Color::CurrentColor => dest.write_str("currentcolor"),
-            Color::Rgba(rgba) => rgba.to_css(dest),
-            Color::Hsl(hsl) => hsl.to_css(dest),
-            Color::Hwb(hwb) => hwb.to_css(dest),
-            Color::Lab(lab) => lab.to_css(dest),
-            Color::Lch(lch) => lch.to_css(dest),
-            Color::Oklab(lab) => lab.to_css(dest),
-            Color::Oklch(lch) => lch.to_css(dest),
-            Color::ColorFunction(color_function) => color_function.to_css(dest),
-        }
-    }
-}
-
-/// Either a number or a percentage.
-pub enum NumberOrPercentage {
-    /// `<number>`.
-    Number {
-        /// The numeric value parsed, as a float.
-        value: f32,
-    },
-    /// `<percentage>`
-    Percentage {
-        /// The value as a float, divided by 100 so that the nominal range is
-        /// 0.0 to 1.0.
-        unit_value: f32,
-    },
-}
-
-impl NumberOrPercentage {
-    /// Return the value as a percentage.
-    pub fn unit_value(&self) -> f32 {
-        match *self {
-            NumberOrPercentage::Number { value } => value,
-            NumberOrPercentage::Percentage { unit_value } => unit_value,
-        }
-    }
-
-    /// Return the value as a number with a percentage adjusted to the
-    /// `percentage_basis`.
-    pub fn value(&self, percentage_basis: f32) -> f32 {
-        match *self {
-            Self::Number { value } => value,
-            Self::Percentage { unit_value } => unit_value * percentage_basis,
-        }
-    }
-}
-
-/// Either an angle or a number.
-pub enum AngleOrNumber {
-    /// `<number>`.
-    Number {
-        /// The numeric value parsed, as a float.
-        value: f32,
-    },
-    /// `<angle>`
-    Angle {
-        /// The value as a number of degrees.
-        degrees: f32,
-    },
-}
-
-impl AngleOrNumber {
-    /// Return the angle in degrees. `AngleOrNumber::Number` is returned as
-    /// degrees, because it is the canonical unit.
-    pub fn degrees(&self) -> f32 {
-        match *self {
-            AngleOrNumber::Number { value } => value,
-            AngleOrNumber::Angle { degrees } => degrees,
-        }
-    }
-}
-
-/// A trait that can be used to hook into how `cssparser` parses color
-/// components, with the intention of implementing more complicated behavior.
-///
-/// For example, this is used by Servo to support calc() in color.
-pub trait ColorParser<'i> {
-    /// The type that the parser will construct on a successful parse.
-    type Output: FromParsedColor;
-
-    /// A custom error type that can be returned from the parsing functions.
-    type Error: 'i;
-
-    /// Parse an `<angle>` or `<number>`.
-    ///
-    /// Returns the result in degrees.
-    fn parse_angle_or_number<'t>(
-        &self,
-        input: &mut Parser<'i, 't>,
-    ) -> Result<AngleOrNumber, ParseError<'i, Self::Error>> {
-        let location = input.current_source_location();
-        Ok(match *input.next()? {
-            Token::Number { value, .. } => AngleOrNumber::Number { value },
-            Token::Dimension {
-                value: v, ref unit, ..
-            } => {
-                let degrees = match_ignore_ascii_case! { unit,
-                    "deg" => v,
-                    "grad" => v * 360. / 400.,
-                    "rad" => v * 360. / (2. * PI),
-                    "turn" => v * 360.,
-                    _ => {
-                        return Err(location.new_unexpected_token_error(Token::Ident(unit.clone())))
-                    }
-                };
-
-                AngleOrNumber::Angle { degrees }
-            }
-            ref t => return Err(location.new_unexpected_token_error(t.clone())),
-        })
-    }
-
-    /// Parse a `<percentage>` value.
-    ///
-    /// Returns the result in a number from 0.0 to 1.0.
-    fn parse_percentage<'t>(
-        &self,
-        input: &mut Parser<'i, 't>,
-    ) -> Result<f32, ParseError<'i, Self::Error>> {
-        input.expect_percentage().map_err(From::from)
-    }
-
-    /// Parse a `<number>` value.
-    fn parse_number<'t>(
-        &self,
-        input: &mut Parser<'i, 't>,
-    ) -> Result<f32, ParseError<'i, Self::Error>> {
-        input.expect_number().map_err(From::from)
-    }
-
-    /// Parse a `<number>` value or a `<percentage>` value.
-    fn parse_number_or_percentage<'t>(
-        &self,
-        input: &mut Parser<'i, 't>,
-    ) -> Result<NumberOrPercentage, ParseError<'i, Self::Error>> {
-        let location = input.current_source_location();
-        Ok(match *input.next()? {
-            Token::Number { value, .. } => NumberOrPercentage::Number { value },
-            Token::Percentage { unit_value, .. } => NumberOrPercentage::Percentage { unit_value },
-            ref t => return Err(location.new_unexpected_token_error(t.clone())),
-        })
-    }
-}
-
-/// Default implementation of a [`ColorParser`]
-pub struct DefaultColorParser;
-
-impl<'i> ColorParser<'i> for DefaultColorParser {
-    type Output = Color;
-    type Error = ();
-}
-
-impl Color {
-    /// Parse a <color> value, per CSS Color Module Level 3.
-    ///
-    /// FIXME(#2) Deprecated CSS2 System Colors are not supported yet.
-    pub fn parse<'i>(input: &mut Parser<'i, '_>) -> Result<Color, ParseError<'i, ()>> {
-        parse_color_with(&DefaultColorParser, input)
-    }
-}
-
-/// This trait is used by the [`ColorParser`] to construct colors of any type.
-pub trait FromParsedColor {
-    /// Construct a new color from the CSS `currentcolor` keyword.
-    fn from_current_color() -> Self;
-
-    /// Construct a new color from red, green, blue and alpha components.
-    fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self;
-
-    /// Construct a new color from hue, saturation, lightness and alpha components.
-    fn from_hsl(
-        hue: Option<f32>,
-        saturation: Option<f32>,
-        lightness: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self;
-
-    /// Construct a new color from hue, blackness, whiteness and alpha components.
-    fn from_hwb(
-        hue: Option<f32>,
-        whiteness: Option<f32>,
-        blackness: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self;
-
-    /// Construct a new color from the `lab` notation.
-    fn from_lab(lightness: Option<f32>, a: Option<f32>, b: Option<f32>, alpha: Option<f32>)
-        -> Self;
-
-    /// Construct a new color from the `lch` notation.
-    fn from_lch(
-        lightness: Option<f32>,
-        chroma: Option<f32>,
-        hue: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self;
-
-    /// Construct a new color from the `oklab` notation.
-    fn from_oklab(
-        lightness: Option<f32>,
-        a: Option<f32>,
-        b: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self;
-
-    /// Construct a new color from the `oklch` notation.
-    fn from_oklch(
-        lightness: Option<f32>,
-        chroma: Option<f32>,
-        hue: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self;
-
-    /// Construct a new color with a predefined color space.
-    fn from_color_function(
-        color_space: PredefinedColorSpace,
-        c1: Option<f32>,
-        c2: Option<f32>,
-        c3: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self;
-}
-
 /// Parse a color hash, without the leading '#' character.
 #[inline]
-pub fn parse_hash_color<'i, O>(value: &[u8]) -> Result<O, ()>
-where
-    O: FromParsedColor,
-{
+pub fn parse_hash_color(value: &[u8]) -> Result<(u8, u8, u8, f32), ()> {
     Ok(match value.len() {
-        8 => O::from_rgba(
+        8 => (
             from_hex(value[0])? * 16 + from_hex(value[1])?,
             from_hex(value[2])? * 16 + from_hex(value[3])?,
             from_hex(value[4])? * 16 + from_hex(value[5])?,
             (from_hex(value[6])? * 16 + from_hex(value[7])?) as f32 / 255.0,
         ),
-        6 => O::from_rgba(
+        6 => (
             from_hex(value[0])? * 16 + from_hex(value[1])?,
             from_hex(value[2])? * 16 + from_hex(value[3])?,
             from_hex(value[4])? * 16 + from_hex(value[5])?,
             OPAQUE,
         ),
-        4 => O::from_rgba(
+        4 => (
             from_hex(value[0])? * 17,
             from_hex(value[1])? * 17,
             from_hex(value[2])? * 17,
             (from_hex(value[3])? * 17) as f32 / 255.0,
         ),
-        3 => O::from_rgba(
+        3 => (
             from_hex(value[0])? * 17,
             from_hex(value[1])? * 17,
             from_hex(value[2])? * 17,
@@ -898,112 +172,6 @@ where
     })
 }
 
-/// Parse a CSS color using the specified [`ColorParser`] and return a new color
-/// value on success.
-pub fn parse_color_with<'i, 't, P>(
-    color_parser: &P,
-    input: &mut Parser<'i, 't>,
-) -> Result<P::Output, ParseError<'i, P::Error>>
-where
-    P: ColorParser<'i>,
-{
-    let location = input.current_source_location();
-    let token = input.next()?;
-    match *token {
-        Token::Hash(ref value) | Token::IDHash(ref value) => parse_hash_color(value.as_bytes()),
-        Token::Ident(ref value) => parse_color_keyword(value),
-        Token::Function(ref name) => {
-            let name = name.clone();
-            return input.parse_nested_block(|arguments| {
-                parse_color_function(color_parser, name, arguments)
-            });
-        }
-        _ => Err(()),
-    }
-    .map_err(|()| location.new_unexpected_token_error(token.clone()))
-}
-
-impl FromParsedColor for Color {
-    #[inline]
-    fn from_current_color() -> Self {
-        Color::CurrentColor
-    }
-
-    #[inline]
-    fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
-        Color::Rgba(RgbaLegacy::new(red, green, blue, alpha))
-    }
-
-    fn from_hsl(
-        hue: Option<f32>,
-        saturation: Option<f32>,
-        lightness: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self {
-        Color::Hsl(Hsl::new(hue, saturation, lightness, alpha))
-    }
-
-    fn from_hwb(
-        hue: Option<f32>,
-        blackness: Option<f32>,
-        whiteness: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self {
-        Color::Hwb(Hwb::new(hue, blackness, whiteness, alpha))
-    }
-
-    #[inline]
-    fn from_lab(
-        lightness: Option<f32>,
-        a: Option<f32>,
-        b: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self {
-        Color::Lab(Lab::new(lightness, a, b, alpha))
-    }
-
-    #[inline]
-    fn from_lch(
-        lightness: Option<f32>,
-        chroma: Option<f32>,
-        hue: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self {
-        Color::Lch(Lch::new(lightness, chroma, hue, alpha))
-    }
-
-    #[inline]
-    fn from_oklab(
-        lightness: Option<f32>,
-        a: Option<f32>,
-        b: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self {
-        Color::Oklab(Oklab::new(lightness, a, b, alpha))
-    }
-
-    #[inline]
-    fn from_oklch(
-        lightness: Option<f32>,
-        chroma: Option<f32>,
-        hue: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self {
-        Color::Oklch(Oklch::new(lightness, chroma, hue, alpha))
-    }
-
-    #[inline]
-    fn from_color_function(
-        color_space: PredefinedColorSpace,
-        c1: Option<f32>,
-        c2: Option<f32>,
-        c3: Option<f32>,
-        alpha: Option<f32>,
-    ) -> Self {
-        Color::ColorFunction(ColorFunction::new(color_space, c1, c2, c3, alpha))
-    }
-}
-
 ascii_case_insensitive_phf_map! {
     named_colors -> (u8, u8, u8) = {
         "black" => (0, 0, 0),
@@ -1161,12 +329,8 @@ ascii_case_insensitive_phf_map! {
 /// Returns the named color with the given name.
 /// <https://drafts.csswg.org/css-color-4/#typedef-named-color>
 #[inline]
-pub fn parse_named_color<Output>(ident: &str) -> Result<Output, ()>
-where
-    Output: FromParsedColor,
-{
-    let &(r, g, b) = named_colors::get(ident).ok_or(())?;
-    Ok(Output::from_rgba(r, g, b, 1.0))
+pub fn parse_named_color(ident: &str) -> Result<(u8, u8, u8), ()> {
+    named_colors::get(ident).copied().ok_or(())
 }
 
 /// Returns an iterator over all named CSS colors.
@@ -1176,23 +340,6 @@ pub fn all_named_colors() -> impl Iterator<Item = (&'static str, (u8, u8, u8))>
     named_colors::entries().map(|(k, v)| (*k, *v))
 }
 
-/// Return the named color with the given name.
-///
-/// Matching is case-insensitive in the ASCII range.
-/// CSS escaping (if relevant) should be resolved before calling this function.
-/// (For example, the value of an `Ident` token is fine.)
-#[inline]
-pub fn parse_color_keyword<Output>(ident: &str) -> Result<Output, ()>
-where
-    Output: FromParsedColor,
-{
-    Ok(match_ignore_ascii_case! { ident ,
-        "transparent" => Output::from_rgba(0, 0, 0, 0.0),
-        "currentcolor" => Output::from_current_color(),
-        _ => return parse_named_color(ident),
-    })
-}
-
 #[inline]
 fn from_hex(c: u8) -> Result<u8, ()> {
     match c {
@@ -1202,466 +349,3 @@ fn from_hex(c: u8) -> Result<u8, ()> {
         _ => Err(()),
     }
 }
-
-fn clamp_unit_f32(val: f32) -> u8 {
-    // Whilst scaling by 256 and flooring would provide
-    // an equal distribution of integers to percentage inputs,
-    // this is not what Gecko does so we instead multiply by 255
-    // and round (adding 0.5 and flooring is equivalent to rounding)
-    //
-    // Chrome does something similar for the alpha value, but not
-    // the rgb values.
-    //
-    // See <https://bugzilla.mozilla.org/show_bug.cgi?id=1340484>
-    //
-    // Clamping to 256 and rounding after would let 1.0 map to 256, and
-    // `256.0_f32 as u8` is undefined behavior:
-    //
-    // <https://github.com/rust-lang/rust/issues/10184>
-    clamp_floor_256_f32(val * 255.)
-}
-
-fn clamp_floor_256_f32(val: f32) -> u8 {
-    val.round().clamp(0., 255.) as u8
-}
-
-fn parse_none_or<'i, 't, F, T, E>(input: &mut Parser<'i, 't>, thing: F) -> Result<Option<T>, E>
-where
-    F: FnOnce(&mut Parser<'i, 't>) -> Result<T, E>,
-{
-    match input.try_parse(|p| p.expect_ident_matching("none")) {
-        Ok(_) => Ok(None),
-        Err(_) => Ok(Some(thing(input)?)),
-    }
-}
-
-/// Parse one of the color functions: rgba(), lab(), color(), etc.
-#[inline]
-fn parse_color_function<'i, 't, P>(
-    color_parser: &P,
-    name: CowRcStr<'i>,
-    arguments: &mut Parser<'i, 't>,
-) -> Result<P::Output, ParseError<'i, P::Error>>
-where
-    P: ColorParser<'i>,
-{
-    let color = match_ignore_ascii_case! { &name,
-        "rgb" | "rgba" => parse_rgb(color_parser, arguments),
-
-        "hsl" | "hsla" => parse_hsl(color_parser, arguments),
-
-        "hwb" => parse_hwb(color_parser, arguments),
-
-        // for L: 0% = 0.0, 100% = 100.0
-        // for a and b: -100% = -125, 100% = 125
-        "lab" => parse_lab_like(color_parser, arguments, 100.0, 125.0, P::Output::from_lab),
-
-        // for L: 0% = 0.0, 100% = 100.0
-        // for C: 0% = 0, 100% = 150
-        "lch" => parse_lch_like(color_parser, arguments, 100.0, 150.0, P::Output::from_lch),
-
-        // for L: 0% = 0.0, 100% = 1.0
-        // for a and b: -100% = -0.4, 100% = 0.4
-        "oklab" => parse_lab_like(color_parser, arguments, 1.0, 0.4, P::Output::from_oklab),
-
-        // for L: 0% = 0.0, 100% = 1.0
-        // for C: 0% = 0.0 100% = 0.4
-        "oklch" => parse_lch_like(color_parser, arguments, 1.0, 0.4, P::Output::from_oklch),
-
-        "color" => parse_color_with_color_space(color_parser, arguments),
-
-        _ => return Err(arguments.new_unexpected_token_error(Token::Ident(name))),
-    }?;
-
-    arguments.expect_exhausted()?;
-
-    Ok(color)
-}
-
-/// Parse the alpha component by itself from either number or percentage,
-/// clipping the result to [0.0..1.0].
-#[inline]
-fn parse_alpha_component<'i, 't, P>(
-    color_parser: &P,
-    arguments: &mut Parser<'i, 't>,
-) -> Result<f32, ParseError<'i, P::Error>>
-where
-    P: ColorParser<'i>,
-{
-    Ok(color_parser
-        .parse_number_or_percentage(arguments)?
-        .unit_value()
-        .clamp(0.0, OPAQUE))
-}
-
-fn parse_legacy_alpha<'i, 't, P>(
-    color_parser: &P,
-    arguments: &mut Parser<'i, 't>,
-) -> Result<f32, ParseError<'i, P::Error>>
-where
-    P: ColorParser<'i>,
-{
-    Ok(if !arguments.is_exhausted() {
-        arguments.expect_comma()?;
-        parse_alpha_component(color_parser, arguments)?
-    } else {
-        OPAQUE
-    })
-}
-
-fn parse_modern_alpha<'i, 't, P>(
-    color_parser: &P,
-    arguments: &mut Parser<'i, 't>,
-) -> Result<Option<f32>, ParseError<'i, P::Error>>
-where
-    P: ColorParser<'i>,
-{
-    if !arguments.is_exhausted() {
-        arguments.expect_delim('/')?;
-        parse_none_or(arguments, |p| parse_alpha_component(color_parser, p))
-    } else {
-        Ok(Some(OPAQUE))
-    }
-}
-
-#[inline]
-fn parse_rgb<'i, 't, P>(
-    color_parser: &P,
-    arguments: &mut Parser<'i, 't>,
-) -> Result<P::Output, ParseError<'i, P::Error>>
-where
-    P: ColorParser<'i>,
-{
-    let maybe_red = parse_none_or(arguments, |p| color_parser.parse_number_or_percentage(p))?;
-
-    // If the first component is not "none" and is followed by a comma, then we
-    // are parsing the legacy syntax.
-    let is_legacy_syntax = maybe_red.is_some() && arguments.try_parse(|p| p.expect_comma()).is_ok();
-
-    let (red, green, blue, alpha) = if is_legacy_syntax {
-        let (red, green, blue) = match maybe_red.unwrap() {
-            NumberOrPercentage::Number { value } => {
-                let red = clamp_floor_256_f32(value);
-                let green = clamp_floor_256_f32(color_parser.parse_number(arguments)?);
-                arguments.expect_comma()?;
-                let blue = clamp_floor_256_f32(color_parser.parse_number(arguments)?);
-                (red, green, blue)
-            }
-            NumberOrPercentage::Percentage { unit_value } => {
-                let red = clamp_unit_f32(unit_value);
-                let green = clamp_unit_f32(color_parser.parse_percentage(arguments)?);
-                arguments.expect_comma()?;
-                let blue = clamp_unit_f32(color_parser.parse_percentage(arguments)?);
-                (red, green, blue)
-            }
-        };
-
-        let alpha = parse_legacy_alpha(color_parser, arguments)?;
-
-        (red, green, blue, alpha)
-    } else {
-        #[inline]
-        fn get_component_value(c: Option<NumberOrPercentage>) -> u8 {
-            c.map(|c| match c {
-                NumberOrPercentage::Number { value } => clamp_floor_256_f32(value),
-                NumberOrPercentage::Percentage { unit_value } => clamp_unit_f32(unit_value),
-            })
-            .unwrap_or(0)
-        }
-
-        let red = get_component_value(maybe_red);
-
-        let green = get_component_value(parse_none_or(arguments, |p| {
-            color_parser.parse_number_or_percentage(p)
-        })?);
-
-        let blue = get_component_value(parse_none_or(arguments, |p| {
-            color_parser.parse_number_or_percentage(p)
-        })?);
-
-        let alpha = parse_modern_alpha(color_parser, arguments)?.unwrap_or(0.0);
-
-        (red, green, blue, alpha)
-    };
-
-    Ok(P::Output::from_rgba(red, green, blue, alpha))
-}
-
-/// Parses hsl syntax.
-///
-/// <https://drafts.csswg.org/css-color/#the-hsl-notation>
-#[inline]
-fn parse_hsl<'i, 't, P>(
-    color_parser: &P,
-    arguments: &mut Parser<'i, 't>,
-) -> Result<P::Output, ParseError<'i, P::Error>>
-where
-    P: ColorParser<'i>,
-{
-    let maybe_hue = parse_none_or(arguments, |p| color_parser.parse_angle_or_number(p))?;
-
-    // If the hue is not "none" and is followed by a comma, then we are parsing
-    // the legacy syntax.
-    let is_legacy_syntax = maybe_hue.is_some() && arguments.try_parse(|p| p.expect_comma()).is_ok();
-
-    let saturation: Option<f32>;
-    let lightness: Option<f32>;
-
-    let alpha = if is_legacy_syntax {
-        saturation = Some(color_parser.parse_percentage(arguments)?);
-        arguments.expect_comma()?;
-        lightness = Some(color_parser.parse_percentage(arguments)?);
-        Some(parse_legacy_alpha(color_parser, arguments)?)
-    } else {
-        saturation = parse_none_or(arguments, |p| color_parser.parse_percentage(p))?;
-        lightness = parse_none_or(arguments, |p| color_parser.parse_percentage(p))?;
-
-        parse_modern_alpha(color_parser, arguments)?
-    };
-
-    let hue = maybe_hue.map(|h| normalize_hue(h.degrees()));
-    let saturation = saturation.map(|s| s.clamp(0.0, 1.0));
-    let lightness = lightness.map(|l| l.clamp(0.0, 1.0));
-
-    Ok(P::Output::from_hsl(hue, saturation, lightness, alpha))
-}
-
-/// Parses hwb syntax.
-///
-/// <https://drafts.csswg.org/css-color/#the-hbw-notation>
-#[inline]
-fn parse_hwb<'i, 't, P>(
-    color_parser: &P,
-    arguments: &mut Parser<'i, 't>,
-) -> Result<P::Output, ParseError<'i, P::Error>>
-where
-    P: ColorParser<'i>,
-{
-    let (hue, whiteness, blackness, alpha) = parse_components(
-        color_parser,
-        arguments,
-        P::parse_angle_or_number,
-        P::parse_percentage,
-        P::parse_percentage,
-    )?;
-
-    let hue = hue.map(|h| normalize_hue(h.degrees()));
-    let whiteness = whiteness.map(|w| w.clamp(0.0, 1.0));
-    let blackness = blackness.map(|b| b.clamp(0.0, 1.0));
-
-    Ok(P::Output::from_hwb(hue, whiteness, blackness, alpha))
-}
-
-/// <https://drafts.csswg.org/css-color-4/#hwb-to-rgb>
-#[inline]
-pub fn hwb_to_rgb(h: f32, w: f32, b: f32) -> (f32, f32, f32) {
-    if w + b >= 1.0 {
-        let gray = w / (w + b);
-        return (gray, gray, gray);
-    }
-
-    // hue is expected in the range [0..1].
-    let (mut red, mut green, mut blue) = hsl_to_rgb(h, 1.0, 0.5);
-    let x = 1.0 - w - b;
-    red = red * x + w;
-    green = green * x + w;
-    blue = blue * x + w;
-    (red, green, blue)
-}
-
-/// <https://drafts.csswg.org/css-color/#hsl-color>
-/// except with h pre-multiplied by 3, to avoid some rounding errors.
-#[inline]
-pub fn hsl_to_rgb(hue: f32, saturation: f32, lightness: f32) -> (f32, f32, f32) {
-    debug_assert!((0.0..=1.0).contains(&hue));
-
-    fn hue_to_rgb(m1: f32, m2: f32, mut h3: f32) -> f32 {
-        if h3 < 0. {
-            h3 += 3.
-        }
-        if h3 > 3. {
-            h3 -= 3.
-        }
-        if h3 * 2. < 1. {
-            m1 + (m2 - m1) * h3 * 2.
-        } else if h3 * 2. < 3. {
-            m2
-        } else if h3 < 2. {
-            m1 + (m2 - m1) * (2. - h3) * 2.
-        } else {
-            m1
-        }
-    }
-    let m2 = if lightness <= 0.5 {
-        lightness * (saturation + 1.)
-    } else {
-        lightness + saturation - lightness * saturation
-    };
-    let m1 = lightness * 2. - m2;
-    let hue_times_3 = hue * 3.;
-    let red = hue_to_rgb(m1, m2, hue_times_3 + 1.);
-    let green = hue_to_rgb(m1, m2, hue_times_3);
-    let blue = hue_to_rgb(m1, m2, hue_times_3 - 1.);
-    (red, green, blue)
-}
-
-type IntoColorFn<Output> =
-    fn(l: Option<f32>, a: Option<f32>, b: Option<f32>, alpha: Option<f32>) -> Output;
-
-#[inline]
-fn parse_lab_like<'i, 't, P>(
-    color_parser: &P,
-    arguments: &mut Parser<'i, 't>,
-    lightness_range: f32,
-    a_b_range: f32,
-    into_color: IntoColorFn<P::Output>,
-) -> Result<P::Output, ParseError<'i, P::Error>>
-where
-    P: ColorParser<'i>,
-{
-    let (lightness, a, b, alpha) = parse_components(
-        color_parser,
-        arguments,
-        P::parse_number_or_percentage,
-        P::parse_number_or_percentage,
-        P::parse_number_or_percentage,
-    )?;
-
-    let lightness = lightness.map(|l| l.value(lightness_range));
-    let a = a.map(|a| a.value(a_b_range));
-    let b = b.map(|b| b.value(a_b_range));
-
-    Ok(into_color(lightness, a, b, alpha))
-}
-
-#[inline]
-fn parse_lch_like<'i, 't, P>(
-    color_parser: &P,
-    arguments: &mut Parser<'i, 't>,
-    lightness_range: f32,
-    chroma_range: f32,
-    into_color: IntoColorFn<P::Output>,
-) -> Result<P::Output, ParseError<'i, P::Error>>
-where
-    P: ColorParser<'i>,
-{
-    let (lightness, chroma, hue, alpha) = parse_components(
-        color_parser,
-        arguments,
-        P::parse_number_or_percentage,
-        P::parse_number_or_percentage,
-        P::parse_angle_or_number,
-    )?;
-
-    let lightness = lightness.map(|l| l.value(lightness_range));
-    let chroma = chroma.map(|c| c.value(chroma_range));
-    let hue = hue.map(|h| normalize_hue(h.degrees()));
-
-    Ok(into_color(lightness, chroma, hue, alpha))
-}
-
-/// Parse the color() function.
-#[inline]
-fn parse_color_with_color_space<'i, 't, P>(
-    color_parser: &P,
-    arguments: &mut Parser<'i, 't>,
-) -> Result<P::Output, ParseError<'i, P::Error>>
-where
-    P: ColorParser<'i>,
-{
-    let color_space = {
-        let location = arguments.current_source_location();
-
-        let ident = arguments.expect_ident()?;
-        PredefinedColorSpace::from_str(ident)
-            .map_err(|_| location.new_unexpected_token_error(Token::Ident(ident.clone())))?
-    };
-
-    let (c1, c2, c3, alpha) = parse_components(
-        color_parser,
-        arguments,
-        P::parse_number_or_percentage,
-        P::parse_number_or_percentage,
-        P::parse_number_or_percentage,
-    )?;
-
-    let c1 = c1.map(|c| c.unit_value());
-    let c2 = c2.map(|c| c.unit_value());
-    let c3 = c3.map(|c| c.unit_value());
-
-    Ok(P::Output::from_color_function(
-        color_space,
-        c1,
-        c2,
-        c3,
-        alpha,
-    ))
-}
-
-type ComponentParseResult<'i, R1, R2, R3, Error> =
-    Result<(Option<R1>, Option<R2>, Option<R3>, Option<f32>), ParseError<'i, Error>>;
-
-/// Parse the color components and alpha with the modern [color-4] syntax.
-pub fn parse_components<'i, 't, P, F1, F2, F3, R1, R2, R3>(
-    color_parser: &P,
-    input: &mut Parser<'i, 't>,
-    f1: F1,
-    f2: F2,
-    f3: F3,
-) -> ComponentParseResult<'i, R1, R2, R3, P::Error>
-where
-    P: ColorParser<'i>,
-    F1: FnOnce(&P, &mut Parser<'i, 't>) -> Result<R1, ParseError<'i, P::Error>>,
-    F2: FnOnce(&P, &mut Parser<'i, 't>) -> Result<R2, ParseError<'i, P::Error>>,
-    F3: FnOnce(&P, &mut Parser<'i, 't>) -> Result<R3, ParseError<'i, P::Error>>,
-{
-    let r1 = parse_none_or(input, |p| f1(color_parser, p))?;
-    let r2 = parse_none_or(input, |p| f2(color_parser, p))?;
-    let r3 = parse_none_or(input, |p| f3(color_parser, p))?;
-
-    let alpha = parse_modern_alpha(color_parser, input)?;
-
-    Ok((r1, r2, r3, alpha))
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn serialize_modern_components() {
-        // None.
-        assert_eq!(ModernComponent(&None).to_css_string(), "none".to_string());
-
-        // Finite values.
-        assert_eq!(
-            ModernComponent(&Some(10.0)).to_css_string(),
-            "10".to_string()
-        );
-        assert_eq!(
-            ModernComponent(&Some(-10.0)).to_css_string(),
-            "-10".to_string()
-        );
-        assert_eq!(ModernComponent(&Some(0.0)).to_css_string(), "0".to_string());
-        assert_eq!(
-            ModernComponent(&Some(-0.0)).to_css_string(),
-            "0".to_string()
-        );
-
-        // Infinite values.
-        assert_eq!(
-            ModernComponent(&Some(f32::INFINITY)).to_css_string(),
-            "calc(infinity)".to_string()
-        );
-        assert_eq!(
-            ModernComponent(&Some(f32::NEG_INFINITY)).to_css_string(),
-            "calc(-infinity)".to_string()
-        );
-
-        // NaN.
-        assert_eq!(
-            ModernComponent(&Some(f32::NAN)).to_css_string(),
-            "calc(NaN)".to_string()
-        );
-    }
-}
diff --git a/src/lib.rs b/src/lib.rs
index 143ec87b..dc44fb74 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -67,12 +67,6 @@ fn parse_border_spacing(_context: &ParserContext, input: &mut Parser)
 
 #![recursion_limit = "200"] // For color::parse_color_keyword
 
-pub use crate::color::{
-    all_named_colors, hsl_to_rgb, hwb_to_rgb, parse_color_keyword, parse_color_with,
-    parse_hash_color, parse_named_color, serialize_color_alpha, AngleOrNumber, Color,
-    ColorFunction, ColorParser, FromParsedColor, Hsl, Hwb, Lab, Lch, NumberOrPercentage, Oklab,
-    Oklch, PredefinedColorSpace, RgbaLegacy,
-};
 pub use crate::cow_rc_str::CowRcStr;
 pub use crate::from_bytes::{stylesheet_encoding, EncodingSupport};
 #[doc(hidden)]
@@ -100,7 +94,7 @@ mod macros;
 mod rules_and_declarations;
 mod tokenizer;
 
-mod color;
+pub mod color;
 mod cow_rc_str;
 mod from_bytes;
 mod nth;
diff --git a/src/tests.rs b/src/tests.rs
index ae17bd81..d4bc5f51 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -8,18 +8,15 @@ extern crate test;
 use encoding_rs;
 use serde_json::{self, json, Map, Value};
 
-use crate::color::{parse_color_with, FromParsedColor};
-use crate::{ColorParser, PredefinedColorSpace, Delimiters};
-
 #[cfg(feature = "bench")]
 use self::test::Bencher;
 
 use super::{
     parse_important, parse_nth, parse_one_declaration, parse_one_rule, stylesheet_encoding,
-    AtRuleParser, BasicParseError, BasicParseErrorKind, Color, CowRcStr, DeclarationParser,
-    Delimiter, EncodingSupport, ParseError, ParseErrorKind, Parser, ParserInput, ParserState,
-    QualifiedRuleParser, RgbaLegacy, RuleBodyItemParser, RuleBodyParser, SourceLocation,
-    StyleSheetParser, ToCss, Token, TokenSerializationType, UnicodeRange,
+    AtRuleParser, BasicParseError, BasicParseErrorKind, CowRcStr, DeclarationParser, Delimiter,
+    EncodingSupport, ParseError, ParseErrorKind, Parser, ParserInput, ParserState,
+    QualifiedRuleParser, RuleBodyItemParser, RuleBodyParser, SourceLocation, StyleSheetParser,
+    ToCss, Token, TokenSerializationType, UnicodeRange,
 };
 
 macro_rules! JArray {
@@ -356,96 +353,6 @@ fn test_expect_url() {
     assert!(parse(&mut input).is_err());
 }
 
-fn run_color_tests<F: Fn(Result<Color, ()>) -> Value>(json_data: &str, to_json: F) {
-    run_json_tests(json_data, |input| {
-        let result: Result<_, ParseError<()>> =
-            input.parse_entirely(|i| Color::parse(i).map_err(Into::into));
-        to_json(result.map_err(|_| ()))
-    });
-}
-
-#[test]
-fn color3() {
-    run_color_tests(include_str!("css-parsing-tests/color3.json"), |c| {
-        c.ok()
-            .map(|v| v.to_css_string().to_json())
-            .unwrap_or(Value::Null)
-    })
-}
-
-#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
-#[test]
-fn color3_hsl() {
-    run_color_tests(include_str!("css-parsing-tests/color3_hsl.json"), |c| {
-        c.ok()
-            .map(|v| v.to_css_string().to_json())
-            .unwrap_or(Value::Null)
-    })
-}
-
-/// color3_keywords.json is different: R, G and B are in 0..255 rather than 0..1
-#[test]
-fn color3_keywords() {
-    run_color_tests(
-        include_str!("css-parsing-tests/color3_keywords.json"),
-        |c| {
-            c.ok()
-                .map(|v| v.to_css_string().to_json())
-                .unwrap_or(Value::Null)
-        },
-    )
-}
-
-#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
-#[test]
-fn color4_hwb() {
-    run_color_tests(include_str!("css-parsing-tests/color4_hwb.json"), |c| {
-        c.ok()
-            .map(|v| v.to_css_string().to_json())
-            .unwrap_or(Value::Null)
-    })
-}
-
-#[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
-#[test]
-fn color4_lab_lch_oklab_oklch() {
-    run_color_tests(
-        include_str!("css-parsing-tests/color4_lab_lch_oklab_oklch.json"),
-        |c| {
-            c.ok()
-                .map(|v| v.to_css_string().to_json())
-                .unwrap_or(Value::Null)
-        },
-    )
-}
-
-#[test]
-fn color4_color_function() {
-    run_color_tests(
-        include_str!("css-parsing-tests/color4_color_function.json"),
-        |c| {
-            c.ok()
-                .map(|v| v.to_css_string().to_json())
-                .unwrap_or(Value::Null)
-        },
-    )
-}
-
-macro_rules! parse_single_color {
-    ($i:expr) => {{
-        let input = $i;
-        let mut input = ParserInput::new(input);
-        let mut input = Parser::new(&mut input);
-        Color::parse(&mut input).map_err(Into::<ParseError<()>>::into)
-    }};
-}
-
-#[test]
-fn color4_invalid_color_space() {
-    let result = parse_single_color!("color(invalid 1 1 1)");
-    assert!(result.is_err());
-}
-
 #[test]
 fn nth() {
     run_json_tests(include_str!("css-parsing-tests/An+B.json"), |input| {
@@ -466,12 +373,16 @@ fn parse_comma_separated_ignoring_errors() {
     let mut input = ParserInput::new(input);
     let mut input = Parser::new(&mut input);
     let result = input.parse_comma_separated_ignoring_errors(|input| {
-        Color::parse(input).map_err(Into::<ParseError<()>>::into)
+        let loc = input.current_source_location();
+        let ident = input.expect_ident()?;
+        crate::color::parse_named_color(ident).map_err(|()| {
+            loc.new_unexpected_token_error::<ParseError<()>>(Token::Ident(ident.clone()))
+        })
     });
     assert_eq!(result.len(), 3);
-    assert_eq!(result[0].to_css_string(), "rgb(255, 0, 0)");
-    assert_eq!(result[1].to_css_string(), "rgb(255, 255, 0)");
-    assert_eq!(result[2].to_css_string(), "rgb(0, 0, 255)");
+    assert_eq!(result[0], (255, 0, 0));
+    assert_eq!(result[1], (255, 255, 0));
+    assert_eq!(result[2], (0, 0, 255));
 }
 
 #[test]
@@ -587,30 +498,6 @@ fn serialize_bad_tokens() {
     assert!(parser.next().is_err());
 }
 
-#[test]
-fn serialize_current_color() {
-    let c = Color::CurrentColor;
-    assert!(c.to_css_string() == "currentcolor");
-}
-
-#[test]
-fn serialize_rgb_full_alpha() {
-    let c = Color::Rgba(RgbaLegacy::new(255, 230, 204, 1.0));
-    assert_eq!(c.to_css_string(), "rgb(255, 230, 204)");
-}
-
-#[test]
-fn serialize_rgba() {
-    let c = Color::Rgba(RgbaLegacy::new(26, 51, 77, 0.125));
-    assert_eq!(c.to_css_string(), "rgba(26, 51, 77, 0.125)");
-}
-
-#[test]
-fn serialize_rgba_two_digit_float_if_roundtrips() {
-    let c = Color::Rgba(RgbaLegacy::from_floats(0., 0., 0., 0.5));
-    assert_eq!(c.to_css_string(), "rgba(0, 0, 0, 0.5)");
-}
-
 #[test]
 fn line_numbers() {
     let mut input = ParserInput::new(concat!(
@@ -895,26 +782,6 @@ where
     }
 }
 
-impl ToJson for Color {
-    fn to_json(&self) -> Value {
-        match *self {
-            Color::CurrentColor => "currentcolor".to_json(),
-            Color::Rgba(ref rgba) => {
-                json!([rgba.red, rgba.green, rgba.blue, rgba.alpha])
-            }
-            Color::Hsl(ref c) => json!([c.hue, c.saturation, c.lightness, c.alpha]),
-            Color::Hwb(ref c) => json!([c.hue, c.whiteness, c.blackness, c.alpha]),
-            Color::Lab(ref c) => json!([c.lightness, c.a, c.b, c.alpha]),
-            Color::Lch(ref c) => json!([c.lightness, c.chroma, c.hue, c.alpha]),
-            Color::Oklab(ref c) => json!([c.lightness, c.a, c.b, c.alpha]),
-            Color::Oklch(ref c) => json!([c.lightness, c.chroma, c.hue, c.alpha]),
-            Color::ColorFunction(ref c) => {
-                json!([c.color_space.as_str(), c.c1, c.c2, c.c3, c.alpha])
-            }
-        }
-    }
-}
-
 impl<'a> ToJson for CowRcStr<'a> {
     fn to_json(&self) -> Value {
         let s: &str = &*self;
@@ -925,6 +792,7 @@ impl<'a> ToJson for CowRcStr<'a> {
 #[bench]
 #[cfg(feature = "bench")]
 fn delimiter_from_byte(b: &mut Bencher) {
+    use crate::Delimiters;
     b.iter(|| {
         for _ in 0..1000 {
             for i in 0..256 {
@@ -1492,146 +1360,3 @@ fn servo_define_css_keyword_enum() {
 
     assert_eq!(UserZoom::from_ident("fixed"), Ok(UserZoom::Fixed));
 }
-
-#[test]
-fn generic_parser() {
-    #[derive(Debug, PartialEq)]
-    enum OutputType {
-        CurrentColor,
-        Rgba(u8, u8, u8, f32),
-        Hsl(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
-        Hwb(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
-        Lab(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
-        Lch(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
-        Oklab(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
-        Oklch(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
-        ColorFunction(
-            PredefinedColorSpace,
-            Option<f32>,
-            Option<f32>,
-            Option<f32>,
-            Option<f32>,
-        ),
-    }
-
-    impl FromParsedColor for OutputType {
-        fn from_current_color() -> Self {
-            OutputType::CurrentColor
-        }
-
-        fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
-            OutputType::Rgba(red, green, blue, alpha)
-        }
-
-        fn from_hsl(
-            hue: Option<f32>,
-            saturation: Option<f32>,
-            lightness: Option<f32>,
-            alpha: Option<f32>,
-        ) -> Self {
-            OutputType::Hsl(hue, saturation, lightness, alpha)
-        }
-
-        fn from_hwb(
-            hue: Option<f32>,
-            blackness: Option<f32>,
-            whiteness: Option<f32>,
-            alpha: Option<f32>,
-        ) -> Self {
-            OutputType::Hwb(hue, blackness, whiteness, alpha)
-        }
-
-        fn from_lab(
-            lightness: Option<f32>,
-            a: Option<f32>,
-            b: Option<f32>,
-            alpha: Option<f32>,
-        ) -> Self {
-            OutputType::Lab(lightness, a, b, alpha)
-        }
-
-        fn from_lch(
-            lightness: Option<f32>,
-            chroma: Option<f32>,
-            hue: Option<f32>,
-            alpha: Option<f32>,
-        ) -> Self {
-            OutputType::Lch(lightness, chroma, hue, alpha)
-        }
-
-        fn from_oklab(
-            lightness: Option<f32>,
-            a: Option<f32>,
-            b: Option<f32>,
-            alpha: Option<f32>,
-        ) -> Self {
-            OutputType::Oklab(lightness, a, b, alpha)
-        }
-
-        fn from_oklch(
-            lightness: Option<f32>,
-            chroma: Option<f32>,
-            hue: Option<f32>,
-            alpha: Option<f32>,
-        ) -> Self {
-            OutputType::Oklch(lightness, chroma, hue, alpha)
-        }
-
-        fn from_color_function(
-            color_space: PredefinedColorSpace,
-            c1: Option<f32>,
-            c2: Option<f32>,
-            c3: Option<f32>,
-            alpha: Option<f32>,
-        ) -> Self {
-            OutputType::ColorFunction(color_space, c1, c2, c3, alpha)
-        }
-    }
-
-    struct TestColorParser;
-    impl<'i> ColorParser<'i> for TestColorParser {
-        type Output = OutputType;
-        type Error = ();
-    }
-
-    #[rustfmt::skip]
-    const TESTS: &[(&str, OutputType)] = &[
-        ("currentColor",                OutputType::CurrentColor),
-        ("rgb(1, 2, 3)",                OutputType::Rgba(1, 2, 3, 1.0)),
-        ("rgba(1, 2, 3, 0.4)",          OutputType::Rgba(1, 2, 3, 0.4)),
-        ("rgb(none none none / none)",  OutputType::Rgba(0, 0, 0, 0.0)),
-        ("rgb(1 none 3 / none)",        OutputType::Rgba(1, 0, 3, 0.0)),
-
-        ("hsla(45deg, 20%, 30%, 0.4)",  OutputType::Hsl(Some(45.0), Some(0.2), Some(0.3), Some(0.4))),
-        ("hsl(45deg none none)",        OutputType::Hsl(Some(45.0), None, None, Some(1.0))),
-        ("hsl(none 10% none / none)",   OutputType::Hsl(None, Some(0.1), None, None)),
-        ("hsl(120 100.0% 50.0%)",       OutputType::Hsl(Some(120.0), Some(1.0), Some(0.5), Some(1.0))),
-
-        ("hwb(45deg 20% 30% / 0.4)",    OutputType::Hwb(Some(45.0), Some(0.2), Some(0.3), Some(0.4))),
-
-        ("lab(100 20 30 / 0.4)",        OutputType::Lab(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
-        ("lch(100 20 30 / 0.4)",        OutputType::Lch(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
-
-        ("oklab(100 20 30 / 0.4)",      OutputType::Oklab(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
-        ("oklch(100 20 30 / 0.4)",      OutputType::Oklch(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
-
-        ("color(srgb 0.1 0.2 0.3 / 0.4)",           OutputType::ColorFunction(PredefinedColorSpace::Srgb, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
-        ("color(srgb none none none)",              OutputType::ColorFunction(PredefinedColorSpace::Srgb, None, None, None, Some(1.0))),
-        ("color(srgb none none none / none)",       OutputType::ColorFunction(PredefinedColorSpace::Srgb, None, None, None, None)),
-        ("color(srgb-linear 0.1 0.2 0.3 / 0.4)",    OutputType::ColorFunction(PredefinedColorSpace::SrgbLinear, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
-        ("color(display-p3 0.1 0.2 0.3 / 0.4)",     OutputType::ColorFunction(PredefinedColorSpace::DisplayP3, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
-        ("color(a98-rgb 0.1 0.2 0.3 / 0.4)",        OutputType::ColorFunction(PredefinedColorSpace::A98Rgb, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
-        ("color(prophoto-rgb 0.1 0.2 0.3 / 0.4)",   OutputType::ColorFunction(PredefinedColorSpace::ProphotoRgb, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
-        ("color(rec2020 0.1 0.2 0.3 / 0.4)",        OutputType::ColorFunction(PredefinedColorSpace::Rec2020, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
-        ("color(xyz-d50 0.1 0.2 0.3 / 0.4)",        OutputType::ColorFunction(PredefinedColorSpace::XyzD50, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
-        ("color(xyz-d65 0.1 0.2 0.3 / 0.4)",        OutputType::ColorFunction(PredefinedColorSpace::XyzD65, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
-    ];
-
-    for (input, expected) in TESTS {
-        let mut input = ParserInput::new(*input);
-        let mut input = Parser::new(&mut input);
-
-        let actual: OutputType = parse_color_with(&TestColorParser, &mut input).unwrap();
-        assert_eq!(actual, *expected);
-    }
-}

From cab31ead1cded6a6c48967953298861e914739ad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Mon, 11 Sep 2023 15:24:11 +0200
Subject: [PATCH 17/38] Bump version.

---
 Cargo.toml       | 2 +-
 color/Cargo.toml | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index aae87dcf..ab2341d8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cssparser"
-version = "0.32.0"
+version = "0.33.0"
 authors = [ "Simon Sapin <simon.sapin@exyr.org>" ]
 
 description = "Rust implementation of CSS Syntax Level 3"
diff --git a/color/Cargo.toml b/color/Cargo.toml
index d3201a12..d65ee3ed 100644
--- a/color/Cargo.toml
+++ b/color/Cargo.toml
@@ -12,7 +12,7 @@ edition = "2021"
 path = "lib.rs"
 
 [dependencies]
-cssparser = { path = ".." }
+cssparser = { version = "0.33", path = ".." }
 
 [dev-dependencies]
 serde_json = "1.0"

From aaa966d9d6ae70c4b8a62bb5e3a14c068bb7dff0 Mon Sep 17 00:00:00 2001
From: Zach Hoffman <zach@zrhoffman.net>
Date: Tue, 14 Nov 2023 07:46:37 -0700
Subject: [PATCH 18/38] Replace TokenSerializationType with
 TokenSerializationTypeVariants (#369)

* Replace TokenSerializationType with TokenSerializationTypeVariants

Making TokenSerializationType public is useful to describe a CSS string
that is already known to be valid in cases when the
TokenSerializationTypes of the start and end of the CSS string is
needed, but Tokens are not.

This helps with creating a custom_properties::VariableValue from the CSS
string of a computed value for CSS Properties and Values, see Mozilla
bug 1858305 [1].

[1]: https://bugzilla.mozilla.org/show_bug.cgi?id=1858305

* Derive Default trait for TokenSerializationType

* Deprecate TokenSerializationType::nothing()
---
 src/serializer.rs | 160 ++++++++++++++++++++++++++++++++--------------
 src/tests.rs      |   2 +-
 2 files changed, 112 insertions(+), 50 deletions(-)

diff --git a/src/serializer.rs b/src/serializer.rs
index 19f01456..09c22402 100644
--- a/src/serializer.rs
+++ b/src/serializer.rs
@@ -378,19 +378,110 @@ impl_tocss_for_float!(f32);
 impl_tocss_for_float!(f64);
 
 /// A category of token. See the `needs_separator_when_before` method.
-#[derive(Copy, Clone, Eq, PartialEq, Debug)]
-pub struct TokenSerializationType(TokenSerializationTypeVariants);
+#[derive(Copy, Clone, Eq, PartialEq, Debug, Default)]
+pub enum TokenSerializationType {
+    /// No token serialization type.
+    #[default]
+    Nothing,
+
+    /// The [`<whitespace-token>`](https://drafts.csswg.org/css-syntax/#whitespace-token-diagram)
+    /// type.
+    WhiteSpace,
+
+    /// The [`<at-keyword-token>`](https://drafts.csswg.org/css-syntax/#at-keyword-token-diagram)
+    /// type, the "[`<hash-token>`](https://drafts.csswg.org/css-syntax/#hash-token-diagram) with
+    /// the type flag set to 'unrestricted'" type, or the
+    /// "[`<hash-token>`](https://drafts.csswg.org/css-syntax/#hash-token-diagram) with the type
+    /// flag set to 'id'" type.
+    AtKeywordOrHash,
+
+    /// The [`<number-token>`](https://drafts.csswg.org/css-syntax/#number-token-diagram) type.
+    Number,
+
+    /// The [`<dimension-token>`](https://drafts.csswg.org/css-syntax/#dimension-token-diagram)
+    /// type.
+    Dimension,
+
+    /// The [`<percentage-token>`](https://drafts.csswg.org/css-syntax/#percentage-token-diagram)
+    /// type.
+    Percentage,
+
+    /// The [`<url-token>`](https://drafts.csswg.org/css-syntax/#url-token-diagram) or
+    /// `<bad-url-token>` type.
+    UrlOrBadUrl,
+
+    /// The [`<function-token>`](https://drafts.csswg.org/css-syntax/#function-token-diagram) type.
+    Function,
+
+    /// The [`<ident-token>`](https://drafts.csswg.org/css-syntax/#ident-token-diagram) type.
+    Ident,
+
+    /// The `-->` [`<CDC-token>`](https://drafts.csswg.org/css-syntax/#CDC-token-diagram) type.
+    CDC,
+
+    /// The `|=`
+    /// [`<dash-match-token>`](https://drafts.csswg.org/css-syntax/#dash-match-token-diagram) type.
+    DashMatch,
+
+    /// The `*=`
+    /// [`<substring-match-token>`](https://drafts.csswg.org/css-syntax/#substring-match-token-diagram)
+    /// type.
+    SubstringMatch,
+
+    /// The `<(-token>` type.
+    OpenParen,
+
+    /// The `#` `<delim-token>` type.
+    DelimHash,
+
+    /// The `@` `<delim-token>` type.
+    DelimAt,
+
+    /// The `.` or `+` `<delim-token>` type.
+    DelimDotOrPlus,
+
+    /// The `-` `<delim-token>` type.
+    DelimMinus,
+
+    /// The `?` `<delim-token>` type.
+    DelimQuestion,
+
+    /// The `$`, `^`, or `~` `<delim-token>` type.
+    DelimAssorted,
+
+    /// The `=` `<delim-token>` type.
+    DelimEquals,
+
+    /// The `|` `<delim-token>` type.
+    DelimBar,
+
+    /// The `/` `<delim-token>` type.
+    DelimSlash,
+
+    /// The `*` `<delim-token>` type.
+    DelimAsterisk,
+
+    /// The `%` `<delim-token>` type.
+    DelimPercent,
+
+    /// A type indicating any other token.
+    Other,
+}
 
 impl TokenSerializationType {
     /// Return a value that represents the absence of a token, e.g. before the start of the input.
+    #[deprecated(
+        since = "0.32.1",
+        note = "use TokenSerializationType::Nothing or TokenSerializationType::default() instead"
+    )]
     pub fn nothing() -> TokenSerializationType {
-        TokenSerializationType(TokenSerializationTypeVariants::Nothing)
+        Default::default()
     }
 
-    /// If this value is `TokenSerializationType::nothing()`, set it to the given value instead.
+    /// If this value is `TokenSerializationType::Nothing`, set it to the given value instead.
     pub fn set_if_nothing(&mut self, new_value: TokenSerializationType) {
-        if self.0 == TokenSerializationTypeVariants::Nothing {
-            self.0 = new_value.0
+        if matches!(self, TokenSerializationType::Nothing) {
+            *self = new_value
         }
     }
 
@@ -404,10 +495,10 @@ impl TokenSerializationType {
     /// See https://github.com/w3c/csswg-drafts/issues/4088 for the
     /// `DelimPercent` bits.
     pub fn needs_separator_when_before(self, other: TokenSerializationType) -> bool {
-        use self::TokenSerializationTypeVariants::*;
-        match self.0 {
+        use self::TokenSerializationType::*;
+        match self {
             Ident => matches!(
-                other.0,
+                other,
                 Ident
                     | Function
                     | UrlOrBadUrl
@@ -419,15 +510,15 @@ impl TokenSerializationType {
                     | OpenParen
             ),
             AtKeywordOrHash | Dimension => matches!(
-                other.0,
+                other,
                 Ident | Function | UrlOrBadUrl | DelimMinus | Number | Percentage | Dimension | CDC
             ),
             DelimHash | DelimMinus => matches!(
-                other.0,
+                other,
                 Ident | Function | UrlOrBadUrl | DelimMinus | Number | Percentage | Dimension
             ),
             Number => matches!(
-                other.0,
+                other,
                 Ident
                     | Function
                     | UrlOrBadUrl
@@ -437,11 +528,11 @@ impl TokenSerializationType {
                     | DelimPercent
                     | Dimension
             ),
-            DelimAt => matches!(other.0, Ident | Function | UrlOrBadUrl | DelimMinus),
-            DelimDotOrPlus => matches!(other.0, Number | Percentage | Dimension),
-            DelimAssorted | DelimAsterisk => matches!(other.0, DelimEquals),
-            DelimBar => matches!(other.0, DelimEquals | DelimBar | DashMatch),
-            DelimSlash => matches!(other.0, DelimAsterisk | SubstringMatch),
+            DelimAt => matches!(other, Ident | Function | UrlOrBadUrl | DelimMinus),
+            DelimDotOrPlus => matches!(other, Number | Percentage | Dimension),
+            DelimAssorted | DelimAsterisk => matches!(other, DelimEquals),
+            DelimBar => matches!(other, DelimEquals | DelimBar | DashMatch),
+            DelimSlash => matches!(other, DelimAsterisk | SubstringMatch),
             Nothing | WhiteSpace | Percentage | UrlOrBadUrl | Function | CDC | OpenParen
             | DashMatch | SubstringMatch | DelimQuestion | DelimEquals | DelimPercent | Other => {
                 false
@@ -450,43 +541,14 @@ impl TokenSerializationType {
     }
 }
 
-#[derive(Copy, Clone, Eq, PartialEq, Debug)]
-enum TokenSerializationTypeVariants {
-    Nothing,
-    WhiteSpace,
-    AtKeywordOrHash,
-    Number,
-    Dimension,
-    Percentage,
-    UrlOrBadUrl,
-    Function,
-    Ident,
-    CDC,
-    DashMatch,
-    SubstringMatch,
-    OpenParen,      // '('
-    DelimHash,      // '#'
-    DelimAt,        // '@'
-    DelimDotOrPlus, // '.', '+'
-    DelimMinus,     // '-'
-    DelimQuestion,  // '?'
-    DelimAssorted,  // '$', '^', '~'
-    DelimEquals,    // '='
-    DelimBar,       // '|'
-    DelimSlash,     // '/'
-    DelimAsterisk,  // '*'
-    DelimPercent,   // '%'
-    Other,          // anything else
-}
-
 impl<'a> Token<'a> {
     /// Categorize a token into a type that determines when `/**/` needs to be inserted
     /// between two tokens when serialized next to each other without whitespace in between.
     ///
     /// See the `TokenSerializationType::needs_separator_when_before` method.
     pub fn serialization_type(&self) -> TokenSerializationType {
-        use self::TokenSerializationTypeVariants::*;
-        TokenSerializationType(match *self {
+        use self::TokenSerializationType::*;
+        match self {
             Token::Ident(_) => Ident,
             Token::AtKeyword(_) | Token::Hash(_) | Token::IDHash(_) => AtKeywordOrHash,
             Token::UnquotedUrl(_) | Token::BadUrl(_) => UrlOrBadUrl,
@@ -526,6 +588,6 @@ impl<'a> Token<'a> {
             | Token::IncludeMatch
             | Token::PrefixMatch
             | Token::SuffixMatch => Other,
-        })
+        }
     }
 }
diff --git a/src/tests.rs b/src/tests.rs
index d4bc5f51..f9dea193 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -466,7 +466,7 @@ fn serializer(preserve_comments: bool) {
             }
             let mut serialized = String::new();
             write_to(
-                TokenSerializationType::nothing(),
+                TokenSerializationType::Nothing,
                 input,
                 &mut serialized,
                 preserve_comments,

From 87438e19840e47d21f9d5b958676c333e2e46d66 Mon Sep 17 00:00:00 2001
From: Gabriel de Perthuis <g2p.code@gmail.com>
Date: Fri, 19 Jan 2024 18:10:25 +0100
Subject: [PATCH 19/38] Fix dependencies minimal versions (#365)

Tested with:

cargo +nightly update -Zminimal-versions
cargo check --all-targets
cargo +nightly check --all-targets --all-features
---
 Cargo.toml        | 4 ++--
 color/Cargo.toml  | 2 +-
 macros/Cargo.toml | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index ab2341d8..c7beb4c1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,7 +15,7 @@ rust-version = "1.63"
 exclude = ["src/css-parsing-tests/**", "src/big-data-url.css"]
 
 [dev-dependencies]
-serde_json = "1.0"
+serde_json = "1.0.25"
 difference = "2.0"
 encoding_rs = "0.8"
 
@@ -23,7 +23,7 @@ encoding_rs = "0.8"
 cssparser-macros = {path = "./macros", version = "0.6.1"}
 dtoa-short = "0.3"
 itoa = "1.0"
-phf = {version = ">=0.8,<=0.11", features = ["macros"]}
+phf = {version = "0.11.2", features = ["macros"]}
 serde = {version = "1.0", optional = true}
 smallvec = "1.0"
 
diff --git a/color/Cargo.toml b/color/Cargo.toml
index d65ee3ed..d1e315a8 100644
--- a/color/Cargo.toml
+++ b/color/Cargo.toml
@@ -15,6 +15,6 @@ path = "lib.rs"
 cssparser = { version = "0.33", path = ".." }
 
 [dev-dependencies]
-serde_json = "1.0"
+serde_json = "1.0.25"
 difference = "2.0"
 encoding_rs = "0.8"
diff --git a/macros/Cargo.toml b/macros/Cargo.toml
index 1c225bf2..494705f9 100644
--- a/macros/Cargo.toml
+++ b/macros/Cargo.toml
@@ -13,5 +13,5 @@ path = "lib.rs"
 proc-macro = true
 
 [dependencies]
-quote = "1"
+quote = "1.0.29"
 syn = {version = "2", features = ["full", "extra-traits"]}

From c3314d15b281f376538cdc91bbb9ce21d5052231 Mon Sep 17 00:00:00 2001
From: Martin Robinson <mrobinson@igalia.com>
Date: Wed, 20 Mar 2024 10:45:34 +0100
Subject: [PATCH 20/38] Rename `master` branch to `main` (#371)

This is in line with the policy decided in the TSC.
---
 .github/workflows/main.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 0d3c0229..07bedca5 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -2,7 +2,7 @@ name: CI
 
 on:
   push:
-    branches: [master]
+    branches: [main]
   pull_request:
   workflow_dispatch:
   merge_group:

From 08e4d5e4b3a9311b563567e151baa994ab025f75 Mon Sep 17 00:00:00 2001
From: Chipnertkj <32001812+chipnertkj@users.noreply.github.com>
Date: Thu, 7 Dec 2023 02:26:33 +0100
Subject: [PATCH 21/38] Apply clippy lints for more idiomatic code

---
 color/tests.rs                | 47 ++++++++++-----------
 macros/lib.rs                 | 20 ++++-----
 src/cow_rc_str.rs             |  6 +--
 src/macros.rs                 |  4 +-
 src/nth.rs                    | 16 +++----
 src/parser.rs                 | 19 ++++-----
 src/rules_and_declarations.rs | 16 +++----
 src/serializer.rs             | 32 +++++++-------
 src/tests.rs                  | 64 +++++++++++++---------------
 src/tokenizer.rs              | 78 ++++++++++++++++++-----------------
 src/unicode_range.rs          | 20 ++++-----
 11 files changed, 157 insertions(+), 165 deletions(-)

diff --git a/color/tests.rs b/color/tests.rs
index babb076b..85eb430e 100644
--- a/color/tests.rs
+++ b/color/tests.rs
@@ -3,25 +3,21 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use super::*;
-use crate::{ColorParser, PredefinedColorSpace, Color, RgbaLegacy};
-use cssparser::{Parser, ParserInput};
-use serde_json::{self, json, Value};
+use cssparser::ParserInput;
+use serde_json::{json, Value};
 
 fn almost_equals(a: &Value, b: &Value) -> bool {
     match (a, b) {
-        (&Value::Number(ref a), &Value::Number(ref b)) => {
+        (Value::Number(a), Value::Number(b)) => {
             let a = a.as_f64().unwrap();
             let b = b.as_f64().unwrap();
             (a - b).abs() <= a.abs() * 1e-6
         }
 
         (&Value::Bool(a), &Value::Bool(b)) => a == b,
-        (&Value::String(ref a), &Value::String(ref b)) => a == b,
-        (&Value::Array(ref a), &Value::Array(ref b)) => {
-            a.len() == b.len()
-                && a.iter()
-                    .zip(b.iter())
-                    .all(|(ref a, ref b)| almost_equals(*a, *b))
+        (Value::String(a), Value::String(b)) => a == b,
+        (Value::Array(a), Value::Array(b)) => {
+            a.len() == b.len() && a.iter().zip(b.iter()).all(|(a, b)| almost_equals(a, b))
         }
         (&Value::Object(_), &Value::Object(_)) => panic!("Not implemented"),
         (&Value::Null, &Value::Null) => true,
@@ -43,8 +39,7 @@ fn assert_json_eq(results: Value, expected: Value, message: &str) {
     }
 }
 
-
-fn run_raw_json_tests<F: Fn(Value, Value) -> ()>(json_data: &str, run: F) {
+fn run_raw_json_tests<F: Fn(Value, Value)>(json_data: &str, run: F) {
     let items = match serde_json::from_str(json_data) {
         Ok(Value::Array(items)) => items,
         other => panic!("Invalid JSON: {:?}", other),
@@ -92,11 +87,14 @@ fn color3() {
 #[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
 #[test]
 fn color3_hsl() {
-    run_color_tests(include_str!("../src/css-parsing-tests/color3_hsl.json"), |c| {
-        c.ok()
-            .map(|v| v.to_css_string().to_json())
-            .unwrap_or(Value::Null)
-    })
+    run_color_tests(
+        include_str!("../src/css-parsing-tests/color3_hsl.json"),
+        |c| {
+            c.ok()
+                .map(|v| v.to_css_string().to_json())
+                .unwrap_or(Value::Null)
+        },
+    )
 }
 
 /// color3_keywords.json is different: R, G and B are in 0..255 rather than 0..1
@@ -115,11 +113,14 @@ fn color3_keywords() {
 #[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
 #[test]
 fn color4_hwb() {
-    run_color_tests(include_str!("../src/css-parsing-tests/color4_hwb.json"), |c| {
-        c.ok()
-            .map(|v| v.to_css_string().to_json())
-            .unwrap_or(Value::Null)
-    })
+    run_color_tests(
+        include_str!("../src/css-parsing-tests/color4_hwb.json"),
+        |c| {
+            c.ok()
+                .map(|v| v.to_css_string().to_json())
+                .unwrap_or(Value::Null)
+        },
+    )
 }
 
 #[cfg_attr(all(miri, feature = "skip_long_tests"), ignore)]
@@ -355,7 +356,7 @@ fn generic_parser() {
     ];
 
     for (input, expected) in TESTS {
-        let mut input = ParserInput::new(*input);
+        let mut input = ParserInput::new(input);
         let mut input = Parser::new(&mut input);
 
         let actual: OutputType = parse_color_with(&TestColorParser, &mut input).unwrap();
diff --git a/macros/lib.rs b/macros/lib.rs
index 4354cc8e..8b40bd4c 100644
--- a/macros/lib.rs
+++ b/macros/lib.rs
@@ -48,9 +48,7 @@ fn get_byte_from_lit(lit: &syn::Lit) -> u8 {
 
 fn get_byte_from_expr_lit(expr: &syn::Expr) -> u8 {
     match *expr {
-        syn::Expr::Lit(syn::ExprLit { ref lit, .. }) => {
-            get_byte_from_lit(lit)
-        }
+        syn::Expr::Lit(syn::ExprLit { ref lit, .. }) => get_byte_from_lit(lit),
         _ => unreachable!(),
     }
 }
@@ -63,15 +61,17 @@ fn parse_pat_to_table<'a>(
     table: &mut [u8; 256],
 ) {
     match pat {
-        &syn::Pat::Lit(syn::PatLit { ref lit, .. }) => {
+        syn::Pat::Lit(syn::PatLit { ref lit, .. }) => {
             let value = get_byte_from_lit(lit);
             if table[value as usize] == 0 {
                 table[value as usize] = case_id;
             }
         }
-        &syn::Pat::Range(syn::PatRange { ref start, ref end, .. }) => {
-            let lo = get_byte_from_expr_lit(&start.as_ref().unwrap());
-            let hi = get_byte_from_expr_lit(&end.as_ref().unwrap());
+        syn::Pat::Range(syn::PatRange {
+            ref start, ref end, ..
+        }) => {
+            let lo = get_byte_from_expr_lit(start.as_ref().unwrap());
+            let hi = get_byte_from_expr_lit(end.as_ref().unwrap());
             for value in lo..hi {
                 if table[value as usize] == 0 {
                     table[value as usize] = case_id;
@@ -81,14 +81,14 @@ fn parse_pat_to_table<'a>(
                 table[hi as usize] = case_id;
             }
         }
-        &syn::Pat::Wild(_) => {
+        syn::Pat::Wild(_) => {
             for byte in table.iter_mut() {
                 if *byte == 0 {
                     *byte = case_id;
                 }
             }
         }
-        &syn::Pat::Ident(syn::PatIdent { ref ident, .. }) => {
+        syn::Pat::Ident(syn::PatIdent { ref ident, .. }) => {
             assert_eq!(*wildcard, None);
             *wildcard = Some(ident);
             for byte in table.iter_mut() {
@@ -97,7 +97,7 @@ fn parse_pat_to_table<'a>(
                 }
             }
         }
-        &syn::Pat::Or(syn::PatOr { ref cases, .. }) => {
+        syn::Pat::Or(syn::PatOr { ref cases, .. }) => {
             for case in cases {
                 parse_pat_to_table(case, case_id, wildcard, table);
             }
diff --git a/src/cow_rc_str.rs b/src/cow_rc_str.rs
index ecf14a0a..26508481 100644
--- a/src/cow_rc_str.rs
+++ b/src/cow_rc_str.rs
@@ -4,7 +4,7 @@
 
 use std::borrow::{Borrow, Cow};
 use std::rc::Rc;
-use std::{cmp, fmt, hash, marker, mem, ops, slice, str, ptr};
+use std::{cmp, fmt, hash, marker, mem, ops, ptr, slice, str};
 
 /// A string that is either shared (heap-allocated and reference-counted) or borrowed.
 ///
@@ -23,9 +23,9 @@ pub struct CowRcStr<'a> {
     phantom: marker::PhantomData<Result<&'a str, Rc<String>>>,
 }
 
-fn _static_assert_same_size<'a>() {
+fn _static_assert_same_size() {
     // "Instantiate" the generic function without calling it.
-    let _ = mem::transmute::<CowRcStr<'a>, Option<CowRcStr<'a>>>;
+    let _ = mem::transmute::<CowRcStr<'_>, Option<CowRcStr<'_>>>;
 }
 
 impl<'a> From<Cow<'a, str>> for CowRcStr<'a> {
diff --git a/src/macros.rs b/src/macros.rs
index fc4b77a1..67d83658 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -182,7 +182,7 @@ pub fn _cssparser_internal_to_lowercase<'a>(
         let input_bytes =
             unsafe { &*(input.as_bytes() as *const [u8] as *const [MaybeUninit<u8>]) };
 
-        buffer.copy_from_slice(&*input_bytes);
+        buffer.copy_from_slice(input_bytes);
 
         // Same as above re layout, plus these bytes have been initialized:
         let buffer = unsafe { &mut *(buffer as *mut [MaybeUninit<u8>] as *mut [u8]) };
@@ -195,7 +195,7 @@ pub fn _cssparser_internal_to_lowercase<'a>(
     }
 
     Some(
-        match input.bytes().position(|byte| matches!(byte, b'A'..=b'Z')) {
+        match input.bytes().position(|byte| byte.is_ascii_uppercase()) {
             Some(first_uppercase) => make_ascii_lowercase(buffer, input, first_uppercase),
             // common case: input is already lower-case
             None => input,
diff --git a/src/nth.rs b/src/nth.rs
index 518de4d9..e4bde0de 100644
--- a/src/nth.rs
+++ b/src/nth.rs
@@ -8,7 +8,7 @@ use super::{BasicParseError, Parser, ParserInput, Token};
 /// The input is typically the arguments of a function,
 /// in which case the caller needs to check if the arguments’ parser is exhausted.
 /// Return `Ok((A, B))`, or `Err(())` for a syntax error.
-pub fn parse_nth<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(i32, i32), BasicParseError<'i>> {
+pub fn parse_nth<'i>(input: &mut Parser<'i, '_>) -> Result<(i32, i32), BasicParseError<'i>> {
     match *input.next()? {
         Token::Number {
             int_value: Some(b), ..
@@ -22,7 +22,7 @@ pub fn parse_nth<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(i32, i32), Basic
                 unit,
                 "n" => Ok(parse_b(input, a)?),
                 "n-" => Ok(parse_signless_b(input, a, -1)?),
-                _ => match parse_n_dash_digits(&*unit) {
+                _ => match parse_n_dash_digits(unit) {
                     Ok(b) => Ok((a, b)),
                     Err(()) => {
                         let unit = unit.clone();
@@ -40,8 +40,8 @@ pub fn parse_nth<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(i32, i32), Basic
                 "n-" => Ok(parse_signless_b(input, 1, -1)?),
                 "-n-" => Ok(parse_signless_b(input, -1, -1)?),
                 _ => {
-                    let (slice, a) = if value.starts_with("-") {
-                        (&value[1..], -1)
+                    let (slice, a) = if let Some(stripped) = value.strip_prefix('-') {
+                        (stripped, -1)
                     } else {
                         (&**value, 1)
                     };
@@ -81,7 +81,7 @@ pub fn parse_nth<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(i32, i32), Basic
     }
 }
 
-fn parse_b<'i, 't>(input: &mut Parser<'i, 't>, a: i32) -> Result<(i32, i32), BasicParseError<'i>> {
+fn parse_b<'i>(input: &mut Parser<'i, '_>, a: i32) -> Result<(i32, i32), BasicParseError<'i>> {
     let start = input.state();
     match input.next() {
         Ok(&Token::Delim('+')) => parse_signless_b(input, a, 1),
@@ -98,8 +98,8 @@ fn parse_b<'i, 't>(input: &mut Parser<'i, 't>, a: i32) -> Result<(i32, i32), Bas
     }
 }
 
-fn parse_signless_b<'i, 't>(
-    input: &mut Parser<'i, 't>,
+fn parse_signless_b<'i>(
+    input: &mut Parser<'i, '_>,
     a: i32,
     b_sign: i32,
 ) -> Result<(i32, i32), BasicParseError<'i>> {
@@ -118,7 +118,7 @@ fn parse_n_dash_digits(string: &str) -> Result<i32, ()> {
     let bytes = string.as_bytes();
     if bytes.len() >= 3
         && bytes[..2].eq_ignore_ascii_case(b"n-")
-        && bytes[2..].iter().all(|&c| matches!(c, b'0'..=b'9'))
+        && bytes[2..].iter().all(|&c| c.is_ascii_digit())
     {
         Ok(parse_number_saturate(&string[1..]).unwrap()) // Include the minus sign
     } else {
diff --git a/src/parser.rs b/src/parser.rs
index dd7777a2..424306e1 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -116,7 +116,7 @@ impl<'i, T> From<BasicParseError<'i>> for ParseError<'i, T> {
 impl SourceLocation {
     /// Create a new BasicParseError at this location for an unexpected token
     #[inline]
-    pub fn new_basic_unexpected_token_error<'i>(self, token: Token<'i>) -> BasicParseError<'i> {
+    pub fn new_basic_unexpected_token_error(self, token: Token<'_>) -> BasicParseError<'_> {
         BasicParseError {
             kind: BasicParseErrorKind::UnexpectedToken(token),
             location: self,
@@ -125,7 +125,7 @@ impl SourceLocation {
 
     /// Create a new ParseError at this location for an unexpected token
     #[inline]
-    pub fn new_unexpected_token_error<'i, E>(self, token: Token<'i>) -> ParseError<'i, E> {
+    pub fn new_unexpected_token_error<E>(self, token: Token<'_>) -> ParseError<'_, E> {
         ParseError {
             kind: ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken(token)),
             location: self,
@@ -652,9 +652,8 @@ impl<'i: 't, 't> Parser<'i, 't> {
         let token = if using_cached_token {
             let cached_token = self.input.cached_token.as_ref().unwrap();
             self.input.tokenizer.reset(&cached_token.end_state);
-            match cached_token.token {
-                Token::Function(ref name) => self.input.tokenizer.see_function(name),
-                _ => {}
+            if let Token::Function(ref name) = cached_token.token {
+                self.input.tokenizer.see_function(name)
             }
             &cached_token.token
         } else {
@@ -748,7 +747,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
             match self.parse_until_before(Delimiter::Comma, &mut parse_one) {
                 Ok(v) => values.push(v),
                 Err(e) if !ignore_errors => return Err(e),
-                Err(_) => {},
+                Err(_) => {}
             }
             match self.next() {
                 Err(_) => return Ok(values),
@@ -835,7 +834,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
     /// expect_ident, but clone the CowRcStr
     #[inline]
     pub fn expect_ident_cloned(&mut self) -> Result<CowRcStr<'i>, BasicParseError<'i>> {
-        self.expect_ident().map(|s| s.clone())
+        self.expect_ident().cloned()
     }
 
     /// Parse a <ident-token> whose unescaped value is an ASCII-insensitive match for the given value.
@@ -860,7 +859,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
     /// expect_string, but clone the CowRcStr
     #[inline]
     pub fn expect_string_cloned(&mut self) -> Result<CowRcStr<'i>, BasicParseError<'i>> {
-        self.expect_string().map(|s| s.clone())
+        self.expect_string().cloned()
     }
 
     /// Parse either a <ident-token> or a <string-token>, and return the unescaped value.
@@ -879,7 +878,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
             Token::UnquotedUrl(ref value) => Ok(value.clone()),
             Token::Function(ref name) if name.eq_ignore_ascii_case("url") => {
                 self.parse_nested_block(|input| {
-                    input.expect_string().map_err(Into::into).map(|s| s.clone())
+                    input.expect_string().map_err(Into::into).cloned()
                 })
                 .map_err(ParseError::<()>::basic)
             }
@@ -894,7 +893,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
             Token::QuotedString(ref value) => Ok(value.clone()),
             Token::Function(ref name) if name.eq_ignore_ascii_case("url") => {
                 self.parse_nested_block(|input| {
-                    input.expect_string().map_err(Into::into).map(|s| s.clone())
+                    input.expect_string().map_err(Into::into).cloned()
                 })
                 .map_err(ParseError::<()>::basic)
             }
diff --git a/src/rules_and_declarations.rs b/src/rules_and_declarations.rs
index fb33a7d0..b23e9dc0 100644
--- a/src/rules_and_declarations.rs
+++ b/src/rules_and_declarations.rs
@@ -14,7 +14,7 @@ use crate::parser::{parse_nested_block, parse_until_after, ParseUntilErrorBehavi
 ///
 /// Typical usage is `input.try_parse(parse_important).is_ok()`
 /// at the end of a `DeclarationParser::parse_value` implementation.
-pub fn parse_important<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(), BasicParseError<'i>> {
+pub fn parse_important<'i>(input: &mut Parser<'i, '_>) -> Result<(), BasicParseError<'i>> {
     input.expect_delim('!')?;
     input.expect_ident_matching("important")
 }
@@ -253,10 +253,10 @@ where
             self.input.skip_whitespace();
             let start = self.input.state();
             match self.input.next_including_whitespace_and_comments().ok()? {
-                Token::CloseCurlyBracket |
-                Token::WhiteSpace(..) |
-                Token::Semicolon |
-                Token::Comment(..) => continue,
+                Token::CloseCurlyBracket
+                | Token::WhiteSpace(..)
+                | Token::Semicolon
+                | Token::Comment(..) => continue,
                 Token::AtKeyword(ref name) => {
                     let name = name.clone();
                     return Some(parse_at_rule(&start, name, self.input, &mut *self.parser));
@@ -294,7 +294,7 @@ where
                             &mut *self.parser,
                             Delimiter::Semicolon | Delimiter::CurlyBracketBlock,
                         ) {
-                            return Some(Ok(qual))
+                            return Some(Ok(qual));
                         }
                     }
 
@@ -367,7 +367,7 @@ where
             let start = self.input.state();
             let at_keyword = match self.input.next_byte()? {
                 b'@' => match self.input.next_including_whitespace_and_comments() {
-                    Ok(&Token::AtKeyword(ref name)) => Some(name.clone()),
+                    Ok(Token::AtKeyword(name)) => Some(name.clone()),
                     _ => {
                         self.input.reset(&start);
                         None
@@ -503,5 +503,5 @@ where
     input.expect_curly_bracket_block()?;
     // Do this here so that we consume the `{` even if the prelude is `Err`.
     let prelude = prelude?;
-    parse_nested_block(input, |input| parser.parse_block(prelude, &start, input))
+    parse_nested_block(input, |input| parser.parse_block(prelude, start, input))
 }
diff --git a/src/serializer.rs b/src/serializer.rs
index 09c22402..403976cd 100644
--- a/src/serializer.rs
+++ b/src/serializer.rs
@@ -3,8 +3,7 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use crate::match_byte;
-use dtoa_short::{self, Notation};
-use itoa;
+use dtoa_short::Notation;
 use std::fmt::{self, Write};
 use std::str;
 
@@ -49,10 +48,9 @@ where
         dtoa_short::write(dest, value)?
     };
 
-    if int_value.is_none() && value.fract() == 0. {
-        if !notation.decimal_point && !notation.scientific {
-            dest.write_str(".0")?;
-        }
+    if int_value.is_none() && value.fract() == 0. && !notation.decimal_point && !notation.scientific
+    {
+        dest.write_str(".0")?;
     }
     Ok(())
 }
@@ -63,10 +61,10 @@ impl<'a> ToCss for Token<'a> {
         W: fmt::Write,
     {
         match *self {
-            Token::Ident(ref value) => serialize_identifier(&**value, dest)?,
+            Token::Ident(ref value) => serialize_identifier(value, dest)?,
             Token::AtKeyword(ref value) => {
                 dest.write_str("@")?;
-                serialize_identifier(&**value, dest)?;
+                serialize_identifier(value, dest)?;
             }
             Token::Hash(ref value) => {
                 dest.write_str("#")?;
@@ -74,12 +72,12 @@ impl<'a> ToCss for Token<'a> {
             }
             Token::IDHash(ref value) => {
                 dest.write_str("#")?;
-                serialize_identifier(&**value, dest)?;
+                serialize_identifier(value, dest)?;
             }
-            Token::QuotedString(ref value) => serialize_string(&**value, dest)?,
+            Token::QuotedString(ref value) => serialize_string(value, dest)?,
             Token::UnquotedUrl(ref value) => {
                 dest.write_str("url(")?;
-                serialize_unquoted_url(&**value, dest)?;
+                serialize_unquoted_url(value, dest)?;
                 dest.write_str(")")?;
             }
             Token::Delim(value) => dest.write_char(value)?,
@@ -134,7 +132,7 @@ impl<'a> ToCss for Token<'a> {
             Token::CDC => dest.write_str("-->")?,
 
             Token::Function(ref name) => {
-                serialize_identifier(&**name, dest)?;
+                serialize_identifier(name, dest)?;
                 dest.write_str("(")?;
             }
             Token::ParenthesisBlock => dest.write_str("(")?,
@@ -167,7 +165,7 @@ fn hex_escape<W>(ascii_byte: u8, dest: &mut W) -> fmt::Result
 where
     W: fmt::Write,
 {
-    static HEX_DIGITS: &'static [u8; 16] = b"0123456789abcdef";
+    static HEX_DIGITS: &[u8; 16] = b"0123456789abcdef";
     let b3;
     let b4;
     let bytes = if ascii_byte > 0x0F {
@@ -179,7 +177,7 @@ where
         b3 = [b'\\', HEX_DIGITS[ascii_byte as usize], b' '];
         &b3[..]
     };
-    dest.write_str(unsafe { str::from_utf8_unchecked(&bytes) })
+    dest.write_str(unsafe { str::from_utf8_unchecked(bytes) })
 }
 
 fn char_escape<W>(ascii_byte: u8, dest: &mut W) -> fmt::Result
@@ -199,9 +197,9 @@ where
         return Ok(());
     }
 
-    if value.starts_with("--") {
+    if let Some(value) = value.strip_prefix("--") {
         dest.write_str("--")?;
-        serialize_name(&value[2..], dest)
+        serialize_name(value, dest)
     } else if value == "-" {
         dest.write_str("\\-")
     } else {
@@ -240,7 +238,7 @@ where
         dest.write_str(&value[chunk_start..i])?;
         if let Some(escaped) = escaped {
             dest.write_str(escaped)?;
-        } else if (b >= b'\x01' && b <= b'\x1F') || b == b'\x7F' {
+        } else if (b'\x01'..=b'\x1F').contains(&b) || b == b'\x7F' {
             hex_escape(b, dest)?;
         } else {
             char_escape(b, dest)?;
diff --git a/src/tests.rs b/src/tests.rs
index f9dea193..98c51f61 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -5,8 +5,7 @@
 #[cfg(feature = "bench")]
 extern crate test;
 
-use encoding_rs;
-use serde_json::{self, json, Map, Value};
+use serde_json::{json, Map, Value};
 
 #[cfg(feature = "bench")]
 use self::test::Bencher;
@@ -25,25 +24,23 @@ macro_rules! JArray {
 }
 
 fn almost_equals(a: &Value, b: &Value) -> bool {
-    match (a, b) {
-        (&Value::Number(ref a), &Value::Number(ref b)) => {
+    let var_name = match (a, b) {
+        (Value::Number(a), Value::Number(b)) => {
             let a = a.as_f64().unwrap();
             let b = b.as_f64().unwrap();
             (a - b).abs() <= a.abs() * 1e-6
         }
 
         (&Value::Bool(a), &Value::Bool(b)) => a == b,
-        (&Value::String(ref a), &Value::String(ref b)) => a == b,
-        (&Value::Array(ref a), &Value::Array(ref b)) => {
-            a.len() == b.len()
-                && a.iter()
-                    .zip(b.iter())
-                    .all(|(ref a, ref b)| almost_equals(*a, *b))
+        (Value::String(a), Value::String(b)) => a == b,
+        (Value::Array(a), Value::Array(b)) => {
+            a.len() == b.len() && a.iter().zip(b.iter()).all(|(a, b)| almost_equals(a, b))
         }
         (&Value::Object(_), &Value::Object(_)) => panic!("Not implemented"),
         (&Value::Null, &Value::Null) => true,
         _ => false,
-    }
+    };
+    var_name
 }
 
 fn normalize(json: &mut Value) {
@@ -77,7 +74,7 @@ fn assert_json_eq(results: Value, mut expected: Value, message: &str) {
     }
 }
 
-fn run_raw_json_tests<F: Fn(Value, Value) -> ()>(json_data: &str, run: F) {
+fn run_raw_json_tests<F: Fn(Value, Value)>(json_data: &str, run: F) {
     let items = match serde_json::from_str(json_data) {
         Ok(Value::Array(items)) => items,
         other => panic!("Invalid JSON: {:?}", other),
@@ -242,7 +239,7 @@ fn stylesheet_from_bytes() {
 
     fn get_string<'a>(map: &'a Map<String, Value>, key: &str) -> Option<&'a str> {
         match map.get(key) {
-            Some(&Value::String(ref s)) => Some(s),
+            Some(Value::String(s)) => Some(s),
             Some(&Value::Null) => None,
             None => None,
             _ => panic!("Unexpected JSON"),
@@ -393,7 +390,7 @@ fn unicode_range() {
             if input.is_exhausted() {
                 Ok(result)
             } else {
-                while let Ok(_) = input.next() {}
+                while input.next().is_ok() {}
                 Ok(None)
             }
         });
@@ -593,8 +590,6 @@ fn line_numbers() {
 
 #[test]
 fn overflow() {
-    use std::iter::repeat;
-
     let css = r"
          2147483646
          2147483647
@@ -619,7 +614,7 @@ fn overflow() {
          -3.402824e+38
 
     "
-    .replace("{309 zeros}", &repeat('0').take(309).collect::<String>());
+    .replace("{309 zeros}", &"0".repeat(309));
     let mut input = ParserInput::new(&css);
     let mut input = Parser::new(&mut input);
 
@@ -637,15 +632,13 @@ fn overflow() {
     assert_eq!(input.expect_integer(), Ok(-2147483648));
     assert_eq!(input.expect_integer(), Ok(-2147483648));
 
-    assert_eq!(input.expect_number(), Ok(3.30282347e+38));
+    assert_eq!(input.expect_number(), Ok(3.302_823_5e38));
     assert_eq!(input.expect_number(), Ok(f32::MAX));
     assert_eq!(input.expect_number(), Ok(f32::INFINITY));
-    assert!(f32::MAX != f32::INFINITY);
 
-    assert_eq!(input.expect_number(), Ok(-3.30282347e+38));
+    assert_eq!(input.expect_number(), Ok(-3.302_823_5e38));
     assert_eq!(input.expect_number(), Ok(f32::MIN));
     assert_eq!(input.expect_number(), Ok(f32::NEG_INFINITY));
-    assert!(f32::MIN != f32::NEG_INFINITY);
 }
 
 #[test]
@@ -784,7 +777,7 @@ where
 
 impl<'a> ToJson for CowRcStr<'a> {
     fn to_json(&self) -> Value {
-        let s: &str = &*self;
+        let s: &str = self;
         s.to_json()
     }
 }
@@ -847,7 +840,7 @@ fn no_stack_overflow_multiple_nested_blocks() {
     }
     let mut input = ParserInput::new(&input);
     let mut input = Parser::new(&mut input);
-    while let Ok(..) = input.next() {}
+    while input.next().is_ok() {}
 }
 
 impl<'i> DeclarationParser<'i> for JsonParser {
@@ -870,11 +863,9 @@ impl<'i> DeclarationParser<'i> for JsonParser {
                 // (even CSS Variables forbid top-level `!`)
                 if token == Token::Delim('!') {
                     input.reset(&start);
-                    if parse_important(input).is_ok() {
-                        if input.is_exhausted() {
-                            important = true;
-                            break;
-                        }
+                    if parse_important(input).is_ok() && input.is_exhausted() {
+                        important = true;
+                        break;
                     }
                     input.reset(&start);
                     token = input.next_including_whitespace().unwrap().clone();
@@ -905,7 +896,7 @@ impl<'i> AtRuleParser<'i> for JsonParser {
         ];
         match_ignore_ascii_case! { &*name,
             "charset" => {
-                Err(input.new_error(BasicParseErrorKind::AtRuleInvalid(name.clone()).into()))
+                Err(input.new_error(BasicParseErrorKind::AtRuleInvalid(name.clone())))
             },
             _ => Ok(prelude),
         }
@@ -978,9 +969,9 @@ fn one_component_value_to_json(token: Token, input: &mut Parser) -> Value {
     fn numeric(value: f32, int_value: Option<i32>, has_sign: bool) -> Vec<Value> {
         vec![
             Token::Number {
-                value: value,
-                int_value: int_value,
-                has_sign: has_sign,
+                value,
+                int_value,
+                has_sign,
             }
             .to_css_string()
             .to_json(),
@@ -1137,7 +1128,7 @@ fn parse_until_before_stops_at_delimiter_or_end_of_input() {
                             let ox = ix.next();
                             let oy = iy.next();
                             assert_eq!(ox, oy);
-                            if let Err(_) = ox {
+                            if ox.is_err() {
                                 break;
                             }
                         }
@@ -1223,7 +1214,7 @@ fn parse_sourcemapping_comments() {
     for test in tests {
         let mut input = ParserInput::new(test.0);
         let mut parser = Parser::new(&mut input);
-        while let Ok(_) = parser.next_including_whitespace() {}
+        while parser.next_including_whitespace().is_ok() {}
         assert_eq!(parser.current_source_map_url(), test.1);
     }
 }
@@ -1247,7 +1238,7 @@ fn parse_sourceurl_comments() {
     for test in tests {
         let mut input = ParserInput::new(test.0);
         let mut parser = Parser::new(&mut input);
-        while let Ok(_) = parser.next_including_whitespace() {}
+        while parser.next_including_whitespace().is_ok() {}
         assert_eq!(parser.current_source_url(), test.1);
     }
 }
@@ -1321,7 +1312,8 @@ fn utf16_columns() {
                     break;
                 }
                 Err(_) => {
-                    assert!(false);
+                    // should this be an explicit panic instead?
+                    unreachable!();
                 }
                 Ok(_) => {}
             };
diff --git a/src/tokenizer.rs b/src/tokenizer.rs
index a3b70063..f1716c71 100644
--- a/src/tokenizer.rs
+++ b/src/tokenizer.rs
@@ -255,10 +255,10 @@ impl<'a> Tokenizer<'a> {
 
     #[inline]
     pub fn see_function(&mut self, name: &str) {
-        if self.var_or_env_functions == SeenStatus::LookingForThem {
-            if name.eq_ignore_ascii_case("var") || name.eq_ignore_ascii_case("env") {
-                self.var_or_env_functions = SeenStatus::SeenAtLeastOne;
-            }
+        if self.var_or_env_functions == SeenStatus::LookingForThem
+            && (name.eq_ignore_ascii_case("var") || name.eq_ignore_ascii_case("env"))
+        {
+            self.var_or_env_functions = SeenStatus::SeenAtLeastOne;
         }
     }
 
@@ -322,10 +322,12 @@ impl<'a> Tokenizer<'a> {
 
     pub fn current_source_line(&self) -> &'a str {
         let current = self.position();
-        let start = self.slice(SourcePosition(0)..current)
+        let start = self
+            .slice(SourcePosition(0)..current)
             .rfind(|c| matches!(c, '\r' | '\n' | '\x0C'))
             .map_or(0, |start| start + 1);
-        let end = self.slice(current..SourcePosition(self.input.len()))
+        let end = self
+            .slice(current..SourcePosition(self.input.len()))
             .find(|c| matches!(c, '\r' | '\n' | '\x0C'))
             .map_or(self.input.len(), |end| current.0 + end);
         self.slice(SourcePosition(start)..SourcePosition(end))
@@ -424,7 +426,10 @@ impl<'a> Tokenizer<'a> {
 
     #[inline]
     fn next_char(&self) -> char {
-        unsafe { self.input.get_unchecked(self.position().0..) }.chars().next().unwrap()
+        unsafe { self.input.get_unchecked(self.position().0..) }
+            .chars()
+            .next()
+            .unwrap()
     }
 
     // Given that a newline has been seen, advance over the newline
@@ -582,11 +587,11 @@ fn next_token<'a>(tokenizer: &mut Tokenizer<'a>) -> Result<Token<'a>, ()> {
         b'+' => {
             if (
                 tokenizer.has_at_least(1)
-                && matches!(tokenizer.byte_at(1), b'0'..=b'9')
+                && tokenizer.byte_at(1).is_ascii_digit()
             ) || (
                 tokenizer.has_at_least(2)
                 && tokenizer.byte_at(1) == b'.'
-                && matches!(tokenizer.byte_at(2), b'0'..=b'9')
+                && tokenizer.byte_at(2).is_ascii_digit()
             ) {
                 consume_numeric(tokenizer)
             } else {
@@ -598,11 +603,11 @@ fn next_token<'a>(tokenizer: &mut Tokenizer<'a>) -> Result<Token<'a>, ()> {
         b'-' => {
             if (
                 tokenizer.has_at_least(1)
-                && matches!(tokenizer.byte_at(1), b'0'..=b'9')
+                && tokenizer.byte_at(1).is_ascii_digit()
             ) || (
                 tokenizer.has_at_least(2)
                 && tokenizer.byte_at(1) == b'.'
-                && matches!(tokenizer.byte_at(2), b'0'..=b'9')
+                && tokenizer.byte_at(2).is_ascii_digit()
             ) {
                 consume_numeric(tokenizer)
             } else if tokenizer.starts_with(b"-->") {
@@ -617,8 +622,7 @@ fn next_token<'a>(tokenizer: &mut Tokenizer<'a>) -> Result<Token<'a>, ()> {
         },
         b'.' => {
             if tokenizer.has_at_least(1)
-                && matches!(tokenizer.byte_at(1), b'0'..=b'9'
-            ) {
+                && tokenizer.byte_at(1).is_ascii_digit() {
                 consume_numeric(tokenizer)
             } else {
                 tokenizer.advance(1);
@@ -1001,7 +1005,7 @@ fn byte_to_hex_digit(b: u8) -> Option<u32> {
 }
 
 fn byte_to_decimal_digit(b: u8) -> Option<u32> {
-    if b >= b'0' && b <= b'9' {
+    if b.is_ascii_digit() {
         Some((b - b'0') as u32)
     } else {
         None
@@ -1038,7 +1042,7 @@ fn consume_numeric<'a>(tokenizer: &mut Tokenizer<'a>) -> Token<'a> {
     let mut fractional_part: f64 = 0.;
     if tokenizer.has_at_least(1)
         && tokenizer.next_byte_unchecked() == b'.'
-        && matches!(tokenizer.byte_at(1), b'0'..=b'9')
+        && tokenizer.byte_at(1).is_ascii_digit()
     {
         is_integer = false;
         tokenizer.advance(1); // Consume '.'
@@ -1055,32 +1059,32 @@ fn consume_numeric<'a>(tokenizer: &mut Tokenizer<'a>) -> Token<'a> {
 
     let mut value = sign * (integral_part + fractional_part);
 
-    if tokenizer.has_at_least(1) && matches!(tokenizer.next_byte_unchecked(), b'e' | b'E') {
-        if matches!(tokenizer.byte_at(1), b'0'..=b'9')
+    if tokenizer.has_at_least(1)
+        && matches!(tokenizer.next_byte_unchecked(), b'e' | b'E')
+        && (tokenizer.byte_at(1).is_ascii_digit()
             || (tokenizer.has_at_least(2)
                 && matches!(tokenizer.byte_at(1), b'+' | b'-')
-                && matches!(tokenizer.byte_at(2), b'0'..=b'9'))
-        {
-            is_integer = false;
+                && tokenizer.byte_at(2).is_ascii_digit()))
+    {
+        is_integer = false;
+        tokenizer.advance(1);
+        let (has_sign, sign) = match tokenizer.next_byte_unchecked() {
+            b'-' => (true, -1.),
+            b'+' => (true, 1.),
+            _ => (false, 1.),
+        };
+        if has_sign {
             tokenizer.advance(1);
-            let (has_sign, sign) = match tokenizer.next_byte_unchecked() {
-                b'-' => (true, -1.),
-                b'+' => (true, 1.),
-                _ => (false, 1.),
-            };
-            if has_sign {
-                tokenizer.advance(1);
-            }
-            let mut exponent: f64 = 0.;
-            while let Some(digit) = byte_to_decimal_digit(tokenizer.next_byte_unchecked()) {
-                exponent = exponent * 10. + digit as f64;
-                tokenizer.advance(1);
-                if tokenizer.is_eof() {
-                    break;
-                }
+        }
+        let mut exponent: f64 = 0.;
+        while let Some(digit) = byte_to_decimal_digit(tokenizer.next_byte_unchecked()) {
+            exponent = exponent * 10. + digit as f64;
+            tokenizer.advance(1);
+            if tokenizer.is_eof() {
+                break;
             }
-            value *= f64::powf(10., sign * exponent);
         }
+        value *= f64::powf(10., sign * exponent);
     }
 
     let int_value = if is_integer {
@@ -1339,7 +1343,7 @@ fn consume_unquoted_url<'a>(tokenizer: &mut Tokenizer<'a>) -> Result<Token<'a>,
 }
 
 // (value, number of digits up to 6)
-fn consume_hex_digits<'a>(tokenizer: &mut Tokenizer<'a>) -> (u32, u32) {
+fn consume_hex_digits(tokenizer: &mut Tokenizer<'_>) -> (u32, u32) {
     let mut value = 0;
     let mut digits = 0;
     while digits < 6 && !tokenizer.is_eof() {
diff --git a/src/unicode_range.rs b/src/unicode_range.rs
index b0a2017c..ce6bb3b5 100644
--- a/src/unicode_range.rs
+++ b/src/unicode_range.rs
@@ -24,7 +24,7 @@ pub struct UnicodeRange {
 
 impl UnicodeRange {
     /// https://drafts.csswg.org/css-syntax/#urange-syntax
-    pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, BasicParseError<'i>> {
+    pub fn parse<'i>(input: &mut Parser<'i, '_>) -> Result<Self, BasicParseError<'i>> {
         // <urange> =
         //   u '+' <ident-token> '?'* |
         //   u <dimension-token> '?'* |
@@ -57,7 +57,7 @@ impl UnicodeRange {
     }
 }
 
-fn parse_tokens<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(), BasicParseError<'i>> {
+fn parse_tokens<'i>(input: &mut Parser<'i, '_>) -> Result<(), BasicParseError<'i>> {
     match input.next_including_whitespace()?.clone() {
         Token::Delim('+') => {
             match *input.next_including_whitespace()? {
@@ -123,15 +123,13 @@ fn parse_concatenated(text: &[u8]) -> Result<UnicodeRange, ()> {
             start: first_hex_value,
             end: first_hex_value,
         });
-    } else {
-        if let Some((&b'-', mut text)) = text.split_first() {
-            let (second_hex_value, hex_digit_count) = consume_hex(&mut text);
-            if hex_digit_count > 0 && hex_digit_count <= 6 && text.is_empty() {
-                return Ok(UnicodeRange {
-                    start: first_hex_value,
-                    end: second_hex_value,
-                });
-            }
+    } else if let Some((&b'-', mut text)) = text.split_first() {
+        let (second_hex_value, hex_digit_count) = consume_hex(&mut text);
+        if hex_digit_count > 0 && hex_digit_count <= 6 && text.is_empty() {
+            return Ok(UnicodeRange {
+                start: first_hex_value,
+                end: second_hex_value,
+            });
         }
     }
     Err(())

From 50b3203748b22d159eabbf085783d78c764cea1f Mon Sep 17 00:00:00 2001
From: Chipnertkj <32001812+chipnertkj@users.noreply.github.com>
Date: Thu, 7 Dec 2023 02:01:45 +0100
Subject: [PATCH 22/38] Make color use serde, and update serialization to be
 derived.

---
 Cargo.toml       |   8 +--
 color/Cargo.toml |   6 ++-
 color/lib.rs     | 123 +++++------------------------------------------
 src/color.rs     |   2 +
 4 files changed, 23 insertions(+), 116 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index c7beb4c1..ea04cb43 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "cssparser"
 version = "0.33.0"
-authors = [ "Simon Sapin <simon.sapin@exyr.org>" ]
+authors = ["Simon Sapin <simon.sapin@exyr.org>"]
 
 description = "Rust implementation of CSS Syntax Level 3"
 documentation = "https://docs.rs/cssparser/"
@@ -20,11 +20,11 @@ difference = "2.0"
 encoding_rs = "0.8"
 
 [dependencies]
-cssparser-macros = {path = "./macros", version = "0.6.1"}
+cssparser-macros = { path = "./macros", version = "0.6.1" }
 dtoa-short = "0.3"
 itoa = "1.0"
-phf = {version = "0.11.2", features = ["macros"]}
-serde = {version = "1.0", optional = true}
+phf =  { version = "0.11.2", features = ["macros"] }
+serde = { version = "1.0", features = ["derive"], optional = true }
 smallvec = "1.0"
 
 [features]
diff --git a/color/Cargo.toml b/color/Cargo.toml
index d1e315a8..47544815 100644
--- a/color/Cargo.toml
+++ b/color/Cargo.toml
@@ -12,7 +12,11 @@ edition = "2021"
 path = "lib.rs"
 
 [dependencies]
-cssparser = { version = "0.33", path = ".." }
+cssparser = { path = ".." }
+serde = { version = "1.0", features = ["derive"], optional = true }
+
+[features]
+serde = ["cssparser/serde", "dep:serde"]
 
 [dev-dependencies]
 serde_json = "1.0.25"
diff --git a/color/lib.rs b/color/lib.rs
index 1c52e38d..cf30fd5b 100644
--- a/color/lib.rs
+++ b/color/lib.rs
@@ -16,8 +16,6 @@ use cssparser::color::{
     PredefinedColorSpace, OPAQUE,
 };
 use cssparser::{match_ignore_ascii_case, CowRcStr, ParseError, Parser, ToCss, Token};
-#[cfg(feature = "serde")]
-use serde::{Deserialize, Deserializer, Serialize, Serializer};
 use std::f32::consts::PI;
 use std::fmt;
 use std::str::FromStr;
@@ -55,10 +53,8 @@ where
     let token = input.next()?;
     match *token {
         Token::Hash(ref value) | Token::IDHash(ref value) => {
-            parse_hash_color(value.as_bytes()).map(|(r, g, b, a)| {
-                P::Output::from_rgba(r, g, b, a)
-            })
-        },
+            parse_hash_color(value.as_bytes()).map(|(r, g, b, a)| P::Output::from_rgba(r, g, b, a))
+        }
         Token::Ident(ref value) => parse_color_keyword(value),
         Token::Function(ref name) => {
             let name = name.clone();
@@ -506,6 +502,7 @@ fn normalize_hue(hue: f32) -> f32 {
 }
 
 /// A color with red, green, blue, and alpha components, in a byte each.
+#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
 #[derive(Clone, Copy, PartialEq, Debug)]
 pub struct RgbaLegacy {
     /// The red component.
@@ -544,27 +541,6 @@ impl RgbaLegacy {
     }
 }
 
-#[cfg(feature = "serde")]
-impl Serialize for RgbaLegacy {
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: Serializer,
-    {
-        (self.red, self.green, self.blue, self.alpha).serialize(serializer)
-    }
-}
-
-#[cfg(feature = "serde")]
-impl<'de> Deserialize<'de> for RgbaLegacy {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        let (r, g, b, a) = Deserialize::deserialize(deserializer)?;
-        Ok(RgbaLegacy::new(r, g, b, a))
-    }
-}
-
 impl ToCss for RgbaLegacy {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
     where
@@ -588,6 +564,7 @@ impl ToCss for RgbaLegacy {
 
 /// Color specified by hue, saturation and lightness components.
 #[derive(Clone, Copy, PartialEq, Debug)]
+#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
 pub struct Hsl {
     /// The hue component.
     pub hue: Option<f32>,
@@ -632,29 +609,9 @@ impl ToCss for Hsl {
     }
 }
 
-#[cfg(feature = "serde")]
-impl Serialize for Hsl {
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: Serializer,
-    {
-        (self.hue, self.saturation, self.lightness, self.alpha).serialize(serializer)
-    }
-}
-
-#[cfg(feature = "serde")]
-impl<'de> Deserialize<'de> for Hsl {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        let (lightness, a, b, alpha) = Deserialize::deserialize(deserializer)?;
-        Ok(Self::new(lightness, a, b, alpha))
-    }
-}
-
 /// Color specified by hue, whiteness and blackness components.
 #[derive(Clone, Copy, PartialEq, Debug)]
+#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
 pub struct Hwb {
     /// The hue component.
     pub hue: Option<f32>,
@@ -699,32 +656,12 @@ impl ToCss for Hwb {
     }
 }
 
-#[cfg(feature = "serde")]
-impl Serialize for Hwb {
-    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-    where
-        S: Serializer,
-    {
-        (self.hue, self.whiteness, self.blackness, self.alpha).serialize(serializer)
-    }
-}
-
-#[cfg(feature = "serde")]
-impl<'de> Deserialize<'de> for Hwb {
-    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-    where
-        D: Deserializer<'de>,
-    {
-        let (lightness, whiteness, blackness, alpha) = Deserialize::deserialize(deserializer)?;
-        Ok(Self::new(lightness, whiteness, blackness, alpha))
-    }
-}
-
 // NOTE: LAB and OKLAB is not declared inside the [impl_lab_like] macro,
 // because it causes cbindgen to ignore them.
 
 /// Color specified by lightness, a- and b-axis components.
 #[derive(Clone, Copy, PartialEq, Debug)]
+#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
 pub struct Lab {
     /// The lightness component.
     pub lightness: Option<f32>,
@@ -738,6 +675,7 @@ pub struct Lab {
 
 /// Color specified by lightness, a- and b-axis components.
 #[derive(Clone, Copy, PartialEq, Debug)]
+#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
 pub struct Oklab {
     /// The lightness component.
     pub lightness: Option<f32>,
@@ -768,27 +706,6 @@ macro_rules! impl_lab_like {
             }
         }
 
-        #[cfg(feature = "serde")]
-        impl Serialize for $cls {
-            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-            where
-                S: Serializer,
-            {
-                (self.lightness, self.a, self.b, self.alpha).serialize(serializer)
-            }
-        }
-
-        #[cfg(feature = "serde")]
-        impl<'de> Deserialize<'de> for $cls {
-            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-            where
-                D: Deserializer<'de>,
-            {
-                let (lightness, a, b, alpha) = Deserialize::deserialize(deserializer)?;
-                Ok(Self::new(lightness, a, b, alpha))
-            }
-        }
-
         impl ToCss for $cls {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result
             where
@@ -816,6 +733,7 @@ impl_lab_like!(Oklab, "oklab");
 
 /// Color specified by lightness, chroma and hue components.
 #[derive(Clone, Copy, PartialEq, Debug)]
+#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
 pub struct Lch {
     /// The lightness component.
     pub lightness: Option<f32>,
@@ -829,6 +747,7 @@ pub struct Lch {
 
 /// Color specified by lightness, chroma and hue components.
 #[derive(Clone, Copy, PartialEq, Debug)]
+#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
 pub struct Oklch {
     /// The lightness component.
     pub lightness: Option<f32>,
@@ -859,27 +778,6 @@ macro_rules! impl_lch_like {
             }
         }
 
-        #[cfg(feature = "serde")]
-        impl Serialize for $cls {
-            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-            where
-                S: Serializer,
-            {
-                (self.lightness, self.chroma, self.hue, self.alpha).serialize(serializer)
-            }
-        }
-
-        #[cfg(feature = "serde")]
-        impl<'de> Deserialize<'de> for $cls {
-            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
-            where
-                D: Deserializer<'de>,
-            {
-                let (lightness, chroma, hue, alpha) = Deserialize::deserialize(deserializer)?;
-                Ok(Self::new(lightness, chroma, hue, alpha))
-            }
-        }
-
         impl ToCss for $cls {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result
             where
@@ -905,6 +803,7 @@ impl_lch_like!(Oklch, "oklch");
 /// A color specified by the color() function.
 /// <https://drafts.csswg.org/css-color-4/#color-function>
 #[derive(Clone, Copy, PartialEq, Debug)]
+#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
 pub struct ColorFunction {
     /// The color space for this color.
     pub color_space: PredefinedColorSpace,
@@ -966,6 +865,8 @@ impl ToCss for ColorFunction {
 ///
 /// <https://drafts.csswg.org/css-color-4/#color-type>
 #[derive(Clone, Copy, PartialEq, Debug)]
+#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
+#[cfg_attr(feature = "serde", serde(tag = "type"))]
 pub enum Color {
     /// The 'currentcolor' keyword.
     CurrentColor,
diff --git a/src/color.rs b/src/color.rs
index d5f9a5c0..f4d11809 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -77,6 +77,8 @@ pub fn serialize_color_alpha(
 /// A Predefined color space specified in:
 /// <https://drafts.csswg.org/css-color-4/#predefined>
 #[derive(Clone, Copy, PartialEq, Debug)]
+#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
+#[cfg_attr(feature = "serde", serde(tag = "type"))]
 pub enum PredefinedColorSpace {
     /// <https://drafts.csswg.org/css-color-4/#predefined-sRGB>
     Srgb,

From d44a7ccf35c83f7fee3c214d9e6015efa80b5df0 Mon Sep 17 00:00:00 2001
From: Tiaan Louw <tiaanl@gmail.com>
Date: Sat, 6 Apr 2024 19:08:42 +0200
Subject: [PATCH 23/38] Fix the documentation of what certain parse functions
 return (#372)

---
 src/parser.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/parser.rs b/src/parser.rs
index 424306e1..b1357f26 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -677,7 +677,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
     }
 
     /// Have the given closure parse something, then check the the input is exhausted.
-    /// The result is overridden to `Err(())` if some input remains.
+    /// The result is overridden to an `Err(..)` if some input remains.
     ///
     /// This can help tell e.g. `color: green;` from `color: green 4px;`
     #[inline]
@@ -767,7 +767,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
     /// The given closure is called with a "delimited" parser
     /// that stops at the end of the block or function (at the matching closing token).
     ///
-    /// The result is overridden to `Err(())` if the closure leaves some input before that point.
+    /// The result is overridden to an `Err(..)` if the closure leaves some input before that point.
     #[inline]
     pub fn parse_nested_block<F, T, E>(&mut self, parse: F) -> Result<T, ParseError<'i, E>>
     where
@@ -783,7 +783,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
     /// that stops before the first character at this block/function nesting level
     /// that matches the given set of delimiters, or at the end of the input.
     ///
-    /// The result is overridden to `Err(())` if the closure leaves some input before that point.
+    /// The result is overridden to an `Err(..)` if the closure leaves some input before that point.
     #[inline]
     pub fn parse_until_before<F, T, E>(
         &mut self,

From 22e42797d21a21cab414eaafc2240632bee99816 Mon Sep 17 00:00:00 2001
From: Alex Touchet <alextouchet@outlook.com>
Date: Sun, 7 Apr 2024 05:31:02 -0700
Subject: [PATCH 24/38] Update Servo style crate URL (#379)

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 84d47d9e..d9ca4ada 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@ rust-cssparser
 
 [![Build Status](https://github.com/servo/rust-cssparser/actions/workflows/main.yml/badge.svg)](https://github.com/servo/rust-cssparser/actions)
 
-[Documentation](https://docs.rs/cssparser/)
+[Documentation](https://docs.rs/cssparser)
 
 Rust implementation of
 [CSS Syntax Module Level 3](https://drafts.csswg.org/css-syntax/)
@@ -53,5 +53,5 @@ Parsing CSS involves a series of steps:
   It does however provide some helper functions to parse [CSS colors](src/color.rs)
   and [An+B](src/nth.rs) (the argument to `:nth-child()` and related selectors.
 
-  See [Servo’s `style` crate](https://github.com/servo/servo/tree/master/components/style)
+  See [Servo’s `style` crate](https://github.com/servo/stylo/tree/main/style)
   for an example of a parser based on rust-cssparser.

From e95c5be76ef12f44e258f5c021b937d069e16b17 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Mon, 8 Apr 2024 00:03:00 +0200
Subject: [PATCH 25/38] Add a profiling cargo profile.

---
 Cargo.toml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Cargo.toml b/Cargo.toml
index ea04cb43..6630f7f4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,6 +27,10 @@ phf =  { version = "0.11.2", features = ["macros"] }
 serde = { version = "1.0", features = ["derive"], optional = true }
 smallvec = "1.0"
 
+[profile.profiling]
+inherits = "release"
+debug = true
+
 [features]
 bench = []
 dummy_match_byte = []

From 8f13fc9689af200b2bd04ba6ea15a1bc1fe29090 Mon Sep 17 00:00:00 2001
From: Tiaan Louw <tiaanl@gmail.com>
Date: Mon, 8 Apr 2024 00:04:27 +0200
Subject: [PATCH 26/38] Further clarifications in docs for what errors are
 returned. (#380)

Based on #281
---
 src/nth.rs                    |  2 +-
 src/parser.rs                 |  2 +-
 src/rules_and_declarations.rs | 12 ++++++------
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/nth.rs b/src/nth.rs
index e4bde0de..4fe5a6bc 100644
--- a/src/nth.rs
+++ b/src/nth.rs
@@ -7,7 +7,7 @@ use super::{BasicParseError, Parser, ParserInput, Token};
 /// Parse the *An+B* notation, as found in the `:nth-child()` selector.
 /// The input is typically the arguments of a function,
 /// in which case the caller needs to check if the arguments’ parser is exhausted.
-/// Return `Ok((A, B))`, or `Err(())` for a syntax error.
+/// Return `Ok((A, B))`, or an `Err(..)` for a syntax error.
 pub fn parse_nth<'i>(input: &mut Parser<'i, '_>) -> Result<(i32, i32), BasicParseError<'i>> {
     match *input.next()? {
         Token::Number {
diff --git a/src/parser.rs b/src/parser.rs
index b1357f26..77a21008 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -698,7 +698,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
     ///
     /// Successful results are accumulated in a vector.
     ///
-    /// This method returns `Err(())` the first time that a closure call does,
+    /// This method returns an`Err(..)` the first time that a closure call does,
     /// or if a closure call leaves some input before the next comma or the end
     /// of the input.
     #[inline]
diff --git a/src/rules_and_declarations.rs b/src/rules_and_declarations.rs
index b23e9dc0..c6af2311 100644
--- a/src/rules_and_declarations.rs
+++ b/src/rules_and_declarations.rs
@@ -34,7 +34,7 @@ pub trait DeclarationParser<'i> {
     ///
     /// Return the finished representation for the declaration
     /// as returned by `DeclarationListParser::next`,
-    /// or `Err(())` to ignore the entire declaration as invalid.
+    /// or an `Err(..)` to ignore the entire declaration as invalid.
     ///
     /// Declaration name matching should be case-insensitive in the ASCII range.
     /// This can be done with `std::ascii::Ascii::eq_ignore_ascii_case`,
@@ -78,7 +78,7 @@ pub trait AtRuleParser<'i> {
     /// Parse the prelude of an at-rule with the given `name`.
     ///
     /// Return the representation of the prelude and the type of at-rule,
-    /// or `Err(())` to ignore the entire at-rule as invalid.
+    /// or an `Err(..)` to ignore the entire at-rule as invalid.
     ///
     /// The prelude is the part after the at-keyword
     /// and before the `;` semicolon or `{ /* ... */ }` block.
@@ -122,7 +122,7 @@ pub trait AtRuleParser<'i> {
     ///
     /// Return the finished representation of the at-rule
     /// as returned by `RuleListParser::next` or `DeclarationListParser::next`,
-    /// or `Err(())` to ignore the entire at-rule as invalid.
+    /// or an `Err(..)` to ignore the entire at-rule as invalid.
     ///
     /// This is only called when `parse_prelude` returned `WithBlock`, and a block
     /// was indeed found following the prelude.
@@ -161,7 +161,7 @@ pub trait QualifiedRuleParser<'i> {
     /// Parse the prelude of a qualified rule. For style rules, this is as Selector list.
     ///
     /// Return the representation of the prelude,
-    /// or `Err(())` to ignore the entire at-rule as invalid.
+    /// or an `Err(..)` to ignore the entire at-rule as invalid.
     ///
     /// The prelude is the part before the `{ /* ... */ }` block.
     ///
@@ -180,7 +180,7 @@ pub trait QualifiedRuleParser<'i> {
     ///
     /// Return the finished representation of the qualified rule
     /// as returned by `RuleListParser::next`,
-    /// or `Err(())` to ignore the entire at-rule as invalid.
+    /// or an `Err(..)` to ignore the entire at-rule as invalid.
     fn parse_block<'t>(
         &mut self,
         prelude: Self::Prelude,
@@ -353,7 +353,7 @@ where
     }
 }
 
-/// `RuleListParser` is an iterator that yields `Ok(_)` for a rule or `Err(())` for an invalid one.
+/// `RuleListParser` is an iterator that yields `Ok(_)` for a rule or an `Err(..)` for an invalid one.
 impl<'i, 't, 'a, R, P, E: 'i> Iterator for StyleSheetParser<'i, 't, 'a, P>
 where
     P: QualifiedRuleParser<'i, QualifiedRule = R, Error = E>

From ca69d958968ae6f15aa6a921242e1d2c052254a4 Mon Sep 17 00:00:00 2001
From: Tiaan Louw <tiaanl@gmail.com>
Date: Tue, 16 Apr 2024 18:08:01 +0200
Subject: [PATCH 27/38] Add cargo fmt and cargo clippy checks to CI (#384)

---
 .github/workflows/main.yml    |  7 +++++--
 color/lib.rs                  |  1 +
 src/color.rs                  |  4 +++-
 src/parser.rs                 |  3 ++-
 src/rules_and_declarations.rs |  1 +
 src/serializer.rs             |  4 ++--
 src/tests.rs                  | 10 ++++------
 src/tokenizer.rs              |  8 ++++----
 8 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 07bedca5..b08ddef7 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -7,7 +7,7 @@ on:
   workflow_dispatch:
   merge_group:
     types: [checks_requested]
-    
+
 jobs:
   linux-ci:
     name: Linux
@@ -36,7 +36,10 @@ jobs:
           profile: minimal
           toolchain: ${{ matrix.toolchain }}
           override: true
-          components: ${{ matrix.toolchain == 'nightly' && 'miri,rust-src' || '' }}
+          components: rustfmt, clippy, ${{ matrix.toolchain == 'nightly' && 'miri,rust-src' || '' }}
+
+      - name: Cargo format & lint
+        run: cargo fmt --check && cargo clippy -- -Dwarnings
 
       - name: Cargo build
         run: cargo build ${{ matrix.features }}
diff --git a/color/lib.rs b/color/lib.rs
index cf30fd5b..83d0f279 100644
--- a/color/lib.rs
+++ b/color/lib.rs
@@ -25,6 +25,7 @@ use std::str::FromStr;
 /// Matching is case-insensitive in the ASCII range.
 /// CSS escaping (if relevant) should be resolved before calling this function.
 /// (For example, the value of an `Ident` token is fine.)
+#[allow(clippy::result_unit_err)]
 #[inline]
 pub fn parse_color_keyword<Output>(ident: &str) -> Result<Output, ()>
 where
diff --git a/src/color.rs b/src/color.rs
index f4d11809..e3ae926d 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -76,7 +76,7 @@ pub fn serialize_color_alpha(
 
 /// A Predefined color space specified in:
 /// <https://drafts.csswg.org/css-color-4/#predefined>
-#[derive(Clone, Copy, PartialEq, Debug)]
+#[derive(Clone, Copy, Eq, PartialEq, Debug)]
 #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
 #[cfg_attr(feature = "serde", serde(tag = "type"))]
 pub enum PredefinedColorSpace {
@@ -143,6 +143,7 @@ impl ToCss for PredefinedColorSpace {
 }
 
 /// Parse a color hash, without the leading '#' character.
+#[allow(clippy::result_unit_err)]
 #[inline]
 pub fn parse_hash_color(value: &[u8]) -> Result<(u8, u8, u8, f32), ()> {
     Ok(match value.len() {
@@ -330,6 +331,7 @@ ascii_case_insensitive_phf_map! {
 
 /// Returns the named color with the given name.
 /// <https://drafts.csswg.org/css-color-4/#typedef-named-color>
+#[allow(clippy::result_unit_err)]
 #[inline]
 pub fn parse_named_color(ident: &str) -> Result<(u8, u8, u8), ()> {
     named_colors::get(ident).copied().ok_or(())
diff --git a/src/parser.rs b/src/parser.rs
index 77a21008..e65cb013 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -53,7 +53,7 @@ impl ParserState {
 ///
 /// Would need to scan the whole {} block to find a semicolon, only for parsing getting restarted
 /// as a qualified rule later.
-#[derive(Clone, Copy, Debug, PartialEq)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
 pub enum ParseUntilErrorBehavior {
     /// Consume until we see the relevant delimiter or the end of the stream.
     Consume,
@@ -606,6 +606,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
     /// See the `Parser::parse_nested_block` method to parse the content of functions or blocks.
     ///
     /// This only returns a closing token when it is unmatched (and therefore an error).
+    #[allow(clippy::should_implement_trait)]
     pub fn next(&mut self) -> Result<&Token<'i>, BasicParseError<'i>> {
         self.skip_whitespace();
         self.next_including_whitespace_and_comments()
diff --git a/src/rules_and_declarations.rs b/src/rules_and_declarations.rs
index c6af2311..9240f6de 100644
--- a/src/rules_and_declarations.rs
+++ b/src/rules_and_declarations.rs
@@ -106,6 +106,7 @@ pub trait AtRuleParser<'i> {
     /// This is only called when `parse_prelude` returned `WithoutBlock`, and
     /// either the `;` semicolon indeed follows the prelude, or parser is at
     /// the end of the input.
+    #[allow(clippy::result_unit_err)]
     fn rule_without_block(
         &mut self,
         prelude: Self::Prelude,
diff --git a/src/serializer.rs b/src/serializer.rs
index 403976cd..3c6e31cb 100644
--- a/src/serializer.rs
+++ b/src/serializer.rs
@@ -338,7 +338,7 @@ where
 
 macro_rules! impl_tocss_for_int {
     ($T: ty) => {
-        impl<'a> ToCss for $T {
+        impl ToCss for $T {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result
             where
                 W: fmt::Write,
@@ -361,7 +361,7 @@ impl_tocss_for_int!(u64);
 
 macro_rules! impl_tocss_for_float {
     ($T: ty) => {
-        impl<'a> ToCss for $T {
+        impl ToCss for $T {
             fn to_css<W>(&self, dest: &mut W) -> fmt::Result
             where
                 W: fmt::Write,
diff --git a/src/tests.rs b/src/tests.rs
index 98c51f61..7389664d 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -430,11 +430,9 @@ fn serializer(preserve_comments: bool) {
                 preserve_comments: bool,
             ) {
                 while let Ok(token) = if preserve_comments {
-                    input
-                        .next_including_whitespace_and_comments()
-                        .map(|t| t.clone())
+                    input.next_including_whitespace_and_comments().cloned()
                 } else {
-                    input.next_including_whitespace().map(|t| t.clone())
+                    input.next_including_whitespace().cloned()
                 } {
                     let token_type = token.serialization_type();
                     if !preserve_comments && previous_token.needs_separator_when_before(token_type)
@@ -856,7 +854,7 @@ impl<'i> DeclarationParser<'i> for JsonParser {
         let mut important = false;
         loop {
             let start = input.state();
-            if let Ok(mut token) = input.next_including_whitespace().map(|t| t.clone()) {
+            if let Ok(mut token) = input.next_including_whitespace().cloned() {
                 // Hack to deal with css-parsing-tests assuming that
                 // `!important` in the middle of a declaration value is OK.
                 // This can never happen per spec
@@ -959,7 +957,7 @@ impl<'i> RuleBodyItemParser<'i, Value, ()> for JsonParser {
 
 fn component_values_to_json(input: &mut Parser) -> Vec<Value> {
     let mut values = vec![];
-    while let Ok(token) = input.next_including_whitespace().map(|t| t.clone()) {
+    while let Ok(token) = input.next_including_whitespace().cloned() {
         values.push(one_component_value_to_json(token, input));
     }
     values
diff --git a/src/tokenizer.rs b/src/tokenizer.rs
index f1716c71..ea173a5e 100644
--- a/src/tokenizer.rs
+++ b/src/tokenizer.rs
@@ -566,11 +566,11 @@ fn next_token<'a>(tokenizer: &mut Tokenizer<'a>) -> Result<Token<'a>, ()> {
         b'#' => {
             tokenizer.advance(1);
             if is_ident_start(tokenizer) { IDHash(consume_name(tokenizer)) }
-            else if !tokenizer.is_eof() && match tokenizer.next_byte_unchecked() {
+            else if !tokenizer.is_eof() &&
+                matches!(tokenizer.next_byte_unchecked(), b'0'..=b'9' | b'-') {
                 // Any other valid case here already resulted in IDHash.
-                b'0'..=b'9' | b'-' => true,
-                _ => false,
-            } { Hash(consume_name(tokenizer)) }
+                Hash(consume_name(tokenizer))
+            }
             else { Delim('#') }
         },
         b'$' => {

From cda06eede1c32af105add4017fbe1b651319f334 Mon Sep 17 00:00:00 2001
From: Tiaan Louw <tiaanl@gmail.com>
Date: Tue, 16 Apr 2024 19:02:53 +0200
Subject: [PATCH 28/38] Make PredefinedColorSpace follow the convention of
 parse() and ToCss (#386)

Also bump version to 0.34, because this is a breaking change.
---
 Cargo.toml     |  4 ++--
 color/lib.rs   |  9 +-------
 color/tests.rs |  2 +-
 src/color.rs   | 57 ++++++++++++++++++++++----------------------------
 4 files changed, 29 insertions(+), 43 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 6630f7f4..f783f19f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cssparser"
-version = "0.33.0"
+version = "0.34.0"
 authors = ["Simon Sapin <simon.sapin@exyr.org>"]
 
 description = "Rust implementation of CSS Syntax Level 3"
@@ -23,7 +23,7 @@ encoding_rs = "0.8"
 cssparser-macros = { path = "./macros", version = "0.6.1" }
 dtoa-short = "0.3"
 itoa = "1.0"
-phf =  { version = "0.11.2", features = ["macros"] }
+phf = { version = "0.11.2", features = ["macros"] }
 serde = { version = "1.0", features = ["derive"], optional = true }
 smallvec = "1.0"
 
diff --git a/color/lib.rs b/color/lib.rs
index 83d0f279..5b116c23 100644
--- a/color/lib.rs
+++ b/color/lib.rs
@@ -18,7 +18,6 @@ use cssparser::color::{
 use cssparser::{match_ignore_ascii_case, CowRcStr, ParseError, Parser, ToCss, Token};
 use std::f32::consts::PI;
 use std::fmt;
-use std::str::FromStr;
 
 /// Return the named color with the given name.
 ///
@@ -402,13 +401,7 @@ fn parse_color_with_color_space<'i, 't, P>(
 where
     P: ColorParser<'i>,
 {
-    let color_space = {
-        let location = arguments.current_source_location();
-
-        let ident = arguments.expect_ident()?;
-        PredefinedColorSpace::from_str(ident)
-            .map_err(|_| location.new_unexpected_token_error(Token::Ident(ident.clone())))?
-    };
+    let color_space = PredefinedColorSpace::parse(arguments)?;
 
     let (c1, c2, c3, alpha) = parse_components(
         color_parser,
diff --git a/color/tests.rs b/color/tests.rs
index 85eb430e..d8d8e5d4 100644
--- a/color/tests.rs
+++ b/color/tests.rs
@@ -215,7 +215,7 @@ impl ToJson for Color {
             Color::Oklab(ref c) => json!([c.lightness, c.a, c.b, c.alpha]),
             Color::Oklch(ref c) => json!([c.lightness, c.chroma, c.hue, c.alpha]),
             Color::ColorFunction(ref c) => {
-                json!([c.color_space.as_str(), c.c1, c.c2, c.c3, c.alpha])
+                json!([c.color_space.to_css_string(), c.c1, c.c2, c.c3, c.alpha])
             }
         }
     }
diff --git a/src/color.rs b/src/color.rs
index e3ae926d..978936e0 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -14,9 +14,8 @@
 /// The opaque alpha value of 1.0.
 pub const OPAQUE: f32 = 1.0;
 
-use crate::ToCss;
+use crate::{BasicParseError, Parser, ToCss, Token};
 use std::fmt;
-use std::str::FromStr;
 
 /// Clamp a 0..1 number to a 0..255 range to u8.
 ///
@@ -99,36 +98,21 @@ pub enum PredefinedColorSpace {
 }
 
 impl PredefinedColorSpace {
-    /// Returns the string value of the predefined color space.
-    pub fn as_str(&self) -> &str {
-        match self {
-            PredefinedColorSpace::Srgb => "srgb",
-            PredefinedColorSpace::SrgbLinear => "srgb-linear",
-            PredefinedColorSpace::DisplayP3 => "display-p3",
-            PredefinedColorSpace::A98Rgb => "a98-rgb",
-            PredefinedColorSpace::ProphotoRgb => "prophoto-rgb",
-            PredefinedColorSpace::Rec2020 => "rec2020",
-            PredefinedColorSpace::XyzD50 => "xyz-d50",
-            PredefinedColorSpace::XyzD65 => "xyz-d65",
-        }
-    }
-}
-
-impl FromStr for PredefinedColorSpace {
-    type Err = ();
+    /// Parse a PredefinedColorSpace from the given input.
+    pub fn parse<'i>(input: &mut Parser<'i, '_>) -> Result<Self, BasicParseError<'i>> {
+        let location = input.current_source_location();
 
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        Ok(match_ignore_ascii_case! { s,
-            "srgb" => PredefinedColorSpace::Srgb,
-            "srgb-linear" => PredefinedColorSpace::SrgbLinear,
-            "display-p3" => PredefinedColorSpace::DisplayP3,
-            "a98-rgb" => PredefinedColorSpace::A98Rgb,
-            "prophoto-rgb" => PredefinedColorSpace::ProphotoRgb,
-            "rec2020" => PredefinedColorSpace::Rec2020,
-            "xyz-d50" => PredefinedColorSpace::XyzD50,
-            "xyz" | "xyz-d65" => PredefinedColorSpace::XyzD65,
-
-            _ => return Err(()),
+        let ident = input.expect_ident()?;
+        Ok(match_ignore_ascii_case! { ident,
+            "srgb" => Self::Srgb,
+            "srgb-linear" => Self::SrgbLinear,
+            "display-p3" => Self::DisplayP3,
+            "a98-rgb" => Self::A98Rgb,
+            "prophoto-rgb" => Self::ProphotoRgb,
+            "rec2020" => Self::Rec2020,
+            "xyz-d50" => Self::XyzD50,
+            "xyz" | "xyz-d65" => Self::XyzD65,
+            _ => return Err(location.new_basic_unexpected_token_error(Token::Ident(ident.clone()))),
         })
     }
 }
@@ -138,7 +122,16 @@ impl ToCss for PredefinedColorSpace {
     where
         W: fmt::Write,
     {
-        dest.write_str(self.as_str())
+        dest.write_str(match self {
+            Self::Srgb => "srgb",
+            Self::SrgbLinear => "srgb-linear",
+            Self::DisplayP3 => "display-p3",
+            Self::A98Rgb => "a98-rgb",
+            Self::ProphotoRgb => "prophoto-rgb",
+            Self::Rec2020 => "rec2020",
+            Self::XyzD50 => "xyz-d50",
+            Self::XyzD65 => "xyz-d65",
+        })
     }
 }
 

From b75ce6a8df2dbd712fac9d49ba38ee09b96d0d52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Wed, 17 Apr 2024 22:46:32 +0200
Subject: [PATCH 29/38] parser: Implement recent syntax spec change to avoid
 parsing custom properties that look like selectors.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This implements the:

> If the first two non-<whitespace-token> values of rule’s prelude are
> an <ident-token> whose value starts with "--" followed by a
> <colon-token>, then...

From https://drafts.csswg.org/css-syntax/#consume-qualified-rule

Mozilla Bug: 1884879
Differential Revision: https://phabricator.services.mozilla.com/D207796
---
 src/parser.rs                 | 26 ++++++++++------
 src/rules_and_declarations.rs | 58 ++++++++++++++++++++++++++---------
 2 files changed, 60 insertions(+), 24 deletions(-)

diff --git a/src/parser.rs b/src/parser.rs
index e65cb013..dd35fc50 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -117,8 +117,14 @@ impl SourceLocation {
     /// Create a new BasicParseError at this location for an unexpected token
     #[inline]
     pub fn new_basic_unexpected_token_error(self, token: Token<'_>) -> BasicParseError<'_> {
+        self.new_basic_error(BasicParseErrorKind::UnexpectedToken(token))
+    }
+
+    /// Create a new BasicParseError at this location
+    #[inline]
+    pub fn new_basic_error(self, kind: BasicParseErrorKind<'_>) -> BasicParseError<'_> {
         BasicParseError {
-            kind: BasicParseErrorKind::UnexpectedToken(token),
+            kind,
             location: self,
         }
     }
@@ -126,8 +132,14 @@ impl SourceLocation {
     /// Create a new ParseError at this location for an unexpected token
     #[inline]
     pub fn new_unexpected_token_error<E>(self, token: Token<'_>) -> ParseError<'_, E> {
+        self.new_error(BasicParseErrorKind::UnexpectedToken(token))
+    }
+
+    /// Create a new basic ParseError at the current location
+    #[inline]
+    pub fn new_error<E>(self, kind: BasicParseErrorKind<'_>) -> ParseError<'_, E> {
         ParseError {
-            kind: ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken(token)),
+            kind: ParseErrorKind::Basic(kind),
             location: self,
         }
     }
@@ -450,19 +462,13 @@ impl<'i: 't, 't> Parser<'i, 't> {
     /// Create a new BasicParseError at the current location
     #[inline]
     pub fn new_basic_error(&self, kind: BasicParseErrorKind<'i>) -> BasicParseError<'i> {
-        BasicParseError {
-            kind,
-            location: self.current_source_location(),
-        }
+        self.current_source_location().new_basic_error(kind)
     }
 
     /// Create a new basic ParseError at the current location
     #[inline]
     pub fn new_error<E>(&self, kind: BasicParseErrorKind<'i>) -> ParseError<'i, E> {
-        ParseError {
-            kind: ParseErrorKind::Basic(kind),
-            location: self.current_source_location(),
-        }
+        self.current_source_location().new_error(kind)
     }
 
     /// Create a new custom BasicParseError at the current location
diff --git a/src/rules_and_declarations.rs b/src/rules_and_declarations.rs
index 9240f6de..48da02b5 100644
--- a/src/rules_and_declarations.rs
+++ b/src/rules_and_declarations.rs
@@ -4,9 +4,7 @@
 
 // https://drafts.csswg.org/css-syntax/#parsing
 
-use super::{
-    BasicParseError, BasicParseErrorKind, Delimiter, Delimiters, ParseError, Parser, Token,
-};
+use super::{BasicParseError, BasicParseErrorKind, Delimiter, ParseError, Parser, Token};
 use crate::cow_rc_str::CowRcStr;
 use crate::parser::{parse_nested_block, parse_until_after, ParseUntilErrorBehavior, ParserState};
 
@@ -293,7 +291,7 @@ where
                             &start,
                             self.input,
                             &mut *self.parser,
-                            Delimiter::Semicolon | Delimiter::CurlyBracketBlock,
+                            /* nested = */ true,
                         ) {
                             return Some(Ok(qual));
                         }
@@ -304,12 +302,8 @@ where
                 token => {
                     let result = if self.parser.parse_qualified() {
                         self.input.reset(&start);
-                        let delimiters = if self.parser.parse_declarations() {
-                            Delimiter::Semicolon | Delimiter::CurlyBracketBlock
-                        } else {
-                            Delimiter::CurlyBracketBlock
-                        };
-                        parse_qualified_rule(&start, self.input, &mut *self.parser, delimiters)
+                        let nested = self.parser.parse_declarations();
+                        parse_qualified_rule(&start, self.input, &mut *self.parser, nested)
                     } else {
                         let token = token.clone();
                         self.input.parse_until_after(Delimiter::Semicolon, |_| {
@@ -398,7 +392,7 @@ where
                     &start,
                     self.input,
                     &mut *self.parser,
-                    Delimiter::CurlyBracketBlock,
+                    /* nested = */ false,
                 );
                 return Some(result.map_err(|e| (e, self.input.slice_from(start.position()))));
             }
@@ -451,7 +445,7 @@ where
         if let Some(name) = at_keyword {
             parse_at_rule(&start, name, input, parser).map_err(|e| e.0)
         } else {
-            parse_qualified_rule(&start, input, parser, Delimiter::CurlyBracketBlock)
+            parse_qualified_rule(&start, input, parser, /* nested = */ false)
         }
     })
 }
@@ -491,16 +485,52 @@ where
     }
 }
 
+//  If the first two non-<whitespace-token> values of rule’s prelude are an <ident-token> whose
+//  value starts with "--" followed by a <colon-token>, then...
+fn looks_like_a_custom_property(input: &mut Parser) -> bool {
+    let ident = match input.expect_ident() {
+        Ok(i) => i,
+        Err(..) => return false,
+    };
+    ident.starts_with("--") && input.expect_colon().is_ok()
+}
+
+// https://drafts.csswg.org/css-syntax/#consume-a-qualified-rule
 fn parse_qualified_rule<'i, 't, P, E>(
     start: &ParserState,
     input: &mut Parser<'i, 't>,
     parser: &mut P,
-    delimiters: Delimiters,
+    nested: bool,
 ) -> Result<<P as QualifiedRuleParser<'i>>::QualifiedRule, ParseError<'i, E>>
 where
     P: QualifiedRuleParser<'i, Error = E>,
 {
-    let prelude = input.parse_until_before(delimiters, |input| parser.parse_prelude(input));
+    input.skip_whitespace();
+    let prelude = {
+        let state = input.state();
+        if looks_like_a_custom_property(input) {
+            // If nested is true, consume the remnants of a bad declaration from input, with
+            // nested set to true, and return nothing.
+            // If nested is false, consume a block from input, and return nothing.
+            let delimiters = if nested {
+                Delimiter::Semicolon
+            } else {
+                Delimiter::CurlyBracketBlock
+            };
+            let _: Result<(), ParseError<()>> = input.parse_until_after(delimiters, |_| Ok(()));
+            return Err(state
+                .source_location()
+                .new_error(BasicParseErrorKind::QualifiedRuleInvalid));
+        }
+        let delimiters = if nested {
+            Delimiter::Semicolon | Delimiter::CurlyBracketBlock
+        } else {
+            Delimiter::CurlyBracketBlock
+        };
+        input.reset(&state);
+        input.parse_until_before(delimiters, |input| parser.parse_prelude(input))
+    };
+
     input.expect_curly_bracket_block()?;
     // Do this here so that we consume the `{` even if the prelude is `Err`.
     let prelude = prelude?;

From 4765111c002e247c9c9e2cccefd239ddd5c46b38 Mon Sep 17 00:00:00 2001
From: Jonathan Kew <jfkthame@gmail.com>
Date: Wed, 5 Jun 2024 23:56:56 +0100
Subject: [PATCH 30/38] [unicode-range] Avoid integer overflow (panic in debug
 builds)

If a long string of hex digits are passed to unicode-range, the code tries to
parse them into a number before checking whether there are more than the 6 digits
allowed by the syntax, and this may lead to integer overflow.

To avoid this, check the number of digits and error out earlier if there are
too many to possibly be valid.

(See https://bugzilla.mozilla.org/show_bug.cgi?id=1900403)
---
 src/css-parsing-tests/urange.json |  5 +++++
 src/unicode_range.rs              | 14 +++++++++-----
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/css-parsing-tests/urange.json b/src/css-parsing-tests/urange.json
index 857d1d62..4dcb529c 100644
--- a/src/css-parsing-tests/urange.json
+++ b/src/css-parsing-tests/urange.json
@@ -84,6 +84,11 @@
     null,
     null,
     null
+],
+
+"U+26F9200D2640, U+10000-26F9200D2640", [
+    null,
+    null
 ]
 
 ]
diff --git a/src/unicode_range.rs b/src/unicode_range.rs
index ce6bb3b5..a4130ef0 100644
--- a/src/unicode_range.rs
+++ b/src/unicode_range.rs
@@ -104,7 +104,7 @@ fn parse_concatenated(text: &[u8]) -> Result<UnicodeRange, ()> {
         Some((&b'+', text)) => text,
         _ => return Err(()),
     };
-    let (first_hex_value, hex_digit_count) = consume_hex(&mut text);
+    let (first_hex_value, hex_digit_count) = consume_hex(&mut text, 6)?;
     let question_marks = consume_question_marks(&mut text);
     let consumed = hex_digit_count + question_marks;
     if consumed == 0 || consumed > 6 {
@@ -124,7 +124,7 @@ fn parse_concatenated(text: &[u8]) -> Result<UnicodeRange, ()> {
             end: first_hex_value,
         });
     } else if let Some((&b'-', mut text)) = text.split_first() {
-        let (second_hex_value, hex_digit_count) = consume_hex(&mut text);
+        let (second_hex_value, hex_digit_count) = consume_hex(&mut text, 6)?;
         if hex_digit_count > 0 && hex_digit_count <= 6 && text.is_empty() {
             return Ok(UnicodeRange {
                 start: first_hex_value,
@@ -135,19 +135,23 @@ fn parse_concatenated(text: &[u8]) -> Result<UnicodeRange, ()> {
     Err(())
 }
 
-fn consume_hex(text: &mut &[u8]) -> (u32, usize) {
+// Consume hex digits, but return an error if more than digit_limit are found.
+fn consume_hex(text: &mut &[u8], digit_limit: usize) -> Result<(u32, usize), ()> {
     let mut value = 0;
     let mut digits = 0;
     while let Some((&byte, rest)) = text.split_first() {
         if let Some(digit_value) = (byte as char).to_digit(16) {
+            if digits == digit_limit {
+                return Err(());
+            }
             value = value * 0x10 + digit_value;
             digits += 1;
-            *text = rest
+            *text = rest;
         } else {
             break;
         }
     }
-    (value, digits)
+    Ok((value, digits))
 }
 
 fn consume_question_marks(text: &mut &[u8]) -> usize {

From bb071313db0d23a1cea87d1589e42e4ff388e51a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Thu, 7 Nov 2024 18:25:09 +0100
Subject: [PATCH 31/38] Fix clippy lints.

---
 src/cow_rc_str.rs             | 28 ++++++++++++++--------------
 src/parser.rs                 |  8 ++++----
 src/rules_and_declarations.rs |  4 ++--
 src/serializer.rs             |  6 +++---
 src/tests.rs                  |  4 ++--
 src/tokenizer.rs              | 14 +++++---------
 6 files changed, 30 insertions(+), 34 deletions(-)

diff --git a/src/cow_rc_str.rs b/src/cow_rc_str.rs
index 26508481..03631f47 100644
--- a/src/cow_rc_str.rs
+++ b/src/cow_rc_str.rs
@@ -51,7 +51,7 @@ impl<'a> From<&'a str> for CowRcStr<'a> {
     }
 }
 
-impl<'a> From<String> for CowRcStr<'a> {
+impl From<String> for CowRcStr<'_> {
     #[inline]
     fn from(s: String) -> Self {
         CowRcStr::from_rc(Rc::new(s))
@@ -84,7 +84,7 @@ impl<'a> CowRcStr<'a> {
     }
 }
 
-impl<'a> Clone for CowRcStr<'a> {
+impl Clone for CowRcStr<'_> {
     #[inline]
     fn clone(&self) -> Self {
         match self.unpack() {
@@ -99,7 +99,7 @@ impl<'a> Clone for CowRcStr<'a> {
     }
 }
 
-impl<'a> Drop for CowRcStr<'a> {
+impl Drop for CowRcStr<'_> {
     #[inline]
     fn drop(&mut self) {
         if let Err(ptr) = self.unpack() {
@@ -108,7 +108,7 @@ impl<'a> Drop for CowRcStr<'a> {
     }
 }
 
-impl<'a> ops::Deref for CowRcStr<'a> {
+impl ops::Deref for CowRcStr<'_> {
     type Target = str;
 
     #[inline]
@@ -119,65 +119,65 @@ impl<'a> ops::Deref for CowRcStr<'a> {
 
 // Boilerplate / trivial impls below.
 
-impl<'a> AsRef<str> for CowRcStr<'a> {
+impl AsRef<str> for CowRcStr<'_> {
     #[inline]
     fn as_ref(&self) -> &str {
         self
     }
 }
 
-impl<'a> Borrow<str> for CowRcStr<'a> {
+impl Borrow<str> for CowRcStr<'_> {
     #[inline]
     fn borrow(&self) -> &str {
         self
     }
 }
 
-impl<'a> Default for CowRcStr<'a> {
+impl Default for CowRcStr<'_> {
     #[inline]
     fn default() -> Self {
         Self::from("")
     }
 }
 
-impl<'a> hash::Hash for CowRcStr<'a> {
+impl hash::Hash for CowRcStr<'_> {
     #[inline]
     fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
         str::hash(self, hasher)
     }
 }
 
-impl<'a, T: AsRef<str>> PartialEq<T> for CowRcStr<'a> {
+impl<T: AsRef<str>> PartialEq<T> for CowRcStr<'_> {
     #[inline]
     fn eq(&self, other: &T) -> bool {
         str::eq(self, other.as_ref())
     }
 }
 
-impl<'a, T: AsRef<str>> PartialOrd<T> for CowRcStr<'a> {
+impl<T: AsRef<str>> PartialOrd<T> for CowRcStr<'_> {
     #[inline]
     fn partial_cmp(&self, other: &T) -> Option<cmp::Ordering> {
         str::partial_cmp(self, other.as_ref())
     }
 }
 
-impl<'a> Eq for CowRcStr<'a> {}
+impl Eq for CowRcStr<'_> {}
 
-impl<'a> Ord for CowRcStr<'a> {
+impl Ord for CowRcStr<'_> {
     #[inline]
     fn cmp(&self, other: &Self) -> cmp::Ordering {
         str::cmp(self, other)
     }
 }
 
-impl<'a> fmt::Display for CowRcStr<'a> {
+impl fmt::Display for CowRcStr<'_> {
     #[inline]
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         str::fmt(self, formatter)
     }
 }
 
-impl<'a> fmt::Debug for CowRcStr<'a> {
+impl fmt::Debug for CowRcStr<'_> {
     #[inline]
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         str::fmt(self, formatter)
diff --git a/src/parser.rs b/src/parser.rs
index dd35fc50..0a432912 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -76,7 +76,7 @@ pub enum BasicParseErrorKind<'i> {
     QualifiedRuleInvalid,
 }
 
-impl<'i> fmt::Display for BasicParseErrorKind<'i> {
+impl fmt::Display for BasicParseErrorKind<'_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
             BasicParseErrorKind::UnexpectedToken(token) => {
@@ -176,7 +176,7 @@ impl<'i, T> ParseErrorKind<'i, T> {
     }
 }
 
-impl<'i, E: fmt::Display> fmt::Display for ParseErrorKind<'i, E> {
+impl<E: fmt::Display> fmt::Display for ParseErrorKind<'_, E> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
             ParseErrorKind::Basic(ref basic) => basic.fmt(f),
@@ -218,13 +218,13 @@ impl<'i, T> ParseError<'i, T> {
     }
 }
 
-impl<'i, E: fmt::Display> fmt::Display for ParseError<'i, E> {
+impl<E: fmt::Display> fmt::Display for ParseError<'_, E> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.kind.fmt(f)
     }
 }
 
-impl<'i, E: fmt::Display + fmt::Debug> std::error::Error for ParseError<'i, E> {}
+impl<E: fmt::Display + fmt::Debug> std::error::Error for ParseError<'_, E> {}
 
 /// The owned input for a parser.
 pub struct ParserInput<'i> {
diff --git a/src/rules_and_declarations.rs b/src/rules_and_declarations.rs
index 48da02b5..188e354e 100644
--- a/src/rules_and_declarations.rs
+++ b/src/rules_and_declarations.rs
@@ -241,7 +241,7 @@ impl<'i, 't, 'a, P, I, E> RuleBodyParser<'i, 't, 'a, P, I, E> {
 }
 
 /// https://drafts.csswg.org/css-syntax/#consume-a-blocks-contents
-impl<'i, 't, 'a, I, P, E: 'i> Iterator for RuleBodyParser<'i, 't, 'a, P, I, E>
+impl<'i, I, P, E: 'i> Iterator for RuleBodyParser<'i, '_, '_, P, I, E>
 where
     P: RuleBodyItemParser<'i, I, E>,
 {
@@ -349,7 +349,7 @@ where
 }
 
 /// `RuleListParser` is an iterator that yields `Ok(_)` for a rule or an `Err(..)` for an invalid one.
-impl<'i, 't, 'a, R, P, E: 'i> Iterator for StyleSheetParser<'i, 't, 'a, P>
+impl<'i, R, P, E: 'i> Iterator for StyleSheetParser<'i, '_, '_, P>
 where
     P: QualifiedRuleParser<'i, QualifiedRule = R, Error = E>
         + AtRuleParser<'i, AtRule = R, Error = E>,
diff --git a/src/serializer.rs b/src/serializer.rs
index 3c6e31cb..5df73954 100644
--- a/src/serializer.rs
+++ b/src/serializer.rs
@@ -55,7 +55,7 @@ where
     Ok(())
 }
 
-impl<'a> ToCss for Token<'a> {
+impl ToCss for Token<'_> {
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
     where
         W: fmt::Write,
@@ -311,7 +311,7 @@ where
     }
 }
 
-impl<'a, W> fmt::Write for CssStringWriter<'a, W>
+impl<W> fmt::Write for CssStringWriter<'_, W>
 where
     W: fmt::Write,
 {
@@ -539,7 +539,7 @@ impl TokenSerializationType {
     }
 }
 
-impl<'a> Token<'a> {
+impl Token<'_> {
     /// Categorize a token into a type that determines when `/**/` needs to be inserted
     /// between two tokens when serialized next to each other without whitespace in between.
     ///
diff --git a/src/tests.rs b/src/tests.rs
index 7389664d..ec0fc517 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -773,7 +773,7 @@ where
     }
 }
 
-impl<'a> ToJson for CowRcStr<'a> {
+impl ToJson for CowRcStr<'_> {
     fn to_json(&self) -> Value {
         let s: &str = self;
         s.to_json()
@@ -946,7 +946,7 @@ impl<'i> QualifiedRuleParser<'i> for JsonParser {
     }
 }
 
-impl<'i> RuleBodyItemParser<'i, Value, ()> for JsonParser {
+impl RuleBodyItemParser<'_, Value, ()> for JsonParser {
     fn parse_qualified(&self) -> bool {
         true
     }
diff --git a/src/tokenizer.rs b/src/tokenizer.rs
index ea173a5e..2e86c66a 100644
--- a/src/tokenizer.rs
+++ b/src/tokenizer.rs
@@ -190,7 +190,7 @@ pub enum Token<'a> {
     CloseCurlyBracket,
 }
 
-impl<'a> Token<'a> {
+impl Token<'_> {
     /// Return whether this token represents a parse error.
     ///
     /// `BadUrl` and `BadString` are tokenizer-level parse errors.
@@ -324,11 +324,11 @@ impl<'a> Tokenizer<'a> {
         let current = self.position();
         let start = self
             .slice(SourcePosition(0)..current)
-            .rfind(|c| matches!(c, '\r' | '\n' | '\x0C'))
+            .rfind(['\r', '\n', '\x0C'])
             .map_or(0, |start| start + 1);
         let end = self
             .slice(current..SourcePosition(self.input.len()))
-            .find(|c| matches!(c, '\r' | '\n' | '\x0C'))
+            .find(['\r', '\n', '\x0C'])
             .map_or(self.input.len(), |end| current.0 + end);
         self.slice(SourcePosition(start)..SourcePosition(end))
     }
@@ -720,9 +720,7 @@ fn check_for_source_map<'a>(tokenizer: &mut Tokenizer<'a>, contents: &'a str) {
     // If there is a source map directive, extract the URL.
     if contents.starts_with(directive) || contents.starts_with(directive_old) {
         let contents = &contents[directive.len()..];
-        tokenizer.source_map_url = contents
-            .split(|c| c == ' ' || c == '\t' || c == '\x0C' || c == '\r' || c == '\n')
-            .next()
+        tokenizer.source_map_url = contents.split([' ', '\t', '\x0C', '\r', '\n']).next();
     }
 
     let directive = "# sourceURL=";
@@ -731,9 +729,7 @@ fn check_for_source_map<'a>(tokenizer: &mut Tokenizer<'a>, contents: &'a str) {
     // If there is a source map directive, extract the URL.
     if contents.starts_with(directive) || contents.starts_with(directive_old) {
         let contents = &contents[directive.len()..];
-        tokenizer.source_url = contents
-            .split(|c| c == ' ' || c == '\t' || c == '\x0C' || c == '\r' || c == '\n')
-            .next()
+        tokenizer.source_url = contents.split([' ', '\t', '\x0C', '\r', '\n']).next()
     }
 }
 

From 6fb149bc852a019b08958eac199720404c6b4932 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Thu, 7 Nov 2024 19:17:56 +0100
Subject: [PATCH 32/38] Bump cssparser_color version. (#395)

---
 color/Cargo.toml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/color/Cargo.toml b/color/Cargo.toml
index 47544815..d5cde913 100644
--- a/color/Cargo.toml
+++ b/color/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cssparser-color"
-version = "0.1.0"
+version = "0.2.0"
 authors = ["Emilio Cobos Álvarez <emilio@crisal.io>"]
 description = "Color implementation based on cssparser"
 documentation = "https://docs.rs/cssparser-color/"
@@ -12,7 +12,7 @@ edition = "2021"
 path = "lib.rs"
 
 [dependencies]
-cssparser = { path = ".." }
+cssparser = { path = "..", version = "0.34" }
 serde = { version = "1.0", features = ["derive"], optional = true }
 
 [features]

From fa6f5eb23f058c6fce444ac781b0b380003fdb59 Mon Sep 17 00:00:00 2001
From: AlaskanEmily <31194934+AlaskanEmily@users.noreply.github.com>
Date: Tue, 3 Dec 2024 14:07:38 -0800
Subject: [PATCH 33/38] Minor optimization of Delimiters::from_byte to avoid an
 extra branch. (#397)

Co-authored-by: AlaskanEmily <emcdonough@mozilla.com>
---
 src/parser.rs | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/parser.rs b/src/parser.rs
index 0a432912..aabeea6a 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -360,10 +360,8 @@ impl Delimiters {
             table
         };
 
-        match byte {
-            None => Delimiter::None,
-            Some(b) => TABLE[b as usize],
-        }
+        assert_eq!(TABLE[0], Delimiter::None);
+        TABLE[byte.unwrap_or(0) as usize]
     }
 }
 

From 008a91c3cea7da09baf092c9be8b77c4d385141a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= <emilio@crisal.io>
Date: Fri, 21 Feb 2025 11:30:43 +0100
Subject: [PATCH 34/38] Fix clippy lints (#401)

---
 src/from_bytes.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/from_bytes.rs b/src/from_bytes.rs
index 78a56d3e..7d9d2c76 100644
--- a/src/from_bytes.rs
+++ b/src/from_bytes.rs
@@ -24,9 +24,9 @@ pub trait EncodingSupport {
 ///
 /// * `css_bytes`: A byte string.
 /// * `protocol_encoding`: The encoding label, if any, defined by HTTP or equivalent protocol.
-///     (e.g. via the `charset` parameter of the `Content-Type` header.)
+///   (e.g. via the `charset` parameter of the `Content-Type` header.)
 /// * `environment_encoding`: An optional `Encoding` object for the [environment encoding]
-///     (https://drafts.csswg.org/css-syntax/#environment-encoding), if any.
+///   (https://drafts.csswg.org/css-syntax/#environment-encoding), if any.
 ///
 /// Returns the encoding to use.
 pub fn stylesheet_encoding<E>(

From 5e477ab8195f64ed9b22ab1cf7b08685347f3879 Mon Sep 17 00:00:00 2001
From: Nicolas Chevobbe <nchevobbe@users.noreply.github.com>
Date: Fri, 21 Feb 2025 11:30:02 +0100
Subject: [PATCH 35/38] Add declaration_start parameter to DeclarationParser
 parse_value (#400)

---
 src/rules_and_declarations.rs | 6 ++++--
 src/tests.rs                  | 1 +
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/rules_and_declarations.rs b/src/rules_and_declarations.rs
index 188e354e..bdaef077 100644
--- a/src/rules_and_declarations.rs
+++ b/src/rules_and_declarations.rs
@@ -49,6 +49,7 @@ pub trait DeclarationParser<'i> {
         &mut self,
         name: CowRcStr<'i>,
         input: &mut Parser<'i, 't>,
+        _declaration_start: &ParserState,
     ) -> Result<Self::Declaration, ParseError<'i, Self::Error>> {
         Err(input.new_error(BasicParseErrorKind::UnexpectedToken(Token::Ident(name))))
     }
@@ -279,7 +280,7 @@ where
                             error_behavior,
                             |input| {
                                 input.expect_colon()?;
-                                parser.parse_value(name, input)
+                                parser.parse_value(name, input, &start)
                             },
                         )
                     };
@@ -408,12 +409,13 @@ pub fn parse_one_declaration<'i, 't, P, E>(
 where
     P: DeclarationParser<'i, Error = E>,
 {
+    let start = input.state();
     let start_position = input.position();
     input
         .parse_entirely(|input| {
             let name = input.expect_ident()?.clone();
             input.expect_colon()?;
-            parser.parse_value(name, input)
+            parser.parse_value(name, input, &start)
         })
         .map_err(|e| (e, input.slice_from(start_position)))
 }
diff --git a/src/tests.rs b/src/tests.rs
index ec0fc517..3c122f0d 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -849,6 +849,7 @@ impl<'i> DeclarationParser<'i> for JsonParser {
         &mut self,
         name: CowRcStr<'i>,
         input: &mut Parser<'i, 't>,
+        _declaration_start: &ParserState,
     ) -> Result<Value, ParseError<'i, ()>> {
         let mut value = vec![];
         let mut important = false;

From 0d800216303aa6586b1469cb948859fb1dbd6a2f Mon Sep 17 00:00:00 2001
From: Nico Burns <nico@nicoburns.com>
Date: Fri, 21 Feb 2025 23:31:11 +1300
Subject: [PATCH 36/38] Implement `MallocSizeOf` for cssparser types (#399)

* Implement MallocSizeOf for cssparser types

* Fix clippy lints

Signed-off-by: Nico Burns <nico@nicoburns.com>

---------

Signed-off-by: Nico Burns <nico@nicoburns.com>
---
 .github/workflows/main.yml | 1 +
 Cargo.toml                 | 3 ++-
 src/serializer.rs          | 3 +++
 src/tokenizer.rs           | 6 ++++++
 4 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index b08ddef7..a7be6aec 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -22,6 +22,7 @@ jobs:
         features:
           -
           - --features dummy_match_byte
+          - --features malloc_size_of
         include:
           - toolchain: nightly
             features: --features bench
diff --git a/Cargo.toml b/Cargo.toml
index f783f19f..f4e980fd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cssparser"
-version = "0.34.0"
+version = "0.34.1"
 authors = ["Simon Sapin <simon.sapin@exyr.org>"]
 
 description = "Rust implementation of CSS Syntax Level 3"
@@ -25,6 +25,7 @@ dtoa-short = "0.3"
 itoa = "1.0"
 phf = { version = "0.11.2", features = ["macros"] }
 serde = { version = "1.0", features = ["derive"], optional = true }
+malloc_size_of = { version = "0.1", default-features = false, optional = true }
 smallvec = "1.0"
 
 [profile.profiling]
diff --git a/src/serializer.rs b/src/serializer.rs
index 5df73954..6696a622 100644
--- a/src/serializer.rs
+++ b/src/serializer.rs
@@ -466,6 +466,9 @@ pub enum TokenSerializationType {
     Other,
 }
 
+#[cfg(feature = "malloc_size_of")]
+malloc_size_of::malloc_size_of_is_0!(TokenSerializationType);
+
 impl TokenSerializationType {
     /// Return a value that represents the absence of a token, e.g. before the start of the input.
     #[deprecated(
diff --git a/src/tokenizer.rs b/src/tokenizer.rs
index 2e86c66a..892d10ae 100644
--- a/src/tokenizer.rs
+++ b/src/tokenizer.rs
@@ -533,6 +533,9 @@ impl<'a> Tokenizer<'a> {
 #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
 pub struct SourcePosition(pub(crate) usize);
 
+#[cfg(feature = "malloc_size_of")]
+malloc_size_of::malloc_size_of_is_0!(SourcePosition);
+
 impl SourcePosition {
     /// Returns the current byte index in the original input.
     #[inline]
@@ -552,6 +555,9 @@ pub struct SourceLocation {
     pub column: u32,
 }
 
+#[cfg(feature = "malloc_size_of")]
+malloc_size_of::malloc_size_of_is_0!(SourceLocation);
+
 fn next_token<'a>(tokenizer: &mut Tokenizer<'a>) -> Result<Token<'a>, ()> {
     if tokenizer.is_eof() {
         return Err(());

From 958a3f098acb92ddacdce18a7ef2c4a87ac3326f Mon Sep 17 00:00:00 2001
From: Nicolas Chevobbe <nchevobbe@users.noreply.github.com>
Date: Fri, 21 Feb 2025 14:28:55 +0100
Subject: [PATCH 37/38] Derive Default for SourceLocation (#402)

---
 src/tokenizer.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tokenizer.rs b/src/tokenizer.rs
index 892d10ae..1c85e10a 100644
--- a/src/tokenizer.rs
+++ b/src/tokenizer.rs
@@ -545,7 +545,7 @@ impl SourcePosition {
 }
 
 /// The line and column number for a given position within the input.
-#[derive(PartialEq, Eq, Debug, Clone, Copy)]
+#[derive(PartialEq, Eq, Debug, Clone, Copy, Default)]
 pub struct SourceLocation {
     /// The line number, starting at 0 for the first line.
     pub line: u32,

From 3dd4f63639925438d9932dafc0d81395847f9be4 Mon Sep 17 00:00:00 2001
From: Nico Burns <nico@nicoburns.com>
Date: Fri, 21 Mar 2025 07:11:19 +1300
Subject: [PATCH 38/38] Bump version 0.35.0 (#404)

Signed-off-by: Nico Burns <nico@nicoburns.com>
---
 Cargo.toml       | 2 +-
 color/Cargo.toml | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index f4e980fd..6604f20e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cssparser"
-version = "0.34.1"
+version = "0.35.0"
 authors = ["Simon Sapin <simon.sapin@exyr.org>"]
 
 description = "Rust implementation of CSS Syntax Level 3"
diff --git a/color/Cargo.toml b/color/Cargo.toml
index d5cde913..5dd6aac7 100644
--- a/color/Cargo.toml
+++ b/color/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "cssparser-color"
-version = "0.2.0"
+version = "0.3.0"
 authors = ["Emilio Cobos Álvarez <emilio@crisal.io>"]
 description = "Color implementation based on cssparser"
 documentation = "https://docs.rs/cssparser-color/"
@@ -12,7 +12,7 @@ edition = "2021"
 path = "lib.rs"
 
 [dependencies]
-cssparser = { path = "..", version = "0.34" }
+cssparser = { path = "..", version = "0.35" }
 serde = { version = "1.0", features = ["derive"], optional = true }
 
 [features]
