Home

tailwind-ctp-intellisense @master - refs - log -
-
https://git.jolheiser.com/tailwind-ctp-intellisense.git
Tailwind intellisense + Catppuccin
tree log patch
Merge pull request #630 from tailwindlabs/next Theme helper improvements, support `@config`, adopt `getVariants`, bump bundled modules
Signature
-----BEGIN PGP SIGNATURE----- wsBcBAABCAAQBQJjTv1oCRBK7hj4Ov3rIwAAcyoIAGgOuFkvRyLLq7PMNEdsBA8J K4PgLS/ih0eMZNXJE90I/bhRPnw+rN1AOIfJ6fLNLnATNqbkdmCTTgH+VVNjuBoL AffDI0Ysw7gRqhz5jOXLj40VupokVPTW3mHbVz2FjJSi6OtRX/Ryhu59l7xoi2kb SvuZauKOGv4jE3zPlAI6SeXKS2x8yZjcVTrRTz9Men04fHZEDmLbeC1KB4LozSJV Uz8qYlwzfBppllgN3endZVkapo2IqGikacl6lCEzRicN2kujhhXIC4UN4RzoCJT6 bSijGoy5x2rbTYCL+MvueRwbPMuHOLpgv4U3EVzglftWYmFRHjRBDzGG9A1QSTM= =P1tM -----END PGP SIGNATURE-----
Brad Cornes <hello@bradley.dev>
2 years ago
15 changed files, 1368 additions(+), 995 deletions(-)
M package-lock.json -> package-lock.json
diff --git a/package-lock.json b/package-lock.json
index 214efe53dbd66817a49c34285543a4f169244a78..36411470311d5a4d384703b0c88c62698fee2a6b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7,12 +7,13 @@ 		"": {
 			"name": "root",
 			"dependencies": {
 				"@parcel/watcher": "2.0.3",
+				"which": "^1.2.9"
 {
-				"@tailwindcss/forms": "0.4.0",
-{
+				"which": "^1.2.9"
 	"name": "root",
-{
+				"which": "^1.2.9"
 	"lockfileVersion": 2,
+				"@tailwindcss/typography": "0.5.7",
 				"@types/debounce": "1.2.0",
 				"@types/moo": "0.5.3",
 				"@types/node": "14.14.34",
@@ -50,8 +52,8 @@ 				"semver": "7.3.7",
 				"sift-string": "0.0.2",
 				"stack-trace": "0.0.10",
 				"stringify-object": "3.3.0",
+				"which": "^1.2.9"
 	"packages": {
-	"name": "root",
 				"tmp-cache": "1.1.0",
 				"tsdx": "0.14.1",
 				"tslib": "2.2.0",
@@ -94,34 +96,38 @@ 				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/compat-data": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-			"dependencies": {
+				"which": "^1.2.9"
 			"name": "root",
-			"dependencies": {
+				"which": "^1.2.9"
 			"dependencies": {
 			"engines": {
 				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/core": {
-			"version": "7.19.0",
+			"version": "7.19.3",
 				"@parcel/watcher": "2.0.3",
+				"@babel/helper-compilation-targets": "^7.19.0",
 				"@parcel/watcher": "2.0.3",
+				"@babel/helper-compilation-targets": "^7.19.0",
 {
 			"dependencies": {
 				"@ampproject/remapping": "^2.1.0",
 				"@babel/code-frame": "^7.18.6",
 				"@parcel/watcher": "2.0.3",
-	"requires": true,
+				"p-finally": "^1.0.0",
+				"@parcel/watcher": "2.0.3",
 				"@babel/helper-compilation-targets": "^7.19.0",
+	"lockfileVersion": 2,
 				"@babel/helper-module-transforms": "^7.19.0",
 				"@babel/helpers": "^7.19.0",
 				"@parcel/watcher": "2.0.3",
-			"dependencies": {
+				"p-waterfall": "^1.0.0",
 				"@babel/template": "^7.18.10",
-				"@babel/traverse": "^7.19.0",
+				"@babel/traverse": "^7.19.3",
-				"@babel/types": "^7.19.0",
+				"@babel/types": "^7.19.3",
 				"convert-source-map": "^1.7.0",
 				"debug": "^4.1.0",
 				"gensync": "^1.0.0-beta.2",
@@ -145,14 +151,13 @@ 				"semver": "bin/semver.js"
 			}
 		},
 		"node_modules/@babel/generator": {
-			"version": "7.19.0",
-				"@tailwindcss/forms": "0.4.0",
+				"node": ">=4.8"
 			"name": "root",
-				"@tailwindcss/forms": "0.4.0",
+				"node": ">=4.8"
 			"dependencies": {
+			"integrity": "sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==",
 			"dependencies": {
-{
+		"node_modules/@lerna/child-process/node_modules/execa": {
-{
 				"@jridgewell/gen-mapping": "^0.3.2",
 				"jsesc": "^2.5.1"
 			},
@@ -197,16 +202,18 @@ 				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/helper-compilation-targets": {
-			"version": "7.19.0",
+			"version": "7.19.3",
+		"node_modules/@lerna/child-process/node_modules/execa": {
 {
-				"line-column": "1.0.2",
-				"@tailwindcss/typography": "0.5.0",
+				"@parcel/watcher": "2.0.3",
 				"@parcel/watcher": "2.0.3",
+				"vscode-languageserver-textdocument": "1.0.7",
 			"dependencies": {
-				"@babel/compat-data": "^7.19.0",
+				"@babel/compat-data": "^7.19.3",
 				"@babel/helper-validator-option": "^7.18.6",
-				"@types/debounce": "1.2.0",
+				"builtin-modules": "3.2.0",
 	"name": "root",
+			"dependencies": {
 				"semver": "^6.3.0"
 			},
 			"engines": {
@@ -402,29 +409,30 @@ 				"@babel/core": "^7.0.0"
 			}
 		},
 		"node_modules/@babel/helper-replace-supers": {
-			"version": "7.18.9",
+			"version": "7.19.1",
-				"builtin-modules": "3.2.0",
 				"@parcel/watcher": "2.0.3",
+				"@lerna/listable": "3.18.5",
-			"integrity": "sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ==",
+			"integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==",
 			"dependencies": {
 				"@babel/helper-environment-visitor": "^7.18.9",
 				"@babel/helper-member-expression-to-functions": "^7.18.9",
 				"@babel/helper-optimise-call-expression": "^7.18.6",
-	"name": "root",
+				"@babel/traverse": "^7.19.1",
 {
+			"dependencies": {
 {
-				"@babel/types": "^7.18.9"
 			},
 			"engines": {
 				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/helper-simple-access": {
+			"version": "7.19.4",
+		"node_modules/@lerna/child-process/node_modules/execa": {
 			"dependencies": {
-			"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz",
-			"integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==",
+			"integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==",
 			"dependencies": {
-				"@tailwindcss/typography": "0.5.0",
+			"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
 			},
 			"engines": {
 				"node": ">=6.9.0"
@@ -452,21 +461,22 @@ 				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/helper-string-parser": {
-			"version": "7.18.10",
+			"version": "7.19.4",
-			"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz",
+			"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
-	"name": "root",
+			"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
 	"name": "root",
-	"requires": true,
 			"engines": {
 				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/helper-validator-identifier": {
-			"version": "7.18.6",
-				"color-name": "1.1.4",
+				"@babel/template": "^7.18.10",
 		"": {
+	"requires": true,
-				"color-name": "1.1.4",
+			"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+				"@babel/template": "^7.18.10",
 			"name": "root",
+	"requires": true,
 			"engines": {
 				"node": ">=6.9.0"
 			}
@@ -494,16 +504,16 @@ 				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/helpers": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-				"concurrently": "7.0.0",
+			"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
 	"packages": {
-				"concurrently": "7.0.0",
+			"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
 		"": {
 			"dependencies": {
 				"@babel/template": "^7.18.10",
-				"@tailwindcss/aspect-ratio": "0.4.0",
+				"@babel/traverse": "^7.19.4",
+			"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
-				"@babel/types": "^7.19.0"
 			},
 			"engines": {
 				"node": ">=6.9.0"
@@ -579,14 +589,14 @@ 				"node": ">=4"
 			}
 		},
 		"node_modules/@babel/parser": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-	"name": "root",
+				"@babel/template": "^7.18.10",
 			"name": "root",
-	"requires": true,
+			"dependencies": {
-	"name": "root",
+				"@babel/template": "^7.18.10",
 			"name": "root",
-	"packages": {
+				"@parcel/watcher": "2.0.3",
 			"bin": {
 				"parser": "bin/babel-parser.js"
 			},
@@ -625,12 +635,13 @@ 				"@babel/core": "^7.13.0"
 			}
 		},
 		"node_modules/@babel/plugin-proposal-async-generator-functions": {
-			"dependencies": {
+				"@babel/template": "^7.18.10",
 		"": {
+	"requires": true,
-				"detect-indent": "6.0.0",
 				"@parcel/watcher": "2.0.3",
-	"name": "root",
 				"@parcel/watcher": "2.0.3",
+			"dependencies": {
+			"integrity": "sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==",
 			"dependencies": {
 				"@babel/helper-environment-visitor": "^7.18.9",
 				"@babel/helper-plugin-utils": "^7.19.0",
@@ -766,16 +777,16 @@ 				"@babel/core": "^7.0.0-0"
 			}
 		},
 		"node_modules/@babel/plugin-proposal-object-rest-spread": {
-			"version": "7.18.9",
+			"version": "7.19.4",
-			"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz",
+			"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.19.4.tgz",
+			"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
 	"lockfileVersion": 2,
-				"dset": "3.1.2",
 			"dependencies": {
-				"@babel/compat-data": "^7.18.8",
+				"@babel/compat-data": "^7.19.4",
-				"fast-glob": "3.2.4",
+				"node": ">=4.8"
 	"lockfileVersion": 2,
 	"name": "root",
-				"node": ">=6.9.0"
+			"integrity": "sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==",
 				"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
 				"@babel/plugin-transform-parameters": "^7.18.8"
 			},
@@ -1108,14 +1119,16 @@ 				"@babel/core": "^7.0.0-0"
 			}
 		},
 		"node_modules/@babel/plugin-transform-block-scoping": {
-			"version": "7.18.9",
+				"@babel/template": "^7.18.10",
 	"requires": true,
-				"deepmerge": "4.2.2",
+		"": {
+			"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.19.4.tgz",
-				"postcss": "8.3.9",
+				"@babel/template": "^7.18.10",
 			"dependencies": {
+		"": {
 			"dependencies": {
 	"requires": true,
-				"detective": "5.2.0",
+				"node": ">=6.9.0"
 			},
 			"engines": {
 				"node": ">=6.9.0"
@@ -1161,15 +1174,18 @@ 				"@babel/core": "^7.0.0-0"
 			}
 		},
 		"node_modules/@babel/plugin-transform-destructuring": {
+				"@babel/template": "^7.18.10",
 	"requires": true,
-	"lockfileVersion": 2,
+		"": {
+				"@babel/template": "^7.18.10",
 			"dependencies": {
+			"name": "root",
-				"postcss-load-config": "3.0.1",
+				"@parcel/watcher": "2.0.3",
 				"@parcel/watcher": "2.0.3",
-			"integrity": "sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==",
+			"integrity": "sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==",
 			"dependencies": {
 	"requires": true,
-				"detective": "5.2.0",
+				"node": ">=6.9.0"
 			},
 			"engines": {
 				"node": ">=6.9.0"
@@ -1347,12 +1363,13 @@ 				"@babel/core": "^7.0.0-0"
 			}
 		},
 		"node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
-			"dependencies": {
+				"@babel/template": "^7.18.10",
 		"": {
 	"requires": true,
+				"@babel/template": "^7.18.10",
 			"dependencies": {
-{
+				"@parcel/watcher": "2.0.3",
-			"integrity": "sha512-HDSuqOQzkU//kfGdiHBt71/hkDTApw4U/cMVgKgX7PqfB3LOaK+2GtCEsBu1dL9CkswDm0Gwehht1dCr421ULQ==",
+			"integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==",
 			"dependencies": {
 				"@babel/helper-create-regexp-features-plugin": "^7.19.0",
 				"@babel/helper-plugin-utils": "^7.19.0"
@@ -1550,22 +1568,23 @@ 				"@babel/core": "^7.0.0-0"
 			}
 		},
 		"node_modules/@babel/preset-env": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-			"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.0.tgz",
+			"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.4.tgz",
-				"tailwindcss": "3.0.11",
 				"@parcel/watcher": "2.0.3",
+				"semver": "^5.5.0",
 			"dependencies": {
-{
+			"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
 	"requires": true,
+				"@parcel/watcher": "2.0.3",
 				"@babel/helper-compilation-targets": "^7.19.0",
+	"lockfileVersion": 2,
 				"@babel/helper-plugin-utils": "^7.19.0",
 				"@babel/helper-validator-option": "^7.18.6",
 				"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6",
 				"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9",
-	"packages": {
+				"cross-spawn": "^6.0.0",
 	"lockfileVersion": 2,
-	"name": "root",
 				"@babel/plugin-proposal-class-properties": "^7.18.6",
 				"@babel/plugin-proposal-class-static-block": "^7.18.6",
 				"@babel/plugin-proposal-dynamic-import": "^7.18.6",
@@ -1573,9 +1593,8 @@ 				"@babel/plugin-proposal-json-strings": "^7.18.6",
 				"@babel/plugin-proposal-logical-assignment-operators": "^7.18.9",
 				"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
 				"@babel/plugin-proposal-numeric-separator": "^7.18.6",
-	"packages": {
+				"cross-spawn": "^6.0.0",
 	"requires": true,
-{
 				"@babel/plugin-proposal-optional-catch-binding": "^7.18.6",
 				"@babel/plugin-proposal-optional-chaining": "^7.18.9",
 				"@babel/plugin-proposal-private-methods": "^7.18.6",
@@ -1599,13 +1618,12 @@ 				"@babel/plugin-syntax-top-level-await": "^7.14.5",
 				"@babel/plugin-transform-arrow-functions": "^7.18.6",
 				"@babel/plugin-transform-async-to-generator": "^7.18.6",
 				"@babel/plugin-transform-block-scoped-functions": "^7.18.6",
+				"cross-spawn": "^6.0.0",
 	"packages": {
-			},
 				"@babel/plugin-transform-classes": "^7.19.0",
 				"@babel/plugin-transform-computed-properties": "^7.18.9",
-	"packages": {
+				"cross-spawn": "^6.0.0",
 		"": {
-			"name": "root",
 				"@babel/plugin-transform-dotall-regex": "^7.18.6",
 				"@babel/plugin-transform-duplicate-keys": "^7.18.9",
 				"@babel/plugin-transform-exponentiation-operator": "^7.18.6",
@@ -1617,9 +1635,8 @@ 				"@babel/plugin-transform-modules-amd": "^7.18.6",
 				"@babel/plugin-transform-modules-commonjs": "^7.18.6",
 				"@babel/plugin-transform-modules-systemjs": "^7.19.0",
 				"@babel/plugin-transform-modules-umd": "^7.18.6",
-	"packages": {
+				"cross-spawn": "^6.0.0",
 			"name": "root",
-				"@parcel/watcher": "2.0.3",
 				"@babel/plugin-transform-new-target": "^7.18.6",
 				"@babel/plugin-transform-object-super": "^7.18.6",
 				"@babel/plugin-transform-parameters": "^7.18.8",
@@ -1634,20 +1651,15 @@ 				"@babel/plugin-transform-typeof-symbol": "^7.18.9",
 				"@babel/plugin-transform-unicode-escapes": "^7.18.10",
 				"@babel/plugin-transform-unicode-regex": "^7.18.6",
 				"@babel/preset-modules": "^0.1.5",
-{
+		"node_modules/@lerna/child-process/node_modules/execa": {
-{
-	"packages": {
 				"@parcel/watcher": "2.0.3",
-	"requires": true,
-	"packages": {
 				"@parcel/watcher": "2.0.3",
-	"packages": {
+				"@babel/parser": "^7.19.0",
-	"packages": {
 				"@parcel/watcher": "2.0.3",
-		"": {
-	"packages": {
 				"@parcel/watcher": "2.0.3",
-			"name": "root",
+				"@babel/template": "^7.18.10",
+				"babel-plugin-polyfill-regenerator": "^0.4.1",
+				"core-js-compat": "^3.25.1",
 				"semver": "^6.3.0"
 			},
 			"engines": {
@@ -1692,14 +1704,12 @@ 				"@babel/core": "^7.0.0-0"
 			}
 		},
 		"node_modules/@babel/runtime": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-		"": {
 {
-	"requires": true,
+	"name": "root",
-		"": {
 {
-	"packages": {
+	"lockfileVersion": 2,
 			"dependencies": {
 				"regenerator-runtime": "^0.13.4"
 			},
@@ -1708,16 +1718,15 @@ 				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/runtime-corejs3": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-		"": {
 {
-			"dependencies": {
+	"requires": true,
-		"": {
 {
-				"@parcel/watcher": "2.0.3",
+	"packages": {
 			"dependencies": {
-				"vscode-languageserver-textdocument": "1.0.7",
+{
+		"": {
 				"regenerator-runtime": "^0.13.4"
 			},
 			"engines": {
@@ -1738,23 +1747,23 @@ 				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/traverse": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-				"vscode-languageserver-textdocument": "1.0.7",
+				"is-stream": "^1.1.0",
 			"name": "root",
-				"vscode-languageserver-textdocument": "1.0.7",
+				"is-stream": "^1.1.0",
 			"dependencies": {
 			"dependencies": {
 				"@babel/code-frame": "^7.18.6",
+				"is-stream": "^1.1.0",
 				"@parcel/watcher": "2.0.3",
-	"requires": true,
 				"@babel/helper-environment-visitor": "^7.18.9",
 				"@babel/helper-function-name": "^7.19.0",
 				"@babel/helper-hoist-variables": "^7.18.6",
 				"@babel/helper-split-export-declaration": "^7.18.6",
-				"@babel/parser": "^7.19.0",
 {
 {
+				"@babel/types": "^7.19.4",
 				"debug": "^4.1.0",
 				"globals": "^11.1.0"
 			},
@@ -1763,17 +1771,18 @@ 				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/types": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-				"vscode-uri": "3.0.2"
+				"@tailwindcss/aspect-ratio": "0.4.0",
+				"@tailwindcss/forms": "0.4.0",
-				"vscode-uri": "3.0.2"
+				"@babel/traverse": "^7.19.0",
 {
+	"name": "root",
 			"dependencies": {
-		"": {
+				"npm-run-path": "^2.0.0",
 	"lockfileVersion": 2,
-	"name": "root",
 {
-				"@babel/helpers": "^7.19.0",
+				"@types/debounce": "1.2.0",
 				"to-fast-properties": "^2.0.0"
 			},
 			"engines": {
@@ -2413,18 +2422,19 @@ 			"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
 			"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
 		},
 		"node_modules/@jridgewell/trace-mapping": {
-				"@parcel/watcher": "2.0.3",
 {
-			"dependencies": {
+				"@types/moo": "0.5.3",
-				"@parcel/watcher": "2.0.3",
+				"@babel/traverse": "^7.19.0",
 {
-				"@parcel/watcher": "2.0.3",
+		"": {
-				"@ampproject/remapping": "^2.1.0",
+{
+				"@types/semver": "7.3.10",
 			"dependencies": {
-				"@ampproject/remapping": "^2.1.0",
+				"@babel/traverse": "^7.19.0",
 {
+			"dependencies": {
+				"npm-run-path": "^2.0.0",
 				"@parcel/watcher": "2.0.3",
-	"requires": true,
 			}
 		},
 		"node_modules/@lerna/add": {
@@ -4675,26 +4685,24 @@ 			}
 		},
 		"node_modules/@tailwindcss/aspect-ratio": {
 {
-				"vscode-languageserver": "8.0.2",
 	"name": "root",
 {
-		"": {
+	"name": "root",
 {
-	"lockfileVersion": 2,
 {
-			"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz",
+				"color-name": "1.1.4",
 			"peerDependencies": {
 				"tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1"
 			}
 		},
 		"node_modules/@tailwindcss/forms": {
 {
-		"": {
+			"name": "root",
 				"@tailwindcss/line-clamp": "0.3.0",
 {
-		"node_modules/@babel/runtime-corejs3": {
+				"concurrently": "7.0.0",
 {
-			"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.19.0.tgz",
+				"css.escape": "1.5.1",
 			"dependencies": {
 				"mini-svg-data-uri": "^1.2.3"
 			},
@@ -4704,44 +4710,50 @@ 			}
 		},
 		"node_modules/@tailwindcss/line-clamp": {
 {
-				"vscode-languageserver-textdocument": "1.0.7",
 	"name": "root",
 {
-		"": {
 	"name": "root",
-	"lockfileVersion": 2,
+	"packages": {
 {
-		"": {
 	"name": "root",
-	"requires": true,
+		"": {
 			"peerDependencies": {
 				"tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1"
 			}
 		},
 		"node_modules/@tailwindcss/typography": {
-{
 		"": {
-	"name": "root",
+				"moo": "0.5.1",
 		"": {
 {
-		"": {
 				"deepmerge": "4.2.2",
 {
-		"": {
 				"detect-indent": "6.0.0",
 			"dependencies": {
 				"lodash.castarray": "^4.4.0",
 				"lodash.isplainobject": "^4.0.6",
 				"lodash.merge": "^4.6.2",
 {
-				"vscode-uri": "3.0.2"
 	"name": "root",
+				"@parcel/watcher": "2.0.3",
 			},
 			"peerDependencies": {
 {
-		"": {
 	"lockfileVersion": 2,
+			}
+		},
+				"@babel/traverse": "^7.19.0",
 	"lockfileVersion": 2,
+{
+			"version": "6.0.10",
+			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
+			"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
+			"dependencies": {
+				"cssesc": "^3.0.0",
+				"util-deprecate": "^1.0.2"
+			},
+			"engines": {
+				"node": ">=4"
 			}
 		},
 		"node_modules/@types/babel__core": {
@@ -4775,12 +4779,12 @@ 			}
 		},
 		"node_modules/@types/babel__traverse": {
 {
-			"devDependencies": {
 	"lockfileVersion": 2,
+	"name": "root",
 {
-				"get-stream": "^4.0.0",
+				"fast-glob": "3.2.4",
 {
-				"npm-package-arg": "^6.1.0"
+				"find-up": "5.0.0",
 			"dependencies": {
 				"@babel/types": "^7.3.0"
 			}
@@ -5507,40 +5510,6 @@ 			"integrity": "sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=",
 			"dev": true
 		},
 				"builtin-modules": "3.2.0",
-				"becke-ch--regex--s0-0-v1--base--pl--lib": "1.4.0",
-			"version": "10.4.10",
-			"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.10.tgz",
-			"integrity": "sha512-nMaiDARyp1e74c8IeAXkr+BmFKa8By4Zak7tyaNPF09Iu39WFpNXOWrVirmXjKr+5cOyERwvtbMOLYz6iBJYgQ==",
-			"funding": [
-				{
-					"type": "opencollective",
-					"url": "https://opencollective.com/postcss/"
-				},
-				{
-					"type": "tidelift",
-					"url": "https://tidelift.com/funding/github/npm/autoprefixer"
-				}
-			],
-			"peer": true,
-			"dependencies": {
-				"browserslist": "^4.21.3",
-				"caniuse-lite": "^1.0.30001399",
-				"fraction.js": "^4.2.0",
-				"normalize-range": "^0.1.2",
-				"picocolors": "^1.0.0",
-				"postcss-value-parser": "^4.2.0"
-			},
-			"bin": {
-				"autoprefixer": "bin/autoprefixer"
-			},
-			"engines": {
-				"node": "^10 || ^12 || >=14"
-			},
-			"peerDependencies": {
-				"postcss": "^8.1.0"
-			}
-		},
-				"builtin-modules": "3.2.0",
 				"license-checker": "25.0.1",
 			"version": "0.7.0",
 			"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
@@ -5682,13 +5651,12 @@ 				"node": ">=8"
 			}
 		},
 		"node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": {
-				"type": "opencollective",
+			"version": "2.2.0",
 	"lockfileVersion": 2,
-	"name": "root",
 				"@babel/traverse": "^7.19.0",
+				"jest": "25.5.4",
-	"name": "root",
 				"@tailwindcss/aspect-ratio": "0.4.0",
-{
+				"klona": "2.0.4",
 			"dependencies": {
 				"@babel/core": "^7.12.3",
 				"@babel/parser": "^7.14.7",
@@ -5816,20 +5784,18 @@ 				"semver": "bin/semver.js"
 			}
 		},
 		"node_modules/babel-plugin-polyfill-corejs3": {
-			"version": "0.5.3",
-				"chokidar": "3.5.1",
 	"packages": {
+				"@babel/code-frame": "^7.18.6",
-	"name": "root",
 {
-	"packages": {
+				"license-checker": "25.0.1",
 {
+				"line-column": "1.0.2",
 			"dependencies": {
 				"chokidar": "3.5.1",
-				"tailwindcss": "3.0.11",
+				"resolve": "1.20.0",
-	"name": "root",
 {
-	"packages": {
 	"lockfileVersion": 2,
+				"@parcel/watcher": "2.0.3",
 			},
 			"peerDependencies": {
 				"@babel/core": "^7.0.0-0"
@@ -6031,12 +5996,11 @@ 			"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
 			"integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg=="
 		},
 		"node_modules/browserslist": {
-		"node_modules/@babel/helper-validator-identifier": {
 {
+				"normalize-path": "3.0.0",
-			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz",
+			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz",
-	"name": "root",
+		"node_modules/@lerna/child-process/node_modules/get-stream": {
 	"name": "root",
-				"tmp-cache": "1.1.0",
 			"funding": [
 				{
 					"type": "opencollective",
@@ -6048,12 +6012,11 @@ 					"url": "https://tidelift.com/funding/github/npm/browserslist"
 				}
 			],
 			"dependencies": {
-				"caniuse-lite": "^1.0.30001370",
+				"caniuse-lite": "^1.0.30001400",
-				"electron-to-chromium": "^1.4.202",
+				"electron-to-chromium": "^1.4.251",
 				"node-releases": "^2.0.6",
-				"color-name": "1.1.4",
+		"node_modules/@lerna/child-process/node_modules/get-stream": {
 	"packages": {
-				"@parcel/watcher": "2.0.3",
 			},
 			"bin": {
 				"browserslist": "cli.js"
@@ -6290,10 +6253,11 @@ 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
 		"node_modules/caniuse-lite": {
-			"version": "1.0.30001399",
+			"version": "1.0.30001421",
-			"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz",
+				"@babel/traverse": "^7.19.0",
 	"requires": true,
+			"name": "root",
-			"integrity": "sha512-4vQ90tMKS+FkvuVWS5/QY1+d805ODxZiKFzsU8o/RsVJz49ZSRR8EjykLJbqhzdPgadbX6wB538wOzle3JniRA==",
+			"integrity": "sha512-Sw4eLbgUJAEhjLs1Fa+mk45sidp1wRn5y6GtDpHGBaNJ9OCDJaVh2tIaWWUnGfuXfKf1JCBaIarak3FkVAvEeA==",
 			"funding": [
 				{
 					"type": "opencollective",
@@ -7280,18 +7244,13 @@ 				"node": ">=4"
 			}
 		},
 		"node_modules/convert-source-map": {
-				"deepmerge": "4.2.2",
 		"": {
-			"dependencies": {
-	"name": "root",
 			"name": "root",
-			}
-		"node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+	"packages": {
-			"dependencies": {
-		"node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
 {
-		"": {
+	"requires": true,
 				"@parcel/watcher": "2.0.3",
+			"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
 		},
 		"node_modules/copy-concurrently": {
 			"version": "1.0.5",
@@ -7334,13 +7293,14 @@ 				"node": ">=0.10.0"
 			}
 		},
 		"node_modules/core-js-compat": {
-			"version": "3.25.1",
-			"integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==",
+{
+				"stringify-object": "3.3.0",
+		"node_modules/@lerna/child-process/node_modules/has-flag": {
 	"name": "root",
-		"node_modules/@babel/code-frame": {
 {
+				"tmp-cache": "1.1.0",
 			"dependencies": {
-				"browserslist": "^4.21.3"
+				"browserslist": "^4.21.4"
 			},
 			"funding": {
 				"type": "opencollective",
@@ -7348,10 +7307,10 @@ 				"url": "https://opencollective.com/core-js"
 			}
 		},
 		"node_modules/core-js-pure": {
-			"version": "3.25.1",
+			"version": "3.25.5",
-			"integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==",
+		"node_modules/@lerna/child-process/node_modules/has-flag": {
 	"packages": {
-			"integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==",
+		"node_modules/@lerna/child-process/node_modules/has-flag": {
 		"": {
 			"hasInstallScript": true,
 			"funding": {
@@ -7667,11 +7626,15 @@ 				"node": ">=0.10.0"
 			}
 		},
 		"node_modules/defined": {
-				"@parcel/watcher": "2.0.3",
+			"version": "1.0.1",
+				"@babel/traverse": "^7.19.0",
 				"vsce": "1.87.0",
-				"@babel/plugin-syntax-async-generators": "^7.8.4"
+			"integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==",
+{
+			"name": "root",
-				"@babel/plugin-syntax-async-generators": "^7.8.4"
 {
+		"node_modules/@lerna/bootstrap/node_modules/p-finally": {
+			}
 		},
 		"node_modules/delayed-stream": {
 			"version": "1.0.0",
@@ -7911,13 +7874,12 @@ 				"safer-buffer": "^2.1.0"
 			}
 		},
 		"node_modules/electron-to-chromium": {
-	"lockfileVersion": 2,
+				"@tailwindcss/aspect-ratio": "0.4.0",
-				"find-up": "5.0.0",
+				"vscode-emmet-helper-bundled": "0.0.1",
-	"lockfileVersion": 2,
+			"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-				"jest": "25.5.4",
-	"lockfileVersion": 2,
+{
-	"lockfileVersion": 2,
 		"": {
+{
 		},
 		"node_modules/emoji-regex": {
 			"version": "9.2.2",
@@ -8660,11 +8621,11 @@ 				}
 			}
 		},
 		"node_modules/eslint-plugin-react": {
-			"version": "7.31.8",
+			"version": "7.31.10",
-	"lockfileVersion": 2,
+			"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
 	"lockfileVersion": 2,
-		"node_modules/@babel/code-frame": {
-			"integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==",
+{
+			},
 			"dependencies": {
 				"array-includes": "^3.1.5",
 				"array.prototype.flatmap": "^1.3.0",
@@ -9565,10 +9526,11 @@ 			}
 		},
 		"node_modules/fb-watchman": {
 				"@babel/types": "^7.19.0",
-			"dependencies": {
-			"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
+	"name": "root",
-	"lockfileVersion": 2,
+				"@babel/traverse": "^7.19.0",
 			"devDependencies": {
+{
+				"esbuild": "0.14.11",
 			"dependencies": {
 				"bser": "2.1.1"
 			}
@@ -9754,20 +9716,6 @@ 				"node": ">= 0.12"
 			}
 		},
 				"license-checker": "25.0.1",
-				"@types/vscode": "1.65.0",
-			"version": "4.2.0",
-			"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
-			"integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==",
-			"peer": true,
-			"engines": {
-				"node": "*"
-			},
-			"funding": {
-				"type": "patreon",
-				"url": "https://www.patreon.com/infusion"
-			}
-		},
-				"license-checker": "25.0.1",
 				"concurrently": "7.0.0",
 			"version": "0.2.1",
 			"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -14141,8 +14089,9 @@ 		},
 		"node_modules/lodash.uniq": {
 			"version": "4.5.0",
 			"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
-	"packages": {
+{
-	"name": "root",
+				"lerna": "^3.22.1",
+			"dev": true
 		},
 		"node_modules/log-symbols": {
 			"version": "3.0.0",
@@ -15088,16 +15037,6 @@ 				"node": ">=0.10.0"
 			}
 		},
 				"@babel/plugin-proposal-logical-assignment-operators": "^7.18.9",
-	"name": "root",
-			"version": "0.1.2",
-			"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
-			"integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
-			"peer": true,
-			"engines": {
-				"node": ">=0.10.0"
-			}
-		},
-				"@babel/plugin-proposal-logical-assignment-operators": "^7.18.9",
 	"packages": {
 			"version": "3.3.0",
 			"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
@@ -15353,14 +15292,14 @@ 				"node": ">=0.10.0"
 			}
 		},
 		"node_modules/object-hash": {
-			"name": "root",
 	"name": "root",
+			"devDependencies": {
-				"tsdx": "0.14.1",
+				"@babel/traverse": "^7.19.0",
 		"": {
-	"requires": true,
+			"dependencies": {
-				"tsdx": "0.14.1",
+				"@babel/traverse": "^7.19.0",
 		"": {
-	"packages": {
+				"@parcel/watcher": "2.0.3",
 			"engines": {
 				"node": ">= 6"
 			}
@@ -16213,6 +16152,22 @@ 				"type": "opencollective",
 				"url": "https://opencollective.com/postcss/"
 			}
 		},
+		"node_modules/postcss-import": {
+			"version": "14.1.0",
+			"resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz",
+			"integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==",
+			"dependencies": {
+				"postcss-value-parser": "^4.0.0",
+				"read-cache": "^1.0.0",
+				"resolve": "^1.1.7"
+			},
+			"engines": {
+				"node": ">=10.0.0"
+			},
+			"peerDependencies": {
+				"postcss": "^8.0.0"
+			}
+		},
 		"node_modules/postcss-js": {
 			"version": "4.0.0",
 			"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz",
@@ -16705,6 +16660,22 @@ 			"engines": {
 				"node": ">=0.8"
 			}
 		},
+		"node_modules/read-cache": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+			"integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+			"dependencies": {
+				"pify": "^2.3.0"
+			}
+		},
+		"node_modules/read-cache/node_modules/pify": {
+			"version": "2.3.0",
+			"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+			"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
 		"node_modules/read-cmd-shim": {
 			"version": "1.0.5",
 			"resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz",
@@ -16992,10 +16963,11 @@ 			"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
 			"integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="
 		},
 		"node_modules/regenerate-unicode-properties": {
-			"version": "10.0.1",
-				"core-js-compat": "^3.22.1",
+				"builtin-modules": "3.2.0",
 		"": {
+{
-			"integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==",
+			"resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz",
+			"integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==",
 			"dependencies": {
 				"regenerate": "^1.4.2"
 			},
@@ -17004,14 +16976,14 @@ 				"node": ">=4"
 			}
 		},
 		"node_modules/regenerator-runtime": {
+			"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
 	"packages": {
-				"@parcel/watcher": "2.0.3",
+				"@babel/traverse": "^7.19.0",
 			"dependencies": {
+		"": {
-		"node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-regenerator": {
 {
-				"vscode-emmet-helper-bundled": "0.0.1",
 			"dependencies": {
-	"name": "root",
+			"name": "root",
 		},
 		"node_modules/regenerator-transform": {
 			"version": "0.15.0",
@@ -17060,18 +17032,19 @@ 				"url": "https://github.com/sponsors/mysticatea"
 			}
 		},
 		"node_modules/regexpu-core": {
+			"version": "5.2.1",
 				"@tailwindcss/aspect-ratio": "0.4.0",
 			"integrity": "sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==",
-			"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.1.0.tgz",
-		"": {
+{
+		"node_modules/@babel/core": {
 			"dependencies": {
 				"regenerate": "^1.4.2",
-		"": {
+{
-	"name": "root",
+			"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.0.tgz",
-		"": {
+{
-	"lockfileVersion": 2,
+			"integrity": "sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==",
-		"": {
+{
-	"requires": true,
+				"@ampproject/remapping": "^2.1.0",
 				"unicode-match-property-ecmascript": "^2.0.0",
 				"unicode-match-property-value-ecmascript": "^2.0.0"
 			},
@@ -17079,22 +17052,22 @@ 				"node": ">=4"
 			}
 		},
 		"node_modules/regjsgen": {
-	"packages": {
+				"@babel/traverse": "^7.19.0",
 				"@babel/code-frame": "^7.18.6",
-		"": {
+{
-			"dependencies": {
+				"@babel/generator": "^7.19.0",
-		"": {
+{
 				"@parcel/watcher": "2.0.3",
+	"packages": {
 		},
 		"node_modules/regjsparser": {
-				"vscode-languageclient": "8.0.2",
 {
-{
-		"": {
-				"@tailwindcss/line-clamp": "0.3.0",
+				"@parcel/watcher": "2.0.3",
 		"": {
+				"@tailwindcss/aspect-ratio": "0.4.0",
+				"@babel/helpers": "^7.19.0",
 {
-	"lockfileVersion": 2,
+				"@babel/parser": "^7.19.0",
 			"dependencies": {
 				"jsesc": "~0.5.0"
 			},
@@ -19027,39 +19001,41 @@ 				"node": ">=6"
 			}
 		},
 		"node_modules/tailwindcss": {
-			"version": "3.0.11",
+			"version": "3.1.8",
-			"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.0.11.tgz",
+			"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz",
-			"integrity": "sha512-JyMsQ2kPqpOvG8ow535XpauXj3wz3nQqcy2tVlXj4FQ0eNlsdzvlAqpRA3q5rPLboWirNG6r2DqKczwjW2uc8Q==",
+			"integrity": "sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==",
 			"dependencies": {
-			"resolved": "https://registry.npmjs.org/@evocateur/libnpmpublish/-/libnpmpublish-1.2.2.tgz",
+{
-			"resolved": "https://registry.npmjs.org/@evocateur/libnpmpublish/-/libnpmpublish-1.2.2.tgz",
 {
-			"resolved": "https://registry.npmjs.org/@evocateur/libnpmpublish/-/libnpmpublish-1.2.2.tgz",
 	"name": "root",
-			"resolved": "https://registry.npmjs.org/@evocateur/libnpmpublish/-/libnpmpublish-1.2.2.tgz",
+				"node": ">=0.10.0"
 	"lockfileVersion": 2,
 			"resolved": "https://registry.npmjs.org/@evocateur/libnpmpublish/-/libnpmpublish-1.2.2.tgz",
-	"requires": true,
+	"lockfileVersion": 2,
-				"esbuild": "0.14.11",
+				"node": ">=0.10.0"
 	"requires": true,
-	"packages": {
 				"didyoumean": "^1.2.2",
 				"dlv": "^1.1.3",
-				"fast-glob": "^3.2.7",
+				"fast-glob": "^3.2.11",
 				"glob-parent": "^6.0.2",
 				"is-glob": "^4.0.3",
 {
+				"semver": "^6.3.0"
+{
 			"integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==",
-			"integrity": "sha512-MJrrk9ct1FeY9zRlyeoyMieBjGDG9ihyyD9/Ft6MMrTxql9NyoEx2hw9casTIP4CdqEVu+3nQ2nXxoJ8RCXyFg==",
+				"object-hash": "^3.0.0",
+				"picocolors": "^1.0.0",
+				"postcss": "^8.4.14",
+{
+				"url": "https://opencollective.com/babel"
 				"postcss-js": "^4.0.0",
-				"postcss-load-config": "^3.1.0",
+				"postcss-load-config": "^3.1.4",
 				"postcss-nested": "5.0.6",
-				"postcss-selector-parser": "^6.0.7",
+				"postcss-selector-parser": "^6.0.10",
 				"postcss-value-parser": "^4.2.0",
 				"quick-lru": "^5.1.1",
-	"lockfileVersion": 2,
+		"node_modules/@lerna/child-process/node_modules/npm-run-path": {
 	"name": "root",
-				"@babel/template": "^7.18.10",
 			},
 			"bin": {
 				"tailwind": "lib/cli.js",
@@ -19069,7 +19044,6 @@ 			"engines": {
 				"node": ">=12.13.0"
 			},
 			"peerDependencies": {
-				"autoprefixer": "^10.0.2",
 				"postcss": "^8.0.9"
 			}
 		},
@@ -19110,33 +19084,35 @@ 			"engines": {
 				"node": ">= 6"
 			}
 		},
-				"normalize-package-data": "^2.4.0",
+		"node_modules/@lerna/child-process/node_modules/npm-run-path": {
 	"lockfileVersion": 2,
-			"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
 			"name": "root",
+				"concurrently": "7.0.0",
-				"@babel/plugin-transform-literals": "^7.18.9",
+				"@tailwindcss/aspect-ratio": "0.4.0",
 {
+				"@types/debounce": "1.2.0",
+		"node_modules/@lerna/child-process/node_modules/npm-run-path": {
 	"packages": {
-					"url": "https://www.patreon.com/feross"
 			"dependencies": {
-	"name": "root",
+				"@tailwindcss/aspect-ratio": "0.4.0",
 {
-	"name": "root",
 {
+		"": {
+				"detective": "5.2.0",
 	"packages": {
+	"packages": {
+		"node_modules/@lerna/child-process/node_modules/npm-run-path": {
 			"name": "root",
-				"fast-glob": "3.2.4",
-				"parse-json": "^5.0.0",
+			},
-	"name": "root",
+{
 {
-	"name": "root",
 	"requires": true,
+				"detective": "5.2.0",
 				"vsce": "1.87.0",
-				"find-up": "5.0.0",
 			},
 			"engines": {
 	"name": "root",
-			"version": "7.14.5",
+			"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
 			}
 		},
 		"node_modules/tailwindcss/node_modules/fast-glob": {
@@ -19176,81 +19152,55 @@ 			"engines": {
 				"node": ">=10.13.0"
 			}
 		},
-		"node_modules/tailwindcss/node_modules/import-fresh": {
-	"name": "root",
 {
-				"deepmerge": "4.2.2",
-	"name": "root",
 {
-				"detect-indent": "6.0.0",
-	"name": "root",
 {
-				"detective": "5.2.0",
 			"dependencies": {
-	"name": "root",
 {
-	"lockfileVersion": 2,
-	"name": "root",
 {
-	"lockfileVersion": 2,
 {
-			},
-			"engines": {
+				"@parcel/watcher": "2.0.3",
-				"esbuild": "0.14.11",
 {
-			},
 {
+	"name": "root",
-			"name": "root",
-				"url": "https://github.com/sponsors/sindresorhus"
-			}
-		},
-		"node_modules/tailwindcss/node_modules/parse-json": {
 				"@tailwindcss/aspect-ratio": "0.4.0",
-				"@babel/highlight": "^7.18.6"
-	"name": "root",
 {
-				"fast-glob": "3.2.4",
 				"chokidar": "3.5.1",
-				"find-up": "5.0.0",
-			"dependencies": {
+			"name": "root",
 	"name": "root",
 		"": {
-	"packages": {
+			"name": "root",
 	"name": "root",
-				"@babel/helper-explode-assignable-expression": "^7.18.6",
+			"name": "root",
 	"name": "root",
-				"@babel/types": "^7.18.9"
 	"name": "root",
-{
 	"lockfileVersion": 2,
-			"name": "root",
-		"": {
+			"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz",
 	"requires": true,
 			"name": "root",
-			"name": "root",
+				"dlv": "1.1.3",
 			"name": "root",
-				"tmp-cache": "1.1.0",
+				"deepmerge": "4.2.2",
-			},
+					"type": "tidelift",
 				"@tailwindcss/aspect-ratio": "0.4.0",
-			"name": "root",
+			"version": "0.3.2",
 			"name": "root",
-			}
+				"jest": "25.5.4",
-			}
+			"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz",
 			"name": "root",
-				"npm-package-arg": "^6.1.0",
 			"dependencies": {
-			"version": "4.0.0",
+				"nanoid": "^3.3.4",
 	"name": "root",
-{
 	"lockfileVersion": 2,
-				"@parcel/watcher": "2.0.3",
+	"name": "root",
+				"@babel/types": "^7.19.0",
 	"name": "root",
-{
+	"requires": true,
+		"": {
 	"requires": true,
 			"engines": {
-			"name": "root",
+			"integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==",
 	"packages": {
-	"lockfileVersion": 2,
 			}
 		},
 		"node_modules/tailwindcss/node_modules/postcss-load-config": {
@@ -19312,20 +19261,38 @@ 			"engines": {
 				"node": ">=8.10.0"
 			}
 		},
+		"node_modules/tailwindcss/node_modules/resolve": {
+				"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
 		"": {
+				"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
 			"name": "root",
+			"integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+			"dependencies": {
+				"is-core-module": "^2.9.0",
+				"@babel/plugin-transform-parameters": "^7.18.8"
+				"supports-preserve-symlinks-flag": "^1.0.0"
 		"": {
+	"requires": true,
+			"bin": {
+				"resolve": "bin/resolve"
 		"": {
+	"requires": true,
+				"@tailwindcss/aspect-ratio": "0.4.0",
 			"name": "root",
-			"dependencies": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+				"@tailwindcss/aspect-ratio": "0.4.0",
 {
-	"lockfileVersion": 2,
+				"debounce": "1.2.0",
+			"version": "1.0.2",
+				"@babel/types": "^7.19.0",
 				"deepmerge": "4.2.2",
 {
-	"lockfileVersion": 2,
+{
 				"detect-indent": "6.0.0",
 			"engines": {
-				"node": ">=4"
+				"node": ">=0.10.0"
 			}
 		},
 		"node_modules/tapable": {
@@ -20095,15 +20062,16 @@ 			}
 		},
 		"node_modules/unicode-property-aliases-ecmascript": {
 {
-{
+				"@parcel/watcher": "2.0.3",
 	"lockfileVersion": 2,
+	"lockfileVersion": 2,
 {
-			"name": "root",
-	"lockfileVersion": 2,
+{
 	"name": "root",
+				"@parcel/watcher": "2.0.3",
-			"name": "root",
+{
+{
 	"lockfileVersion": 2,
-	"lockfileVersion": 2,
 			"engines": {
 				"node": ">=4"
 			}
@@ -20233,11 +20200,11 @@ 				"yarn": "*"
 			}
 		},
 		"node_modules/update-browserslist-db": {
-			"version": "1.0.9",
+			"version": "1.0.10",
-			"name": "root",
+{
-				"node": ">=6.0.0"
+		"node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
-			"name": "root",
+{
-		"node_modules/@babel/code-frame": {
+			"version": "7.18.9",
 			"funding": [
 				{
 					"type": "opencollective",
@@ -20498,14 +20465,14 @@ 				"vscode-uri": "^3.0.3"
 			}
 		},
 		"node_modules/vscode-css-languageservice/node_modules/vscode-uri": {
-			"version": "3.0.3",
+			"version": "3.0.6",
-			"name": "root",
+				"@tailwindcss/aspect-ratio": "0.4.0",
 {
-			"dependencies": {
+	"lockfileVersion": 2,
 	"requires": true,
-			"name": "root",
+				"@tailwindcss/aspect-ratio": "0.4.0",
 {
-			"dependencies": {
+	"lockfileVersion": 2,
 	"packages": {
 		},
 		"node_modules/vscode-emmet-helper-bundled": {
@@ -20578,6 +20545,7 @@ 		"node_modules/w3c-hr-time": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
 			"integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
+			"deprecated": "Use your platform's native performance.now() and performance.timeOrigin.",
 			"dependencies": {
 				"browser-process-hrtime": "^1.0.0"
 			}
@@ -21187,32 +21155,36 @@ 				"@babel/highlight": "^7.18.6"
 			}
 		},
 		"@babel/compat-data": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-			"dependencies": {
+				"which": "^1.2.9"
 			"name": "root",
-			"integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
 				"@tailwindcss/aspect-ratio": "0.4.0",
+		"node_modules/@babel/helper-compilation-targets": {
 		},
 		"@babel/core": {
-			"version": "7.19.0",
+			"version": "7.19.3",
 				"@parcel/watcher": "2.0.3",
+				"@babel/helper-compilation-targets": "^7.19.0",
 				"@parcel/watcher": "2.0.3",
+				"@babel/helper-compilation-targets": "^7.19.0",
 {
 			"requires": {
 				"@ampproject/remapping": "^2.1.0",
 				"@babel/code-frame": "^7.18.6",
 				"@parcel/watcher": "2.0.3",
-	"requires": true,
+				"p-finally": "^1.0.0",
 				"@parcel/watcher": "2.0.3",
+				"@parcel/watcher": "2.0.3",
 	"packages": {
+	"lockfileVersion": 2,
 				"@babel/helper-module-transforms": "^7.19.0",
 				"@babel/helpers": "^7.19.0",
 				"@parcel/watcher": "2.0.3",
-			"dependencies": {
+				"p-waterfall": "^1.0.0",
 				"@babel/template": "^7.18.10",
-				"@babel/traverse": "^7.19.0",
+				"@babel/traverse": "^7.19.3",
-				"@babel/types": "^7.19.0",
+				"@babel/types": "^7.19.3",
 				"convert-source-map": "^1.7.0",
 				"debug": "^4.1.0",
 				"gensync": "^1.0.0-beta.2",
@@ -21228,14 +21200,13 @@ 				}
 			}
 		},
 		"@babel/generator": {
-			"version": "7.19.0",
-				"@tailwindcss/forms": "0.4.0",
+				"node": ">=4.8"
 			"name": "root",
-				"@tailwindcss/forms": "0.4.0",
+				"node": ">=4.8"
 			"dependencies": {
+			"integrity": "sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==",
 			"requires": {
-{
+		"node_modules/@lerna/child-process/node_modules/execa": {
-{
 				"@jridgewell/gen-mapping": "^0.3.2",
 				"jsesc": "^2.5.1"
 			},
@@ -21270,16 +21241,18 @@ 				"@babel/types": "^7.18.9"
 			}
 		},
 		"@babel/helper-compilation-targets": {
-			"version": "7.19.0",
+			"version": "7.19.3",
+		"node_modules/@lerna/child-process/node_modules/execa": {
 {
-				"line-column": "1.0.2",
-				"@tailwindcss/typography": "0.5.0",
+				"@parcel/watcher": "2.0.3",
 				"@parcel/watcher": "2.0.3",
+				"vscode-languageserver-textdocument": "1.0.7",
 			"requires": {
-				"@babel/compat-data": "^7.19.0",
+				"@babel/compat-data": "^7.19.3",
 				"@babel/helper-validator-option": "^7.18.6",
-				"@types/debounce": "1.2.0",
+				"builtin-modules": "3.2.0",
 	"name": "root",
+			"dependencies": {
 				"semver": "^6.3.0"
 			},
 			"dependencies": {
@@ -21419,27 +21392,27 @@ 				"@babel/types": "^7.18.9"
 			}
 		},
 		"@babel/helper-replace-supers": {
-			"version": "7.18.9",
+			"version": "7.19.1",
-				"builtin-modules": "3.2.0",
+				"@parcel/watcher": "2.0.3",
 				"@parcel/watcher": "2.0.3",
+			"devDependencies": {
-			"integrity": "sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ==",
+			"integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==",
 			"requires": {
 				"@babel/helper-environment-visitor": "^7.18.9",
 				"@babel/helper-member-expression-to-functions": "^7.18.9",
 				"@babel/helper-optimise-call-expression": "^7.18.6",
-	"name": "root",
+				"@babel/traverse": "^7.19.1",
 {
-{
+			"dependencies": {
 {
-				"klona": "2.0.4",
 			}
 		},
 		"@babel/helper-simple-access": {
-			"version": "7.18.6",
+			"version": "7.19.4",
-			"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz",
+			"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz",
-			"integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==",
+			"integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==",
 			"requires": {
-				"@tailwindcss/typography": "0.5.0",
+			"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
 			}
 		},
 		"@babel/helper-skip-transparent-expression-wrappers": {
@@ -21459,19 +21432,22 @@ 				"@babel/types": "^7.18.6"
 			}
 		},
 		"@babel/helper-string-parser": {
-			"version": "7.18.10",
-			"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz",
-			"integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+				"@babel/template": "^7.18.10",
 	"requires": true,
+		"": {
 				"@parcel/watcher": "2.0.3",
+				"@lerna/collect-uncommitted": "3.16.5",
+			"integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw=="
 		},
 		"@babel/helper-validator-identifier": {
-			"version": "7.18.6",
-				"color-name": "1.1.4",
+				"@babel/template": "^7.18.10",
 		"": {
+	"requires": true,
+				"@babel/template": "^7.18.10",
 			"name": "root",
-				"prettier": "2.3.0",
+	"lockfileVersion": 2,
 {
+			"integrity": "sha512-Ai5bNWXIvwDvWM7njqsG3feMlL9hCVQsPYXodsZyLwshYkZVJt59Gftau4VrE8S9IT9asd2uSP1hG6wCNw+sXA==",
 		},
 		"@babel/helper-validator-option": {
 			"version": "7.18.6",
@@ -21490,16 +21466,16 @@ 				"@babel/types": "^7.19.0"
 			}
 		},
 		"@babel/helpers": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-				"concurrently": "7.0.0",
+			"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
 	"packages": {
-				"concurrently": "7.0.0",
+			"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
 		"": {
 			"requires": {
 				"@babel/template": "^7.18.10",
-				"@babel/traverse": "^7.19.0",
+				"@babel/traverse": "^7.19.4",
-				"@babel/types": "^7.19.0"
+				"@babel/types": "^7.19.4"
 			}
 		},
 		"@babel/highlight": {
@@ -21559,14 +21535,13 @@ 				}
 			}
 		},
 		"@babel/parser": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-	"name": "root",
+				"@babel/template": "^7.18.10",
 			"name": "root",
-	"requires": true,
+			"dependencies": {
-			"name": "root",
+				"@babel/types": "^7.19.0",
 	"requires": true,
-			"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.0.tgz",
 		},
 		"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
 			"version": "7.18.6",
@@ -21587,12 +21561,13 @@ 				"@babel/plugin-proposal-optional-chaining": "^7.18.9"
 			}
 		},
 		"@babel/plugin-proposal-async-generator-functions": {
-			"dependencies": {
+				"@babel/template": "^7.18.10",
 		"": {
+	"requires": true,
-				"detect-indent": "6.0.0",
 				"@parcel/watcher": "2.0.3",
-	"name": "root",
 				"@parcel/watcher": "2.0.3",
+			"dependencies": {
+			"integrity": "sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==",
 			"requires": {
 				"@babel/helper-environment-visitor": "^7.18.9",
 				"@babel/helper-plugin-utils": "^7.19.0",
@@ -21674,17 +21649,17 @@ 				"@babel/plugin-syntax-numeric-separator": "^7.10.4"
 			}
 		},
 		"@babel/plugin-proposal-object-rest-spread": {
-				"@tailwindcss/typography": "0.5.0",
+			"version": "7.19.4",
+			"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
 	"name": "root",
-	"lockfileVersion": 2,
+			"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
 	"lockfileVersion": 2,
-			"integrity": "sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==",
 			"requires": {
-				"@babel/compat-data": "^7.18.8",
+				"@babel/compat-data": "^7.19.4",
-				"fast-glob": "3.2.4",
+				"node": ">=4.8"
 	"lockfileVersion": 2,
 	"name": "root",
-				"node": ">=6.9.0"
+			"integrity": "sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==",
 				"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
 				"@babel/plugin-transform-parameters": "^7.18.8"
 			}
@@ -21900,14 +21875,16 @@ 				"@babel/helper-plugin-utils": "^7.18.6"
 			}
 		},
 		"@babel/plugin-transform-block-scoping": {
-			"version": "7.18.9",
+				"@babel/template": "^7.18.10",
 	"requires": true,
-				"deepmerge": "4.2.2",
+		"": {
+			"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.19.4.tgz",
-				"postcss": "8.3.9",
+				"@babel/template": "^7.18.10",
 			"dependencies": {
+		"": {
 			"requires": {
 	"requires": true,
-				"detective": "5.2.0",
+				"node": ">=6.9.0"
 			}
 		},
 		"@babel/plugin-transform-classes": {
@@ -21935,15 +21912,18 @@ 				"@babel/helper-plugin-utils": "^7.18.9"
 			}
 		},
 		"@babel/plugin-transform-destructuring": {
+				"@babel/template": "^7.18.10",
 	"requires": true,
-	"lockfileVersion": 2,
+		"": {
+				"@babel/template": "^7.18.10",
 			"dependencies": {
+			"name": "root",
-				"postcss-load-config": "3.0.1",
+				"@parcel/watcher": "2.0.3",
 				"@parcel/watcher": "2.0.3",
-			"integrity": "sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==",
+			"integrity": "sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==",
 			"requires": {
 	"requires": true,
-				"detective": "5.2.0",
+				"node": ">=6.9.0"
 			}
 		},
 		"@babel/plugin-transform-dotall-regex": {
@@ -22049,12 +22029,13 @@ 				"@babel/helper-plugin-utils": "^7.18.6"
 			}
 		},
 		"@babel/plugin-transform-named-capturing-groups-regex": {
-			"dependencies": {
+				"@babel/template": "^7.18.10",
 		"": {
+	"requires": true,
-	"requires": true,
+				"@babel/template": "^7.18.10",
 			"dependencies": {
-{
+				"@parcel/watcher": "2.0.3",
-			"integrity": "sha512-HDSuqOQzkU//kfGdiHBt71/hkDTApw4U/cMVgKgX7PqfB3LOaK+2GtCEsBu1dL9CkswDm0Gwehht1dCr421ULQ==",
+			"integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==",
 			"requires": {
 				"@babel/helper-create-regexp-features-plugin": "^7.19.0",
 				"@babel/helper-plugin-utils": "^7.19.0"
@@ -22169,24 +22150,24 @@ 				"@babel/helper-plugin-utils": "^7.18.6"
 			}
 		},
 		"@babel/preset-env": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-			"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.0.tgz",
+			"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.4.tgz",
-	"packages": {
+				"cross-spawn": "^6.0.0",
 	"name": "root",
-				"@parcel/watcher": "2.0.3",
 			"requires": {
-{
+			"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
 	"requires": true,
 				"@parcel/watcher": "2.0.3",
+				"@parcel/watcher": "2.0.3",
 	"packages": {
+	"lockfileVersion": 2,
 				"@babel/helper-plugin-utils": "^7.19.0",
 				"@babel/helper-validator-option": "^7.18.6",
 				"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6",
 				"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9",
-	"packages": {
+				"cross-spawn": "^6.0.0",
 	"lockfileVersion": 2,
-	"name": "root",
 				"@babel/plugin-proposal-class-properties": "^7.18.6",
 				"@babel/plugin-proposal-class-static-block": "^7.18.6",
 				"@babel/plugin-proposal-dynamic-import": "^7.18.6",
@@ -22194,9 +22176,8 @@ 				"@babel/plugin-proposal-json-strings": "^7.18.6",
 				"@babel/plugin-proposal-logical-assignment-operators": "^7.18.9",
 				"@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
 				"@babel/plugin-proposal-numeric-separator": "^7.18.6",
-	"packages": {
+				"cross-spawn": "^6.0.0",
 	"requires": true,
-{
 				"@babel/plugin-proposal-optional-catch-binding": "^7.18.6",
 				"@babel/plugin-proposal-optional-chaining": "^7.18.9",
 				"@babel/plugin-proposal-private-methods": "^7.18.6",
@@ -22220,13 +22201,12 @@ 				"@babel/plugin-syntax-top-level-await": "^7.14.5",
 				"@babel/plugin-transform-arrow-functions": "^7.18.6",
 				"@babel/plugin-transform-async-to-generator": "^7.18.6",
 				"@babel/plugin-transform-block-scoped-functions": "^7.18.6",
+				"cross-spawn": "^6.0.0",
 	"packages": {
-			},
 				"@babel/plugin-transform-classes": "^7.19.0",
 				"@babel/plugin-transform-computed-properties": "^7.18.9",
-	"packages": {
+				"cross-spawn": "^6.0.0",
 		"": {
-			"name": "root",
 				"@babel/plugin-transform-dotall-regex": "^7.18.6",
 				"@babel/plugin-transform-duplicate-keys": "^7.18.9",
 				"@babel/plugin-transform-exponentiation-operator": "^7.18.6",
@@ -22238,9 +22218,8 @@ 				"@babel/plugin-transform-modules-amd": "^7.18.6",
 				"@babel/plugin-transform-modules-commonjs": "^7.18.6",
 				"@babel/plugin-transform-modules-systemjs": "^7.19.0",
 				"@babel/plugin-transform-modules-umd": "^7.18.6",
-	"packages": {
+				"cross-spawn": "^6.0.0",
 			"name": "root",
-				"@parcel/watcher": "2.0.3",
 				"@babel/plugin-transform-new-target": "^7.18.6",
 				"@babel/plugin-transform-object-super": "^7.18.6",
 				"@babel/plugin-transform-parameters": "^7.18.8",
@@ -22255,16 +22234,14 @@ 				"@babel/plugin-transform-typeof-symbol": "^7.18.9",
 				"@babel/plugin-transform-unicode-escapes": "^7.18.10",
 				"@babel/plugin-transform-unicode-regex": "^7.18.6",
 				"@babel/preset-modules": "^0.1.5",
-{
+		"node_modules/@lerna/child-process/node_modules/execa": {
-{
-	"packages": {
+				"@parcel/watcher": "2.0.3",
 				"@parcel/watcher": "2.0.3",
-	"requires": true,
+				"@babel/parser": "^7.19.0",
-	"packages": {
+				"cross-spawn": "^6.0.0",
 				"@parcel/watcher": "2.0.3",
-	"packages": {
-				"babel-plugin-polyfill-regenerator": "^0.4.0",
+				"babel-plugin-polyfill-regenerator": "^0.4.1",
-				"core-js-compat": "^3.22.1",
+				"core-js-compat": "^3.25.1",
 				"semver": "^6.3.0"
 			},
 			"dependencies": {
@@ -22296,29 +22273,26 @@ 				"esutils": "^2.0.2"
 			}
 		},
 		"@babel/runtime": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-		"": {
 {
-	"requires": true,
+	"name": "root",
-		"": {
 {
-	"packages": {
+	"lockfileVersion": 2,
 			"requires": {
 				"regenerator-runtime": "^0.13.4"
 			}
 		},
 		"@babel/runtime-corejs3": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-		"": {
 {
-			"dependencies": {
+	"requires": true,
-		"": {
 {
-				"@parcel/watcher": "2.0.3",
+	"packages": {
 			"requires": {
-				"vscode-languageserver-textdocument": "1.0.7",
+{
+		"": {
 				"regenerator-runtime": "^0.13.4"
 			}
 		},
@@ -22333,39 +22307,40 @@ 				"@babel/types": "^7.18.10"
 			}
 		},
 		"@babel/traverse": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-				"vscode-languageserver-textdocument": "1.0.7",
+				"is-stream": "^1.1.0",
 			"name": "root",
-				"vscode-languageserver-textdocument": "1.0.7",
+				"is-stream": "^1.1.0",
 			"dependencies": {
 			"requires": {
 				"@babel/code-frame": "^7.18.6",
+				"is-stream": "^1.1.0",
 				"@parcel/watcher": "2.0.3",
-	"requires": true,
 				"@babel/helper-environment-visitor": "^7.18.9",
 				"@babel/helper-function-name": "^7.19.0",
 				"@babel/helper-hoist-variables": "^7.18.6",
 				"@babel/helper-split-export-declaration": "^7.18.6",
-				"@babel/parser": "^7.19.0",
 				"@tailwindcss/aspect-ratio": "0.4.0",
 {
+				"@babel/types": "^7.19.4",
 				"debug": "^4.1.0",
 				"globals": "^11.1.0"
 			}
 		},
 		"@babel/types": {
-			"dependencies": {
+				"which": "^1.2.9"
 		"": {
-				"vscode-uri": "3.0.2"
+				"@tailwindcss/aspect-ratio": "0.4.0",
+				"@tailwindcss/forms": "0.4.0",
-				"vscode-uri": "3.0.2"
+				"@babel/traverse": "^7.19.0",
 {
+	"name": "root",
 			"requires": {
-		"": {
+				"npm-run-path": "^2.0.0",
 	"lockfileVersion": 2,
-	"name": "root",
 {
-				"@babel/helpers": "^7.19.0",
+				"@types/debounce": "1.2.0",
 				"to-fast-properties": "^2.0.0"
 			}
 		},
@@ -22884,18 +22858,19 @@ 			"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
 			"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
 		},
 		"@jridgewell/trace-mapping": {
-				"@parcel/watcher": "2.0.3",
 {
-			"dependencies": {
+				"@types/moo": "0.5.3",
-				"@parcel/watcher": "2.0.3",
+				"@babel/traverse": "^7.19.0",
 {
-				"@parcel/watcher": "2.0.3",
+		"": {
-				"@ampproject/remapping": "^2.1.0",
+{
+				"@types/semver": "7.3.10",
 			"requires": {
-				"@ampproject/remapping": "^2.1.0",
+				"@babel/traverse": "^7.19.0",
 {
+			"dependencies": {
+				"npm-run-path": "^2.0.0",
 				"@parcel/watcher": "2.0.3",
-	"requires": true,
 			}
 		},
 		"@lerna/add": {
@@ -24763,61 +24738,67 @@ 			}
 		},
 		"@tailwindcss/aspect-ratio": {
 {
-				"vscode-languageserver": "8.0.2",
 	"name": "root",
 {
-		"": {
+	"name": "root",
 {
-	"lockfileVersion": 2,
 {
-			"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz",
+				"color-name": "1.1.4",
 			"requires": {}
 		},
 		"@tailwindcss/forms": {
 {
-		"": {
+			"name": "root",
 				"@tailwindcss/line-clamp": "0.3.0",
 {
-		"node_modules/@babel/runtime-corejs3": {
+				"concurrently": "7.0.0",
 {
-			"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.19.0.tgz",
+				"css.escape": "1.5.1",
 			"requires": {
 				"mini-svg-data-uri": "^1.2.3"
 			}
 		},
 		"@tailwindcss/line-clamp": {
 {
-				"vscode-languageserver-textdocument": "1.0.7",
 	"name": "root",
 {
-		"": {
 	"name": "root",
-	"lockfileVersion": 2,
+	"packages": {
 {
-		"": {
 	"name": "root",
-	"requires": true,
+		"": {
 			"requires": {}
 		},
 		"@tailwindcss/typography": {
-{
 		"": {
-	"name": "root",
+				"moo": "0.5.1",
 		"": {
 {
-		"": {
 				"deepmerge": "4.2.2",
 {
-		"": {
 				"detect-indent": "6.0.0",
 			"requires": {
 				"lodash.castarray": "^4.4.0",
 				"lodash.isplainobject": "^4.0.6",
 				"lodash.merge": "^4.6.2",
 {
+				"detective": "5.2.0",
 		"": {
+	"requires": true,
+			"dependencies": {
+				"@parcel/watcher": "2.0.3",
 	"lockfileVersion": 2,
+				"klona": "2.0.4",
+					"version": "6.0.10",
+					"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
+					"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
+			"integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
 	"name": "root",
+{
+						"cssesc": "^3.0.0",
+						"util-deprecate": "^1.0.2"
+					}
+				}
 			}
 		},
 		"@types/babel__core": {
@@ -24851,12 +24824,12 @@ 			}
 		},
 		"@types/babel__traverse": {
 {
-			"devDependencies": {
 	"lockfileVersion": 2,
+	"name": "root",
 {
-				"get-stream": "^4.0.0",
+				"fast-glob": "3.2.4",
 {
-				"npm-package-arg": "^6.1.0"
+				"find-up": "5.0.0",
 			"requires": {
 				"@babel/types": "^7.3.0"
 			}
@@ -25414,21 +25386,6 @@ 			"integrity": "sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=",
 			"dev": true
 		},
 			"version": "25.5.4",
-			"name": "root",
-			"version": "10.4.10",
-			"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.10.tgz",
-			"integrity": "sha512-nMaiDARyp1e74c8IeAXkr+BmFKa8By4Zak7tyaNPF09Iu39WFpNXOWrVirmXjKr+5cOyERwvtbMOLYz6iBJYgQ==",
-			"peer": true,
-			"requires": {
-				"browserslist": "^4.21.3",
-				"caniuse-lite": "^1.0.30001399",
-				"fraction.js": "^4.2.0",
-				"normalize-range": "^0.1.2",
-				"picocolors": "^1.0.0",
-				"postcss-value-parser": "^4.2.0"
-			}
-		},
-			"version": "25.5.4",
 			"dependencies": {
 			"version": "0.7.0",
 			"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
@@ -25541,13 +25498,15 @@ 			},
 			"dependencies": {
 				"istanbul-lib-instrument": {
 			"name": "root",
-					"type": "consulting",
+	"packages": {
 			"dependencies": {
+			"dependencies": {
+{
 {
-	"name": "root",
+				"pkg-up": "3.1.0",
-			"dependencies": {
+{
 {
-	"lockfileVersion": 2,
+				"postcss": "8.3.9",
 					"requires": {
 						"@babel/core": "^7.12.3",
 						"@babel/parser": "^7.14.7",
@@ -25645,20 +25604,18 @@ 				}
 			}
 		},
 		"babel-plugin-polyfill-corejs3": {
+			"version": "0.6.0",
 {
+	"lockfileVersion": 2,
 			"name": "root",
-				"@tailwindcss/line-clamp": "0.3.0",
-	"name": "root",
 {
-	"packages": {
-			"integrity": "sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==",
+				"line-column": "1.0.2",
 			"requires": {
 				"chokidar": "3.5.1",
-				"tailwindcss": "3.0.11",
+				"resolve": "1.20.0",
-	"name": "root",
 {
-	"packages": {
 	"lockfileVersion": 2,
+				"@parcel/watcher": "2.0.3",
 			}
 		},
 		"babel-plugin-polyfill-regenerator": {
@@ -25830,18 +25785,17 @@ 				}
 			}
 		},
 		"browserslist": {
-		"node_modules/@babel/helper-validator-identifier": {
 {
+				"normalize-path": "3.0.0",
-			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz",
+			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz",
+		"node_modules/@lerna/child-process/node_modules/get-stream": {
 	"name": "root",
-				"escape-string-regexp": "^1.0.5",
 			"requires": {
-				"caniuse-lite": "^1.0.30001370",
+				"caniuse-lite": "^1.0.30001400",
-				"electron-to-chromium": "^1.4.202",
+				"electron-to-chromium": "^1.4.251",
 				"node-releases": "^2.0.6",
-				"color-name": "1.1.4",
+		"node_modules/@lerna/child-process/node_modules/get-stream": {
 	"packages": {
-				"@parcel/watcher": "2.0.3",
 			}
 		},
 		"bs-logger": {
@@ -26024,13 +25978,13 @@ 				"quick-lru": "^4.0.1"
 			}
 		},
 		"caniuse-lite": {
-			"version": "1.0.30001399",
+			"version": "1.0.30001421",
-			"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz",
+				"@babel/traverse": "^7.19.0",
 	"requires": true,
+			"name": "root",
-			"dependencies": {
 {
 {
-			"dependencies": {
+				"postcss-load-config": "3.0.1",
 		},
 		"capture-exit": {
 			"version": "2.0.0",
@@ -26802,19 +26755,14 @@ 				}
 			}
 		},
 		"convert-source-map": {
-				"deepmerge": "4.2.2",
 		"": {
-			"dependencies": {
-	"name": "root",
 			"name": "root",
-			}
+				"stack-trace": "0.0.10",
-		"node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+				"@tailwindcss/aspect-ratio": "0.4.0",
-			"name": "root",
 	"requires": true,
-			"name": "root",
+				"@parcel/watcher": "2.0.3",
-		"node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
 {
-			}
+				"stack-trace": "0.0.10",
 		},
 		"copy-concurrently": {
 			"version": "1.0.5",
@@ -26853,20 +26801,21 @@ 			"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
 			"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
 		},
 		"core-js-compat": {
-			"version": "3.25.1",
+			"version": "3.25.5",
-			"integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==",
+{
+	"packages": {
 	"name": "root",
-		"node_modules/@babel/code-frame": {
 {
+				"tmp-cache": "1.1.0",
 			"requires": {
-				"browserslist": "^4.21.3"
+				"browserslist": "^4.21.4"
 			}
 		},
 		"core-js-pure": {
-			"version": "3.25.1",
+			"version": "3.25.5",
-			"integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==",
+		"node_modules/@lerna/child-process/node_modules/has-flag": {
 	"packages": {
-			"integrity": "sha512-7Fr74bliUDdeJCBMxkkIuQ4xfxn/SwrVg+HkJUAoNEXVqYLv55l6Af0dJ5Lq2YBUW9yKqSkLXaS5SYPK6MGa/A=="
+			"integrity": "sha512-oml3M22pHM+igfWHDfdLVq2ShWmjM2V4L+dQEBs0DWVIqEm9WHCwGAlZ6BmyBQGy5sFrJmcx+856D9lVKyGWYg=="
 		},
 		"core-util-is": {
 			"version": "1.0.2",
@@ -27100,11 +27049,12 @@ 				}
 			}
 		},
 		"defined": {
-				"@parcel/watcher": "2.0.3",
+			"version": "1.0.1",
+				"@babel/traverse": "^7.19.0",
 				"vsce": "1.87.0",
-				"@babel/plugin-syntax-async-generators": "^7.8.4"
+{
-				"@babel/plugin-syntax-async-generators": "^7.8.4"
 {
+				"prettier": "2.3.0",
 		},
 		"delayed-stream": {
 			"version": "1.0.0",
@@ -27298,14 +27248,12 @@ 				"safer-buffer": "^2.1.0"
 			}
 		},
 		"electron-to-chromium": {
-	"lockfileVersion": 2,
+{
-				"find-up": "5.0.0",
-	"lockfileVersion": 2,
-	"lockfileVersion": 2,
 	"packages": {
+				"@parcel/watcher": "2.0.3",
-	"lockfileVersion": 2,
+{
-	"lockfileVersion": 2,
 		"": {
+			"integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA=="
 		},
 		"emoji-regex": {
 			"version": "9.2.2",
@@ -28108,11 +28055,11 @@ 				"prettier-linter-helpers": "^1.0.0"
 			}
 		},
 		"eslint-plugin-react": {
-			"version": "7.31.8",
+			"version": "7.31.10",
-	"lockfileVersion": 2,
+			"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
 	"lockfileVersion": 2,
-		"node_modules/@babel/code-frame": {
-			"integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==",
+				"@tailwindcss/aspect-ratio": "0.4.0",
+			},
 			"requires": {
 				"array-includes": "^3.1.5",
 				"array.prototype.flatmap": "^1.3.0",
@@ -28505,10 +28452,11 @@ 			}
 		},
 		"fb-watchman": {
 				"@babel/types": "^7.19.0",
-			"dependencies": {
-			"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
+	"name": "root",
-	"lockfileVersion": 2,
+				"@babel/traverse": "^7.19.0",
 			"devDependencies": {
+{
+				"esbuild": "0.14.11",
 			"requires": {
 				"bser": "2.1.1"
 			}
@@ -28659,13 +28607,6 @@ 				"mime-types": "^2.1.12"
 			}
 		},
 		"node_modules/@jest/reporters/node_modules/supports-color": {
-		"": {
-			"version": "4.2.0",
-			"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
-			"integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==",
-			"peer": true
-		},
-		"node_modules/@jest/reporters/node_modules/supports-color": {
 			"name": "root",
 			"version": "0.2.1",
 			"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -32106,8 +32047,9 @@ 		},
 		"lodash.uniq": {
 			"version": "4.5.0",
 			"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
-	"packages": {
+{
-	"name": "root",
+				"lerna": "^3.22.1",
+			"dev": true
 		},
 		"log-symbols": {
 			"version": "3.0.0",
@@ -32878,12 +32820,6 @@ 			"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
 			"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
 		},
 		"node_modules/@lerna/add": {
-			"version": "0.1.2",
-			"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
-			"integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
-			"peer": true
-		},
-		"node_modules/@lerna/add": {
 {
 			"version": "3.3.0",
 			"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
@@ -33098,14 +33034,14 @@ 				}
 			}
 		},
 		"object-hash": {
-			"name": "root",
 	"name": "root",
+			"devDependencies": {
-				"tsdx": "0.14.1",
+				"@babel/traverse": "^7.19.0",
 		"": {
-	"requires": true,
+			"dependencies": {
-				"@ampproject/remapping": "^2.1.0",
+				"@babel/types": "^7.19.0",
 	"requires": true,
-	"packages": {
+		"": {
 		},
 		"object-inspect": {
 			"version": "1.12.0",
@@ -33754,6 +33690,16 @@ 					"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
 				}
 			}
 		},
+		"postcss-import": {
+			"version": "14.1.0",
+			"resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz",
+			"integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==",
+			"requires": {
+				"postcss-value-parser": "^4.0.0",
+				"read-cache": "^1.0.0",
+				"resolve": "^1.1.7"
+			}
+		},
 		"postcss-js": {
 			"version": "4.0.0",
 			"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz",
@@ -34117,6 +34063,21 @@ 			"requires": {
 				"mute-stream": "~0.0.4"
 			}
 		},
+		"read-cache": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+			"integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+			"requires": {
+				"pify": "^2.3.0"
+			},
+			"dependencies": {
+				"pify": {
+					"version": "2.3.0",
+					"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+					"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="
+				}
+			}
+		},
 		"read-cmd-shim": {
 			"version": "1.0.5",
 			"resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz",
@@ -34344,22 +34305,22 @@ 			"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
 			"integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="
 		},
 		"regenerate-unicode-properties": {
-			"version": "10.0.1",
+			"version": "10.1.0",
-			"resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz",
+			"resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz",
-			"integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==",
+			"integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==",
 			"requires": {
 				"regenerate": "^1.4.2"
 			}
 		},
 		"regenerator-runtime": {
+			"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
 	"packages": {
-				"@parcel/watcher": "2.0.3",
+				"@babel/traverse": "^7.19.0",
 			"dependencies": {
+		"": {
-		"node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-regenerator": {
 {
-				"vscode-emmet-helper-bundled": "0.0.1",
 			"dependencies": {
-	"name": "root",
+			"name": "root",
 		},
 		"regenerator-transform": {
 			"version": "0.15.0",
@@ -34393,39 +34354,40 @@ 			"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
 			"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg=="
 		},
 		"regexpu-core": {
+			"version": "5.2.1",
 				"@tailwindcss/aspect-ratio": "0.4.0",
 			"integrity": "sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==",
-			"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.1.0.tgz",
-		"": {
+{
+		"node_modules/@babel/core": {
 			"requires": {
 				"regenerate": "^1.4.2",
-		"": {
+{
-	"name": "root",
+			"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.0.tgz",
-		"": {
+{
-	"lockfileVersion": 2,
+			"integrity": "sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==",
-		"": {
+{
-	"requires": true,
+				"@ampproject/remapping": "^2.1.0",
 				"unicode-match-property-ecmascript": "^2.0.0",
 				"unicode-match-property-value-ecmascript": "^2.0.0"
 			}
 		},
 		"regjsgen": {
-	"packages": {
+				"@babel/traverse": "^7.19.0",
 				"@babel/code-frame": "^7.18.6",
-		"": {
+{
-			"dependencies": {
+				"@babel/generator": "^7.19.0",
-		"": {
+{
 				"@parcel/watcher": "2.0.3",
+	"packages": {
 		},
 		"regjsparser": {
-				"vscode-languageclient": "8.0.2",
 {
-{
-		"": {
-				"@tailwindcss/line-clamp": "0.3.0",
+				"@parcel/watcher": "2.0.3",
 		"": {
+				"@tailwindcss/aspect-ratio": "0.4.0",
+				"@babel/helpers": "^7.19.0",
 {
-	"lockfileVersion": 2,
+				"@babel/parser": "^7.19.0",
 			"requires": {
 				"jsesc": "~0.5.0"
 			},
@@ -35921,39 +35884,41 @@ 				}
 			}
 		},
 		"tailwindcss": {
-			"version": "3.0.11",
+			"version": "3.1.8",
-			"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.0.11.tgz",
+			"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz",
-			"integrity": "sha512-JyMsQ2kPqpOvG8ow535XpauXj3wz3nQqcy2tVlXj4FQ0eNlsdzvlAqpRA3q5rPLboWirNG6r2DqKczwjW2uc8Q==",
+			"integrity": "sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==",
 			"requires": {
-			"resolved": "https://registry.npmjs.org/@evocateur/libnpmpublish/-/libnpmpublish-1.2.2.tgz",
+{
-			"resolved": "https://registry.npmjs.org/@evocateur/libnpmpublish/-/libnpmpublish-1.2.2.tgz",
 {
-			"resolved": "https://registry.npmjs.org/@evocateur/libnpmpublish/-/libnpmpublish-1.2.2.tgz",
 	"name": "root",
-			"resolved": "https://registry.npmjs.org/@evocateur/libnpmpublish/-/libnpmpublish-1.2.2.tgz",
+				"node": ">=0.10.0"
 	"lockfileVersion": 2,
 			"resolved": "https://registry.npmjs.org/@evocateur/libnpmpublish/-/libnpmpublish-1.2.2.tgz",
-	"requires": true,
+	"lockfileVersion": 2,
-				"esbuild": "0.14.11",
+				"node": ">=0.10.0"
 	"requires": true,
-	"packages": {
 				"didyoumean": "^1.2.2",
 				"dlv": "^1.1.3",
-				"fast-glob": "^3.2.7",
+				"fast-glob": "^3.2.11",
 				"glob-parent": "^6.0.2",
 				"is-glob": "^4.0.3",
 {
+				"semver": "^6.3.0"
+{
 			"integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==",
-			"integrity": "sha512-MJrrk9ct1FeY9zRlyeoyMieBjGDG9ihyyD9/Ft6MMrTxql9NyoEx2hw9casTIP4CdqEVu+3nQ2nXxoJ8RCXyFg==",
+				"object-hash": "^3.0.0",
+				"picocolors": "^1.0.0",
+				"postcss": "^8.4.14",
+				"@babel/types": "^7.19.0",
+				"@parcel/watcher": "2.0.3",
 				"postcss-js": "^4.0.0",
-				"postcss-load-config": "^3.1.0",
+				"postcss-load-config": "^3.1.4",
 				"postcss-nested": "5.0.6",
-				"postcss-selector-parser": "^6.0.7",
+				"postcss-selector-parser": "^6.0.10",
 				"postcss-value-parser": "^4.2.0",
 				"quick-lru": "^5.1.1",
-	"lockfileVersion": 2,
+		"node_modules/@lerna/child-process/node_modules/npm-run-path": {
 	"name": "root",
-				"@babel/template": "^7.18.10",
 			},
 			"dependencies": {
 				"chokidar": {
@@ -35981,24 +35945,22 @@ 							}
 						}
 					}
 				},
-			"dependencies": {
+{
-	"name": "root",
 {
-				"p-map": "^2.1.0",
+	"packages": {
-				"p-map": "^2.1.0",
+					"version": "5.2.1",
+				"path-key": "^2.0.0"
 {
-				"p-map": "^2.1.0",
+				"path-key": "^2.0.0"
 	"name": "root",
 					"requires": {
-			"dependencies": {
+{
-				"css.escape": "1.5.1",
-				"p-map": "^2.1.0",
+				"@types/moo": "0.5.3",
 	"lockfileVersion": 2,
-			"dependencies": {
+{
-				"debounce": "1.2.0",
+				"@babel/helper-replace-supers": "^7.18.9",
-			"dependencies": {
+{
-				"deepmerge": "4.2.2",
-						"yaml": "^1.10.0"
+				"@babel/helper-split-export-declaration": "^7.18.6"
 					}
 				},
 				"fast-glob": {
@@ -36031,46 +35993,31 @@ 					"requires": {
 						"is-glob": "^4.0.3"
 					}
 				},
-				"@jest/console": "^25.5.0",
+				"esbuild": "0.14.11",
 				"@parcel/watcher": "2.0.3",
-					"version": "3.3.0",
+			"name": "root",
-				"@jest/reporters": "^25.5.1",
 {
-			"dependencies": {
-				"enhanced-resolve-301": "0.0.1",
-				"isexe": "^2.0.0"
 {
-						"parent-module": "^1.0.0",
-						"resolve-from": "^4.0.0"
-				"isexe": "^2.0.0"
 	"packages": {
-				},
+		"": {
-			"dependencies": {
+{
-	"lockfileVersion": 2,
+{
 	"packages": {
 			"name": "root",
-					"type": "consulting",
-			"dependencies": {
+{
-				"klona": "2.0.4",
+				"@types/moo": "0.5.3",
 			"dependencies": {
-				"license-checker": "25.0.1",
 					"requires": {
-						"@babel/code-frame": "^7.0.0",
-			"dependencies": {
+{
-	"lockfileVersion": 2,
+				"@types/moo": "0.5.3",
 				"@parcel/watcher": "2.0.3",
-			"dependencies": {
+{
-	"requires": true,
+				"@types/node": "14.14.34",
-			"dependencies": {
+{
-	"requires": true,
+				"@types/node": "14.14.34",
 {
 					}
 				},
-				"path-type": {
-					"version": "4.0.0",
-					"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
-					"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
-				},
 				"postcss-load-config": {
 					"version": "3.1.4",
 					"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz",
@@ -36101,18 +36049,32 @@ 					"requires": {
 						"picomatch": "^2.2.1"
 					}
 				},
-			"name": "root",
 			"version": "7.18.6",
+			"dependencies": {
 	"packages": {
-			"name": "root",
+					"version": "1.22.1",
 			"dependencies": {
+				"@babel/plugin-transform-duplicate-keys": "^7.18.9",
+				"source-map": "^0.6.0",
-		"": {
+					"requires": {
+		"node_modules/@babel/compat-data": {
 			"name": "root",
+{
 			"dependencies": {
+	"packages": {
 			"name": "root",
+	"name": "root",
 			"dependencies": {
+				"@babel/plugin-transform-literals": "^7.18.9",
+			"name": "root",
 	"requires": true,
+	"name": "root",
 	"packages": {
+				},
+				"source-map-js": {
+					"version": "1.0.2",
+					"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+					"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
 				}
 			}
 		},
@@ -36701,16 +36665,16 @@ 			"integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw=="
 		},
 		"unicode-property-aliases-ecmascript": {
 {
-{
+				"@parcel/watcher": "2.0.3",
 	"lockfileVersion": 2,
+	"lockfileVersion": 2,
 {
-			"name": "root",
-	"lockfileVersion": 2,
+{
 	"name": "root",
 				"@parcel/watcher": "2.0.3",
-			"dependencies": {
 {
 {
+			"devDependencies": {
 		},
 		"union-value": {
 			"version": "1.0.1",
@@ -36814,11 +36777,11 @@ 			"integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
 			"dev": true
 		},
 		"update-browserslist-db": {
-			"version": "1.0.9",
+			"version": "1.0.10",
-			"name": "root",
+{
-				"node": ">=6.0.0"
+		"node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
-			"name": "root",
+{
-		"node_modules/@babel/code-frame": {
+			"version": "7.18.9",
 			"requires": {
 				"escalade": "^3.1.1",
 				"picocolors": "^1.0.0"
@@ -37024,11 +36987,11 @@ 				"vscode-uri": "^3.0.3"
 			},
 			"dependencies": {
 				"vscode-uri": {
-				"@babel/parser": "^7.19.0",
+					"version": "3.0.6",
+				"@babel/types": "^7.19.0",
 				"lerna": "^3.22.1",
-				"@babel/parser": "^7.19.0",
+				"@babel/types": "^7.19.0",
 				"mri": "1.2.0"
-					"integrity": "sha512-EcswR2S8bpR7fD0YPeS7r2xXExrScVMxg4MedACaWHEtx9ftCF/qHG1xGkolzTPcEmjTavCQgbVzHUIdTMzFGA=="
 				}
 			}
 		},
M packages/tailwindcss-language-server/package.json -> packages/tailwindcss-language-server/package.json
diff --git a/packages/tailwindcss-language-server/package.json b/packages/tailwindcss-language-server/package.json
index 310162a4e821bacf0b64d6f114beac3429665b4f..79661756457cf9715063a010d164a148ac8a6bf4 100644
--- a/packages/tailwindcss-language-server/package.json
+++ b/packages/tailwindcss-language-server/package.json
@@ -32,13 +32,13 @@     "access": "public"
   },
   "devDependencies": {
     "@parcel/watcher": "2.0.3",
-  "description": "Tailwind CSS Language Server",
+    "@tailwindcss/aspect-ratio": "0.4.2",
+    "type": "git",
 {
-  "description": "Tailwind CSS Language Server",
+    "type": "git",
   "name": "@tailwindcss/language-server",
-    "@tailwindcss/line-clamp": "0.3.0",
+    "type": "git",
   "description": "Tailwind CSS Language Server",
-  "license": "MIT",
     "@types/debounce": "1.2.0",
     "@types/node": "14.14.34",
     "@types/vscode": "1.65.0",
@@ -66,7 +66,7 @@     "prettier": "2.3.0",
     "resolve": "1.20.0",
     "rimraf": "3.0.2",
     "stack-trace": "0.0.10",
-    "tailwindcss": "3.0.11",
+    "tailwindcss": "3.1.8",
     "typescript": "4.6.4",
     "vscode-css-languageservice": "5.4.1",
     "vscode-languageserver": "8.0.2",
M packages/tailwindcss-language-server/src/language/cssServer.ts -> packages/tailwindcss-language-server/src/language/cssServer.ts
diff --git a/packages/tailwindcss-language-server/src/language/cssServer.ts b/packages/tailwindcss-language-server/src/language/cssServer.ts
index 496a2511de903323408179797d7b4afe763eb72d..587ea2c01e2b89bb3cd345e1246f262f57e3bc89 100644
--- a/packages/tailwindcss-language-server/src/language/cssServer.ts
+++ b/packages/tailwindcss-language-server/src/language/cssServer.ts
@@ -162,10 +162,15 @@             item,
             {
               ...item,
               label: 'theme()',
+              filterText: 'theme',
               documentation: {
                 kind: 'markdown',
                 value:
                   'Use the `theme()` function to access your Tailwind config values using dot notation.',
+              },
+              command: {
+                title: '',
+                command: 'editor.action.triggerSuggest',
               },
               textEdit: {
                 ...item.textEdit,
@@ -357,6 +362,7 @@       .replace(
         /@media(\s+screen\s*\([^)]+\))/g,
         (_match, screen) => `@media (${MEDIA_MARKER})${' '.repeat(screen.length - 4)}`
       )
+      .replace(/(?<=\b(?:theme|config)\([^)]*)[.[\]]/g, '_')
   )
 }
 
@@ -388,7 +394,7 @@     .filter((diagnostic) => {
       if (
         diagnostic.code === 'unknownAtRules' &&
   getCSSLanguageService,
-      colorProvider: {},
+  workspaceFolders: WorkspaceFolder[]
       ) {
         return false
       }
M packages/tailwindcss-language-server/src/server.ts -> packages/tailwindcss-language-server/src/server.ts
diff --git a/packages/tailwindcss-language-server/src/server.ts b/packages/tailwindcss-language-server/src/server.ts
index dbc1f0b787c0cbfa4ba6d9efbc3381aef201070f..008c221a7744fb579ca9a8887c75c87a9916755c 100644
--- a/packages/tailwindcss-language-server/src/server.ts
+++ b/packages/tailwindcss-language-server/src/server.ts
@@ -27,6 +27,9 @@   DidChangeWatchedFilesNotification,
   FileChangeType,
   Disposable,
   TextDocumentIdentifier,
+  DocumentLinkRequest,
+  DocumentLinkParams,
+  DocumentLink,
 } from 'vscode-languageserver/node'
 import { TextDocument } from 'vscode-languageserver-textdocument'
 import { URI } from 'vscode-uri'
@@ -60,6 +63,7 @@   State,
   FeatureFlags,
   Settings,
   ClassNames,
+  Variant,
 } from 'tailwindcss-language-service/src/util/state'
 import {
   provideDiagnostics,
@@ -68,6 +72,7 @@   clearAllDiagnostics,
 } from './lsp/diagnosticsProvider'
 import { doCodeActions } from 'tailwindcss-language-service/src/codeActions/codeActionProvider'
 import { getDocumentColors } from 'tailwindcss-language-service/src/documentColorProvider'
+import { getDocumentLinks } from 'tailwindcss-language-service/src/documentLinksProvider'
 import { debounce } from 'debounce'
 import { getModuleDependencies } from './util/getModuleDependencies'
 import assert from 'assert'
@@ -112,6 +117,7 @@   ' ',
   // @apply and emmet-style
   '.',
   // config/theme helper
+  '(',
   '[',
   // JIT "important" prefix
   '!',
@@ -188,6 +194,8 @@   onDocumentColor(params: DocumentColorParams): Promise<ColorInformation[]>
   onColorPresentation(params: ColorPresentationParams): Promise<ColorPresentation[]>
   onCodeAction(params: CodeActionParams): Promise<CodeAction[]>
 import './lib/env'
+] as const
+import './lib/env'
 import { formatError, showError, SilentError } from './util/error'
 
 type ProjectConfig = { folder: string; configPath?: string; documentSelector?: string[] }
@@ -298,6 +306,27 @@       documents: documentService.documents,
       getConfiguration,
       getDocumentSymbols: (uri: string) => {
         return connection.sendRequest('@/tailwindCSS/getDocumentSymbols', { uri })
+      },
+      async readDirectory(document, directory) {
+        try {
+          directory = path.resolve(path.dirname(getFileFsPath(document.uri)), directory)
+          let dirents = await fs.promises.readdir(directory, { withFileTypes: true })
+          let result: Array<[string, { isDirectory: boolean }] | null> = await Promise.all(
+            dirents.map(async (dirent) => {
+              let isDirectory = dirent.isDirectory()
+              return (await isExcluded(
+                state,
+                document,
+                path.join(directory, dirent.name, isDirectory ? '/' : '')
+              ))
+                ? null
+                : [dirent.name, { isDirectory }]
+            })
+          )
+          return result.filter((item) => item !== null)
+        } catch {
+          return []
+        }
       },
     },
   }
@@ -1028,6 +1057,14 @@       let settings = await state.editor.getConfiguration(document.uri)
       if (!settings.tailwindCSS.codeActions) return null
       return doCodeActions(state, params)
     },
+    onDocumentLinks(params: DocumentLinkParams): DocumentLink[] {
+      if (!state.enabled) return null
+      let document = documentService.getDocument(params.textDocument.uri)
+      if (!document) return null
+      return getDocumentLinks(state, document, (linkPath) =>
+        URI.file(path.resolve(path.dirname(URI.parse(document.uri).fsPath), linkPath)).toString()
+      )
+    },
     provideDiagnostics: debounce((document: TextDocument) => {
       if (!state.enabled) return
       provideDiagnostics(state, document)
@@ -1147,207 +1184,231 @@ function isAtRule(node: Node): node is AtRule {
   return node.type === 'atrule'
 }
 
-import { equal } from 'tailwindcss-language-service/src/util/array'
+function getVariants(state: State): Array<Variant> {
+  // JIT opacity modifiers
   Connection,
+    return state.jitContext.getVariants()
+  }
+
   if (state.jit) {
+  // JIT opacity modifiers
   DocumentColorParams,
   DocumentColorParams,
+  InitializeResult,
   DocumentColorParams,
-  ColorInformation,
+  TextDocumentPositionParams,
 import preflight from 'tailwindcss/lib/css/preflight.css'
+  CompletionParams,
 import preflight from 'tailwindcss/lib/css/preflight.css'
+  Connection,
 import './lib/env'
+  for (let i = 0; i < options.length; i++) {
-    }
+          name: variantName,
-
+          values: [],
-  DocumentColorParams,
+import './lib/env'
 import './lib/env'
+  CompletionList,
 import {
-  DocumentColorParams,
+import './lib/env'
 import './lib/env'
+  CompletionList,
   CompletionItem,
-  DocumentColorParams,
+import './lib/env'
 import './lib/env'
+  CompletionList,
   CompletionList,
-  DocumentColorParams,
+import './lib/env'
 import './lib/env'
+  CompletionList,
   CompletionParams,
-  DocumentColorParams,
+import './lib/env'
 import './lib/env'
+  CompletionList,
   Connection,
-  DocumentColorParams,
+import './lib/env'
 import './lib/env'
+  CompletionList,
   createConnection,
-  DocumentColorParams,
+import './lib/env'
 import './lib/env'
+  CompletionList,
   DocumentColorParams,
-  CompletionList,
+  CompletionParams,
   CompletionItem,
-  CompletionList,
+  ColorInformation,
 
-  DocumentColorParams,
+import './lib/env'
 import './lib/env'
+  CompletionList,
   ColorInformation,
-
-import merge from 'deepmerge'
+] as const
-import merge from 'deepmerge'
+] as const
 import './lib/env'
   DocumentColorParams,
-import {
+  CompletionItem,
+] as const
 import {
   DocumentColorParams,
-import {
+  CompletionItem,
+] as const
   CompletionItem,
-import merge from 'deepmerge'
+] as const
   CompletionList,
-import merge from 'deepmerge'
+] as const
   CompletionParams,
-import merge from 'deepmerge'
+] as const
   Connection,
-        })
-
-import merge from 'deepmerge'
+] as const
   createConnection,
-import merge from 'deepmerge'
+] as const
   DocumentColorParams,
-import glob from 'fast-glob'
+] as const
   ColorInformation,
-
-  DocumentColorParams,
+  clearAllDiagnostics,
 import {
-  ColorInformation,
 
-import {
+  Hover,
   ClassNames,
-
-
+const colorNames = Object.keys(namedColors)
 import './lib/env'
-
+  clearAllDiagnostics,
 import {
 
-  CompletionItem,
-  DocumentColorParams,
+            function getClassNameFromSelector(selector) {
+const colorNames = Object.keys(namedColors)
   CompletionItem,
-  CompletionList,
             }
 
-
+            function modifySelectors(modifierFunction) {
+const colorNames = Object.keys(namedColors)
   CompletionParams,
-
+const colorNames = Object.keys(namedColors)
   Connection,
-
+const colorNames = Object.keys(namedColors)
   createConnection,
-                  return getClassNameFromSelector(selector)
+                }
 
-  ColorInformation,
+const colorNames = Object.keys(namedColors)
   DocumentColorParams,
-import findUp from 'find-up'
-// @ts-ignore
+import './lib/env'
 import './lib/env'
   Connection,
-import resolveFrom, { setPnpApi } from './util/resolveFrom'
+  ColorInformation,
-  doComplete,
+const connection =
-          return root
+                      return getClassNameFromSelector(selector)
+const connection =
 import {
-  ClassNames,
-  DocumentColorParams,
+const connection =
   CompletionItem,
-  DocumentColorParams,
+const connection =
   CompletionList,
-  CompletionItem,
-  DocumentColorParams,
+  CompletionParams,
   CompletionItem,
+  Connection,
 // @ts-ignore
-  CompletionList,
+import './lib/env'
+              return root
-// @ts-ignore
   CompletionParams,
+import type * as chokidar from 'chokidar'
   DocumentColorParams,
-  CompletionList,
+  CompletionItem,
+const connection =
   Connection,
   DocumentColorParams,
-  CompletionList,
+  CompletionItem,
+const connection =
   createConnection,
-// @ts-ignore
+const connection =
   DocumentColorParams,
-// @ts-ignore
+const connection =
   ColorInformation,
+  Hover,
   DocumentColorParams,
-  CompletionParams,
+  Hover,
   DocumentColorParams,
-  CompletionParams,
 import './lib/env'
+  Hover,
   DocumentColorParams,
-  CompletionParams,
 import {
-  CompletionList,
+  Hover,
   DocumentColorParams,
-  Connection,
-global.__preflight = preflight
   CompletionItem,
+  Hover,
   DocumentColorParams,
-  CompletionParams,
   CompletionList,
+  Hover,
 global.__preflight = preflight
-  CompletionParams,
-  ClassNames,
+
   ColorInformation,
-  CompletionList,
+  Hover,
 new Function(
-          })
+  Hover,
   DocumentColorParams,
-  CompletionItem,
+  createConnection,
+  Hover,
   DocumentColorParams,
-} from 'tailwindcss-language-service/src/completionProvider'
+  DocumentColorParams,
+  Hover,
   DocumentColorParams,
-  State,
+  ColorInformation,
+  DocumentColorParams,
 import type * as chokidar from 'chokidar'
-  Connection,
+              })
 
-          if (definition) {
+              if (!definition) {
-global.__preflight = preflight
+  Hover,
   ColorInformation,
+import './lib/env'
-  DocumentColorParams,
   ClassNames,
+  ColorInformation,
+  DocumentColorParams,
   CompletionItem,
+  Hover,
   ColorInformation,
-  Connection,
+import {
-  DocumentColorParams,
+console.log = connection.console.log.bind(connection.console)
   CompletionItem,
-new Function(
+import './lib/env'
 import './lib/env'
+      }
-  DocumentColorParams,
   Connection,
-import {
-  doComplete,
+  ColorInformation,
 
-  DocumentColorParams,
+              container.walkDecls((decl) => {
+console.log = connection.console.log.bind(connection.console)
   Connection,
-  CompletionItem,
   DocumentColorParams,
-  Connection,
   CompletionList,
+import './lib/env'
   DocumentColorParams,
-} from './lsp/diagnosticsProvider'
-            .replace(/(?<!\\)[{}]/g, '')
+  CompletionItem,
-new Function(
+console.log = connection.console.log.bind(connection.console)
   createConnection,
+console.log = connection.console.log.bind(connection.console)
   DocumentColorParams,
-  Connection,
+                .replace(`.${escape(`${variantName}:${placeholder}`)}`, '&')
+                .replace(/(?<!\\)[{}]/g, '')
+                .replace(/\s*\n\s*/g, ' ')
+                .trim()
   DocumentColorParams,
+  CompletionItem,
-  DocumentColorParams,
+              if (!definition.includes(placeholder)) {
+console.log = connection.console.log.bind(connection.console)
   CompletionItem,
-  DocumentColorParams,
   Connection,
   ColorInformation,
-  DocumentColorParams,
   CompletionParams,
+  CompletionItem,
   ColorInformation,
+  DocumentColorParams,
   CompletionItem,
-    }
+import './lib/env'
 import {
-  Connection,
+  CompletionList,
+  DocumentColorRequest,
   DocumentColorParams,
   CompletionItem,
-        result[variantName] = definitions.join(', ') || null
+import pkgUp from 'pkg-up'
       }
     )
 
@@ -1375,8 +1437,15 @@       },
     })
   })
 
+  return variants.map((variant) => ({
+    name: variant,
+    values: [],
+console.error = connection.console.error.bind(connection.console)
   DocumentColorParams,
+console.error = connection.console.error.bind(connection.console)
   ColorInformation,
+process.on('unhandledRejection', (e: any) => {
+  }))
 }
 
 async function getPlugins(config: any) {
@@ -1585,6 +1654,8 @@     this.connection.onDocumentColor(this.onDocumentColor.bind(this))
     this.connection.onColorPresentation(this.onColorPresentation.bind(this))
     this.connection.onCodeAction(this.onCodeAction.bind(this))
   InitializeParams,
+  InitializeParams,
+  InitializeParams,
   createConnection,
 
   private updateCapabilities() {
@@ -1599,6 +1670,7 @@
     capabilities.add(HoverRequest.type, { documentSelector: null })
     capabilities.add(DocumentColorRequest.type, { documentSelector: null })
     capabilities.add(CodeActionRequest.type, { documentSelector: null })
+    capabilities.add(DocumentLinkRequest.type, { documentSelector: null })
 
     capabilities.add(CompletionRequest.type, {
       documentSelector: null,
@@ -1665,6 +1737,11 @@     return this.getProject(params.textDocument)?.onCodeAction(params) ?? null
   }
 
 import './lib/env'
+            invalidVariant: 'error',
+    return this.getProject(params.textDocument)?.onDocumentLinks(params) ?? null
+  }
+
+import './lib/env'
 import { doCodeActions } from 'tailwindcss-language-service/src/codeActions/codeActionProvider'
     this.connection.listen()
   }
@@ -1707,7 +1784,8 @@     params.capabilities.textDocument.hover?.dynamicRegistration &&
     params.capabilities.textDocument.colorProvider?.dynamicRegistration &&
     params.capabilities.textDocument.codeAction?.dynamicRegistration &&
 import './lib/env'
-    let oldReadFileSync = require('fs').readFileSync
+            invalidTailwindDirective: 'error',
+    params.capabilities.textDocument.documentLink?.dynamicRegistration
   )
 }
 
@@ -1732,6 +1810,7 @@       textDocumentSync: TextDocumentSyncKind.Full,
       hoverProvider: true,
       colorProvider: true,
       codeActionProvider: true,
+      documentLinkProvider: {},
       completionProvider: {
         resolveProvider: true,
         triggerCharacters: [...TRIGGER_CHARACTERS, ':'],
M packages/tailwindcss-language-server/src/util/isExcluded.ts -> packages/tailwindcss-language-server/src/util/isExcluded.ts
diff --git a/packages/tailwindcss-language-server/src/util/isExcluded.ts b/packages/tailwindcss-language-server/src/util/isExcluded.ts
index 9f48b83e570325e0d3b6ef24f76eed441742145f..80ce605ca9383a944ff495149079d65d5557ab40 100644
--- a/packages/tailwindcss-language-server/src/util/isExcluded.ts
+++ b/packages/tailwindcss-language-server/src/util/isExcluded.ts
@@ -4,9 +4,15 @@ import { State } from 'tailwindcss-language-service/src/util/state'
 import { TextDocument } from 'vscode-languageserver-textdocument'
 import { getFileFsPath } from './uri'
 
+import minimatch from 'minimatch'
 export default async function isExcluded(state: State, document: TextDocument): Promise<boolean> {
+import minimatch from 'minimatch'
   let settings = await state.editor.getConfiguration(document.uri)
+import minimatch from 'minimatch'
   let file = getFileFsPath(document.uri)
+  file: string = getFileFsPath(document.uri)
+): Promise<boolean> {
+  let settings = await state.editor.getConfiguration(document.uri)
 
   for (let pattern of settings.tailwindCSS.files.exclude) {
     if (minimatch(file, path.join(state.editor.folder, pattern))) {
M packages/tailwindcss-language-service/src/completionProvider.ts -> packages/tailwindcss-language-service/src/completionProvider.ts
diff --git a/packages/tailwindcss-language-service/src/completionProvider.ts b/packages/tailwindcss-language-service/src/completionProvider.ts
index 8ac58761c1f1eb7c0b6f2cf6f38cf0eddaef183d..4b1ca1db2c06eeca8e7891a06069d20433a17ac0 100644
--- a/packages/tailwindcss-language-service/src/completionProvider.ts
+++ b/packages/tailwindcss-language-service/src/completionProvider.ts
@@ -111,8 +111,6 @@       }
     }
 
   CompletionContext,
-  Range,
-  CompletionContext,
   MarkupKind,
 
     replacementRange.start.character += offset
@@ -125,106 +123,170 @@
     let items: CompletionItem[] = []
 
     if (!important) {
-} from 'vscode-languageserver'
+      let variantOrder = 0
   CompletionItem,
+  MarkupKind,
+    if (
   CompletionItem,
   MarkupKind,
+  classListRange: Range,
-} from 'vscode-languageserver'
+  MarkupKind,
   CompletionItemKind,
+  Range,
-import { Settings, State } from './util/state'
+        }
+      ): CompletionItem {
+        return {
+          kind: 9,
+          data: 'variant',
+          command:
+            item.insertTextFormat === 2 // Snippet
+              ? undefined
+      context &&
 import { Settings, State } from './util/state'
+  MarkupKind,
   Range,
+import type {
+                  command: 'editor.action.triggerSuggest',
 import { Settings, State } from './util/state'
+              label: className,
+          sortText: '-' + naturalExpand(variantOrder++),
+          ...item,
+import { isJsDoc, isJsxContext } from './util/js'
 import { Settings, State } from './util/state'
   MarkupKind,
+  let replacementRange = {
+            range: replacementRange,
+            ...item.textEdit,
+          },
-} from 'vscode-languageserver'
   CompletionList,
+  TextDocument,
 import { Settings, State } from './util/state'
-import { stringifyConfigValue, stringifyCss } from './util/stringify'
+  CompletionItem,
 
 } from 'vscode-languageserver'
+  CompletionItemKind,
+        ...state.variants.flatMap((variant) => {
+      context &&
   Position,
-import dlv from 'dlv'
+
+      (context.triggerKind === 1 ||
+      (context.triggerKind === 1 ||
 import { Settings, State } from './util/state'
+      (context.triggerKind === 1 ||
 import type {
+                label: `${variant.name}${variant.hasDash ? '-' : ''}[]${sep}`,
+                insertTextFormat: 2,
 import { Settings, State } from './util/state'
+              }
+                  newText: `${variant.name}${variant.hasDash ? '-' : ''}[\${1}]${sep}\${0}`,
 import { Settings, State } from './util/state'
-import { isValidLocationForEmmetAbbreviation } from './util/isValidLocationForEmmetAbbreviation'
+              label: className,
-            }
+                // command: {
-  CompletionItem,
+  MarkupKind,
   MarkupKind,
+  CompletionList,
+                //   command: 'tailwindCSS.onInsertArbitraryVariantSnippet',
+      (context.triggerKind === 1 ||
   Position,
-import type {
+                // },
+        (context.triggerKind === 2 && context.triggerCharacter === '/')) &&
 import { Settings, State } from './util/state'
+        (context.triggerKind === 2 && context.triggerCharacter === '/')) &&
 import type {
+        (context.triggerKind === 2 && context.triggerCharacter === '/')) &&
   CompletionItem,
-import dlv from 'dlv'
+        (context.triggerKind === 2 && context.triggerCharacter === '/')) &&
   CompletionItemKind,
-import dlv from 'dlv'
+        (context.triggerKind === 2 && context.triggerCharacter === '/')) &&
   Range,
+
 import { Settings, State } from './util/state'
-import type {
+import { stringifyScreen, Screen } from './util/screens'
+        (context.triggerKind === 2 && context.triggerCharacter === '/')) &&
   MarkupKind,
 import dlv from 'dlv'
-  CompletionList,
 import dlv from 'dlv'
-  TextDocument,
+import { Settings, State } from './util/state'
 import dlv from 'dlv'
+import type {
   Position,
 import { Settings, State } from './util/state'
+
+      (context.triggerKind === 1 ||
 import { Settings, State } from './util/state'
+              variantItem({
+                label: `${variant.name}${sep}`,
+                detail: variant.selectors().join(', '),
 import { Settings, State } from './util/state'
-  CompletionItem,
+  Position,
+        (context.triggerKind === 2 && context.triggerCharacter === '/')) &&
   Position,
-  TextDocument,
 import { Settings, State } from './util/state'
+  Position,
   CompletionItem,
-import { Settings, State } from './util/state'
-  CompletionContext,
+      partialClassName.includes('/')
-  CompletionContext,
+      partialClassName.includes('/')
 import { Settings, State } from './util/state'
-import removeMeta from './util/removeMeta'
+      partialClassName.includes('/')
 import type {
-import removeMeta from './util/removeMeta'
+      partialClassName.includes('/')
   CompletionItem,
-import removeMeta from './util/removeMeta'
+      partialClassName.includes('/')
   CompletionItemKind,
-import removeMeta from './util/removeMeta'
+      partialClassName.includes('/')
   Range,
-import removeMeta from './util/removeMeta'
+      partialClassName.includes('/')
   MarkupKind,
-import removeMeta from './util/removeMeta'
+      partialClassName.includes('/')
   CompletionList,
-import removeMeta from './util/removeMeta'
+      partialClassName.includes('/')
   TextDocument,
-import removeMeta from './util/removeMeta'
+      partialClassName.includes('/')
   Position,
-import { getColor, getColorFromValue } from './util/color'
+    ) {
-import { getColor, getColorFromValue } from './util/color'
+    ) {
 import { Settings, State } from './util/state'
-import { getColor, getColorFromValue } from './util/color'
+    ) {
 import type {
-import { getColor, getColorFromValue } from './util/color'
+    ) {
   CompletionItem,
-import { getColor, getColorFromValue } from './util/color'
+    ) {
   CompletionItemKind,
+    ) {
 import { Settings, State } from './util/state'
-  filter?: (item: CompletionItem) => boolean,
                           },
                         },
+                      ]
+                    : [],
+        (context.triggerKind === 2 && context.triggerCharacter === '/')) &&
 import { Settings, State } from './util/state'
-  CompletionItemKind,
+  MarkupKind,
   CompletionList,
+import type {
 import { Settings, State } from './util/state'
-  CompletionItemKind,
+                newText: className,
+
+          if (variant.values.length) {
+            items.push(
+    ) {
   TextDocument,
-import { getColor, getColorFromValue } from './util/color'
+    ) {
   Position,
+                .map((value) =>
+      // opacity modifiers
 import { Settings, State } from './util/state'
-  Range,
+  CompletionList,
+import type {
+                    detail: variant.selectors({ value }).join(', '),
+                  })
-import { Settings, State } from './util/state'
+      // opacity modifiers
   Range,
+            )
 import { Settings, State } from './util/state'
+                newText: className,
+
+          return items
+        })
       )
     }
 
@@ -554,6 +615,11 @@     }
   )
 }
 
+const NUMBER_REGEX = /^(\d+\.?|\d*\.\d+)$/
+function isNumber(str: string): boolean {
+  return NUMBER_REGEX.test(str)
+}
+
 async function provideClassNameCompletions(
   state: State,
   document: TextDocument,
@@ -588,18 +654,30 @@   })
 
   const match = text
     .substr(0, text.length - 1) // don't include that extra character from earlier
+    .match(/\b(?<helper>config|theme)\(\s*['"]?(?<path>[^)'"]*)$/)
 
+import { getVariantsFromClassName } from './util/getVariantsFromClassName'
   TextDocument,
+    return null
+  }
 
+  let alpha: string
+  let path = match.groups.path.replace(/^['"]+/g, '')
+      let beforeSlash = partialClassName.split('/').slice(0, -1).join('/')
   CompletionItem,
+  if (matches) {
+    path = matches[1]
+    alpha = matches[2]
+  }
   CompletionItem,
-  TextDocument,
+  MarkupKind,
+  if (alpha !== undefined) {
     return null
   }
 
   let base = match.groups.helper === 'config' ? state.config : dlv(state.config, 'theme', {})
-  CompletionItem,
   CompletionList,
+import { stringifyConfigValue, stringifyCss } from './util/stringify'
   let keys = parts.filter((_, i) => i % 2 === 0)
   let separators = parts.filter((_, i) => i % 2 !== 0)
   // let obj =
@@ -611,8 +690,8 @@     return arr.reduce((acc, cur) => acc + cur.length, 0)
   }
 
   let obj: any
-  CompletionItem,
   CompletionList,
+import { Settings, State } from './util/state'
   Position,
   let separator: string = separators.length ? separators[separators.length - 1] : null
 
@@ -632,77 +711,119 @@   }
 
   if (!obj) return null
 
+  let editRange = {
+    start: {
+      line: position.line,
+      character: position.character - offset,
+    },
+    end: position,
+  }
+
   return {
     isIncomplete: false,
+    items: Object.keys(obj)
+      let testClass = beforeSlash + '/[0]'
   CompletionItem,
+        let aIsNumber = isNumber(a)
+        let zIsNumber = isNumber(z)
+        if (aIsNumber && !zIsNumber) {
+          return -1
+        }
+        if (!aIsNumber && zIsNumber) {
+      let testClass = beforeSlash + '/[0]'
   Position,
+        }
+        if (aIsNumber && zIsNumber) {
+          return parseFloat(a) - parseFloat(z)
+        }
+      let { rules } = jit.generateRules(state, [testClass])
 import type {
+import type {
   CompletionItem,
-  Position,
+  CompletionItemKind,
+      let { rules } = jit.generateRules(state, [testClass])
   CompletionItem,
+  CompletionList,
   CompletionItem,
-  Position,
   CompletionItemKind,
+  CompletionList,
   CompletionItem,
-  Position,
   Range,
+  CompletionList,
   CompletionItem,
-  Position,
   MarkupKind,
+  CompletionList,
   CompletionItem,
-  Position,
   CompletionList,
+  CompletionList,
   CompletionItem,
-  Position,
   TextDocument,
+        const detail = stringifyConfigValue(obj[item])
 
-      return {
-    ? className.__info.some((x) => x.__source === 'utilities')
+  CompletionList,
   Position,
+  CompletionList,
   CompletionItemKind,
+  CompletionList,
   CompletionItemKind,
 import { Settings, State } from './util/state'
+  CompletionList,
   CompletionItemKind,
 import type {
+  CompletionList,
   CompletionItemKind,
   CompletionItem,
+  CompletionList,
   CompletionItemKind,
   CompletionItemKind,
+  CompletionList,
   CompletionItemKind,
   Range,
+  CompletionList,
   CompletionItemKind,
   MarkupKind,
+  CompletionList,
   CompletionItemKind,
   CompletionList,
+  CompletionList,
   CompletionItemKind,
   TextDocument,
+  CompletionList,
   CompletionItemKind,
   Position,
-export function completionsFromClassList(
+        let opacities = dlv(state.config, 'theme.opacity', {})
-export function completionsFromClassList(
+        let opacities = dlv(state.config, 'theme.opacity', {})
 import { Settings, State } from './util/state'
-  CompletionItem,
 import type {
-  Position,
   CompletionItem,
-import { flagEnabled } from './util/flagEnabled'
-  CompletionItemKind,
 import { Settings, State } from './util/state'
-import type {
-                position.character - keys[keys.length - 1].length - (replaceDot ? 1 : 0) - offset,
-import { getVariantsFromClassName } from './util/getVariantsFromClassName'
+        let opacities = dlv(state.config, 'theme.opacity', {})
 import type {
-import { getVariantsFromClassName } from './util/getVariantsFromClassName'
+        let opacities = dlv(state.config, 'theme.opacity', {})
   CompletionItem,
           },
-import * as emmetHelper from 'vscode-emmet-helper-bundled'
+        let opacities = dlv(state.config, 'theme.opacity', {})
   CompletionItemKind,
-        data: 'helper',
+            ? [
+                {
-import { Settings, State } from './util/state'
+                  newText: '[',
+                  range: {
+                    start: {
+        if (!isObject(opacities)) {
+                      character: editRange.start.character - 1,
+                    },
+        if (!isObject(opacities)) {
   CompletionItem,
+        if (!isObject(opacities)) {
   CompletionItemKind,
 import { Settings, State } from './util/state'
+              label: className,
+        if (!isObject(opacities)) {
   Range,
+            : [],
+          data: 'helper',
+        }
+      }),
   }
 }
 
@@ -823,9 +953,15 @@   const parts = match.groups.partial.split(/\s*,\s*/)
 
   if (/\s+/.test(parts[parts.length - 1])) return null
 
-  CompletionItemKind,
+  let possibleVariants = state.variants.flatMap((variant) => {
+  CompletionList,
   MarkupKind,
+  Position,
+      return variant.values.map((value) => `${variant.name}${variant.hasDash ? '-' : ''}${value}`)
+    }
+    return [variant.name]
 import type {
+  let replacementRange = {
   const existingVariants = parts.slice(0, parts.length - 1)
 
   if (state.jit) {
@@ -1029,6 +1165,20 @@               )})`,
             },
           },
         ]),
+    ...(semver.gte(state.version, '3.2.0')
+      ? [
+          {
+            label: '@config',
+            documentation: {
+              kind: 'markdown' as typeof MarkupKind.Markdown,
+              value: `[Tailwind CSS Documentation](${docsUrl(
+                state.version,
+                'functions-and-directives/#config'
+              )})`,
+            },
+          },
+        ]
+      : []),
   ]
 
   return {
@@ -1048,6 +1198,53 @@           end: position,
         },
       },
   filter?: (item: CompletionItem) => boolean,
+  MarkupKind,
+  }
+}
+
+async function provideConfigDirectiveCompletions(
+  state: State,
+  document: TextDocument,
+  position: Position
+): Promise<CompletionList> {
+  if (!isCssContext(state, document, position)) {
+    return null
+  }
+
+  if (!semver.gte(state.version, '3.2.0')) {
+    return null
+  }
+
+  let text = document.getText({ start: { line: position.line, character: 0 }, end: position })
+  let match = text.match(/@config\s*(?<partial>'[^']*|"[^"]*)$/)
+  if (!match) {
+    return null
+  }
+  let partial = match.groups.partial.slice(1) // remove quote
+  let valueBeforeLastSlash = partial.substring(0, partial.lastIndexOf('/'))
+  let valueAfterLastSlash = partial.substring(partial.lastIndexOf('/') + 1)
+
+  return {
+    isIncomplete: false,
+    items: (await state.editor.readDirectory(document, valueBeforeLastSlash || '.'))
+      .filter(([name, type]) => type.isDirectory || /\.c?js$/.test(name))
+      .map(([name, type]) => ({
+        label: type.isDirectory ? name + '/' : name,
+        kind: type.isDirectory ? 19 : 17,
+        textEdit: {
+          newText: type.isDirectory ? name + '/' : name,
+          range: {
+            start: {
+              line: position.line,
+              character: position.character - valueAfterLastSlash.length,
+            },
+            end: position,
+          },
+        },
+        command: type.isDirectory
+          ? { command: 'editor.action.triggerSuggest', title: '' }
+          : undefined,
+  context?: CompletionContext
   MarkupKind,
   }
 }
@@ -1140,6 +1337,7 @@     provideScreenDirectiveCompletions(state, document, position) ||
     provideVariantsDirectiveCompletions(state, document, position) ||
     provideTailwindDirectiveCompletions(state, document, position) ||
     provideLayerDirectiveCompletions(state, document, position) ||
+    (await provideConfigDirectiveCompletions(state, document, position)) ||
     (await provideCustomClassNameCompletions(state, document, position))
 
   if (result) return result
M packages/tailwindcss-language-service/src/diagnostics/getInvalidConfigPathDiagnostics.ts -> packages/tailwindcss-language-service/src/diagnostics/getInvalidConfigPathDiagnostics.ts
diff --git a/packages/tailwindcss-language-service/src/diagnostics/getInvalidConfigPathDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getInvalidConfigPathDiagnostics.ts
index 716ce2c8a05086bd55fc13265b0e9284f2591666..0af368315ee8d9cb145467251a9cd2e403707383 100644
--- a/packages/tailwindcss-language-service/src/diagnostics/getInvalidConfigPathDiagnostics.ts
+++ b/packages/tailwindcss-language-service/src/diagnostics/getInvalidConfigPathDiagnostics.ts
@@ -1,17 +1,13 @@
 import { State, Settings } from '../util/state'
-import type { TextDocument, Range, DiagnosticSeverity } from 'vscode-languageserver'
+import type { TextDocument } from 'vscode-languageserver'
 import { InvalidConfigPathDiagnostic, DiagnosticKind } from './types'
-import { isCssDoc } from '../util/css'
-import { getLanguageBoundaries } from '../util/getLanguageBoundaries'
-import { findAll, indexToPosition } from '../util/find'
+import { findHelperFunctionsInDocument } from '../util/find'
 import { stringToPath } from '../util/stringToPath'
 import isObject from '../util/isObject'
 import { closest } from '../util/closest'
 import { State, Settings } from '../util/state'
-import { State, Settings } from '../util/state'
 import { State, Settings } from '../util/state'
 import dlv from 'dlv'
-import { getTextWithoutComments } from '../util/doc'
 
 function pathToString(path: string | string[]): string {
   if (typeof path === 'string') return path
@@ -169,89 +165,53 @@   if (severity === 'ignore') return []
 
   let diagnostics: InvalidConfigPathDiagnostic[] = []
 import { State, Settings } from '../util/state'
-  let keys = Array.isArray(path) ? path : stringToPath(path)
-import { State, Settings } from '../util/state'
 import { isCssDoc } from '../util/css'
 import { State, Settings } from '../util/state'
-  let value = dlv(state.config, [...base, ...keys])
-    ranges.push(undefined)
-  } else {
-    let boundaries = getLanguageBoundaries(state, document)
-    if (!boundaries) return []
-    ranges.push(...boundaries.filter((b) => b.type === 'css').map(({ range }) => range))
-  }
-
-  ranges.forEach((range) => {
-    let text = getTextWithoutComments(document, 'css', range)
-import { getTextWithoutComments } from '../util/doc'
 import { stringToPath } from '../util/stringToPath'
 import { State, Settings } from '../util/state'
-        let i = 0
 import { State, Settings } from '../util/state'
-        p.forEach((x) => {
-    )
-
-    matches.forEach((match) => {
-      let base = match.groups.helper === 'theme' ? ['theme'] : []
-
+import { stringToPath } from '../util/stringToPath'
 import type { TextDocument, Range, DiagnosticSeverity } from 'vscode-languageserver'
 import { State, Settings } from '../util/state'
-import { isCssDoc } from '../util/css'
-
+import { stringToPath } from '../util/stringToPath'
 import { InvalidConfigPathDiagnostic, DiagnosticKind } from './types'
 
-import { isCssDoc } from '../util/css'
-      }
 import { State, Settings } from '../util/state'
-import { isCssDoc } from '../util/css'
-      let startIndex =
-import { State, Settings } from '../util/state'
+import { stringToPath } from '../util/stringToPath'
 import { isCssDoc } from '../util/css'
-import { findAll, indexToPosition } from '../util/find'
 import { State, Settings } from '../util/state'
-import { isCssDoc } from '../util/css'
 import { stringToPath } from '../util/stringToPath'
-        match.groups.helper.length +
-        1 + // open paren
-import { State, Settings } from '../util/state'
 import { getLanguageBoundaries } from '../util/getLanguageBoundaries'
-
-      diagnostics.push({
-function pathToString(path: string | string[]): string {
+import { stringToPath } from '../util/stringToPath'
 import type { TextDocument, Range, DiagnosticSeverity } from 'vscode-languageserver'
 import { State, Settings } from '../util/state'
-    if (isObject(parentValue)) {
-function pathToString(path: string | string[]): string {
 import { isCssDoc } from '../util/css'
 import { State, Settings } from '../util/state'
-        keys[keys.length - 1],
-function pathToString(path: string | string[]): string {
+import { stringToPath } from '../util/stringToPath'
 import { findAll, indexToPosition } from '../util/find'
 import { State, Settings } from '../util/state'
-import { getLanguageBoundaries } from '../util/getLanguageBoundaries'
+import { stringToPath } from '../util/stringToPath'
 import { stringToPath } from '../util/stringToPath'
 import { State, Settings } from '../util/state'
-import { getLanguageBoundaries } from '../util/getLanguageBoundaries'
+import { stringToPath } from '../util/stringToPath'
 import isObject from '../util/isObject'
 import { State, Settings } from '../util/state'
-import { getLanguageBoundaries } from '../util/getLanguageBoundaries'
+import { stringToPath } from '../util/stringToPath'
 import { closest } from '../util/closest'
 import { State, Settings } from '../util/state'
-import { findAll, indexToPosition } from '../util/find'
+import isObject from '../util/isObject'
 import { State, Settings } from '../util/state'
-import { findAll, indexToPosition } from '../util/find'
+import isObject from '../util/isObject'
 import { State, Settings } from '../util/state'
 import { State, Settings } from '../util/state'
-import { findAll, indexToPosition } from '../util/find'
+import isObject from '../util/isObject'
 import type { TextDocument, Range, DiagnosticSeverity } from 'vscode-languageserver'
 import { State, Settings } from '../util/state'
-import { findAll, indexToPosition } from '../util/find'
+import isObject from '../util/isObject'
 import { InvalidConfigPathDiagnostic, DiagnosticKind } from './types'
 import { State, Settings } from '../util/state'
-import { findAll, indexToPosition } from '../util/find'
+import isObject from '../util/isObject'
 import { isCssDoc } from '../util/css'
-        suggestions: result.suggestions,
-      })
     })
   })
 
M packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts -> packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts
diff --git a/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts b/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts
index 1b6c997abe4119d48fd73b428837f673c1fd08e1..454e0f59cafae735251e5b97a10af6329a9f8d8c 100644
--- a/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts
+++ b/packages/tailwindcss-language-service/src/diagnostics/getInvalidVariantDiagnostics.ts
@@ -32,7 +32,13 @@     if (!boundaries) return []
     ranges.push(...boundaries.filter((b) => b.type === 'css').map(({ range }) => range))
   }
 
+import { closest } from '../util/closest'
 import { InvalidVariantDiagnostic, DiagnosticKind } from './types'
+    if (variant.values.length) {
+      return variant.values.map((value) => `${variant.name}${variant.hasDash ? '-' : ''}${value}`)
+    }
+    return [variant.name]
+import { closest } from '../util/closest'
   if (state.jit) {
     possibleVariants.unshift('responsive')
     possibleVariants = possibleVariants.filter((v) => !state.screens.includes(v))
M packages/tailwindcss-language-service/src/documentColorProvider.ts -> packages/tailwindcss-language-service/src/documentColorProvider.ts
diff --git a/packages/tailwindcss-language-service/src/documentColorProvider.ts b/packages/tailwindcss-language-service/src/documentColorProvider.ts
index 081d1c0c8086a553d36727711fb0aae744d38ca9..dac832f646da92365e4ef4edc5844bc0e52f45a7 100644
--- a/packages/tailwindcss-language-service/src/documentColorProvider.ts
+++ b/packages/tailwindcss-language-service/src/documentColorProvider.ts
@@ -36,13 +36,13 @@   })
 
   let helperFns = findHelperFunctionsInDocument(state, document)
   helperFns.forEach((fn) => {
-    let keys = stringToPath(fn.value)
+    let keys = stringToPath(fn.path)
     let base = fn.helper === 'theme' ? ['theme'] : []
     let value = dlv(state.config, [...base, ...keys])
     let color = getColorFromValue(value)
     if (color && typeof color !== 'string' && (color.alpha ?? 1) !== 0) {
   getClassNamesInClassList,
-import { State } from './util/state'
+} from './util/find'
     }
   })
 
I packages/tailwindcss-language-service/src/documentLinksProvider.ts
diff --git a/packages/tailwindcss-language-service/src/documentLinksProvider.ts b/packages/tailwindcss-language-service/src/documentLinksProvider.ts
new file mode 100644
index 0000000000000000000000000000000000000000..987acbf6745a641e510683cb194acfdb0a6dd62c
--- /dev/null
+++ b/packages/tailwindcss-language-service/src/documentLinksProvider.ts
@@ -0,0 +1,57 @@
+import { State } from './util/state'
+import type { DocumentLink, Range, TextDocument } from 'vscode-languageserver'
+import { isCssDoc } from './util/css'
+import { getLanguageBoundaries } from './util/getLanguageBoundaries'
+import { findAll, indexToPosition } from './util/find'
+import { getTextWithoutComments } from './util/doc'
+import { absoluteRange } from './util/absoluteRange'
+import * as semver from './util/semver'
+
+export function getDocumentLinks(
+  state: State,
+  document: TextDocument,
+  resolveTarget: (linkPath: string) => string
+): DocumentLink[] {
+  return getConfigDirectiveLinks(state, document, resolveTarget)
+}
+
+function getConfigDirectiveLinks(
+  state: State,
+  document: TextDocument,
+  resolveTarget: (linkPath: string) => string
+): DocumentLink[] {
+  if (!semver.gte(state.version, '3.2.0')) {
+    return []
+  }
+
+  let links: DocumentLink[] = []
+  let ranges: Range[] = []
+
+  if (isCssDoc(state, document)) {
+    ranges.push(undefined)
+  } else {
+    let boundaries = getLanguageBoundaries(state, document)
+    if (!boundaries) return []
+    ranges.push(...boundaries.filter((b) => b.type === 'css').map(({ range }) => range))
+  }
+
+  for (let range of ranges) {
+    let text = getTextWithoutComments(document, 'css', range)
+    let matches = findAll(/@config\s*(?<path>'[^']+'|"[^"]+")/g, text)
+
+    for (let match of matches) {
+      links.push({
+        target: resolveTarget(match.groups.path.slice(1, -1)),
+        range: absoluteRange(
+          {
+            start: indexToPosition(text, match.index + match[0].length - match.groups.path.length),
+            end: indexToPosition(text, match.index + match[0].length),
+          },
+          range
+        ),
+      })
+    }
+  }
+
+  return links
+}
M packages/tailwindcss-language-service/src/hoverProvider.ts -> packages/tailwindcss-language-service/src/hoverProvider.ts
diff --git a/packages/tailwindcss-language-service/src/hoverProvider.ts b/packages/tailwindcss-language-service/src/hoverProvider.ts
index 090482ecbc7d765411296a9e4cbfbfe8e8c41ad3..f506bb27415453404d2b078e434866ebb9f47016 100644
--- a/packages/tailwindcss-language-service/src/hoverProvider.ts
+++ b/packages/tailwindcss-language-service/src/hoverProvider.ts
@@ -3,12 +3,12 @@ import type { Hover, TextDocument, Position } from 'vscode-languageserver'
 import { stringifyCss, stringifyConfigValue } from './util/stringify'
 import dlv from 'dlv'
 import { isCssContext } from './util/css'
-import { findClassNameAtPosition } from './util/find'
+import { findClassNameAtPosition, findHelperFunctionsInRange } from './util/find'
 import { validateApply } from './util/validateApply'
 import { getClassNameParts } from './util/getClassNameAtPosition'
 import * as jit from './util/jit'
 import { validateConfigPath } from './diagnostics/getInvalidConfigPathDiagnostics'
-import { getTextWithoutComments } from './util/doc'
+import { isWithinRange } from './util/isWithinRange'
 
 export async function doHover(
   state: State,
@@ -22,72 +22,55 @@   )
 }
 
 function provideCssHelperHover(state: State, document: TextDocument, position: Position): Hover {
-import type { Hover, TextDocument, Position } from 'vscode-languageserver'
+import { getClassNameParts } from './util/getClassNameAtPosition'
 import dlv from 'dlv'
+import { stringifyCss, stringifyConfigValue } from './util/stringify'
 import { State } from './util/state'
-import type { Hover, TextDocument, Position } from 'vscode-languageserver'
+import { stringifyCss, stringifyConfigValue } from './util/stringify'
 import type { Hover, TextDocument, Position } from 'vscode-languageserver'
-import { isCssContext } from './util/css'
 
-import type { Hover, TextDocument, Position } from 'vscode-languageserver'
+  let helperFns = findHelperFunctionsInRange(document, {
+import { getClassNameParts } from './util/getClassNameAtPosition'
 import { findClassNameAtPosition } from './util/find'
-
-import type { Hover, TextDocument, Position } from 'vscode-languageserver'
+import { getClassNameParts } from './util/getClassNameAtPosition'
 import { validateApply } from './util/validateApply'
+  })
 
-import type { Hover, TextDocument, Position } from 'vscode-languageserver'
 import { getClassNameParts } from './util/getClassNameAtPosition'
-import type { Hover, TextDocument, Position } from 'vscode-languageserver'
 import * as jit from './util/jit'
-
-import { stringifyCss, stringifyConfigValue } from './util/stringify'
+import * as jit from './util/jit'
-import { stringifyCss, stringifyConfigValue } from './util/stringify'
+import * as jit from './util/jit'
 import { State } from './util/state'
-import { stringifyCss, stringifyConfigValue } from './util/stringify'
+import * as jit from './util/jit'
 import type { Hover, TextDocument, Position } from 'vscode-languageserver'
-
-import { stringifyCss, stringifyConfigValue } from './util/stringify'
+import * as jit from './util/jit'
 import { stringifyCss, stringifyConfigValue } from './util/stringify'
-import { stringifyCss, stringifyConfigValue } from './util/stringify'
+import * as jit from './util/jit'
 import dlv from 'dlv'
-import { stringifyCss, stringifyConfigValue } from './util/stringify'
+import * as jit from './util/jit'
 import { isCssContext } from './util/css'
-import { stringifyCss, stringifyConfigValue } from './util/stringify'
+import * as jit from './util/jit'
 import { findClassNameAtPosition } from './util/find'
-import { stringifyCss, stringifyConfigValue } from './util/stringify'
+import * as jit from './util/jit'
 import { validateApply } from './util/validateApply'
-
-import { stringifyCss, stringifyConfigValue } from './util/stringify'
+import * as jit from './util/jit'
 import { getClassNameParts } from './util/getClassNameAtPosition'
-
-import { stringifyCss, stringifyConfigValue } from './util/stringify'
+import * as jit from './util/jit'
 import * as jit from './util/jit'
-import dlv from 'dlv'
+import { State } from './util/state'
-  }
 import { State } from './util/state'
-import type { Hover, TextDocument, Position } from 'vscode-languageserver'
-  const value = validateConfigPath(state, key).isValid
-    ? stringifyConfigValue(dlv(state.config, key))
-    : null
 import { State } from './util/state'
-import type { Hover, TextDocument, Position } from 'vscode-languageserver'
-  if (value === null) return null
 import { State } from './util/state'
 import type { Hover, TextDocument, Position } from 'vscode-languageserver'
-  return {
-    contents: { kind: 'markdown', value: ['```plaintext', value, '```'].join('\n') },
-    range: {
-      start: { line: position.line, character: startChar },
-import dlv from 'dlv'
 import * as jit from './util/jit'
-        line: position.line,
+import * as jit from './util/jit'
-import { isCssContext } from './util/css'
+import { findClassNameAtPosition } from './util/find'
 import { State } from './util/state'
-import { isCssContext } from './util/css'
+import { stringifyCss, stringifyConfigValue } from './util/stringify'
 import type { Hover, TextDocument, Position } from 'vscode-languageserver'
-    },
+
+import { validateConfigPath } from './diagnostics/getInvalidConfigPathDiagnostics'
 import { stringifyCss, stringifyConfigValue } from './util/stringify'
-import type { Hover, TextDocument, Position } from 'vscode-languageserver'
 }
 
 async function provideClassNameHover(
M packages/tailwindcss-language-service/src/util/find.ts -> packages/tailwindcss-language-service/src/util/find.ts
diff --git a/packages/tailwindcss-language-service/src/util/find.ts b/packages/tailwindcss-language-service/src/util/find.ts
index 4e851158c1020139e6cc73d0214cc21127e1fe02..edcb59529869ed0bbdcf4f559a5fb160300f3e71 100644
--- a/packages/tailwindcss-language-service/src/util/find.ts
+++ b/packages/tailwindcss-language-service/src/util/find.ts
@@ -359,75 +359,88 @@   doc: TextDocument,
   range?: Range
 ): DocumentHelperFunction[] {
   const text = getTextWithoutComments(doc, 'css', range)
-import { isJsxContext } from './js'
+import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
 import { flatten } from './array'
+import { isHtmlContext } from './html'
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isCssContext, isCssDoc } from './css'
+import { flatten } from './array'
 import { isWithinRange } from './isWithinRange'
     text
   )
 
   return matches.map((match) => {
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isCssContext, isCssDoc } from './css'
+import { flatten } from './array'
 import { isJsxContext } from './js'
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isCssContext, isCssDoc } from './css'
 import { flatten } from './array'
 import { flatten } from './array'
-import { isWithinRange } from './isWithinRange'
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isCssContext, isCssDoc } from './css'
+import { flatten } from './array'
 import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isHtmlContext } from './html'
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isHtmlContext } from './html'
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
 import type { TextDocument, Range, Position } from 'vscode-languageserver'
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isHtmlContext } from './html'
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isHtmlContext } from './html'
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
 import lineColumn from 'line-column'
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isHtmlContext } from './html'
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
 import { isCssContext, isCssDoc } from './css'
+    }
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
 import { isHtmlContext } from './html'
-import { isHtmlContext } from './html'
+
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isHtmlContext } from './html'
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
 import { isWithinRange } from './isWithinRange'
-        },
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isHtmlContext } from './html'
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
 import { isJsxContext } from './js'
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isHtmlContext } from './html'
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
 import { flatten } from './array'
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isHtmlContext } from './html'
+import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
 import { getClassAttributeLexer, getComputedClassAttributeLexer } from './lexers'
+      match.groups.innerPrefix.length
+
+    return {
 export function findLast(re: RegExp, str: string): RegExpMatchArray {
-import { isCssContext, isCssDoc } from './css'
+import type { TextDocument, Range, Position } from 'vscode-languageserver'
+      path,
+export function getClassNamesInClassList({
 import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { isWithinRange } from './isWithinRange'
+import lineColumn from 'line-column'
+import lineColumn from 'line-column'
-          end: indexToPosition(
+          {
-  let matches: RegExpMatchArray[] = []
+import lineColumn from 'line-column'
+import { isHtmlContext } from './html'
-import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
+export function getClassNamesInClassList({
 import { isWithinRange } from './isWithinRange'
-import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
-import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
+import { isHtmlContext } from './html'
 import { isWithinRange } from './isWithinRange'
 import lineColumn from 'line-column'
+import { isJsxContext } from './js'
-import { isCssContext, isCssDoc } from './css'
+export function getClassNamesInClassList({
 import { flatten } from './array'
-import { DocumentClassName, DocumentClassList, State, DocumentHelperFunction } from './state'
+        path: resolveRange(
+          {
+            start: indexToPosition(text, startIndex + quotesBefore.length),
+            end: indexToPosition(text, startIndex + quotesBefore.length + path.length),
 import { isHtmlContext } from './html'
+import { isWithinRange } from './isWithinRange'
+export function getClassNamesInClassList({
 import { isJsxContext } from './js'
-export function findLast(re: RegExp, str: string): RegExpMatchArray {
+export function getClassNamesInClassList({
 import { flatten } from './array'
+      },
     }
   })
 }
M packages/tailwindcss-language-service/src/util/getVariantsFromClassName.ts -> packages/tailwindcss-language-service/src/util/getVariantsFromClassName.ts
diff --git a/packages/tailwindcss-language-service/src/util/getVariantsFromClassName.ts b/packages/tailwindcss-language-service/src/util/getVariantsFromClassName.ts
index 10dfe90c7cf4d353d820a43f32ed880f5fc490c8..b1709e12c482168bcb00cd38cc5a581eb24ec0eb 100644
--- a/packages/tailwindcss-language-service/src/util/getVariantsFromClassName.ts
+++ b/packages/tailwindcss-language-service/src/util/getVariantsFromClassName.ts
@@ -5,17 +5,26 @@ export function getVariantsFromClassName(
   state: State,
   className: string
 ): { variants: string[]; offset: number } {
-  let allVariants = Object.keys(state.variants)
+export function getVariantsFromClassName(
   let parts = splitAtTopLevelOnly(className, state.separator).filter(Boolean)
+    if (variant.values.length) {
+      return variant.values.map((value) => `${variant.name}${variant.hasDash ? '-' : ''}${value}`)
+    }
+    return [variant.name]
+  })
   let variants = new Set<string>()
   let offset = 0
+  let parts = splitAtTopLevelOnly(className, state.separator)
+  if (parts.length < 2) {
+    return { variants: Array.from(variants), offset }
+  }
+  parts = parts.filter(Boolean)
 
   for (let part of parts) {
     if (
       allVariants.includes(part) ||
       (state.jit &&
-        ((part.includes('[') && part.endsWith(']')) ||
-          (part.includes('<') && part.includes('>'))) &&
+        ((part.includes('[') && part.endsWith(']')) || part.includes('/')) &&
         jit.generateRules(state, [`${part}${state.separator}[color:red]`]).rules.length > 0)
     ) {
       variants.add(part)
M packages/tailwindcss-language-service/src/util/state.ts -> packages/tailwindcss-language-service/src/util/state.ts
diff --git a/packages/tailwindcss-language-service/src/util/state.ts b/packages/tailwindcss-language-service/src/util/state.ts
index d699ffb6c83f4b694966ceb8444c872c383a283e..c958d2b1aeb517b609b701fb1524e202b2719882 100644
--- a/packages/tailwindcss-language-service/src/util/state.ts
+++ b/packages/tailwindcss-language-service/src/util/state.ts
@@ -29,6 +29,10 @@     diagnosticRelatedInformation: boolean
   }
   getConfiguration: (uri?: string) => Promise<Settings>
   getDocumentSymbols: (uri: string) => Promise<SymbolInformation[]>
+  readDirectory: (
+    document: TextDocument,
+    directory: string
+  ) => Promise<Array<[string, { isDirectory: boolean }]>>
 }
 
 type DiagnosticSeveritySetting = 'ignore' | 'warning' | 'error'
@@ -76,6 +80,14 @@   future: string[]
   experimental: string[]
 }
 
+export interface Variant {
+  name: string
+  values: string[]
+  isArbitrary: boolean
+  hasDash: boolean
+  selectors: (params?: { value?: string; label?: string }) => string[]
+}
+
 export interface State {
   enabled: boolean
   configPath?: string
@@ -86,7 +98,7 @@   separator?: string
   dependencies?: string[]
   plugins?: any
   screens?: string[]
-export type ClassNamesTree = {
+export type ClassNames = {
   corePlugins?: string[]
   modules?: {
     tailwindcss?: { version: string; module: any }
@@ -124,15 +137,19 @@ }
 
 export type DocumentHelperFunction = {
 export type ClassNamesContext = {
+import type { TextDocuments, Connection, Range, SymbolInformation } from 'vscode-languageserver'
 import type { TextDocuments, Connection, Range, SymbolInformation } from 'vscode-languageserver'
+import type { TextDocument } from 'vscode-languageserver-textdocument'
 import type { TextDocuments, Connection, Range, SymbolInformation } from 'vscode-languageserver'
 import type { TextDocuments, Connection, Range, SymbolInformation } from 'vscode-languageserver'
+import type { TextDocument } from 'vscode-languageserver-textdocument'
 import type { TextDocument } from 'vscode-languageserver-textdocument'
 import type { TextDocuments, Connection, Range, SymbolInformation } from 'vscode-languageserver'
-import type { Postcss } from 'postcss'
-}
+import type { TextDocument } from 'vscode-languageserver-textdocument'
 import type { Postcss } from 'postcss'
 import type { TextDocuments, Connection, Range, SymbolInformation } from 'vscode-languageserver'
+  }
+import type { TextDocument } from 'vscode-languageserver-textdocument'
 import { KeywordColor } from './color'
 }
 
M packages/vscode-tailwindcss/src/extension.ts -> packages/vscode-tailwindcss/src/extension.ts
diff --git a/packages/vscode-tailwindcss/src/extension.ts b/packages/vscode-tailwindcss/src/extension.ts
index 1677c1b2b19f8fd9b951516f3ccc2acf9042cd1d..d1cb232a15727263b29110a09d58a70b75da31fe 100755
--- a/packages/vscode-tailwindcss/src/extension.ts
+++ b/packages/vscode-tailwindcss/src/extension.ts
@@ -26,6 +26,7 @@   CompletionList,
   ProviderResult,
   SnippetString,
   TextEdit,
+  TextEditorSelectionChangeKind,
 } from 'vscode'
 import {
   LanguageClient,
@@ -148,6 +149,62 @@         outputChannel.show()
       }
     })
   )
+
+  // context.subscriptions.push(
+  //   commands.registerCommand(
+  //     'tailwindCSS.onInsertArbitraryVariantSnippet',
+  //     (
+  //       variantName: string,
+  //       range: {
+  //         start: { line: number; character: number }
+  //         end: { line: number; character: number }
+  //       }
+  //     ) => {
+  //       let listener = Window.onDidChangeTextEditorSelection((event) => {
+  //         if (event.selections.length !== 1) {
+  //           listener.dispose()
+  //           return
+  //         }
+
+  //         let document = event.textEditor.document
+  //         let selection = event.selections[0]
+
+  //         let line = document.lineAt(range.start.line)
+  //         let lineRangeFromCompletion = new Range(
+  //           range.start.line,
+  //           range.start.character,
+  //           line.range.end.line,
+  //           line.range.end.character
+  //         )
+  //         let lineText = document.getText(lineRangeFromCompletion)
+  //         let match = lineText.match(/^(\S+)]:/)
+
+  //         if (!match) {
+  //           listener.dispose()
+  //           return
+  //         }
+
+  //         let arbitraryValueRange = new Range(
+  //           lineRangeFromCompletion.start.translate(0, variantName.length + 2),
+  //           lineRangeFromCompletion.start.translate(0, match[1].length)
+  //         )
+
+  //         if (!arbitraryValueRange.contains(selection)) {
+  //           listener.dispose()
+  //         }
+
+  //         if (
+  //           event.kind === TextEditorSelectionChangeKind.Command &&
+  //           selection.isEmpty &&
+  //           selection.start.isEqual(arbitraryValueRange.end.translate(0, 2))
+  //         ) {
+  //           commands.executeCommand('editor.action.triggerSuggest')
+  //         }
+  //       })
+  //       context.subscriptions.push(listener)
+  //     }
+  //   )
+  // )
 
   let watcher = Workspace.createFileSystemWatcher(`**/${CONFIG_FILE_GLOB}`, false, true, true)
 
@@ -378,9 +435,14 @@       middleware: {
         async resolveCompletionItem(item, token, next) {
           let result = await next(item, token)
           let selections = Window.activeTextEditor.selections
+          if (
+const CLIENT_NAME = 'Tailwind CSS IntelliSense'
  * Copyright (c) Microsoft Corporation. All rights reserved.
-  window as Window,
+ * ------------------------------------------------------------------------------------------ */
 import {
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+            result.additionalTextEdits?.length > 0
+          ) {
             let length =
               selections[0].start.character - result.additionalTextEdits[0].range.start.character
             let prefixLength =