Repository: stylelint-scss/stylelint-scss
Pull request #1022 (2024-07-10 13:58:35)

selector-no-redundant-nesting-selector: Add support for Dart Sass deprecation
Related to #1020

Mister-Hope: LGTM, but see https://github.com/sass/dart-sass/issues/2276#issue-2399880250

As we can revert this change back once the new behavior is activated, so this change might better be opt-in with a new rule option.
kristerkari: > LGTM, but see [sass/dart-sass#2276 (comment)](https://github.com/sass/dart-sass/issues/2276#issue-2399880250)

Thanks, I'll need to read through the comments to understand what's going on 😄 
kristerkari: > As we can revert this change back once the new behavior is activated, so this change might better be opt-in with a new rule option.

Yeah, I can also put it behind a rule option for opt-in.

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c6e71b2..3fe2ed6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,30 @@
+# 6.7.0
+
+- Added: `function-no-unknown`: add support for Sass v1.78 `color.channel` function (#1052).
+
+**Full Changelog**: https://github.com/stylelint-scss/stylelint-scss/compare/v6.6.0...v6.7.0
+
+# 6.6.0
+
+- Added: `declaration-property-value-no-unknown`: add support for first-class operators (#1042).
+- Added: `declaration-property-value-no-unknown`: add support SCSS variables as arguments in nested functions (#1042).
+
+**Full Changelog**: https://github.com/stylelint-scss/stylelint-scss/compare/v6.5.1...v6.6.0
+
+# 6.5.1
+
+- Fixed: `function-quote-no-quoted-strings-inside` fix broken autofix (#1043).
+
+**Full Changelog**: https://github.com/stylelint-scss/stylelint-scss/compare/v6.5.0...v6.5.1
+
+# 6.5.0
+
+- Added: `property-no-unknown` add support for nested declarations (#1024).
+- Added: `declaration-property-value-no-unknown` rule (#1023).
+- Fixed: `operator-no-unspaced` fix false positives with comparison operators (#1037).
+
+**Full Changelog**: https://github.com/stylelint-scss/stylelint-scss/compare/v6.4.1...v6.5.0
+
 # 6.4.1
 
 - Fixed: false positive for mixins in `load-partial-extension` (#1021).
diff --git a/README.md b/README.md
index 49921b8..dba79fb 100644
--- a/README.md
+++ b/README.md
@@ -137,6 +137,7 @@ Please also see the [example configs](./docs/examples/) for special cases.
 
 - [`declaration-nested-properties`](./src/rules/declaration-nested-properties/README.md): Require or disallow properties with `-` in their names to be in a form of a nested group.
 - [`declaration-nested-properties-no-divided-groups`](./src/rules/declaration-nested-properties-no-divided-groups/README.md): Disallow nested properties of the same "namespace" to be divided into multiple groups.
+- [`declaration-property-value-no-unknown`](./src/rules/declaration-property-value-no-unknown/README.md): Disallow unknown values for properties within declarations.
 
 ### Dimension
 
@@ -230,7 +231,7 @@ Thanks goes to these wonderful people:
 <th align="center"><a href="https://github.com/rambleraptor"><img alt="rambleraptor" src="https://avatars.githubusercontent.com/u/1325798?v=4&s=80" width="80"></a></th>
 <th align="center"><a href="https://github.com/XhmikosR"><img alt="XhmikosR" src="https://avatars.githubusercontent.com/u/349621?v=4&s=80" width="80"></a></th>
 <th align="center"><a href="https://github.com/ybiquitous"><img alt="ybiquitous" src="https://avatars.githubusercontent.com/u/473530?v=4&s=80" width="80"></a></th>
-<th align="center"><a href="https://github.com/Eugeno"><img alt="Eugeno" src="https://avatars.githubusercontent.com/u/23382920?v=4&s=80" width="80"></a></th>
+<th align="center"><a href="https://github.com/pamelalozano16"><img alt="pamelalozano16" src="https://avatars.githubusercontent.com/u/30474787?v=4&s=80" width="80"></a></th>
 </tr>
 </thead>
 <tbody><tr>
@@ -239,13 +240,13 @@ Thanks goes to these wonderful people:
 <td align="center"><a href="https://github.com/rambleraptor">rambleraptor</a></td>
 <td align="center"><a href="https://github.com/XhmikosR">XhmikosR</a></td>
 <td align="center"><a href="https://github.com/ybiquitous">ybiquitous</a></td>
-<td align="center"><a href="https://github.com/Eugeno">Eugeno</a></td>
+<td align="center"><a href="https://github.com/pamelalozano16">pamelalozano16</a></td>
 </tr>
 </tbody></table>
 <table>
 <thead>
 <tr>
-<th align="center"><a href="https://github.com/pamelalozano16"><img alt="pamelalozano16" src="https://avatars.githubusercontent.com/u/30474787?v=4&s=80" width="80"></a></th>
+<th align="center"><a href="https://github.com/Eugeno"><img alt="Eugeno" src="https://avatars.githubusercontent.com/u/23382920?v=4&s=80" width="80"></a></th>
 <th align="center"><a href="https://github.com/joseph118"><img alt="joseph118" src="https://avatars.githubusercontent.com/u/6863655?v=4&s=80" width="80"></a></th>
 <th align="center"><a href="https://github.com/stof"><img alt="stof" src="https://avatars.githubusercontent.com/u/439401?v=4&s=80" width="80"></a></th>
 <th align="center"><a href="https://github.com/niksy"><img alt="niksy" src="https://avatars.githubusercontent.com/u/389286?v=4&s=80" width="80"></a></th>
@@ -254,7 +255,7 @@ Thanks goes to these wonderful people:
 </tr>
 </thead>
 <tbody><tr>
-<td align="center"><a href="https://github.com/pamelalozano16">pamelalozano16</a></td>
+<td align="center"><a href="https://github.com/Eugeno">Eugeno</a></td>
 <td align="center"><a href="https://github.com/joseph118">joseph118</a></td>
 <td align="center"><a href="https://github.com/stof">stof</a></td>
 <td align="center"><a href="https://github.com/niksy">niksy</a></td>
@@ -266,27 +267,27 @@ Thanks goes to these wonderful people:
 <thead>
 <tr>
 <th align="center"><a href="https://github.com/pipopotamasu"><img alt="pipopotamasu" src="https://avatars.githubusercontent.com/u/14048211?v=4&s=80" width="80"></a></th>
+<th align="center"><a href="https://github.com/FloEdelmann"><img alt="FloEdelmann" src="https://avatars.githubusercontent.com/u/202916?v=4&s=80" width="80"></a></th>
 <th align="center"><a href="https://github.com/jhae-de"><img alt="jhae-de" src="https://avatars.githubusercontent.com/u/28291021?v=4&s=80" width="80"></a></th>
 <th align="center"><a href="https://github.com/OriR"><img alt="OriR" src="https://avatars.githubusercontent.com/u/2384068?v=4&s=80" width="80"></a></th>
 <th align="center"><a href="https://github.com/ntwb"><img alt="ntwb" src="https://avatars.githubusercontent.com/u/1016458?v=4&s=80" width="80"></a></th>
 <th align="center"><a href="https://github.com/ricardogobbosouza"><img alt="ricardogobbosouza" src="https://avatars.githubusercontent.com/u/13064722?v=4&s=80" width="80"></a></th>
-<th align="center"><a href="https://github.com/jeddy3"><img alt="jeddy3" src="https://avatars.githubusercontent.com/u/808227?v=4&s=80" width="80"></a></th>
 </tr>
 </thead>
 <tbody><tr>
 <td align="center"><a href="https://github.com/pipopotamasu">pipopotamasu</a></td>
+<td align="center"><a href="https://github.com/FloEdelmann">FloEdelmann</a></td>
 <td align="center"><a href="https://github.com/jhae-de">jhae-de</a></td>
 <td align="center"><a href="https://github.com/OriR">OriR</a></td>
 <td align="center"><a href="https://github.com/ntwb">ntwb</a></td>
 <td align="center"><a href="https://github.com/ricardogobbosouza">ricardogobbosouza</a></td>
-<td align="center"><a href="https://github.com/jeddy3">jeddy3</a></td>
 </tr>
 </tbody></table>
 <table>
 <thead>
 <tr>
+<th align="center"><a href="https://github.com/jeddy3"><img alt="jeddy3" src="https://avatars.githubusercontent.com/u/808227?v=4&s=80" width="80"></a></th>
 <th align="center"><a href="https://github.com/evilebottnawi"><img alt="evilebottnawi" src="https://avatars.githubusercontent.com/u/23334705?v=4&s=80" width="80"></a></th>
-<th align="center"><a href="https://github.com/FloEdelmann"><img alt="FloEdelmann" src="https://avatars.githubusercontent.com/u/202916?v=4&s=80" width="80"></a></th>
 <th align="center"><a href="https://github.com/kevindew"><img alt="kevindew" src="https://avatars.githubusercontent.com/u/282717?v=4&s=80" width="80"></a></th>
 <th align="center"><a href="https://github.com/thibaudcolas"><img alt="thibaudcolas" src="https://avatars.githubusercontent.com/u/877585?v=4&s=80" width="80"></a></th>
 <th align="center"><a href="https://github.com/chimurai"><img alt="chimurai" src="https://avatars.githubusercontent.com/u/655241?v=4&s=80" width="80"></a></th>
@@ -294,8 +295,8 @@ Thanks goes to these wonderful people:
 </tr>
 </thead>
 <tbody><tr>
+<td align="center"><a href="https://github.com/jeddy3">jeddy3</a></td>
 <td align="center"><a href="https://github.com/evilebottnawi">evilebottnawi</a></td>
-<td align="center"><a href="https://github.com/FloEdelmann">FloEdelmann</a></td>
 <td align="center"><a href="https://github.com/kevindew">kevindew</a></td>
 <td align="center"><a href="https://github.com/thibaudcolas">thibaudcolas</a></td>
 <td align="center"><a href="https://github.com/chimurai">chimurai</a></td>
diff --git a/package-lock.json b/package-lock.json
index 8ac487b..7c388e9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,34 +1,37 @@
 {
   "name": "stylelint-scss",
-  "version": "6.4.1",
+  "version": "6.7.0",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "stylelint-scss",
-      "version": "6.4.1",
+      "version": "6.7.0",
       "license": "MIT",
       "dependencies": {
+        "css-tree": "^3.0.0",
+        "is-plain-object": "^5.0.0",
         "known-css-properties": "^0.34.0",
         "postcss-media-query-parser": "^0.2.3",
-        "postcss-resolve-nested-selector": "^0.1.1",
-        "postcss-selector-parser": "^6.1.0",
+        "postcss-resolve-nested-selector": "^0.1.6",
+        "postcss-selector-parser": "^6.1.2",
         "postcss-value-parser": "^4.2.0"
       },
       "devDependencies": {
+        "common-tags": "^1.8.2",
         "cross-env": "^7.0.3",
         "eslint": "^8.57.0",
         "github-contributors-list": "^1.2.5",
-        "husky": "^9.0.11",
+        "husky": "^9.1.6",
         "jest": "^29.7.0",
         "jest-preset-stylelint": "^7.1.0",
         "lint-staged": "^14.0.1",
-        "np": "^10.0.6",
-        "postcss": "^8.4.39",
+        "np": "^10.0.7",
+        "postcss": "^8.4.47",
         "postcss-less": "^6.0.0",
         "postcss-scss": "^4.0.9",
-        "prettier": "^3.3.2",
-        "stylelint": "^16.6.1"
+        "prettier": "^3.3.3",
+        "stylelint": "^16.10.0"
       },
       "engines": {
         "node": ">=18.12.0"
@@ -691,9 +694,9 @@
       "dev": true
     },
     "node_modules/@csstools/css-parser-algorithms": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.6.3.tgz",
-      "integrity": "sha512-xI/tL2zxzEbESvnSxwFgwvy5HS00oCXxL4MLs6HUiDcYfwowsoQaABKxUElp1ARITrINzBnsECOc1q0eg2GOrA==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.1.tgz",
+      "integrity": "sha512-lSquqZCHxDfuTg/Sk2hiS0mcSFCEBuj49JfzPHJogDBT0mGCyY5A1AQzBWngitrp7i1/HAZpIgzF/VjhOEIJIg==",
       "dev": true,
       "funding": [
         {
@@ -706,16 +709,16 @@
         }
       ],
       "engines": {
-        "node": "^14 || ^16 || >=18"
+        "node": ">=18"
       },
       "peerDependencies": {
-        "@csstools/css-tokenizer": "^2.3.1"
+        "@csstools/css-tokenizer": "^3.0.1"
       }
     },
     "node_modules/@csstools/css-tokenizer": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.3.1.tgz",
-      "integrity": "sha512-iMNHTyxLbBlWIfGtabT157LH9DUx9X8+Y3oymFEuMj8HNc+rpE3dPFGFgHjpKfjeFDjLjYIAIhXPGvS2lKxL9g==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.1.tgz",
+      "integrity": "sha512-UBqaiu7kU0lfvaP982/o3khfXccVlHPWp0/vwwiIgDF0GmqqqxoiXC/6FCjlS9u92f7CoEz6nXKQnrn1kIAkOw==",
       "dev": true,
       "funding": [
         {
@@ -728,13 +731,13 @@
         }
       ],
       "engines": {
-        "node": "^14 || ^16 || >=18"
+        "node": ">=18"
       }
     },
     "node_modules/@csstools/media-query-list-parser": {
-      "version": "2.1.11",
-      "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.11.tgz",
-      "integrity": "sha512-uox5MVhvNHqitPP+SynrB1o8oPxPMt2JLgp5ghJOWf54WGQ5OKu47efne49r1SWqs3wRP8xSWjnO9MBKxhB1dA==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-3.0.1.tgz",
+      "integrity": "sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==",
       "dev": true,
       "funding": [
         {
@@ -747,17 +750,17 @@
         }
       ],
       "engines": {
-        "node": "^14 || ^16 || >=18"
+        "node": ">=18"
       },
       "peerDependencies": {
-        "@csstools/css-parser-algorithms": "^2.6.3",
-        "@csstools/css-tokenizer": "^2.3.1"
+        "@csstools/css-parser-algorithms": "^3.0.1",
+        "@csstools/css-tokenizer": "^3.0.1"
       }
     },
     "node_modules/@csstools/selector-specificity": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz",
-      "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-4.0.0.tgz",
+      "integrity": "sha512-189nelqtPd8++phaHNwYovKZI0FOzH1vQEE3QhHHkNIGrg5fSs9CbYP3RvfEH5geztnIA9Jwq91wyOIwAW5JIQ==",
       "dev": true,
       "funding": [
         {
@@ -770,10 +773,10 @@
         }
       ],
       "engines": {
-        "node": "^14 || ^16 || >=18"
+        "node": ">=18"
       },
       "peerDependencies": {
-        "postcss-selector-parser": "^6.0.13"
+        "postcss-selector-parser": "^6.1.0"
       }
     },
     "node_modules/@dual-bundle/import-meta-resolve": {
@@ -2481,6 +2484,15 @@
         "node": ">=16"
       }
     },
+    "node_modules/common-tags": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
+      "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
     "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -2662,21 +2674,21 @@
       }
     },
     "node_modules/css-functions-list": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz",
-      "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==",
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz",
+      "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==",
       "dev": true,
       "engines": {
         "node": ">=12 || >=16"
       }
     },
     "node_modules/css-tree": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
-      "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
-      "dev": true,
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.0.0.tgz",
+      "integrity": "sha512-o88DVQ6GzsABn1+6+zo2ct801dBO5OASVyxbbvA2W20ue2puSh/VOuqUj90eUeMSX/xqGqBmOKiRQN7tJOuBXw==",
+      "license": "MIT",
       "dependencies": {
-        "mdn-data": "2.0.30",
+        "mdn-data": "2.10.0",
         "source-map-js": "^1.0.1"
       },
       "engines": {
@@ -3905,12 +3917,12 @@
       }
     },
     "node_modules/husky": {
-      "version": "9.0.11",
-      "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz",
-      "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==",
+      "version": "9.1.6",
+      "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.6.tgz",
+      "integrity": "sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==",
       "dev": true,
       "bin": {
-        "husky": "bin.mjs"
+        "husky": "bin.js"
       },
       "engines": {
         "node": ">=18"
@@ -3952,9 +3964,9 @@
       ]
     },
     "node_modules/ignore": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
-      "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
+      "version": "5.3.2",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+      "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
       "dev": true,
       "engines": {
         "node": ">= 4"
@@ -4701,7 +4713,6 @@
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
       "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
-      "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -6705,10 +6716,10 @@
       }
     },
     "node_modules/mdn-data": {
-      "version": "2.0.30",
-      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
-      "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
-      "dev": true
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.10.0.tgz",
+      "integrity": "sha512-qq7C3EtK3yJXMwz1zAab65pjl+UhohqMOctTgcqjLOWABqmwj+me02LSsCuEUxnst9X1lCBpoE0WArGKgdGDzw==",
+      "license": "CC0-1.0"
     },
     "node_modules/meow": {
       "version": "13.2.0",
@@ -6934,9 +6945,9 @@
       }
     },
     "node_modules/np": {
-      "version": "10.0.6",
-      "resolved": "https://registry.npmjs.org/np/-/np-10.0.6.tgz",
-      "integrity": "sha512-173uUvFDmHtme1ra3JDMjYzqa94XHJAHoNae6lCA4mJWMIz073x9FE2O8SHMMjKXlHetRdOXufLUjdimRxXR3A==",
+      "version": "10.0.7",
+      "resolved": "https://registry.npmjs.org/np/-/np-10.0.7.tgz",
+      "integrity": "sha512-vIPKQwOYKpQU40PU5x/vLfN2haj8ObxMvR1QGt7EZnBPWdm4WEbHdumYAnMV7AeR9kACsMqcqAP37sAo5cW5jA==",
       "dev": true,
       "dependencies": {
         "chalk": "^5.3.0",
@@ -7826,9 +7837,9 @@
       }
     },
     "node_modules/picocolors": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
-      "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
+      "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
       "dev": true
     },
     "node_modules/picomatch": {
@@ -7929,9 +7940,9 @@
       }
     },
     "node_modules/postcss": {
-      "version": "8.4.39",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz",
-      "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==",
+      "version": "8.4.47",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
+      "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
       "dev": true,
       "funding": [
         {
@@ -7949,8 +7960,8 @@
       ],
       "dependencies": {
         "nanoid": "^3.3.7",
-        "picocolors": "^1.0.1",
-        "source-map-js": "^1.2.0"
+        "picocolors": "^1.1.0",
+        "source-map-js": "^1.2.1"
       },
       "engines": {
         "node": "^10 || ^12 || >=14"
@@ -7974,14 +7985,14 @@
       "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig=="
     },
     "node_modules/postcss-resolve-nested-selector": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
-      "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw=="
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz",
+      "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw=="
     },
     "node_modules/postcss-safe-parser": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz",
-      "integrity": "sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==",
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz",
+      "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==",
       "dev": true,
       "funding": [
         {
@@ -8031,9 +8042,9 @@
       }
     },
     "node_modules/postcss-selector-parser": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz",
-      "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+      "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
       "dependencies": {
         "cssesc": "^3.0.0",
         "util-deprecate": "^1.0.2"
@@ -8057,9 +8068,9 @@
       }
     },
     "node_modules/prettier": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
-      "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
+      "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
       "dev": true,
       "bin": {
         "prettier": "bin/prettier.cjs"
@@ -8724,10 +8735,9 @@
       }
     },
     "node_modules/source-map-js": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
-      "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
-      "dev": true,
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
       "engines": {
         "node": ">=0.10.0"
       }
@@ -8919,9 +8929,9 @@
       }
     },
     "node_modules/stylelint": {
-      "version": "16.6.1",
-      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.6.1.tgz",
-      "integrity": "sha512-yNgz2PqWLkhH2hw6X9AweV9YvoafbAD5ZsFdKN9BvSDVwGvPh+AUIrn7lYwy1S7IHmtFin75LLfX1m0D2tHu8Q==",
+      "version": "16.10.0",
+      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.10.0.tgz",
+      "integrity": "sha512-z/8X2rZ52dt2c0stVwI9QL2AFJhLhbPkyfpDFcizs200V/g7v+UYY6SNcB9hKOLcDDX/yGLDsY/pX08sLkz9xQ==",
       "dev": true,
       "funding": [
         {
@@ -8934,42 +8944,41 @@
         }
       ],
       "dependencies": {
-        "@csstools/css-parser-algorithms": "^2.6.3",
-        "@csstools/css-tokenizer": "^2.3.1",
-        "@csstools/media-query-list-parser": "^2.1.11",
-        "@csstools/selector-specificity": "^3.1.1",
+        "@csstools/css-parser-algorithms": "^3.0.1",
+        "@csstools/css-tokenizer": "^3.0.1",
+        "@csstools/media-query-list-parser": "^3.0.1",
+        "@csstools/selector-specificity": "^4.0.0",
         "@dual-bundle/import-meta-resolve": "^4.1.0",
         "balanced-match": "^2.0.0",
         "colord": "^2.9.3",
         "cosmiconfig": "^9.0.0",
-        "css-functions-list": "^3.2.2",
-        "css-tree": "^2.3.1",
-        "debug": "^4.3.4",
+        "css-functions-list": "^3.2.3",
+        "css-tree": "^3.0.0",
+        "debug": "^4.3.7",
         "fast-glob": "^3.3.2",
         "fastest-levenshtein": "^1.0.16",
-        "file-entry-cache": "^9.0.0",
+        "file-entry-cache": "^9.1.0",
         "global-modules": "^2.0.0",
         "globby": "^11.1.0",
         "globjoin": "^0.1.4",
         "html-tags": "^3.3.1",
-        "ignore": "^5.3.1",
+        "ignore": "^6.0.2",
         "imurmurhash": "^0.1.4",
         "is-plain-object": "^5.0.0",
-        "known-css-properties": "^0.31.0",
+        "known-css-properties": "^0.34.0",
         "mathml-tag-names": "^2.1.3",
         "meow": "^13.2.0",
-        "micromatch": "^4.0.7",
+        "micromatch": "^4.0.8",
         "normalize-path": "^3.0.0",
         "picocolors": "^1.0.1",
-        "postcss": "^8.4.38",
-        "postcss-resolve-nested-selector": "^0.1.1",
-        "postcss-safe-parser": "^7.0.0",
-        "postcss-selector-parser": "^6.1.0",
+        "postcss": "^8.4.47",
+        "postcss-resolve-nested-selector": "^0.1.6",
+        "postcss-safe-parser": "^7.0.1",
+        "postcss-selector-parser": "^6.1.2",
         "postcss-value-parser": "^4.2.0",
         "resolve-from": "^5.0.0",
         "string-width": "^4.2.3",
-        "strip-ansi": "^7.1.0",
-        "supports-hyperlinks": "^3.0.0",
+        "supports-hyperlinks": "^3.1.0",
         "svg-tags": "^1.0.0",
         "table": "^6.8.2",
         "write-file-atomic": "^5.0.1"
@@ -9013,6 +9022,23 @@
         }
       }
     },
+    "node_modules/stylelint/node_modules/debug": {
+      "version": "4.3.7",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+      "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/stylelint/node_modules/emoji-regex": {
       "version": "8.0.0",
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -9020,9 +9046,9 @@
       "dev": true
     },
     "node_modules/stylelint/node_modules/file-entry-cache": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz",
-      "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==",
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.1.0.tgz",
+      "integrity": "sha512-/pqPFG+FdxWQj+/WSuzXSDaNzxgTLr/OrR1QuqfEZzDakpdYE70PwUxL7BPUa8hpjbvY1+qvCl8k+8Tq34xJgg==",
       "dev": true,
       "dependencies": {
         "flat-cache": "^5.0.0"
@@ -9064,6 +9090,24 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/stylelint/node_modules/globby/node_modules/ignore": {
+      "version": "5.3.2",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+      "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/stylelint/node_modules/ignore": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz",
+      "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4"
+      }
+    },
     "node_modules/stylelint/node_modules/is-fullwidth-code-point": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -9073,16 +9117,10 @@
         "node": ">=8"
       }
     },
-    "node_modules/stylelint/node_modules/known-css-properties": {
-      "version": "0.31.0",
-      "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.31.0.tgz",
-      "integrity": "sha512-sBPIUGTNF0czz0mwGGUoKKJC8Q7On1GPbCSFPfyEsfHb2DyBG0Y4QtV+EVWpINSaiGKZblDNuF5AezxSgOhesQ==",
-      "dev": true
-    },
     "node_modules/stylelint/node_modules/micromatch": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
-      "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+      "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
       "dev": true,
       "dependencies": {
         "braces": "^3.0.3",
@@ -9092,6 +9130,12 @@
         "node": ">=8.6"
       }
     },
+    "node_modules/stylelint/node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "dev": true
+    },
     "node_modules/stylelint/node_modules/resolve-from": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
@@ -9139,33 +9183,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/stylelint/node_modules/strip-ansi": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
-      "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-regex": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
-      }
-    },
-    "node_modules/stylelint/node_modules/strip-ansi/node_modules/ansi-regex": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
-      "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
-      "dev": true,
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
-      }
-    },
     "node_modules/stylelint/node_modules/write-file-atomic": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
@@ -9192,9 +9209,9 @@
       }
     },
     "node_modules/supports-hyperlinks": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz",
-      "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.1.0.tgz",
+      "integrity": "sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==",
       "dev": true,
       "dependencies": {
         "has-flag": "^4.0.0",
@@ -9202,6 +9219,9 @@
       },
       "engines": {
         "node": ">=14.18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/supports-preserve-symlinks-flag": {
@@ -10407,29 +10427,29 @@
       "dev": true
     },
     "@csstools/css-parser-algorithms": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.6.3.tgz",
-      "integrity": "sha512-xI/tL2zxzEbESvnSxwFgwvy5HS00oCXxL4MLs6HUiDcYfwowsoQaABKxUElp1ARITrINzBnsECOc1q0eg2GOrA==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.1.tgz",
+      "integrity": "sha512-lSquqZCHxDfuTg/Sk2hiS0mcSFCEBuj49JfzPHJogDBT0mGCyY5A1AQzBWngitrp7i1/HAZpIgzF/VjhOEIJIg==",
       "dev": true,
       "requires": {}
     },
     "@csstools/css-tokenizer": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.3.1.tgz",
-      "integrity": "sha512-iMNHTyxLbBlWIfGtabT157LH9DUx9X8+Y3oymFEuMj8HNc+rpE3dPFGFgHjpKfjeFDjLjYIAIhXPGvS2lKxL9g==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.1.tgz",
+      "integrity": "sha512-UBqaiu7kU0lfvaP982/o3khfXccVlHPWp0/vwwiIgDF0GmqqqxoiXC/6FCjlS9u92f7CoEz6nXKQnrn1kIAkOw==",
       "dev": true
     },
     "@csstools/media-query-list-parser": {
-      "version": "2.1.11",
-      "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.11.tgz",
-      "integrity": "sha512-uox5MVhvNHqitPP+SynrB1o8oPxPMt2JLgp5ghJOWf54WGQ5OKu47efne49r1SWqs3wRP8xSWjnO9MBKxhB1dA==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-3.0.1.tgz",
+      "integrity": "sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==",
       "dev": true,
       "requires": {}
     },
     "@csstools/selector-specificity": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz",
-      "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-4.0.0.tgz",
+      "integrity": "sha512-189nelqtPd8++phaHNwYovKZI0FOzH1vQEE3QhHHkNIGrg5fSs9CbYP3RvfEH5geztnIA9Jwq91wyOIwAW5JIQ==",
       "dev": true,
       "requires": {}
     },
@@ -11699,6 +11719,12 @@
       "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==",
       "dev": true
     },
+    "common-tags": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
+      "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
+      "dev": true
+    },
     "concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -11830,18 +11856,17 @@
       }
     },
     "css-functions-list": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz",
-      "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==",
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz",
+      "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==",
       "dev": true
     },
     "css-tree": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
-      "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
-      "dev": true,
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.0.0.tgz",
+      "integrity": "sha512-o88DVQ6GzsABn1+6+zo2ct801dBO5OASVyxbbvA2W20ue2puSh/VOuqUj90eUeMSX/xqGqBmOKiRQN7tJOuBXw==",
       "requires": {
-        "mdn-data": "2.0.30",
+        "mdn-data": "2.10.0",
         "source-map-js": "^1.0.1"
       }
     },
@@ -12714,9 +12739,9 @@
       "dev": true
     },
     "husky": {
-      "version": "9.0.11",
-      "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz",
-      "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==",
+      "version": "9.1.6",
+      "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.6.tgz",
+      "integrity": "sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==",
       "dev": true
     },
     "iconv-lite": {
@@ -12735,9 +12760,9 @@
       "dev": true
     },
     "ignore": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
-      "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
+      "version": "5.3.2",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+      "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
       "dev": true
     },
     "ignore-walk": {
@@ -13276,8 +13301,7 @@
     "is-plain-object": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
-      "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
-      "dev": true
+      "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
     },
     "is-promise": {
       "version": "2.2.2",
@@ -14750,10 +14774,9 @@
       "dev": true
     },
     "mdn-data": {
-      "version": "2.0.30",
-      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
-      "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
-      "dev": true
+      "version": "2.10.0",
+      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.10.0.tgz",
+      "integrity": "sha512-qq7C3EtK3yJXMwz1zAab65pjl+UhohqMOctTgcqjLOWABqmwj+me02LSsCuEUxnst9X1lCBpoE0WArGKgdGDzw=="
     },
     "meow": {
       "version": "13.2.0",
@@ -14914,9 +14937,9 @@
       "dev": true
     },
     "np": {
-      "version": "10.0.6",
-      "resolved": "https://registry.npmjs.org/np/-/np-10.0.6.tgz",
-      "integrity": "sha512-173uUvFDmHtme1ra3JDMjYzqa94XHJAHoNae6lCA4mJWMIz073x9FE2O8SHMMjKXlHetRdOXufLUjdimRxXR3A==",
+      "version": "10.0.7",
+      "resolved": "https://registry.npmjs.org/np/-/np-10.0.7.tgz",
+      "integrity": "sha512-vIPKQwOYKpQU40PU5x/vLfN2haj8ObxMvR1QGt7EZnBPWdm4WEbHdumYAnMV7AeR9kACsMqcqAP37sAo5cW5jA==",
       "dev": true,
       "requires": {
         "chalk": "^5.3.0",
@@ -15511,9 +15534,9 @@
       "dev": true
     },
     "picocolors": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
-      "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
+      "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
       "dev": true
     },
     "picomatch": {
@@ -15583,14 +15606,14 @@
       }
     },
     "postcss": {
-      "version": "8.4.39",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz",
-      "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==",
+      "version": "8.4.47",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
+      "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
       "dev": true,
       "requires": {
         "nanoid": "^3.3.7",
-        "picocolors": "^1.0.1",
-        "source-map-js": "^1.2.0"
+        "picocolors": "^1.1.0",
+        "source-map-js": "^1.2.1"
       }
     },
     "postcss-less": {
@@ -15606,14 +15629,14 @@
       "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig=="
     },
     "postcss-resolve-nested-selector": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
-      "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw=="
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz",
+      "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw=="
     },
     "postcss-safe-parser": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz",
-      "integrity": "sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==",
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz",
+      "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==",
       "dev": true,
       "requires": {}
     },
@@ -15625,9 +15648,9 @@
       "requires": {}
     },
     "postcss-selector-parser": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz",
-      "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+      "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
       "requires": {
         "cssesc": "^3.0.0",
         "util-deprecate": "^1.0.2"
@@ -15645,9 +15668,9 @@
       "dev": true
     },
     "prettier": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
-      "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
+      "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
       "dev": true
     },
     "pretty-format": {
@@ -16086,10 +16109,9 @@
       "dev": true
     },
     "source-map-js": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
-      "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
-      "dev": true
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
     },
     "source-map-support": {
       "version": "0.5.13",
@@ -16237,47 +16259,46 @@
       "dev": true
     },
     "stylelint": {
-      "version": "16.6.1",
-      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.6.1.tgz",
-      "integrity": "sha512-yNgz2PqWLkhH2hw6X9AweV9YvoafbAD5ZsFdKN9BvSDVwGvPh+AUIrn7lYwy1S7IHmtFin75LLfX1m0D2tHu8Q==",
+      "version": "16.10.0",
+      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.10.0.tgz",
+      "integrity": "sha512-z/8X2rZ52dt2c0stVwI9QL2AFJhLhbPkyfpDFcizs200V/g7v+UYY6SNcB9hKOLcDDX/yGLDsY/pX08sLkz9xQ==",
       "dev": true,
       "requires": {
-        "@csstools/css-parser-algorithms": "^2.6.3",
-        "@csstools/css-tokenizer": "^2.3.1",
-        "@csstools/media-query-list-parser": "^2.1.11",
-        "@csstools/selector-specificity": "^3.1.1",
+        "@csstools/css-parser-algorithms": "^3.0.1",
+        "@csstools/css-tokenizer": "^3.0.1",
+        "@csstools/media-query-list-parser": "^3.0.1",
+        "@csstools/selector-specificity": "^4.0.0",
         "@dual-bundle/import-meta-resolve": "^4.1.0",
         "balanced-match": "^2.0.0",
         "colord": "^2.9.3",
         "cosmiconfig": "^9.0.0",
-        "css-functions-list": "^3.2.2",
-        "css-tree": "^2.3.1",
-        "debug": "^4.3.4",
+        "css-functions-list": "^3.2.3",
+        "css-tree": "^3.0.0",
+        "debug": "^4.3.7",
         "fast-glob": "^3.3.2",
         "fastest-levenshtein": "^1.0.16",
-        "file-entry-cache": "^9.0.0",
+        "file-entry-cache": "^9.1.0",
         "global-modules": "^2.0.0",
         "globby": "^11.1.0",
         "globjoin": "^0.1.4",
         "html-tags": "^3.3.1",
-        "ignore": "^5.3.1",
+        "ignore": "^6.0.2",
         "imurmurhash": "^0.1.4",
         "is-plain-object": "^5.0.0",
-        "known-css-properties": "^0.31.0",
+        "known-css-properties": "^0.34.0",
         "mathml-tag-names": "^2.1.3",
         "meow": "^13.2.0",
-        "micromatch": "^4.0.7",
+        "micromatch": "^4.0.8",
         "normalize-path": "^3.0.0",
         "picocolors": "^1.0.1",
-        "postcss": "^8.4.38",
-        "postcss-resolve-nested-selector": "^0.1.1",
-        "postcss-safe-parser": "^7.0.0",
-        "postcss-selector-parser": "^6.1.0",
+        "postcss": "^8.4.47",
+        "postcss-resolve-nested-selector": "^0.1.6",
+        "postcss-safe-parser": "^7.0.1",
+        "postcss-selector-parser": "^6.1.2",
         "postcss-value-parser": "^4.2.0",
         "resolve-from": "^5.0.0",
         "string-width": "^4.2.3",
-        "strip-ansi": "^7.1.0",
-        "supports-hyperlinks": "^3.0.0",
+        "supports-hyperlinks": "^3.1.0",
         "svg-tags": "^1.0.0",
         "table": "^6.8.2",
         "write-file-atomic": "^5.0.1"
@@ -16301,6 +16322,15 @@
             "parse-json": "^5.2.0"
           }
         },
+        "debug": {
+          "version": "4.3.7",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+          "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.3"
+          }
+        },
         "emoji-regex": {
           "version": "8.0.0",
           "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -16308,9 +16338,9 @@
           "dev": true
         },
         "file-entry-cache": {
-          "version": "9.0.0",
-          "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz",
-          "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==",
+          "version": "9.1.0",
+          "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.1.0.tgz",
+          "integrity": "sha512-/pqPFG+FdxWQj+/WSuzXSDaNzxgTLr/OrR1QuqfEZzDakpdYE70PwUxL7BPUa8hpjbvY1+qvCl8k+8Tq34xJgg==",
           "dev": true,
           "requires": {
             "flat-cache": "^5.0.0"
@@ -16338,30 +16368,44 @@
             "ignore": "^5.2.0",
             "merge2": "^1.4.1",
             "slash": "^3.0.0"
+          },
+          "dependencies": {
+            "ignore": {
+              "version": "5.3.2",
+              "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+              "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+              "dev": true
+            }
           }
         },
+        "ignore": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz",
+          "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==",
+          "dev": true
+        },
         "is-fullwidth-code-point": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
           "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
           "dev": true
         },
-        "known-css-properties": {
-          "version": "0.31.0",
-          "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.31.0.tgz",
-          "integrity": "sha512-sBPIUGTNF0czz0mwGGUoKKJC8Q7On1GPbCSFPfyEsfHb2DyBG0Y4QtV+EVWpINSaiGKZblDNuF5AezxSgOhesQ==",
-          "dev": true
-        },
         "micromatch": {
-          "version": "4.0.7",
-          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
-          "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
+          "version": "4.0.8",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+          "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
           "dev": true,
           "requires": {
             "braces": "^3.0.3",
             "picomatch": "^2.3.1"
           }
         },
+        "ms": {
+          "version": "2.1.3",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+          "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+          "dev": true
+        },
         "resolve-from": {
           "version": "5.0.0",
           "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
@@ -16396,23 +16440,6 @@
             }
           }
         },
-        "strip-ansi": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
-          "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^6.0.1"
-          },
-          "dependencies": {
-            "ansi-regex": {
-              "version": "6.0.1",
-              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
-              "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
-              "dev": true
-            }
-          }
-        },
         "write-file-atomic": {
           "version": "5.0.1",
           "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
@@ -16435,9 +16462,9 @@
       }
     },
     "supports-hyperlinks": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz",
-      "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.1.0.tgz",
+      "integrity": "sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==",
       "dev": true,
       "requires": {
         "has-flag": "^4.0.0",
diff --git a/package.json b/package.json
index a1d36b8..2d2fc62 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "stylelint-scss",
   "description": "A collection of SCSS-specific rules for Stylelint",
-  "version": "6.4.1",
+  "version": "6.7.0",
   "author": "Krister Kari",
   "repository": "stylelint-scss/stylelint-scss",
   "license": "MIT",
@@ -13,26 +13,29 @@
     "stylelint": "^16.0.2"
   },
   "dependencies": {
+    "css-tree": "^3.0.0",
+    "is-plain-object": "^5.0.0",
     "known-css-properties": "^0.34.0",
     "postcss-media-query-parser": "^0.2.3",
-    "postcss-resolve-nested-selector": "^0.1.1",
-    "postcss-selector-parser": "^6.1.0",
+    "postcss-resolve-nested-selector": "^0.1.6",
+    "postcss-selector-parser": "^6.1.2",
     "postcss-value-parser": "^4.2.0"
   },
   "devDependencies": {
+    "common-tags": "^1.8.2",
     "cross-env": "^7.0.3",
     "eslint": "^8.57.0",
     "github-contributors-list": "^1.2.5",
-    "husky": "^9.0.11",
+    "husky": "^9.1.6",
     "jest": "^29.7.0",
     "jest-preset-stylelint": "^7.1.0",
     "lint-staged": "^14.0.1",
-    "np": "^10.0.6",
-    "postcss": "^8.4.39",
+    "np": "^10.0.7",
+    "postcss": "^8.4.47",
     "postcss-less": "^6.0.0",
     "postcss-scss": "^4.0.9",
-    "prettier": "^3.3.2",
-    "stylelint": "^16.6.1"
+    "prettier": "^3.3.3",
+    "stylelint": "^16.10.0"
   },
   "files": [
     "src/**/*.js",
diff --git a/src/rules/declaration-property-value-no-unknown/README.md b/src/rules/declaration-property-value-no-unknown/README.md
new file mode 100644
index 0000000..80a45a2
--- /dev/null
+++ b/src/rules/declaration-property-value-no-unknown/README.md
@@ -0,0 +1,141 @@
+# declaration-property-value-no-unknown
+
+Disallow unknown values for properties within declarations.
+
+<!-- prettier-ignore -->
+```css
+a { top: unknown; }
+/** ↑    ↑
+ * property and value pairs like these */
+```
+
+This rule considers values for properties defined within the CSS specifications to be known. You can use the `propertiesSyntax` and `typesSyntax` secondary options to extend the syntax.
+
+This rule is only appropriate for CSS. You should not turn it on for CSS-like languages, such as Sass or Less, as they have their own syntaxes.
+
+This rule is experimental with some false negatives that we'll patch in minor releases.
+
+It sometimes overlaps with:
+
+- [`color-no-invalid-hex`](../color-no-invalid-hex/README.md)
+- [`function-no-unknown`](../function-no-unknown/README.md)
+- [`string-no-newline`](../string-no-newline/README.md)
+- [`unit-no-unknown`](../unit-no-unknown/README.md)
+
+If duplicate problems are flagged, you can turn off the corresponding rule.
+
+## Options
+
+### `true`
+
+The following patterns are considered problems:
+
+<!-- prettier-ignore -->
+```css
+a { top: red; }
+```
+
+<!-- prettier-ignore -->
+```css
+a { top: unknown; }
+```
+
+The following patterns are _not_ considered problems:
+
+<!-- prettier-ignore -->
+```css
+a { top: 0; }
+```
+
+<!-- prettier-ignore -->
+```css
+a { top: var(--foo); }
+```
+
+## Optional secondary options
+
+### `ignoreProperties: { "property": ["/regex/", /regex/, "non-regex"]|"/regex/"|/regex/|"non-regex" }`
+
+Ignore the specified property and value pairs. Keys in the object indicate property names. If a string in the object is surrounded with `"/"`, it's interpreted as a regular expression. For example, `"/.+/"` matches any strings.
+
+Given:
+
+```json
+{
+  "top": ["unknown"],
+  "/^margin-/": "/^--foo/",
+  "padding": "/.+/",
+  "/.+/": "--unknown-value"
+}
+```
+
+The following patterns are _not_ considered problems:
+
+<!-- prettier-ignore -->
+```css
+a { top: unknown; }
+```
+
+<!-- prettier-ignore -->
+```css
+a { margin-top: --foo-bar; }
+```
+
+<!-- prettier-ignore -->
+```css
+a { padding: invalid; }
+```
+
+<!-- prettier-ignore -->
+```css
+a { width: --unknown-value; }
+```
+
+### `propertiesSyntax: { property: syntax }`
+
+Extend or alter the properties syntax dictionary. [CSS Value Definition Syntax](https://github.com/csstree/csstree/blob/master/docs/definition-syntax.md) is used to define a value's syntax. If a definition starts with `|` it is added to the [existing definition value](https://csstree.github.io/docs/syntax/) if any.
+
+Given:
+
+```json
+{ "size": "<length-percentage>" }
+```
+
+The following patterns are _not_ considered problems:
+
+<!-- prettier-ignore -->
+```css
+a { size: 0; }
+```
+
+<!-- prettier-ignore -->
+```css
+a { size: 10px }
+```
+
+### `typesSyntax: { type: syntax }`
+
+Extend or alter the types syntax dictionary. [CSS Value Definition Syntax](https://github.com/csstree/csstree/blob/master/docs/definition-syntax.md) is used to define a value's syntax. If a definition starts with `|` it is added to the [existing definition value](https://csstree.github.io/docs/syntax/) if any.
+
+Types are something like a preset which allows you to reuse a definition across other definitions. So, you'll likely want to also use the `propertiesSyntax` option when using this option.
+
+Given:
+
+```json
+{
+  "propertiesSyntax": { "top": "| <--foo()>" },
+  "typesSyntax": { "--foo()": "--foo( <length-percentage> )" }
+}
+```
+
+The following patterns are _not_ considered problems:
+
+<!-- prettier-ignore -->
+```css
+a { top: --foo(0); }
+```
+
+<!-- prettier-ignore -->
+```css
+a { top: --foo(10px); }
+```
\ No newline at end of file
diff --git a/src/rules/declaration-property-value-no-unknown/index.js b/src/rules/declaration-property-value-no-unknown/index.js
new file mode 100644
index 0000000..1c5e88f
--- /dev/null
+++ b/src/rules/declaration-property-value-no-unknown/index.js
@@ -0,0 +1,322 @@
+"use strict";
+
+const cssTree = require("css-tree");
+const isPlainObject = require("is-plain-object");
+const typeGuards = require("../../utils/typeGuards.js");
+const declarationValueIndex = require("../../utils/declarationValueIndex.js");
+const getDeclarationValue = require("../../utils/getDeclarationValue.js");
+const isCustomProperty = require("../../utils/isCustomPropertySet.js");
+const isStandardSyntaxDeclaration = require("../../utils/isStandardSyntaxDeclaration.js");
+const isStandardSyntaxProperty = require("../../utils/isStandardSyntaxProperty.js");
+const isStandardSyntaxValue = require("../../utils/isStandardSyntaxValue.js");
+const matchesStringOrRegExp = require("../../utils/matchesStringOrRegExp.js");
+const atKeywords = require("../../utils/atKeywords.js");
+const validateObjectWithArrayProps = require("../../utils/validateObjectWithArrayProps.js");
+const { utils } = require("stylelint");
+const { isFunctionCall } = require("../../utils/validateTypes");
+const findOperators = require("../../utils/sassValueParser");
+const {
+  parseFunctionArguments
+} = require("../../utils/parseFunctionArguments");
+const {
+  isDollarVar,
+  isIfStatement,
+  isNestedProperty
+} = require("../../utils/validateTypes");
+const namespace = require("../../utils/namespace");
+const ruleUrl = require("../../utils/ruleUrl");
+
+const ruleName = namespace("declaration-property-value-no-unknown");
+
+const messages = utils.ruleMessages(ruleName, {
+  rejected: (property, value) =>
+    `Unexpected unknown value "${value}" for property "${property}"`,
+  rejectedParseError: (property, value) =>
+    `Cannot parse property value "${value}" for property "${property}"`
+});
+
+const meta = {
+  url: ruleUrl(ruleName)
+};
+
+const SYNTAX_DESCRIPTOR = /^syntax$/i;
+
+function extractFunctionName(inputString) {
+  const matches = [...inputString.matchAll(/(?:\s*([\w\-$]+)\s*)?\(/g)].flat();
+  return matches;
+}
+
+function hasDollarVarArg(functionCall) {
+  for (const i of parseFunctionArguments(functionCall)) {
+    if (isFunctionCall(i.value)) return hasDollarVarArg(i.value);
+    if (isDollarVar(i.value)) return true;
+  }
+  return false;
+}
+
+const unsupportedFunctions = ["clamp", "min", "max", "env"];
+const mathOperators = ["+", "/", "-", "*", "%"];
+
+function rule(primary, secondaryOptions) {
+  return (root, result) => {
+    const validOptions = utils.validateOptions(
+      result,
+      ruleName,
+      { actual: primary },
+      {
+        actual: secondaryOptions,
+        possible: {
+          ignoreProperties: [validateObjectWithArrayProps],
+          propertiesSyntax: [isPlainObject.isPlainObject],
+          typesSyntax: [isPlainObject.isPlainObject]
+        },
+        optional: true
+      }
+    );
+
+    if (!validOptions) {
+      return;
+    }
+
+    const ignoreProperties = Array.from(
+      Object.entries(secondaryOptions?.ignoreProperties ?? {})
+    );
+
+    /** @type {(name: string, propValue: string) => boolean} */
+    const isPropIgnored = (name, value) => {
+      const [, valuePattern] =
+        ignoreProperties.find(([namePattern]) =>
+          matchesStringOrRegExp(name, namePattern)
+        ) || [];
+
+      return valuePattern && matchesStringOrRegExp(value, valuePattern);
+    };
+
+    const propertiesSyntax = {
+      "text-box-edge":
+        "auto | [ text | cap | ex | ideographic | ideographic-ink ] [ text | alphabetic | ideographic | ideographic-ink ]?",
+      "text-box-trim": "none | trim-start | trim-end | trim-both",
+      "view-timeline":
+        "[ <'view-timeline-name'> [ <'view-timeline-axis'> || <'view-timeline-inset'> ]? ]#",
+      ...secondaryOptions?.propertiesSyntax
+    };
+    const typesSyntax = { ...secondaryOptions?.typesSyntax };
+
+    /** @type {Map<string, string>} */
+    const typedCustomPropertyNames = new Map();
+
+    // Unless we tracked return values of declared functions, they're all valid.
+    root.walkAtRules("function", atRule => {
+      unsupportedFunctions.push(extractFunctionName(atRule.params)[1]);
+    });
+
+    root.walkAtRules(/^property$/i, atRule => {
+      const propName = atRule.params.trim();
+
+      if (!propName || !atRule.nodes || !isCustomProperty(propName)) return;
+
+      for (const node of atRule.nodes) {
+        if (
+          typeGuards.isDeclaration(node) &&
+          SYNTAX_DESCRIPTOR.test(node.prop)
+        ) {
+          const value = node.value.trim();
+          const unquoted = cssTree.string.decode(value);
+
+          // Only string values are valid.
+          // We can not check the syntax of this property.
+          if (unquoted === value) continue;
+
+          // Any value is allowed in this custom property.
+          // We don't need to check this property.
+          if (unquoted === "*") continue;
+
+          // https://github.com/csstree/csstree/pull/256
+          // We can circumvent this issue by prefixing the property name,
+          // making it a vendor-prefixed property instead of a custom property.
+          // No one should be using `-stylelint--` as a property prefix.
+          //
+          // When this is resolved `typedCustomPropertyNames` can become a `Set<string>`
+          // and the prefix can be removed.
+          const prefixedPropName = `-stylelint${propName}`;
+
+          typedCustomPropertyNames.set(propName, prefixedPropName);
+          propertiesSyntax[prefixedPropName] = unquoted;
+        }
+      }
+    });
+
+    const forkedLexer = cssTree.fork({
+      properties: propertiesSyntax,
+      types: typesSyntax
+    }).lexer;
+
+    root.walkDecls(decl => {
+      const { prop, parent } = decl;
+      const value = getDeclarationValue(decl);
+
+      //csstree/csstree#243
+      // NOTE: CSSTree's `fork()` doesn't support `-moz-initial`, but it may be possible in the future.
+      if (/^-moz-initial$/i.test(value)) return;
+
+      if (!isStandardSyntaxDeclaration(decl)) return;
+
+      if (!isStandardSyntaxProperty(prop)) return;
+
+      if (!isStandardSyntaxValue(value)) return;
+
+      if (isCustomProperty(prop) && !typedCustomPropertyNames.has(prop)) return;
+
+      if (isPropIgnored(prop, value)) return;
+
+      // Unless we tracked values of variables, they're all valid.
+      if (value.split(" ").some(val => isDollarVar(val))) return;
+      if (value.split(" ").some(val => hasDollarVarArg(val))) return;
+      if (value.split(" ").some(val => containsCustomFunction(val))) return;
+
+      /** @type {import('css-tree').CssNode} */
+      let cssTreeValueNode;
+
+      try {
+        cssTreeValueNode = cssTree.parse(value, {
+          context: "value",
+          positions: true
+        });
+
+        if (containsCustomFunction(cssTreeValueNode)) return;
+        if (containsUnsupportedFunction(cssTreeValueNode)) return;
+      } catch (e) {
+        const index = declarationValueIndex(decl);
+        const endIndex = index + value.length;
+
+        // Hidden declarations
+        if (isIfStatement(value)) return;
+        if (hasDollarVarArg(value)) return;
+        const operators = findOperators({ string: value }).map(o => o.symbol);
+
+        for (const operator of operators) {
+          if (mathOperators.includes(operator)) {
+            return;
+          }
+        }
+
+        utils.report({
+          message: messages.rejectedParseError(prop, value),
+          node: decl,
+          index,
+          endIndex,
+          result,
+          ruleName
+        });
+
+        return;
+      }
+
+      const { error } =
+        parent &&
+        typeGuards.isAtRule(parent) &&
+        !atKeywords.nestingSupportedAtKeywords.has(parent.name.toLowerCase())
+          ? forkedLexer.matchAtruleDescriptor(
+              parent.name,
+              prop,
+              cssTreeValueNode
+            )
+          : forkedLexer.matchProperty(
+              typedCustomPropertyNames.get(prop) ?? prop,
+              cssTreeValueNode
+            );
+
+      if (!error) return;
+
+      if (!("mismatchLength" in error)) return;
+
+      const { name, rawMessage, loc } = error;
+
+      if (name !== "SyntaxMatchError") return;
+
+      if (rawMessage !== "Mismatch") return;
+
+      const valueIndex = declarationValueIndex(decl);
+      const mismatchValue = value.slice(loc.start.offset, loc.end.offset);
+      const operators = findOperators({ string: value }).map(o => o.symbol);
+
+      for (const operator of operators) {
+        if (mathOperators.includes(operator)) {
+          return;
+        }
+      }
+
+      utils.report({
+        message: messages.rejected(prop, mismatchValue),
+        node: decl,
+        index: valueIndex + loc.start.offset,
+        endIndex: valueIndex + loc.end.offset,
+        result,
+        ruleName
+      });
+    });
+
+    // Handle nested properties
+    root.walkRules(node => {
+      if (!isNestedProperty(node.selector)) return;
+      node.each(decl => {
+        let pointer = node;
+        let prop = String(decl.prop);
+        while (
+          pointer &&
+          pointer.selector &&
+          pointer.selector[pointer.selector.length - 1] === ":" &&
+          pointer.selector.substring(0, 2) !== "--"
+        ) {
+          prop = pointer.selector.replace(":", "") + "-" + prop;
+          pointer = pointer.parent;
+        }
+        const { error } = forkedLexer.matchProperty(prop, String(decl.value));
+
+        if (!error) return;
+
+        utils.report({
+          message: messages.rejected(prop, decl.value),
+          node,
+          result,
+          ruleName
+        });
+      });
+    });
+  };
+}
+
+/**
+ *
+ * @see csstree/csstree#164 min, max, clamp
+ * @see csstree/csstree#245 env
+ *
+ * @param {import('css-tree').CssNode} cssTreeNode
+ * @returns {boolean}
+ */
+function containsUnsupportedFunction(cssTreeNode) {
+  return Boolean(
+    cssTree.find(
+      cssTreeNode,
+      node =>
+        node.type === "Function" &&
+        ["clamp", "min", "max", "env"].includes(node.name)
+    )
+  );
+}
+
+function containsCustomFunction(cssTreeNode) {
+  return Boolean(
+    cssTree.find(
+      cssTreeNode,
+      node =>
+        node.type === "Function" && unsupportedFunctions.includes(node.name)
+    )
+  );
+}
+
+rule.ruleName = ruleName;
+rule.messages = messages;
+rule.meta = meta;
+
+module.exports = rule;
diff --git a/src/rules/function-quote-no-quoted-strings-inside/index.js b/src/rules/function-quote-no-quoted-strings-inside/index.js
index b202942..b307cb4 100644
--- a/src/rules/function-quote-no-quoted-strings-inside/index.js
+++ b/src/rules/function-quote-no-quoted-strings-inside/index.js
@@ -60,8 +60,7 @@ function rule(primary, _, context) {
         // postcss-value-parser represents quoted strings as type 'string' (as opposed to word)
         if (node.nodes[0].quote || vars[node.nodes[0].value] === "string") {
           if (context.fix) {
-            const contents = decl.value.match(/quote\((.*)\)/);
-            decl.value = decl.value.replace(/quote\(.*\)/, contents[1]);
+            decl.value = decl.value.replace(/quote\((.*)\)/, "$1");
           } else {
             const index = declarationValueIndex(decl) + node.sourceIndex;
             utils.report({
diff --git a/src/rules/function-unquote-no-unquoted-strings-inside/index.js b/src/rules/function-unquote-no-unquoted-strings-inside/index.js
index 9a46635..996dc45 100644
--- a/src/rules/function-unquote-no-unquoted-strings-inside/index.js
+++ b/src/rules/function-unquote-no-unquoted-strings-inside/index.js
@@ -51,7 +51,7 @@ function rule(primary, _, context) {
           return;
         }
 
-        // Verify we're only looking at quote() calls.
+        // Verify we're only looking at unquote() calls.
         if (node.value !== "unquote") {
           return;
         }
@@ -63,9 +63,7 @@ function rule(primary, _, context) {
           vars[node.nodes[0].value] === "word"
         ) {
           if (context.fix) {
-            const contents = /unquote\((.*)\)/.exec(decl.value);
-
-            decl.value = contents[1];
+            decl.value = decl.value.replace(/unquote\((.*)\)/, "$1");
           } else {
             const index = declarationValueIndex(decl) + node.sourceIndex;
             utils.report({
diff --git a/src/rules/index.js b/src/rules/index.js
index 21a218a..b8afe6b 100644
--- a/src/rules/index.js
+++ b/src/rules/index.js
@@ -36,6 +36,7 @@ const rules = {
   "comment-no-loud": require("./comment-no-loud"),
   "declaration-nested-properties-no-divided-groups": require("./declaration-nested-properties-no-divided-groups"),
   "declaration-nested-properties": require("./declaration-nested-properties"),
+  "declaration-property-value-no-unknown": require("./declaration-property-value-no-unknown"),
   "dimension-no-non-numeric-values": require("./dimension-no-non-numeric-values"),
   "dollar-variable-colon-newline-after": require("./dollar-variable-colon-newline-after"),
   "dollar-variable-colon-space-after": require("./dollar-variable-colon-space-after"),
diff --git a/src/rules/property-no-unknown/index.js b/src/rules/property-no-unknown/index.js
index e986b94..9bd1da3 100644
--- a/src/rules/property-no-unknown/index.js
+++ b/src/rules/property-no-unknown/index.js
@@ -111,6 +111,17 @@ function rule(primary, secondaryOptions) {
         pointer = pointer.parent;
       }
 
+      // Support `nested-property:value { property: value};
+      while (
+        pointer &&
+        isType(pointer, "decl") &&
+        pointer.isNested &&
+        pointer.prop
+      ) {
+        prop = pointer.prop + "-" + prop;
+        pointer = pointer.parent;
+      }
+
       if (allValidProperties.has(prop.toLowerCase())) {
         return;
       }
diff --git a/src/rules/selector-no-redundant-nesting-selector/index.js b/src/rules/selector-no-redundant-nesting-selector/index.js
index d98a635..a02ad96 100644
--- a/src/rules/selector-no-redundant-nesting-selector/index.js
+++ b/src/rules/selector-no-redundant-nesting-selector/index.js
@@ -39,6 +39,10 @@ function rule(actual, options) {
     }
 
     root.walkRules(/&/, rule => {
+      if (rule.selector === "&") {
+        return;
+      }
+
       parseSelector(rule.selector, result, rule, fullSelector => {
         // "Ampersand followed by a combinator followed by non-combinator non-ampersand and not the selector end"
         fullSelector.walkNesting(node => {
diff --git a/src/utils/atKeywords.js b/src/utils/atKeywords.js
new file mode 100644
index 0000000..3b5147a
--- /dev/null
+++ b/src/utils/atKeywords.js
@@ -0,0 +1,62 @@
+"use strict";
+
+const uniteSets = require("../utils/uniteSets.js");
+
+// https://www.w3.org/TR/css-nesting-1/#conditionals
+const nestingSupportedAtKeywords = new Set([
+  "container",
+  "layer",
+  "media",
+  "scope",
+  "starting-style",
+  "supports"
+]);
+
+// https://www.w3.org/TR/css-page-3/#syntax-page-selector
+const pageMarginAtKeywords = new Set([
+  "top-left-corner",
+  "top-left",
+  "top-center",
+  "top-right",
+  "top-right-corner",
+  "bottom-left-corner",
+  "bottom-left",
+  "bottom-center",
+  "bottom-right",
+  "bottom-right-corner",
+  "left-top",
+  "left-middle",
+  "left-bottom",
+  "right-top",
+  "right-middle",
+  "right-bottom"
+]);
+
+// https://developer.mozilla.org/en/docs/Web/CSS/At-rule
+const atKeywords = uniteSets(nestingSupportedAtKeywords, pageMarginAtKeywords, [
+  "annotation",
+  "apply",
+  "character-variant",
+  "charset",
+  "counter-style",
+  "custom-media",
+  "custom-selector",
+  "document",
+  "font-face",
+  "font-feature-values",
+  "import",
+  "keyframes",
+  "namespace",
+  "nest",
+  "ornaments",
+  "page",
+  "property",
+  "scroll-timeline",
+  "styleset",
+  "stylistic",
+  "swash",
+  "viewport"
+]);
+
+exports.atKeywords = atKeywords;
+exports.nestingSupportedAtKeywords = nestingSupportedAtKeywords;
diff --git a/src/utils/functions.js b/src/utils/functions.js
index 24f61ae..63c8b77 100644
--- a/src/utils/functions.js
+++ b/src/utils/functions.js
@@ -41,6 +41,7 @@ const COLOR_FUNCTIONS = Object.freeze([
   "color.blackness",
   "color.blue",
   "color.change",
+  "color.channel",
   "color.complement",
   "color.grayscale",
   "color.green",
diff --git a/src/utils/getDeclarationValue.js b/src/utils/getDeclarationValue.js
new file mode 100644
index 0000000..7cbd577
--- /dev/null
+++ b/src/utils/getDeclarationValue.js
@@ -0,0 +1,13 @@
+"use strict";
+
+/**
+ * @param {import('postcss').Declaration} decl
+ * @returns {string}
+ */
+function getDeclarationValue(decl) {
+  const raws = decl.raws;
+
+  return (raws.value && raws.value.raw) || decl.value;
+}
+
+module.exports = getDeclarationValue;
diff --git a/src/utils/isStandardSyntaxValue.js b/src/utils/isStandardSyntaxValue.js
new file mode 100644
index 0000000..af097fd
--- /dev/null
+++ b/src/utils/isStandardSyntaxValue.js
@@ -0,0 +1,54 @@
+"use strict";
+
+const hasInterpolation = require("./hasInterpolation.js");
+
+/**
+ * Check whether a value is standard
+ *
+ * @param {string} value
+ * @returns {boolean}
+ */
+function isStandardSyntaxValue(value) {
+  let normalizedValue = value;
+
+  // Ignore operators before variables (example -$variable)
+  if (/^[-+*/]/.test(value.charAt(0))) {
+    normalizedValue = normalizedValue.slice(1);
+  }
+
+  // SCSS variable (example $variable)
+  if (normalizedValue.startsWith("$")) {
+    return false;
+  }
+
+  // SCSS namespace (example namespace.$variable)
+  if (/^.+\.\$/.test(value)) {
+    return false;
+  }
+
+  // SCSS namespace (example namespace.function-name())
+  if (/^.+\.[-\w]+\(/.test(value)) {
+    return false;
+  }
+
+  // Less variable
+  if (normalizedValue.startsWith("@")) {
+    return false;
+  }
+
+  // SCSS or Less interpolation
+  if (hasInterpolation(normalizedValue)) {
+    return false;
+  }
+
+  // WebExtension replacement keyword used by Chrome/Firefox
+  // more information: https://developer.chrome.com/extensions/i18n
+  // and https://github.com/stylelint/stylelint/issues/4707
+  if (/__MSG_\S+__/.test(value)) {
+    return false;
+  }
+
+  return true;
+}
+
+module.exports = isStandardSyntaxValue;
diff --git a/src/utils/sassValueParser/index.js b/src/utils/sassValueParser/index.js
index 782881f..5831d23 100644
--- a/src/utils/sassValueParser/index.js
+++ b/src/utils/sassValueParser/index.js
@@ -366,6 +366,10 @@ function checkMinus(string, index) {
   const isPrecedingOperator_ = isPrecedingOperator(string, index);
   const isInsideFunctionCall_ = isInsideFunctionCall(string, index);
 
+  if (isComparisonOperatorBefore(before)) {
+    return "sign";
+  }
+
   if (isAtStart_) {
     // console.log("-, -<sth> or - <sth>")
     return "sign";
@@ -974,6 +978,10 @@ function isFunctionAfter(after) {
   return result;
 }
 
+function isComparisonOperatorBefore(before) {
+  return before.search(/([><=!]=|[<>])\s+$/) !== -1;
+}
+
 /**
  * Checks if the input string is a hex color value
  *
diff --git a/src/utils/typeGuards.js b/src/utils/typeGuards.js
new file mode 100644
index 0000000..0b74c4d
--- /dev/null
+++ b/src/utils/typeGuards.js
@@ -0,0 +1,104 @@
+"use strict";
+
+/** @typedef {import('postcss').Node} Node */
+/** @typedef {import('postcss').Source} NodeSource */
+
+/**
+ * @param {Node} node
+ * @returns {node is import('postcss').Root}
+ */
+function isRoot(node) {
+  return node.type === "root";
+}
+
+/**
+ * @param {Node} node
+ * @returns {node is import('postcss').Rule}
+ */
+function isRule(node) {
+  return node.type === "rule";
+}
+
+/**
+ * @param {Node} node
+ * @returns {node is import('postcss').AtRule}
+ */
+function isAtRule(node) {
+  return node.type === "atrule";
+}
+
+/**
+ * @param {Node} node
+ * @returns {node is import('postcss').Comment}
+ */
+function isComment(node) {
+  return node.type === "comment";
+}
+
+/**
+ * @param {Node} node
+ * @returns {node is import('postcss').Declaration}
+ */
+function isDeclaration(node) {
+  return node.type === "decl";
+}
+
+/**
+ * @param {Node} node
+ * @returns {node is import('postcss').Document}
+ */
+function isDocument(node) {
+  return node.type === "document";
+}
+
+/**
+ * @param {import('postcss-value-parser').Node} node
+ * @returns {node is import('postcss-value-parser').DivNode}
+ */
+function isValueDiv(node) {
+  return node.type === "div";
+}
+
+/**
+ * @param {import('postcss-value-parser').Node} node
+ * @returns {node is import('postcss-value-parser').FunctionNode}
+ */
+function isValueFunction(node) {
+  return node.type === "function";
+}
+
+/**
+ * @param {import('postcss-value-parser').Node} node
+ * @returns {node is import('postcss-value-parser').SpaceNode}
+ */
+function isValueSpace(node) {
+  return node.type === "space";
+}
+
+/**
+ * @param {import('postcss-value-parser').Node} node
+ * @returns {node is import('postcss-value-parser').WordNode}
+ */
+function isValueWord({ type }) {
+  return type === "word";
+}
+
+/**
+ * @param {Node} node
+ * @returns {node is (Node & {source: NodeSource})}
+ */
+function hasSource(node) {
+  return Boolean(node.source);
+}
+
+exports.hasSource = hasSource;
+exports.isAtRule = isAtRule;
+exports.isComment = isComment;
+exports.isDeclaration = isDeclaration;
+exports.isDocument = isDocument;
+exports.isRoot = isRoot;
+exports.isRule = isRule;
+exports.isValueDiv = isValueDiv;
+exports.isValueFunction = isValueFunction;
+exports.isValueSpace = isValueSpace;
+exports.isValueWord = isValueWord;
diff --git a/src/utils/uniteSets.js b/src/utils/uniteSets.js
new file mode 100644
index 0000000..722619f
--- /dev/null
+++ b/src/utils/uniteSets.js
@@ -0,0 +1,13 @@
+"use strict";
+
+/**
+ * Unite two or more sets
+ *
+ * @param {Iterable<string>[]} args
+ * @see {@link https://github.com/microsoft/TypeScript/issues/57228|GitHub}
+ */
+function uniteSets(...args) {
+  return new Set([...args].reduce((result, set) => [...result, ...set], []));
+}
+
+module.exports = uniteSets;
diff --git a/src/utils/validateObjectWithArrayProps.js b/src/utils/validateObjectWithArrayProps.js
new file mode 100644
index 0000000..8eeb111
--- /dev/null
+++ b/src/utils/validateObjectWithArrayProps.js
@@ -0,0 +1,33 @@
+"use strict";
+
+const isPlainObject = require("is-plain-object");
+
+/**
+ * Check whether the variable is an object and all its properties are one or more values
+ * that satisfy the specified validator(s):
+ *
+ * @example
+ * ignoreProperties = {
+ *   value1: ["item11", "item12", "item13"],
+ *   value2: "item2",
+ * };
+ * validateObjectWithArrayProps(isString)(ignoreProperties);
+ * //=> true
+ *
+ * @typedef {(value: unknown) => boolean} Validator
+ * @param {...Validator} validators
+ * @returns {Validator}
+ */
+function validateObjectWithArrayProps(...validators) {
+  return value => {
+    if (isPlainObject.isPlainObject(value) || !value) {
+      return false;
+    }
+
+    return Object.values(value)
+      .flat()
+      .every(item => validators.some(v => v(item)));
+  };
+}
+
+module.exports = validateObjectWithArrayProps;
diff --git a/src/utils/validateTypes.js b/src/utils/validateTypes.js
index 0610c75..bdc4d38 100644
--- a/src/utils/validateTypes.js
+++ b/src/utils/validateTypes.js
@@ -36,9 +36,47 @@ function isString(value) {
   return typeof value === "string" || value instanceof String;
 }
 
+/**
+ * Checks if the value is a function
+ * @param {unknown} value
+ * @returns {value is Function}
+ */
+function isFunctionCall(value) {
+  const functionCallPattern = /[a-zA-Z0-9_-]+\s*\(\s*(.*)\s*\)/g;
+  return functionCallPattern.test(value);
+}
+
+/**
+ * Checks if the value is a if statement.
+ * @param {unknown} value
+ * @returns {value is IfStatement}
+ */
+function isIfStatement(value) {
+  const ifStatementPattern = /if\s*\(\s*(.*)\s*\)/g;
+  return ifStatementPattern.test(value);
+}
+
+/**
+ * Checks if the value is a ${var-name}.
+ * @param {unknown} value
+ * @returns {value is variable}
+ */
+const isDollarVar = value => value.length > 0 && value[0] === "$";
+
+/**
+ * Checks if the selector is nested property.
+ * @param {unknown} selector
+ * @returns {selector is variable}
+ */
+const isNestedProperty = selector => selector[selector.length - 1] === ":";
+
 module.exports = {
   isBoolean,
   isNumber,
   isRegExp,
-  isString
+  isString,
+  isFunctionCall,
+  isDollarVar,
+  isIfStatement,
+  isNestedProperty
 };


Test patch:
diff --git a/src/rules/declaration-property-value-no-unknown/__tests__/index.js b/src/rules/declaration-property-value-no-unknown/__tests__/index.js
new file mode 100644
index 0000000..c80cfe3
--- /dev/null
+++ b/src/rules/declaration-property-value-no-unknown/__tests__/index.js
@@ -0,0 +1,646 @@
+"use strict";
+
+const { ruleName, messages } = require("..");
+const { stripIndent } = require("common-tags");
+
+testRule({
+  ruleName,
+  config: true,
+
+  accept: [
+    {
+      code: "a { top: 0; }"
+    },
+    {
+      code: "a { @starting-style { opacity: 0; } }"
+    },
+    {
+      code: "a { @media screen { top: 0; } }"
+    },
+    {
+      code: "a { margin: auto 10em; }"
+    },
+    {
+      code: "a { margin-inline: calc(100% - 10px); }"
+    },
+    {
+      code: "a { top: var(--foo); }"
+    },
+    {
+      code: "a { top: env(titlebar-area-height); }"
+    },
+    {
+      code: "a { foo: 1px; }"
+    },
+    {
+      code: "a { --foo: 1px; }"
+    },
+    {
+      code: "a { color: lightgrey; }"
+    },
+    {
+      code: "a { color: lightgray; }"
+    },
+    {
+      code: "a { display: -moz-inline-stack; }"
+    },
+    {
+      code: "a { color: -moz-initial; }"
+    },
+    {
+      code: "a { font-size: clamp(1rem, 1vw + 1rem, 3rem); }"
+    },
+    {
+      code: "a { font-size: min(1rem, 3rem); }"
+    },
+    {
+      code: "a { font-size: max(1rem, 3rem); }"
+    },
+    {
+      code: "a { word-break: auto-phrase; }"
+    },
+    {
+      code: "a { overflow: overlay; }"
+    },
+    {
+      code: "a { width: min-intrinsic; }"
+    },
+    {
+      code: "a { view-timeline: --bar x; }"
+    },
+    {
+      code: "a { view-timeline: --qux inline 1px 2px; }"
+    },
+    {
+      code: "a { anchor-name: --bar, --qux; }"
+    },
+    {
+      code: stripIndent`
+				a { font-weight: bolder; }
+				@font-face { font-weight: 100 200; }
+			`,
+      description:
+        "at-rule descriptor and property with the same name but different syntaxes"
+    },
+    {
+      code: stripIndent`
+				a { --foo: red; }
+
+				@property --foo {
+					syntax: "<color>";
+					inherits: false;
+					initial-value: #c0ffee;
+				}
+			`
+    },
+    {
+      code: stripIndent`
+				a { --foo: 10px; }
+				a { --foo: 10%; }
+
+				@property --foo {
+					syntax: "<length> | <percentage>";
+					inherits: false;
+					initial-value: 10px;
+				}
+			`
+    },
+    {
+      code: stripIndent`
+				a { --foo: bigger; }
+				a { --foo: BIGGER; }
+
+				@property --foo {
+					syntax: "big | bigger | BIGGER";
+					inherits: false;
+					initial-value: big;
+				}
+			`
+    },
+    {
+      code: stripIndent`
+				a { --foo: 10px; }
+				a { --foo: 10px 10vh; }
+
+				@property --foo {
+					syntax: "<length>+";
+					inherits: false;
+					initial-value: 10px;
+				}
+			`
+    },
+    {
+      code: stripIndent`
+				a { --foo: red; }
+				a { --foo: 10px 10vh; }
+
+				@property --foo {
+					syntax: "*";
+					inherits: false;
+					initial-value: 10px;
+				}
+			`
+    },
+    {
+      code: stripIndent`
+				a { --foo: var(--bar); }
+				@property --foo {
+					syntax: "<color>";
+					inherits: false;
+					initial-value: #c0ffee;
+				}
+			`
+    },
+    {
+      code: stripIndent`a {
+				top: /* stylelint-disable-next-line scss/declaration-property-value-no-unknown */
+					red;
+			}`
+    },
+    {
+      code: `
+      @function get-color() {
+        @return #336699;
+      }
+      .element {
+        color: get-color();
+      }
+    `,
+      description: "Function call as value"
+    },
+    {
+      code: `
+      @function get-color() {
+        @return #336699;
+      }
+      .element {
+        backround: border-box get-color();
+      }
+    `,
+      description: "Function call as value in shorthand format"
+    },
+    {
+      code: `
+      $var1: 1px;
+      a {
+        margin: 2px $var1;
+      }
+    `,
+      description: "SCSS variable as value"
+    },
+    {
+      code: `
+      $rounded-corners: false;
+      .button {
+        border-radius: if($rounded-corners, 5px, null);
+      }
+    `,
+      description: "Hidden declarations as value"
+    },
+    {
+      code: `
+      a {
+        margin: 3px + 10px;
+      }
+      `,
+      description: "Plus operator"
+    },
+    {
+      code: `
+      a {
+        margin: 3px - 10px;
+      }
+      `,
+      description: "Less operator"
+    },
+    {
+      code: `
+      a {
+        margin: 1 + 2 * 3 == 1 + (2 * 3);
+      }
+      `,
+      description: "Several operators"
+    },
+    {
+      code: `
+      a {
+        padding: 1px +2px;
+      }
+      `,
+      description: "Several operators"
+    },
+    {
+      code: `
+      .transparent-blue {
+        filter: opacity(10% + 25%);
+      }
+      `,
+      description: "Operators as function arguments"
+    },
+    {
+      code: `
+      $var1: minmax($var1, max-content);
+      a {
+        grid-template-columns: repeat(
+          auto-fit,
+          $var1
+        );
+      }`,
+      description: "Var as argument in function"
+    },
+    {
+      code: `
+      $var1: 3px;
+      a {
+        grid-template-columns: repeat(
+          auto-fit,
+          minmax($var1, max-content)
+        );
+      }`,
+      description: "Var as argument in nested functions"
+    },
+    {
+      code: `
+        background: transparent
+        linear-gradient(
+          to right,
+          rgba($mat-gray-300, 0) 0%,
+          rgba($mat-gray-300, 0.2) 20%,
+          rgba($mat-gray-300, 0.5) 50%,
+          rgba($mat-gray-300, 0.2) 80%,
+          rgba($mat-gray-300, 0) 100%
+        )
+        repeat-y;`,
+      description: "Function call in shorthand format"
+    }
+  ],
+
+  reject: [
+    {
+      code: "a { text-box-edge: text ex; }",
+      message: messages.rejected("text-box-edge", "ex"),
+      line: 1,
+      column: 25,
+      endLine: 1,
+      endColumn: 27
+    },
+    {
+      code: "a { text-box-trim: foo; }",
+      message: messages.rejected("text-box-trim", "foo"),
+      line: 1,
+      column: 20,
+      endLine: 1,
+      endColumn: 23
+    },
+    {
+      code: "a { text-spacing-trim: bar; }",
+      message: messages.rejected("text-spacing-trim", "bar"),
+      line: 1,
+      column: 24,
+      endLine: 1,
+      endColumn: 27
+    },
+    {
+      code: "a { text-wrap: foo; }",
+      message: messages.rejected("text-wrap", "foo"),
+      line: 1,
+      column: 16,
+      endLine: 1,
+      endColumn: 19
+    },
+    {
+      code: "a { view-timeline-name: foo; }",
+      message: messages.rejected("view-timeline-name", "foo"),
+      line: 1,
+      column: 25,
+      endLine: 1,
+      endColumn: 28
+    },
+    {
+      code: "a { view-transition-name:; }",
+      message: messages.rejected("view-transition-name", ""),
+      line: 1,
+      column: 26,
+      endLine: 1,
+      endColumn: 27
+    },
+    {
+      code: "a { anchor-name: foo; }",
+      message: messages.rejected("anchor-name", "foo"),
+      line: 1,
+      column: 18,
+      endLine: 1,
+      endColumn: 21
+    },
+    {
+      code: "a { field-sizing: bar; }",
+      message: messages.rejected("field-sizing", "bar"),
+      line: 1,
+      column: 19,
+      endLine: 1,
+      endColumn: 22
+    },
+    {
+      code: "a { top: unknown; }",
+      message: messages.rejected("top", "unknown"),
+      line: 1,
+      column: 10,
+      endLine: 1,
+      endColumn: 17
+    },
+    {
+      code: "a { @media screen { top: unknown; } }",
+      message: messages.rejected("top", "unknown"),
+      line: 1,
+      column: 26,
+      endLine: 1,
+      endColumn: 33
+    },
+    {
+      code: "a { @starting-style { padding: auto; } }",
+      message: messages.rejected("padding", "auto"),
+      line: 1,
+      column: 32,
+      endLine: 1,
+      endColumn: 36
+    },
+    {
+      code: "a { top: red; }",
+      message: messages.rejected("top", "red"),
+      line: 1,
+      column: 10,
+      endLine: 1,
+      endColumn: 13
+    },
+    {
+      code: stripIndent`a {
+				top: /* a comment */
+					red;
+			}`,
+      message: messages.rejected("top", "red"),
+      line: 3,
+      column: 6,
+      endLine: 3,
+      endColumn: 9
+    },
+    {
+      code: "a { color: ; }",
+      message: messages.rejected("color", ""),
+      line: 1,
+      column: 12,
+      endLine: 1,
+      endColumn: 13
+    },
+    {
+      code: "a { padding: auto; }",
+      message: messages.rejected("padding", "auto"),
+      line: 1,
+      column: 14,
+      endLine: 1,
+      endColumn: 18
+    },
+    {
+      code: "a { display: fixed }",
+      message: messages.rejected("display", "fixed"),
+      line: 1,
+      column: 14,
+      endLine: 1,
+      endColumn: 19
+    },
+    {
+      code: "a { color: rgb(67 67 67 70%); }",
+      message: messages.rejected("color", "70%"),
+      line: 1,
+      column: 25,
+      endLine: 1,
+      endColumn: 28
+    },
+    {
+      code: "a { transition: background-color 0.6s ease-in-out 0; }",
+      message: messages.rejected("transition", "0"),
+      line: 1,
+      column: 51,
+      endLine: 1,
+      endColumn: 52
+    },
+    {
+      code: 'a { margin-top: "10px"; }',
+      message: messages.rejected("margin-top", '"10px"'),
+      line: 1,
+      column: 17,
+      endLine: 1,
+      endColumn: 23
+    },
+    {
+      code: "a { color: greem; }",
+      message: messages.rejected("color", "greem"),
+      line: 1,
+      column: 12,
+      endLine: 1,
+      endColumn: 17
+    },
+    {
+      code: "a { filter: alpha(opacity=30); }",
+      message: messages.rejectedParseError("filter", "alpha(opacity=30)"),
+      line: 1,
+      column: 13,
+      endLine: 1,
+      endColumn: 30
+    },
+    {
+      code: `
+        a {
+          color: red;
+          font: {
+            size: red;
+          }
+        }
+      `,
+      message: messages.rejected("font-size", "red"),
+      line: 4,
+      column: 11,
+      endLine: 6,
+      endColumn: 12
+    },
+    // {
+    // 	code: stripIndent`
+    // 		a { --foo: 10px; }
+    // 		@property --foo {
+    // 			syntax: "<color>";
+    // 			inherits: false;
+    // 			initial-value: #c0ffee;
+    // 		}
+    // 	`,
+    // 	message: messages.rejected('--foo', '10px'),
+    // 	line: 1,
+    // 	column: 12,
+    // 	endLine: 1,
+    // 	endColumn: 16,
+    // },
+    {
+      code: stripIndent`
+				a { --foo: 10px; }
+				@property --foo {
+					syntax: not-a-string;
+					inherits: false;
+					initial-value: #c0ffee;
+				}
+			`,
+      message: messages.rejected("syntax", "not-a-string"),
+      line: 3,
+      column: 10,
+      endLine: 3,
+      endColumn: 22
+    },
+    {
+      code: 'a { font-family: "Foo" serif; }',
+      message: messages.rejected("font-family", "serif"),
+      line: 1,
+      column: 24,
+      endLine: 1,
+      endColumn: 29
+    },
+    {
+      code: 'a { font-family: "Foo"  serif; }',
+      message: messages.rejected("font-family", "serif"),
+      line: 1,
+      column: 25,
+      endLine: 1,
+      endColumn: 30
+    }
+  ]
+});
+
+testRule({
+  ruleName,
+  config: [
+    true,
+    {
+      ignoreProperties: {
+        top: "/.+/",
+        padding: ["auto"],
+        "/.+/": /--foo/
+      }
+    }
+  ],
+
+  accept: [
+    {
+      code: "a { top: 0; }"
+    },
+    {
+      code: "a { top: red; }"
+    },
+    {
+      code: "a { padding: auto; }"
+    },
+    {
+      code: "a { margin: 10px --foo; }"
+    }
+  ],
+
+  reject: [
+    {
+      code: "a { color: 1; }",
+      message: messages.rejected("color", "1"),
+      line: 1,
+      column: 12,
+      endLine: 1,
+      endColumn: 13
+    },
+    {
+      code: "a { padding-left: auto; }",
+      message: messages.rejected("padding-left", "auto"),
+      line: 1,
+      column: 19,
+      endLine: 1,
+      endColumn: 23
+    },
+    {
+      code: "a { padding: 10px --bar; }",
+      message: messages.rejected("padding", "--bar"),
+      line: 1,
+      column: 19,
+      endLine: 1,
+      endColumn: 24
+    }
+  ]
+});
+
+testRule({
+  ruleName,
+  config: [true, { propertiesSyntax: { size: "<length-percentage>" } }],
+
+  accept: [
+    {
+      code: "a { size: 10px; }"
+    }
+  ],
+
+  reject: [
+    {
+      code: "a { size: red; }",
+      message: messages.rejected("size", "red"),
+      line: 1,
+      column: 11,
+      endLine: 1,
+      endColumn: 14
+    }
+  ]
+});
+
+testRule({
+  ruleName,
+  config: [
+    true,
+    {
+      propertiesSyntax: { top: "| <--foo()>" },
+      typesSyntax: { "--foo()": "--foo( <length-percentage> )" }
+    }
+  ],
+
+  accept: [
+    {
+      code: "a { top: 10px; }"
+    },
+    {
+      code: "a { top: --foo(5px); }"
+    }
+  ],
+
+  reject: [
+    {
+      code: "a { top: red; }",
+      message: messages.rejected("top", "red"),
+      line: 1,
+      column: 10,
+      endLine: 1,
+      endColumn: 13
+    }
+  ]
+});
+
+testRule({
+  ruleName,
+  config: true,
+  customSyntax: "postcss-scss",
+
+  accept: [
+    {
+      code: "a { $foo: bar; }"
+    },
+    {
+      code: "a { top: #{foo}; }"
+    },
+    {
+      // https://github.com/stylelint/stylelint/issues/7403
+      code: stripIndent`
+				a {
+					top: #{
+						foo
+					};
+				}
+			`
+    }
+  ]
+});
diff --git a/src/rules/function-unquote-no-unquoted-strings-inside/__tests__/index.js b/src/rules/function-unquote-no-unquoted-strings-inside/__tests__/index.js
index 8bec538..9e57734 100644
--- a/src/rules/function-unquote-no-unquoted-strings-inside/__tests__/index.js
+++ b/src/rules/function-unquote-no-unquoted-strings-inside/__tests__/index.js
@@ -68,6 +68,24 @@ testRule({
           font-family: $font;
         }
       `
+    },
+    {
+      code: `
+      a {
+        border: outset unquote(#f33);
+      }
+      `,
+      description: "#1040",
+      message: messages.rejected,
+      line: 3,
+      column: 24,
+      endLine: 3,
+      endColumn: 31,
+      fixed: `
+      a {
+        border: outset #f33;
+      }
+      `
     }
   ]
 });
diff --git a/src/rules/operator-no-unspaced/__tests__/index.js b/src/rules/operator-no-unspaced/__tests__/index.js
index ff9e937..eadf486 100644
--- a/src/rules/operator-no-unspaced/__tests__/index.js
+++ b/src/rules/operator-no-unspaced/__tests__/index.js
@@ -649,6 +649,23 @@ testRule({
     {
       code: "a { inset: -#{$top} -#{$right} -#{$bottom} -#{$left}; }",
       description: "issue #286"
+    },
+    {
+      code: `
+      $lhs: 1;
+      $rhs: 2;
+
+      // https://sass-lang.com/documentation/operators/equality/
+      @if $lhs == -$rhs {}
+      @if $lhs != -$rhs {}
+
+      // https://sass-lang.com/documentation/operators/relational/
+      @if $lhs <= -$rhs {}
+      @if $lhs >= -$rhs {}
+      @if $lhs < -$rhs {}
+      @if $lhs > -$rhs {}
+      `,
+      description: "issue #286"
     }
   ],
 
diff --git a/src/rules/property-no-unknown/__tests__/index.js b/src/rules/property-no-unknown/__tests__/index.js
index 8ff713e..4f5db78 100644
--- a/src/rules/property-no-unknown/__tests__/index.js
+++ b/src/rules/property-no-unknown/__tests__/index.js
@@ -2,6 +2,24 @@
 
 const { messages, ruleName } = require("..");
 
+testRule({
+  ruleName,
+  config: [true],
+  customSyntax: "postcss-scss",
+
+  accept: [
+    {
+      code: `
+      button {
+        border: none {
+            block-end: 2px solid red;
+        }
+      }
+      `
+    }
+  ]
+});
+
 testRule({
   ruleName,
   config: [true],
diff --git a/src/rules/selector-no-redundant-nesting-selector/__tests__/index.js b/src/rules/selector-no-redundant-nesting-selector/__tests__/index.js
index aea71a4..ec19b27 100644
--- a/src/rules/selector-no-redundant-nesting-selector/__tests__/index.js
+++ b/src/rules/selector-no-redundant-nesting-selector/__tests__/index.js
@@ -163,6 +163,43 @@ testRule({
       }
       `,
       description: ":where, followed by a pseudo-element selector, issue #1000"
+    },
+    {
+      code: `
+      .example {
+        color: red;
+
+        a {
+          font-weight: bold;
+        }
+
+        & {
+          font-weight: normal;
+        }
+      }
+      `,
+      description:
+        "Dart Sass 1.77.7: https://sass-lang.com/documentation/breaking-changes/mixed-decls/"
+    },
+    {
+      code: `
+      p {
+        & {}
+      }
+    `,
+      description:
+        "when an ampersand is used by itself." +
+        "Dart Sass 1.77.7: https://sass-lang.com/documentation/breaking-changes/mixed-decls/"
+    },
+    {
+      code: `
+      p {
+          &   {}
+      }
+    `,
+      description:
+        "when an ampersand is used by itself and there are extra spaces." +
+        "Dart Sass 1.77.7: https://sass-lang.com/documentation/breaking-changes/mixed-decls/"
     }
   ],
 
@@ -328,27 +365,6 @@ testRule({
       message: messages.rejected,
       description: "ampersand followed by newline and tag selector"
     },
-    {
-      code: `
-      p {
-        & {}
-      }
-    `,
-      line: 3,
-      message: messages.rejected,
-      description: "when an ampersand is used by itself"
-    },
-    {
-      code: `
-      p {
-          &   {}
-      }
-    `,
-      line: 3,
-      message: messages.rejected,
-      description:
-        "when an ampersand is used by itself and there are extra spaces"
-    },
     {
       code: `
       .a {