diff --git a/.changeset/quick-colts-sing.md b/.changeset/quick-colts-sing.md
new file mode 100644
index 0000000..77469e9
--- /dev/null
+++ b/.changeset/quick-colts-sing.md
@@ -0,0 +1,5 @@
+---
+"css-variables-language-server": minor
+---
+
+use postcss-sass and postcss-less to parse the relevant files
diff --git a/package-lock.json b/package-lock.json
index f176ca3..53d33ca 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
- "name": "css-variables-intellisense",
- "version": "2.3.12",
+ "name": "root",
+ "version": "0.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
- "name": "css-variables-intellisense",
- "version": "2.3.12",
+ "name": "root",
+ "version": "0.0.0",
"workspaces": [
"packages/*"
],
@@ -2035,6 +2035,12 @@
"dev": true,
"peer": true
},
+ "node_modules/@types/less": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/less/-/less-3.0.3.tgz",
+ "integrity": "sha512-1YXyYH83h6We1djyoUEqTlVyQtCfJAFXELSKW2ZRtjHD4hQ82CC4lvrv5D0l0FLcKBaiPbXyi3MpMsI9ZRgKsw==",
+ "dev": true
+ },
"node_modules/@types/minimist": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
@@ -2059,6 +2065,15 @@
"integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
"dev": true
},
+ "node_modules/@types/postcss-less": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/postcss-less/-/postcss-less-4.0.2.tgz",
+ "integrity": "sha512-qDpf8D7RYupncwCFiVeyeDrDExzXJGZ7Km6I1LLeAvd+1bH6KhhWBZGxdysB1oJQdjCajXxakjK7pFiC7uBbEA==",
+ "dev": true,
+ "dependencies": {
+ "postcss": "^8.1.2"
+ }
+ },
"node_modules/@types/prettier": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz",
@@ -2474,7 +2489,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
- "dev": true,
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
@@ -2724,7 +2738,6 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -3081,7 +3094,6 @@
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
- "dev": true,
"funding": [
{
"type": "individual",
@@ -3108,7 +3120,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
"dependencies": {
"is-glob": "^4.0.1"
},
@@ -3229,6 +3240,17 @@
"safe-buffer": "~5.1.1"
}
},
+ "node_modules/copy-anything": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz",
+ "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
+ "dependencies": {
+ "is-what": "^3.14.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@@ -3647,6 +3669,18 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
+ "node_modules/errno": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
+ "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
+ "optional": true,
+ "dependencies": {
+ "prr": "~1.0.1"
+ },
+ "bin": {
+ "errno": "cli.js"
+ }
+ },
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -4712,7 +4746,6 @@
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
@@ -4934,7 +4967,7 @@
"version": "4.2.10",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
- "dev": true
+ "devOptional": true
},
"node_modules/grapheme-splitter": {
"version": "1.0.4",
@@ -5149,6 +5182,23 @@
"node": ">= 4"
}
},
+ "node_modules/image-size": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
+ "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==",
+ "optional": true,
+ "bin": {
+ "image-size": "bin/image-size.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/immutable": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
+ "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ=="
+ },
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -5260,7 +5310,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
"dependencies": {
"binary-extensions": "^2.0.0"
},
@@ -5522,6 +5571,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-what": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz",
+ "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA=="
+ },
"node_modules/is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -5827,6 +5881,18 @@
"node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
}
},
+ "node_modules/jest-environment-node-single-context": {
+ "version": "28.1.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-node-single-context/-/jest-environment-node-single-context-28.1.0.tgz",
+ "integrity": "sha512-mIHXjJuL01XPXgomj3kL1q5i36Iisfq4TI03NrSMgGvnCTeyMJrPTxoGYq1hfTQchnl6umDbkveLpwv8RgqseA==",
+ "dev": true,
+ "dependencies": {
+ "jest-environment-node": "^28.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/kayahr/jest-environment-node-single-context?sponsor=1"
+ }
+ },
"node_modules/jest-get-type": {
"version": "28.0.2",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz",
@@ -6296,6 +6362,58 @@
"node": ">=6"
}
},
+ "node_modules/less": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz",
+ "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==",
+ "dependencies": {
+ "copy-anything": "^2.0.1",
+ "parse-node-version": "^1.0.1",
+ "tslib": "^2.3.0"
+ },
+ "bin": {
+ "lessc": "bin/lessc"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "optionalDependencies": {
+ "errno": "^0.1.1",
+ "graceful-fs": "^4.1.2",
+ "image-size": "~0.5.0",
+ "make-dir": "^2.1.0",
+ "mime": "^1.4.1",
+ "needle": "^3.1.0",
+ "source-map": "~0.6.0"
+ }
+ },
+ "node_modules/less/node_modules/make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "optional": true,
+ "dependencies": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/less/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "optional": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/less/node_modules/tslib": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
+ },
"node_modules/leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@@ -6641,7 +6759,7 @@
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
- "dev": true,
+ "devOptional": true,
"bin": {
"mime": "cli.js"
},
@@ -6903,7 +7021,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
+ "devOptional": true
},
"node_modules/mute-stream": {
"version": "0.0.8",
@@ -6946,6 +7064,44 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
+ "node_modules/needle": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/needle/-/needle-3.1.0.tgz",
+ "integrity": "sha512-gCE9weDhjVGCRqS8dwDR/D3GTAeyXLXuqp7I8EzH6DllZGXSUyxuqqLh+YX9rMAWaaTFyVAg6rHGL25dqvczKw==",
+ "optional": true,
+ "dependencies": {
+ "debug": "^3.2.6",
+ "iconv-lite": "^0.6.3",
+ "sax": "^1.2.4"
+ },
+ "bin": {
+ "needle": "bin/needle"
+ },
+ "engines": {
+ "node": ">= 4.4.x"
+ }
+ },
+ "node_modules/needle/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "optional": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/needle/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "optional": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/node-abi": {
"version": "3.24.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.24.0.tgz",
@@ -7022,7 +7178,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -7274,6 +7429,14 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/parse-node-version": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
+ "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/parse-semver": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz",
@@ -7385,7 +7548,7 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
- "dev": true,
+ "devOptional": true,
"engines": {
"node": ">=6"
}
@@ -7486,6 +7649,17 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/postcss-less": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-6.0.0.tgz",
+ "integrity": "sha512-FPX16mQLyEjLzEuuJtxA8X3ejDLNGGEG503d2YGZR5Ask1SpDN8KmZUMpzCvyalWRywAn1n1VOA5dcqfCLo5rg==",
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "postcss": "^8.3.5"
+ }
+ },
"node_modules/postcss-load-config": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz",
@@ -7515,6 +7689,21 @@
}
}
},
+ "node_modules/postcss-scss": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.4.tgz",
+ "integrity": "sha512-aBBbVyzA8b3hUL0MGrpydxxXKXFZc5Eqva0Q3V9qsBOLEMsjb6w49WfpsoWzpEgcqJGW4t7Rio8WXVU9Gd8vWg==",
+ "engines": {
+ "node": ">=12.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ "peerDependencies": {
+ "postcss": "^8.3.3"
+ }
+ },
"node_modules/postcss/node_modules/nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
@@ -7634,6 +7823,12 @@
"node": ">= 6"
}
},
+ "node_modules/prr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
+ "optional": true
+ },
"node_modules/pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
@@ -7920,7 +8115,6 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
"dependencies": {
"picomatch": "^2.2.1"
},
@@ -8118,13 +8312,29 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "dev": true
+ "devOptional": true
+ },
+ "node_modules/sass": {
+ "version": "1.54.7",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.7.tgz",
+ "integrity": "sha512-3q7MQz7sCpVG6TLhUfZwGOcd2/sm2ghYN2JEdRjNiW04ILdvahdo9GuAs+bxsxZ3hDCKv+wUT5w0iFWGU0CxlA==",
+ "dependencies": {
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "bin": {
+ "sass": "sass.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
},
"node_modules/sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
- "dev": true
+ "devOptional": true
},
"node_modules/semver": {
"version": "6.3.0",
@@ -8408,7 +8618,7 @@
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true,
+ "devOptional": true,
"engines": {
"node": ">=0.10.0"
}
@@ -10088,25 +10298,32 @@
}
},
"packages/css-variables-language-server": {
- "version": "1.0.0",
+ "version": "2.4.1",
"license": "MIT",
"dependencies": {
"axios": "^0.27.2",
"culori": "0.20.1",
"fast-glob": "^3.2.7",
+ "less": "^4.1.3",
"line-column": "^1.0.2",
"postcss": "^8.4.16",
+ "postcss-less": "^6.0.0",
+ "postcss-scss": "^4.0.4",
+ "sass": "^1.54.7",
"vscode-languageserver": "^7.0.0",
"vscode-languageserver-textdocument": "^1.0.1",
"vscode-uri": "^3.0.3"
},
"devDependencies": {
"@types/jest": "^28.1.8",
+ "@types/less": "^3.0.3",
+ "@types/postcss-less": "^4.0.2",
"@typescript-eslint/eslint-plugin": "^5.35.1",
"@typescript-eslint/parser": "^5.35.1",
"eslint": "^8.23.0",
"eslint-config-airbnb-typescript": "^17.0.0",
"jest": "^28.0.0",
+ "jest-environment-node-single-context": "^28.1.0",
"ts-jest": "^28.0.8",
"tsup": "^6.2.3",
"typescript": "^4.8.2"
@@ -10135,7 +10352,7 @@
}
},
"packages/vscode-css-variables": {
- "version": "2.3.13",
+ "version": "2.4.2",
"devDependencies": {
"@types/mocha": "^9.1.1",
"@types/node": "^18.7.13",
@@ -11786,6 +12003,12 @@
"dev": true,
"peer": true
},
+ "@types/less": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/less/-/less-3.0.3.tgz",
+ "integrity": "sha512-1YXyYH83h6We1djyoUEqTlVyQtCfJAFXELSKW2ZRtjHD4hQ82CC4lvrv5D0l0FLcKBaiPbXyi3MpMsI9ZRgKsw==",
+ "dev": true
+ },
"@types/minimist": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
@@ -11810,6 +12033,15 @@
"integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
"dev": true
},
+ "@types/postcss-less": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/postcss-less/-/postcss-less-4.0.2.tgz",
+ "integrity": "sha512-qDpf8D7RYupncwCFiVeyeDrDExzXJGZ7Km6I1LLeAvd+1bH6KhhWBZGxdysB1oJQdjCajXxakjK7pFiC7uBbEA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^8.1.2"
+ }
+ },
"@types/prettier": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz",
@@ -12084,7 +12316,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
- "dev": true,
"requires": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
@@ -12268,8 +12499,7 @@
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
- "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
- "dev": true
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
},
"bl": {
"version": "4.1.0",
@@ -12522,7 +12752,6 @@
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
- "dev": true,
"requires": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
@@ -12538,7 +12767,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
"requires": {
"is-glob": "^4.0.1"
}
@@ -12642,6 +12870,14 @@
"safe-buffer": "~5.1.1"
}
},
+ "copy-anything": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz",
+ "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
+ "requires": {
+ "is-what": "^3.14.1"
+ }
+ },
"core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@@ -12676,6 +12912,8 @@
"version": "file:packages/css-variables-language-server",
"requires": {
"@types/jest": "^28.1.8",
+ "@types/less": "^3.0.3",
+ "@types/postcss-less": "*",
"@typescript-eslint/eslint-plugin": "^5.35.1",
"@typescript-eslint/parser": "^5.35.1",
"axios": "^0.27.2",
@@ -12684,8 +12922,13 @@
"eslint-config-airbnb-typescript": "^17.0.0",
"fast-glob": "^3.2.7",
"jest": "^28.0.0",
+ "jest-environment-node-single-context": "^28.1.0",
+ "less": "^4.1.3",
"line-column": "^1.0.2",
"postcss": "^8.4.16",
+ "postcss-less": "^6.0.0",
+ "postcss-scss": "^4.0.4",
+ "sass": "^1.54.7",
"ts-jest": "^28.0.8",
"tsup": "^6.2.3",
"typescript": "^4.8.2",
@@ -12967,6 +13210,15 @@
"integrity": "sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg==",
"dev": true
},
+ "errno": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
+ "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
+ "optional": true,
+ "requires": {
+ "prr": "~1.0.1"
+ }
+ },
"error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -13689,7 +13941,6 @@
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
- "dev": true,
"optional": true
},
"fstream": {
@@ -13846,7 +14097,7 @@
"version": "4.2.10",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
- "dev": true
+ "devOptional": true
},
"grapheme-splitter": {
"version": "1.0.4",
@@ -13992,6 +14243,17 @@
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
"dev": true
},
+ "image-size": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
+ "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==",
+ "optional": true
+ },
+ "immutable": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
+ "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ=="
+ },
"import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -14076,7 +14338,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
"requires": {
"binary-extensions": "^2.0.0"
}
@@ -14242,6 +14503,11 @@
"call-bind": "^1.0.2"
}
},
+ "is-what": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz",
+ "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA=="
+ },
"is-windows": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -14465,6 +14731,15 @@
"jest-util": "^28.1.3"
}
},
+ "jest-environment-node-single-context": {
+ "version": "28.1.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-node-single-context/-/jest-environment-node-single-context-28.1.0.tgz",
+ "integrity": "sha512-mIHXjJuL01XPXgomj3kL1q5i36Iisfq4TI03NrSMgGvnCTeyMJrPTxoGYq1hfTQchnl6umDbkveLpwv8RgqseA==",
+ "dev": true,
+ "requires": {
+ "jest-environment-node": "^28.0.2"
+ }
+ },
"jest-get-type": {
"version": "28.0.2",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz",
@@ -14837,6 +15112,46 @@
"integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
"dev": true
},
+ "less": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/less/-/less-4.1.3.tgz",
+ "integrity": "sha512-w16Xk/Ta9Hhyei0Gpz9m7VS8F28nieJaL/VyShID7cYvP6IL5oHeL6p4TXSDJqZE/lNv0oJ2pGVjJsRkfwm5FA==",
+ "requires": {
+ "copy-anything": "^2.0.1",
+ "errno": "^0.1.1",
+ "graceful-fs": "^4.1.2",
+ "image-size": "~0.5.0",
+ "make-dir": "^2.1.0",
+ "mime": "^1.4.1",
+ "needle": "^3.1.0",
+ "parse-node-version": "^1.0.1",
+ "source-map": "~0.6.0",
+ "tslib": "^2.3.0"
+ },
+ "dependencies": {
+ "make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "optional": true,
+ "requires": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ }
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "optional": true
+ },
+ "tslib": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
+ }
+ }
+ },
"leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@@ -15110,7 +15425,7 @@
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
- "dev": true
+ "devOptional": true
},
"mime-db": {
"version": "1.52.0",
@@ -15309,7 +15624,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
+ "devOptional": true
},
"mute-stream": {
"version": "0.0.8",
@@ -15346,6 +15661,37 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
+ "needle": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/needle/-/needle-3.1.0.tgz",
+ "integrity": "sha512-gCE9weDhjVGCRqS8dwDR/D3GTAeyXLXuqp7I8EzH6DllZGXSUyxuqqLh+YX9rMAWaaTFyVAg6rHGL25dqvczKw==",
+ "optional": true,
+ "requires": {
+ "debug": "^3.2.6",
+ "iconv-lite": "^0.6.3",
+ "sax": "^1.2.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "optional": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "optional": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ }
+ }
+ }
+ },
"node-abi": {
"version": "3.24.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.24.0.tgz",
@@ -15413,8 +15759,7 @@
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
},
"npm-run-path": {
"version": "4.0.1",
@@ -15591,6 +15936,11 @@
"lines-and-columns": "^1.1.6"
}
},
+ "parse-node-version": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
+ "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA=="
+ },
"parse-semver": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz",
@@ -15677,7 +16027,7 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
- "dev": true
+ "devOptional": true
},
"pirates": {
"version": "4.0.5",
@@ -15750,6 +16100,12 @@
}
}
},
+ "postcss-less": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-6.0.0.tgz",
+ "integrity": "sha512-FPX16mQLyEjLzEuuJtxA8X3ejDLNGGEG503d2YGZR5Ask1SpDN8KmZUMpzCvyalWRywAn1n1VOA5dcqfCLo5rg==",
+ "requires": {}
+ },
"postcss-load-config": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz",
@@ -15760,6 +16116,12 @@
"yaml": "^1.10.2"
}
},
+ "postcss-scss": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.4.tgz",
+ "integrity": "sha512-aBBbVyzA8b3hUL0MGrpydxxXKXFZc5Eqva0Q3V9qsBOLEMsjb6w49WfpsoWzpEgcqJGW4t7Rio8WXVU9Gd8vWg==",
+ "requires": {}
+ },
"prebuild-install": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
@@ -15840,6 +16202,12 @@
"sisteransi": "^1.0.5"
}
},
+ "prr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
+ "optional": true
+ },
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
@@ -16060,7 +16428,6 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
"requires": {
"picomatch": "^2.2.1"
}
@@ -16191,13 +16558,23 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "dev": true
+ "devOptional": true
+ },
+ "sass": {
+ "version": "1.54.7",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.7.tgz",
+ "integrity": "sha512-3q7MQz7sCpVG6TLhUfZwGOcd2/sm2ghYN2JEdRjNiW04ILdvahdo9GuAs+bxsxZ3hDCKv+wUT5w0iFWGU0CxlA==",
+ "requires": {
+ "chokidar": ">=3.0.0 <4.0.0",
+ "immutable": "^4.0.0",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ }
},
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
- "dev": true
+ "devOptional": true
},
"semver": {
"version": "6.3.0",
@@ -16407,7 +16784,7 @@
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
+ "devOptional": true
},
"source-map-js": {
"version": "1.0.2",
diff --git a/packages/css-variables-language-server/jest.config.js b/packages/css-variables-language-server/jest.config.js
index 4327f53..f47e700 100644
--- a/packages/css-variables-language-server/jest.config.js
+++ b/packages/css-variables-language-server/jest.config.js
@@ -1,6 +1,6 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
- testEnvironment: 'node',
+ testEnvironment: 'jest-environment-node-single-context',
testPathIgnorePatterns: ["out/*"]
};
\ No newline at end of file
diff --git a/packages/css-variables-language-server/package.json b/packages/css-variables-language-server/package.json
index f15c500..bf39d11 100644
--- a/packages/css-variables-language-server/package.json
+++ b/packages/css-variables-language-server/package.json
@@ -12,8 +12,12 @@
"axios": "^0.27.2",
"culori": "0.20.1",
"fast-glob": "^3.2.7",
+ "less": "^4.1.3",
"line-column": "^1.0.2",
"postcss": "^8.4.16",
+ "postcss-less": "^6.0.0",
+ "postcss-scss": "^4.0.4",
+ "sass": "^1.54.7",
"vscode-languageserver": "^7.0.0",
"vscode-languageserver-textdocument": "^1.0.1",
"vscode-uri": "^3.0.3"
@@ -27,13 +31,16 @@
},
"devDependencies": {
"@types/jest": "^28.1.8",
+ "@types/less": "^3.0.3",
+ "@types/postcss-less": "^4.0.2",
+ "@typescript-eslint/eslint-plugin": "^5.35.1",
+ "@typescript-eslint/parser": "^5.35.1",
+ "eslint": "^8.23.0",
+ "eslint-config-airbnb-typescript": "^17.0.0",
"jest": "^28.0.0",
+ "jest-environment-node-single-context": "^28.1.0",
"ts-jest": "^28.0.8",
"tsup": "^6.2.3",
- "typescript": "^4.8.2",
- "eslint": "^8.23.0",
- "eslint-config-airbnb-typescript": "^17.0.0",
- "@typescript-eslint/eslint-plugin": "^5.35.1",
- "@typescript-eslint/parser": "^5.35.1"
+ "typescript": "^4.8.2"
}
}
diff --git a/packages/css-variables-language-server/src/CSSVariableManager.ts b/packages/css-variables-language-server/src/CSSVariableManager.ts
index 37f975f..7d52adf 100644
--- a/packages/css-variables-language-server/src/CSSVariableManager.ts
+++ b/packages/css-variables-language-server/src/CSSVariableManager.ts
@@ -5,7 +5,9 @@ import * as culori from 'culori';
import axios from 'axios';
import postcss from 'postcss';
import { pathToFileURL } from 'url';
-
+import path from 'path';
+import postcssSCSS from 'postcss-scss';
+import postcssLESS from 'postcss-less';
import CacheManager from './CacheManager';
import isColor from './utils/isColor';
import { culoriColorToVscodeColor } from './utils/culoriColorToVscodeColor';
@@ -45,6 +47,20 @@ export const defaultSettings: CSSVariablesSettings = {
],
};
+const getAST = (filePath: string, content: string) => {
+ const fileExtension = path.extname(filePath);
+
+ if (fileExtension === '.less') {
+ return postcssLESS.parse(content);
+ }
+
+ if (fileExtension === '.scss') {
+ return postcssSCSS.parse(content);
+ }
+
+ return postcss.parse(content);
+};
+
export default class CSSVariableManager {
private cacheManager = new CacheManager();
@@ -58,7 +74,8 @@ export default class CSSVariableManager {
try {
// reset cache for this file
this.cacheManager.clearFileCache(filePath);
- const ast = postcss.parse(content);
+
+ const ast = getAST(filePath, content);
const fileURI = pathToFileURL(filePath).toString();
const importUrls = [];
@@ -130,7 +147,7 @@ export default class CSSVariableManager {
}
});
} catch (error) {
- console.error(error);
+ console.error(filePath);
}
};
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/color/bezierEasing.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/color/bezierEasing.less
new file mode 100644
index 0000000..f53ffb3
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/color/bezierEasing.less
@@ -0,0 +1,110 @@
+/* stylelint-disable */
+.bezierEasingMixin() {
+@functions: ~`(function() {
+ var NEWTON_ITERATIONS = 4;
+ var NEWTON_MIN_SLOPE = 0.001;
+ var SUBDIVISION_PRECISION = 0.0000001;
+ var SUBDIVISION_MAX_ITERATIONS = 10;
+
+ var kSplineTableSize = 11;
+ var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+ var float32ArraySupported = typeof Float32Array === 'function';
+
+ function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
+ function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
+ function C (aA1) { return 3.0 * aA1; }
+
+ // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+ function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }
+
+ // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+ function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }
+
+ function binarySubdivide (aX, aA, aB, mX1, mX2) {
+ var currentX, currentT, i = 0;
+ do {
+ currentT = aA + (aB - aA) / 2.0;
+ currentX = calcBezier(currentT, mX1, mX2) - aX;
+ if (currentX > 0.0) {
+ aB = currentT;
+ } else {
+ aA = currentT;
+ }
+ } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+ return currentT;
+ }
+
+ function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
+ for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+ var currentSlope = getSlope(aGuessT, mX1, mX2);
+ if (currentSlope === 0.0) {
+ return aGuessT;
+ }
+ var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+ aGuessT -= currentX / currentSlope;
+ }
+ return aGuessT;
+ }
+
+ var BezierEasing = function (mX1, mY1, mX2, mY2) {
+ if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
+ throw new Error('bezier x values must be in [0, 1] range');
+ }
+
+ // Precompute samples table
+ var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
+ if (mX1 !== mY1 || mX2 !== mY2) {
+ for (var i = 0; i < kSplineTableSize; ++i) {
+ sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+ }
+ }
+
+ function getTForX (aX) {
+ var intervalStart = 0.0;
+ var currentSample = 1;
+ var lastSample = kSplineTableSize - 1;
+
+ for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
+ intervalStart += kSampleStepSize;
+ }
+ --currentSample;
+
+ // Interpolate to provide an initial guess for t
+ var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
+ var guessForT = intervalStart + dist * kSampleStepSize;
+
+ var initialSlope = getSlope(guessForT, mX1, mX2);
+ if (initialSlope >= NEWTON_MIN_SLOPE) {
+ return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+ } else if (initialSlope === 0.0) {
+ return guessForT;
+ } else {
+ return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+ }
+ }
+
+ return function BezierEasing (x) {
+ if (mX1 === mY1 && mX2 === mY2) {
+ return x; // linear
+ }
+ // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+ if (x === 0) {
+ return 0;
+ }
+ if (x === 1) {
+ return 1;
+ }
+ return calcBezier(getTForX(x), mY1, mY2);
+ };
+ };
+
+ this.colorEasing = BezierEasing(0.26, 0.09, 0.37, 0.18);
+ // less 3 requires a return
+ return '';
+})()`;
+}
+// It is hacky way to make this function will be compiled preferentially by less
+// resolve error: `ReferenceError: colorPalette is not defined`
+// https://github.com/ant-design/ant-motion/issues/44
+.bezierEasingMixin();
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/color/colorPalette.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/color/colorPalette.less
new file mode 100644
index 0000000..e662c07
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/color/colorPalette.less
@@ -0,0 +1,85 @@
+/* stylelint-disable no-duplicate-selectors */
+@import "bezierEasing";
+@import "tinyColor";
+
+// We create a very complex algorithm which take the place of original tint/shade color system
+// to make sure no one can understand it 👻
+// and create an entire color palette magicly by inputing just a single primary color.
+// We are using bezier-curve easing function and some color manipulations like tint/shade/darken/spin
+.colorPaletteMixin() {
+@functions: ~`(function() {
+ var hueStep = 2;
+ var saturationStep = 0.16;
+ var saturationStep2 = 0.05;
+ var brightnessStep1 = 0.05;
+ var brightnessStep2 = 0.15;
+ var lightColorCount = 5;
+ var darkColorCount = 4;
+
+ var getHue = function(hsv, i, isLight) {
+ var hue;
+ if (hsv.h >= 60 && hsv.h <= 240) {
+ hue = isLight ? hsv.h - hueStep * i : hsv.h + hueStep * i;
+ } else {
+ hue = isLight ? hsv.h + hueStep * i : hsv.h - hueStep * i;
+ }
+ if (hue < 0) {
+ hue += 360;
+ } else if (hue >= 360) {
+ hue -= 360;
+ }
+ return Math.round(hue);
+ };
+ var getSaturation = function(hsv, i, isLight) {
+ // grey color don't change saturation
+ if (hsv.h === 0 && hsv.s === 0) {
+ return hsv.s;
+ }
+ var saturation;
+ if (isLight) {
+ saturation = hsv.s - saturationStep * i;
+ } else if (i === darkColorCount) {
+ saturation = hsv.s + saturationStep;
+ } else {
+ saturation = hsv.s + saturationStep2 * i;
+ }
+ if (saturation > 1) {
+ saturation = 1;
+ }
+ if (isLight && i === lightColorCount && saturation > 0.1) {
+ saturation = 0.1;
+ }
+ if (saturation < 0.06) {
+ saturation = 0.06;
+ }
+ return Number(saturation.toFixed(2));
+ };
+ var getValue = function(hsv, i, isLight) {
+ var value;
+ if (isLight) {
+ value = hsv.v + brightnessStep1 * i;
+ }else{
+ value = hsv.v - brightnessStep2 * i
+ }
+ if (value > 1) {
+ value = 1;
+ }
+ return Number(value.toFixed(2))
+ };
+
+ this.colorPalette = function(color, index) {
+ var isLight = index <= 6;
+ var hsv = tinycolor(color).toHsv();
+ var i = isLight ? lightColorCount + 1 - index : index - lightColorCount - 1;
+ return tinycolor({
+ h: getHue(hsv, i, isLight),
+ s: getSaturation(hsv, i, isLight),
+ v: getValue(hsv, i, isLight),
+ }).toHexString();
+ };
+})()`;
+}
+// It is hacky way to make this function will be compiled preferentially by less
+// resolve error: `ReferenceError: colorPalette is not defined`
+// https://github.com/ant-design/ant-motion/issues/44
+.colorPaletteMixin();
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/color/colors.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/color/colors.less
new file mode 100644
index 0000000..51540bf
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/color/colors.less
@@ -0,0 +1,162 @@
+@import 'colorPalette';
+
+// color palettes
+@blue-base: #1890ff;
+@blue-1: color(~`colorPalette('@{blue-6}', 1) `);
+@blue-2: color(~`colorPalette('@{blue-6}', 2) `);
+@blue-3: color(~`colorPalette('@{blue-6}', 3) `);
+@blue-4: color(~`colorPalette('@{blue-6}', 4) `);
+@blue-5: color(~`colorPalette('@{blue-6}', 5) `);
+@blue-6: @blue-base;
+@blue-7: color(~`colorPalette('@{blue-6}', 7) `);
+@blue-8: color(~`colorPalette('@{blue-6}', 8) `);
+@blue-9: color(~`colorPalette('@{blue-6}', 9) `);
+@blue-10: color(~`colorPalette('@{blue-6}', 10) `);
+
+@purple-base: #722ed1;
+@purple-1: color(~`colorPalette('@{purple-6}', 1) `);
+@purple-2: color(~`colorPalette('@{purple-6}', 2) `);
+@purple-3: color(~`colorPalette('@{purple-6}', 3) `);
+@purple-4: color(~`colorPalette('@{purple-6}', 4) `);
+@purple-5: color(~`colorPalette('@{purple-6}', 5) `);
+@purple-6: @purple-base;
+@purple-7: color(~`colorPalette('@{purple-6}', 7) `);
+@purple-8: color(~`colorPalette('@{purple-6}', 8) `);
+@purple-9: color(~`colorPalette('@{purple-6}', 9) `);
+@purple-10: color(~`colorPalette('@{purple-6}', 10) `);
+
+@cyan-base: #13c2c2;
+@cyan-1: color(~`colorPalette('@{cyan-6}', 1) `);
+@cyan-2: color(~`colorPalette('@{cyan-6}', 2) `);
+@cyan-3: color(~`colorPalette('@{cyan-6}', 3) `);
+@cyan-4: color(~`colorPalette('@{cyan-6}', 4) `);
+@cyan-5: color(~`colorPalette('@{cyan-6}', 5) `);
+@cyan-6: @cyan-base;
+@cyan-7: color(~`colorPalette('@{cyan-6}', 7) `);
+@cyan-8: color(~`colorPalette('@{cyan-6}', 8) `);
+@cyan-9: color(~`colorPalette('@{cyan-6}', 9) `);
+@cyan-10: color(~`colorPalette('@{cyan-6}', 10) `);
+
+@green-base: #52c41a;
+@green-1: color(~`colorPalette('@{green-6}', 1) `);
+@green-2: color(~`colorPalette('@{green-6}', 2) `);
+@green-3: color(~`colorPalette('@{green-6}', 3) `);
+@green-4: color(~`colorPalette('@{green-6}', 4) `);
+@green-5: color(~`colorPalette('@{green-6}', 5) `);
+@green-6: @green-base;
+@green-7: color(~`colorPalette('@{green-6}', 7) `);
+@green-8: color(~`colorPalette('@{green-6}', 8) `);
+@green-9: color(~`colorPalette('@{green-6}', 9) `);
+@green-10: color(~`colorPalette('@{green-6}', 10) `);
+
+@magenta-base: #eb2f96;
+@magenta-1: color(~`colorPalette('@{magenta-6}', 1) `);
+@magenta-2: color(~`colorPalette('@{magenta-6}', 2) `);
+@magenta-3: color(~`colorPalette('@{magenta-6}', 3) `);
+@magenta-4: color(~`colorPalette('@{magenta-6}', 4) `);
+@magenta-5: color(~`colorPalette('@{magenta-6}', 5) `);
+@magenta-6: @magenta-base;
+@magenta-7: color(~`colorPalette('@{magenta-6}', 7) `);
+@magenta-8: color(~`colorPalette('@{magenta-6}', 8) `);
+@magenta-9: color(~`colorPalette('@{magenta-6}', 9) `);
+@magenta-10: color(~`colorPalette('@{magenta-6}', 10) `);
+
+// alias of magenta
+@pink-base: #eb2f96;
+@pink-1: color(~`colorPalette('@{pink-6}', 1) `);
+@pink-2: color(~`colorPalette('@{pink-6}', 2) `);
+@pink-3: color(~`colorPalette('@{pink-6}', 3) `);
+@pink-4: color(~`colorPalette('@{pink-6}', 4) `);
+@pink-5: color(~`colorPalette('@{pink-6}', 5) `);
+@pink-6: @pink-base;
+@pink-7: color(~`colorPalette('@{pink-6}', 7) `);
+@pink-8: color(~`colorPalette('@{pink-6}', 8) `);
+@pink-9: color(~`colorPalette('@{pink-6}', 9) `);
+@pink-10: color(~`colorPalette('@{pink-6}', 10) `);
+
+@red-base: #f5222d;
+@red-1: color(~`colorPalette('@{red-6}', 1) `);
+@red-2: color(~`colorPalette('@{red-6}', 2) `);
+@red-3: color(~`colorPalette('@{red-6}', 3) `);
+@red-4: color(~`colorPalette('@{red-6}', 4) `);
+@red-5: color(~`colorPalette('@{red-6}', 5) `);
+@red-6: @red-base;
+@red-7: color(~`colorPalette('@{red-6}', 7) `);
+@red-8: color(~`colorPalette('@{red-6}', 8) `);
+@red-9: color(~`colorPalette('@{red-6}', 9) `);
+@red-10: color(~`colorPalette('@{red-6}', 10) `);
+
+@orange-base: #fa8c16;
+@orange-1: color(~`colorPalette('@{orange-6}', 1) `);
+@orange-2: color(~`colorPalette('@{orange-6}', 2) `);
+@orange-3: color(~`colorPalette('@{orange-6}', 3) `);
+@orange-4: color(~`colorPalette('@{orange-6}', 4) `);
+@orange-5: color(~`colorPalette('@{orange-6}', 5) `);
+@orange-6: @orange-base;
+@orange-7: color(~`colorPalette('@{orange-6}', 7) `);
+@orange-8: color(~`colorPalette('@{orange-6}', 8) `);
+@orange-9: color(~`colorPalette('@{orange-6}', 9) `);
+@orange-10: color(~`colorPalette('@{orange-6}', 10) `);
+
+@yellow-base: #fadb14;
+@yellow-1: color(~`colorPalette('@{yellow-6}', 1) `);
+@yellow-2: color(~`colorPalette('@{yellow-6}', 2) `);
+@yellow-3: color(~`colorPalette('@{yellow-6}', 3) `);
+@yellow-4: color(~`colorPalette('@{yellow-6}', 4) `);
+@yellow-5: color(~`colorPalette('@{yellow-6}', 5) `);
+@yellow-6: @yellow-base;
+@yellow-7: color(~`colorPalette('@{yellow-6}', 7) `);
+@yellow-8: color(~`colorPalette('@{yellow-6}', 8) `);
+@yellow-9: color(~`colorPalette('@{yellow-6}', 9) `);
+@yellow-10: color(~`colorPalette('@{yellow-6}', 10) `);
+
+@volcano-base: #fa541c;
+@volcano-1: color(~`colorPalette('@{volcano-6}', 1) `);
+@volcano-2: color(~`colorPalette('@{volcano-6}', 2) `);
+@volcano-3: color(~`colorPalette('@{volcano-6}', 3) `);
+@volcano-4: color(~`colorPalette('@{volcano-6}', 4) `);
+@volcano-5: color(~`colorPalette('@{volcano-6}', 5) `);
+@volcano-6: @volcano-base;
+@volcano-7: color(~`colorPalette('@{volcano-6}', 7) `);
+@volcano-8: color(~`colorPalette('@{volcano-6}', 8) `);
+@volcano-9: color(~`colorPalette('@{volcano-6}', 9) `);
+@volcano-10: color(~`colorPalette('@{volcano-6}', 10) `);
+
+@geekblue-base: #2f54eb;
+@geekblue-1: color(~`colorPalette('@{geekblue-6}', 1) `);
+@geekblue-2: color(~`colorPalette('@{geekblue-6}', 2) `);
+@geekblue-3: color(~`colorPalette('@{geekblue-6}', 3) `);
+@geekblue-4: color(~`colorPalette('@{geekblue-6}', 4) `);
+@geekblue-5: color(~`colorPalette('@{geekblue-6}', 5) `);
+@geekblue-6: @geekblue-base;
+@geekblue-7: color(~`colorPalette('@{geekblue-6}', 7) `);
+@geekblue-8: color(~`colorPalette('@{geekblue-6}', 8) `);
+@geekblue-9: color(~`colorPalette('@{geekblue-6}', 9) `);
+@geekblue-10: color(~`colorPalette('@{geekblue-6}', 10) `);
+
+@lime-base: #a0d911;
+@lime-1: color(~`colorPalette('@{lime-6}', 1) `);
+@lime-2: color(~`colorPalette('@{lime-6}', 2) `);
+@lime-3: color(~`colorPalette('@{lime-6}', 3) `);
+@lime-4: color(~`colorPalette('@{lime-6}', 4) `);
+@lime-5: color(~`colorPalette('@{lime-6}', 5) `);
+@lime-6: @lime-base;
+@lime-7: color(~`colorPalette('@{lime-6}', 7) `);
+@lime-8: color(~`colorPalette('@{lime-6}', 8) `);
+@lime-9: color(~`colorPalette('@{lime-6}', 9) `);
+@lime-10: color(~`colorPalette('@{lime-6}', 10) `);
+
+@gold-base: #faad14;
+@gold-1: color(~`colorPalette('@{gold-6}', 1) `);
+@gold-2: color(~`colorPalette('@{gold-6}', 2) `);
+@gold-3: color(~`colorPalette('@{gold-6}', 3) `);
+@gold-4: color(~`colorPalette('@{gold-6}', 4) `);
+@gold-5: color(~`colorPalette('@{gold-6}', 5) `);
+@gold-6: @gold-base;
+@gold-7: color(~`colorPalette('@{gold-6}', 7) `);
+@gold-8: color(~`colorPalette('@{gold-6}', 8) `);
+@gold-9: color(~`colorPalette('@{gold-6}', 9) `);
+@gold-10: color(~`colorPalette('@{gold-6}', 10) `);
+
+@preset-colors: pink, magenta, red, volcano, orange, yellow, gold, cyan, lime, green, blue, geekblue,
+ purple;
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/color/tinyColor.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/color/tinyColor.less
new file mode 100644
index 0000000..e576c78
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/color/tinyColor.less
@@ -0,0 +1,1184 @@
+/* stylelint-disable declaration-bang-space-before,no-duplicate-selectors,string-no-newline */
+.tinyColorMixin() {
+@functions: ~`(function() {
+// TinyColor v1.4.1
+// https://github.com/bgrins/TinyColor
+// 2016-07-07, Brian Grinstead, MIT License
+var trimLeft = /^\s+/,
+ trimRight = /\s+$/,
+ tinyCounter = 0,
+ mathRound = Math.round,
+ mathMin = Math.min,
+ mathMax = Math.max,
+ mathRandom = Math.random;
+
+function tinycolor (color, opts) {
+
+ color = (color) ? color : '';
+ opts = opts || { };
+
+ // If input is already a tinycolor, return itself
+ if (color instanceof tinycolor) {
+ return color;
+ }
+ // If we are called as a function, call using new instead
+ if (!(this instanceof tinycolor)) {
+ return new tinycolor(color, opts);
+ }
+
+ var rgb = inputToRGB(color);
+ this._originalInput = color,
+ this._r = rgb.r,
+ this._g = rgb.g,
+ this._b = rgb.b,
+ this._a = rgb.a,
+ this._roundA = mathRound(100*this._a) / 100,
+ this._format = opts.format || rgb.format;
+ this._gradientType = opts.gradientType;
+
+ // Don't let the range of [0,255] come back in [0,1].
+ // Potentially lose a little bit of precision here, but will fix issues where
+ // .5 gets interpreted as half of the total, instead of half of 1
+ // If it was supposed to be 128, this was already taken care of by inputToRgb
+ if (this._r < 1) { this._r = mathRound(this._r); }
+ if (this._g < 1) { this._g = mathRound(this._g); }
+ if (this._b < 1) { this._b = mathRound(this._b); }
+
+ this._ok = rgb.ok;
+ this._tc_id = tinyCounter++;
+}
+
+tinycolor.prototype = {
+ isDark: function() {
+ return this.getBrightness() < 128;
+ },
+ isLight: function() {
+ return !this.isDark();
+ },
+ isValid: function() {
+ return this._ok;
+ },
+ getOriginalInput: function() {
+ return this._originalInput;
+ },
+ getFormat: function() {
+ return this._format;
+ },
+ getAlpha: function() {
+ return this._a;
+ },
+ getBrightness: function() {
+ //http://www.w3.org/TR/AERT#color-contrast
+ var rgb = this.toRgb();
+ return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
+ },
+ getLuminance: function() {
+ //http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
+ var rgb = this.toRgb();
+ var RsRGB, GsRGB, BsRGB, R, G, B;
+ RsRGB = rgb.r/255;
+ GsRGB = rgb.g/255;
+ BsRGB = rgb.b/255;
+
+ if (RsRGB <= 0.03928) {R = RsRGB / 12.92;} else {R = Math.pow(((RsRGB + 0.055) / 1.055), 2.4);}
+ if (GsRGB <= 0.03928) {G = GsRGB / 12.92;} else {G = Math.pow(((GsRGB + 0.055) / 1.055), 2.4);}
+ if (BsRGB <= 0.03928) {B = BsRGB / 12.92;} else {B = Math.pow(((BsRGB + 0.055) / 1.055), 2.4);}
+ return (0.2126 * R) + (0.7152 * G) + (0.0722 * B);
+ },
+ setAlpha: function(value) {
+ this._a = boundAlpha(value);
+ this._roundA = mathRound(100*this._a) / 100;
+ return this;
+ },
+ toHsv: function() {
+ var hsv = rgbToHsv(this._r, this._g, this._b);
+ return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };
+ },
+ toHsvString: function() {
+ var hsv = rgbToHsv(this._r, this._g, this._b);
+ var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
+ return (this._a == 1) ?
+ "hsv(" + h + ", " + s + "%, " + v + "%)" :
+ "hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")";
+ },
+ toHsl: function() {
+ var hsl = rgbToHsl(this._r, this._g, this._b);
+ return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };
+ },
+ toHslString: function() {
+ var hsl = rgbToHsl(this._r, this._g, this._b);
+ var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
+ return (this._a == 1) ?
+ "hsl(" + h + ", " + s + "%, " + l + "%)" :
+ "hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")";
+ },
+ toHex: function(allow3Char) {
+ return rgbToHex(this._r, this._g, this._b, allow3Char);
+ },
+ toHexString: function(allow3Char) {
+ return '#' + this.toHex(allow3Char);
+ },
+ toHex8: function(allow4Char) {
+ return rgbaToHex(this._r, this._g, this._b, this._a, allow4Char);
+ },
+ toHex8String: function(allow4Char) {
+ return '#' + this.toHex8(allow4Char);
+ },
+ toRgb: function() {
+ return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };
+ },
+ toRgbString: function() {
+ return (this._a == 1) ?
+ "rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" :
+ "rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")";
+ },
+ toPercentageRgb: function() {
+ return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a };
+ },
+ toPercentageRgbString: function() {
+ return (this._a == 1) ?
+ "rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" :
+ "rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")";
+ },
+ toName: function() {
+ if (this._a === 0) {
+ return "transparent";
+ }
+
+ if (this._a < 1) {
+ return false;
+ }
+
+ return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;
+ },
+ toFilter: function(secondColor) {
+ var hex8String = '#' + rgbaToArgbHex(this._r, this._g, this._b, this._a);
+ var secondHex8String = hex8String;
+ var gradientType = this._gradientType ? "GradientType = 1, " : "";
+
+ if (secondColor) {
+ var s = tinycolor(secondColor);
+ secondHex8String = '#' + rgbaToArgbHex(s._r, s._g, s._b, s._a);
+ }
+
+ return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
+ },
+ toString: function(format) {
+ var formatSet = !!format;
+ format = format || this._format;
+
+ var formattedString = false;
+ var hasAlpha = this._a < 1 && this._a >= 0;
+ var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "hex4" || format === "hex8" || format === "name");
+
+ if (needsAlphaFormat) {
+ // Special case for "transparent", all other non-alpha formats
+ // will return rgba when there is transparency.
+ if (format === "name" && this._a === 0) {
+ return this.toName();
+ }
+ return this.toRgbString();
+ }
+ if (format === "rgb") {
+ formattedString = this.toRgbString();
+ }
+ if (format === "prgb") {
+ formattedString = this.toPercentageRgbString();
+ }
+ if (format === "hex" || format === "hex6") {
+ formattedString = this.toHexString();
+ }
+ if (format === "hex3") {
+ formattedString = this.toHexString(true);
+ }
+ if (format === "hex4") {
+ formattedString = this.toHex8String(true);
+ }
+ if (format === "hex8") {
+ formattedString = this.toHex8String();
+ }
+ if (format === "name") {
+ formattedString = this.toName();
+ }
+ if (format === "hsl") {
+ formattedString = this.toHslString();
+ }
+ if (format === "hsv") {
+ formattedString = this.toHsvString();
+ }
+
+ return formattedString || this.toHexString();
+ },
+ clone: function() {
+ return tinycolor(this.toString());
+ },
+
+ _applyModification: function(fn, args) {
+ var color = fn.apply(null, [this].concat([].slice.call(args)));
+ this._r = color._r;
+ this._g = color._g;
+ this._b = color._b;
+ this.setAlpha(color._a);
+ return this;
+ },
+ lighten: function() {
+ return this._applyModification(lighten, arguments);
+ },
+ brighten: function() {
+ return this._applyModification(brighten, arguments);
+ },
+ darken: function() {
+ return this._applyModification(darken, arguments);
+ },
+ desaturate: function() {
+ return this._applyModification(desaturate, arguments);
+ },
+ saturate: function() {
+ return this._applyModification(saturate, arguments);
+ },
+ greyscale: function() {
+ return this._applyModification(greyscale, arguments);
+ },
+ spin: function() {
+ return this._applyModification(spin, arguments);
+ },
+
+ _applyCombination: function(fn, args) {
+ return fn.apply(null, [this].concat([].slice.call(args)));
+ },
+ analogous: function() {
+ return this._applyCombination(analogous, arguments);
+ },
+ complement: function() {
+ return this._applyCombination(complement, arguments);
+ },
+ monochromatic: function() {
+ return this._applyCombination(monochromatic, arguments);
+ },
+ splitcomplement: function() {
+ return this._applyCombination(splitcomplement, arguments);
+ },
+ triad: function() {
+ return this._applyCombination(triad, arguments);
+ },
+ tetrad: function() {
+ return this._applyCombination(tetrad, arguments);
+ }
+};
+
+// If input is an object, force 1 into "1.0" to handle ratios properly
+// String input requires "1.0" as input, so 1 will be treated as 1
+tinycolor.fromRatio = function(color, opts) {
+ if (typeof color == "object") {
+ var newColor = {};
+ for (var i in color) {
+ if (color.hasOwnProperty(i)) {
+ if (i === "a") {
+ newColor[i] = color[i];
+ }
+ else {
+ newColor[i] = convertToPercentage(color[i]);
+ }
+ }
+ }
+ color = newColor;
+ }
+
+ return tinycolor(color, opts);
+};
+
+// Given a string or object, convert that input to RGB
+// Possible string inputs:
+//
+// "red"
+// "#f00" or "f00"
+// "#ff0000" or "ff0000"
+// "#ff000000" or "ff000000"
+// "rgb 255 0 0" or "rgb (255, 0, 0)"
+// "rgb 1.0 0 0" or "rgb (1, 0, 0)"
+// "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
+// "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
+// "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
+// "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
+// "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
+//
+function inputToRGB(color) {
+
+ var rgb = { r: 0, g: 0, b: 0 };
+ var a = 1;
+ var s = null;
+ var v = null;
+ var l = null;
+ var ok = false;
+ var format = false;
+
+ if (typeof color == "string") {
+ color = stringInputToObject(color);
+ }
+
+ if (typeof color == "object") {
+ if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) {
+ rgb = rgbToRgb(color.r, color.g, color.b);
+ ok = true;
+ format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
+ }
+ else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) {
+ s = convertToPercentage(color.s);
+ v = convertToPercentage(color.v);
+ rgb = hsvToRgb(color.h, s, v);
+ ok = true;
+ format = "hsv";
+ }
+ else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) {
+ s = convertToPercentage(color.s);
+ l = convertToPercentage(color.l);
+ rgb = hslToRgb(color.h, s, l);
+ ok = true;
+ format = "hsl";
+ }
+
+ if (color.hasOwnProperty("a")) {
+ a = color.a;
+ }
+ }
+
+ a = boundAlpha(a);
+
+ return {
+ ok: ok,
+ format: color.format || format,
+ r: mathMin(255, mathMax(rgb.r, 0)),
+ g: mathMin(255, mathMax(rgb.g, 0)),
+ b: mathMin(255, mathMax(rgb.b, 0)),
+ a: a
+ };
+}
+
+// Conversion Functions
+// --------------------
+
+// rgbToHsl, rgbToHsv, hslToRgb, hsvToRgb modified from:
+//
+
+// rgbToRgb
+// Handle bounds / percentage checking to conform to CSS color spec
+//
+// *Assumes:* r, g, b in [0, 255] or [0, 1]
+// *Returns:* { r, g, b } in [0, 255]
+function rgbToRgb(r, g, b){
+ return {
+ r: bound01(r, 255) * 255,
+ g: bound01(g, 255) * 255,
+ b: bound01(b, 255) * 255
+ };
+}
+
+// rgbToHsl
+// Converts an RGB color value to HSL.
+// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
+// *Returns:* { h, s, l } in [0,1]
+function rgbToHsl(r, g, b) {
+
+ r = bound01(r, 255);
+ g = bound01(g, 255);
+ b = bound01(b, 255);
+
+ var max = mathMax(r, g, b), min = mathMin(r, g, b);
+ var h, s, l = (max + min) / 2;
+
+ if(max == min) {
+ h = s = 0; // achromatic
+ }
+ else {
+ var d = max - min;
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+ switch(max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+
+ h /= 6;
+ }
+
+ return { h: h, s: s, l: l };
+}
+
+// hslToRgb
+// Converts an HSL color value to RGB.
+// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
+// *Returns:* { r, g, b } in the set [0, 255]
+function hslToRgb(h, s, l) {
+ var r, g, b;
+
+ h = bound01(h, 360);
+ s = bound01(s, 100);
+ l = bound01(l, 100);
+
+ function hue2rgb(p, q, t) {
+ if(t < 0) t += 1;
+ if(t > 1) t -= 1;
+ if(t < 1/6) return p + (q - p) * 6 * t;
+ if(t < 1/2) return q;
+ if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
+ return p;
+ }
+
+ if(s === 0) {
+ r = g = b = l; // achromatic
+ }
+ else {
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+ var p = 2 * l - q;
+ r = hue2rgb(p, q, h + 1/3);
+ g = hue2rgb(p, q, h);
+ b = hue2rgb(p, q, h - 1/3);
+ }
+
+ return { r: r * 255, g: g * 255, b: b * 255 };
+}
+
+// rgbToHsv
+// Converts an RGB color value to HSV
+// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
+// *Returns:* { h, s, v } in [0,1]
+function rgbToHsv(r, g, b) {
+
+ r = bound01(r, 255);
+ g = bound01(g, 255);
+ b = bound01(b, 255);
+
+ var max = mathMax(r, g, b), min = mathMin(r, g, b);
+ var h, s, v = max;
+
+ var d = max - min;
+ s = max === 0 ? 0 : d / max;
+
+ if(max == min) {
+ h = 0; // achromatic
+ }
+ else {
+ switch(max) {
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+ case g: h = (b - r) / d + 2; break;
+ case b: h = (r - g) / d + 4; break;
+ }
+ h /= 6;
+ }
+ return { h: h, s: s, v: v };
+}
+
+// hsvToRgb
+// Converts an HSV color value to RGB.
+// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
+// *Returns:* { r, g, b } in the set [0, 255]
+ function hsvToRgb(h, s, v) {
+
+ h = bound01(h, 360) * 6;
+ s = bound01(s, 100);
+ v = bound01(v, 100);
+
+ var i = Math.floor(h),
+ f = h - i,
+ p = v * (1 - s),
+ q = v * (1 - f * s),
+ t = v * (1 - (1 - f) * s),
+ mod = i % 6,
+ r = [v, q, p, p, t, v][mod],
+ g = [t, v, v, q, p, p][mod],
+ b = [p, p, t, v, v, q][mod];
+
+ return { r: r * 255, g: g * 255, b: b * 255 };
+}
+
+// rgbToHex
+// Converts an RGB color to hex
+// Assumes r, g, and b are contained in the set [0, 255]
+// Returns a 3 or 6 character hex
+function rgbToHex(r, g, b, allow3Char) {
+
+ var hex = [
+ pad2(mathRound(r).toString(16)),
+ pad2(mathRound(g).toString(16)),
+ pad2(mathRound(b).toString(16))
+ ];
+
+ // Return a 3 character hex if possible
+ if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
+ return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
+ }
+
+ return hex.join("");
+}
+
+// rgbaToHex
+// Converts an RGBA color plus alpha transparency to hex
+// Assumes r, g, b are contained in the set [0, 255] and
+// a in [0, 1]. Returns a 4 or 8 character rgba hex
+function rgbaToHex(r, g, b, a, allow4Char) {
+
+ var hex = [
+ pad2(mathRound(r).toString(16)),
+ pad2(mathRound(g).toString(16)),
+ pad2(mathRound(b).toString(16)),
+ pad2(convertDecimalToHex(a))
+ ];
+
+ // Return a 4 character hex if possible
+ if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) {
+ return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0);
+ }
+
+ return hex.join("");
+}
+
+// rgbaToArgbHex
+// Converts an RGBA color to an ARGB Hex8 string
+// Rarely used, but required for "toFilter()"
+function rgbaToArgbHex(r, g, b, a) {
+
+ var hex = [
+ pad2(convertDecimalToHex(a)),
+ pad2(mathRound(r).toString(16)),
+ pad2(mathRound(g).toString(16)),
+ pad2(mathRound(b).toString(16))
+ ];
+
+ return hex.join("");
+}
+
+// equals
+// Can be called with any tinycolor input
+tinycolor.equals = function (color1, color2) {
+ if (!color1 || !color2) { return false; }
+ return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
+};
+
+tinycolor.random = function() {
+ return tinycolor.fromRatio({
+ r: mathRandom(),
+ g: mathRandom(),
+ b: mathRandom()
+ });
+};
+
+// Modification Functions
+// ----------------------
+// Thanks to less.js for some of the basics here
+//
+
+function desaturate(color, amount) {
+ amount = (amount === 0) ? 0 : (amount || 10);
+ var hsl = tinycolor(color).toHsl();
+ hsl.s -= amount / 100;
+ hsl.s = clamp01(hsl.s);
+ return tinycolor(hsl);
+}
+
+function saturate(color, amount) {
+ amount = (amount === 0) ? 0 : (amount || 10);
+ var hsl = tinycolor(color).toHsl();
+ hsl.s += amount / 100;
+ hsl.s = clamp01(hsl.s);
+ return tinycolor(hsl);
+}
+
+function greyscale(color) {
+ return tinycolor(color).desaturate(100);
+}
+
+function lighten (color, amount) {
+ amount = (amount === 0) ? 0 : (amount || 10);
+ var hsl = tinycolor(color).toHsl();
+ hsl.l += amount / 100;
+ hsl.l = clamp01(hsl.l);
+ return tinycolor(hsl);
+}
+
+function brighten(color, amount) {
+ amount = (amount === 0) ? 0 : (amount || 10);
+ var rgb = tinycolor(color).toRgb();
+ rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));
+ rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));
+ rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));
+ return tinycolor(rgb);
+}
+
+function darken (color, amount) {
+ amount = (amount === 0) ? 0 : (amount || 10);
+ var hsl = tinycolor(color).toHsl();
+ hsl.l -= amount / 100;
+ hsl.l = clamp01(hsl.l);
+ return tinycolor(hsl);
+}
+
+// Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.
+// Values outside of this range will be wrapped into this range.
+function spin(color, amount) {
+ var hsl = tinycolor(color).toHsl();
+ var hue = (hsl.h + amount) % 360;
+ hsl.h = hue < 0 ? 360 + hue : hue;
+ return tinycolor(hsl);
+}
+
+// Combination Functions
+// ---------------------
+// Thanks to jQuery xColor for some of the ideas behind these
+//
+
+function complement(color) {
+ var hsl = tinycolor(color).toHsl();
+ hsl.h = (hsl.h + 180) % 360;
+ return tinycolor(hsl);
+}
+
+function triad(color) {
+ var hsl = tinycolor(color).toHsl();
+ var h = hsl.h;
+ return [
+ tinycolor(color),
+ tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
+ tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
+ ];
+}
+
+function tetrad(color) {
+ var hsl = tinycolor(color).toHsl();
+ var h = hsl.h;
+ return [
+ tinycolor(color),
+ tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
+ tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
+ tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
+ ];
+}
+
+function splitcomplement(color) {
+ var hsl = tinycolor(color).toHsl();
+ var h = hsl.h;
+ return [
+ tinycolor(color),
+ tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
+ tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
+ ];
+}
+
+function analogous(color, results, slices) {
+ results = results || 6;
+ slices = slices || 30;
+
+ var hsl = tinycolor(color).toHsl();
+ var part = 360 / slices;
+ var ret = [tinycolor(color)];
+
+ for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
+ hsl.h = (hsl.h + part) % 360;
+ ret.push(tinycolor(hsl));
+ }
+ return ret;
+}
+
+function monochromatic(color, results) {
+ results = results || 6;
+ var hsv = tinycolor(color).toHsv();
+ var h = hsv.h, s = hsv.s, v = hsv.v;
+ var ret = [];
+ var modification = 1 / results;
+
+ while (results--) {
+ ret.push(tinycolor({ h: h, s: s, v: v}));
+ v = (v + modification) % 1;
+ }
+
+ return ret;
+}
+
+// Utility Functions
+// ---------------------
+
+tinycolor.mix = function(color1, color2, amount) {
+ amount = (amount === 0) ? 0 : (amount || 50);
+
+ var rgb1 = tinycolor(color1).toRgb();
+ var rgb2 = tinycolor(color2).toRgb();
+
+ var p = amount / 100;
+
+ var rgba = {
+ r: ((rgb2.r - rgb1.r) * p) + rgb1.r,
+ g: ((rgb2.g - rgb1.g) * p) + rgb1.g,
+ b: ((rgb2.b - rgb1.b) * p) + rgb1.b,
+ a: ((rgb2.a - rgb1.a) * p) + rgb1.a
+ };
+
+ return tinycolor(rgba);
+};
+
+// Readability Functions
+// ---------------------
+// false
+// tinycolor.isReadable("#000", "#111",{level:"AA",size:"large"}) => false
+tinycolor.isReadable = function(color1, color2, wcag2) {
+ var readability = tinycolor.readability(color1, color2);
+ var wcag2Parms, out;
+
+ out = false;
+
+ wcag2Parms = validateWCAG2Parms(wcag2);
+ switch (wcag2Parms.level + wcag2Parms.size) {
+ case "AAsmall":
+ case "AAAlarge":
+ out = readability >= 4.5;
+ break;
+ case "AAlarge":
+ out = readability >= 3;
+ break;
+ case "AAAsmall":
+ out = readability >= 7;
+ break;
+ }
+ return out;
+
+};
+
+// mostReadable
+// Given a base color and a list of possible foreground or background
+// colors for that base, returns the most readable color.
+// Optionally returns Black or White if the most readable color is unreadable.
+// *Example*
+// tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:false}).toHexString(); // "#112255"
+// tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:true}).toHexString(); // "#ffffff"
+// tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"large"}).toHexString(); // "#faf3f3"
+// tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"small"}).toHexString(); // "#ffffff"
+tinycolor.mostReadable = function(baseColor, colorList, args) {
+ var bestColor = null;
+ var bestScore = 0;
+ var readability;
+ var includeFallbackColors, level, size ;
+ args = args || {};
+ includeFallbackColors = args.includeFallbackColors ;
+ level = args.level;
+ size = args.size;
+
+ for (var i= 0; i < colorList.length ; i++) {
+ readability = tinycolor.readability(baseColor, colorList[i]);
+ if (readability > bestScore) {
+ bestScore = readability;
+ bestColor = tinycolor(colorList[i]);
+ }
+ }
+
+ if (tinycolor.isReadable(baseColor, bestColor, {"level":level,"size":size}) || !includeFallbackColors) {
+ return bestColor;
+ }
+ else {
+ args.includeFallbackColors=false;
+ return tinycolor.mostReadable(baseColor,["#fff", "#000"],args);
+ }
+};
+
+// Big List of Colors
+// ------------------
+//
+var names = tinycolor.names = {
+ aliceblue: "f0f8ff",
+ antiquewhite: "faebd7",
+ aqua: "0ff",
+ aquamarine: "7fffd4",
+ azure: "f0ffff",
+ beige: "f5f5dc",
+ bisque: "ffe4c4",
+ black: "000",
+ blanchedalmond: "ffebcd",
+ blue: "00f",
+ blueviolet: "8a2be2",
+ brown: "a52a2a",
+ burlywood: "deb887",
+ burntsienna: "ea7e5d",
+ cadetblue: "5f9ea0",
+ chartreuse: "7fff00",
+ chocolate: "d2691e",
+ coral: "ff7f50",
+ cornflowerblue: "6495ed",
+ cornsilk: "fff8dc",
+ crimson: "dc143c",
+ cyan: "0ff",
+ darkblue: "00008b",
+ darkcyan: "008b8b",
+ darkgoldenrod: "b8860b",
+ darkgray: "a9a9a9",
+ darkgreen: "006400",
+ darkgrey: "a9a9a9",
+ darkkhaki: "bdb76b",
+ darkmagenta: "8b008b",
+ darkolivegreen: "556b2f",
+ darkorange: "ff8c00",
+ darkorchid: "9932cc",
+ darkred: "8b0000",
+ darksalmon: "e9967a",
+ darkseagreen: "8fbc8f",
+ darkslateblue: "483d8b",
+ darkslategray: "2f4f4f",
+ darkslategrey: "2f4f4f",
+ darkturquoise: "00ced1",
+ darkviolet: "9400d3",
+ deeppink: "ff1493",
+ deepskyblue: "00bfff",
+ dimgray: "696969",
+ dimgrey: "696969",
+ dodgerblue: "1e90ff",
+ firebrick: "b22222",
+ floralwhite: "fffaf0",
+ forestgreen: "228b22",
+ fuchsia: "f0f",
+ gainsboro: "dcdcdc",
+ ghostwhite: "f8f8ff",
+ gold: "ffd700",
+ goldenrod: "daa520",
+ gray: "808080",
+ green: "008000",
+ greenyellow: "adff2f",
+ grey: "808080",
+ honeydew: "f0fff0",
+ hotpink: "ff69b4",
+ indianred: "cd5c5c",
+ indigo: "4b0082",
+ ivory: "fffff0",
+ khaki: "f0e68c",
+ lavender: "e6e6fa",
+ lavenderblush: "fff0f5",
+ lawngreen: "7cfc00",
+ lemonchiffon: "fffacd",
+ lightblue: "add8e6",
+ lightcoral: "f08080",
+ lightcyan: "e0ffff",
+ lightgoldenrodyellow: "fafad2",
+ lightgray: "d3d3d3",
+ lightgreen: "90ee90",
+ lightgrey: "d3d3d3",
+ lightpink: "ffb6c1",
+ lightsalmon: "ffa07a",
+ lightseagreen: "20b2aa",
+ lightskyblue: "87cefa",
+ lightslategray: "789",
+ lightslategrey: "789",
+ lightsteelblue: "b0c4de",
+ lightyellow: "ffffe0",
+ lime: "0f0",
+ limegreen: "32cd32",
+ linen: "faf0e6",
+ magenta: "f0f",
+ maroon: "800000",
+ mediumaquamarine: "66cdaa",
+ mediumblue: "0000cd",
+ mediumorchid: "ba55d3",
+ mediumpurple: "9370db",
+ mediumseagreen: "3cb371",
+ mediumslateblue: "7b68ee",
+ mediumspringgreen: "00fa9a",
+ mediumturquoise: "48d1cc",
+ mediumvioletred: "c71585",
+ midnightblue: "191970",
+ mintcream: "f5fffa",
+ mistyrose: "ffe4e1",
+ moccasin: "ffe4b5",
+ navajowhite: "ffdead",
+ navy: "000080",
+ oldlace: "fdf5e6",
+ olive: "808000",
+ olivedrab: "6b8e23",
+ orange: "ffa500",
+ orangered: "ff4500",
+ orchid: "da70d6",
+ palegoldenrod: "eee8aa",
+ palegreen: "98fb98",
+ paleturquoise: "afeeee",
+ palevioletred: "db7093",
+ papayawhip: "ffefd5",
+ peachpuff: "ffdab9",
+ peru: "cd853f",
+ pink: "ffc0cb",
+ plum: "dda0dd",
+ powderblue: "b0e0e6",
+ purple: "800080",
+ rebeccapurple: "663399",
+ red: "f00",
+ rosybrown: "bc8f8f",
+ royalblue: "4169e1",
+ saddlebrown: "8b4513",
+ salmon: "fa8072",
+ sandybrown: "f4a460",
+ seagreen: "2e8b57",
+ seashell: "fff5ee",
+ sienna: "a0522d",
+ silver: "c0c0c0",
+ skyblue: "87ceeb",
+ slateblue: "6a5acd",
+ slategray: "708090",
+ slategrey: "708090",
+ snow: "fffafa",
+ springgreen: "00ff7f",
+ steelblue: "4682b4",
+ tan: "d2b48c",
+ teal: "008080",
+ thistle: "d8bfd8",
+ tomato: "ff6347",
+ turquoise: "40e0d0",
+ violet: "ee82ee",
+ wheat: "f5deb3",
+ white: "fff",
+ whitesmoke: "f5f5f5",
+ yellow: "ff0",
+ yellowgreen: "9acd32"
+};
+
+// Make it easy to access colors via hexNames[hex]
+var hexNames = tinycolor.hexNames = flip(names);
+
+// Utilities
+// ---------
+
+// { 'name1': 'val1' } becomes { 'val1': 'name1' }
+function flip(o) {
+ var flipped = { };
+ for (var i in o) {
+ if (o.hasOwnProperty(i)) {
+ flipped[o[i]] = i;
+ }
+ }
+ return flipped;
+}
+
+// Return a valid alpha value [0,1] with all invalid values being set to 1
+function boundAlpha(a) {
+ a = parseFloat(a);
+
+ if (isNaN(a) || a < 0 || a > 1) {
+ a = 1;
+ }
+
+ return a;
+}
+
+// Take input from [0, n] and return it as [0, 1]
+function bound01(n, max) {
+ if (isOnePointZero(n)) { n = "100%"; }
+
+ var processPercent = isPercentage(n);
+ n = mathMin(max, mathMax(0, parseFloat(n)));
+
+ // Automatically convert percentage into number
+ if (processPercent) {
+ n = parseInt(n * max, 10) / 100;
+ }
+
+ // Handle floating point rounding errors
+ if ((Math.abs(n - max) < 0.000001)) {
+ return 1;
+ }
+
+ // Convert into [0, 1] range if it isn't already
+ return (n % max) / parseFloat(max);
+}
+
+// Force a number between 0 and 1
+function clamp01(val) {
+ return mathMin(1, mathMax(0, val));
+}
+
+// Parse a base-16 hex value into a base-10 integer
+function parseIntFromHex(val) {
+ return parseInt(val, 16);
+}
+
+// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
+//
+function isOnePointZero(n) {
+ return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
+}
+
+// Check to see if string passed in is a percentage
+function isPercentage(n) {
+ return typeof n === "string" && n.indexOf('%') != -1;
+}
+
+// Force a hex value to have 2 characters
+function pad2(c) {
+ return c.length == 1 ? '0' + c : '' + c;
+}
+
+// Replace a decimal with it's percentage value
+function convertToPercentage(n) {
+ if (n <= 1) {
+ n = (n * 100) + "%";
+ }
+
+ return n;
+}
+
+// Converts a decimal to a hex value
+function convertDecimalToHex(d) {
+ return Math.round(parseFloat(d) * 255).toString(16);
+}
+// Converts a hex value to a decimal
+function convertHexToDecimal(h) {
+ return (parseIntFromHex(h) / 255);
+}
+
+var matchers = (function() {
+
+ //
+ var CSS_INTEGER = "[-\\+]?\\d+%?";
+
+ //
+ var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
+
+ // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
+ var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
+
+ // Actual matching.
+ // Parentheses and commas are optional, but not required.
+ // Whitespace can take the place of commas or opening paren
+ var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
+ var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
+
+ return {
+ CSS_UNIT: new RegExp(CSS_UNIT),
+ rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
+ rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
+ hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
+ hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
+ hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
+ hsva: new RegExp("hsva" + PERMISSIVE_MATCH4),
+ hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
+ hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
+ hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
+ hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
+ };
+})();
+
+// isValidCSSUnit
+// Take in a single string / number and check to see if it looks like a CSS unit
+// (see matchers above for definition).
+function isValidCSSUnit(color) {
+ return !!matchers.CSS_UNIT.exec(color);
+}
+
+// stringInputToObject
+// Permissive string parsing. Take in a number of formats, and output an object
+// based on detected format. Returns { r, g, b } or { h, s, l } or { h, s, v}
+function stringInputToObject(color) {
+
+ color = color.replace(trimLeft, '').replace(trimRight, '').toLowerCase();
+ var named = false;
+ if (names[color]) {
+ color = names[color];
+ named = true;
+ }
+ else if (color == 'transparent') {
+ return { r: 0, g: 0, b: 0, a: 0, format: "name" };
+ }
+
+ // Try to match string input using regular expressions.
+ // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
+ // Just return an object and let the conversion functions handle that.
+ // This way the result will be the same whether the tinycolor is initialized with string or object.
+ var match;
+ if ((match = matchers.rgb.exec(color))) {
+ return { r: match[1], g: match[2], b: match[3] };
+ }
+ if ((match = matchers.rgba.exec(color))) {
+ return { r: match[1], g: match[2], b: match[3], a: match[4] };
+ }
+ if ((match = matchers.hsl.exec(color))) {
+ return { h: match[1], s: match[2], l: match[3] };
+ }
+ if ((match = matchers.hsla.exec(color))) {
+ return { h: match[1], s: match[2], l: match[3], a: match[4] };
+ }
+ if ((match = matchers.hsv.exec(color))) {
+ return { h: match[1], s: match[2], v: match[3] };
+ }
+ if ((match = matchers.hsva.exec(color))) {
+ return { h: match[1], s: match[2], v: match[3], a: match[4] };
+ }
+ if ((match = matchers.hex8.exec(color))) {
+ return {
+ r: parseIntFromHex(match[1]),
+ g: parseIntFromHex(match[2]),
+ b: parseIntFromHex(match[3]),
+ a: convertHexToDecimal(match[4]),
+ format: named ? "name" : "hex8"
+ };
+ }
+ if ((match = matchers.hex6.exec(color))) {
+ return {
+ r: parseIntFromHex(match[1]),
+ g: parseIntFromHex(match[2]),
+ b: parseIntFromHex(match[3]),
+ format: named ? "name" : "hex"
+ };
+ }
+ if ((match = matchers.hex4.exec(color))) {
+ return {
+ r: parseIntFromHex(match[1] + '' + match[1]),
+ g: parseIntFromHex(match[2] + '' + match[2]),
+ b: parseIntFromHex(match[3] + '' + match[3]),
+ a: convertHexToDecimal(match[4] + '' + match[4]),
+ format: named ? "name" : "hex8"
+ };
+ }
+ if ((match = matchers.hex3.exec(color))) {
+ return {
+ r: parseIntFromHex(match[1] + '' + match[1]),
+ g: parseIntFromHex(match[2] + '' + match[2]),
+ b: parseIntFromHex(match[3] + '' + match[3]),
+ format: named ? "name" : "hex"
+ };
+ }
+
+ return false;
+}
+
+function validateWCAG2Parms(parms) {
+ // return valid WCAG2 parms for isReadable.
+ // If input parms are invalid, return {"level":"AA", "size":"small"}
+ var level, size;
+ parms = parms || {"level":"AA", "size":"small"};
+ level = (parms.level || "AA").toUpperCase();
+ size = (parms.size || "small").toLowerCase();
+ if (level !== "AA" && level !== "AAA") {
+ level = "AA";
+ }
+ if (size !== "small" && size !== "large") {
+ size = "small";
+ }
+ return {"level":level, "size":size};
+}
+
+this.tinycolor = tinycolor;
+
+})()`;
+}
+// It is hacky way to make this function will be compiled preferentially by less
+// resolve error: `ReferenceError: colorPalette is not defined`
+// https://github.com/ant-design/ant-motion/issues/44
+.tinyColorMixin();
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/compact.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/compact.less
new file mode 100644
index 0000000..ef0008b
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/compact.less
@@ -0,0 +1,4 @@
+@root-entry-name: default;
+
+@import './themes/compact.less';
+@import './core/index';
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/base.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/base.less
new file mode 100644
index 0000000..a704c55
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/base.less
@@ -0,0 +1,10 @@
+// Config global less under antd
+[class^=~'@{ant-prefix}-'],
+[class*=~' @{ant-prefix}-'] {
+ // remove the clear button of a text input control in IE10+
+ &::-ms-clear,
+ input::-ms-clear,
+ input::-ms-reveal {
+ display: none;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/global.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/global.less
new file mode 100644
index 0000000..cb26cce
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/global.less
@@ -0,0 +1,491 @@
+/* stylelint-disable property-no-vendor-prefix, at-rule-no-vendor-prefix */
+
+// Reboot
+//
+// Normalization of HTML elements, manually forked from Normalize.css to remove
+// styles targeting irrelevant browsers while applying new styles.
+//
+// Normalize is licensed MIT. https://github.com/necolas/normalize.css
+
+// HTML & Body reset
+@{html-selector},
+body {
+ .square(100%);
+}
+
+// remove the clear button of a text input control in IE10+
+input::-ms-clear,
+input::-ms-reveal {
+ display: none;
+}
+
+// Document
+//
+// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.
+// 2. Change the default font family in all browsers.
+// 3. Correct the line height in all browsers.
+// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.
+// 5. Setting @viewport causes scrollbars to overlap content in IE11 and Edge, so
+// we force a non-overlapping, non-auto-hiding scrollbar to counteract.
+// 6. Change the default tap highlight to be completely transparent in iOS.
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box; // 1
+}
+
+@{html-selector} {
+ font-family: sans-serif; // 2
+ line-height: 1.15; // 3
+ -webkit-text-size-adjust: 100%; // 4
+ -ms-text-size-adjust: 100%; // 4
+ -ms-overflow-style: scrollbar; // 5
+ -webkit-tap-highlight-color: fade(@black, 0%); // 6
+}
+
+// IE10+ doesn't honor `` in some cases.
+@-ms-viewport {
+ width: device-width;
+}
+
+// Body
+//
+// 1. remove the margin in all browsers.
+// 2. As a best practice, apply a default `body-background`.
+
+body {
+ margin: 0; // 1
+ color: @text-color;
+ font-size: @font-size-base;
+ font-family: @font-family;
+ font-variant: @font-variant-base;
+ line-height: @line-height-base;
+ background-color: @body-background; // 2
+ font-feature-settings: @font-feature-settings-base;
+}
+
+// Suppress the focus outline on elements that cannot be accessed via keyboard.
+// This prevents an unwanted focus outline from appearing around elements that
+// might still respond to pointer events.
+//
+// Credit: https://github.com/suitcss/base
+[tabindex='-1']:focus {
+ outline: none !important;
+}
+
+// Content grouping
+//
+// 1. Add the correct box sizing in Firefox.
+// 2. Show the overflow in Edge and IE.
+
+hr {
+ box-sizing: content-box; // 1
+ height: 0; // 1
+ overflow: visible; // 2
+}
+
+//
+// Typography
+//
+
+// remove top margins from headings
+//
+// By default, ``-`` all receive top and bottom margins. We nuke the top
+// margin for easier control within type scales as it avoids margin collapsing.
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ margin-top: 0;
+ margin-bottom: 0.5em;
+ color: @heading-color;
+ font-weight: 500;
+}
+
+// Reset margins on paragraphs
+//
+// Similarly, the top margin on ` `s get reset. However, we also reset the
+// bottom margin to use `em` units instead of `em`.
+p {
+ margin-top: 0;
+ margin-bottom: 1em;
+}
+
+// Abbreviations
+//
+// 1. remove the bottom border in Firefox 39-.
+// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+// 3. Add explicit cursor to indicate changed behavior.
+// 4. Duplicate behavior to the data-* attribute for our tooltip plugin
+
+abbr[title],
+abbr[data-original-title] {
+ // 4
+ text-decoration: underline; // 2
+ text-decoration: underline dotted; // 2
+ border-bottom: 0; // 1
+ cursor: help; // 3
+}
+
+address {
+ margin-bottom: 1em;
+ font-style: normal;
+ line-height: inherit;
+}
+
+input[type='text'],
+input[type='password'],
+input[type='number'],
+textarea {
+ -webkit-appearance: none;
+}
+
+ol,
+ul,
+dl {
+ margin-top: 0;
+ margin-bottom: 1em;
+}
+
+ol ol,
+ul ul,
+ol ul,
+ul ol {
+ margin-bottom: 0;
+}
+
+dt {
+ font-weight: 500;
+}
+
+dd {
+ margin-bottom: 0.5em;
+ margin-left: 0; // Undo browser default
+}
+
+blockquote {
+ margin: 0 0 1em;
+}
+
+dfn {
+ font-style: italic; // Add the correct font style in Android 4.3-
+}
+
+b,
+strong {
+ font-weight: bolder; // Add the correct font weight in Chrome, Edge, and Safari
+}
+
+small {
+ font-size: 80%; // Add the correct font size in all browsers
+}
+
+//
+// Prevent `sub` and `sup` elements from affecting the line height in
+// all browsers.
+//
+
+sub,
+sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+//
+// Links
+//
+
+a {
+ color: @link-color;
+ text-decoration: @link-decoration;
+ background-color: transparent; // remove the gray background on active links in IE 10.
+ outline: none;
+ cursor: pointer;
+ transition: color 0.3s;
+ -webkit-text-decoration-skip: objects; // remove gaps in links underline in iOS 8+ and Safari 8+.
+
+ &:hover {
+ color: @link-hover-color;
+ }
+
+ &:active {
+ color: @link-active-color;
+ }
+
+ &:active,
+ &:hover {
+ text-decoration: @link-hover-decoration;
+ outline: 0;
+ }
+
+ // https://github.com/ant-design/ant-design/issues/22503
+ &:focus {
+ text-decoration: @link-focus-decoration;
+ outline: @link-focus-outline;
+ }
+
+ &[disabled] {
+ color: @disabled-color;
+ cursor: not-allowed;
+ }
+}
+
+//
+// Code
+//
+
+pre,
+code,
+kbd,
+samp {
+ font-size: 1em; // Correct the odd `em` font sizing in all browsers.
+ font-family: @code-family;
+}
+
+pre {
+ // remove browser default top margin
+ margin-top: 0;
+ // Reset browser default of `1em` to use `em`s
+ margin-bottom: 1em;
+ // Don't allow content to break outside
+ overflow: auto;
+}
+
+//
+// Figures
+//
+figure {
+ // Apply a consistent margin strategy (matches our type styles).
+ margin: 0 0 1em;
+}
+
+//
+// Images and content
+//
+
+img {
+ vertical-align: middle;
+ border-style: none; // remove the border on images inside links in IE 10-.
+}
+
+// Avoid 300ms click delay on touch devices that support the `touch-action` CSS property.
+//
+// In particular, unlike most other browsers, IE11+Edge on Windows 10 on touch devices and IE Mobile 10-11
+// DON'T remove the click delay when `` is present.
+// However, they DO support emoving the click delay via `touch-action: manipulation`.
+// See:
+// * https://getbootstrap.com/docs/4.0/content/reboot/#click-delay-optimization-for-touch
+// * http://caniuse.com/#feat=css-touch-action
+// * https://patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay
+
+a,
+area,
+button,
+[role='button'],
+input:not([type='range']),
+label,
+select,
+summary,
+textarea {
+ touch-action: manipulation;
+}
+
+//
+// Tables
+//
+
+table {
+ border-collapse: collapse; // Prevent double borders
+}
+
+caption {
+ padding-top: 0.75em;
+ padding-bottom: 0.3em;
+ color: @text-color-secondary;
+ text-align: left;
+ caption-side: bottom;
+}
+
+//
+// Forms
+//
+
+input,
+button,
+select,
+optgroup,
+textarea {
+ margin: 0; // remove the margin in Firefox and Safari
+ color: inherit;
+ font-size: inherit;
+ font-family: inherit;
+ line-height: inherit;
+}
+
+button,
+input {
+ overflow: visible; // Show the overflow in Edge
+}
+
+button,
+select {
+ text-transform: none; // remove the inheritance of text transform in Firefox
+}
+
+// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
+// controls in Android 4.
+// 2. Correct the inability to style clickable types in iOS and Safari.
+button,
+@{html-selector} [type="button"], /* 1 */
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button; // 2
+}
+
+// remove inner border and padding from Firefox, but don't restore the outline like Normalize.
+button::-moz-focus-inner,
+[type='button']::-moz-focus-inner,
+[type='reset']::-moz-focus-inner,
+[type='submit']::-moz-focus-inner {
+ padding: 0;
+ border-style: none;
+}
+
+input[type='radio'],
+input[type='checkbox'] {
+ box-sizing: border-box; // 1. Add the correct box sizing in IE 10-
+ padding: 0; // 2. remove the padding in IE 10-
+}
+
+input[type='date'],
+input[type='time'],
+input[type='datetime-local'],
+input[type='month'] {
+ // remove the default appearance of temporal inputs to avoid a Mobile Safari
+ // bug where setting a custom line-height prevents text from being vertically
+ // centered within the input.
+ // See https://bugs.webkit.org/show_bug.cgi?id=139848
+ // and https://github.com/twbs/bootstrap/issues/11266
+ -webkit-appearance: listbox;
+}
+
+textarea {
+ overflow: auto; // remove the default vertical scrollbar in IE.
+ // Textareas should really only resize vertically so they don't break their (horizontal) containers.
+ resize: vertical;
+}
+
+fieldset {
+ // Browsers set a default `min-width: min-content;` on fieldsets,
+ // unlike e.g. `
`s, which have `min-width: 0;` by default.
+ // So we reset that to ensure fieldsets behave more like a standard block element.
+ // See https://github.com/twbs/bootstrap/issues/12359
+ // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements
+ min-width: 0;
+ margin: 0;
+ // Reset the default outline behavior of fieldsets so they don't affect page layout.
+ padding: 0;
+ border: 0;
+}
+
+// 1. Correct the text wrapping in Edge and IE.
+// 2. Correct the color inheritance from `fieldset` elements in IE.
+legend {
+ display: block;
+ width: 100%;
+ max-width: 100%; // 1
+ margin-bottom: 0.5em;
+ padding: 0;
+ color: inherit; // 2
+ font-size: 1.5em;
+ line-height: inherit;
+ white-space: normal; // 1
+}
+
+progress {
+ vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.
+}
+
+// Correct the cursor style of incement and decement buttons in Chrome.
+[type='number']::-webkit-inner-spin-button,
+[type='number']::-webkit-outer-spin-button {
+ height: auto;
+}
+
+[type='search'] {
+ // This overrides the extra rounded corners on search inputs in iOS so that our
+ // `.form-control` class can properly style them. Note that this cannot simply
+ // be added to `.form-control` as it's not specific enough. For details, see
+ // https://github.com/twbs/bootstrap/issues/11586.
+ outline-offset: -2px; // 2. Correct the outline style in Safari.
+ -webkit-appearance: none;
+}
+
+//
+// remove the inner padding and cancel buttons in Chrome and Safari on macOS.
+//
+
+[type='search']::-webkit-search-cancel-button,
+[type='search']::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+//
+// 1. Correct the inability to style clickable types in iOS and Safari.
+// 2. Change font properties to `inherit` in Safari.
+//
+
+::-webkit-file-upload-button {
+ font: inherit; // 2
+ -webkit-appearance: button; // 1
+}
+
+//
+// Correct element displays
+//
+
+output {
+ display: inline-block;
+}
+
+summary {
+ display: list-item; // Add the correct display in all browsers
+}
+
+template {
+ display: none; // Add the correct display in IE
+}
+
+// Always hide an element with the `hidden` HTML attribute (from PureCSS).
+// Needed for proper display in IE 10-.
+[hidden] {
+ display: none !important;
+}
+
+mark {
+ padding: 0.2em;
+ background-color: @yellow-1;
+}
+
+::selection {
+ color: @text-color-inverse;
+ background: @text-selection-bg;
+}
+
+// Utility classes
+.clearfix {
+ .clearfix();
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/iconfont.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/iconfont.less
new file mode 100644
index 0000000..597b854
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/iconfont.less
@@ -0,0 +1,22 @@
+@import '../themes/index';
+@import '../mixins/iconfont';
+
+.@{iconfont-css-prefix} {
+ .iconfont-mixin();
+
+ // https://github.com/ant-design/ant-design/issues/33703
+ & > & {
+ line-height: 0;
+ vertical-align: 0;
+ }
+
+ &[tabindex] {
+ cursor: pointer;
+ }
+}
+
+.@{iconfont-css-prefix}-spin,
+.@{iconfont-css-prefix}-spin::before {
+ display: inline-block;
+ animation: loadingCircle 1s infinite linear;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/index.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/index.less
new file mode 100644
index 0000000..c493947
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/index.less
@@ -0,0 +1,5 @@
+@import '../mixins/index';
+@import 'base';
+@import 'global';
+@import 'iconfont';
+@import 'motion';
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion.less
new file mode 100644
index 0000000..286d50e
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion.less
@@ -0,0 +1,22 @@
+// @import '../mixins/motion'; This has moved to theme/xxx inside.
+@import 'motion/fade';
+@import 'motion/move';
+@import 'motion/other';
+@import 'motion/slide';
+@import 'motion/zoom';
+
+// For common/openAnimation
+.ant-motion-collapse-legacy {
+ overflow: hidden;
+
+ &-active {
+ transition: height @animation-duration-base @ease-in-out,
+ opacity @animation-duration-base @ease-in-out !important;
+ }
+}
+
+.ant-motion-collapse {
+ overflow: hidden;
+ transition: height @animation-duration-base @ease-in-out,
+ opacity @animation-duration-base @ease-in-out !important;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/fade.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/fade.less
new file mode 100644
index 0000000..f4a9513
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/fade.less
@@ -0,0 +1,34 @@
+.fade-motion(@className, @keyframeName) {
+ @name: ~'@{ant-prefix}-@{className}';
+ .make-motion(@name, @keyframeName);
+ .@{name}-enter,
+ .@{name}-appear {
+ opacity: 0;
+ animation-timing-function: linear;
+ }
+ .@{name}-leave {
+ animation-timing-function: linear;
+ }
+}
+
+.fade-motion(fade, antFade);
+
+@keyframes antFadeIn {
+ 0% {
+ opacity: 0;
+ }
+
+ 100% {
+ opacity: 1;
+ }
+}
+
+@keyframes antFadeOut {
+ 0% {
+ opacity: 1;
+ }
+
+ 100% {
+ opacity: 0;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/move.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/move.less
new file mode 100644
index 0000000..733f26d
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/move.less
@@ -0,0 +1,129 @@
+.move-motion(@className, @keyframeName) {
+ @name: ~'@{ant-prefix}-@{className}';
+ .make-motion(@name, @keyframeName);
+ .@{name}-enter,
+ .@{name}-appear {
+ opacity: 0;
+ animation-timing-function: @ease-out-circ;
+ }
+ .@{name}-leave {
+ animation-timing-function: @ease-in-circ;
+ }
+}
+
+.move-motion(move-up, antMoveUp);
+.move-motion(move-down, antMoveDown);
+.move-motion(move-left, antMoveLeft);
+.move-motion(move-right, antMoveRight);
+
+@keyframes antMoveDownIn {
+ 0% {
+ transform: translateY(100%);
+ transform-origin: 0 0;
+ opacity: 0;
+ }
+
+ 100% {
+ transform: translateY(0%);
+ transform-origin: 0 0;
+ opacity: 1;
+ }
+}
+
+@keyframes antMoveDownOut {
+ 0% {
+ transform: translateY(0%);
+ transform-origin: 0 0;
+ opacity: 1;
+ }
+
+ 100% {
+ transform: translateY(100%);
+ transform-origin: 0 0;
+ opacity: 0;
+ }
+}
+
+@keyframes antMoveLeftIn {
+ 0% {
+ transform: translateX(-100%);
+ transform-origin: 0 0;
+ opacity: 0;
+ }
+
+ 100% {
+ transform: translateX(0%);
+ transform-origin: 0 0;
+ opacity: 1;
+ }
+}
+
+@keyframes antMoveLeftOut {
+ 0% {
+ transform: translateX(0%);
+ transform-origin: 0 0;
+ opacity: 1;
+ }
+
+ 100% {
+ transform: translateX(-100%);
+ transform-origin: 0 0;
+ opacity: 0;
+ }
+}
+
+@keyframes antMoveRightIn {
+ 0% {
+ transform: translateX(100%);
+ transform-origin: 0 0;
+ opacity: 0;
+ }
+
+ 100% {
+ transform: translateX(0%);
+ transform-origin: 0 0;
+ opacity: 1;
+ }
+}
+
+@keyframes antMoveRightOut {
+ 0% {
+ transform: translateX(0%);
+ transform-origin: 0 0;
+ opacity: 1;
+ }
+
+ 100% {
+ transform: translateX(100%);
+ transform-origin: 0 0;
+ opacity: 0;
+ }
+}
+
+@keyframes antMoveUpIn {
+ 0% {
+ transform: translateY(-100%);
+ transform-origin: 0 0;
+ opacity: 0;
+ }
+
+ 100% {
+ transform: translateY(0%);
+ transform-origin: 0 0;
+ opacity: 1;
+ }
+}
+
+@keyframes antMoveUpOut {
+ 0% {
+ transform: translateY(0%);
+ transform-origin: 0 0;
+ opacity: 1;
+ }
+
+ 100% {
+ transform: translateY(-100%);
+ transform-origin: 0 0;
+ opacity: 0;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/other.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/other.less
new file mode 100644
index 0000000..d1a2549
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/other.less
@@ -0,0 +1,51 @@
+@keyframes loadingCircle {
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+
+@click-animating-true: ~"[@{ant-prefix}-click-animating='true']";
+@click-animating-with-extra-node-true: ~"[@{ant-prefix}-click-animating-without-extra-node='true']";
+
+@{click-animating-true},
+@{click-animating-with-extra-node-true} {
+ position: relative;
+}
+
+html {
+ --antd-wave-shadow-color: @primary-color;
+ --scroll-bar: 0;
+}
+
+@click-animating-with-extra-node-true-after: ~'@{click-animating-with-extra-node-true}::after';
+
+@{click-animating-with-extra-node-true-after},
+.@{ant-prefix}-click-animating-node {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ display: block;
+ border-radius: inherit;
+ box-shadow: 0 0 0 0 @primary-color;
+ box-shadow: 0 0 0 0 var(--antd-wave-shadow-color);
+ opacity: 0.2;
+ animation: fadeEffect 2s @ease-out-circ, waveEffect 0.4s @ease-out-circ;
+ animation-fill-mode: forwards;
+ content: '';
+ pointer-events: none;
+}
+
+@keyframes waveEffect {
+ 100% {
+ box-shadow: 0 0 0 @primary-color;
+ box-shadow: 0 0 0 @wave-animation-width var(--antd-wave-shadow-color);
+ }
+}
+
+@keyframes fadeEffect {
+ 100% {
+ opacity: 0;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/slide.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/slide.less
new file mode 100644
index 0000000..17de58c
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/slide.less
@@ -0,0 +1,129 @@
+.slide-motion(@className, @keyframeName) {
+ @name: ~'@{ant-prefix}-@{className}';
+ .make-motion(@name, @keyframeName);
+ .@{name}-enter,
+ .@{name}-appear {
+ opacity: 0;
+ animation-timing-function: @ease-out-quint;
+ }
+ .@{name}-leave {
+ animation-timing-function: @ease-in-quint;
+ }
+}
+
+.slide-motion(slide-up, antSlideUp);
+.slide-motion(slide-down, antSlideDown);
+.slide-motion(slide-left, antSlideLeft);
+.slide-motion(slide-right, antSlideRight);
+
+@keyframes antSlideUpIn {
+ 0% {
+ transform: scaleY(0.8);
+ transform-origin: 0% 0%;
+ opacity: 0;
+ }
+
+ 100% {
+ transform: scaleY(1);
+ transform-origin: 0% 0%;
+ opacity: 1;
+ }
+}
+
+@keyframes antSlideUpOut {
+ 0% {
+ transform: scaleY(1);
+ transform-origin: 0% 0%;
+ opacity: 1;
+ }
+
+ 100% {
+ transform: scaleY(0.8);
+ transform-origin: 0% 0%;
+ opacity: 0;
+ }
+}
+
+@keyframes antSlideDownIn {
+ 0% {
+ transform: scaleY(0.8);
+ transform-origin: 100% 100%;
+ opacity: 0;
+ }
+
+ 100% {
+ transform: scaleY(1);
+ transform-origin: 100% 100%;
+ opacity: 1;
+ }
+}
+
+@keyframes antSlideDownOut {
+ 0% {
+ transform: scaleY(1);
+ transform-origin: 100% 100%;
+ opacity: 1;
+ }
+
+ 100% {
+ transform: scaleY(0.8);
+ transform-origin: 100% 100%;
+ opacity: 0;
+ }
+}
+
+@keyframes antSlideLeftIn {
+ 0% {
+ transform: scaleX(0.8);
+ transform-origin: 0% 0%;
+ opacity: 0;
+ }
+
+ 100% {
+ transform: scaleX(1);
+ transform-origin: 0% 0%;
+ opacity: 1;
+ }
+}
+
+@keyframes antSlideLeftOut {
+ 0% {
+ transform: scaleX(1);
+ transform-origin: 0% 0%;
+ opacity: 1;
+ }
+
+ 100% {
+ transform: scaleX(0.8);
+ transform-origin: 0% 0%;
+ opacity: 0;
+ }
+}
+
+@keyframes antSlideRightIn {
+ 0% {
+ transform: scaleX(0.8);
+ transform-origin: 100% 0%;
+ opacity: 0;
+ }
+
+ 100% {
+ transform: scaleX(1);
+ transform-origin: 100% 0%;
+ opacity: 1;
+ }
+}
+
+@keyframes antSlideRightOut {
+ 0% {
+ transform: scaleX(1);
+ transform-origin: 100% 0%;
+ opacity: 1;
+ }
+
+ 100% {
+ transform: scaleX(0.8);
+ transform-origin: 100% 0%;
+ opacity: 0;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/zoom.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/zoom.less
new file mode 100644
index 0000000..72739b7
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/core/motion/zoom.less
@@ -0,0 +1,179 @@
+.zoom-motion(@className, @keyframeName, @duration: @animation-duration-base) {
+ @name: ~'@{ant-prefix}-@{className}';
+ .make-motion(@name, @keyframeName, @duration);
+ .@{name}-enter,
+ .@{name}-appear {
+ transform: scale(0); // need this by yiminghe
+ opacity: 0;
+ animation-timing-function: @ease-out-circ;
+
+ &-prepare {
+ transform: none;
+ }
+ }
+ .@{name}-leave {
+ animation-timing-function: @ease-in-out-circ;
+ }
+}
+
+// For Modal, Select choosen item
+.zoom-motion(zoom, antZoom);
+// For Popover, Popconfirm, Dropdown
+.zoom-motion(zoom-big, antZoomBig);
+// For Tooltip
+.zoom-motion(zoom-big-fast, antZoomBig, @animation-duration-fast);
+
+.zoom-motion(zoom-up, antZoomUp);
+.zoom-motion(zoom-down, antZoomDown);
+.zoom-motion(zoom-left, antZoomLeft);
+.zoom-motion(zoom-right, antZoomRight);
+
+@keyframes antZoomIn {
+ 0% {
+ transform: scale(0.2);
+ opacity: 0;
+ }
+
+ 100% {
+ transform: scale(1);
+ opacity: 1;
+ }
+}
+
+@keyframes antZoomOut {
+ 0% {
+ transform: scale(1);
+ }
+
+ 100% {
+ transform: scale(0.2);
+ opacity: 0;
+ }
+}
+
+@keyframes antZoomBigIn {
+ 0% {
+ transform: scale(0.8);
+ opacity: 0;
+ }
+
+ 100% {
+ transform: scale(1);
+ opacity: 1;
+ }
+}
+
+@keyframes antZoomBigOut {
+ 0% {
+ transform: scale(1);
+ }
+
+ 100% {
+ transform: scale(0.8);
+ opacity: 0;
+ }
+}
+
+@keyframes antZoomUpIn {
+ 0% {
+ transform: scale(0.8);
+ transform-origin: 50% 0%;
+ opacity: 0;
+ }
+
+ 100% {
+ transform: scale(1);
+ transform-origin: 50% 0%;
+ }
+}
+
+@keyframes antZoomUpOut {
+ 0% {
+ transform: scale(1);
+ transform-origin: 50% 0%;
+ }
+
+ 100% {
+ transform: scale(0.8);
+ transform-origin: 50% 0%;
+ opacity: 0;
+ }
+}
+
+@keyframes antZoomLeftIn {
+ 0% {
+ transform: scale(0.8);
+ transform-origin: 0% 50%;
+ opacity: 0;
+ }
+
+ 100% {
+ transform: scale(1);
+ transform-origin: 0% 50%;
+ }
+}
+
+@keyframes antZoomLeftOut {
+ 0% {
+ transform: scale(1);
+ transform-origin: 0% 50%;
+ }
+
+ 100% {
+ transform: scale(0.8);
+ transform-origin: 0% 50%;
+ opacity: 0;
+ }
+}
+
+@keyframes antZoomRightIn {
+ 0% {
+ transform: scale(0.8);
+ transform-origin: 100% 50%;
+ opacity: 0;
+ }
+
+ 100% {
+ transform: scale(1);
+ transform-origin: 100% 50%;
+ }
+}
+
+@keyframes antZoomRightOut {
+ 0% {
+ transform: scale(1);
+ transform-origin: 100% 50%;
+ }
+
+ 100% {
+ transform: scale(0.8);
+ transform-origin: 100% 50%;
+ opacity: 0;
+ }
+}
+
+@keyframes antZoomDownIn {
+ 0% {
+ transform: scale(0.8);
+ transform-origin: 50% 100%;
+ opacity: 0;
+ }
+
+ 100% {
+ transform: scale(1);
+ transform-origin: 50% 100%;
+ }
+}
+
+@keyframes antZoomDownOut {
+ 0% {
+ transform: scale(1);
+ transform-origin: 50% 100%;
+ }
+
+ 100% {
+ transform: scale(0.8);
+ transform-origin: 50% 100%;
+ opacity: 0;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/dark.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/dark.less
new file mode 100644
index 0000000..12a3731
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/dark.less
@@ -0,0 +1,4 @@
+@root-entry-name: default;
+
+@import './themes/dark.less';
+@import './core/index';
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/default.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/default.less
new file mode 100644
index 0000000..ecec084
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/default.less
@@ -0,0 +1,4 @@
+// This is same as `index.less` but given `root-entry-name` for `dist/antd.less` usage
+@root-entry-name: default;
+
+@import './index';
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/index.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/index.less
new file mode 100644
index 0000000..04efa3b
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/index.less
@@ -0,0 +1,2 @@
+@import './themes/index';
+@import './core/index';
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/index.tsx b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/index.tsx
new file mode 100644
index 0000000..d74e52e
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/index.tsx
@@ -0,0 +1 @@
+import './index.less';
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/box.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/box.less
new file mode 100644
index 0000000..4bd3ffa
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/box.less
@@ -0,0 +1,7 @@
+.box(@position: absolute) {
+ position: @position;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/clearfix.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/clearfix.less
new file mode 100644
index 0000000..07e89f8
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/clearfix.less
@@ -0,0 +1,16 @@
+// mixins for clearfix
+// ------------------------
+.clearfix() {
+ // https://github.com/ant-design/ant-design/issues/21301#issuecomment-583955229
+ &::before {
+ display: table;
+ content: '';
+ }
+
+ &::after {
+ // https://github.com/ant-design/ant-design/issues/21864
+ display: table;
+ clear: both;
+ content: '';
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/compatibility.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/compatibility.less
new file mode 100644
index 0000000..9464a75
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/compatibility.less
@@ -0,0 +1,13 @@
+// Compatibility for browsers.
+
+// Placeholder text
+.placeholder(@color: @input-placeholder-color) {
+ &::placeholder {
+ color: @color;
+ user-select: none; // https://github.com/ant-design/ant-design/pull/32639
+ }
+
+ &:placeholder-shown {
+ text-overflow: ellipsis;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/customize.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/customize.less
new file mode 100644
index 0000000..6f6fc18
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/customize.less
@@ -0,0 +1,181 @@
+// customize dark components background in popover containers(like Modal, Drawer, Card, Popover, Popconfirm, Notification, ...)
+// for dark theme
+.popover-customize-bg(@containerClass, @background: @popover-background, @prefix: @ant-prefix)
+ when
+ (@theme = dark) {
+ @picker-prefix-cls: ~'@{prefix}-picker';
+ @slider-prefix-cls: ~'@{prefix}-slider';
+ @anchor-prefix-cls: ~'@{prefix}-anchor';
+ @collapse-prefix-cls: ~'@{prefix}-collapse';
+ @tab-prefix-cls: ~'@{prefix}-tabs';
+ @timeline-prefix-cls: ~'@{prefix}-timeline';
+ @tree-prefix-cls: ~'@{prefix}-tree';
+ @card-prefix-cls: ~'@{prefix}-card';
+ @badge-prefix-cls: ~'@{prefix}-badge';
+ @transfer-prefix-cls: ~'@{prefix}-transfer';
+ @calendar-prefix-cls: ~'@{prefix}-picker-calendar';
+ @calendar-picker-prefix-cls: ~'@{prefix}-picker';
+ @table-prefix-cls: ~'@{prefix}-table';
+
+ @popover-border: @border-width-base @border-style-base @popover-customize-border-color;
+
+ .@{containerClass} {
+ .@{picker-prefix-cls}-clear,
+ .@{slider-prefix-cls}-handle,
+ .@{anchor-prefix-cls}-wrapper,
+ .@{collapse-prefix-cls}-content,
+ .@{timeline-prefix-cls}-item-head,
+ .@{card-prefix-cls} {
+ background-color: @background;
+ }
+
+ .@{transfer-prefix-cls} {
+ &-list {
+ &-header {
+ background: @background;
+ border-bottom: @popover-border;
+ }
+ &-content-item:not(.@{transfer-prefix-cls}-list-content-item-disabled):hover {
+ background-color: @item-hover-bg;
+ }
+ }
+ }
+
+ tr.@{table-prefix-cls}-expanded-row {
+ &,
+ &:hover {
+ > td {
+ background: #272727;
+ }
+ }
+ }
+ .@{table-prefix-cls}.@{table-prefix-cls}-small {
+ thead {
+ > tr {
+ > th {
+ background-color: @background;
+ border-bottom: @popover-border;
+ }
+ }
+ }
+ }
+ .@{table-prefix-cls} {
+ background-color: @background;
+ .@{table-prefix-cls}-row-expand-icon {
+ border: @popover-border;
+ }
+
+ tfoot {
+ > tr {
+ > th,
+ > td {
+ border-bottom: @popover-border;
+ }
+ }
+ }
+
+ thead {
+ > tr {
+ > th {
+ background-color: #272727;
+ border-bottom: @popover-border;
+ }
+ }
+ }
+
+ tbody {
+ > tr {
+ > td {
+ border-bottom: @popover-border;
+ &.@{table-prefix-cls}-cell-fix-left,
+ &.@{table-prefix-cls}-cell-fix-right {
+ background-color: @background;
+ }
+ }
+ &.@{table-prefix-cls}-row:hover {
+ > td {
+ background: @table-header-sort-active-bg;
+ }
+ }
+ }
+ }
+ &.@{table-prefix-cls}-bordered {
+ .@{table-prefix-cls}-title {
+ border: @popover-border;
+ }
+
+ // ============================= Cell =============================
+ thead > tr > th,
+ tbody > tr > td,
+ tfoot > tr > th,
+ tfoot > tr > td {
+ border-right: @popover-border;
+ }
+
+ // Fixed right should provides additional border
+ .@{table-prefix-cls}-cell-fix-right-first::after {
+ border-right: @popover-border;
+ }
+
+ // ============================ Header ============================
+ table > {
+ thead {
+ > tr:not(:last-child) > th {
+ border-bottom: @border-width-base @border-style-base @border-color-split;
+ }
+ }
+ }
+
+ // =========================== Content ============================
+ .@{table-prefix-cls}-container {
+ border: @popover-border;
+ }
+
+ // ========================== Expandable ==========================
+ .@{table-prefix-cls}-expanded-row-fixed {
+ &::after {
+ border-right: @popover-border;
+ }
+ }
+
+ .@{table-prefix-cls}-footer {
+ border: @popover-border;
+ }
+ }
+ .@{table-prefix-cls}-filter-trigger-container-open {
+ background-color: #525252;
+ }
+ }
+
+ .@{calendar-prefix-cls}-full {
+ background-color: @background;
+ .@{calendar-picker-prefix-cls}-panel {
+ background-color: @background;
+ .@{calendar-prefix-cls}-date {
+ border-top: 2px solid @popover-customize-border-color;
+ }
+ }
+ }
+
+ .@{tab-prefix-cls} {
+ &.@{tab-prefix-cls}-card .@{tab-prefix-cls}-card-bar .@{tab-prefix-cls}-tab-active {
+ background-color: @background;
+ border-bottom: @border-width-base solid @background;
+ }
+ }
+
+ .@{badge-prefix-cls} {
+ &-count {
+ box-shadow: 0 0 0 1px @background;
+ }
+ }
+
+ .@{tree-prefix-cls} {
+ &-show-line {
+ .@{tree-prefix-cls}-switcher {
+ background: @background;
+ }
+ }
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/iconfont.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/iconfont.less
new file mode 100644
index 0000000..dd32dd7
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/iconfont.less
@@ -0,0 +1,28 @@
+.iconfont-mixin() {
+ display: inline-block;
+ color: @icon-color;
+ font-style: normal;
+ line-height: 0;
+ text-align: center;
+ text-transform: none;
+ vertical-align: -0.125em; // for SVG icon, see https://blog.prototypr.io/align-svg-icons-to-text-and-say-goodbye-to-font-icons-d44b3d7b26b4
+ text-rendering: optimizelegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+
+ > * {
+ line-height: 1;
+ }
+
+ svg {
+ display: inline-block;
+ }
+
+ &::before {
+ display: none; // dont display old icon.
+ }
+
+ & &-icon {
+ display: block;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/index.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/index.less
new file mode 100644
index 0000000..1da375e
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/index.less
@@ -0,0 +1,14 @@
+// Mixins
+// --------------------------------------------------
+@import 'size';
+@import 'compatibility';
+@import 'clearfix';
+@import 'iconfont';
+@import 'typography';
+@import 'customize';
+@import 'box';
+@import 'modal-mask';
+@import 'motion';
+@import 'reset';
+@import 'operation-unit';
+@import 'rounded-arrow';
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/modal-mask.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/modal-mask.less
new file mode 100644
index 0000000..b406bc1
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/modal-mask.less
@@ -0,0 +1,30 @@
+@import 'box';
+
+.modal-mask() {
+ pointer-events: none;
+
+ &.@{ant-prefix}-zoom-enter,
+ &.@{ant-prefix}-zoom-appear {
+ transform: none; // reset scale avoid mousePosition bug
+ opacity: 0;
+ animation-duration: @animation-duration-slow;
+ user-select: none; // https://github.com/ant-design/ant-design/issues/11777
+ }
+
+ &-mask {
+ .box(fixed);
+ z-index: @zindex-modal-mask;
+ height: 100%;
+ background-color: @modal-mask-bg;
+
+ &-hidden {
+ display: none;
+ }
+ }
+
+ &-wrap {
+ .box(fixed);
+ overflow: auto;
+ outline: 0;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/motion.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/motion.less
new file mode 100644
index 0000000..1e15350
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/motion.less
@@ -0,0 +1,33 @@
+.motion-common(@duration: @animation-duration-base) {
+ animation-duration: @duration;
+ animation-fill-mode: both;
+}
+
+.motion-common-leave(@duration: @animation-duration-base) {
+ animation-duration: @duration;
+ animation-fill-mode: both;
+}
+
+.make-motion(@className, @keyframeName, @duration: @animation-duration-base) {
+ .@{className}-enter,
+ .@{className}-appear {
+ .motion-common(@duration);
+
+ animation-play-state: paused;
+ }
+ .@{className}-leave {
+ .motion-common-leave(@duration);
+
+ animation-play-state: paused;
+ }
+ .@{className}-enter.@{className}-enter-active,
+ .@{className}-appear.@{className}-appear-active {
+ animation-name: ~'@{keyframeName}In';
+ animation-play-state: running;
+ }
+ .@{className}-leave.@{className}-leave-active {
+ animation-name: ~'@{keyframeName}Out';
+ animation-play-state: running;
+ pointer-events: none;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/operation-unit.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/operation-unit.less
new file mode 100644
index 0000000..b695171
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/operation-unit.less
@@ -0,0 +1,15 @@
+.operation-unit() {
+ color: @link-color;
+ outline: none;
+ cursor: pointer;
+ transition: color 0.3s;
+
+ &:focus-visible,
+ &:hover {
+ color: @link-hover-color;
+ }
+
+ &:active {
+ color: @link-active-color;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/reset.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/reset.less
new file mode 100644
index 0000000..905c16e
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/reset.less
@@ -0,0 +1,11 @@
+.reset-component() {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ color: @text-color;
+ font-size: @font-size-base;
+ font-variant: @font-variant-base;
+ line-height: @line-height-base;
+ list-style: none;
+ font-feature-settings: @font-feature-settings-base;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/rounded-arrow.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/rounded-arrow.less
new file mode 100644
index 0000000..1c82643
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/rounded-arrow.less
@@ -0,0 +1,44 @@
+.roundedArrow(@width, @outer-radius, @bg-color: var(--antd-arrow-background-color)) {
+ @corner-height: unit(((@outer-radius) * (1 - 1 / sqrt(2))));
+
+ @width-without-unit: unit(@width);
+ @outer-radius-without-unit: unit(@outer-radius);
+ @inner-radius-without-unit: unit(@arrow-border-radius);
+
+ @a-x: @width-without-unit - @corner-height;
+ @a-y: 2 * @width-without-unit + @corner-height;
+ @b-x: @a-x + @outer-radius-without-unit * (1 / sqrt(2));
+ @b-y: 2 * @width-without-unit;
+ @c-x: 2 * @width-without-unit - @inner-radius-without-unit;
+ @c-y: 2 * @width-without-unit;
+ @d-x: 2 * @width-without-unit;
+ @d-y: 2 * @width-without-unit - @inner-radius-without-unit;
+ @e-x: 2 * @width-without-unit;
+ @e-y: @f-y + @outer-radius-without-unit * (1 / sqrt(2));
+ @f-x: 2 * @width-without-unit + @corner-height;
+ @f-y: @width-without-unit - @corner-height;
+ @g-x: @f-x - 1;
+ @g-y: @f-y;
+ @h-x: @a-x;
+ @h-y: @a-y - 1;
+
+ border-radius: 0 0 @arrow-border-radius;
+ pointer-events: none;
+
+ &::before {
+ position: absolute;
+ top: -@width;
+ left: -@width;
+ width: @width * 3;
+ height: @width * 3;
+ background: @bg-color;
+ // Hack firefox: https://github.com/ant-design/ant-design/pull/33710#issuecomment-1015287825
+ background-repeat: no-repeat;
+ background-position: ceil(-@width + 1px) ceil(-@width + 1px);
+ content: '';
+ clip-path: inset(33% 33%); // For browsers that do not support path()
+ clip-path: path(
+ 'M @{a-x} @{a-y} A @{outer-radius-without-unit} @{outer-radius-without-unit} 0 0 1 @{b-x} @{b-y} L @{c-x} @{c-y} A @{inner-radius-without-unit} @{inner-radius-without-unit} 0 0 0 @{d-x} @{d-y} L @{e-x} @{e-y} A @{outer-radius-without-unit} @{outer-radius-without-unit} 0 0 1 @{f-x} @{f-y} L @{g-x} @{g-y} L @{h-x} @{h-y} Z'
+ );
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/size.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/size.less
new file mode 100644
index 0000000..a8be650
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/size.less
@@ -0,0 +1,10 @@
+// Sizing shortcuts
+
+.size(@width; @height) {
+ width: @width;
+ height: @height;
+}
+
+.square(@size) {
+ .size(@size; @size);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/typography.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/typography.less
new file mode 100644
index 0000000..71a4d39
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/mixins/typography.less
@@ -0,0 +1,58 @@
+// =============== Common ===============
+.typography-paragraph() {
+ margin-bottom: 1em;
+}
+
+.typography-title(@fontSize; @fontWeight; @lineHeight; @headingColor; @headingMarginBottom;) {
+ margin-bottom: @headingMarginBottom;
+ color: @headingColor;
+ font-weight: @fontWeight;
+ font-size: @fontSize;
+ line-height: @lineHeight;
+}
+
+.typography-title-1() {
+ .typography-title(
+ @heading-1-size,
+ @typography-title-font-weight,
+ 1.23,
+ @heading-color,
+ @typography-title-margin-bottom
+ );
+}
+.typography-title-2() {
+ .typography-title(
+ @heading-2-size,
+ @typography-title-font-weight,
+ 1.35,
+ @heading-color,
+ @typography-title-margin-bottom
+ );
+}
+.typography-title-3() {
+ .typography-title(
+ @heading-3-size,
+ @typography-title-font-weight,
+ 1.35,
+ @heading-color,
+ @typography-title-margin-bottom
+ );
+}
+.typography-title-4() {
+ .typography-title(
+ @heading-4-size,
+ @typography-title-font-weight,
+ 1.4,
+ @heading-color,
+ @typography-title-margin-bottom
+ );
+}
+.typography-title-5() {
+ .typography-title(
+ @heading-5-size,
+ @typography-title-font-weight,
+ 1.5,
+ @heading-color,
+ @typography-title-margin-bottom
+ );
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/compact.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/compact.less
new file mode 100644
index 0000000..c650b9e
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/compact.less
@@ -0,0 +1,295 @@
+@import './default.less';
+
+@line-height-base: 1.66667;
+@mode: compact;
+@font-size-base: 12px;
+@font-size-lg: @font-size-base + 2px;
+
+// default paddings
+@default-padding-lg: 24px; // containers
+@default-padding-md: 16px; // small containers and buttons
+@default-padding-sm: 12px; // Form controls and items
+@default-padding-xs: 8px; // small items
+@default-padding-xss: 4px; // more small
+
+// vertical paddings
+@padding-lg: 16px; // containers
+@padding-md: 8px; // small containers and buttons
+@padding-sm: 8px; // Form controls and items
+@padding-xs: 4px; // small items
+@padding-xss: 0px; // more small
+
+// vertical padding for all form controls
+@control-padding-horizontal: @padding-sm;
+@control-padding-horizontal-sm: @default-padding-xs;
+
+// vertical margins
+@margin-lg: 16px; // containers
+@margin-md: 8px; // small containers and buttons
+@margin-sm: 8px; // Form controls and items
+@margin-xs: 4px; // small items
+@margin-xss: 0px; // more small
+
+// height rules
+@height-base: 28px;
+@height-lg: 32px;
+@height-sm: 22px;
+
+// Button
+// ---
+@btn-padding-horizontal-base: @default-padding-sm - 1px;
+@btn-padding-horizontal-lg: @btn-padding-horizontal-base;
+@btn-padding-horizontal-sm: @default-padding-xs - 1px;
+@btn-square-only-icon-size-lg: 16px;
+@btn-square-only-icon-size: 14px;
+@btn-square-only-icon-size-sm: 12px;
+
+// Breadcrumb
+// ---
+@breadcrumb-font-size: @font-size-base;
+@breadcrumb-icon-font-size: @font-size-base;
+
+//Dropdown
+@dropdown-line-height: 18px;
+
+// Menu
+@menu-item-padding: 0 12px;
+@menu-horizontal-line-height: 38px;
+@menu-inline-toplevel-item-height: 32px;
+@menu-item-height: 32px;
+@menu-item-vertical-margin: 0px;
+@menu-item-boundary-margin: 0px;
+@menu-icon-margin-right: 8px;
+
+// Checkbox
+@checkbox-size: 14px;
+@checkbox-group-item-margin-right: 6px;
+
+// picker
+@picker-panel-cell-height: 22px;
+@picker-panel-cell-width: 32px;
+@picker-text-height: 32px;
+@picker-time-panel-cell-height: 24px;
+@picker-panel-without-time-cell-height: 48px;
+
+// Form
+// ---
+@form-item-margin-bottom: 16px;
+@form-vertical-label-padding: 0 0 4px;
+
+// Rate
+// ---
+@rate-star-size: 16px;
+
+// Radio
+// ---
+@radio-size: 14px;
+@radio-wrapper-margin-right: 6px;
+
+// Switch
+// ---
+@switch-height: 20px;
+@switch-sm-height: 14px;
+@switch-min-width: 40px;
+@switch-sm-min-width: 24px;
+@switch-inner-margin-min: 4px;
+@switch-inner-margin-max: 22px;
+
+// Slider
+// ---
+@slider-handle-size: 12px;
+@slider-handle-margin-top: -4px;
+
+// Input
+// ---
+@input-padding-vertical-base: round(
+ max(
+ (round(((@input-height-base - @font-size-base * @line-height-base) / 2) * 10) / 10) -
+ @border-width-base,
+ 2px
+ )
+);
+@input-padding-horizontal-lg: 11px;
+
+// PageHeader
+// ---
+@page-header-padding: 16px;
+@page-header-padding-vertical: 8px;
+@page-header-heading-title: 16px;
+@page-header-heading-sub-title: 12px;
+@page-header-tabs-tab-font-size: 14px;
+
+// Pagination
+// ---
+@pagination-mini-options-size-changer-top: 1px;
+@pagination-item-size-sm: 22px;
+
+// Cascader
+// ----
+@cascader-dropdown-line-height: @dropdown-line-height;
+
+// Select
+// ---
+@select-dropdown-height: @height-base;
+@select-single-item-height-lg: 32px;
+@select-multiple-item-height: @input-height-base - max(@input-padding-vertical-base, 4) * 2; // Normal 24px
+@select-multiple-item-height-lg: 24px;
+@select-multiple-item-spacing-half: 3px;
+
+// Tree
+// ---
+@tree-title-height: 20px;
+
+// Transfer
+// ---
+@transfer-item-padding-vertical: 3px;
+@transfer-list-search-icon-top: 8px;
+@transfer-header-height: 36px;
+
+// Comment
+// ---
+@comment-actions-margin-bottom: 0px;
+@comment-actions-margin-top: @margin-xs;
+@comment-content-detail-p-margin-bottom: 0px;
+
+// Steps
+// ---
+@steps-icon-size: 24px;
+@steps-icon-custom-size: 20px;
+@steps-icon-custom-font-size: 20px;
+@steps-icon-custom-top: 2px;
+@steps-icon-margin: 2px 8px 2px 0;
+@steps-icon-font-size: @font-size-base;
+@steps-dot-top: 4px;
+@steps-icon-top: 0px;
+@steps-small-icon-size: 20px;
+@steps-vertical-icon-width: 12px;
+@steps-vertical-tail-width: 12px;
+@steps-vertical-tail-width-sm: 10px;
+// Collapse
+// ---
+//@collapse-header-padding-extra: 32px;
+@collapse-content-padding: @padding-md @padding-lg;
+
+// List
+// ---
+@list-item-meta-description-font-size: @font-size-sm;
+@list-item-padding-sm: 4px 12px;
+@list-item-padding-lg: 12px 16px;
+
+// Drawer
+// ---
+@drawer-header-padding: 11px @padding-lg;
+@drawer-footer-padding-vertical: @padding-sm;
+@drawer-footer-padding-horizontal: @padding-sm;
+@drawer-header-close-size: 44px;
+
+// Modal
+// --
+@modal-header-padding-vertical: 11px;
+@modal-header-padding: @modal-header-padding-vertical @modal-header-padding-horizontal;
+@modal-footer-padding-vertical: @padding-sm;
+@modal-header-close-size: @modal-header-title-line-height + 2 * @modal-header-padding-vertical;
+@modal-confirm-body-padding: 24px 24px 16px;
+
+// Message
+// ---
+@message-notice-content-padding: 8px 16px;
+
+// popover
+// --
+@popover-min-height: 28px;
+@popover-padding-horizontal: @default-padding-sm;
+
+// Card
+// ---
+@card-head-height: 36px;
+@card-head-font-size: @card-head-font-size-sm;
+@card-head-padding: 8.5px;
+@card-padding-base: 12px;
+@card-padding-base-sm: @card-padding-base;
+@card-head-height-sm: 30px;
+@card-head-padding-sm: 6px;
+@card-actions-li-margin: 4px 0;
+@card-head-tabs-margin-bottom: -9px;
+
+// Table
+// ---
+@table-padding-vertical: 12px;
+@table-padding-horizontal: 8px;
+@table-padding-vertical-md: 8px;
+@table-padding-horizontal-md: 8px;
+@table-padding-vertical-sm: 4px;
+@table-padding-horizontal-sm: 4px;
+@table-selection-column-width: 32px;
+
+// Statistic
+// ---
+@statistic-content-font-size: 20px;
+
+// Alert
+// ---
+@alert-with-description-no-icon-padding-vertical: 7px;
+@alert-with-description-padding-vertical: 11px;
+@alert-icon-top: 7px + @font-size-base * (@line-height-base / 2) - (@font-size-base / 2);
+@alert-with-description-icon-size: 20px;
+
+// Skeleton
+// ---
+@skeleton-paragraph-margin-top: 20px;
+@skeleton-paragraph-li-margin-top: 12px;
+@skeleton-paragraph-li-height: 14px;
+@skeleton-title-height: 14px;
+@skeleton-title-paragraph-margin-top: 20px;
+
+// Descriptions
+@descriptions-title-margin-bottom: 8px;
+@descriptions-default-padding: 12px @padding-lg;
+@descriptions-item-padding-bottom: @padding-xs;
+
+// Avatar
+// ---
+@avatar-size-base: 28px;
+@avatar-size-lg: 32px;
+@avatar-size-sm: 22px;
+@avatar-font-size-base: 16px;
+@avatar-font-size-lg: 20px;
+@avatar-font-size-sm: 12px;
+
+// Badge
+// ---
+@badge-height: 18px;
+
+// Tag
+// ---
+@tag-line-height: 18px;
+
+// Notification
+// ---
+@notification-padding-vertical: 12px;
+@notification-padding-horizontal: 16px;
+
+// Result
+// ---
+@result-title-font-size: 20px;
+@result-icon-font-size: 64px;
+@result-extra-margin: 24px 0 0 0;
+
+// Anchor
+// ---
+@anchor-link-top: 4px;
+@anchor-link-left: 16px;
+@anchor-link-padding: @anchor-link-top 0 @anchor-link-top @anchor-link-left;
+
+// Tabs
+// ---
+@tabs-card-horizontal-padding: 4px @padding-md;
+
+// Progress
+// ---
+@progress-circle-text-font-size: 0.833333em;
+
+// Image
+// ---
+@image-size-base: 48px;
+@image-font-size-base: 24px;
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/dark.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/dark.less
new file mode 100644
index 0000000..4cfda90
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/dark.less
@@ -0,0 +1,457 @@
+@import './default.less';
+
+@theme: dark;
+// color palettes
+@blue-1: mix(color(~`colorPalette('@{blue-base}', 8) `), @component-background, 15%);
+@blue-2: mix(color(~`colorPalette('@{blue-base}', 7) `), @component-background, 25%);
+@blue-3: mix(@blue-base, @component-background, 30%);
+@blue-4: mix(@blue-base, @component-background, 45%);
+@blue-5: mix(@blue-base, @component-background, 65%);
+@blue-6: mix(@blue-base, @component-background, 85%);
+@blue-7: mix(color(~`colorPalette('@{blue-base}', 5) `), @component-background, 90%);
+@blue-8: mix(color(~`colorPalette('@{blue-base}', 4) `), @component-background, 95%);
+@blue-9: mix(color(~`colorPalette('@{blue-base}', 3) `), @component-background, 97%);
+@blue-10: mix(color(~`colorPalette('@{blue-base}', 2) `), @component-background, 98%);
+
+@purple-1: mix(color(~`colorPalette('@{purple-base}', 8) `), @component-background, 15%);
+@purple-2: mix(color(~`colorPalette('@{purple-base}', 7) `), @component-background, 25%);
+@purple-3: mix(@purple-base, @component-background, 30%);
+@purple-4: mix(@purple-base, @component-background, 45%);
+@purple-5: mix(@purple-base, @component-background, 65%);
+@purple-6: mix(@purple-base, @component-background, 85%);
+@purple-7: mix(color(~`colorPalette('@{purple-base}', 5) `), @component-background, 90%);
+@purple-8: mix(color(~`colorPalette('@{purple-base}', 4) `), @component-background, 95%);
+@purple-9: mix(color(~`colorPalette('@{purple-base}', 3) `), @component-background, 97%);
+@purple-10: mix(color(~`colorPalette('@{purple-base}', 2) `), @component-background, 98%);
+
+@cyan-1: mix(color(~`colorPalette('@{cyan-base}', 8) `), @component-background, 15%);
+@cyan-2: mix(color(~`colorPalette('@{cyan-base}', 7) `), @component-background, 25%);
+@cyan-3: mix(@cyan-base, @component-background, 30%);
+@cyan-4: mix(@cyan-base, @component-background, 45%);
+@cyan-5: mix(@cyan-base, @component-background, 65%);
+@cyan-6: mix(@cyan-base, @component-background, 85%);
+@cyan-7: mix(color(~`colorPalette('@{cyan-base}', 5) `), @component-background, 90%);
+@cyan-8: mix(color(~`colorPalette('@{cyan-base}', 4) `), @component-background, 95%);
+@cyan-9: mix(color(~`colorPalette('@{cyan-base}', 3) `), @component-background, 97%);
+@cyan-10: mix(color(~`colorPalette('@{cyan-base}', 2) `), @component-background, 98%);
+
+@green-1: mix(color(~`colorPalette('@{green-base}', 8) `), @component-background, 15%);
+@green-2: mix(color(~`colorPalette('@{green-base}', 7) `), @component-background, 25%);
+@green-3: mix(@green-base, @component-background, 30%);
+@green-4: mix(@green-base, @component-background, 45%);
+@green-5: mix(@green-base, @component-background, 65%);
+@green-6: mix(@green-base, @component-background, 85%);
+@green-7: mix(color(~`colorPalette('@{green-base}', 5) `), @component-background, 90%);
+@green-8: mix(color(~`colorPalette('@{green-base}', 4) `), @component-background, 95%);
+@green-9: mix(color(~`colorPalette('@{green-base}', 3) `), @component-background, 97%);
+@green-10: mix(color(~`colorPalette('@{green-base}', 2) `), @component-background, 98%);
+
+@magenta-1: mix(color(~`colorPalette('@{magenta-base}', 8) `), @component-background, 15%);
+@magenta-2: mix(color(~`colorPalette('@{magenta-base}', 7) `), @component-background, 25%);
+@magenta-3: mix(@magenta-base, @component-background, 30%);
+@magenta-4: mix(@magenta-base, @component-background, 45%);
+@magenta-5: mix(@magenta-base, @component-background, 65%);
+@magenta-6: mix(@magenta-base, @component-background, 85%);
+@magenta-7: mix(color(~`colorPalette('@{magenta-base}', 5) `), @component-background, 90%);
+@magenta-8: mix(color(~`colorPalette('@{magenta-base}', 4) `), @component-background, 95%);
+@magenta-9: mix(color(~`colorPalette('@{magenta-base}', 3) `), @component-background, 97%);
+@magenta-10: mix(color(~`colorPalette('@{magenta-base}', 2) `), @component-background, 98%);
+
+@pink-1: mix(color(~`colorPalette('@{pink-base}', 8) `), @component-background, 15%);
+@pink-2: mix(color(~`colorPalette('@{pink-base}', 7) `), @component-background, 25%);
+@pink-3: mix(@pink-base, @component-background, 30%);
+@pink-4: mix(@pink-base, @component-background, 45%);
+@pink-5: mix(@pink-base, @component-background, 65%);
+@pink-6: mix(@pink-base, @component-background, 85%);
+@pink-7: mix(color(~`colorPalette('@{pink-base}', 5) `), @component-background, 90%);
+@pink-8: mix(color(~`colorPalette('@{pink-base}', 4) `), @component-background, 95%);
+@pink-9: mix(color(~`colorPalette('@{pink-base}', 3) `), @component-background, 97%);
+@pink-10: mix(color(~`colorPalette('@{pink-base}', 2) `), @component-background, 98%);
+
+@red-1: mix(color(~`colorPalette('@{red-base}', 8) `), @component-background, 15%);
+@red-2: mix(color(~`colorPalette('@{red-base}', 7) `), @component-background, 25%);
+@red-3: mix(@red-base, @component-background, 30%);
+@red-4: mix(@red-base, @component-background, 45%);
+@red-5: mix(@red-base, @component-background, 65%);
+@red-6: mix(@red-base, @component-background, 85%);
+@red-7: mix(color(~`colorPalette('@{red-base}', 5) `), @component-background, 90%);
+@red-8: mix(color(~`colorPalette('@{red-base}', 4) `), @component-background, 95%);
+@red-9: mix(color(~`colorPalette('@{red-base}', 3) `), @component-background, 97%);
+@red-10: mix(color(~`colorPalette('@{red-base}', 2) `), @component-background, 98%);
+
+@orange-1: mix(color(~`colorPalette('@{orange-base}', 8) `), @component-background, 15%);
+@orange-2: mix(color(~`colorPalette('@{orange-base}', 7) `), @component-background, 25%);
+@orange-3: mix(@orange-base, @component-background, 30%);
+@orange-4: mix(@orange-base, @component-background, 45%);
+@orange-5: mix(@orange-base, @component-background, 65%);
+@orange-6: mix(@orange-base, @component-background, 85%);
+@orange-7: mix(color(~`colorPalette('@{orange-base}', 5) `), @component-background, 90%);
+@orange-8: mix(color(~`colorPalette('@{orange-base}', 4) `), @component-background, 95%);
+@orange-9: mix(color(~`colorPalette('@{orange-base}', 3) `), @component-background, 97%);
+@orange-10: mix(color(~`colorPalette('@{orange-base}', 2) `), @component-background, 98%);
+
+@yellow-1: mix(color(~`colorPalette('@{yellow-base}', 8) `), @component-background, 15%);
+@yellow-2: mix(color(~`colorPalette('@{yellow-base}', 7) `), @component-background, 25%);
+@yellow-3: mix(@yellow-base, @component-background, 30%);
+@yellow-4: mix(@yellow-base, @component-background, 45%);
+@yellow-5: mix(@yellow-base, @component-background, 65%);
+@yellow-6: mix(@yellow-base, @component-background, 85%);
+@yellow-7: mix(color(~`colorPalette('@{yellow-base}', 5) `), @component-background, 90%);
+@yellow-8: mix(color(~`colorPalette('@{yellow-base}', 4) `), @component-background, 95%);
+@yellow-9: mix(color(~`colorPalette('@{yellow-base}', 3) `), @component-background, 97%);
+@yellow-10: mix(color(~`colorPalette('@{yellow-base}', 2) `), @component-background, 98%);
+
+@volcano-1: mix(color(~`colorPalette('@{volcano-base}', 8) `), @component-background, 15%);
+@volcano-2: mix(color(~`colorPalette('@{volcano-base}', 7) `), @component-background, 25%);
+@volcano-3: mix(@volcano-base, @component-background, 30%);
+@volcano-4: mix(@volcano-base, @component-background, 45%);
+@volcano-5: mix(@volcano-base, @component-background, 65%);
+@volcano-6: mix(@volcano-base, @component-background, 85%);
+@volcano-7: mix(color(~`colorPalette('@{volcano-base}', 5) `), @component-background, 90%);
+@volcano-8: mix(color(~`colorPalette('@{volcano-base}', 4) `), @component-background, 95%);
+@volcano-9: mix(color(~`colorPalette('@{volcano-base}', 3) `), @component-background, 97%);
+@volcano-10: mix(color(~`colorPalette('@{volcano-base}', 2) `), @component-background, 98%);
+
+@geekblue-1: mix(color(~`colorPalette('@{geekblue-base}', 8) `), @component-background, 15%);
+@geekblue-2: mix(color(~`colorPalette('@{geekblue-base}', 7) `), @component-background, 25%);
+@geekblue-3: mix(@geekblue-base, @component-background, 30%);
+@geekblue-4: mix(@geekblue-base, @component-background, 45%);
+@geekblue-5: mix(@geekblue-base, @component-background, 65%);
+@geekblue-6: mix(@geekblue-base, @component-background, 85%);
+@geekblue-7: mix(color(~`colorPalette('@{geekblue-base}', 5) `), @component-background, 90%);
+@geekblue-8: mix(color(~`colorPalette('@{geekblue-base}', 4) `), @component-background, 95%);
+@geekblue-9: mix(color(~`colorPalette('@{geekblue-base}', 3) `), @component-background, 97%);
+@geekblue-10: mix(color(~`colorPalette('@{geekblue-base}', 2) `), @component-background, 98%);
+
+@lime-1: mix(color(~`colorPalette('@{lime-base}', 8) `), @component-background, 15%);
+@lime-2: mix(color(~`colorPalette('@{lime-base}', 7) `), @component-background, 25%);
+@lime-3: mix(@lime-base, @component-background, 30%);
+@lime-4: mix(@lime-base, @component-background, 45%);
+@lime-5: mix(@lime-base, @component-background, 65%);
+@lime-6: mix(@lime-base, @component-background, 85%);
+@lime-7: mix(color(~`colorPalette('@{lime-base}', 5) `), @component-background, 90%);
+@lime-8: mix(color(~`colorPalette('@{lime-base}', 4) `), @component-background, 95%);
+@lime-9: mix(color(~`colorPalette('@{lime-base}', 3) `), @component-background, 97%);
+@lime-10: mix(color(~`colorPalette('@{lime-base}', 2) `), @component-background, 98%);
+
+@gold-1: mix(color(~`colorPalette('@{gold-base}', 8) `), @component-background, 15%);
+@gold-2: mix(color(~`colorPalette('@{gold-base}', 7) `), @component-background, 25%);
+@gold-3: mix(@gold-base, @component-background, 30%);
+@gold-4: mix(@gold-base, @component-background, 45%);
+@gold-5: mix(@gold-base, @component-background, 65%);
+@gold-6: mix(@gold-base, @component-background, 85%);
+@gold-7: mix(color(~`colorPalette('@{gold-base}', 5) `), @component-background, 90%);
+@gold-8: mix(color(~`colorPalette('@{gold-base}', 4) `), @component-background, 95%);
+@gold-9: mix(color(~`colorPalette('@{gold-base}', 3) `), @component-background, 97%);
+@gold-10: mix(color(~`colorPalette('@{gold-base}', 2) `), @component-background, 98%);
+
+// Color used by default to control hover and active backgrounds and for
+// alert info backgrounds.
+@primary-1: mix(color(~`colorPalette('@{primary-color}', 8) `), @component-background, 15%);
+@primary-2: mix(color(~`colorPalette('@{primary-color}', 7) `), @component-background, 25%);
+@primary-3: mix(@primary-color, @component-background, 30%);
+@primary-4: mix(@primary-color, @component-background, 45%);
+@primary-5: mix(@primary-color, @component-background, 65%);
+@primary-6: @primary-color;
+@primary-7: mix(color(~`colorPalette('@{primary-color}', 5) `), @component-background, 90%);
+@primary-8: mix(color(~`colorPalette('@{primary-color}', 4) `), @component-background, 95%);
+@primary-9: mix(color(~`colorPalette('@{primary-color}', 3) `), @component-background, 97%);
+@primary-10: mix(color(~`colorPalette('@{primary-color}', 2) `), @component-background, 98%);
+
+// Layer background
+@popover-background: #1f1f1f;
+@popover-customize-border-color: #3a3a3a;
+@body-background: @black;
+@component-background: #141414;
+
+@text-color: fade(@white, 85%);
+@text-color-secondary: fade(@white, 45%);
+@text-color-inverse: @white;
+@icon-color-hover: fade(@white, 75%);
+@heading-color: fade(@white, 85%);
+
+// The background colors for active and hover states for things like
+// list items or table cells.
+@item-active-bg: @primary-1;
+@item-hover-bg: fade(@white, 8%);
+
+// Border color
+@border-color-base: #434343; // base border outline a component
+@border-color-split: #303030; // split border inside a component
+
+@background-color-light: fade(@white, 4%); // background of header and selected item
+@background-color-base: fade(@white, 8%); // Default grey background color
+
+// Disabled states
+@disabled-color: fade(@white, 30%);
+@disabled-bg: @background-color-base;
+@disabled-color-dark: fade(@white, 30%);
+
+// Tree
+// ---
+@tree-bg: transparent;
+
+// List
+// ---
+@list-customize-card-bg: transparent;
+
+// Shadow
+// ---
+@shadow-color: rgba(0, 0, 0, 0.45);
+@shadow-color-inverse: @component-background;
+@box-shadow-base: @shadow-2;
+@shadow-1-up: 0 -6px 16px -8px rgba(0, 0, 0, 0.32), 0 -9px 28px 0 rgba(0, 0, 0, 0.2),
+ 0 -12px 48px 16px rgba(0, 0, 0, 0.12);
+@shadow-1-down: 0 6px 16px -8px rgba(0, 0, 0, 0.32), 0 9px 28px 0 rgba(0, 0, 0, 0.2),
+ 0 12px 48px 16px rgba(0, 0, 0, 0.12);
+@shadow-1-right: 6px 0 16px -8px rgba(0, 0, 0, 0.32), 9px 0 28px 0 rgba(0, 0, 0, 0.2),
+ 12px 0 48px 16px rgba(0, 0, 0, 0.12);
+@shadow-2: 0 3px 6px -4px rgba(0, 0, 0, 0.48), 0 6px 16px 0 rgba(0, 0, 0, 0.32),
+ 0 9px 28px 8px rgba(0, 0, 0, 0.2);
+
+// Buttons
+// ---
+@btn-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
+@btn-primary-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
+@btn-text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
+
+@btn-default-bg: transparent;
+
+@btn-default-ghost-color: @text-color;
+@btn-default-ghost-border: fade(@white, 25%);
+
+@btn-text-hover-bg: rgba(255, 255, 255, 0.03);
+
+// Checkbox
+// ---
+@checkbox-check-bg: transparent;
+
+// Descriptions
+// ---
+@descriptions-bg: @background-color-light;
+
+// Divider
+// ---
+@divider-color: rgba(255, 255, 255, 12%);
+
+// Modal
+// ---
+@modal-header-bg: @popover-background;
+@modal-header-border-color-split: @border-color-split;
+@modal-content-bg: @popover-background;
+@modal-footer-border-color-split: @border-color-split;
+
+// Radio
+// ---
+@radio-solid-checked-color: @white;
+@radio-dot-disabled-color: fade(@white, 20%);
+
+// Radio buttons
+// ---
+@radio-disabled-button-checked-bg: fade(@white, 20%);
+@radio-disabled-button-checked-color: @disabled-color;
+
+// Layout
+// ---
+@layout-body-background: @body-background;
+@layout-header-background: @popover-background;
+@layout-trigger-background: #262626;
+
+// Input
+// ---
+@input-bg: transparent;
+@input-placeholder-color: fade(@white, 30%);
+@input-icon-color: fade(@white, 30%);
+@input-number-handler-active-bg: @item-hover-bg;
+@input-icon-hover-color: fade(@white, 85%);
+
+// Select
+// ---
+@select-background: transparent;
+@select-dropdown-bg: @popover-background;
+@select-clear-background: @component-background;
+@select-selection-item-bg: fade(@white, 8);
+@select-selection-item-border-color: @border-color-split;
+@select-multiple-disabled-background: @component-background;
+@select-multiple-item-disabled-color: #595959;
+@select-multiple-item-disabled-border-color: @popover-background;
+
+// Cascader
+// ---
+@cascader-bg: transparent;
+@cascader-menu-bg: @popover-background;
+@cascader-menu-border-color-split: @border-color-split;
+
+// Tooltip
+// ---
+// Tooltip background color
+@tooltip-bg: #434343;
+
+// Menu
+// ---
+// dark theme
+@menu-dark-inline-submenu-bg: @component-background;
+@menu-dark-bg: @popover-background;
+@menu-popup-bg: @popover-background;
+
+// Message
+// ---
+@message-notice-content-bg: @popover-background;
+
+// Notification
+@notification-bg: @popover-background;
+
+// LINK
+@link-hover-color: @primary-5;
+@link-active-color: @primary-7;
+
+// Table
+// --
+@table-header-bg: #1d1d1d;
+@table-body-sort-bg: fade(@white, 1%);
+@table-row-hover-bg: #262626;
+@table-header-cell-split-color: fade(@white, 8%);
+@table-header-sort-bg: #262626;
+@table-header-filter-active-bg: #434343;
+@table-header-sort-active-bg: #303030;
+@table-fixed-header-sort-active-bg: #222;
+@table-filter-btns-bg: @popover-background;
+@table-expanded-row-bg: @table-header-bg;
+@table-filter-dropdown-bg: @popover-background;
+@table-expand-icon-bg: transparent;
+
+// Tag
+// ---
+@info-color-deprecated-bg: @primary-1;
+@info-color-deprecated-border: @primary-3;
+@success-color-deprecated-bg: @green-1;
+@success-color-deprecated-border: @green-3;
+@warning-color-deprecated-bg: @orange-1;
+@warning-color-deprecated-border: @orange-3;
+@error-color-deprecated-bg: @red-1;
+@error-color-deprecated-border: @red-3;
+
+// TimePicker
+// ---
+@picker-basic-cell-hover-with-range-color: darken(@primary-color, 35%);
+@picker-basic-cell-disabled-bg: #303030;
+@picker-border-color: @border-color-split;
+@picker-bg: transparent;
+@picker-date-hover-range-border-color: darken(@primary-color, 20%);
+
+// Dropdown
+// ---
+@dropdown-menu-bg: @popover-background;
+@dropdown-menu-submenu-disabled-bg: transparent;
+
+// Steps
+// ---
+@steps-nav-arrow-color: fade(@white, 20%);
+@steps-background: transparent;
+
+// Avatar
+// ---
+@avatar-bg: fade(@white, 30%);
+
+// Progress
+// ---
+@progress-steps-item-bg: fade(@white, 8%);
+
+// Calendar
+// ---
+@calendar-bg: @popover-background;
+@calendar-input-bg: @calendar-bg;
+@calendar-border-color: transparent;
+@calendar-full-bg: @component-background;
+
+// Badge
+// ---
+@badge-text-color: @white;
+
+// Popover
+@popover-bg: @popover-background;
+
+// Drawer
+@drawer-bg: @popover-background;
+
+// Card
+// ---
+@card-actions-background: @component-background;
+@card-skeleton-bg: #303030;
+@card-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.64), 0 3px 6px 0 rgba(0, 0, 0, 0.48),
+ 0 5px 12px 4px rgba(0, 0, 0, 0.36);
+
+// Transfer
+// ---
+@transfer-item-hover-bg: #262626;
+
+// Comment
+// ---
+@comment-bg: transparent;
+@comment-author-time-color: fade(@white, 30%);
+@comment-action-hover-color: fade(@white, 65%);
+
+// Rate
+// ---
+@rate-star-bg: fade(@white, 12%);
+
+// Switch
+// ---
+@switch-bg: @white;
+
+// Pagination
+// ---
+@pagination-item-bg: transparent;
+@pagination-item-bg-active: transparent;
+@pagination-item-link-bg: transparent;
+@pagination-item-disabled-bg-active: fade(@white, 25%);
+@pagination-item-disabled-color-active: @black;
+@pagination-item-input-bg: @pagination-item-bg;
+
+// PageHeader
+// ---
+@page-header-back-color: @icon-color;
+@page-header-ghost-bg: transparent;
+
+// Slider
+// ---
+@slider-rail-background-color: #262626;
+@slider-rail-background-color-hover: @border-color-base;
+@slider-dot-border-color: @border-color-split;
+@slider-dot-border-color-active: @primary-4;
+
+// Skeleton
+// ---
+@skeleton-to-color: fade(@white, 16%);
+
+// Alert
+// ---
+@alert-success-border-color: @green-3;
+@alert-success-bg-color: @green-1;
+@alert-success-icon-color: @success-color;
+@alert-info-border-color: @primary-3;
+@alert-info-bg-color: @primary-1;
+@alert-info-icon-color: @info-color;
+@alert-warning-border-color: @gold-3;
+@alert-warning-bg-color: @gold-1;
+@alert-warning-icon-color: @warning-color;
+@alert-error-border-color: @red-3;
+@alert-error-bg-color: @red-1;
+@alert-error-icon-color: @error-color;
+
+// Timeline
+// ---
+@timeline-color: @border-color-split;
+@timeline-dot-color: @primary-color;
+
+// Mentions
+// ---
+@mentions-dropdown-bg: @popover-background;
+
+// Segmented
+// ---
+@segmented-bg: fade(@black, 25%);
+@segmented-hover-bg: fade(@black, 45%);
+@segmented-selected-bg: #333333;
+@segmented-label-color: fade(@white, 65%);
+@segmented-label-hover-color: fade(@white, 85%);
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/default.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/default.less
new file mode 100644
index 0000000..a439874
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/default.less
@@ -0,0 +1,1081 @@
+/* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */
+@import '../color/colors';
+
+@theme: default;
+
+// The prefix to use on all css classes from ant.
+@ant-prefix: ant;
+
+// An override for the html selector for theme prefixes
+@html-selector: html;
+
+// [CSS-VARIABLE-REPLACE-BEGIN: html-variables]
+// [CSS-VARIABLE-REPLACE-END: html-variables]
+
+// -------- Colors -----------
+// >>> Primary
+@primary-color: @blue-6;
+@primary-color-hover: color(~`colorPalette('@{primary-color}', 5) `);
+@primary-color-active: color(~`colorPalette('@{primary-color}', 7) `);
+@primary-color-outline: fade(@primary-color, @outline-fade);
+
+@processing-color: @blue-6;
+
+// >>> Info
+@info-color: @primary-color;
+@info-color-deprecated-bg: color(~`colorPalette('@{info-color}', 1) `);
+@info-color-deprecated-border: color(~`colorPalette('@{info-color}', 3) `);
+
+// >>> Success
+@success-color: @green-6;
+@success-color-hover: color(~`colorPalette('@{success-color}', 5) `);
+@success-color-active: color(~`colorPalette('@{success-color}', 7) `);
+@success-color-outline: fade(@success-color, @outline-fade);
+@success-color-deprecated-bg: color(~`colorPalette('@{success-color}', 1) `);
+@success-color-deprecated-border: color(~`colorPalette('@{success-color}', 3) `);
+
+// >>> Warning
+@warning-color: @gold-6;
+@warning-color-hover: color(~`colorPalette('@{warning-color}', 5) `);
+@warning-color-active: color(~`colorPalette('@{warning-color}', 7) `);
+@warning-color-outline: fade(@warning-color, @outline-fade);
+@warning-color-deprecated-bg: color(~`colorPalette('@{warning-color}', 1) `);
+@warning-color-deprecated-border: color(~`colorPalette('@{warning-color}', 3) `);
+
+// >>> Error
+@error-color: @red-5;
+@error-color-hover: color(~`colorPalette('@{error-color}', 5) `);
+@error-color-active: color(~`colorPalette('@{error-color}', 7) `);
+@error-color-outline: fade(@error-color, @outline-fade);
+@error-color-deprecated-bg: color(~`colorPalette('@{error-color}', 1) `);
+@error-color-deprecated-border: color(~`colorPalette('@{error-color}', 3) `);
+
+@highlight-color: @red-5;
+@normal-color: #d9d9d9;
+@white: #fff;
+@black: #000;
+
+// Color used by default to control hover and active backgrounds and for
+// alert info backgrounds.
+@primary-1: color(~`colorPalette('@{primary-color}', 1) `); // replace tint(@primary-color, 90%)
+@primary-2: color(~`colorPalette('@{primary-color}', 2) `); // replace tint(@primary-color, 80%)
+@primary-3: color(~`colorPalette('@{primary-color}', 3) `); // unused
+@primary-4: color(~`colorPalette('@{primary-color}', 4) `); // unused
+@primary-5: color(
+ ~`colorPalette('@{primary-color}', 5) `
+); // color used to control the text color in many active and hover states, replace tint(@primary-color, 20%)
+@primary-6: @primary-color; // color used to control the text color of active buttons, don't use, use @primary-color
+@primary-7: color(~`colorPalette('@{primary-color}', 7) `); // replace shade(@primary-color, 5%)
+@primary-8: color(~`colorPalette('@{primary-color}', 8) `); // unused
+@primary-9: color(~`colorPalette('@{primary-color}', 9) `); // unused
+@primary-10: color(~`colorPalette('@{primary-color}', 10) `); // unused
+
+// Base Scaffolding Variables
+// ---
+
+// Background color for ``
+@body-background: #fff;
+// Base background color for most components
+@component-background: #fff;
+// Popover background color
+@popover-background: @component-background;
+@popover-customize-border-color: @border-color-split;
+@font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
+ 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
+ 'Noto Color Emoji';
+@code-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
+@text-color: fade(@black, 85%);
+@text-color-secondary: fade(@black, 45%);
+@text-color-inverse: @white;
+@icon-color: inherit;
+@icon-color-hover: fade(@black, 75%);
+@heading-color: fade(@black, 85%);
+@text-color-dark: fade(@white, 85%);
+@text-color-secondary-dark: fade(@white, 65%);
+@text-selection-bg: @primary-color;
+@font-variant-base: tabular-nums;
+@font-feature-settings-base: 'tnum';
+@font-size-base: 14px;
+@font-size-lg: @font-size-base + 2px;
+@font-size-sm: 12px;
+@heading-1-size: ceil(@font-size-base * 2.71);
+@heading-2-size: ceil(@font-size-base * 2.14);
+@heading-3-size: ceil(@font-size-base * 1.71);
+@heading-4-size: ceil(@font-size-base * 1.42);
+@heading-5-size: ceil(@font-size-base * 1.14);
+// https://github.com/ant-design/ant-design/issues/20210
+@line-height-base: 1.5715;
+@border-radius-base: 2px;
+@border-radius-sm: 2px;
+
+// control border
+@control-border-radius: @border-radius-base;
+
+// arrow border
+@arrow-border-radius: 2px;
+
+// vertical paddings
+@padding-lg: 24px; // containers
+@padding-md: 16px; // small containers and buttons
+@padding-sm: 12px; // Form controls and items
+@padding-xs: 8px; // small items
+@padding-xss: 4px; // more small
+
+// vertical padding for all form controls
+@control-padding-horizontal: @padding-sm;
+@control-padding-horizontal-sm: @padding-xs;
+
+// vertical margins
+@margin-lg: 24px; // containers
+@margin-md: 16px; // small containers and buttons
+@margin-sm: 12px; // Form controls and items
+@margin-xs: 8px; // small items
+@margin-xss: 4px; // more small
+
+// height rules
+@height-base: 32px;
+@height-lg: 40px;
+@height-sm: 24px;
+
+// The background colors for active and hover states for things like
+// list items or table cells.
+@item-active-bg: @primary-1;
+@item-hover-bg: #f5f5f5;
+
+// ICONFONT
+@iconfont-css-prefix: anticon;
+
+// LINK
+@link-color: @primary-color;
+@link-hover-color: color(~`colorPalette('@{link-color}', 5) `);
+@link-active-color: color(~`colorPalette('@{link-color}', 7) `);
+@link-decoration: none;
+@link-hover-decoration: none;
+@link-focus-decoration: none;
+@link-focus-outline: 0;
+
+// Animation
+@ease-base-out: cubic-bezier(0.7, 0.3, 0.1, 1);
+@ease-base-in: cubic-bezier(0.9, 0, 0.3, 0.7);
+@ease-out: cubic-bezier(0.215, 0.61, 0.355, 1);
+@ease-in: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+@ease-in-out: cubic-bezier(0.645, 0.045, 0.355, 1);
+@ease-out-back: cubic-bezier(0.12, 0.4, 0.29, 1.46);
+@ease-in-back: cubic-bezier(0.71, -0.46, 0.88, 0.6);
+@ease-in-out-back: cubic-bezier(0.71, -0.46, 0.29, 1.46);
+@ease-out-circ: cubic-bezier(0.08, 0.82, 0.17, 1);
+@ease-in-circ: cubic-bezier(0.6, 0.04, 0.98, 0.34);
+@ease-in-out-circ: cubic-bezier(0.78, 0.14, 0.15, 0.86);
+@ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1);
+@ease-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+@ease-in-out-quint: cubic-bezier(0.86, 0, 0.07, 1);
+
+// Border color
+@border-color-base: hsv(0, 0, 85%); // base border outline a component
+@border-color-split: hsv(0, 0, 94%); // split border inside a component
+@border-color-inverse: @white;
+@border-width-base: 1px; // width of the border for a component
+@border-style-base: solid; // style of a components border
+
+// Outline
+@outline-blur-size: 0;
+@outline-width: 2px;
+@outline-color: @primary-color; // No use anymore
+@outline-fade: 20%;
+
+@background-color-light: hsv(0, 0, 98%); // background of header and selected item
+@background-color-base: hsv(0, 0, 96%); // Default grey background color
+
+// Disabled states
+@disabled-color: fade(#000, 25%);
+@disabled-bg: @background-color-base;
+@disabled-active-bg: tint(@black, 90%);
+@disabled-color-dark: fade(#fff, 35%);
+
+// Shadow
+@shadow-color: rgba(0, 0, 0, 0.15);
+@shadow-color-inverse: @component-background;
+@box-shadow-base: @shadow-2;
+@shadow-1-up: 0 -6px 16px -8px rgba(0, 0, 0, 0.08), 0 -9px 28px 0 rgba(0, 0, 0, 0.05),
+ 0 -12px 48px 16px rgba(0, 0, 0, 0.03);
+@shadow-1-down: 0 6px 16px -8px rgba(0, 0, 0, 0.08), 0 9px 28px 0 rgba(0, 0, 0, 0.05),
+ 0 12px 48px 16px rgba(0, 0, 0, 0.03);
+@shadow-1-left: -6px 0 16px -8px rgba(0, 0, 0, 0.08), -9px 0 28px 0 rgba(0, 0, 0, 0.05),
+ -12px 0 48px 16px rgba(0, 0, 0, 0.03);
+@shadow-1-right: 6px 0 16px -8px rgba(0, 0, 0, 0.08), 9px 0 28px 0 rgba(0, 0, 0, 0.05),
+ 12px 0 48px 16px rgba(0, 0, 0, 0.03);
+@shadow-2: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08),
+ 0 9px 28px 8px rgba(0, 0, 0, 0.05);
+
+// Buttons
+@btn-font-weight: 400;
+@btn-border-radius-base: @border-radius-base;
+@btn-border-radius-sm: @border-radius-base;
+@btn-border-width: @border-width-base;
+@btn-border-style: @border-style-base;
+@btn-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
+@btn-primary-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
+@btn-text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
+
+@btn-primary-color: #fff;
+@btn-primary-bg: @primary-color;
+
+@btn-default-color: @text-color;
+@btn-default-bg: @component-background;
+@btn-default-border: @border-color-base;
+
+@btn-danger-color: #fff;
+@btn-danger-bg: @error-color;
+@btn-danger-border: @error-color;
+
+@btn-disable-color: @disabled-color;
+@btn-disable-bg: @disabled-bg;
+@btn-disable-border: @border-color-base;
+
+@btn-default-ghost-color: @component-background;
+@btn-default-ghost-bg: transparent;
+@btn-default-ghost-border: @component-background;
+
+@btn-font-size-lg: @font-size-lg;
+@btn-font-size-sm: @font-size-base;
+@btn-padding-horizontal-base: @padding-md - 1px;
+@btn-padding-horizontal-lg: @btn-padding-horizontal-base;
+@btn-padding-horizontal-sm: @padding-xs - 1px;
+
+@btn-height-base: @height-base;
+@btn-height-lg: @height-lg;
+@btn-height-sm: @height-sm;
+
+@btn-line-height: @line-height-base;
+
+@btn-circle-size: @btn-height-base;
+@btn-circle-size-lg: @btn-height-lg;
+@btn-circle-size-sm: @btn-height-sm;
+
+@btn-square-size: @btn-height-base;
+@btn-square-size-lg: @btn-height-lg;
+@btn-square-size-sm: @btn-height-sm;
+@btn-square-only-icon-size: @font-size-base + 2px;
+@btn-square-only-icon-size-sm: @font-size-base;
+@btn-square-only-icon-size-lg: @btn-font-size-lg + 2px;
+
+@btn-group-border: @primary-5;
+
+@btn-link-hover-bg: transparent;
+@btn-text-hover-bg: rgba(0, 0, 0, 0.018);
+
+// Checkbox
+@checkbox-size: 16px;
+@checkbox-color: @primary-color;
+@checkbox-check-color: #fff;
+@checkbox-check-bg: @checkbox-check-color;
+@checkbox-border-width: @border-width-base;
+@checkbox-border-radius: @border-radius-base;
+@checkbox-group-item-margin-right: 8px;
+
+// Descriptions
+@descriptions-bg: #fafafa;
+@descriptions-title-margin-bottom: 20px;
+@descriptions-default-padding: @padding-md @padding-lg;
+@descriptions-middle-padding: @padding-sm @padding-lg;
+@descriptions-small-padding: @padding-xs @padding-md;
+@descriptions-item-padding-bottom: @padding-md;
+@descriptions-item-trailing-colon: true;
+@descriptions-item-label-colon-margin-right: 8px;
+@descriptions-item-label-colon-margin-left: 2px;
+@descriptions-extra-color: @text-color;
+
+// Divider
+@divider-text-padding: 1em;
+@divider-orientation-margin: 5%;
+@divider-color: rgba(0, 0, 0, 6%);
+@divider-vertical-gutter: 8px;
+
+// Dropdown
+@dropdown-selected-color: @primary-color;
+@dropdown-menu-submenu-disabled-bg: @component-background;
+@dropdown-selected-bg: @item-active-bg;
+
+// Empty
+@empty-font-size: @font-size-base;
+
+// Radio
+@radio-size: 16px;
+@radio-top: 0.2em;
+@radio-border-width: 1px;
+@radio-dot-size: @radio-size - 8px;
+@radio-dot-color: @primary-color;
+@radio-dot-disabled-color: fade(@black, 20%);
+@radio-solid-checked-color: @component-background;
+
+// Radio buttons
+@radio-button-bg: @btn-default-bg;
+@radio-button-checked-bg: @btn-default-bg;
+@radio-button-color: @btn-default-color;
+@radio-button-hover-color: @primary-5;
+@radio-button-active-color: @primary-7;
+@radio-button-padding-horizontal: @padding-md - 1px;
+@radio-disabled-button-checked-bg: @disabled-active-bg;
+@radio-disabled-button-checked-color: @disabled-color;
+@radio-wrapper-margin-right: 8px;
+
+// Media queries breakpoints
+// @screen-xs and @screen-xs-min is not used in Grid
+// smallest break point is @screen-md
+@screen-xs: 480px;
+@screen-xs-min: @screen-xs;
+// 👆 Extra small screen / phone
+
+// 👇 Small screen / tablet
+@screen-sm: 576px;
+@screen-sm-min: @screen-sm;
+
+// Medium screen / desktop
+@screen-md: 768px;
+@screen-md-min: @screen-md;
+
+// Large screen / wide desktop
+@screen-lg: 992px;
+@screen-lg-min: @screen-lg;
+
+// Extra large screen / full hd
+@screen-xl: 1200px;
+@screen-xl-min: @screen-xl;
+
+// Extra extra large screen / large desktop
+@screen-xxl: 1600px;
+@screen-xxl-min: @screen-xxl;
+
+// provide a maximum
+@screen-xs-max: (@screen-sm-min - 1px);
+@screen-sm-max: (@screen-md-min - 1px);
+@screen-md-max: (@screen-lg-min - 1px);
+@screen-lg-max: (@screen-xl-min - 1px);
+@screen-xl-max: (@screen-xxl-min - 1px);
+
+// Grid system
+@grid-columns: 24;
+
+// Layout
+@layout-body-background: #f0f2f5;
+@layout-header-background: #001529;
+@layout-header-height: 64px;
+@layout-header-padding: 0 50px;
+@layout-header-color: @text-color;
+@layout-footer-padding: 24px 50px;
+@layout-footer-background: @layout-body-background;
+@layout-sider-background: @layout-header-background;
+@layout-trigger-height: 48px;
+@layout-trigger-background: #002140;
+@layout-trigger-color: #fff;
+@layout-zero-trigger-width: 36px;
+@layout-zero-trigger-height: 42px;
+// Layout light theme
+@layout-sider-background-light: #fff;
+@layout-trigger-background-light: #fff;
+@layout-trigger-color-light: @text-color;
+
+// z-index list, order by `z-index`
+@zindex-badge: auto;
+@zindex-table-fixed: 2;
+@zindex-affix: 10;
+@zindex-back-top: 10;
+@zindex-picker-panel: 10;
+@zindex-popup-close: 10;
+@zindex-modal: 1000;
+@zindex-modal-mask: 1000;
+@zindex-message: 1010;
+@zindex-notification: 1010;
+@zindex-popover: 1030;
+@zindex-dropdown: 1050;
+@zindex-picker: 1050;
+@zindex-popoconfirm: 1060;
+@zindex-tooltip: 1070;
+@zindex-image: 1080;
+
+// Animation
+@animation-duration-slow: 0.3s; // Modal
+@animation-duration-base: 0.2s;
+@animation-duration-fast: 0.1s; // Tooltip
+
+//CollapsePanel
+@collapse-panel-border-radius: @border-radius-base;
+
+//Dropdown
+@dropdown-menu-bg: @component-background;
+@dropdown-vertical-padding: 5px;
+@dropdown-edge-child-vertical-padding: 4px;
+@dropdown-font-size: @font-size-base;
+@dropdown-line-height: 22px;
+
+// Form
+// ---
+@label-required-color: @highlight-color;
+@label-color: @heading-color;
+@form-warning-input-bg: @input-bg;
+@form-item-margin-bottom: 24px;
+@form-item-trailing-colon: true;
+@form-vertical-label-padding: 0 0 8px;
+@form-vertical-label-margin: 0;
+@form-item-label-font-size: @font-size-base;
+@form-item-label-height: @input-height-base;
+@form-item-label-colon-margin-right: 8px;
+@form-item-label-colon-margin-left: 2px;
+@form-error-input-bg: @input-bg;
+
+// Input
+// ---
+@input-height-base: @height-base;
+@input-height-lg: @height-lg;
+@input-height-sm: @height-sm;
+@input-padding-horizontal: @control-padding-horizontal - 1px;
+@input-padding-horizontal-base: @input-padding-horizontal;
+@input-padding-horizontal-sm: @control-padding-horizontal-sm - 1px;
+@input-padding-horizontal-lg: @input-padding-horizontal;
+@input-padding-vertical-base: max(
+ (round(((@input-height-base - @font-size-base * @line-height-base) / 2) * 10) / 10) -
+ @border-width-base,
+ 3px
+);
+@input-padding-vertical-sm: max(
+ (round(((@input-height-sm - @font-size-base * @line-height-base) / 2) * 10) / 10) -
+ @border-width-base,
+ 0
+);
+@input-padding-vertical-lg: (
+ ceil(((@input-height-lg - @font-size-lg * @line-height-base) / 2) * 10) / 10
+ ) - @border-width-base;
+@input-placeholder-color: hsv(0, 0, 75%);
+@input-color: @text-color;
+@input-icon-color: @input-color;
+@input-border-color: @border-color-base;
+@input-bg: @component-background;
+@input-number-hover-border-color: @input-hover-border-color;
+@input-number-handler-active-bg: #f4f4f4;
+@input-number-handler-hover-bg: @primary-5;
+@input-number-handler-bg: @component-background;
+@input-number-handler-border-color: @border-color-base;
+@input-addon-bg: @background-color-light;
+@input-hover-border-color: @primary-5;
+@input-disabled-bg: @disabled-bg;
+@input-outline-offset: 0 0;
+@input-icon-hover-color: fade(@black, 85%);
+@input-disabled-color: @disabled-color;
+
+// Mentions
+// ---
+@mentions-dropdown-bg: @component-background;
+@mentions-dropdown-menu-item-hover-bg: @mentions-dropdown-bg;
+
+// Select
+// ---
+@select-border-color: @border-color-base;
+@select-item-selected-color: @text-color;
+@select-item-selected-font-weight: 600;
+@select-dropdown-bg: @component-background;
+@select-item-selected-bg: @primary-1;
+@select-item-active-bg: @item-hover-bg;
+@select-dropdown-vertical-padding: @dropdown-vertical-padding;
+@select-dropdown-font-size: @dropdown-font-size;
+@select-dropdown-line-height: @dropdown-line-height;
+@select-dropdown-height: 32px;
+@select-background: @component-background;
+@select-clear-background: @select-background;
+@select-selection-item-bg: @background-color-base;
+@select-selection-item-border-color: @border-color-split;
+@select-single-item-height-lg: 40px;
+@select-multiple-item-height: @input-height-base - @input-padding-vertical-base * 2; // Normal 24px
+@select-multiple-item-height-lg: 32px;
+@select-multiple-item-spacing-half: ceil((@input-padding-vertical-base / 2));
+@select-multiple-disabled-background: @input-disabled-bg;
+@select-multiple-item-disabled-color: #bfbfbf;
+@select-multiple-item-disabled-border-color: @select-border-color;
+
+// Cascader
+// ---
+@cascader-bg: @component-background;
+@cascader-item-selected-bg: @primary-1;
+@cascader-menu-bg: @component-background;
+@cascader-menu-border-color-split: @border-color-split;
+
+// Cascader
+// ----
+@cascader-dropdown-vertical-padding: @dropdown-vertical-padding;
+@cascader-dropdown-edge-child-vertical-padding: @dropdown-edge-child-vertical-padding;
+@cascader-dropdown-font-size: @dropdown-font-size;
+@cascader-dropdown-line-height: @dropdown-line-height;
+
+// Anchor
+// ---
+@anchor-bg: transparent;
+@anchor-border-color: @border-color-split;
+@anchor-link-top: 4px;
+@anchor-link-left: 16px;
+@anchor-link-padding: @anchor-link-top 0 @anchor-link-top @anchor-link-left;
+
+// Tooltip
+// ---
+// Tooltip max width
+@tooltip-max-width: 250px;
+// Tooltip text color
+@tooltip-color: #fff;
+// Tooltip background color
+@tooltip-bg: rgba(0, 0, 0, 0.75);
+// Tooltip arrow width
+@tooltip-arrow-width: 8px * sqrt(2);
+// Tooltip distance with trigger
+@tooltip-distance: @tooltip-arrow-width - 1px + 4px;
+// Tooltip arrow color
+@tooltip-arrow-color: @tooltip-bg;
+@tooltip-border-radius: @border-radius-base;
+
+// Popover
+// ---
+// Popover body background color
+@popover-bg: @component-background;
+// Popover text color
+@popover-color: @text-color;
+// Popover maximum width
+@popover-min-width: 177px;
+@popover-min-height: 32px;
+// Popover arrow width
+@popover-arrow-width: @tooltip-arrow-width;
+// Popover arrow color
+@popover-arrow-color: @popover-bg;
+// Popover outer arrow width
+// Popover outer arrow color
+@popover-arrow-outer-color: @popover-bg;
+// Popover distance with trigger
+@popover-distance: @popover-arrow-width + 4px;
+@popover-padding-horizontal: @padding-md;
+
+// Modal
+// --
+@modal-header-padding-vertical: @padding-md;
+@modal-header-padding-horizontal: @padding-lg;
+@modal-body-padding: @padding-lg;
+@modal-header-bg: @component-background;
+@modal-header-padding: @modal-header-padding-vertical @modal-header-padding-horizontal;
+@modal-header-border-width: @border-width-base;
+@modal-header-border-style: @border-style-base;
+@modal-header-title-line-height: 22px;
+@modal-header-title-font-size: @font-size-lg;
+@modal-header-border-color-split: @border-color-split;
+@modal-header-close-size: @modal-header-title-line-height + 2 * @modal-header-padding-vertical;
+@modal-content-bg: @component-background;
+@modal-heading-color: @heading-color;
+@modal-close-color: @text-color-secondary;
+@modal-footer-bg: transparent;
+@modal-footer-border-color-split: @border-color-split;
+@modal-footer-border-style: @border-style-base;
+@modal-footer-padding-vertical: 10px;
+@modal-footer-padding-horizontal: 16px;
+@modal-footer-border-width: @border-width-base;
+@modal-mask-bg: fade(@black, 45%);
+@modal-confirm-body-padding: 32px 32px 24px;
+@modal-confirm-title-font-size: @font-size-lg;
+@modal-border-radius: @border-radius-base;
+
+// Progress
+// --
+@progress-default-color: @processing-color;
+@progress-remaining-color: @background-color-base;
+@progress-info-text-color: @progress-text-color;
+@progress-radius: 100px;
+@progress-steps-item-bg: #f3f3f3;
+@progress-text-font-size: 1em;
+@progress-text-color: @text-color; // This is for circle text color, should be renamed better
+@progress-circle-text-font-size: 1em;
+// Menu
+// ---
+@menu-inline-toplevel-item-height: 40px;
+@menu-item-height: 40px;
+@menu-item-group-height: @line-height-base;
+@menu-collapsed-width: 80px;
+@menu-bg: @component-background;
+@menu-popup-bg: @component-background;
+@menu-item-color: @text-color;
+@menu-inline-submenu-bg: @background-color-light;
+@menu-highlight-color: @primary-color;
+@menu-highlight-danger-color: @error-color;
+@menu-item-active-bg: @primary-1;
+@menu-item-active-danger-bg: @red-1;
+@menu-item-active-border-width: 3px;
+@menu-item-group-title-color: @text-color-secondary;
+@menu-item-vertical-margin: 4px;
+@menu-item-font-size: @font-size-base;
+@menu-item-boundary-margin: 8px;
+@menu-item-padding-horizontal: 20px;
+@menu-item-padding: 0 @menu-item-padding-horizontal;
+@menu-horizontal-line-height: 46px;
+@menu-icon-margin-right: 10px;
+@menu-icon-size: @menu-item-font-size;
+@menu-icon-size-lg: @font-size-lg;
+@menu-item-group-title-font-size: @menu-item-font-size;
+
+// dark theme
+@menu-dark-color: @text-color-secondary-dark;
+@menu-dark-danger-color: @error-color;
+@menu-dark-bg: @layout-header-background;
+@menu-dark-arrow-color: #fff;
+@menu-dark-inline-submenu-bg: #000c17;
+@menu-dark-highlight-color: #fff;
+@menu-dark-item-active-bg: @primary-color;
+@menu-dark-item-active-danger-bg: @error-color;
+@menu-dark-selected-item-icon-color: @white;
+@menu-dark-selected-item-text-color: @white;
+@menu-dark-item-hover-bg: transparent;
+// Spin
+// ---
+@spin-dot-size-sm: 14px;
+@spin-dot-size: 20px;
+@spin-dot-size-lg: 32px;
+
+// Table
+// --
+@table-bg: @component-background;
+@table-header-bg: @background-color-light;
+@table-header-color: @heading-color;
+@table-header-sort-bg: @background-color-base;
+@table-body-sort-bg: #fafafa;
+@table-row-hover-bg: @background-color-light;
+@table-selected-row-color: inherit;
+@table-selected-row-bg: @primary-1;
+@table-body-selected-sort-bg: @table-selected-row-bg;
+@table-selected-row-hover-bg: darken(@table-selected-row-bg, 2%);
+@table-expanded-row-bg: #fbfbfb;
+@table-padding-vertical: 16px;
+@table-padding-horizontal: 16px;
+@table-padding-vertical-md: (@table-padding-vertical * 3 / 4);
+@table-padding-horizontal-md: (@table-padding-horizontal / 2);
+@table-padding-vertical-sm: (@table-padding-vertical / 2);
+@table-padding-horizontal-sm: (@table-padding-horizontal / 2);
+@table-border-color: @border-color-split;
+@table-border-radius-base: @border-radius-base;
+@table-footer-bg: @background-color-light;
+@table-footer-color: @heading-color;
+@table-header-bg-sm: @table-header-bg;
+@table-font-size: @font-size-base;
+@table-font-size-md: @table-font-size;
+@table-font-size-sm: @table-font-size;
+@table-header-cell-split-color: rgba(0, 0, 0, 0.06);
+// Sorter
+// Legacy: `table-header-sort-active-bg` is used for hover not real active
+@table-header-sort-active-bg: rgba(0, 0, 0, 0.04);
+@table-fixed-header-sort-active-bg: hsv(0, 0, 96%);
+
+// Filter
+@table-header-filter-active-bg: rgba(0, 0, 0, 0.04);
+@table-filter-btns-bg: inherit;
+@table-filter-dropdown-bg: @component-background;
+@table-expand-icon-bg: @component-background;
+@table-selection-column-width: 32px;
+// Sticky
+@table-sticky-scroll-bar-bg: fade(#000, 35%);
+@table-sticky-scroll-bar-radius: 4px;
+
+// Tag
+// --
+@tag-border-radius: @border-radius-base;
+@tag-default-bg: @background-color-light;
+@tag-default-color: @text-color;
+@tag-font-size: @font-size-sm;
+@tag-line-height: 20px;
+
+// TimePicker
+// ---
+@picker-bg: @component-background;
+@picker-basic-cell-hover-color: @item-hover-bg;
+@picker-basic-cell-active-with-range-color: @primary-1;
+@picker-basic-cell-hover-with-range-color: lighten(@primary-color, 35%);
+@picker-basic-cell-disabled-bg: rgba(0, 0, 0, 0.04);
+@picker-border-color: @border-color-split;
+@picker-date-hover-range-border-color: lighten(@primary-color, 20%);
+@picker-date-hover-range-color: @picker-basic-cell-hover-with-range-color;
+@picker-time-panel-column-width: 56px;
+@picker-time-panel-column-height: 224px;
+@picker-time-panel-cell-height: 28px;
+@picker-panel-cell-height: 24px;
+@picker-panel-cell-width: 36px;
+@picker-text-height: 40px;
+@picker-panel-without-time-cell-height: 66px;
+
+// Calendar
+// ---
+@calendar-bg: @component-background;
+@calendar-input-bg: @input-bg;
+@calendar-border-color: @border-color-inverse;
+@calendar-item-active-bg: @item-active-bg;
+@calendar-column-active-bg: fade(@calendar-item-active-bg, 20%);
+@calendar-full-bg: @calendar-bg;
+@calendar-full-panel-bg: @calendar-full-bg;
+
+// Carousel
+// ---
+@carousel-dot-width: 16px;
+@carousel-dot-height: 3px;
+@carousel-dot-active-width: 24px;
+
+// Badge
+// ---
+@badge-height: 20px;
+@badge-height-sm: 14px;
+@badge-dot-size: 6px;
+@badge-font-size: @font-size-sm;
+@badge-font-size-sm: @font-size-sm;
+@badge-font-weight: normal;
+@badge-status-size: 6px;
+@badge-text-color: @component-background;
+@badge-color: @highlight-color;
+
+// Rate
+// ---
+@rate-star-color: @yellow-6;
+@rate-star-bg: @border-color-split;
+@rate-star-size: 20px;
+@rate-star-hover-scale: scale(1.1);
+
+// Card
+// ---
+@card-head-color: @heading-color;
+@card-head-background: transparent;
+@card-head-font-size: @font-size-lg;
+@card-head-font-size-sm: @font-size-base;
+@card-head-padding: 16px;
+@card-head-padding-sm: (@card-head-padding / 2);
+@card-head-height: 48px;
+@card-head-height-sm: 36px;
+@card-inner-head-padding: 12px;
+@card-padding-base: 24px;
+@card-padding-base-sm: (@card-padding-base / 2);
+@card-actions-background: @component-background;
+@card-actions-li-margin: 12px 0;
+@card-skeleton-bg: #cfd8dc;
+@card-background: @component-background;
+@card-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.16), 0 3px 6px 0 rgba(0, 0, 0, 0.12),
+ 0 5px 12px 4px rgba(0, 0, 0, 0.09);
+@card-radius: @border-radius-base;
+@card-head-tabs-margin-bottom: -17px;
+@card-head-extra-color: @text-color;
+
+// Comment
+// ---
+@comment-bg: inherit;
+@comment-padding-base: @padding-md 0;
+@comment-nest-indent: 44px;
+@comment-font-size-base: @font-size-base;
+@comment-font-size-sm: @font-size-sm;
+@comment-author-name-color: @text-color-secondary;
+@comment-author-time-color: #ccc;
+@comment-action-color: @text-color-secondary;
+@comment-action-hover-color: #595959;
+@comment-actions-margin-bottom: inherit;
+@comment-actions-margin-top: @margin-sm;
+@comment-content-detail-p-margin-bottom: inherit;
+
+// Tabs
+// ---
+@tabs-card-head-background: @background-color-light;
+@tabs-card-height: 40px;
+@tabs-card-active-color: @primary-color;
+@tabs-card-horizontal-padding: (
+ (@tabs-card-height - floor(@font-size-base * @line-height-base)) / 2
+ ) - @border-width-base @padding-md;
+@tabs-card-horizontal-padding-sm: 6px @padding-md;
+@tabs-card-horizontal-padding-lg: 7px @padding-md 6px;
+@tabs-title-font-size: @font-size-base;
+@tabs-title-font-size-lg: @font-size-lg;
+@tabs-title-font-size-sm: @font-size-base;
+@tabs-ink-bar-color: @primary-color;
+@tabs-bar-margin: 0 0 @margin-md 0;
+@tabs-horizontal-gutter: 32px;
+@tabs-horizontal-margin: 0 0 0 @tabs-horizontal-gutter;
+@tabs-horizontal-margin-rtl: 0 0 0 32px;
+@tabs-horizontal-padding: @padding-sm 0;
+@tabs-horizontal-padding-lg: @padding-md 0;
+@tabs-horizontal-padding-sm: @padding-xs 0;
+@tabs-vertical-padding: @padding-xs @padding-lg;
+@tabs-vertical-margin: @margin-md 0 0 0;
+@tabs-scrolling-size: 32px;
+@tabs-highlight-color: @primary-color;
+@tabs-hover-color: @primary-5;
+@tabs-active-color: @primary-7;
+@tabs-card-gutter: 2px;
+@tabs-card-tab-active-border-top: 2px solid transparent;
+
+// BackTop
+// ---
+@back-top-color: #fff;
+@back-top-bg: @text-color-secondary;
+@back-top-hover-bg: @text-color;
+
+// Avatar
+// ---
+@avatar-size-base: 32px;
+@avatar-size-lg: 40px;
+@avatar-size-sm: 24px;
+@avatar-font-size-base: 18px;
+@avatar-font-size-lg: 24px;
+@avatar-font-size-sm: 14px;
+@avatar-bg: #ccc;
+@avatar-color: #fff;
+@avatar-border-radius: @border-radius-base;
+@avatar-group-overlapping: -8px;
+@avatar-group-space: 3px;
+@avatar-group-border-color: #fff;
+
+// Switch
+// ---
+@switch-height: 22px;
+@switch-sm-height: 16px;
+@switch-min-width: 44px;
+@switch-sm-min-width: 28px;
+@switch-disabled-opacity: 0.4;
+@switch-color: @primary-color;
+@switch-bg: @component-background;
+@switch-shadow-color: fade(#00230b, 20%);
+@switch-padding: 2px;
+@switch-inner-margin-min: ceil(@switch-height * 0.3);
+@switch-inner-margin-max: ceil(@switch-height * 1.1);
+@switch-sm-inner-margin-min: ceil(@switch-sm-height * 0.3);
+@switch-sm-inner-margin-max: ceil(@switch-sm-height * 1.1);
+
+// Pagination
+// ---
+@pagination-item-bg: @component-background;
+@pagination-item-size: @height-base;
+@pagination-item-size-sm: 24px;
+@pagination-font-family: @font-family;
+@pagination-font-weight-active: 500;
+@pagination-item-bg-active: @component-background;
+@pagination-item-link-bg: @component-background;
+@pagination-item-disabled-color-active: @disabled-color;
+@pagination-item-disabled-bg-active: @disabled-active-bg;
+@pagination-item-input-bg: @component-background;
+@pagination-mini-options-size-changer-top: 0px;
+
+// PageHeader
+// ---
+@page-header-padding: @padding-lg;
+@page-header-padding-vertical: @padding-md;
+@page-header-padding-breadcrumb: @padding-sm;
+@page-header-content-padding-vertical: @padding-sm;
+@page-header-back-color: #000;
+@page-header-ghost-bg: inherit;
+@page-header-heading-title: @heading-4-size;
+@page-header-heading-sub-title: 14px;
+@page-header-tabs-tab-font-size: 16px;
+
+// Breadcrumb
+// ---
+@breadcrumb-base-color: @text-color-secondary;
+@breadcrumb-last-item-color: @text-color;
+@breadcrumb-font-size: @font-size-base;
+@breadcrumb-icon-font-size: @font-size-base;
+@breadcrumb-link-color: @text-color-secondary;
+@breadcrumb-link-color-hover: @text-color;
+@breadcrumb-separator-color: @text-color-secondary;
+@breadcrumb-separator-margin: 0 @padding-xs;
+
+// Slider
+// ---
+@slider-margin: 10px 6px 10px;
+@slider-rail-background-color: @background-color-base;
+@slider-rail-background-color-hover: #e1e1e1;
+@slider-track-background-color: @primary-3;
+@slider-track-background-color-hover: @primary-4;
+@slider-handle-border-width: 2px;
+@slider-handle-background-color: @component-background;
+@slider-handle-color: @primary-3;
+@slider-handle-color-hover: @primary-4;
+@slider-handle-color-focus: tint(@primary-color, 20%);
+@slider-handle-color-focus-shadow: fade(@primary-color, 12%);
+@slider-handle-color-tooltip-open: @primary-color;
+@slider-handle-size: 14px;
+@slider-handle-margin-top: -5px;
+@slider-handle-shadow: 0;
+@slider-dot-border-color: @border-color-split;
+@slider-dot-border-color-active: tint(@primary-color, 50%);
+@slider-disabled-color: @disabled-color;
+@slider-disabled-background-color: @component-background;
+
+// Tree
+// ---
+@tree-bg: @component-background;
+@tree-title-height: 24px;
+@tree-child-padding: 18px;
+@tree-directory-selected-color: #fff;
+@tree-directory-selected-bg: @primary-color;
+@tree-node-hover-bg: @item-hover-bg;
+@tree-node-selected-bg: @primary-2;
+
+// Collapse
+// ---
+@collapse-header-padding: @padding-sm @padding-md;
+@collapse-header-padding-extra: 40px;
+@collapse-header-bg: @background-color-light;
+@collapse-content-padding: @padding-md;
+@collapse-content-bg: @component-background;
+@collapse-header-arrow-left: 16px;
+
+// Skeleton
+// ---
+@skeleton-color: rgba(190, 190, 190, 0.2);
+@skeleton-to-color: shade(@skeleton-color, 5%);
+@skeleton-paragraph-margin-top: 28px;
+@skeleton-paragraph-li-margin-top: @margin-md;
+@skeleton-paragraph-li-height: 16px;
+@skeleton-title-height: 16px;
+@skeleton-title-paragraph-margin-top: @margin-lg;
+
+// Transfer
+// ---
+@transfer-header-height: 40px;
+@transfer-item-height: @height-base;
+@transfer-disabled-bg: @disabled-bg;
+@transfer-list-height: 200px;
+@transfer-item-hover-bg: @item-hover-bg;
+@transfer-item-selected-hover-bg: darken(@item-active-bg, 2%);
+@transfer-item-padding-vertical: 6px;
+@transfer-list-search-icon-top: 12px;
+
+// Message
+// ---
+@message-notice-content-padding: 10px 16px;
+@message-notice-content-bg: @component-background;
+// Motion
+// ---
+@wave-animation-width: 6px;
+
+// Alert
+// ---
+@alert-success-border-color: ~`colorPalette('@{success-color}', 3) `;
+@alert-success-bg-color: ~`colorPalette('@{success-color}', 1) `;
+@alert-success-icon-color: @success-color;
+@alert-info-border-color: ~`colorPalette('@{info-color}', 3) `;
+@alert-info-bg-color: ~`colorPalette('@{info-color}', 1) `;
+@alert-info-icon-color: @info-color;
+@alert-warning-border-color: ~`colorPalette('@{warning-color}', 3) `;
+@alert-warning-bg-color: ~`colorPalette('@{warning-color}', 1) `;
+@alert-warning-icon-color: @warning-color;
+@alert-error-border-color: ~`colorPalette('@{error-color}', 3) `;
+@alert-error-bg-color: ~`colorPalette('@{error-color}', 1) `;
+@alert-error-icon-color: @error-color;
+@alert-message-color: @heading-color;
+@alert-text-color: @text-color;
+@alert-close-color: @text-color-secondary;
+@alert-close-hover-color: @icon-color-hover;
+@alert-no-icon-padding-vertical: @padding-xs;
+@alert-with-description-no-icon-padding-vertical: @padding-md - 1px;
+@alert-with-description-padding-vertical: @padding-md - 1px;
+@alert-with-description-padding: @alert-with-description-padding-vertical 15px
+ @alert-with-description-no-icon-padding-vertical @alert-with-description-icon-size;
+@alert-icon-top: 8px + @font-size-base * (@line-height-base / 2) - (@font-size-base / 2);
+@alert-with-description-icon-size: 24px;
+
+// List
+// ---
+@list-header-background: transparent;
+@list-footer-background: transparent;
+@list-empty-text-padding: @padding-md;
+@list-item-padding: @padding-sm 0;
+@list-item-padding-sm: @padding-xs @padding-md;
+@list-item-padding-lg: 16px 24px;
+@list-item-meta-margin-bottom: @padding-md;
+@list-item-meta-avatar-margin-right: @padding-md;
+@list-item-meta-title-margin-bottom: @padding-sm;
+@list-customize-card-bg: @component-background;
+@list-item-meta-description-font-size: @font-size-base;
+
+// Statistic
+// ---
+@statistic-title-font-size: @font-size-base;
+@statistic-content-font-size: 24px;
+@statistic-unit-font-size: 24px;
+@statistic-font-family: @font-family;
+
+// Drawer
+// ---
+@drawer-header-padding: @padding-md @padding-lg;
+@drawer-body-padding: @padding-lg;
+@drawer-bg: @component-background;
+@drawer-footer-padding-vertical: @modal-footer-padding-vertical;
+@drawer-footer-padding-horizontal: @modal-footer-padding-horizontal;
+@drawer-header-close-size: 56px;
+@drawer-title-font-size: @font-size-lg;
+@drawer-title-line-height: 22px;
+
+// Timeline
+// ---
+@timeline-width: 2px;
+@timeline-color: @border-color-split;
+@timeline-dot-border-width: 2px;
+@timeline-dot-color: @primary-color;
+@timeline-dot-bg: @component-background;
+@timeline-item-padding-bottom: 20px;
+
+// Typography
+// ---
+@typography-title-font-weight: 600;
+@typography-title-margin-top: 1.2em;
+@typography-title-margin-bottom: 0.5em;
+
+// Upload
+// ---
+@upload-actions-color: @text-color-secondary;
+
+// Steps
+// ---
+@process-tail-color: @border-color-split;
+@steps-nav-arrow-color: fade(@black, 25%);
+@steps-background: @component-background;
+@steps-icon-size: 32px;
+@steps-icon-custom-size: @steps-icon-size;
+@steps-icon-custom-top: 0px;
+@steps-icon-custom-font-size: 24px;
+@steps-icon-top: -0.5px;
+@steps-icon-font-size: @font-size-lg;
+@steps-icon-margin: 0 8px 0 0;
+@steps-title-line-height: @height-base;
+@steps-small-icon-size: 24px;
+@steps-small-icon-margin: 0 8px 0 0;
+@steps-dot-size: 8px;
+@steps-dot-top: 2px;
+@steps-current-dot-size: 10px;
+@steps-description-max-width: 140px;
+@steps-nav-content-max-width: auto;
+@steps-vertical-icon-width: 16px;
+@steps-vertical-tail-width: 16px;
+@steps-vertical-tail-width-sm: 12px;
+
+// Notification
+// ---
+@notification-bg: @component-background;
+@notification-padding-vertical: 16px;
+@notification-padding-horizontal: 24px;
+
+// Result
+// ---
+@result-title-font-size: 24px;
+@result-subtitle-font-size: @font-size-base;
+@result-icon-font-size: 72px;
+@result-extra-margin: 24px 0 0 0;
+
+// Image
+// ---
+@image-size-base: 48px;
+@image-font-size-base: 24px;
+@image-bg: #f5f5f5;
+@image-color: #fff;
+@image-mask-font-size: 16px;
+@image-preview-operation-size: 18px;
+@image-preview-operation-color: @text-color-dark;
+@image-preview-operation-disabled-color: fade(@image-preview-operation-color, 25%);
+
+// Segmented
+// ---
+@segmented-bg: fade(@black, 4%);
+@segmented-hover-bg: fade(@black, 6%);
+@segmented-selected-bg: @white;
+@segmented-label-color: fade(@black, 65%);
+@segmented-label-hover-color: #262626;
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/index.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/index.less
new file mode 100644
index 0000000..fd29f58
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/index.less
@@ -0,0 +1,7 @@
+// Default using variable as entry to support site variable version
+// This will be replaced in webpack bundle
+// @root-entry-name: variable;
+
+// @import './default.less';
+// @import './variable.less';
+@import './@{root-entry-name}.less';
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/variable.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/variable.less
new file mode 100644
index 0000000..faccc43
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/themes/variable.less
@@ -0,0 +1,1136 @@
+/* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */
+@import '../color/colors';
+
+@theme: variable;
+
+// The prefix to use on all css classes from ant.
+@ant-prefix: ant;
+
+// An override for the html selector for theme prefixes
+@html-selector: html;
+
+@{html-selector} {
+ @base-primary: @blue-6;
+
+ // ========= Primary Color =========
+ --@{ant-prefix}-primary-color: @base-primary;
+ --@{ant-prefix}-primary-color-hover: color(~`colorPalette('@{base-primary}', 5) `);
+ --@{ant-prefix}-primary-color-active: color(~`colorPalette('@{base-primary}', 7) `);
+ --@{ant-prefix}-primary-color-outline: fade(@base-primary, @outline-fade);
+
+ // Legacy
+ @legacy-primary-1: color(~`colorPalette('@{base-primary}', 1) `);
+
+ --@{ant-prefix}-primary-1: @legacy-primary-1;
+ --@{ant-prefix}-primary-2: color(~`colorPalette('@{base-primary}', 2) `);
+ --@{ant-prefix}-primary-3: color(~`colorPalette('@{base-primary}', 3) `);
+ --@{ant-prefix}-primary-4: color(~`colorPalette('@{base-primary}', 4) `);
+ --@{ant-prefix}-primary-5: color(~`colorPalette('@{base-primary}', 5) `);
+ --@{ant-prefix}-primary-6: @base-primary;
+ --@{ant-prefix}-primary-7: color(~`colorPalette('@{base-primary}', 7) `);
+
+ // Deprecated
+ --@{ant-prefix}-primary-color-deprecated-pure: ~'';
+ --@{ant-prefix}-primary-color-deprecated-l-35: lighten(@base-primary, 35%);
+ --@{ant-prefix}-primary-color-deprecated-l-20: lighten(@base-primary, 20%);
+ --@{ant-prefix}-primary-color-deprecated-t-20: tint(@base-primary, 20%);
+ --@{ant-prefix}-primary-color-deprecated-t-50: tint(@base-primary, 50%);
+ --@{ant-prefix}-primary-color-deprecated-f-12: fade(@base-primary, 12%);
+ --@{ant-prefix}-primary-color-active-deprecated-f-30: fade(@legacy-primary-1, 30%);
+ --@{ant-prefix}-primary-color-active-deprecated-d-02: darken(@legacy-primary-1, 2%);
+
+ // ========= Success Color =========
+ --@{ant-prefix}-success-color: @green-6;
+ --@{ant-prefix}-success-color-hover: color(~`colorPalette('@{green-6}', 5) `);
+ --@{ant-prefix}-success-color-active: color(~`colorPalette('@{green-6}', 7) `);
+ --@{ant-prefix}-success-color-outline: fade(@green-6, @outline-fade);
+ --@{ant-prefix}-success-color-deprecated-bg: ~`colorPalette('@{green-6}', 1) `;
+ --@{ant-prefix}-success-color-deprecated-border: ~`colorPalette('@{green-6}', 3) `;
+
+ // ========== Error Color ==========
+ --@{ant-prefix}-error-color: @red-5;
+ --@{ant-prefix}-error-color-hover: color(~`colorPalette('@{red-5}', 5) `);
+ --@{ant-prefix}-error-color-active: color(~`colorPalette('@{red-5}', 7) `);
+ --@{ant-prefix}-error-color-outline: fade(@red-5, @outline-fade);
+ --@{ant-prefix}-error-color-deprecated-bg: ~`colorPalette('@{red-5}', 1) `;
+ --@{ant-prefix}-error-color-deprecated-border: ~`colorPalette('@{red-5}', 3) `;
+
+ // ========= Warning Color =========
+ --@{ant-prefix}-warning-color: @gold-6;
+ --@{ant-prefix}-warning-color-hover: color(~`colorPalette('@{gold-6}', 5) `);
+ --@{ant-prefix}-warning-color-active: color(~`colorPalette('@{gold-6}', 7) `);
+ --@{ant-prefix}-warning-color-outline: fade(@gold-6, @outline-fade);
+ --@{ant-prefix}-warning-color-deprecated-bg: ~`colorPalette('@{gold-6}', 1) `;
+ --@{ant-prefix}-warning-color-deprecated-border: ~`colorPalette('@{gold-6}', 3) `;
+
+ // ========== Info Color ===========
+ --@{ant-prefix}-info-color: @base-primary;
+ --@{ant-prefix}-info-color-deprecated-bg: ~`colorPalette('@{base-primary}', 1) `;
+ --@{ant-prefix}-info-color-deprecated-border: ~`colorPalette('@{base-primary}', 3) `;
+}
+
+// -------- Colors -----------
+// >>> Primary
+@primary-color: ~'var(--@{ant-prefix}-primary-color)';
+@primary-color-hover: ~'var(--@{ant-prefix}-primary-color-hover)';
+@primary-color-active: ~'var(--@{ant-prefix}-primary-color-active)';
+@primary-color-outline: ~'var(--@{ant-prefix}-primary-color-outline)';
+
+@processing-color: @primary-color;
+
+// >>> Info
+@info-color: ~'var(--@{ant-prefix}-info-color)';
+@info-color-deprecated-bg: ~'var(--@{ant-prefix}-info-color-deprecated-bg)';
+@info-color-deprecated-border: ~'var(--@{ant-prefix}-info-color-deprecated-border)';
+
+// >>> Success
+@success-color: ~'var(--@{ant-prefix}-success-color)';
+@success-color-hover: ~'var(--@{ant-prefix}-success-color-hover)';
+@success-color-active: ~'var(--@{ant-prefix}-success-color-active)';
+@success-color-outline: ~'var(--@{ant-prefix}-success-color-outline)';
+@success-color-deprecated-bg: ~'var(--@{ant-prefix}-success-color-deprecated-bg)';
+@success-color-deprecated-border: ~'var(--@{ant-prefix}-success-color-deprecated-border)';
+
+// >>> Warning
+@warning-color: ~'var(--@{ant-prefix}-warning-color)';
+@warning-color-hover: ~'var(--@{ant-prefix}-warning-color-hover)';
+@warning-color-active: ~'var(--@{ant-prefix}-warning-color-active)';
+@warning-color-outline: ~'var(--@{ant-prefix}-warning-color-outline)';
+@warning-color-deprecated-bg: ~'var(--@{ant-prefix}-warning-color-deprecated-bg)';
+@warning-color-deprecated-border: ~'var(--@{ant-prefix}-warning-color-deprecated-border)';
+
+// >>> Error
+@error-color: ~'var(--@{ant-prefix}-error-color)';
+@error-color-hover: ~'var(--@{ant-prefix}-error-color-hover)';
+@error-color-active: ~'var(--@{ant-prefix}-error-color-active)';
+@error-color-outline: ~'var(--@{ant-prefix}-error-color-outline)';
+@error-color-deprecated-bg: ~'var(--@{ant-prefix}-error-color-deprecated-bg)';
+@error-color-deprecated-border: ~'var(--@{ant-prefix}-error-color-deprecated-border)';
+
+@highlight-color: @red-5;
+@normal-color: #d9d9d9;
+@white: #fff;
+@black: #000;
+
+// Color used by default to control hover and active backgrounds and for
+// alert info backgrounds.
+@primary-1: ~'var(--@{ant-prefix}-primary-1)'; // replace tint(@primary-color, 90%)
+@primary-2: ~'var(--@{ant-prefix}-primary-2)'; // replace tint(@primary-color, 80%)
+@primary-3: ~'var(--@{ant-prefix}-primary-3)'; // unused
+@primary-4: ~'var(--@{ant-prefix}-primary-4)'; // unused
+@primary-5: ~'var(--@{ant-prefix}-primary-5)'; // color used to control the text color in many active and hover states, replace tint(@primary-color, 20%)
+@primary-6: ~'var(--@{ant-prefix}-primary-6)'; // color used to control the text color of active buttons, don't use, use @primary-color
+@primary-7: ~'var(--@{ant-prefix}-primary-7)'; // replace shade(@primary-color, 5%)
+@primary-8: color(~`colorPalette('@{primary-color}', 8) `); // unused
+@primary-9: color(~`colorPalette('@{primary-color}', 9) `); // unused
+@primary-10: color(~`colorPalette('@{primary-color}', 10) `); // unused
+
+// Base Scaffolding Variables
+// ---
+
+// Background color for ``
+@body-background: #fff;
+// Base background color for most components
+@component-background: #fff;
+// Popover background color
+@popover-background: @component-background;
+@popover-customize-border-color: @border-color-split;
+@font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
+ 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
+ 'Noto Color Emoji';
+@code-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
+@text-color: fade(@black, 85%);
+@text-color-secondary: fade(@black, 45%);
+@text-color-inverse: @white;
+@icon-color: inherit;
+@icon-color-hover: fade(@black, 75%);
+@heading-color: fade(@black, 85%);
+@text-color-dark: fade(@white, 85%);
+@text-color-secondary-dark: fade(@white, 65%);
+@text-selection-bg: @primary-color;
+@font-variant-base: tabular-nums;
+@font-feature-settings-base: 'tnum';
+@font-size-base: 14px;
+@font-size-lg: @font-size-base + 2px;
+@font-size-sm: 12px;
+@heading-1-size: ceil(@font-size-base * 2.71);
+@heading-2-size: ceil(@font-size-base * 2.14);
+@heading-3-size: ceil(@font-size-base * 1.71);
+@heading-4-size: ceil(@font-size-base * 1.42);
+@heading-5-size: ceil(@font-size-base * 1.14);
+// https://github.com/ant-design/ant-design/issues/20210
+@line-height-base: 1.5715;
+@border-radius-base: 2px;
+@border-radius-sm: 2px;
+
+// control border
+@control-border-radius: @border-radius-base;
+
+// arrow border
+@arrow-border-radius: @border-radius-sm;
+
+// vertical paddings
+@padding-lg: 24px; // containers
+@padding-md: 16px; // small containers and buttons
+@padding-sm: 12px; // Form controls and items
+@padding-xs: 8px; // small items
+@padding-xss: 4px; // more small
+
+// vertical padding for all form controls
+@control-padding-horizontal: @padding-sm;
+@control-padding-horizontal-sm: @padding-xs;
+
+// vertical margins
+@margin-lg: 24px; // containers
+@margin-md: 16px; // small containers and buttons
+@margin-sm: 12px; // Form controls and items
+@margin-xs: 8px; // small items
+@margin-xss: 4px; // more small
+
+// height rules
+@height-base: 32px;
+@height-lg: 40px;
+@height-sm: 24px;
+
+// The background colors for active and hover states for things like
+// list items or table cells.
+@item-active-bg: @primary-1;
+@item-hover-bg: #f5f5f5;
+
+// ICONFONT
+@iconfont-css-prefix: anticon;
+
+// LINK
+@link-color: @primary-color;
+@link-hover-color: @primary-color-hover;
+@link-active-color: @primary-color-active;
+@link-decoration: none;
+@link-hover-decoration: none;
+@link-focus-decoration: none;
+@link-focus-outline: 0;
+
+// Animation
+@ease-base-out: cubic-bezier(0.7, 0.3, 0.1, 1);
+@ease-base-in: cubic-bezier(0.9, 0, 0.3, 0.7);
+@ease-out: cubic-bezier(0.215, 0.61, 0.355, 1);
+@ease-in: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+@ease-in-out: cubic-bezier(0.645, 0.045, 0.355, 1);
+@ease-out-back: cubic-bezier(0.12, 0.4, 0.29, 1.46);
+@ease-in-back: cubic-bezier(0.71, -0.46, 0.88, 0.6);
+@ease-in-out-back: cubic-bezier(0.71, -0.46, 0.29, 1.46);
+@ease-out-circ: cubic-bezier(0.08, 0.82, 0.17, 1);
+@ease-in-circ: cubic-bezier(0.6, 0.04, 0.98, 0.34);
+@ease-in-out-circ: cubic-bezier(0.78, 0.14, 0.15, 0.86);
+@ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1);
+@ease-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+@ease-in-out-quint: cubic-bezier(0.86, 0, 0.07, 1);
+
+// Border color
+@border-color-base: hsv(0, 0, 85%); // base border outline a component
+@border-color-split: rgba(0, 0, 0, 0.06); // split border inside a component
+@border-color-inverse: @white;
+@border-width-base: 1px; // width of the border for a component
+@border-style-base: solid; // style of a components border
+
+// Outline
+@outline-blur-size: 0;
+@outline-width: 2px;
+@outline-color: @primary-color; // No use anymore
+@outline-fade: 20%;
+
+@background-color-light: hsv(0, 0, 98%); // background of header and selected item
+@background-color-base: hsv(0, 0, 96%); // Default grey background color
+
+// Disabled states
+@disabled-color: fade(#000, 25%);
+@disabled-bg: @background-color-base;
+@disabled-active-bg: tint(@black, 90%);
+@disabled-color-dark: fade(#fff, 35%);
+
+// Shadow
+@shadow-color: rgba(0, 0, 0, 0.15);
+@shadow-color-inverse: @component-background;
+@box-shadow-base: @shadow-2;
+@shadow-1-up: 0 -6px 16px -8px rgba(0, 0, 0, 0.08), 0 -9px 28px 0 rgba(0, 0, 0, 0.05),
+ 0 -12px 48px 16px rgba(0, 0, 0, 0.03);
+@shadow-1-down: 0 6px 16px -8px rgba(0, 0, 0, 0.08), 0 9px 28px 0 rgba(0, 0, 0, 0.05),
+ 0 12px 48px 16px rgba(0, 0, 0, 0.03);
+@shadow-1-left: -6px 0 16px -8px rgba(0, 0, 0, 0.08), -9px 0 28px 0 rgba(0, 0, 0, 0.05),
+ -12px 0 48px 16px rgba(0, 0, 0, 0.03);
+@shadow-1-right: 6px 0 16px -8px rgba(0, 0, 0, 0.08), 9px 0 28px 0 rgba(0, 0, 0, 0.05),
+ 12px 0 48px 16px rgba(0, 0, 0, 0.03);
+@shadow-2: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08),
+ 0 9px 28px 8px rgba(0, 0, 0, 0.05);
+
+// Buttons
+@btn-font-weight: 400;
+@btn-border-radius-base: @border-radius-base;
+@btn-border-radius-sm: @border-radius-base;
+@btn-border-width: @border-width-base;
+@btn-border-style: @border-style-base;
+@btn-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);
+@btn-primary-shadow: 0 2px 0 rgba(0, 0, 0, 0.045);
+@btn-text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12);
+
+@btn-primary-color: #fff;
+@btn-primary-bg: @primary-color;
+
+@btn-default-color: @text-color;
+@btn-default-bg: @component-background;
+@btn-default-border: @border-color-base;
+
+@btn-danger-color: #fff;
+@btn-danger-bg: @error-color;
+@btn-danger-border: @error-color;
+
+@btn-disable-color: @disabled-color;
+@btn-disable-bg: @disabled-bg;
+@btn-disable-border: @border-color-base;
+
+@btn-default-ghost-color: @component-background;
+@btn-default-ghost-bg: transparent;
+@btn-default-ghost-border: @component-background;
+
+@btn-font-size-lg: @font-size-lg;
+@btn-font-size-sm: @font-size-base;
+@btn-padding-horizontal-base: @padding-md - 1px;
+@btn-padding-horizontal-lg: @btn-padding-horizontal-base;
+@btn-padding-horizontal-sm: @padding-xs - 1px;
+
+@btn-height-base: @height-base;
+@btn-height-lg: @height-lg;
+@btn-height-sm: @height-sm;
+
+@btn-line-height: @line-height-base;
+
+@btn-circle-size: @btn-height-base;
+@btn-circle-size-lg: @btn-height-lg;
+@btn-circle-size-sm: @btn-height-sm;
+
+@btn-square-size: @btn-height-base;
+@btn-square-size-lg: @btn-height-lg;
+@btn-square-size-sm: @btn-height-sm;
+@btn-square-only-icon-size: @font-size-base + 2px;
+@btn-square-only-icon-size-sm: @font-size-base;
+@btn-square-only-icon-size-lg: @btn-font-size-lg + 2px;
+
+@btn-group-border: @primary-5;
+
+@btn-link-hover-bg: transparent;
+@btn-text-hover-bg: rgba(0, 0, 0, 0.018);
+
+// Checkbox
+@checkbox-size: 16px;
+@checkbox-color: @primary-color;
+@checkbox-check-color: #fff;
+@checkbox-check-bg: @checkbox-check-color;
+@checkbox-border-width: @border-width-base;
+@checkbox-border-radius: @border-radius-base;
+@checkbox-group-item-margin-right: 8px;
+
+// Descriptions
+@descriptions-bg: #fafafa;
+@descriptions-title-margin-bottom: 20px;
+@descriptions-default-padding: @padding-md @padding-lg;
+@descriptions-middle-padding: @padding-sm @padding-lg;
+@descriptions-small-padding: @padding-xs @padding-md;
+@descriptions-item-padding-bottom: @padding-md;
+@descriptions-item-trailing-colon: true;
+@descriptions-item-label-colon-margin-right: 8px;
+@descriptions-item-label-colon-margin-left: 2px;
+@descriptions-extra-color: @text-color;
+
+// Divider
+@divider-text-padding: 1em;
+@divider-orientation-margin: 5%;
+@divider-color: rgba(0, 0, 0, 6%);
+@divider-vertical-gutter: 8px;
+
+// Dropdown
+@dropdown-selected-color: @primary-color;
+@dropdown-menu-submenu-disabled-bg: @component-background;
+@dropdown-selected-bg: @item-active-bg;
+
+// Empty
+@empty-font-size: @font-size-base;
+
+// Radio
+@radio-size: 16px;
+@radio-top: 0.2em;
+@radio-border-width: 1px;
+@radio-dot-size: @radio-size - 8px;
+@radio-dot-color: @primary-color;
+@radio-dot-disabled-color: fade(@black, 20%);
+@radio-solid-checked-color: @component-background;
+
+// Radio buttons
+@radio-button-bg: @btn-default-bg;
+@radio-button-checked-bg: @btn-default-bg;
+@radio-button-color: @btn-default-color;
+@radio-button-hover-color: @primary-5;
+@radio-button-active-color: @primary-7;
+@radio-button-padding-horizontal: @padding-md - 1px;
+@radio-disabled-button-checked-bg: @disabled-active-bg;
+@radio-disabled-button-checked-color: @disabled-color;
+@radio-wrapper-margin-right: 8px;
+
+// Media queries breakpoints
+// @screen-xs and @screen-xs-min is not used in Grid
+// smallest break point is @screen-md
+@screen-xs: 480px;
+@screen-xs-min: @screen-xs;
+// 👆 Extra small screen / phone
+
+// 👇 Small screen / tablet
+@screen-sm: 576px;
+@screen-sm-min: @screen-sm;
+
+// Medium screen / desktop
+@screen-md: 768px;
+@screen-md-min: @screen-md;
+
+// Large screen / wide desktop
+@screen-lg: 992px;
+@screen-lg-min: @screen-lg;
+
+// Extra large screen / full hd
+@screen-xl: 1200px;
+@screen-xl-min: @screen-xl;
+
+// Extra extra large screen / large desktop
+@screen-xxl: 1600px;
+@screen-xxl-min: @screen-xxl;
+
+// provide a maximum
+@screen-xs-max: (@screen-sm-min - 1px);
+@screen-sm-max: (@screen-md-min - 1px);
+@screen-md-max: (@screen-lg-min - 1px);
+@screen-lg-max: (@screen-xl-min - 1px);
+@screen-xl-max: (@screen-xxl-min - 1px);
+
+// Grid system
+@grid-columns: 24;
+
+// Layout
+@layout-body-background: #f0f2f5;
+@layout-header-background: #001529;
+@layout-header-height: 64px;
+@layout-header-padding: 0 50px;
+@layout-header-color: @text-color;
+@layout-footer-padding: 24px 50px;
+@layout-footer-background: @layout-body-background;
+@layout-sider-background: @layout-header-background;
+@layout-trigger-height: 48px;
+@layout-trigger-background: #002140;
+@layout-trigger-color: #fff;
+@layout-zero-trigger-width: 36px;
+@layout-zero-trigger-height: 42px;
+// Layout light theme
+@layout-sider-background-light: #fff;
+@layout-trigger-background-light: #fff;
+@layout-trigger-color-light: @text-color;
+
+// z-index list, order by `z-index`
+@zindex-badge: auto;
+@zindex-table-fixed: 2;
+@zindex-affix: 10;
+@zindex-back-top: 10;
+@zindex-picker-panel: 10;
+@zindex-popup-close: 10;
+@zindex-modal: 1000;
+@zindex-modal-mask: 1000;
+@zindex-message: 1010;
+@zindex-notification: 1010;
+@zindex-popover: 1030;
+@zindex-dropdown: 1050;
+@zindex-picker: 1050;
+@zindex-popoconfirm: 1060;
+@zindex-tooltip: 1070;
+@zindex-image: 1080;
+
+// Animation
+@animation-duration-slow: 0.3s; // Modal
+@animation-duration-base: 0.2s;
+@animation-duration-fast: 0.1s; // Tooltip
+
+//CollapsePanel
+@collapse-panel-border-radius: @border-radius-base;
+
+//Dropdown
+@dropdown-menu-bg: @component-background;
+@dropdown-vertical-padding: 5px;
+@dropdown-edge-child-vertical-padding: 4px;
+@dropdown-font-size: @font-size-base;
+@dropdown-line-height: 22px;
+
+// Form
+// ---
+@label-required-color: @highlight-color;
+@label-color: @heading-color;
+@form-warning-input-bg: @input-bg;
+@form-item-margin-bottom: 24px;
+@form-item-trailing-colon: true;
+@form-vertical-label-padding: 0 0 8px;
+@form-vertical-label-margin: 0;
+@form-item-label-font-size: @font-size-base;
+@form-item-label-height: @input-height-base;
+@form-item-label-colon-margin-right: 8px;
+@form-item-label-colon-margin-left: 2px;
+@form-error-input-bg: @input-bg;
+
+// Input
+// ---
+@input-height-base: @height-base;
+@input-height-lg: @height-lg;
+@input-height-sm: @height-sm;
+@input-padding-horizontal: @control-padding-horizontal - 1px;
+@input-padding-horizontal-base: @input-padding-horizontal;
+@input-padding-horizontal-sm: @control-padding-horizontal-sm - 1px;
+@input-padding-horizontal-lg: @input-padding-horizontal;
+@input-padding-vertical-base: max(
+ (round(((@input-height-base - @font-size-base * @line-height-base) / 2) * 10) / 10) -
+ @border-width-base,
+ 3px
+);
+@input-padding-vertical-sm: max(
+ (round(((@input-height-sm - @font-size-base * @line-height-base) / 2) * 10) / 10) -
+ @border-width-base,
+ 0
+);
+@input-padding-vertical-lg: (
+ ceil(((@input-height-lg - @font-size-lg * @line-height-base) / 2) * 10) / 10
+ ) - @border-width-base;
+@input-placeholder-color: hsv(0, 0, 75%);
+@input-color: @text-color;
+@input-icon-color: @input-color;
+@input-border-color: @border-color-base;
+@input-bg: @component-background;
+@input-number-hover-border-color: @input-hover-border-color;
+@input-number-handler-active-bg: #f4f4f4;
+@input-number-handler-hover-bg: @primary-5;
+@input-number-handler-bg: @component-background;
+@input-number-handler-border-color: @border-color-base;
+@input-addon-bg: @background-color-light;
+@input-hover-border-color: @primary-5;
+@input-disabled-bg: @disabled-bg;
+@input-outline-offset: 0 0;
+@input-icon-hover-color: fade(@black, 85%);
+@input-disabled-color: @disabled-color;
+
+// Mentions
+// ---
+@mentions-dropdown-bg: @component-background;
+@mentions-dropdown-menu-item-hover-bg: @mentions-dropdown-bg;
+
+// Select
+// ---
+@select-border-color: @border-color-base;
+@select-item-selected-color: @text-color;
+@select-item-selected-font-weight: 600;
+@select-dropdown-bg: @component-background;
+@select-item-selected-bg: @primary-1;
+@select-item-active-bg: @item-hover-bg;
+@select-dropdown-vertical-padding: @dropdown-vertical-padding;
+@select-dropdown-font-size: @dropdown-font-size;
+@select-dropdown-line-height: @dropdown-line-height;
+@select-dropdown-height: 32px;
+@select-background: @component-background;
+@select-clear-background: @select-background;
+@select-selection-item-bg: @background-color-base;
+@select-selection-item-border-color: @border-color-split;
+@select-single-item-height-lg: 40px;
+@select-multiple-item-height: @input-height-base - @input-padding-vertical-base * 2; // Normal 24px
+@select-multiple-item-height-lg: 32px;
+@select-multiple-item-spacing-half: ceil((@input-padding-vertical-base / 2));
+@select-multiple-disabled-background: @input-disabled-bg;
+@select-multiple-item-disabled-color: #bfbfbf;
+@select-multiple-item-disabled-border-color: @select-border-color;
+
+// Cascader
+// ---
+@cascader-bg: @component-background;
+@cascader-item-selected-bg: @primary-1;
+@cascader-menu-bg: @component-background;
+@cascader-menu-border-color-split: @border-color-split;
+
+// Cascader
+// ----
+@cascader-dropdown-vertical-padding: @dropdown-vertical-padding;
+@cascader-dropdown-edge-child-vertical-padding: @dropdown-edge-child-vertical-padding;
+@cascader-dropdown-font-size: @dropdown-font-size;
+@cascader-dropdown-line-height: @dropdown-line-height;
+
+// Anchor
+// ---
+@anchor-bg: transparent;
+@anchor-border-color: @border-color-split;
+@anchor-link-top: 4px;
+@anchor-link-left: 16px;
+@anchor-link-padding: @anchor-link-top 0 @anchor-link-top @anchor-link-left;
+
+// Tooltip
+// ---
+// Tooltip max width
+@tooltip-max-width: 250px;
+// Tooltip text color
+@tooltip-color: #fff;
+// Tooltip background color
+@tooltip-bg: rgba(0, 0, 0, 0.75);
+// Tooltip arrow width
+@tooltip-arrow-width: 8px * sqrt(2);
+// Tooltip distance with trigger
+@tooltip-distance: @tooltip-arrow-width - 1px + 4px;
+// Tooltip arrow color
+@tooltip-arrow-color: @tooltip-bg;
+@tooltip-border-radius: @border-radius-base;
+
+// Popover
+// ---
+// Popover body background color
+@popover-bg: @component-background;
+// Popover text color
+@popover-color: @text-color;
+// Popover maximum width
+@popover-min-width: 177px;
+@popover-min-height: 32px;
+// Popover arrow width
+@popover-arrow-width: @tooltip-arrow-width;
+// Popover arrow color
+@popover-arrow-color: @popover-bg;
+// Popover outer arrow width
+// Popover outer arrow color
+@popover-arrow-outer-color: @popover-bg;
+// Popover distance with trigger
+@popover-distance: @popover-arrow-width + 4px;
+@popover-padding-horizontal: @padding-md;
+
+// Modal
+// --
+@modal-header-padding-vertical: @padding-md;
+@modal-header-padding-horizontal: @padding-lg;
+@modal-body-padding: @padding-lg;
+@modal-header-bg: @component-background;
+@modal-header-padding: @modal-header-padding-vertical @modal-header-padding-horizontal;
+@modal-header-border-width: @border-width-base;
+@modal-header-border-style: @border-style-base;
+@modal-header-title-line-height: 22px;
+@modal-header-title-font-size: @font-size-lg;
+@modal-header-border-color-split: @border-color-split;
+@modal-header-close-size: @modal-header-title-line-height + 2 * @modal-header-padding-vertical;
+@modal-content-bg: @component-background;
+@modal-heading-color: @heading-color;
+@modal-close-color: @text-color-secondary;
+@modal-footer-bg: transparent;
+@modal-footer-border-color-split: @border-color-split;
+@modal-footer-border-style: @border-style-base;
+@modal-footer-padding-vertical: 10px;
+@modal-footer-padding-horizontal: 16px;
+@modal-footer-border-width: @border-width-base;
+@modal-mask-bg: fade(@black, 45%);
+@modal-confirm-body-padding: 32px 32px 24px;
+@modal-confirm-title-font-size: @font-size-lg;
+@modal-border-radius: @border-radius-base;
+
+// Progress
+// --
+@progress-default-color: @processing-color;
+@progress-remaining-color: rgba(0, 0, 0, 0.04);
+@progress-info-text-color: @progress-text-color;
+@progress-radius: 100px;
+@progress-steps-item-bg: #f3f3f3;
+@progress-text-font-size: 1em;
+@progress-text-color: @text-color; // This is for circle text color, should be renamed better
+@progress-circle-text-font-size: 1em;
+// Menu
+// ---
+@menu-inline-toplevel-item-height: 40px;
+@menu-item-height: 40px;
+@menu-item-group-height: @line-height-base;
+@menu-collapsed-width: 80px;
+@menu-bg: @component-background;
+@menu-popup-bg: @component-background;
+@menu-item-color: @text-color;
+@menu-inline-submenu-bg: @background-color-light;
+@menu-highlight-color: @primary-color;
+@menu-highlight-danger-color: @error-color;
+@menu-item-active-bg: @primary-1;
+@menu-item-active-danger-bg: @red-1;
+@menu-item-active-border-width: 3px;
+@menu-item-group-title-color: @text-color-secondary;
+@menu-item-vertical-margin: 4px;
+@menu-item-font-size: @font-size-base;
+@menu-item-boundary-margin: 8px;
+@menu-item-padding-horizontal: 20px;
+@menu-item-padding: 0 @menu-item-padding-horizontal;
+@menu-horizontal-line-height: 46px;
+@menu-icon-margin-right: 10px;
+@menu-icon-size: @menu-item-font-size;
+@menu-icon-size-lg: @font-size-lg;
+@menu-item-group-title-font-size: @menu-item-font-size;
+
+// dark theme
+@menu-dark-color: @text-color-secondary-dark;
+@menu-dark-danger-color: @error-color;
+@menu-dark-bg: @layout-header-background;
+@menu-dark-arrow-color: #fff;
+@menu-dark-inline-submenu-bg: #000c17;
+@menu-dark-highlight-color: #fff;
+@menu-dark-item-active-bg: @primary-color;
+@menu-dark-item-active-danger-bg: @error-color;
+@menu-dark-selected-item-icon-color: @white;
+@menu-dark-selected-item-text-color: @white;
+@menu-dark-item-hover-bg: transparent;
+// Spin
+// ---
+@spin-dot-size-sm: 14px;
+@spin-dot-size: 20px;
+@spin-dot-size-lg: 32px;
+
+// Table
+// --
+@table-bg: @component-background;
+@table-header-bg: @background-color-light;
+@table-header-color: @heading-color;
+@table-header-sort-bg: @background-color-base;
+@table-body-sort-bg: #fafafa;
+@table-row-hover-bg: @background-color-light;
+@table-selected-row-color: inherit;
+@table-selected-row-bg: @primary-1;
+@table-body-selected-sort-bg: @table-selected-row-bg;
+@table-selected-row-hover-bg: ~'var(--@{ant-prefix}-primary-color-active-deprecated-d-02)';
+@table-expanded-row-bg: #fbfbfb;
+@table-padding-vertical: 16px;
+@table-padding-horizontal: 16px;
+@table-padding-vertical-md: (@table-padding-vertical * 3 / 4);
+@table-padding-horizontal-md: (@table-padding-horizontal / 2);
+@table-padding-vertical-sm: (@table-padding-vertical / 2);
+@table-padding-horizontal-sm: (@table-padding-horizontal / 2);
+@table-border-color: @border-color-split;
+@table-border-radius-base: @border-radius-base;
+@table-footer-bg: @background-color-light;
+@table-footer-color: @heading-color;
+@table-header-bg-sm: @table-header-bg;
+@table-font-size: @font-size-base;
+@table-font-size-md: @table-font-size;
+@table-font-size-sm: @table-font-size;
+@table-header-cell-split-color: rgba(0, 0, 0, 0.06);
+// Sorter
+// Legacy: `table-header-sort-active-bg` is used for hover not real active
+@table-header-sort-active-bg: rgba(0, 0, 0, 0.04);
+@table-fixed-header-sort-active-bg: hsv(0, 0, 96%);
+
+// Filter
+@table-header-filter-active-bg: rgba(0, 0, 0, 0.04);
+@table-filter-btns-bg: inherit;
+@table-filter-dropdown-bg: @component-background;
+@table-expand-icon-bg: @component-background;
+@table-selection-column-width: 32px;
+// Sticky
+@table-sticky-scroll-bar-bg: fade(#000, 35%);
+@table-sticky-scroll-bar-radius: 4px;
+
+// Tag
+// --
+@tag-border-radius: @border-radius-base;
+@tag-default-bg: @background-color-light;
+@tag-default-color: @text-color;
+@tag-font-size: @font-size-sm;
+@tag-line-height: 20px;
+
+// TimePicker
+// ---
+@picker-bg: @component-background;
+@picker-basic-cell-hover-color: @item-hover-bg;
+@picker-basic-cell-active-with-range-color: @primary-1;
+@picker-basic-cell-hover-with-range-color: ~'var(--@{ant-prefix}-primary-color-deprecated-l-35)';
+@picker-basic-cell-disabled-bg: rgba(0, 0, 0, 0.04);
+@picker-border-color: @border-color-split;
+@picker-date-hover-range-border-color: ~'var(--@{ant-prefix}-primary-color-deprecated-l-20)';
+@picker-date-hover-range-color: @picker-basic-cell-hover-with-range-color;
+@picker-time-panel-column-width: 56px;
+@picker-time-panel-column-height: 224px;
+@picker-time-panel-cell-height: 28px;
+@picker-panel-cell-height: 24px;
+@picker-panel-cell-width: 36px;
+@picker-text-height: 40px;
+@picker-panel-without-time-cell-height: 66px;
+
+// Calendar
+// ---
+@calendar-bg: @component-background;
+@calendar-input-bg: @input-bg;
+@calendar-border-color: @border-color-inverse;
+@calendar-item-active-bg: @item-active-bg;
+@calendar-column-active-bg: ~'var(--@{ant-prefix}-primary-color-active-deprecated-f-30)';
+@calendar-full-bg: @calendar-bg;
+@calendar-full-panel-bg: @calendar-full-bg;
+
+// Carousel
+// ---
+@carousel-dot-width: 16px;
+@carousel-dot-height: 3px;
+@carousel-dot-active-width: 24px;
+
+// Badge
+// ---
+@badge-height: 20px;
+@badge-height-sm: 14px;
+@badge-dot-size: 6px;
+@badge-font-size: @font-size-sm;
+@badge-font-size-sm: @font-size-sm;
+@badge-font-weight: normal;
+@badge-status-size: 6px;
+@badge-text-color: @component-background;
+@badge-color: @highlight-color;
+
+// Rate
+// ---
+@rate-star-color: @yellow-6;
+@rate-star-bg: @border-color-split;
+@rate-star-size: 20px;
+@rate-star-hover-scale: scale(1.1);
+
+// Card
+// ---
+@card-head-color: @heading-color;
+@card-head-background: transparent;
+@card-head-font-size: @font-size-lg;
+@card-head-font-size-sm: @font-size-base;
+@card-head-padding: 16px;
+@card-head-padding-sm: (@card-head-padding / 2);
+@card-head-height: 48px;
+@card-head-height-sm: 36px;
+@card-inner-head-padding: 12px;
+@card-padding-base: 24px;
+@card-padding-base-sm: (@card-padding-base / 2);
+@card-actions-background: @component-background;
+@card-actions-li-margin: 12px 0;
+@card-skeleton-bg: #cfd8dc;
+@card-background: @component-background;
+@card-shadow: 0 1px 2px -2px rgba(0, 0, 0, 0.16), 0 3px 6px 0 rgba(0, 0, 0, 0.12),
+ 0 5px 12px 4px rgba(0, 0, 0, 0.09);
+@card-radius: @border-radius-base;
+@card-head-tabs-margin-bottom: -17px;
+@card-head-extra-color: @text-color;
+
+// Comment
+// ---
+@comment-bg: inherit;
+@comment-padding-base: @padding-md 0;
+@comment-nest-indent: 44px;
+@comment-font-size-base: @font-size-base;
+@comment-font-size-sm: @font-size-sm;
+@comment-author-name-color: @text-color-secondary;
+@comment-author-time-color: #ccc;
+@comment-action-color: @text-color-secondary;
+@comment-action-hover-color: #595959;
+@comment-actions-margin-bottom: inherit;
+@comment-actions-margin-top: @margin-sm;
+@comment-content-detail-p-margin-bottom: inherit;
+
+// Tabs
+// ---
+@tabs-card-head-background: @background-color-light;
+@tabs-card-height: 40px;
+@tabs-card-active-color: @primary-color;
+@tabs-card-horizontal-padding: (
+ (@tabs-card-height - floor(@font-size-base * @line-height-base)) / 2
+ ) - @border-width-base @padding-md;
+@tabs-card-horizontal-padding-sm: 6px @padding-md;
+@tabs-card-horizontal-padding-lg: 7px @padding-md 6px;
+@tabs-title-font-size: @font-size-base;
+@tabs-title-font-size-lg: @font-size-lg;
+@tabs-title-font-size-sm: @font-size-base;
+@tabs-ink-bar-color: @primary-color;
+@tabs-bar-margin: 0 0 @margin-md 0;
+@tabs-horizontal-gutter: 32px;
+@tabs-horizontal-margin: 0 0 0 @tabs-horizontal-gutter;
+@tabs-horizontal-margin-rtl: 0 0 0 32px;
+@tabs-horizontal-padding: @padding-sm 0;
+@tabs-horizontal-padding-lg: @padding-md 0;
+@tabs-horizontal-padding-sm: @padding-xs 0;
+@tabs-vertical-padding: @padding-xs @padding-lg;
+@tabs-vertical-margin: @margin-md 0 0 0;
+@tabs-scrolling-size: 32px;
+@tabs-highlight-color: @primary-color;
+@tabs-hover-color: @primary-5;
+@tabs-active-color: @primary-7;
+@tabs-card-gutter: 2px;
+@tabs-card-tab-active-border-top: 2px solid transparent;
+
+// BackTop
+// ---
+@back-top-color: #fff;
+@back-top-bg: @text-color-secondary;
+@back-top-hover-bg: @text-color;
+
+// Avatar
+// ---
+@avatar-size-base: 32px;
+@avatar-size-lg: 40px;
+@avatar-size-sm: 24px;
+@avatar-font-size-base: 18px;
+@avatar-font-size-lg: 24px;
+@avatar-font-size-sm: 14px;
+@avatar-bg: #ccc;
+@avatar-color: #fff;
+@avatar-border-radius: @border-radius-base;
+@avatar-group-overlapping: -8px;
+@avatar-group-space: 3px;
+@avatar-group-border-color: #fff;
+
+// Switch
+// ---
+@switch-height: 22px;
+@switch-sm-height: 16px;
+@switch-min-width: 44px;
+@switch-sm-min-width: 28px;
+@switch-disabled-opacity: 0.4;
+@switch-color: @primary-color;
+@switch-bg: @component-background;
+@switch-shadow-color: fade(#00230b, 20%);
+@switch-padding: 2px;
+@switch-inner-margin-min: ceil(@switch-height * 0.3);
+@switch-inner-margin-max: ceil(@switch-height * 1.1);
+@switch-sm-inner-margin-min: ceil(@switch-sm-height * 0.3);
+@switch-sm-inner-margin-max: ceil(@switch-sm-height * 1.1);
+
+// Pagination
+// ---
+@pagination-item-bg: @component-background;
+@pagination-item-size: @height-base;
+@pagination-item-size-sm: 24px;
+@pagination-font-family: @font-family;
+@pagination-font-weight-active: 500;
+@pagination-item-bg-active: @component-background;
+@pagination-item-link-bg: @component-background;
+@pagination-item-disabled-color-active: @disabled-color;
+@pagination-item-disabled-bg-active: @disabled-active-bg;
+@pagination-item-input-bg: @component-background;
+@pagination-mini-options-size-changer-top: 0px;
+
+// PageHeader
+// ---
+@page-header-padding: @padding-lg;
+@page-header-padding-vertical: @padding-md;
+@page-header-padding-breadcrumb: @padding-sm;
+@page-header-content-padding-vertical: @padding-sm;
+@page-header-back-color: #000;
+@page-header-ghost-bg: inherit;
+@page-header-heading-title: @heading-4-size;
+@page-header-heading-sub-title: 14px;
+@page-header-tabs-tab-font-size: 16px;
+
+// Breadcrumb
+// ---
+@breadcrumb-base-color: @text-color-secondary;
+@breadcrumb-last-item-color: @text-color;
+@breadcrumb-font-size: @font-size-base;
+@breadcrumb-icon-font-size: @font-size-base;
+@breadcrumb-link-color: @text-color-secondary;
+@breadcrumb-link-color-hover: @text-color;
+@breadcrumb-separator-color: @text-color-secondary;
+@breadcrumb-separator-margin: 0 @padding-xs;
+
+// Slider
+// ---
+@slider-margin: 10px 6px 10px;
+@slider-rail-background-color: @background-color-base;
+@slider-rail-background-color-hover: #e1e1e1;
+@slider-track-background-color: @primary-3;
+@slider-track-background-color-hover: @primary-4;
+@slider-handle-border-width: 2px;
+@slider-handle-background-color: @component-background;
+@slider-handle-color: @primary-3;
+@slider-handle-color-hover: @primary-4;
+@slider-handle-color-focus: ~'var(--@{ant-prefix}-primary-color-deprecated-t-20)';
+@slider-handle-color-focus-shadow: ~'var(--@{ant-prefix}-primary-color-deprecated-f-12)';
+@slider-handle-color-tooltip-open: @primary-color;
+@slider-handle-size: 14px;
+@slider-handle-margin-top: -5px;
+@slider-handle-shadow: 0;
+@slider-dot-border-color: @border-color-split;
+@slider-dot-border-color-active: ~'var(--@{ant-prefix}-primary-color-deprecated-t-50)';
+@slider-disabled-color: @disabled-color;
+@slider-disabled-background-color: @component-background;
+
+// Tree
+// ---
+@tree-bg: @component-background;
+@tree-title-height: 24px;
+@tree-child-padding: 18px;
+@tree-directory-selected-color: #fff;
+@tree-directory-selected-bg: @primary-color;
+@tree-node-hover-bg: @item-hover-bg;
+@tree-node-selected-bg: @primary-2;
+
+// Collapse
+// ---
+@collapse-header-padding: @padding-sm @padding-md;
+@collapse-header-padding-extra: 40px;
+@collapse-header-bg: @background-color-light;
+@collapse-content-padding: @padding-md;
+@collapse-content-bg: @component-background;
+@collapse-header-arrow-left: 16px;
+
+// Skeleton
+// ---
+@skeleton-color: rgba(190, 190, 190, 0.2);
+@skeleton-to-color: shade(@skeleton-color, 5%);
+@skeleton-paragraph-margin-top: 28px;
+@skeleton-paragraph-li-margin-top: @margin-md;
+@skeleton-paragraph-li-height: 16px;
+@skeleton-title-height: 16px;
+@skeleton-title-paragraph-margin-top: @margin-lg;
+
+// Transfer
+// ---
+@transfer-header-height: 40px;
+@transfer-item-height: @height-base;
+@transfer-disabled-bg: @disabled-bg;
+@transfer-list-height: 200px;
+@transfer-item-hover-bg: @item-hover-bg;
+@transfer-item-selected-hover-bg: ~'var(--@{ant-prefix}-primary-color-active-deprecated-d-02)';
+@transfer-item-padding-vertical: 6px;
+@transfer-list-search-icon-top: 12px;
+
+// Message
+// ---
+@message-notice-content-padding: 10px 16px;
+@message-notice-content-bg: @component-background;
+// Motion
+// ---
+@wave-animation-width: 6px;
+
+// Alert
+// ---
+@alert-success-border-color: @success-color-deprecated-border;
+@alert-success-bg-color: @success-color-deprecated-bg;
+@alert-success-icon-color: @success-color;
+@alert-info-border-color: @info-color-deprecated-border;
+@alert-info-bg-color: @info-color-deprecated-bg;
+@alert-info-icon-color: @info-color;
+@alert-warning-border-color: @warning-color-deprecated-border;
+@alert-warning-bg-color: @warning-color-deprecated-bg;
+@alert-warning-icon-color: @warning-color;
+@alert-error-border-color: @error-color-deprecated-border;
+@alert-error-bg-color: @error-color-deprecated-bg;
+@alert-error-icon-color: @error-color;
+@alert-message-color: @heading-color;
+@alert-text-color: @text-color;
+@alert-close-color: @text-color-secondary;
+@alert-close-hover-color: @icon-color-hover;
+@alert-no-icon-padding-vertical: @padding-xs;
+@alert-with-description-no-icon-padding-vertical: @padding-md - 1px;
+@alert-with-description-padding-vertical: @padding-md - 1px;
+@alert-with-description-padding: @alert-with-description-padding-vertical 15px
+ @alert-with-description-no-icon-padding-vertical @alert-with-description-icon-size;
+@alert-icon-top: 8px + @font-size-base * (@line-height-base / 2) - (@font-size-base / 2);
+@alert-with-description-icon-size: 24px;
+
+// List
+// ---
+@list-header-background: transparent;
+@list-footer-background: transparent;
+@list-empty-text-padding: @padding-md;
+@list-item-padding: @padding-sm 0;
+@list-item-padding-sm: @padding-xs @padding-md;
+@list-item-padding-lg: 16px 24px;
+@list-item-meta-margin-bottom: @padding-md;
+@list-item-meta-avatar-margin-right: @padding-md;
+@list-item-meta-title-margin-bottom: @padding-sm;
+@list-customize-card-bg: @component-background;
+@list-item-meta-description-font-size: @font-size-base;
+
+// Statistic
+// ---
+@statistic-title-font-size: @font-size-base;
+@statistic-content-font-size: 24px;
+@statistic-unit-font-size: 24px;
+@statistic-font-family: @font-family;
+
+// Drawer
+// ---
+@drawer-header-padding: @padding-md @padding-lg;
+@drawer-body-padding: @padding-lg;
+@drawer-bg: @component-background;
+@drawer-footer-padding-vertical: @modal-footer-padding-vertical;
+@drawer-footer-padding-horizontal: @modal-footer-padding-horizontal;
+@drawer-header-close-size: 56px;
+@drawer-title-font-size: @font-size-lg;
+@drawer-title-line-height: 22px;
+
+// Timeline
+// ---
+@timeline-width: 2px;
+@timeline-color: @border-color-split;
+@timeline-dot-border-width: 2px;
+@timeline-dot-color: @primary-color;
+@timeline-dot-bg: @component-background;
+@timeline-item-padding-bottom: 20px;
+
+// Typography
+// ---
+@typography-title-font-weight: 600;
+@typography-title-margin-top: 1.2em;
+@typography-title-margin-bottom: 0.5em;
+
+// Upload
+// ---
+@upload-actions-color: @text-color-secondary;
+
+// Steps
+// ---
+@process-tail-color: @border-color-split;
+@steps-nav-arrow-color: fade(@black, 25%);
+@steps-background: @component-background;
+@steps-icon-size: 32px;
+@steps-icon-custom-size: @steps-icon-size;
+@steps-icon-custom-top: 0px;
+@steps-icon-custom-font-size: 24px;
+@steps-icon-top: -0.5px;
+@steps-icon-font-size: @font-size-lg;
+@steps-icon-margin: 0 8px 0 0;
+@steps-title-line-height: @height-base;
+@steps-small-icon-size: 24px;
+@steps-small-icon-margin: 0 8px 0 0;
+@steps-dot-size: 8px;
+@steps-dot-top: 2px;
+@steps-current-dot-size: 10px;
+@steps-description-max-width: 140px;
+@steps-nav-content-max-width: auto;
+@steps-vertical-icon-width: 16px;
+@steps-vertical-tail-width: 16px;
+@steps-vertical-tail-width-sm: 12px;
+
+// Notification
+// ---
+@notification-bg: @component-background;
+@notification-padding-vertical: 16px;
+@notification-padding-horizontal: 24px;
+
+// Result
+// ---
+@result-title-font-size: 24px;
+@result-subtitle-font-size: @font-size-base;
+@result-icon-font-size: 72px;
+@result-extra-margin: 24px 0 0 0;
+
+// Image
+// ---
+@image-size-base: 48px;
+@image-font-size-base: 24px;
+@image-bg: #f5f5f5;
+@image-color: #fff;
+@image-mask-font-size: 16px;
+@image-preview-operation-size: 18px;
+@image-preview-operation-color: @text-color-dark;
+@image-preview-operation-disabled-color: fade(@image-preview-operation-color, 25%);
+
+// Segmented
+// ---
+@segmented-bg: fade(@black, 4%);
+@segmented-hover-bg: fade(@black, 6%);
+@segmented-selected-bg: @white;
+@segmented-label-color: fade(@black, 65%);
+@segmented-label-hover-color: #262626;
diff --git a/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/variable.less b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/variable.less
new file mode 100644
index 0000000..6c70293
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/less-nested/ant-design/variable.less
@@ -0,0 +1,4 @@
+@root-entry-name: variable;
+
+@import './themes/variable.less';
+@import './core/index';
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/main.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/main.scss
index 8d8cc42..c906f71 100644
--- a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/main.scss
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/main.scss
@@ -1,14 +1,5 @@
$primaryColor: brown;
-:root {
- --main-bg-color: brown;
- --h1: 26px;
- --h2: 22px;
- --h3: 18px;
- --text-base: 16px;
- --carousel-bg: var(--main-bg-color);
-}
-
.one {
color: white;
background-color: var(--main-bg-color);
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/_bootstrap-compass.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/_bootstrap-compass.scss
new file mode 100644
index 0000000..8fbc3cd
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/_bootstrap-compass.scss
@@ -0,0 +1,9 @@
+@function twbs-font-path($path) {
+ @return font-url($path, true);
+}
+
+@function twbs-image-path($path) {
+ @return image-url($path, true);
+}
+
+$bootstrap-sass-asset-helper: true;
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/_bootstrap-mincer.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/_bootstrap-mincer.scss
new file mode 100644
index 0000000..0c4655e
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/_bootstrap-mincer.scss
@@ -0,0 +1,19 @@
+// Mincer asset helper functions
+//
+// This must be imported into a .css.ejs.scss file.
+// Then, <% %>-interpolations will be parsed as strings by Sass, and evaluated by EJS after Sass compilation.
+
+
+@function twbs-font-path($path) {
+ // do something like following
+ // from "path/to/font.ext#suffix" to "<%- asset_path(path/to/font.ext)) + #suffix %>"
+ // from "path/to/font.ext?#suffix" to "<%- asset_path(path/to/font.ext)) + ?#suffix %>"
+ // or from "path/to/font.ext" just "<%- asset_path(path/to/font.ext)) %>"
+ @return "<%- asset_path("#{$path}".replace(/[#?].*$/, '')) + "#{$path}".replace(/(^[^#?]*)([#?]?.*$)/, '$2') %>";
+}
+
+@function twbs-image-path($file) {
+ @return "<%- asset_path("#{$file}") %>";
+}
+
+$bootstrap-sass-asset-helper: true;
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/_bootstrap-sprockets.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/_bootstrap-sprockets.scss
new file mode 100644
index 0000000..9fffc1e
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/_bootstrap-sprockets.scss
@@ -0,0 +1,9 @@
+@function twbs-font-path($path) {
+ @return font-path($path);
+}
+
+@function twbs-image-path($path) {
+ @return image-path($path);
+}
+
+$bootstrap-sass-asset-helper: true;
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/_bootstrap.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/_bootstrap.scss
new file mode 100644
index 0000000..89e3855
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/_bootstrap.scss
@@ -0,0 +1,56 @@
+/*!
+ * Bootstrap v3.4.1 (https://getbootstrap.com/)
+ * Copyright 2011-2019 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+// Core variables and mixins
+@import "bootstrap/variables";
+@import "bootstrap/mixins";
+
+// Reset and dependencies
+@import "bootstrap/normalize";
+@import "bootstrap/print";
+@import "bootstrap/glyphicons";
+
+// Core CSS
+@import "bootstrap/scaffolding";
+@import "bootstrap/type";
+@import "bootstrap/code";
+@import "bootstrap/grid";
+@import "bootstrap/tables";
+@import "bootstrap/forms";
+@import "bootstrap/buttons";
+
+// Components
+@import "bootstrap/component-animations";
+@import "bootstrap/dropdowns";
+@import "bootstrap/button-groups";
+@import "bootstrap/input-groups";
+@import "bootstrap/navs";
+@import "bootstrap/navbar";
+@import "bootstrap/breadcrumbs";
+@import "bootstrap/pagination";
+@import "bootstrap/pager";
+@import "bootstrap/labels";
+@import "bootstrap/badges";
+@import "bootstrap/jumbotron";
+@import "bootstrap/thumbnails";
+@import "bootstrap/alerts";
+@import "bootstrap/progress-bars";
+@import "bootstrap/media";
+@import "bootstrap/list-group";
+@import "bootstrap/panels";
+@import "bootstrap/responsive-embed";
+@import "bootstrap/wells";
+@import "bootstrap/close";
+
+// Components w/ JavaScript
+@import "bootstrap/modals";
+@import "bootstrap/tooltip";
+@import "bootstrap/popovers";
+@import "bootstrap/carousel";
+
+// Utility classes
+@import "bootstrap/utilities";
+@import "bootstrap/responsive-utilities";
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_alerts.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_alerts.scss
new file mode 100644
index 0000000..f9e69bd
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_alerts.scss
@@ -0,0 +1,73 @@
+//
+// Alerts
+// --------------------------------------------------
+
+
+// Base styles
+// -------------------------
+
+.alert {
+ padding: $alert-padding;
+ margin-bottom: $line-height-computed;
+ border: 1px solid transparent;
+ border-radius: $alert-border-radius;
+
+ // Headings for larger alerts
+ h4 {
+ margin-top: 0;
+ color: inherit; // Specified for the h4 to prevent conflicts of changing $headings-color
+ }
+
+ // Provide class for links that match alerts
+ .alert-link {
+ font-weight: $alert-link-font-weight;
+ }
+
+ // Improve alignment and spacing of inner content
+ > p,
+ > ul {
+ margin-bottom: 0;
+ }
+
+ > p + p {
+ margin-top: 5px;
+ }
+}
+
+// Dismissible alerts
+//
+// Expand the right padding and account for the close button's positioning.
+
+// The misspelled .alert-dismissable was deprecated in 3.2.0.
+.alert-dismissable,
+.alert-dismissible {
+ padding-right: ($alert-padding + 20);
+
+ // Adjust close link position
+ .close {
+ position: relative;
+ top: -2px;
+ right: -21px;
+ color: inherit;
+ }
+}
+
+// Alternate styles
+//
+// Generate contextual modifier classes for colorizing the alert.
+
+.alert-success {
+ @include alert-variant($alert-success-bg, $alert-success-border, $alert-success-text);
+}
+
+.alert-info {
+ @include alert-variant($alert-info-bg, $alert-info-border, $alert-info-text);
+}
+
+.alert-warning {
+ @include alert-variant($alert-warning-bg, $alert-warning-border, $alert-warning-text);
+}
+
+.alert-danger {
+ @include alert-variant($alert-danger-bg, $alert-danger-border, $alert-danger-text);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_badges.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_badges.scss
new file mode 100644
index 0000000..44d5dd6
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_badges.scss
@@ -0,0 +1,68 @@
+//
+// Badges
+// --------------------------------------------------
+
+
+// Base class
+.badge {
+ display: inline-block;
+ min-width: 10px;
+ padding: 3px 7px;
+ font-size: $font-size-small;
+ font-weight: $badge-font-weight;
+ line-height: $badge-line-height;
+ color: $badge-color;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ background-color: $badge-bg;
+ border-radius: $badge-border-radius;
+
+ // Empty badges collapse automatically (not available in IE8)
+ &:empty {
+ display: none;
+ }
+
+ // Quick fix for badges in buttons
+ .btn & {
+ position: relative;
+ top: -1px;
+ }
+
+ .btn-xs &,
+ .btn-group-xs > .btn & {
+ top: 0;
+ padding: 1px 5px;
+ }
+
+ // [converter] extracted a& to a.badge
+
+ // Account for badges in navs
+ .list-group-item.active > &,
+ .nav-pills > .active > a > & {
+ color: $badge-active-color;
+ background-color: $badge-active-bg;
+ }
+
+ .list-group-item > & {
+ float: right;
+ }
+
+ .list-group-item > & + & {
+ margin-right: 5px;
+ }
+
+ .nav-pills > li > a > & {
+ margin-left: 3px;
+ }
+}
+
+// Hover state, but only for links
+a.badge {
+ &:hover,
+ &:focus {
+ color: $badge-link-hover-color;
+ text-decoration: none;
+ cursor: pointer;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_breadcrumbs.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_breadcrumbs.scss
new file mode 100644
index 0000000..67e39d9
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_breadcrumbs.scss
@@ -0,0 +1,28 @@
+//
+// Breadcrumbs
+// --------------------------------------------------
+
+
+.breadcrumb {
+ padding: $breadcrumb-padding-vertical $breadcrumb-padding-horizontal;
+ margin-bottom: $line-height-computed;
+ list-style: none;
+ background-color: $breadcrumb-bg;
+ border-radius: $border-radius-base;
+
+ > li {
+ display: inline-block;
+
+ + li:before {
+ padding: 0 5px;
+ color: $breadcrumb-color;
+ // [converter] Workaround for https://github.com/sass/libsass/issues/1115
+ $nbsp: "\00a0";
+ content: "#{$breadcrumb-separator}#{$nbsp}"; // Unicode space added since inline-block means non-collapsing white-space
+ }
+ }
+
+ > .active {
+ color: $breadcrumb-active-color;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_button-groups.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_button-groups.scss
new file mode 100644
index 0000000..6a62faf
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_button-groups.scss
@@ -0,0 +1,244 @@
+//
+// Button groups
+// --------------------------------------------------
+
+// Make the div behave like a button
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle; // match .btn alignment given font-size hack above
+ > .btn {
+ position: relative;
+ float: left;
+ // Bring the "active" button to the front
+ &:hover,
+ &:focus,
+ &:active,
+ &.active {
+ z-index: 2;
+ }
+ }
+}
+
+// Prevent double borders when buttons are next to each other
+.btn-group {
+ .btn + .btn,
+ .btn + .btn-group,
+ .btn-group + .btn,
+ .btn-group + .btn-group {
+ margin-left: -1px;
+ }
+}
+
+// Optional: Group multiple button groups together for a toolbar
+.btn-toolbar {
+ margin-left: -5px; // Offset the first child's margin
+ @include clearfix;
+
+ .btn,
+ .btn-group,
+ .input-group {
+ float: left;
+ }
+ > .btn,
+ > .btn-group,
+ > .input-group {
+ margin-left: 5px;
+ }
+}
+
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+ border-radius: 0;
+}
+
+// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match
+.btn-group > .btn:first-child {
+ margin-left: 0;
+ &:not(:last-child):not(.dropdown-toggle) {
+ @include border-right-radius(0);
+ }
+}
+// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+ @include border-left-radius(0);
+}
+
+// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)
+.btn-group > .btn-group {
+ float: left;
+}
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group > .btn-group:first-child:not(:last-child) {
+ > .btn:last-child,
+ > .dropdown-toggle {
+ @include border-right-radius(0);
+ }
+}
+.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ @include border-left-radius(0);
+}
+
+// On active and open, don't show outline
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline: 0;
+}
+
+
+// Sizing
+//
+// Remix the default button sizing classes into new ones for easier manipulation.
+
+.btn-group-xs > .btn { @extend .btn-xs; }
+.btn-group-sm > .btn { @extend .btn-sm; }
+.btn-group-lg > .btn { @extend .btn-lg; }
+
+
+// Split button dropdowns
+// ----------------------
+
+// Give the line between buttons some depth
+.btn-group > .btn + .dropdown-toggle {
+ padding-right: 8px;
+ padding-left: 8px;
+}
+.btn-group > .btn-lg + .dropdown-toggle {
+ padding-right: 12px;
+ padding-left: 12px;
+}
+
+// The clickable button for toggling the menu
+// Remove the gradient and set the same inset shadow as the :active state
+.btn-group.open .dropdown-toggle {
+ @include box-shadow(inset 0 3px 5px rgba(0, 0, 0, .125));
+
+ // Show no shadow for `.btn-link` since it has no other button styles.
+ &.btn-link {
+ @include box-shadow(none);
+ }
+}
+
+
+// Reposition the caret
+.btn .caret {
+ margin-left: 0;
+}
+// Carets in other button sizes
+.btn-lg .caret {
+ border-width: $caret-width-large $caret-width-large 0;
+ border-bottom-width: 0;
+}
+// Upside down carets for .dropup
+.dropup .btn-lg .caret {
+ border-width: 0 $caret-width-large $caret-width-large;
+}
+
+
+// Vertical button groups
+// ----------------------
+
+.btn-group-vertical {
+ > .btn,
+ > .btn-group,
+ > .btn-group > .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ max-width: 100%;
+ }
+
+ // Clear floats so dropdown menus can be properly placed
+ > .btn-group {
+ @include clearfix;
+ > .btn {
+ float: none;
+ }
+ }
+
+ > .btn + .btn,
+ > .btn + .btn-group,
+ > .btn-group + .btn,
+ > .btn-group + .btn-group {
+ margin-top: -1px;
+ margin-left: 0;
+ }
+}
+
+.btn-group-vertical > .btn {
+ &:not(:first-child):not(:last-child) {
+ border-radius: 0;
+ }
+ &:first-child:not(:last-child) {
+ @include border-top-radius($btn-border-radius-base);
+ @include border-bottom-radius(0);
+ }
+ &:last-child:not(:first-child) {
+ @include border-top-radius(0);
+ @include border-bottom-radius($btn-border-radius-base);
+ }
+}
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+ border-radius: 0;
+}
+.btn-group-vertical > .btn-group:first-child:not(:last-child) {
+ > .btn:last-child,
+ > .dropdown-toggle {
+ @include border-bottom-radius(0);
+ }
+}
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+ @include border-top-radius(0);
+}
+
+
+// Justified button groups
+// ----------------------
+
+.btn-group-justified {
+ display: table;
+ width: 100%;
+ table-layout: fixed;
+ border-collapse: separate;
+ > .btn,
+ > .btn-group {
+ display: table-cell;
+ float: none;
+ width: 1%;
+ }
+ > .btn-group .btn {
+ width: 100%;
+ }
+
+ > .btn-group .dropdown-menu {
+ left: auto;
+ }
+}
+
+
+// Checkbox and radio options
+//
+// In order to support the browser's form validation feedback, powered by the
+// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
+// `display: none;` or `visibility: hidden;` as that also hides the popover.
+// Simply visually hiding the inputs via `opacity` would leave them clickable in
+// certain cases which is prevented by using `clip` and `pointer-events`.
+// This way, we ensure a DOM element is visible to position the popover from.
+//
+// See https://github.com/twbs/bootstrap/pull/12794 and
+// https://github.com/twbs/bootstrap/pull/14559 for more information.
+
+[data-toggle="buttons"] {
+ > .btn,
+ > .btn-group > .btn {
+ input[type="radio"],
+ input[type="checkbox"] {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_buttons.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_buttons.scss
new file mode 100644
index 0000000..62962d7
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_buttons.scss
@@ -0,0 +1,168 @@
+//
+// Buttons
+// --------------------------------------------------
+
+
+// Base styles
+// --------------------------------------------------
+
+.btn {
+ display: inline-block;
+ margin-bottom: 0; // For input.btn
+ font-weight: $btn-font-weight;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: middle;
+ touch-action: manipulation;
+ cursor: pointer;
+ background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
+ border: 1px solid transparent;
+ @include button-size($padding-base-vertical, $padding-base-horizontal, $font-size-base, $line-height-base, $btn-border-radius-base);
+ @include user-select(none);
+
+ &,
+ &:active,
+ &.active {
+ &:focus,
+ &.focus {
+ @include tab-focus;
+ }
+ }
+
+ &:hover,
+ &:focus,
+ &.focus {
+ color: $btn-default-color;
+ text-decoration: none;
+ }
+
+ &:active,
+ &.active {
+ background-image: none;
+ outline: 0;
+ @include box-shadow(inset 0 3px 5px rgba(0, 0, 0, .125));
+ }
+
+ &.disabled,
+ &[disabled],
+ fieldset[disabled] & {
+ cursor: $cursor-disabled;
+ @include opacity(.65);
+ @include box-shadow(none);
+ }
+
+ // [converter] extracted a& to a.btn
+}
+
+a.btn {
+ &.disabled,
+ fieldset[disabled] & {
+ pointer-events: none; // Future-proof disabling of clicks on `
` elements
+ }
+}
+
+
+// Alternate buttons
+// --------------------------------------------------
+
+.btn-default {
+ @include button-variant($btn-default-color, $btn-default-bg, $btn-default-border);
+}
+.btn-primary {
+ @include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border);
+}
+// Success appears as green
+.btn-success {
+ @include button-variant($btn-success-color, $btn-success-bg, $btn-success-border);
+}
+// Info appears as blue-green
+.btn-info {
+ @include button-variant($btn-info-color, $btn-info-bg, $btn-info-border);
+}
+// Warning appears as orange
+.btn-warning {
+ @include button-variant($btn-warning-color, $btn-warning-bg, $btn-warning-border);
+}
+// Danger and error appear as red
+.btn-danger {
+ @include button-variant($btn-danger-color, $btn-danger-bg, $btn-danger-border);
+}
+
+
+// Link buttons
+// -------------------------
+
+// Make a button look and behave like a link
+.btn-link {
+ font-weight: 400;
+ color: $link-color;
+ border-radius: 0;
+
+ &,
+ &:active,
+ &.active,
+ &[disabled],
+ fieldset[disabled] & {
+ background-color: transparent;
+ @include box-shadow(none);
+ }
+ &,
+ &:hover,
+ &:focus,
+ &:active {
+ border-color: transparent;
+ }
+ &:hover,
+ &:focus {
+ color: $link-hover-color;
+ text-decoration: $link-hover-decoration;
+ background-color: transparent;
+ }
+ &[disabled],
+ fieldset[disabled] & {
+ &:hover,
+ &:focus {
+ color: $btn-link-disabled-color;
+ text-decoration: none;
+ }
+ }
+}
+
+
+// Button Sizes
+// --------------------------------------------------
+
+.btn-lg {
+ // line-height: ensure even-numbered height of button next to large input
+ @include button-size($padding-large-vertical, $padding-large-horizontal, $font-size-large, $line-height-large, $btn-border-radius-large);
+}
+.btn-sm {
+ // line-height: ensure proper height of button next to small input
+ @include button-size($padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small, $btn-border-radius-small);
+}
+.btn-xs {
+ @include button-size($padding-xs-vertical, $padding-xs-horizontal, $font-size-small, $line-height-small, $btn-border-radius-small);
+}
+
+
+// Block button
+// --------------------------------------------------
+
+.btn-block {
+ display: block;
+ width: 100%;
+}
+
+// Vertically space out multiple block buttons
+.btn-block + .btn-block {
+ margin-top: 5px;
+}
+
+// Specificity overrides
+input[type="submit"],
+input[type="reset"],
+input[type="button"] {
+ &.btn-block {
+ width: 100%;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_carousel.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_carousel.scss
new file mode 100644
index 0000000..684360f
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_carousel.scss
@@ -0,0 +1,272 @@
+@use "sass:math";
+//
+// Carousel
+// --------------------------------------------------
+
+
+// Wrapper for the slide container and indicators
+.carousel {
+ position: relative;
+}
+
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+
+ > .item {
+ position: relative;
+ display: none;
+ @include transition(.6s ease-in-out left);
+
+ // Account for jankitude on images
+ > img,
+ > a > img {
+ @include img-responsive;
+ line-height: 1;
+ }
+
+ // WebKit CSS3 transforms for supported devices
+ @media all and (transform-3d), (-webkit-transform-3d) {
+ @include transition-transform(0.6s ease-in-out);
+ @include backface-visibility(hidden);
+ @include perspective(1000px);
+
+ &.next,
+ &.active.right {
+ @include translate3d(100%, 0, 0);
+ left: 0;
+ }
+ &.prev,
+ &.active.left {
+ @include translate3d(-100%, 0, 0);
+ left: 0;
+ }
+ &.next.left,
+ &.prev.right,
+ &.active {
+ @include translate3d(0, 0, 0);
+ left: 0;
+ }
+ }
+ }
+
+ > .active,
+ > .next,
+ > .prev {
+ display: block;
+ }
+
+ > .active {
+ left: 0;
+ }
+
+ > .next,
+ > .prev {
+ position: absolute;
+ top: 0;
+ width: 100%;
+ }
+
+ > .next {
+ left: 100%;
+ }
+ > .prev {
+ left: -100%;
+ }
+ > .next.left,
+ > .prev.right {
+ left: 0;
+ }
+
+ > .active.left {
+ left: -100%;
+ }
+ > .active.right {
+ left: 100%;
+ }
+
+}
+
+// Left/right controls for nav
+// ---------------------------
+
+.carousel-control {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: $carousel-control-width;
+ font-size: $carousel-control-font-size;
+ color: $carousel-control-color;
+ text-align: center;
+ text-shadow: $carousel-text-shadow;
+ background-color: rgba(0, 0, 0, 0); // Fix IE9 click-thru bug
+ @include opacity($carousel-control-opacity);
+ // We can't have this transition here because WebKit cancels the carousel
+ // animation if you trip this while in the middle of another animation.
+
+ // Set gradients for backgrounds
+ &.left {
+ @include gradient-horizontal($start-color: rgba(0, 0, 0, .5), $end-color: rgba(0, 0, 0, .0001));
+ }
+ &.right {
+ right: 0;
+ left: auto;
+ @include gradient-horizontal($start-color: rgba(0, 0, 0, .0001), $end-color: rgba(0, 0, 0, .5));
+ }
+
+ // Hover/focus state
+ &:hover,
+ &:focus {
+ color: $carousel-control-color;
+ text-decoration: none;
+ outline: 0;
+ @include opacity(.9);
+ }
+
+ // Toggles
+ .icon-prev,
+ .icon-next,
+ .glyphicon-chevron-left,
+ .glyphicon-chevron-right {
+ position: absolute;
+ top: 50%;
+ z-index: 5;
+ display: inline-block;
+ margin-top: -10px;
+ }
+ .icon-prev,
+ .glyphicon-chevron-left {
+ left: 50%;
+ margin-left: -10px;
+ }
+ .icon-next,
+ .glyphicon-chevron-right {
+ right: 50%;
+ margin-right: -10px;
+ }
+ .icon-prev,
+ .icon-next {
+ width: 20px;
+ height: 20px;
+ font-family: serif;
+ line-height: 1;
+ }
+
+ .icon-prev {
+ &:before {
+ content: "\2039";// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)
+ }
+ }
+ .icon-next {
+ &:before {
+ content: "\203a";// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)
+ }
+ }
+}
+
+// Optional indicator pips
+//
+// Add an unordered list with the following class and add a list item for each
+// slide your carousel holds.
+
+.carousel-indicators {
+ position: absolute;
+ bottom: 10px;
+ left: 50%;
+ z-index: 15;
+ width: 60%;
+ padding-left: 0;
+ margin-left: -30%;
+ text-align: center;
+ list-style: none;
+
+ li {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ margin: 1px;
+ text-indent: -999px;
+ cursor: pointer;
+ // IE8-9 hack for event handling
+ //
+ // Internet Explorer 8-9 does not support clicks on elements without a set
+ // `background-color`. We cannot use `filter` since that's not viewed as a
+ // background color by the browser. Thus, a hack is needed.
+ // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer
+ //
+ // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we
+ // set alpha transparency for the best results possible.
+ background-color: #000 \9; // IE8
+ background-color: rgba(0, 0, 0, 0); // IE9
+
+ border: 1px solid $carousel-indicator-border-color;
+ border-radius: 10px;
+ }
+
+ .active {
+ width: 12px;
+ height: 12px;
+ margin: 0;
+ background-color: $carousel-indicator-active-bg;
+ }
+}
+
+// Optional captions
+// -----------------------------
+// Hidden by default for smaller viewports
+.carousel-caption {
+ position: absolute;
+ right: 15%;
+ bottom: 20px;
+ left: 15%;
+ z-index: 10;
+ padding-top: 20px;
+ padding-bottom: 20px;
+ color: $carousel-caption-color;
+ text-align: center;
+ text-shadow: $carousel-text-shadow;
+
+ & .btn {
+ text-shadow: none; // No shadow for button elements in carousel-caption
+ }
+}
+
+
+// Scale up controls for tablets and up
+@media screen and (min-width: $screen-sm-min) {
+
+ // Scale up the controls a smidge
+ .carousel-control {
+ .glyphicon-chevron-left,
+ .glyphicon-chevron-right,
+ .icon-prev,
+ .icon-next {
+ width: ($carousel-control-font-size * 1.5);
+ height: ($carousel-control-font-size * 1.5);
+ margin-top: math.div($carousel-control-font-size, -2);
+ font-size: ($carousel-control-font-size * 1.5);
+ }
+ .glyphicon-chevron-left,
+ .icon-prev {
+ margin-left: math.div($carousel-control-font-size, -2);
+ }
+ .glyphicon-chevron-right,
+ .icon-next {
+ margin-right: math.div($carousel-control-font-size, -2);
+ }
+ }
+
+ // Show and left align the captions
+ .carousel-caption {
+ right: 20%;
+ left: 20%;
+ padding-bottom: 30px;
+ }
+
+ // Move up the indicators
+ .carousel-indicators {
+ bottom: 20px;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_close.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_close.scss
new file mode 100644
index 0000000..a858a8f
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_close.scss
@@ -0,0 +1,37 @@
+//
+// Close icons
+// --------------------------------------------------
+
+
+.close {
+ float: right;
+ font-size: ($font-size-base * 1.5);
+ font-weight: $close-font-weight;
+ line-height: 1;
+ color: $close-color;
+ text-shadow: $close-text-shadow;
+ @include opacity(.2);
+
+ &:hover,
+ &:focus {
+ color: $close-color;
+ text-decoration: none;
+ cursor: pointer;
+ @include opacity(.5);
+ }
+
+ // [converter] extracted button& to button.close
+}
+
+// Additional properties for button version
+// iOS requires the button element instead of an anchor tag.
+// If you want the anchor version, it requires `href="#"`.
+// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
+button.close {
+ padding: 0;
+ cursor: pointer;
+ background: transparent;
+ border: 0;
+ -webkit-appearance: none;
+ appearance: none;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_code.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_code.scss
new file mode 100644
index 0000000..6299ddb
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_code.scss
@@ -0,0 +1,70 @@
+@use "sass:math";
+//
+// Code (inline and block)
+// --------------------------------------------------
+
+
+// Inline and block code styles
+code,
+kbd,
+pre,
+samp {
+ font-family: $font-family-monospace;
+}
+
+// Inline code
+code {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: $code-color;
+ background-color: $code-bg;
+ border-radius: $border-radius-base;
+}
+
+// User input typically entered via keyboard
+kbd {
+ padding: 2px 4px;
+ font-size: 90%;
+ color: $kbd-color;
+ background-color: $kbd-bg;
+ border-radius: $border-radius-small;
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
+
+ kbd {
+ padding: 0;
+ font-size: 100%;
+ font-weight: 700;
+ box-shadow: none;
+ }
+}
+
+// Blocks of code
+pre {
+ display: block;
+ padding: math.div(($line-height-computed - 1), 2);
+ margin: 0 0 math.div($line-height-computed, 2);
+ font-size: ($font-size-base - 1); // 14px to 13px
+ line-height: $line-height-base;
+ color: $pre-color;
+ word-break: break-all;
+ word-wrap: break-word;
+ background-color: $pre-bg;
+ border: 1px solid $pre-border-color;
+ border-radius: $border-radius-base;
+
+ // Account for some code outputs that place code tags in pre tags
+ code {
+ padding: 0;
+ font-size: inherit;
+ color: inherit;
+ white-space: pre-wrap;
+ background-color: transparent;
+ border-radius: 0;
+ }
+}
+
+// Enable scrollable blocks of code
+.pre-scrollable {
+ max-height: $pre-scrollable-max-height;
+ overflow-y: scroll;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_component-animations.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_component-animations.scss
new file mode 100644
index 0000000..ca4d6b0
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_component-animations.scss
@@ -0,0 +1,38 @@
+//
+// Component animations
+// --------------------------------------------------
+
+// Heads up!
+//
+// We don't use the `.opacity()` mixin here since it causes a bug with text
+// fields in IE7-8. Source: https://github.com/twbs/bootstrap/pull/3552.
+
+.fade {
+ opacity: 0;
+ @include transition(opacity .15s linear);
+
+ &.in {
+ opacity: 1;
+ }
+}
+
+.collapse {
+ display: none;
+
+ &.in { display: block; }
+ // [converter] extracted tr&.in to tr.collapse.in
+ // [converter] extracted tbody&.in to tbody.collapse.in
+}
+
+tr.collapse.in { display: table-row; }
+
+tbody.collapse.in { display: table-row-group; }
+
+.collapsing {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ @include transition-property(height, visibility);
+ @include transition-duration(.35s);
+ @include transition-timing-function(ease);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_dropdowns.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_dropdowns.scss
new file mode 100644
index 0000000..0a5898a
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_dropdowns.scss
@@ -0,0 +1,213 @@
+//
+// Dropdown menus
+// --------------------------------------------------
+
+
+// Dropdown arrow/caret
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-left: 2px;
+ vertical-align: middle;
+ border-top: $caret-width-base dashed;
+ border-top: $caret-width-base solid \9; // IE8
+ border-right: $caret-width-base solid transparent;
+ border-left: $caret-width-base solid transparent;
+}
+
+// The dropdown wrapper (div)
+.dropup,
+.dropdown {
+ position: relative;
+}
+
+// Prevent the focus on the dropdown toggle when closing dropdowns
+.dropdown-toggle:focus {
+ outline: 0;
+}
+
+// The dropdown menu (ul)
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: $zindex-dropdown;
+ display: none; // none by default, but block on "open" of the menu
+ float: left;
+ min-width: 160px;
+ padding: 5px 0;
+ margin: 2px 0 0; // override default ul
+ font-size: $font-size-base;
+ text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
+ list-style: none;
+ background-color: $dropdown-bg;
+ background-clip: padding-box;
+ border: 1px solid $dropdown-fallback-border; // IE8 fallback
+ border: 1px solid $dropdown-border;
+ border-radius: $border-radius-base;
+ @include box-shadow(0 6px 12px rgba(0, 0, 0, .175));
+
+ // Aligns the dropdown menu to right
+ //
+ // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`
+ &.pull-right {
+ right: 0;
+ left: auto;
+ }
+
+ // Dividers (basically an hr) within the dropdown
+ .divider {
+ @include nav-divider($dropdown-divider-bg);
+ }
+
+ // Links within the dropdown menu
+ > li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: 400;
+ line-height: $line-height-base;
+ color: $dropdown-link-color;
+ white-space: nowrap; // prevent links from randomly breaking onto new lines
+
+ &:hover,
+ &:focus {
+ color: $dropdown-link-hover-color;
+ text-decoration: none;
+ background-color: $dropdown-link-hover-bg;
+ }
+ }
+}
+
+// Active state
+.dropdown-menu > .active > a {
+ &,
+ &:hover,
+ &:focus {
+ color: $dropdown-link-active-color;
+ text-decoration: none;
+ background-color: $dropdown-link-active-bg;
+ outline: 0;
+ }
+}
+
+// Disabled state
+//
+// Gray out text and ensure the hover/focus state remains gray
+
+.dropdown-menu > .disabled > a {
+ &,
+ &:hover,
+ &:focus {
+ color: $dropdown-link-disabled-color;
+ }
+
+ // Nuke hover/focus effects
+ &:hover,
+ &:focus {
+ text-decoration: none;
+ cursor: $cursor-disabled;
+ background-color: transparent;
+ background-image: none; // Remove CSS gradient
+ @include reset-filter;
+ }
+}
+
+// Open state for the dropdown
+.open {
+ // Show the menu
+ > .dropdown-menu {
+ display: block;
+ }
+
+ // Remove the outline when :focus is triggered
+ > a {
+ outline: 0;
+ }
+}
+
+// Menu positioning
+//
+// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown
+// menu with the parent.
+.dropdown-menu-right {
+ right: 0;
+ left: auto; // Reset the default from `.dropdown-menu`
+}
+// With v3, we enabled auto-flipping if you have a dropdown within a right
+// aligned nav component. To enable the undoing of that, we provide an override
+// to restore the default dropdown menu alignment.
+//
+// This is only for left-aligning a dropdown menu within a `.navbar-right` or
+// `.pull-right` nav component.
+.dropdown-menu-left {
+ right: auto;
+ left: 0;
+}
+
+// Dropdown section headers
+.dropdown-header {
+ display: block;
+ padding: 3px 20px;
+ font-size: $font-size-small;
+ line-height: $line-height-base;
+ color: $dropdown-header-color;
+ white-space: nowrap; // as with > li > a
+}
+
+// Backdrop to catch body clicks on mobile, etc.
+.dropdown-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: ($zindex-dropdown - 10);
+}
+
+// Right aligned dropdowns
+.pull-right > .dropdown-menu {
+ right: 0;
+ left: auto;
+}
+
+// Allow for dropdowns to go bottom up (aka, dropup-menu)
+//
+// Just add .dropup after the standard .dropdown class and you're set, bro.
+// TODO: abstract this so that the navbar fixed styles are not placed here?
+
+.dropup,
+.navbar-fixed-bottom .dropdown {
+ // Reverse the caret
+ .caret {
+ content: "";
+ border-top: 0;
+ border-bottom: $caret-width-base dashed;
+ border-bottom: $caret-width-base solid \9; // IE8
+ }
+ // Different positioning for bottom up menu
+ .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 2px;
+ }
+}
+
+
+// Component alignment
+//
+// Reiterate per navbar.less and the modified component alignment there.
+
+@media (min-width: $grid-float-breakpoint) {
+ .navbar-right {
+ .dropdown-menu {
+ right: 0; left: auto;
+ }
+ // Necessary for overrides of the default right aligned menu.
+ // Will remove come v4 in all likelihood.
+ .dropdown-menu-left {
+ left: 0; right: auto;
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_forms.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_forms.scss
new file mode 100644
index 0000000..00951b3
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_forms.scss
@@ -0,0 +1,608 @@
+@use "sass:math";
+//
+// Forms
+// --------------------------------------------------
+
+
+// Normalize non-controls
+//
+// Restyle and baseline non-control form elements.
+
+fieldset {
+ // Chrome and Firefox set a `min-width: min-content;` on fieldsets,
+ // so we reset that to ensure it behaves more like a standard block element.
+ // See https://github.com/twbs/bootstrap/issues/12359.
+ min-width: 0;
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: $line-height-computed;
+ font-size: ($font-size-base * 1.5);
+ line-height: inherit;
+ color: $legend-color;
+ border: 0;
+ border-bottom: 1px solid $legend-border-color;
+}
+
+label {
+ display: inline-block;
+ max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)
+ margin-bottom: 5px;
+ font-weight: 700;
+}
+
+
+// Normalize form controls
+//
+// While most of our form styles require extra classes, some basic normalization
+// is required to ensure optimum display with or without those classes to better
+// address browser inconsistencies.
+
+input[type="search"] {
+ // Override content-box in Normalize (* isn't specific enough)
+ @include box-sizing(border-box);
+
+ // Search inputs in iOS
+ //
+ // This overrides the extra rounded corners on search inputs in iOS so that our
+ // `.form-control` class can properly style them. Note that this cannot simply
+ // be added to `.form-control` as it's not specific enough. For details, see
+ // https://github.com/twbs/bootstrap/issues/11586.
+ -webkit-appearance: none;
+ appearance: none;
+}
+
+// Position radios and checkboxes better
+input[type="radio"],
+input[type="checkbox"] {
+ margin: 4px 0 0;
+ margin-top: 1px \9; // IE8-9
+ line-height: normal;
+
+ // Apply same disabled cursor tweak as for inputs
+ // Some special care is needed because s don't inherit their parent's `cursor`.
+ //
+ // Note: Neither radios nor checkboxes can be readonly.
+ &[disabled],
+ &.disabled,
+ fieldset[disabled] & {
+ cursor: $cursor-disabled;
+ }
+}
+
+input[type="file"] {
+ display: block;
+}
+
+// Make range inputs behave like textual form controls
+input[type="range"] {
+ display: block;
+ width: 100%;
+}
+
+// Make multiple select elements height not fixed
+select[multiple],
+select[size] {
+ height: auto;
+}
+
+// Focus for file, radio, and checkbox
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+ @include tab-focus;
+}
+
+// Adjust output element
+output {
+ display: block;
+ padding-top: ($padding-base-vertical + 1);
+ font-size: $font-size-base;
+ line-height: $line-height-base;
+ color: $input-color;
+}
+
+
+// Common form controls
+//
+// Shared size and type resets for form controls. Apply `.form-control` to any
+// of the following form controls:
+//
+// select
+// textarea
+// input[type="text"]
+// input[type="password"]
+// input[type="datetime"]
+// input[type="datetime-local"]
+// input[type="date"]
+// input[type="month"]
+// input[type="time"]
+// input[type="week"]
+// input[type="number"]
+// input[type="email"]
+// input[type="url"]
+// input[type="search"]
+// input[type="tel"]
+// input[type="color"]
+
+.form-control {
+ display: block;
+ width: 100%;
+ height: $input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)
+ padding: $padding-base-vertical $padding-base-horizontal;
+ font-size: $font-size-base;
+ line-height: $line-height-base;
+ color: $input-color;
+ background-color: $input-bg;
+ background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
+ border: 1px solid $input-border;
+ border-radius: $input-border-radius; // Note: This has no effect on s in some browsers, due to the limited stylability of s in CSS.
+ @include box-shadow(inset 0 1px 1px rgba(0, 0, 0, .075));
+ @include transition(border-color ease-in-out .15s, box-shadow ease-in-out .15s);
+
+ // Customize the `:focus` state to imitate native WebKit styles.
+ @include form-control-focus;
+
+ // Placeholder
+ @include placeholder;
+
+ // Unstyle the caret on ``s in IE10+.
+ &::-ms-expand {
+ background-color: transparent;
+ border: 0;
+ }
+
+ // Disabled and read-only inputs
+ //
+ // HTML5 says that controls under a fieldset > legend:first-child won't be
+ // disabled if the fieldset is disabled. Due to implementation difficulty, we
+ // don't honor that edge case; we style them as disabled anyway.
+ &[disabled],
+ &[readonly],
+ fieldset[disabled] & {
+ background-color: $input-bg-disabled;
+ opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655
+ }
+
+ &[disabled],
+ fieldset[disabled] & {
+ cursor: $cursor-disabled;
+ }
+
+ // [converter] extracted textarea& to textarea.form-control
+}
+
+// Reset height for `textarea`s
+textarea.form-control {
+ height: auto;
+}
+
+
+// Special styles for iOS temporal inputs
+//
+// In Mobile Safari, setting `display: block` on temporal inputs causes the
+// text within the input to become vertically misaligned. As a workaround, we
+// set a pixel line-height that matches the given height of the input, but only
+// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848
+//
+// Note that as of 9.3, iOS doesn't support `week`.
+
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+ input[type="date"],
+ input[type="time"],
+ input[type="datetime-local"],
+ input[type="month"] {
+ &.form-control {
+ line-height: $input-height-base;
+ }
+
+ &.input-sm,
+ .input-group-sm & {
+ line-height: $input-height-small;
+ }
+
+ &.input-lg,
+ .input-group-lg & {
+ line-height: $input-height-large;
+ }
+ }
+}
+
+
+// Form groups
+//
+// Designed to help with the organization and spacing of vertical forms. For
+// horizontal forms, use the predefined grid classes.
+
+.form-group {
+ margin-bottom: $form-group-margin-bottom;
+}
+
+
+// Checkboxes and radios
+//
+// Indent the labels to position radios/checkboxes as hanging controls.
+
+.radio,
+.checkbox {
+ position: relative;
+ display: block;
+ margin-top: 10px;
+ margin-bottom: 10px;
+
+ // These are used on elements with descendants
+ &.disabled,
+ fieldset[disabled] & {
+ label {
+ cursor: $cursor-disabled;
+ }
+ }
+
+ label {
+ min-height: $line-height-computed; // Ensure the input doesn't jump when there is no text
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: 400;
+ cursor: pointer;
+ }
+}
+.radio input[type="radio"],
+.radio-inline input[type="radio"],
+.checkbox input[type="checkbox"],
+.checkbox-inline input[type="checkbox"] {
+ position: absolute;
+ margin-top: 4px \9;
+ margin-left: -20px;
+}
+
+.radio + .radio,
+.checkbox + .checkbox {
+ margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing
+}
+
+// Radios and checkboxes on same line
+.radio-inline,
+.checkbox-inline {
+ position: relative;
+ display: inline-block;
+ padding-left: 20px;
+ margin-bottom: 0;
+ font-weight: 400;
+ vertical-align: middle;
+ cursor: pointer;
+
+ // These are used directly on s
+ &.disabled,
+ fieldset[disabled] & {
+ cursor: $cursor-disabled;
+ }
+}
+.radio-inline + .radio-inline,
+.checkbox-inline + .checkbox-inline {
+ margin-top: 0;
+ margin-left: 10px; // space out consecutive inline controls
+}
+
+
+// Static form control text
+//
+// Apply class to a `p` element to make any string of text align with labels in
+// a horizontal form layout.
+
+.form-control-static {
+ min-height: ($line-height-computed + $font-size-base);
+ // Size it appropriately next to real form controls
+ padding-top: ($padding-base-vertical + 1);
+ padding-bottom: ($padding-base-vertical + 1);
+ // Remove default margin from `p`
+ margin-bottom: 0;
+
+ &.input-lg,
+ &.input-sm {
+ padding-right: 0;
+ padding-left: 0;
+ }
+}
+
+
+// Form control sizing
+//
+// Build on `.form-control` with modifier classes to decrease or increase the
+// height and font-size of form controls.
+//
+// The `.form-group-* form-control` variations are sadly duplicated to avoid the
+// issue documented in https://github.com/twbs/bootstrap/issues/15074.
+
+@include input-size('.input-sm', $input-height-small, $padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small, $input-border-radius-small);
+.form-group-sm {
+ .form-control {
+ height: $input-height-small;
+ padding: $padding-small-vertical $padding-small-horizontal;
+ font-size: $font-size-small;
+ line-height: $line-height-small;
+ border-radius: $input-border-radius-small;
+ }
+ select.form-control {
+ height: $input-height-small;
+ line-height: $input-height-small;
+ }
+ textarea.form-control,
+ select[multiple].form-control {
+ height: auto;
+ }
+ .form-control-static {
+ height: $input-height-small;
+ min-height: ($line-height-computed + $font-size-small);
+ padding: ($padding-small-vertical + 1) $padding-small-horizontal;
+ font-size: $font-size-small;
+ line-height: $line-height-small;
+ }
+}
+
+@include input-size('.input-lg', $input-height-large, $padding-large-vertical, $padding-large-horizontal, $font-size-large, $line-height-large, $input-border-radius-large);
+.form-group-lg {
+ .form-control {
+ height: $input-height-large;
+ padding: $padding-large-vertical $padding-large-horizontal;
+ font-size: $font-size-large;
+ line-height: $line-height-large;
+ border-radius: $input-border-radius-large;
+ }
+ select.form-control {
+ height: $input-height-large;
+ line-height: $input-height-large;
+ }
+ textarea.form-control,
+ select[multiple].form-control {
+ height: auto;
+ }
+ .form-control-static {
+ height: $input-height-large;
+ min-height: ($line-height-computed + $font-size-large);
+ padding: ($padding-large-vertical + 1) $padding-large-horizontal;
+ font-size: $font-size-large;
+ line-height: $line-height-large;
+ }
+}
+
+
+// Form control feedback states
+//
+// Apply contextual and semantic states to individual form controls.
+
+.has-feedback {
+ // Enable absolute positioning
+ position: relative;
+
+ // Ensure icons don't overlap text
+ .form-control {
+ padding-right: ($input-height-base * 1.25);
+ }
+}
+// Feedback icon (requires .glyphicon classes)
+.form-control-feedback {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 2; // Ensure icon is above input groups
+ display: block;
+ width: $input-height-base;
+ height: $input-height-base;
+ line-height: $input-height-base;
+ text-align: center;
+ pointer-events: none;
+}
+.input-lg + .form-control-feedback,
+.input-group-lg + .form-control-feedback,
+.form-group-lg .form-control + .form-control-feedback {
+ width: $input-height-large;
+ height: $input-height-large;
+ line-height: $input-height-large;
+}
+.input-sm + .form-control-feedback,
+.input-group-sm + .form-control-feedback,
+.form-group-sm .form-control + .form-control-feedback {
+ width: $input-height-small;
+ height: $input-height-small;
+ line-height: $input-height-small;
+}
+
+// Feedback states
+.has-success {
+ @include form-control-validation($state-success-text, $state-success-text, $state-success-bg);
+}
+.has-warning {
+ @include form-control-validation($state-warning-text, $state-warning-text, $state-warning-bg);
+}
+.has-error {
+ @include form-control-validation($state-danger-text, $state-danger-text, $state-danger-bg);
+}
+
+// Reposition feedback icon if input has visible label above
+.has-feedback label {
+
+ & ~ .form-control-feedback {
+ top: ($line-height-computed + 5); // Height of the `label` and its margin
+ }
+ &.sr-only ~ .form-control-feedback {
+ top: 0;
+ }
+}
+
+
+// Help text
+//
+// Apply to any element you wish to create light text for placement immediately
+// below a form control. Use for general help, formatting, or instructional text.
+
+.help-block {
+ display: block; // account for any element using help-block
+ margin-top: 5px;
+ margin-bottom: 10px;
+ color: lighten($text-color, 25%); // lighten the text some for contrast
+}
+
+
+// Inline forms
+//
+// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
+// forms begin stacked on extra small (mobile) devices and then go inline when
+// viewports reach <768px.
+//
+// Requires wrapping inputs and labels with `.form-group` for proper display of
+// default HTML form controls and our custom form controls (e.g., input groups).
+//
+// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.
+
+// [converter] extracted from `.form-inline` for libsass compatibility
+@mixin form-inline {
+
+ // Kick in the inline
+ @media (min-width: $screen-sm-min) {
+ // Inline-block all the things for "inline"
+ .form-group {
+ display: inline-block;
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ // In navbar-form, allow folks to *not* use `.form-group`
+ .form-control {
+ display: inline-block;
+ width: auto; // Prevent labels from stacking above inputs in `.form-group`
+ vertical-align: middle;
+ }
+
+ // Make static controls behave like regular ones
+ .form-control-static {
+ display: inline-block;
+ }
+
+ .input-group {
+ display: inline-table;
+ vertical-align: middle;
+
+ .input-group-addon,
+ .input-group-btn,
+ .form-control {
+ width: auto;
+ }
+ }
+
+ // Input groups need that 100% width though
+ .input-group > .form-control {
+ width: 100%;
+ }
+
+ .control-label {
+ margin-bottom: 0;
+ vertical-align: middle;
+ }
+
+ // Remove default margin on radios/checkboxes that were used for stacking, and
+ // then undo the floating of radios and checkboxes to match.
+ .radio,
+ .checkbox {
+ display: inline-block;
+ margin-top: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+
+ label {
+ padding-left: 0;
+ }
+ }
+ .radio input[type="radio"],
+ .checkbox input[type="checkbox"] {
+ position: relative;
+ margin-left: 0;
+ }
+
+ // Re-override the feedback icon.
+ .has-feedback .form-control-feedback {
+ top: 0;
+ }
+ }
+}
+// [converter] extracted as `@mixin form-inline` for libsass compatibility
+.form-inline {
+ @include form-inline;
+}
+
+
+
+// Horizontal forms
+//
+// Horizontal forms are built on grid classes and allow you to create forms with
+// labels on the left and inputs on the right.
+
+.form-horizontal {
+
+ // Consistent vertical alignment of radios and checkboxes
+ //
+ // Labels also get some reset styles, but that is scoped to a media query below.
+ .radio,
+ .checkbox,
+ .radio-inline,
+ .checkbox-inline {
+ padding-top: ($padding-base-vertical + 1); // Default padding plus a border
+ margin-top: 0;
+ margin-bottom: 0;
+ }
+ // Account for padding we're adding to ensure the alignment and of help text
+ // and other content below items
+ .radio,
+ .checkbox {
+ min-height: ($line-height-computed + ($padding-base-vertical + 1));
+ }
+
+ // Make form groups behave like rows
+ .form-group {
+ @include make-row;
+ }
+
+ // Reset spacing and right align labels, but scope to media queries so that
+ // labels on narrow viewports stack the same as a default form example.
+ @media (min-width: $screen-sm-min) {
+ .control-label {
+ padding-top: ($padding-base-vertical + 1); // Default padding plus a border
+ margin-bottom: 0;
+ text-align: right;
+ }
+ }
+
+ // Validation states
+ //
+ // Reposition the icon because it's now within a grid column and columns have
+ // `position: relative;` on them. Also accounts for the grid gutter padding.
+ .has-feedback .form-control-feedback {
+ right: floor(math.div($grid-gutter-width, 2));
+ }
+
+ // Form group sizes
+ //
+ // Quick utility class for applying `.input-lg` and `.input-sm` styles to the
+ // inputs and labels within a `.form-group`.
+ .form-group-lg {
+ @media (min-width: $screen-sm-min) {
+ .control-label {
+ padding-top: ($padding-large-vertical + 1);
+ font-size: $font-size-large;
+ }
+ }
+ }
+ .form-group-sm {
+ @media (min-width: $screen-sm-min) {
+ .control-label {
+ padding-top: ($padding-small-vertical + 1);
+ font-size: $font-size-small;
+ }
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_glyphicons.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_glyphicons.scss
new file mode 100644
index 0000000..bd5966d
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_glyphicons.scss
@@ -0,0 +1,307 @@
+//
+// Glyphicons for Bootstrap
+//
+// Since icons are fonts, they can be placed anywhere text is placed and are
+// thus automatically sized to match the surrounding child. To use, create an
+// inline element with the appropriate classes, like so:
+//
+// Star
+
+@at-root {
+ // Import the fonts
+ @font-face {
+ font-family: "Glyphicons Halflings";
+ src: url(if($bootstrap-sass-asset-helper, twbs-font-path("#{$icon-font-path}#{$icon-font-name}.eot"), "#{$icon-font-path}#{$icon-font-name}.eot"));
+ src: url(if($bootstrap-sass-asset-helper, twbs-font-path("#{$icon-font-path}#{$icon-font-name}.eot?#iefix"), "#{$icon-font-path}#{$icon-font-name}.eot?#iefix")) format("embedded-opentype"),
+ url(if($bootstrap-sass-asset-helper, twbs-font-path("#{$icon-font-path}#{$icon-font-name}.woff2"), "#{$icon-font-path}#{$icon-font-name}.woff2")) format("woff2"),
+ url(if($bootstrap-sass-asset-helper, twbs-font-path("#{$icon-font-path}#{$icon-font-name}.woff"), "#{$icon-font-path}#{$icon-font-name}.woff")) format("woff"),
+ url(if($bootstrap-sass-asset-helper, twbs-font-path("#{$icon-font-path}#{$icon-font-name}.ttf"), "#{$icon-font-path}#{$icon-font-name}.ttf")) format("truetype"),
+ url(if($bootstrap-sass-asset-helper, twbs-font-path("#{$icon-font-path}#{$icon-font-name}.svg##{$icon-font-svg-id}"), "#{$icon-font-path}#{$icon-font-name}.svg##{$icon-font-svg-id}")) format("svg");
+ }
+}
+
+// Catchall baseclass
+.glyphicon {
+ position: relative;
+ top: 1px;
+ display: inline-block;
+ font-family: "Glyphicons Halflings";
+ font-style: normal;
+ font-weight: 400;
+ line-height: 1;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+// Individual icons
+.glyphicon-asterisk { &:before { content: "\002a"; } }
+.glyphicon-plus { &:before { content: "\002b"; } }
+.glyphicon-euro,
+.glyphicon-eur { &:before { content: "\20ac"; } }
+.glyphicon-minus { &:before { content: "\2212"; } }
+.glyphicon-cloud { &:before { content: "\2601"; } }
+.glyphicon-envelope { &:before { content: "\2709"; } }
+.glyphicon-pencil { &:before { content: "\270f"; } }
+.glyphicon-glass { &:before { content: "\e001"; } }
+.glyphicon-music { &:before { content: "\e002"; } }
+.glyphicon-search { &:before { content: "\e003"; } }
+.glyphicon-heart { &:before { content: "\e005"; } }
+.glyphicon-star { &:before { content: "\e006"; } }
+.glyphicon-star-empty { &:before { content: "\e007"; } }
+.glyphicon-user { &:before { content: "\e008"; } }
+.glyphicon-film { &:before { content: "\e009"; } }
+.glyphicon-th-large { &:before { content: "\e010"; } }
+.glyphicon-th { &:before { content: "\e011"; } }
+.glyphicon-th-list { &:before { content: "\e012"; } }
+.glyphicon-ok { &:before { content: "\e013"; } }
+.glyphicon-remove { &:before { content: "\e014"; } }
+.glyphicon-zoom-in { &:before { content: "\e015"; } }
+.glyphicon-zoom-out { &:before { content: "\e016"; } }
+.glyphicon-off { &:before { content: "\e017"; } }
+.glyphicon-signal { &:before { content: "\e018"; } }
+.glyphicon-cog { &:before { content: "\e019"; } }
+.glyphicon-trash { &:before { content: "\e020"; } }
+.glyphicon-home { &:before { content: "\e021"; } }
+.glyphicon-file { &:before { content: "\e022"; } }
+.glyphicon-time { &:before { content: "\e023"; } }
+.glyphicon-road { &:before { content: "\e024"; } }
+.glyphicon-download-alt { &:before { content: "\e025"; } }
+.glyphicon-download { &:before { content: "\e026"; } }
+.glyphicon-upload { &:before { content: "\e027"; } }
+.glyphicon-inbox { &:before { content: "\e028"; } }
+.glyphicon-play-circle { &:before { content: "\e029"; } }
+.glyphicon-repeat { &:before { content: "\e030"; } }
+.glyphicon-refresh { &:before { content: "\e031"; } }
+.glyphicon-list-alt { &:before { content: "\e032"; } }
+.glyphicon-lock { &:before { content: "\e033"; } }
+.glyphicon-flag { &:before { content: "\e034"; } }
+.glyphicon-headphones { &:before { content: "\e035"; } }
+.glyphicon-volume-off { &:before { content: "\e036"; } }
+.glyphicon-volume-down { &:before { content: "\e037"; } }
+.glyphicon-volume-up { &:before { content: "\e038"; } }
+.glyphicon-qrcode { &:before { content: "\e039"; } }
+.glyphicon-barcode { &:before { content: "\e040"; } }
+.glyphicon-tag { &:before { content: "\e041"; } }
+.glyphicon-tags { &:before { content: "\e042"; } }
+.glyphicon-book { &:before { content: "\e043"; } }
+.glyphicon-bookmark { &:before { content: "\e044"; } }
+.glyphicon-print { &:before { content: "\e045"; } }
+.glyphicon-camera { &:before { content: "\e046"; } }
+.glyphicon-font { &:before { content: "\e047"; } }
+.glyphicon-bold { &:before { content: "\e048"; } }
+.glyphicon-italic { &:before { content: "\e049"; } }
+.glyphicon-text-height { &:before { content: "\e050"; } }
+.glyphicon-text-width { &:before { content: "\e051"; } }
+.glyphicon-align-left { &:before { content: "\e052"; } }
+.glyphicon-align-center { &:before { content: "\e053"; } }
+.glyphicon-align-right { &:before { content: "\e054"; } }
+.glyphicon-align-justify { &:before { content: "\e055"; } }
+.glyphicon-list { &:before { content: "\e056"; } }
+.glyphicon-indent-left { &:before { content: "\e057"; } }
+.glyphicon-indent-right { &:before { content: "\e058"; } }
+.glyphicon-facetime-video { &:before { content: "\e059"; } }
+.glyphicon-picture { &:before { content: "\e060"; } }
+.glyphicon-map-marker { &:before { content: "\e062"; } }
+.glyphicon-adjust { &:before { content: "\e063"; } }
+.glyphicon-tint { &:before { content: "\e064"; } }
+.glyphicon-edit { &:before { content: "\e065"; } }
+.glyphicon-share { &:before { content: "\e066"; } }
+.glyphicon-check { &:before { content: "\e067"; } }
+.glyphicon-move { &:before { content: "\e068"; } }
+.glyphicon-step-backward { &:before { content: "\e069"; } }
+.glyphicon-fast-backward { &:before { content: "\e070"; } }
+.glyphicon-backward { &:before { content: "\e071"; } }
+.glyphicon-play { &:before { content: "\e072"; } }
+.glyphicon-pause { &:before { content: "\e073"; } }
+.glyphicon-stop { &:before { content: "\e074"; } }
+.glyphicon-forward { &:before { content: "\e075"; } }
+.glyphicon-fast-forward { &:before { content: "\e076"; } }
+.glyphicon-step-forward { &:before { content: "\e077"; } }
+.glyphicon-eject { &:before { content: "\e078"; } }
+.glyphicon-chevron-left { &:before { content: "\e079"; } }
+.glyphicon-chevron-right { &:before { content: "\e080"; } }
+.glyphicon-plus-sign { &:before { content: "\e081"; } }
+.glyphicon-minus-sign { &:before { content: "\e082"; } }
+.glyphicon-remove-sign { &:before { content: "\e083"; } }
+.glyphicon-ok-sign { &:before { content: "\e084"; } }
+.glyphicon-question-sign { &:before { content: "\e085"; } }
+.glyphicon-info-sign { &:before { content: "\e086"; } }
+.glyphicon-screenshot { &:before { content: "\e087"; } }
+.glyphicon-remove-circle { &:before { content: "\e088"; } }
+.glyphicon-ok-circle { &:before { content: "\e089"; } }
+.glyphicon-ban-circle { &:before { content: "\e090"; } }
+.glyphicon-arrow-left { &:before { content: "\e091"; } }
+.glyphicon-arrow-right { &:before { content: "\e092"; } }
+.glyphicon-arrow-up { &:before { content: "\e093"; } }
+.glyphicon-arrow-down { &:before { content: "\e094"; } }
+.glyphicon-share-alt { &:before { content: "\e095"; } }
+.glyphicon-resize-full { &:before { content: "\e096"; } }
+.glyphicon-resize-small { &:before { content: "\e097"; } }
+.glyphicon-exclamation-sign { &:before { content: "\e101"; } }
+.glyphicon-gift { &:before { content: "\e102"; } }
+.glyphicon-leaf { &:before { content: "\e103"; } }
+.glyphicon-fire { &:before { content: "\e104"; } }
+.glyphicon-eye-open { &:before { content: "\e105"; } }
+.glyphicon-eye-close { &:before { content: "\e106"; } }
+.glyphicon-warning-sign { &:before { content: "\e107"; } }
+.glyphicon-plane { &:before { content: "\e108"; } }
+.glyphicon-calendar { &:before { content: "\e109"; } }
+.glyphicon-random { &:before { content: "\e110"; } }
+.glyphicon-comment { &:before { content: "\e111"; } }
+.glyphicon-magnet { &:before { content: "\e112"; } }
+.glyphicon-chevron-up { &:before { content: "\e113"; } }
+.glyphicon-chevron-down { &:before { content: "\e114"; } }
+.glyphicon-retweet { &:before { content: "\e115"; } }
+.glyphicon-shopping-cart { &:before { content: "\e116"; } }
+.glyphicon-folder-close { &:before { content: "\e117"; } }
+.glyphicon-folder-open { &:before { content: "\e118"; } }
+.glyphicon-resize-vertical { &:before { content: "\e119"; } }
+.glyphicon-resize-horizontal { &:before { content: "\e120"; } }
+.glyphicon-hdd { &:before { content: "\e121"; } }
+.glyphicon-bullhorn { &:before { content: "\e122"; } }
+.glyphicon-bell { &:before { content: "\e123"; } }
+.glyphicon-certificate { &:before { content: "\e124"; } }
+.glyphicon-thumbs-up { &:before { content: "\e125"; } }
+.glyphicon-thumbs-down { &:before { content: "\e126"; } }
+.glyphicon-hand-right { &:before { content: "\e127"; } }
+.glyphicon-hand-left { &:before { content: "\e128"; } }
+.glyphicon-hand-up { &:before { content: "\e129"; } }
+.glyphicon-hand-down { &:before { content: "\e130"; } }
+.glyphicon-circle-arrow-right { &:before { content: "\e131"; } }
+.glyphicon-circle-arrow-left { &:before { content: "\e132"; } }
+.glyphicon-circle-arrow-up { &:before { content: "\e133"; } }
+.glyphicon-circle-arrow-down { &:before { content: "\e134"; } }
+.glyphicon-globe { &:before { content: "\e135"; } }
+.glyphicon-wrench { &:before { content: "\e136"; } }
+.glyphicon-tasks { &:before { content: "\e137"; } }
+.glyphicon-filter { &:before { content: "\e138"; } }
+.glyphicon-briefcase { &:before { content: "\e139"; } }
+.glyphicon-fullscreen { &:before { content: "\e140"; } }
+.glyphicon-dashboard { &:before { content: "\e141"; } }
+.glyphicon-paperclip { &:before { content: "\e142"; } }
+.glyphicon-heart-empty { &:before { content: "\e143"; } }
+.glyphicon-link { &:before { content: "\e144"; } }
+.glyphicon-phone { &:before { content: "\e145"; } }
+.glyphicon-pushpin { &:before { content: "\e146"; } }
+.glyphicon-usd { &:before { content: "\e148"; } }
+.glyphicon-gbp { &:before { content: "\e149"; } }
+.glyphicon-sort { &:before { content: "\e150"; } }
+.glyphicon-sort-by-alphabet { &:before { content: "\e151"; } }
+.glyphicon-sort-by-alphabet-alt { &:before { content: "\e152"; } }
+.glyphicon-sort-by-order { &:before { content: "\e153"; } }
+.glyphicon-sort-by-order-alt { &:before { content: "\e154"; } }
+.glyphicon-sort-by-attributes { &:before { content: "\e155"; } }
+.glyphicon-sort-by-attributes-alt { &:before { content: "\e156"; } }
+.glyphicon-unchecked { &:before { content: "\e157"; } }
+.glyphicon-expand { &:before { content: "\e158"; } }
+.glyphicon-collapse-down { &:before { content: "\e159"; } }
+.glyphicon-collapse-up { &:before { content: "\e160"; } }
+.glyphicon-log-in { &:before { content: "\e161"; } }
+.glyphicon-flash { &:before { content: "\e162"; } }
+.glyphicon-log-out { &:before { content: "\e163"; } }
+.glyphicon-new-window { &:before { content: "\e164"; } }
+.glyphicon-record { &:before { content: "\e165"; } }
+.glyphicon-save { &:before { content: "\e166"; } }
+.glyphicon-open { &:before { content: "\e167"; } }
+.glyphicon-saved { &:before { content: "\e168"; } }
+.glyphicon-import { &:before { content: "\e169"; } }
+.glyphicon-export { &:before { content: "\e170"; } }
+.glyphicon-send { &:before { content: "\e171"; } }
+.glyphicon-floppy-disk { &:before { content: "\e172"; } }
+.glyphicon-floppy-saved { &:before { content: "\e173"; } }
+.glyphicon-floppy-remove { &:before { content: "\e174"; } }
+.glyphicon-floppy-save { &:before { content: "\e175"; } }
+.glyphicon-floppy-open { &:before { content: "\e176"; } }
+.glyphicon-credit-card { &:before { content: "\e177"; } }
+.glyphicon-transfer { &:before { content: "\e178"; } }
+.glyphicon-cutlery { &:before { content: "\e179"; } }
+.glyphicon-header { &:before { content: "\e180"; } }
+.glyphicon-compressed { &:before { content: "\e181"; } }
+.glyphicon-earphone { &:before { content: "\e182"; } }
+.glyphicon-phone-alt { &:before { content: "\e183"; } }
+.glyphicon-tower { &:before { content: "\e184"; } }
+.glyphicon-stats { &:before { content: "\e185"; } }
+.glyphicon-sd-video { &:before { content: "\e186"; } }
+.glyphicon-hd-video { &:before { content: "\e187"; } }
+.glyphicon-subtitles { &:before { content: "\e188"; } }
+.glyphicon-sound-stereo { &:before { content: "\e189"; } }
+.glyphicon-sound-dolby { &:before { content: "\e190"; } }
+.glyphicon-sound-5-1 { &:before { content: "\e191"; } }
+.glyphicon-sound-6-1 { &:before { content: "\e192"; } }
+.glyphicon-sound-7-1 { &:before { content: "\e193"; } }
+.glyphicon-copyright-mark { &:before { content: "\e194"; } }
+.glyphicon-registration-mark { &:before { content: "\e195"; } }
+.glyphicon-cloud-download { &:before { content: "\e197"; } }
+.glyphicon-cloud-upload { &:before { content: "\e198"; } }
+.glyphicon-tree-conifer { &:before { content: "\e199"; } }
+.glyphicon-tree-deciduous { &:before { content: "\e200"; } }
+.glyphicon-cd { &:before { content: "\e201"; } }
+.glyphicon-save-file { &:before { content: "\e202"; } }
+.glyphicon-open-file { &:before { content: "\e203"; } }
+.glyphicon-level-up { &:before { content: "\e204"; } }
+.glyphicon-copy { &:before { content: "\e205"; } }
+.glyphicon-paste { &:before { content: "\e206"; } }
+// The following 2 Glyphicons are omitted for the time being because
+// they currently use Unicode codepoints that are outside the
+// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle
+// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.
+// Notably, the bug affects some older versions of the Android Browser.
+// More info: https://github.com/twbs/bootstrap/issues/10106
+// .glyphicon-door { &:before { content: "\1f6aa"; } }
+// .glyphicon-key { &:before { content: "\1f511"; } }
+.glyphicon-alert { &:before { content: "\e209"; } }
+.glyphicon-equalizer { &:before { content: "\e210"; } }
+.glyphicon-king { &:before { content: "\e211"; } }
+.glyphicon-queen { &:before { content: "\e212"; } }
+.glyphicon-pawn { &:before { content: "\e213"; } }
+.glyphicon-bishop { &:before { content: "\e214"; } }
+.glyphicon-knight { &:before { content: "\e215"; } }
+.glyphicon-baby-formula { &:before { content: "\e216"; } }
+.glyphicon-tent { &:before { content: "\26fa"; } }
+.glyphicon-blackboard { &:before { content: "\e218"; } }
+.glyphicon-bed { &:before { content: "\e219"; } }
+.glyphicon-apple { &:before { content: "\f8ff"; } }
+.glyphicon-erase { &:before { content: "\e221"; } }
+.glyphicon-hourglass { &:before { content: "\231b"; } }
+.glyphicon-lamp { &:before { content: "\e223"; } }
+.glyphicon-duplicate { &:before { content: "\e224"; } }
+.glyphicon-piggy-bank { &:before { content: "\e225"; } }
+.glyphicon-scissors { &:before { content: "\e226"; } }
+.glyphicon-bitcoin { &:before { content: "\e227"; } }
+.glyphicon-btc { &:before { content: "\e227"; } }
+.glyphicon-xbt { &:before { content: "\e227"; } }
+.glyphicon-yen { &:before { content: "\00a5"; } }
+.glyphicon-jpy { &:before { content: "\00a5"; } }
+.glyphicon-ruble { &:before { content: "\20bd"; } }
+.glyphicon-rub { &:before { content: "\20bd"; } }
+.glyphicon-scale { &:before { content: "\e230"; } }
+.glyphicon-ice-lolly { &:before { content: "\e231"; } }
+.glyphicon-ice-lolly-tasted { &:before { content: "\e232"; } }
+.glyphicon-education { &:before { content: "\e233"; } }
+.glyphicon-option-horizontal { &:before { content: "\e234"; } }
+.glyphicon-option-vertical { &:before { content: "\e235"; } }
+.glyphicon-menu-hamburger { &:before { content: "\e236"; } }
+.glyphicon-modal-window { &:before { content: "\e237"; } }
+.glyphicon-oil { &:before { content: "\e238"; } }
+.glyphicon-grain { &:before { content: "\e239"; } }
+.glyphicon-sunglasses { &:before { content: "\e240"; } }
+.glyphicon-text-size { &:before { content: "\e241"; } }
+.glyphicon-text-color { &:before { content: "\e242"; } }
+.glyphicon-text-background { &:before { content: "\e243"; } }
+.glyphicon-object-align-top { &:before { content: "\e244"; } }
+.glyphicon-object-align-bottom { &:before { content: "\e245"; } }
+.glyphicon-object-align-horizontal{ &:before { content: "\e246"; } }
+.glyphicon-object-align-left { &:before { content: "\e247"; } }
+.glyphicon-object-align-vertical { &:before { content: "\e248"; } }
+.glyphicon-object-align-right { &:before { content: "\e249"; } }
+.glyphicon-triangle-right { &:before { content: "\e250"; } }
+.glyphicon-triangle-left { &:before { content: "\e251"; } }
+.glyphicon-triangle-bottom { &:before { content: "\e252"; } }
+.glyphicon-triangle-top { &:before { content: "\e253"; } }
+.glyphicon-console { &:before { content: "\e254"; } }
+.glyphicon-superscript { &:before { content: "\e255"; } }
+.glyphicon-subscript { &:before { content: "\e256"; } }
+.glyphicon-menu-left { &:before { content: "\e257"; } }
+.glyphicon-menu-right { &:before { content: "\e258"; } }
+.glyphicon-menu-down { &:before { content: "\e259"; } }
+.glyphicon-menu-up { &:before { content: "\e260"; } }
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_grid.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_grid.scss
new file mode 100644
index 0000000..2ddb73d
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_grid.scss
@@ -0,0 +1,94 @@
+//
+// Grid system
+// --------------------------------------------------
+
+
+// Container widths
+//
+// Set the container width, and override it for fixed navbars in media queries.
+
+.container {
+ @include container-fixed;
+
+ @media (min-width: $screen-sm-min) {
+ width: $container-sm;
+ }
+ @media (min-width: $screen-md-min) {
+ width: $container-md;
+ }
+ @media (min-width: $screen-lg-min) {
+ width: $container-lg;
+ }
+}
+
+
+// Fluid container
+//
+// Utilizes the mixin meant for fixed width containers, but without any defined
+// width for fluid, full width layouts.
+
+.container-fluid {
+ @include container-fixed;
+}
+
+
+// Row
+//
+// Rows contain and clear the floats of your columns.
+
+.row {
+ @include make-row;
+}
+
+.row-no-gutters {
+ margin-right: 0;
+ margin-left: 0;
+
+ [class*="col-"] {
+ padding-right: 0;
+ padding-left: 0;
+ }
+}
+
+
+// Columns
+//
+// Common styles for small and large grid columns
+
+@include make-grid-columns;
+
+
+// Extra small grid
+//
+// Columns, offsets, pushes, and pulls for extra small devices like
+// smartphones.
+
+@include make-grid(xs);
+
+
+// Small grid
+//
+// Columns, offsets, pushes, and pulls for the small device range, from phones
+// to tablets.
+
+@media (min-width: $screen-sm-min) {
+ @include make-grid(sm);
+}
+
+
+// Medium grid
+//
+// Columns, offsets, pushes, and pulls for the desktop device range.
+
+@media (min-width: $screen-md-min) {
+ @include make-grid(md);
+}
+
+
+// Large grid
+//
+// Columns, offsets, pushes, and pulls for the large desktop device range.
+
+@media (min-width: $screen-lg-min) {
+ @include make-grid(lg);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_input-groups.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_input-groups.scss
new file mode 100644
index 0000000..04015fe
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_input-groups.scss
@@ -0,0 +1,171 @@
+//
+// Input groups
+// --------------------------------------------------
+
+// Base styles
+// -------------------------
+.input-group {
+ position: relative; // For dropdowns
+ display: table;
+ border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table
+
+ // Undo padding and float of grid classes
+ &[class*="col-"] {
+ float: none;
+ padding-right: 0;
+ padding-left: 0;
+ }
+
+ .form-control {
+ // Ensure that the input is always above the *appended* addon button for
+ // proper border colors.
+ position: relative;
+ z-index: 2;
+
+ // IE9 fubars the placeholder attribute in text inputs and the arrows on
+ // select elements in input groups. To fix it, we float the input. Details:
+ // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855
+ float: left;
+
+ width: 100%;
+ margin-bottom: 0;
+
+ &:focus {
+ z-index: 3;
+ }
+ }
+}
+
+// Sizing options
+//
+// Remix the default form control sizing classes into new ones for easier
+// manipulation.
+
+.input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+ @extend .input-lg;
+}
+.input-group-sm > .form-control,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .btn {
+ @extend .input-sm;
+}
+
+
+// Display as table-cell
+// -------------------------
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+ display: table-cell;
+
+ &:not(:first-child):not(:last-child) {
+ border-radius: 0;
+ }
+}
+// Addon and addon wrapper for buttons
+.input-group-addon,
+.input-group-btn {
+ width: 1%;
+ white-space: nowrap;
+ vertical-align: middle; // Match the inputs
+}
+
+// Text input groups
+// -------------------------
+.input-group-addon {
+ padding: $padding-base-vertical $padding-base-horizontal;
+ font-size: $font-size-base;
+ font-weight: 400;
+ line-height: 1;
+ color: $input-color;
+ text-align: center;
+ background-color: $input-group-addon-bg;
+ border: 1px solid $input-group-addon-border-color;
+ border-radius: $input-border-radius;
+
+ // Sizing
+ &.input-sm {
+ padding: $padding-small-vertical $padding-small-horizontal;
+ font-size: $font-size-small;
+ border-radius: $input-border-radius-small;
+ }
+ &.input-lg {
+ padding: $padding-large-vertical $padding-large-horizontal;
+ font-size: $font-size-large;
+ border-radius: $input-border-radius-large;
+ }
+
+ // Nuke default margins from checkboxes and radios to vertically center within.
+ input[type="radio"],
+ input[type="checkbox"] {
+ margin-top: 0;
+ }
+}
+
+// Reset rounded corners
+.input-group .form-control:first-child,
+.input-group-addon:first-child,
+.input-group-btn:first-child > .btn,
+.input-group-btn:first-child > .btn-group > .btn,
+.input-group-btn:first-child > .dropdown-toggle,
+.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
+ @include border-right-radius(0);
+}
+.input-group-addon:first-child {
+ border-right: 0;
+}
+.input-group .form-control:last-child,
+.input-group-addon:last-child,
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
+ @include border-left-radius(0);
+}
+.input-group-addon:last-child {
+ border-left: 0;
+}
+
+// Button input groups
+// -------------------------
+.input-group-btn {
+ position: relative;
+ // Jankily prevent input button groups from wrapping with `white-space` and
+ // `font-size` in combination with `inline-block` on buttons.
+ font-size: 0;
+ white-space: nowrap;
+
+ // Negative margin for spacing, position for bringing hovered/focused/actived
+ // element above the siblings.
+ > .btn {
+ position: relative;
+ + .btn {
+ margin-left: -1px;
+ }
+ // Bring the "active" button to the front
+ &:hover,
+ &:focus,
+ &:active {
+ z-index: 2;
+ }
+ }
+
+ // Negative margin to only have a 1px border between the two
+ &:first-child {
+ > .btn,
+ > .btn-group {
+ margin-right: -1px;
+ }
+ }
+ &:last-child {
+ > .btn,
+ > .btn-group {
+ z-index: 2;
+ margin-left: -1px;
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_jumbotron.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_jumbotron.scss
new file mode 100644
index 0000000..07a0f98
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_jumbotron.scss
@@ -0,0 +1,55 @@
+@use "sass:math";
+//
+// Jumbotron
+// --------------------------------------------------
+
+
+.jumbotron {
+ padding-top: $jumbotron-padding;
+ padding-bottom: $jumbotron-padding;
+ margin-bottom: $jumbotron-padding;
+ color: $jumbotron-color;
+ background-color: $jumbotron-bg;
+
+ h1,
+ .h1 {
+ color: $jumbotron-heading-color;
+ }
+
+ p {
+ margin-bottom: math.div($jumbotron-padding, 2);
+ font-size: $jumbotron-font-size;
+ font-weight: 200;
+ }
+
+ > hr {
+ border-top-color: darken($jumbotron-bg, 10%);
+ }
+
+ .container &,
+ .container-fluid & {
+ padding-right: math.div($grid-gutter-width, 2);
+ padding-left: math.div($grid-gutter-width, 2);
+ border-radius: $border-radius-large; // Only round corners at higher resolutions if contained in a container
+ }
+
+ .container {
+ max-width: 100%;
+ }
+
+ @media screen and (min-width: $screen-sm-min) {
+ padding-top: ($jumbotron-padding * 1.6);
+ padding-bottom: ($jumbotron-padding * 1.6);
+
+ .container &,
+ .container-fluid & {
+ padding-right: ($jumbotron-padding * 2);
+ padding-left: ($jumbotron-padding * 2);
+ }
+
+ h1,
+ .h1 {
+ font-size: $jumbotron-heading-font-size;
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_labels.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_labels.scss
new file mode 100644
index 0000000..f7f3013
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_labels.scss
@@ -0,0 +1,66 @@
+//
+// Labels
+// --------------------------------------------------
+
+.label {
+ display: inline;
+ padding: .2em .6em .3em;
+ font-size: 75%;
+ font-weight: 700;
+ line-height: 1;
+ color: $label-color;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: .25em;
+
+ // [converter] extracted a& to a.label
+
+ // Empty labels collapse automatically (not available in IE8)
+ &:empty {
+ display: none;
+ }
+
+ // Quick fix for labels in buttons
+ .btn & {
+ position: relative;
+ top: -1px;
+ }
+}
+
+// Add hover effects, but only for links
+a.label {
+ &:hover,
+ &:focus {
+ color: $label-link-hover-color;
+ text-decoration: none;
+ cursor: pointer;
+ }
+}
+
+// Colors
+// Contextual variations (linked labels get darker on :hover)
+
+.label-default {
+ @include label-variant($label-default-bg);
+}
+
+.label-primary {
+ @include label-variant($label-primary-bg);
+}
+
+.label-success {
+ @include label-variant($label-success-bg);
+}
+
+.label-info {
+ @include label-variant($label-info-bg);
+}
+
+.label-warning {
+ @include label-variant($label-warning-bg);
+}
+
+.label-danger {
+ @include label-variant($label-danger-bg);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_list-group.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_list-group.scss
new file mode 100644
index 0000000..529f179
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_list-group.scss
@@ -0,0 +1,128 @@
+//
+// List groups
+// --------------------------------------------------
+
+
+// Base class
+//
+// Easily usable on , , or .
+
+.list-group {
+ // No need to set list-style: none; since .list-group-item is block level
+ padding-left: 0; // reset padding because ul and ol
+ margin-bottom: 20px;
+}
+
+
+// Individual list items
+//
+// Use on `li`s or `div`s within the `.list-group` parent.
+
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+ // Place the border on the list items and negative margin up for better styling
+ margin-bottom: -1px;
+ background-color: $list-group-bg;
+ border: 1px solid $list-group-border;
+
+ // Round the first and last items
+ &:first-child {
+ @include border-top-radius($list-group-border-radius);
+ }
+ &:last-child {
+ margin-bottom: 0;
+ @include border-bottom-radius($list-group-border-radius);
+ }
+
+ // Disabled state
+ &.disabled,
+ &.disabled:hover,
+ &.disabled:focus {
+ color: $list-group-disabled-color;
+ cursor: $cursor-disabled;
+ background-color: $list-group-disabled-bg;
+
+ // Force color to inherit for custom content
+ .list-group-item-heading {
+ color: inherit;
+ }
+ .list-group-item-text {
+ color: $list-group-disabled-text-color;
+ }
+ }
+
+ // Active class on item itself, not parent
+ &.active,
+ &.active:hover,
+ &.active:focus {
+ z-index: 2; // Place active items above their siblings for proper border styling
+ color: $list-group-active-color;
+ background-color: $list-group-active-bg;
+ border-color: $list-group-active-border;
+
+ // Force color to inherit for custom content
+ .list-group-item-heading,
+ .list-group-item-heading > small,
+ .list-group-item-heading > .small {
+ color: inherit;
+ }
+ .list-group-item-text {
+ color: $list-group-active-text-color;
+ }
+ }
+}
+
+
+// Interactive list items
+//
+// Use anchor or button elements instead of `li`s or `div`s to create interactive items.
+// Includes an extra `.active` modifier class for showing selected items.
+
+a.list-group-item,
+button.list-group-item {
+ color: $list-group-link-color;
+
+ .list-group-item-heading {
+ color: $list-group-link-heading-color;
+ }
+
+ // Hover state
+ &:hover,
+ &:focus {
+ color: $list-group-link-hover-color;
+ text-decoration: none;
+ background-color: $list-group-hover-bg;
+ }
+}
+
+button.list-group-item {
+ width: 100%;
+ text-align: left;
+}
+
+
+// Contextual variants
+//
+// Add modifier classes to change text and background color on individual items.
+// Organizationally, this must come after the `:hover` states.
+
+@include list-group-item-variant(success, $state-success-bg, $state-success-text);
+@include list-group-item-variant(info, $state-info-bg, $state-info-text);
+@include list-group-item-variant(warning, $state-warning-bg, $state-warning-text);
+@include list-group-item-variant(danger, $state-danger-bg, $state-danger-text);
+
+
+// Custom content options
+//
+// Extra classes for creating well-formatted content within `.list-group-item`s.
+
+.list-group-item-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+.list-group-item-text {
+ margin-bottom: 0;
+ line-height: 1.3;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_media.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_media.scss
new file mode 100644
index 0000000..e4ae445
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_media.scss
@@ -0,0 +1,66 @@
+.media {
+ // Proper spacing between instances of .media
+ margin-top: 15px;
+
+ &:first-child {
+ margin-top: 0;
+ }
+}
+
+.media,
+.media-body {
+ overflow: hidden;
+ zoom: 1;
+}
+
+.media-body {
+ width: 10000px;
+}
+
+.media-object {
+ display: block;
+
+ // Fix collapse in webkit from max-width: 100% and display: table-cell.
+ &.img-thumbnail {
+ max-width: none;
+ }
+}
+
+.media-right,
+.media > .pull-right {
+ padding-left: 10px;
+}
+
+.media-left,
+.media > .pull-left {
+ padding-right: 10px;
+}
+
+.media-left,
+.media-right,
+.media-body {
+ display: table-cell;
+ vertical-align: top;
+}
+
+.media-middle {
+ vertical-align: middle;
+}
+
+.media-bottom {
+ vertical-align: bottom;
+}
+
+// Reset margins on headings for tighter default spacing
+.media-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+}
+
+// Media list variation
+//
+// Undo default ul/ol styles
+.media-list {
+ padding-left: 0;
+ list-style: none;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_mixins.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_mixins.scss
new file mode 100644
index 0000000..78cd5aa
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_mixins.scss
@@ -0,0 +1,40 @@
+// Mixins
+// --------------------------------------------------
+
+// Utilities
+@import "mixins/hide-text";
+@import "mixins/opacity";
+@import "mixins/image";
+@import "mixins/labels";
+@import "mixins/reset-filter";
+@import "mixins/resize";
+@import "mixins/responsive-visibility";
+@import "mixins/size";
+@import "mixins/tab-focus";
+@import "mixins/reset-text";
+@import "mixins/text-emphasis";
+@import "mixins/text-overflow";
+@import "mixins/vendor-prefixes";
+
+// Components
+@import "mixins/alerts";
+@import "mixins/buttons";
+@import "mixins/panels";
+@import "mixins/pagination";
+@import "mixins/list-group";
+@import "mixins/nav-divider";
+@import "mixins/forms";
+@import "mixins/progress-bar";
+@import "mixins/table-row";
+
+// Skins
+@import "mixins/background-variant";
+@import "mixins/border-radius";
+@import "mixins/gradients";
+
+// Layout
+@import "mixins/clearfix";
+@import "mixins/center-block";
+@import "mixins/nav-vertical-align";
+@import "mixins/grid-framework";
+@import "mixins/grid";
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_modals.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_modals.scss
new file mode 100644
index 0000000..cf59bef
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_modals.scss
@@ -0,0 +1,150 @@
+//
+// Modals
+// --------------------------------------------------
+
+// .modal-open - body class for killing the scroll
+// .modal - container to scroll within
+// .modal-dialog - positioning shell for the actual modal
+// .modal-content - actual modal w/ bg and corners and shit
+
+// Kill the scroll on the body
+.modal-open {
+ overflow: hidden;
+}
+
+// Container that the modal scrolls within
+.modal {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: $zindex-modal;
+ display: none;
+ overflow: hidden;
+ -webkit-overflow-scrolling: touch;
+
+ // Prevent Chrome on Windows from adding a focus outline. For details, see
+ // https://github.com/twbs/bootstrap/pull/10951.
+ outline: 0;
+
+ // When fading in the modal, animate it to slide down
+ &.fade .modal-dialog {
+ @include translate(0, -25%);
+ @include transition-transform(0.3s ease-out);
+ }
+ &.in .modal-dialog { @include translate(0, 0); }
+}
+.modal-open .modal {
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+
+// Shell div to position the modal with bottom padding
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: 10px;
+}
+
+// Actual modal
+.modal-content {
+ position: relative;
+ background-color: $modal-content-bg;
+ background-clip: padding-box;
+ border: 1px solid $modal-content-fallback-border-color; //old browsers fallback (ie8 etc)
+ border: 1px solid $modal-content-border-color;
+ border-radius: $border-radius-large;
+ @include box-shadow(0 3px 9px rgba(0, 0, 0, .5));
+ // Remove focus outline from opened modal
+ outline: 0;
+}
+
+// Modal background
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: $zindex-modal-background;
+ background-color: $modal-backdrop-bg;
+ // Fade for backdrop
+ &.fade { @include opacity(0); }
+ &.in { @include opacity($modal-backdrop-opacity); }
+}
+
+// Modal header
+// Top section of the modal w/ title and dismiss
+.modal-header {
+ padding: $modal-title-padding;
+ border-bottom: 1px solid $modal-header-border-color;
+ @include clearfix;
+}
+// Close icon
+.modal-header .close {
+ margin-top: -2px;
+}
+
+// Title text within header
+.modal-title {
+ margin: 0;
+ line-height: $modal-title-line-height;
+}
+
+// Modal body
+// Where all modal content resides (sibling of .modal-header and .modal-footer)
+.modal-body {
+ position: relative;
+ padding: $modal-inner-padding;
+}
+
+// Footer (for actions)
+.modal-footer {
+ padding: $modal-inner-padding;
+ text-align: right; // right align buttons
+ border-top: 1px solid $modal-footer-border-color;
+ @include clearfix; // clear it in case folks use .pull-* classes on buttons
+
+ // Properly space out buttons
+ .btn + .btn {
+ margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs
+ margin-left: 5px;
+ }
+ // but override that for button groups
+ .btn-group .btn + .btn {
+ margin-left: -1px;
+ }
+ // and override it for block buttons as well
+ .btn-block + .btn-block {
+ margin-left: 0;
+ }
+}
+
+// Measure scrollbar width for padding body during modal show/hide
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll;
+}
+
+// Scale up the modal
+@media (min-width: $screen-sm-min) {
+ // Automatically set modal's width for larger viewports
+ .modal-dialog {
+ width: $modal-md;
+ margin: 30px auto;
+ }
+ .modal-content {
+ @include box-shadow(0 5px 15px rgba(0, 0, 0, .5));
+ }
+
+ // Modal sizes
+ .modal-sm { width: $modal-sm; }
+}
+
+@media (min-width: $screen-md-min) {
+ .modal-lg { width: $modal-lg; }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_navbar.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_navbar.scss
new file mode 100644
index 0000000..135aba0
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_navbar.scss
@@ -0,0 +1,657 @@
+@use "sass:math";
+//
+// Navbars
+// --------------------------------------------------
+
+
+// Wrapper and base class
+//
+// Provide a static navbar from which we expand to create full-width, fixed, and
+// other navbar variations.
+
+.navbar {
+ position: relative;
+ min-height: $navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)
+ margin-bottom: $navbar-margin-bottom;
+ border: 1px solid transparent;
+
+ // Prevent floats from breaking the navbar
+ @include clearfix;
+
+ @media (min-width: $grid-float-breakpoint) {
+ border-radius: $navbar-border-radius;
+ }
+}
+
+
+// Navbar heading
+//
+// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy
+// styling of responsive aspects.
+
+.navbar-header {
+ @include clearfix;
+
+ @media (min-width: $grid-float-breakpoint) {
+ float: left;
+ }
+}
+
+
+// Navbar collapse (body)
+//
+// Group your navbar content into this for easy collapsing and expanding across
+// various device sizes. By default, this content is collapsed when <768px, but
+// will expand past that for a horizontal display.
+//
+// To start (on mobile devices) the navbar links, forms, and buttons are stacked
+// vertically and include a `max-height` to overflow in case you have too much
+// content for the user's viewport.
+
+.navbar-collapse {
+ padding-right: $navbar-padding-horizontal;
+ padding-left: $navbar-padding-horizontal;
+ overflow-x: visible;
+ border-top: 1px solid transparent;
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
+ @include clearfix;
+ -webkit-overflow-scrolling: touch;
+
+ &.in {
+ overflow-y: auto;
+ }
+
+ @media (min-width: $grid-float-breakpoint) {
+ width: auto;
+ border-top: 0;
+ box-shadow: none;
+
+ &.collapse {
+ display: block !important;
+ height: auto !important;
+ padding-bottom: 0; // Override default setting
+ overflow: visible !important;
+ }
+
+ &.in {
+ overflow-y: visible;
+ }
+
+ // Undo the collapse side padding for navbars with containers to ensure
+ // alignment of right-aligned contents.
+ .navbar-fixed-top &,
+ .navbar-static-top &,
+ .navbar-fixed-bottom & {
+ padding-right: 0;
+ padding-left: 0;
+ }
+ }
+}
+
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ .navbar-collapse {
+ max-height: $navbar-collapse-max-height;
+
+ @media (max-device-width: $screen-xs-min) and (orientation: landscape) {
+ max-height: 200px;
+ }
+ }
+
+ // Fix the top/bottom navbars when screen real estate supports it
+ position: fixed;
+ right: 0;
+ left: 0;
+ z-index: $zindex-navbar-fixed;
+
+ // Undo the rounded corners
+ @media (min-width: $grid-float-breakpoint) {
+ border-radius: 0;
+ }
+}
+
+.navbar-fixed-top {
+ top: 0;
+ border-width: 0 0 1px;
+}
+.navbar-fixed-bottom {
+ bottom: 0;
+ margin-bottom: 0; // override .navbar defaults
+ border-width: 1px 0 0;
+}
+
+
+// Both navbar header and collapse
+//
+// When a container is present, change the behavior of the header and collapse.
+
+.container,
+.container-fluid {
+ > .navbar-header,
+ > .navbar-collapse {
+ margin-right: -$navbar-padding-horizontal;
+ margin-left: -$navbar-padding-horizontal;
+
+ @media (min-width: $grid-float-breakpoint) {
+ margin-right: 0;
+ margin-left: 0;
+ }
+ }
+}
+
+
+//
+// Navbar alignment options
+//
+// Display the navbar across the entirety of the page or fixed it to the top or
+// bottom of the page.
+
+// Static top (unfixed, but 100% wide) navbar
+.navbar-static-top {
+ z-index: $zindex-navbar;
+ border-width: 0 0 1px;
+
+ @media (min-width: $grid-float-breakpoint) {
+ border-radius: 0;
+ }
+}
+
+
+// Brand/project name
+
+.navbar-brand {
+ float: left;
+ height: $navbar-height;
+ padding: $navbar-padding-vertical $navbar-padding-horizontal;
+ font-size: $font-size-large;
+ line-height: $line-height-computed;
+
+ &:hover,
+ &:focus {
+ text-decoration: none;
+ }
+
+ > img {
+ display: block;
+ }
+
+ @media (min-width: $grid-float-breakpoint) {
+ .navbar > .container &,
+ .navbar > .container-fluid & {
+ margin-left: -$navbar-padding-horizontal;
+ }
+ }
+}
+
+
+// Navbar toggle
+//
+// Custom button for toggling the `.navbar-collapse`, powered by the collapse
+// JavaScript plugin.
+
+.navbar-toggle {
+ position: relative;
+ float: right;
+ padding: 9px 10px;
+ margin-right: $navbar-padding-horizontal;
+ @include navbar-vertical-align(34px);
+ background-color: transparent;
+ background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
+ border: 1px solid transparent;
+ border-radius: $border-radius-base;
+
+ // We remove the `outline` here, but later compensate by attaching `:hover`
+ // styles to `:focus`.
+ &:focus {
+ outline: 0;
+ }
+
+ // Bars
+ .icon-bar {
+ display: block;
+ width: 22px;
+ height: 2px;
+ border-radius: 1px;
+ }
+ .icon-bar + .icon-bar {
+ margin-top: 4px;
+ }
+
+ @media (min-width: $grid-float-breakpoint) {
+ display: none;
+ }
+}
+
+
+// Navbar nav links
+//
+// Builds on top of the `.nav` components with its own modifier class to make
+// the nav the full height of the horizontal nav (above 768px).
+
+.navbar-nav {
+ margin: math.div($navbar-padding-vertical, 2) (-$navbar-padding-horizontal);
+
+ > li > a {
+ padding-top: 10px;
+ padding-bottom: 10px;
+ line-height: $line-height-computed;
+ }
+
+ @media (max-width: $grid-float-breakpoint-max) {
+ // Dropdowns get custom display when collapsed
+ .open .dropdown-menu {
+ position: static;
+ float: none;
+ width: auto;
+ margin-top: 0;
+ background-color: transparent;
+ border: 0;
+ box-shadow: none;
+ > li > a,
+ .dropdown-header {
+ padding: 5px 15px 5px 25px;
+ }
+ > li > a {
+ line-height: $line-height-computed;
+ &:hover,
+ &:focus {
+ background-image: none;
+ }
+ }
+ }
+ }
+
+ // Uncollapse the nav
+ @media (min-width: $grid-float-breakpoint) {
+ float: left;
+ margin: 0;
+
+ > li {
+ float: left;
+ > a {
+ padding-top: $navbar-padding-vertical;
+ padding-bottom: $navbar-padding-vertical;
+ }
+ }
+ }
+}
+
+
+// Navbar form
+//
+// Extension of the `.form-inline` with some extra flavor for optimum display in
+// our navbars.
+
+.navbar-form {
+ padding: 10px $navbar-padding-horizontal;
+ margin-right: -$navbar-padding-horizontal;
+ margin-left: -$navbar-padding-horizontal;
+ border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ $shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
+ @include box-shadow($shadow);
+
+ // Mixin behavior for optimum display
+ @include form-inline;
+
+ .form-group {
+ @media (max-width: $grid-float-breakpoint-max) {
+ margin-bottom: 5px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+ }
+
+ // Vertically center in expanded, horizontal navbar
+ @include navbar-vertical-align($input-height-base);
+
+ // Undo 100% width for pull classes
+ @media (min-width: $grid-float-breakpoint) {
+ width: auto;
+ padding-top: 0;
+ padding-bottom: 0;
+ margin-right: 0;
+ margin-left: 0;
+ border: 0;
+ @include box-shadow(none);
+ }
+}
+
+
+// Dropdown menus
+
+// Menu position and menu carets
+.navbar-nav > li > .dropdown-menu {
+ margin-top: 0;
+ @include border-top-radius(0);
+}
+// Menu position and menu caret support for dropups via extra dropup class
+.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
+ margin-bottom: 0;
+ @include border-top-radius($navbar-border-radius);
+ @include border-bottom-radius(0);
+}
+
+
+// Buttons in navbars
+//
+// Vertically center a button within a navbar (when *not* in a form).
+
+.navbar-btn {
+ @include navbar-vertical-align($input-height-base);
+
+ &.btn-sm {
+ @include navbar-vertical-align($input-height-small);
+ }
+ &.btn-xs {
+ @include navbar-vertical-align(22);
+ }
+}
+
+
+// Text in navbars
+//
+// Add a class to make any element properly align itself vertically within the navbars.
+
+.navbar-text {
+ @include navbar-vertical-align($line-height-computed);
+
+ @media (min-width: $grid-float-breakpoint) {
+ float: left;
+ margin-right: $navbar-padding-horizontal;
+ margin-left: $navbar-padding-horizontal;
+ }
+}
+
+
+// Component alignment
+//
+// Repurpose the pull utilities as their own navbar utilities to avoid specificity
+// issues with parents and chaining. Only do this when the navbar is uncollapsed
+// though so that navbar contents properly stack and align in mobile.
+//
+// Declared after the navbar components to ensure more specificity on the margins.
+
+@media (min-width: $grid-float-breakpoint) {
+ .navbar-left {
+ float: left !important;
+ }
+ .navbar-right {
+ float: right !important;
+ margin-right: -$navbar-padding-horizontal;
+
+ ~ .navbar-right {
+ margin-right: 0;
+ }
+ }
+}
+
+
+// Alternate navbars
+// --------------------------------------------------
+
+// Default navbar
+.navbar-default {
+ background-color: $navbar-default-bg;
+ border-color: $navbar-default-border;
+
+ .navbar-brand {
+ color: $navbar-default-brand-color;
+ &:hover,
+ &:focus {
+ color: $navbar-default-brand-hover-color;
+ background-color: $navbar-default-brand-hover-bg;
+ }
+ }
+
+ .navbar-text {
+ color: $navbar-default-color;
+ }
+
+ .navbar-nav {
+ > li > a {
+ color: $navbar-default-link-color;
+
+ &:hover,
+ &:focus {
+ color: $navbar-default-link-hover-color;
+ background-color: $navbar-default-link-hover-bg;
+ }
+ }
+ > .active > a {
+ &,
+ &:hover,
+ &:focus {
+ color: $navbar-default-link-active-color;
+ background-color: $navbar-default-link-active-bg;
+ }
+ }
+ > .disabled > a {
+ &,
+ &:hover,
+ &:focus {
+ color: $navbar-default-link-disabled-color;
+ background-color: $navbar-default-link-disabled-bg;
+ }
+ }
+
+ // Dropdown menu items
+ // Remove background color from open dropdown
+ > .open > a {
+ &,
+ &:hover,
+ &:focus {
+ color: $navbar-default-link-active-color;
+ background-color: $navbar-default-link-active-bg;
+ }
+ }
+
+ @media (max-width: $grid-float-breakpoint-max) {
+ // Dropdowns get custom display when collapsed
+ .open .dropdown-menu {
+ > li > a {
+ color: $navbar-default-link-color;
+ &:hover,
+ &:focus {
+ color: $navbar-default-link-hover-color;
+ background-color: $navbar-default-link-hover-bg;
+ }
+ }
+ > .active > a {
+ &,
+ &:hover,
+ &:focus {
+ color: $navbar-default-link-active-color;
+ background-color: $navbar-default-link-active-bg;
+ }
+ }
+ > .disabled > a {
+ &,
+ &:hover,
+ &:focus {
+ color: $navbar-default-link-disabled-color;
+ background-color: $navbar-default-link-disabled-bg;
+ }
+ }
+ }
+ }
+ }
+
+ .navbar-toggle {
+ border-color: $navbar-default-toggle-border-color;
+ &:hover,
+ &:focus {
+ background-color: $navbar-default-toggle-hover-bg;
+ }
+ .icon-bar {
+ background-color: $navbar-default-toggle-icon-bar-bg;
+ }
+ }
+
+ .navbar-collapse,
+ .navbar-form {
+ border-color: $navbar-default-border;
+ }
+
+
+ // Links in navbars
+ //
+ // Add a class to ensure links outside the navbar nav are colored correctly.
+
+ .navbar-link {
+ color: $navbar-default-link-color;
+ &:hover {
+ color: $navbar-default-link-hover-color;
+ }
+ }
+
+ .btn-link {
+ color: $navbar-default-link-color;
+ &:hover,
+ &:focus {
+ color: $navbar-default-link-hover-color;
+ }
+ &[disabled],
+ fieldset[disabled] & {
+ &:hover,
+ &:focus {
+ color: $navbar-default-link-disabled-color;
+ }
+ }
+ }
+}
+
+// Inverse navbar
+
+.navbar-inverse {
+ background-color: $navbar-inverse-bg;
+ border-color: $navbar-inverse-border;
+
+ .navbar-brand {
+ color: $navbar-inverse-brand-color;
+ &:hover,
+ &:focus {
+ color: $navbar-inverse-brand-hover-color;
+ background-color: $navbar-inverse-brand-hover-bg;
+ }
+ }
+
+ .navbar-text {
+ color: $navbar-inverse-color;
+ }
+
+ .navbar-nav {
+ > li > a {
+ color: $navbar-inverse-link-color;
+
+ &:hover,
+ &:focus {
+ color: $navbar-inverse-link-hover-color;
+ background-color: $navbar-inverse-link-hover-bg;
+ }
+ }
+ > .active > a {
+ &,
+ &:hover,
+ &:focus {
+ color: $navbar-inverse-link-active-color;
+ background-color: $navbar-inverse-link-active-bg;
+ }
+ }
+ > .disabled > a {
+ &,
+ &:hover,
+ &:focus {
+ color: $navbar-inverse-link-disabled-color;
+ background-color: $navbar-inverse-link-disabled-bg;
+ }
+ }
+
+ // Dropdowns
+ > .open > a {
+ &,
+ &:hover,
+ &:focus {
+ color: $navbar-inverse-link-active-color;
+ background-color: $navbar-inverse-link-active-bg;
+ }
+ }
+
+ @media (max-width: $grid-float-breakpoint-max) {
+ // Dropdowns get custom display
+ .open .dropdown-menu {
+ > .dropdown-header {
+ border-color: $navbar-inverse-border;
+ }
+ .divider {
+ background-color: $navbar-inverse-border;
+ }
+ > li > a {
+ color: $navbar-inverse-link-color;
+ &:hover,
+ &:focus {
+ color: $navbar-inverse-link-hover-color;
+ background-color: $navbar-inverse-link-hover-bg;
+ }
+ }
+ > .active > a {
+ &,
+ &:hover,
+ &:focus {
+ color: $navbar-inverse-link-active-color;
+ background-color: $navbar-inverse-link-active-bg;
+ }
+ }
+ > .disabled > a {
+ &,
+ &:hover,
+ &:focus {
+ color: $navbar-inverse-link-disabled-color;
+ background-color: $navbar-inverse-link-disabled-bg;
+ }
+ }
+ }
+ }
+ }
+
+ // Darken the responsive nav toggle
+ .navbar-toggle {
+ border-color: $navbar-inverse-toggle-border-color;
+ &:hover,
+ &:focus {
+ background-color: $navbar-inverse-toggle-hover-bg;
+ }
+ .icon-bar {
+ background-color: $navbar-inverse-toggle-icon-bar-bg;
+ }
+ }
+
+ .navbar-collapse,
+ .navbar-form {
+ border-color: darken($navbar-inverse-bg, 7%);
+ }
+
+ .navbar-link {
+ color: $navbar-inverse-link-color;
+ &:hover {
+ color: $navbar-inverse-link-hover-color;
+ }
+ }
+
+ .btn-link {
+ color: $navbar-inverse-link-color;
+ &:hover,
+ &:focus {
+ color: $navbar-inverse-link-hover-color;
+ }
+ &[disabled],
+ fieldset[disabled] & {
+ &:hover,
+ &:focus {
+ color: $navbar-inverse-link-disabled-color;
+ }
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_navs.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_navs.scss
new file mode 100644
index 0000000..f4f0a55
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_navs.scss
@@ -0,0 +1,242 @@
+//
+// Navs
+// --------------------------------------------------
+
+
+// Base class
+// --------------------------------------------------
+
+.nav {
+ padding-left: 0; // Override default ul/ol
+ margin-bottom: 0;
+ list-style: none;
+ @include clearfix;
+
+ > li {
+ position: relative;
+ display: block;
+
+ > a {
+ position: relative;
+ display: block;
+ padding: $nav-link-padding;
+ &:hover,
+ &:focus {
+ text-decoration: none;
+ background-color: $nav-link-hover-bg;
+ }
+ }
+
+ // Disabled state sets text to gray and nukes hover/tab effects
+ &.disabled > a {
+ color: $nav-disabled-link-color;
+
+ &:hover,
+ &:focus {
+ color: $nav-disabled-link-hover-color;
+ text-decoration: none;
+ cursor: $cursor-disabled;
+ background-color: transparent;
+ }
+ }
+ }
+
+ // Open dropdowns
+ .open > a {
+ &,
+ &:hover,
+ &:focus {
+ background-color: $nav-link-hover-bg;
+ border-color: $link-color;
+ }
+ }
+
+ // Nav dividers (deprecated with v3.0.1)
+ //
+ // This should have been removed in v3 with the dropping of `.nav-list`, but
+ // we missed it. We don't currently support this anywhere, but in the interest
+ // of maintaining backward compatibility in case you use it, it's deprecated.
+ .nav-divider {
+ @include nav-divider;
+ }
+
+ // Prevent IE8 from misplacing imgs
+ //
+ // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989
+ > li > a > img {
+ max-width: none;
+ }
+}
+
+
+// Tabs
+// -------------------------
+
+// Give the tabs something to sit on
+.nav-tabs {
+ border-bottom: 1px solid $nav-tabs-border-color;
+ > li {
+ float: left;
+ // Make the list-items overlay the bottom border
+ margin-bottom: -1px;
+
+ // Actual tabs (as links)
+ > a {
+ margin-right: 2px;
+ line-height: $line-height-base;
+ border: 1px solid transparent;
+ border-radius: $border-radius-base $border-radius-base 0 0;
+ &:hover {
+ border-color: $nav-tabs-link-hover-border-color $nav-tabs-link-hover-border-color $nav-tabs-border-color;
+ }
+ }
+
+ // Active state, and its :hover to override normal :hover
+ &.active > a {
+ &,
+ &:hover,
+ &:focus {
+ color: $nav-tabs-active-link-hover-color;
+ cursor: default;
+ background-color: $nav-tabs-active-link-hover-bg;
+ border: 1px solid $nav-tabs-active-link-hover-border-color;
+ border-bottom-color: transparent;
+ }
+ }
+ }
+ // pulling this in mainly for less shorthand
+ &.nav-justified {
+ @extend .nav-justified;
+ @extend .nav-tabs-justified;
+ }
+}
+
+
+// Pills
+// -------------------------
+.nav-pills {
+ > li {
+ float: left;
+
+ // Links rendered as pills
+ > a {
+ border-radius: $nav-pills-border-radius;
+ }
+ + li {
+ margin-left: 2px;
+ }
+
+ // Active state
+ &.active > a {
+ &,
+ &:hover,
+ &:focus {
+ color: $nav-pills-active-link-hover-color;
+ background-color: $nav-pills-active-link-hover-bg;
+ }
+ }
+ }
+}
+
+
+// Stacked pills
+.nav-stacked {
+ > li {
+ float: none;
+ + li {
+ margin-top: 2px;
+ margin-left: 0; // no need for this gap between nav items
+ }
+ }
+}
+
+
+// Nav variations
+// --------------------------------------------------
+
+// Justified nav links
+// -------------------------
+
+.nav-justified {
+ width: 100%;
+
+ > li {
+ float: none;
+ > a {
+ margin-bottom: 5px;
+ text-align: center;
+ }
+ }
+
+ > .dropdown .dropdown-menu {
+ top: auto;
+ left: auto;
+ }
+
+ @media (min-width: $screen-sm-min) {
+ > li {
+ display: table-cell;
+ width: 1%;
+ > a {
+ margin-bottom: 0;
+ }
+ }
+ }
+}
+
+// Move borders to anchors instead of bottom of list
+//
+// Mixin for adding on top the shared `.nav-justified` styles for our tabs
+.nav-tabs-justified {
+ border-bottom: 0;
+
+ > li > a {
+ // Override margin from .nav-tabs
+ margin-right: 0;
+ border-radius: $border-radius-base;
+ }
+
+ > .active > a,
+ > .active > a:hover,
+ > .active > a:focus {
+ border: 1px solid $nav-tabs-justified-link-border-color;
+ }
+
+ @media (min-width: $screen-sm-min) {
+ > li > a {
+ border-bottom: 1px solid $nav-tabs-justified-link-border-color;
+ border-radius: $border-radius-base $border-radius-base 0 0;
+ }
+ > .active > a,
+ > .active > a:hover,
+ > .active > a:focus {
+ border-bottom-color: $nav-tabs-justified-active-link-border-color;
+ }
+ }
+}
+
+
+// Tabbable tabs
+// -------------------------
+
+// Hide tabbable panes to start, show them when `.active`
+.tab-content {
+ > .tab-pane {
+ display: none;
+ }
+ > .active {
+ display: block;
+ }
+}
+
+
+// Dropdowns
+// -------------------------
+
+// Specific dropdowns
+.nav-tabs .dropdown-menu {
+ // make dropdown border overlap tab border
+ margin-top: -1px;
+ // Remove the top rounded corners here since there is a hard edge above the menu
+ @include border-top-radius(0);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_normalize.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_normalize.scss
new file mode 100644
index 0000000..7850b9a
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_normalize.scss
@@ -0,0 +1,427 @@
+/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+
+//
+// 1. Set default font family to sans-serif.
+// 2. Prevent iOS and IE text size adjust after device orientation change,
+// without disabling user zoom.
+//
+
+html {
+ font-family: sans-serif; // 1
+ -ms-text-size-adjust: 100%; // 2
+ -webkit-text-size-adjust: 100%; // 2
+}
+
+//
+// Remove default margin.
+//
+
+body {
+ margin: 0;
+}
+
+// HTML5 display definitions
+// ==========================================================================
+
+//
+// Correct `block` display not defined for any HTML5 element in IE 8/9.
+// Correct `block` display not defined for `details` or `summary` in IE 10/11
+// and Firefox.
+// Correct `block` display not defined for `main` in IE 11.
+//
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+ display: block;
+}
+
+//
+// 1. Correct `inline-block` display not defined in IE 8/9.
+// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
+//
+
+audio,
+canvas,
+progress,
+video {
+ display: inline-block; // 1
+ vertical-align: baseline; // 2
+}
+
+//
+// Prevent modern browsers from displaying `audio` without controls.
+// Remove excess height in iOS 5 devices.
+//
+
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+
+//
+// Address `[hidden]` styling not present in IE 8/9/10.
+// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.
+//
+
+[hidden],
+template {
+ display: none;
+}
+
+// Links
+// ==========================================================================
+
+//
+// Remove the gray background color from active links in IE 10.
+//
+
+a {
+ background-color: transparent;
+}
+
+//
+// Improve readability of focused elements when they are also in an
+// active/hover state.
+//
+
+a:active,
+a:hover {
+ outline: 0;
+}
+
+// Text-level semantics
+// ==========================================================================
+
+//
+// 1. Remove the bottom border in Chrome 57- and Firefox 39-.
+// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
+//
+
+abbr[title] {
+ border-bottom: none; // 1
+ text-decoration: underline; // 2
+ text-decoration: underline dotted; // 2
+}
+
+//
+// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
+//
+
+b,
+strong {
+ font-weight: bold;
+}
+
+//
+// Address styling not present in Safari and Chrome.
+//
+
+dfn {
+ font-style: italic;
+}
+
+//
+// Address variable `h1` font-size and margin within `section` and `article`
+// contexts in Firefox 4+, Safari, and Chrome.
+//
+
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+//
+// Address styling not present in IE 8/9.
+//
+
+mark {
+ background: #ff0;
+ color: #000;
+}
+
+//
+// Address inconsistent and variable font size in all browsers.
+//
+
+small {
+ font-size: 80%;
+}
+
+//
+// Prevent `sub` and `sup` affecting `line-height` in all browsers.
+//
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+// Embedded content
+// ==========================================================================
+
+//
+// Remove border when inside `a` element in IE 8/9/10.
+//
+
+img {
+ border: 0;
+}
+
+//
+// Correct overflow not hidden in IE 9/10/11.
+//
+
+svg:not(:root) {
+ overflow: hidden;
+}
+
+// Grouping content
+// ==========================================================================
+
+//
+// Address margin not present in IE 8/9 and Safari.
+//
+
+figure {
+ margin: 1em 40px;
+}
+
+//
+// Address differences between Firefox and other browsers.
+//
+
+hr {
+ box-sizing: content-box;
+ height: 0;
+}
+
+//
+// Contain overflow in all browsers.
+//
+
+pre {
+ overflow: auto;
+}
+
+//
+// Address odd `em`-unit font size rendering in all browsers.
+//
+
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+
+// Forms
+// ==========================================================================
+
+//
+// Known limitation: by default, Chrome and Safari on OS X allow very limited
+// styling of `select`, unless a `border` property is set.
+//
+
+//
+// 1. Correct color not being inherited.
+// Known issue: affects color of disabled elements.
+// 2. Correct font properties not being inherited.
+// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
+//
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ color: inherit; // 1
+ font: inherit; // 2
+ margin: 0; // 3
+}
+
+//
+// Address `overflow` set to `hidden` in IE 8/9/10/11.
+//
+
+button {
+ overflow: visible;
+}
+
+//
+// Address inconsistent `text-transform` inheritance for `button` and `select`.
+// All other form control elements do not inherit `text-transform` values.
+// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
+// Correct `select` style inheritance in Firefox.
+//
+
+button,
+select {
+ text-transform: none;
+}
+
+//
+// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
+// and `video` controls.
+// 2. Correct inability to style clickable `input` types in iOS.
+// 3. Improve usability and consistency of cursor style between image-type
+// `input` and others.
+//
+
+button,
+html input[type="button"], // 1
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button; // 2
+ cursor: pointer; // 3
+}
+
+//
+// Re-set default cursor for disabled elements.
+//
+
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+
+//
+// Remove inner padding and border in Firefox 4+.
+//
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+//
+// Address Firefox 4+ setting `line-height` on `input` using `!important` in
+// the UA stylesheet.
+//
+
+input {
+ line-height: normal;
+}
+
+//
+// It's recommended that you don't attempt to style these elements.
+// Firefox's implementation doesn't respect box-sizing, padding, or width.
+//
+// 1. Address box sizing set to `content-box` in IE 8/9/10.
+// 2. Remove excess padding in IE 8/9/10.
+//
+
+input[type="checkbox"],
+input[type="radio"] {
+ box-sizing: border-box; // 1
+ padding: 0; // 2
+}
+
+//
+// Fix the cursor style for Chrome's increment/decrement buttons. For certain
+// `font-size` values of the `input`, it causes the cursor style of the
+// decrement button to change from `default` to `text`.
+//
+
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+//
+// 1. Address `appearance` set to `searchfield` in Safari and Chrome.
+// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.
+//
+
+input[type="search"] {
+ -webkit-appearance: textfield; // 1
+ box-sizing: content-box; //2
+}
+
+//
+// Remove inner padding and search cancel button in Safari and Chrome on OS X.
+// Safari (but not Chrome) clips the cancel button when the search input has
+// padding (and `textfield` appearance).
+//
+
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+//
+// Define consistent border, margin, and padding.
+//
+
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+
+//
+// 1. Correct `color` not being inherited in IE 8/9/10/11.
+// 2. Remove padding so people aren't caught out if they zero out fieldsets.
+//
+
+legend {
+ border: 0; // 1
+ padding: 0; // 2
+}
+
+//
+// Remove default vertical scrollbar in IE 8/9/10/11.
+//
+
+textarea {
+ overflow: auto;
+}
+
+//
+// Don't inherit the `font-weight` (applied by a rule above).
+// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
+//
+
+optgroup {
+ font-weight: bold;
+}
+
+// Tables
+// ==========================================================================
+
+//
+// Remove most spacing between table cells.
+//
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+td,
+th {
+ padding: 0;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_pager.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_pager.scss
new file mode 100644
index 0000000..0762238
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_pager.scss
@@ -0,0 +1,54 @@
+//
+// Pager pagination
+// --------------------------------------------------
+
+
+.pager {
+ padding-left: 0;
+ margin: $line-height-computed 0;
+ text-align: center;
+ list-style: none;
+ @include clearfix;
+ li {
+ display: inline;
+ > a,
+ > span {
+ display: inline-block;
+ padding: 5px 14px;
+ background-color: $pager-bg;
+ border: 1px solid $pager-border;
+ border-radius: $pager-border-radius;
+ }
+
+ > a:hover,
+ > a:focus {
+ text-decoration: none;
+ background-color: $pager-hover-bg;
+ }
+ }
+
+ .next {
+ > a,
+ > span {
+ float: right;
+ }
+ }
+
+ .previous {
+ > a,
+ > span {
+ float: left;
+ }
+ }
+
+ .disabled {
+ > a,
+ > a:hover,
+ > a:focus,
+ > span {
+ color: $pager-disabled-color;
+ cursor: $cursor-disabled;
+ background-color: $pager-bg;
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_pagination.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_pagination.scss
new file mode 100644
index 0000000..c530828
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_pagination.scss
@@ -0,0 +1,86 @@
+//
+// Pagination (multiple pages)
+// --------------------------------------------------
+.pagination {
+ display: inline-block;
+ padding-left: 0;
+ margin: $line-height-computed 0;
+ border-radius: $border-radius-base;
+
+ > li {
+ display: inline; // Remove list-style and block-level defaults
+ > a,
+ > span {
+ position: relative;
+ float: left; // Collapse white-space
+ padding: $padding-base-vertical $padding-base-horizontal;
+ margin-left: -1px;
+ line-height: $line-height-base;
+ color: $pagination-color;
+ text-decoration: none;
+ background-color: $pagination-bg;
+ border: 1px solid $pagination-border;
+
+ &:hover,
+ &:focus {
+ z-index: 2;
+ color: $pagination-hover-color;
+ background-color: $pagination-hover-bg;
+ border-color: $pagination-hover-border;
+ }
+ }
+ &:first-child {
+ > a,
+ > span {
+ margin-left: 0;
+ @include border-left-radius($border-radius-base);
+ }
+ }
+ &:last-child {
+ > a,
+ > span {
+ @include border-right-radius($border-radius-base);
+ }
+ }
+ }
+
+ > .active > a,
+ > .active > span {
+ &,
+ &:hover,
+ &:focus {
+ z-index: 3;
+ color: $pagination-active-color;
+ cursor: default;
+ background-color: $pagination-active-bg;
+ border-color: $pagination-active-border;
+ }
+ }
+
+ > .disabled {
+ > span,
+ > span:hover,
+ > span:focus,
+ > a,
+ > a:hover,
+ > a:focus {
+ color: $pagination-disabled-color;
+ cursor: $cursor-disabled;
+ background-color: $pagination-disabled-bg;
+ border-color: $pagination-disabled-border;
+ }
+ }
+}
+
+// Sizing
+// --------------------------------------------------
+
+// Large
+.pagination-lg {
+ @include pagination-size($padding-large-vertical, $padding-large-horizontal, $font-size-large, $line-height-large, $border-radius-large);
+}
+
+// Small
+.pagination-sm {
+ @include pagination-size($padding-small-vertical, $padding-small-horizontal, $font-size-small, $line-height-small, $border-radius-small);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_panels.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_panels.scss
new file mode 100644
index 0000000..8947ed2
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_panels.scss
@@ -0,0 +1,271 @@
+//
+// Panels
+// --------------------------------------------------
+
+
+// Base class
+.panel {
+ margin-bottom: $line-height-computed;
+ background-color: $panel-bg;
+ border: 1px solid transparent;
+ border-radius: $panel-border-radius;
+ @include box-shadow(0 1px 1px rgba(0, 0, 0, .05));
+}
+
+// Panel contents
+.panel-body {
+ padding: $panel-body-padding;
+ @include clearfix;
+}
+
+// Optional heading
+.panel-heading {
+ padding: $panel-heading-padding;
+ border-bottom: 1px solid transparent;
+ @include border-top-radius(($panel-border-radius - 1));
+
+ > .dropdown .dropdown-toggle {
+ color: inherit;
+ }
+}
+
+// Within heading, strip any `h*` tag of its default margins for spacing.
+.panel-title {
+ margin-top: 0;
+ margin-bottom: 0;
+ font-size: ceil(($font-size-base * 1.125));
+ color: inherit;
+
+ > a,
+ > small,
+ > .small,
+ > small > a,
+ > .small > a {
+ color: inherit;
+ }
+}
+
+// Optional footer (stays gray in every modifier class)
+.panel-footer {
+ padding: $panel-footer-padding;
+ background-color: $panel-footer-bg;
+ border-top: 1px solid $panel-inner-border;
+ @include border-bottom-radius(($panel-border-radius - 1));
+}
+
+
+// List groups in panels
+//
+// By default, space out list group content from panel headings to account for
+// any kind of custom content between the two.
+
+.panel {
+ > .list-group,
+ > .panel-collapse > .list-group {
+ margin-bottom: 0;
+
+ .list-group-item {
+ border-width: 1px 0;
+ border-radius: 0;
+ }
+
+ // Add border top radius for first one
+ &:first-child {
+ .list-group-item:first-child {
+ border-top: 0;
+ @include border-top-radius(($panel-border-radius - 1));
+ }
+ }
+
+ // Add border bottom radius for last one
+ &:last-child {
+ .list-group-item:last-child {
+ border-bottom: 0;
+ @include border-bottom-radius(($panel-border-radius - 1));
+ }
+ }
+ }
+ > .panel-heading + .panel-collapse > .list-group {
+ .list-group-item:first-child {
+ @include border-top-radius(0);
+ }
+ }
+}
+// Collapse space between when there's no additional content.
+.panel-heading + .list-group {
+ .list-group-item:first-child {
+ border-top-width: 0;
+ }
+}
+.list-group + .panel-footer {
+ border-top-width: 0;
+}
+
+// Tables in panels
+//
+// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and
+// watch it go full width.
+
+.panel {
+ > .table,
+ > .table-responsive > .table,
+ > .panel-collapse > .table {
+ margin-bottom: 0;
+
+ caption {
+ padding-right: $panel-body-padding;
+ padding-left: $panel-body-padding;
+ }
+ }
+ // Add border top radius for first one
+ > .table:first-child,
+ > .table-responsive:first-child > .table:first-child {
+ @include border-top-radius(($panel-border-radius - 1));
+
+ > thead:first-child,
+ > tbody:first-child {
+ > tr:first-child {
+ border-top-left-radius: ($panel-border-radius - 1);
+ border-top-right-radius: ($panel-border-radius - 1);
+
+ td:first-child,
+ th:first-child {
+ border-top-left-radius: ($panel-border-radius - 1);
+ }
+ td:last-child,
+ th:last-child {
+ border-top-right-radius: ($panel-border-radius - 1);
+ }
+ }
+ }
+ }
+ // Add border bottom radius for last one
+ > .table:last-child,
+ > .table-responsive:last-child > .table:last-child {
+ @include border-bottom-radius(($panel-border-radius - 1));
+
+ > tbody:last-child,
+ > tfoot:last-child {
+ > tr:last-child {
+ border-bottom-right-radius: ($panel-border-radius - 1);
+ border-bottom-left-radius: ($panel-border-radius - 1);
+
+ td:first-child,
+ th:first-child {
+ border-bottom-left-radius: ($panel-border-radius - 1);
+ }
+ td:last-child,
+ th:last-child {
+ border-bottom-right-radius: ($panel-border-radius - 1);
+ }
+ }
+ }
+ }
+ > .panel-body + .table,
+ > .panel-body + .table-responsive,
+ > .table + .panel-body,
+ > .table-responsive + .panel-body {
+ border-top: 1px solid $table-border-color;
+ }
+ > .table > tbody:first-child > tr:first-child th,
+ > .table > tbody:first-child > tr:first-child td {
+ border-top: 0;
+ }
+ > .table-bordered,
+ > .table-responsive > .table-bordered {
+ border: 0;
+ > thead,
+ > tbody,
+ > tfoot {
+ > tr {
+ > th:first-child,
+ > td:first-child {
+ border-left: 0;
+ }
+ > th:last-child,
+ > td:last-child {
+ border-right: 0;
+ }
+ }
+ }
+ > thead,
+ > tbody {
+ > tr:first-child {
+ > td,
+ > th {
+ border-bottom: 0;
+ }
+ }
+ }
+ > tbody,
+ > tfoot {
+ > tr:last-child {
+ > td,
+ > th {
+ border-bottom: 0;
+ }
+ }
+ }
+ }
+ > .table-responsive {
+ margin-bottom: 0;
+ border: 0;
+ }
+}
+
+
+// Collapsible panels (aka, accordion)
+//
+// Wrap a series of panels in `.panel-group` to turn them into an accordion with
+// the help of our collapse JavaScript plugin.
+
+.panel-group {
+ margin-bottom: $line-height-computed;
+
+ // Tighten up margin so it's only between panels
+ .panel {
+ margin-bottom: 0;
+ border-radius: $panel-border-radius;
+
+ + .panel {
+ margin-top: 5px;
+ }
+ }
+
+ .panel-heading {
+ border-bottom: 0;
+
+ + .panel-collapse > .panel-body,
+ + .panel-collapse > .list-group {
+ border-top: 1px solid $panel-inner-border;
+ }
+ }
+
+ .panel-footer {
+ border-top: 0;
+ + .panel-collapse .panel-body {
+ border-bottom: 1px solid $panel-inner-border;
+ }
+ }
+}
+
+
+// Contextual variations
+.panel-default {
+ @include panel-variant($panel-default-border, $panel-default-text, $panel-default-heading-bg, $panel-default-border);
+}
+.panel-primary {
+ @include panel-variant($panel-primary-border, $panel-primary-text, $panel-primary-heading-bg, $panel-primary-border);
+}
+.panel-success {
+ @include panel-variant($panel-success-border, $panel-success-text, $panel-success-heading-bg, $panel-success-border);
+}
+.panel-info {
+ @include panel-variant($panel-info-border, $panel-info-text, $panel-info-heading-bg, $panel-info-border);
+}
+.panel-warning {
+ @include panel-variant($panel-warning-border, $panel-warning-text, $panel-warning-heading-bg, $panel-warning-border);
+}
+.panel-danger {
+ @include panel-variant($panel-danger-border, $panel-danger-text, $panel-danger-heading-bg, $panel-danger-border);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_popovers.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_popovers.scss
new file mode 100644
index 0000000..6f83842
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_popovers.scss
@@ -0,0 +1,126 @@
+//
+// Popovers
+// --------------------------------------------------
+
+
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: $zindex-popover;
+ display: none;
+ max-width: $popover-max-width;
+ padding: 1px;
+ // Our parent element can be arbitrary since popovers are by default inserted as a sibling of their target element.
+ // So reset our font and text properties to avoid inheriting weird values.
+ @include reset-text;
+ font-size: $font-size-base;
+ background-color: $popover-bg;
+ background-clip: padding-box;
+ border: 1px solid $popover-fallback-border-color;
+ border: 1px solid $popover-border-color;
+ border-radius: $border-radius-large;
+ @include box-shadow(0 5px 10px rgba(0, 0, 0, .2));
+
+ // Offset the popover to account for the popover arrow
+ &.top { margin-top: -$popover-arrow-width; }
+ &.right { margin-left: $popover-arrow-width; }
+ &.bottom { margin-top: $popover-arrow-width; }
+ &.left { margin-left: -$popover-arrow-width; }
+
+ // Arrows
+ // .arrow is outer, .arrow:after is inner
+ > .arrow {
+ border-width: $popover-arrow-outer-width;
+
+ &,
+ &:after {
+ position: absolute;
+ display: block;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+ }
+
+ &:after {
+ content: "";
+ border-width: $popover-arrow-width;
+ }
+ }
+
+ &.top > .arrow {
+ bottom: -$popover-arrow-outer-width;
+ left: 50%;
+ margin-left: -$popover-arrow-outer-width;
+ border-top-color: $popover-arrow-outer-fallback-color; // IE8 fallback
+ border-top-color: $popover-arrow-outer-color;
+ border-bottom-width: 0;
+ &:after {
+ bottom: 1px;
+ margin-left: -$popover-arrow-width;
+ content: " ";
+ border-top-color: $popover-arrow-color;
+ border-bottom-width: 0;
+ }
+ }
+ &.right > .arrow {
+ top: 50%;
+ left: -$popover-arrow-outer-width;
+ margin-top: -$popover-arrow-outer-width;
+ border-right-color: $popover-arrow-outer-fallback-color; // IE8 fallback
+ border-right-color: $popover-arrow-outer-color;
+ border-left-width: 0;
+ &:after {
+ bottom: -$popover-arrow-width;
+ left: 1px;
+ content: " ";
+ border-right-color: $popover-arrow-color;
+ border-left-width: 0;
+ }
+ }
+ &.bottom > .arrow {
+ top: -$popover-arrow-outer-width;
+ left: 50%;
+ margin-left: -$popover-arrow-outer-width;
+ border-top-width: 0;
+ border-bottom-color: $popover-arrow-outer-fallback-color; // IE8 fallback
+ border-bottom-color: $popover-arrow-outer-color;
+ &:after {
+ top: 1px;
+ margin-left: -$popover-arrow-width;
+ content: " ";
+ border-top-width: 0;
+ border-bottom-color: $popover-arrow-color;
+ }
+ }
+
+ &.left > .arrow {
+ top: 50%;
+ right: -$popover-arrow-outer-width;
+ margin-top: -$popover-arrow-outer-width;
+ border-right-width: 0;
+ border-left-color: $popover-arrow-outer-fallback-color; // IE8 fallback
+ border-left-color: $popover-arrow-outer-color;
+ &:after {
+ right: 1px;
+ bottom: -$popover-arrow-width;
+ content: " ";
+ border-right-width: 0;
+ border-left-color: $popover-arrow-color;
+ }
+ }
+}
+
+.popover-title {
+ padding: 8px 14px;
+ margin: 0; // reset heading margin
+ font-size: $font-size-base;
+ background-color: $popover-title-bg;
+ border-bottom: 1px solid darken($popover-title-bg, 5%);
+ border-radius: ($border-radius-large - 1) ($border-radius-large - 1) 0 0;
+}
+
+.popover-content {
+ padding: 9px 14px;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_print.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_print.scss
new file mode 100644
index 0000000..564f304
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_print.scss
@@ -0,0 +1,99 @@
+/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
+
+// ==========================================================================
+// Print styles.
+// Inlined to avoid the additional HTTP request: h5bp.com/r
+// ==========================================================================
+
+@media print {
+ *,
+ *:before,
+ *:after {
+ color: #000 !important; // Black prints faster: h5bp.com/s
+ text-shadow: none !important;
+ background: transparent !important;
+ box-shadow: none !important;
+ }
+
+ a,
+ a:visited {
+ text-decoration: underline;
+ }
+
+ a[href]:after {
+ content: " (" attr(href) ")";
+ }
+
+ abbr[title]:after {
+ content: " (" attr(title) ")";
+ }
+
+ // Don't show links that are fragment identifiers,
+ // or use the `javascript:` pseudo protocol
+ a[href^="#"]:after,
+ a[href^="javascript:"]:after {
+ content: "";
+ }
+
+ pre,
+ blockquote {
+ border: 1px solid #999;
+ page-break-inside: avoid;
+ }
+
+ thead {
+ display: table-header-group; // h5bp.com/t
+ }
+
+ tr,
+ img {
+ page-break-inside: avoid;
+ }
+
+ img {
+ max-width: 100% !important;
+ }
+
+ p,
+ h2,
+ h3 {
+ orphans: 3;
+ widows: 3;
+ }
+
+ h2,
+ h3 {
+ page-break-after: avoid;
+ }
+
+ // Bootstrap specific changes start
+
+ // Bootstrap components
+ .navbar {
+ display: none;
+ }
+ .btn,
+ .dropup > .btn {
+ > .caret {
+ border-top-color: #000 !important;
+ }
+ }
+ .label {
+ border: 1px solid #000;
+ }
+
+ .table {
+ border-collapse: collapse !important;
+
+ td,
+ th {
+ background-color: #fff !important;
+ }
+ }
+ .table-bordered {
+ th,
+ td {
+ border: 1px solid #ddd !important;
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_progress-bars.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_progress-bars.scss
new file mode 100644
index 0000000..e7897de
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_progress-bars.scss
@@ -0,0 +1,87 @@
+//
+// Progress bars
+// --------------------------------------------------
+
+
+// Bar animations
+// -------------------------
+
+// WebKit
+@-webkit-keyframes progress-bar-stripes {
+ from { background-position: 40px 0; }
+ to { background-position: 0 0; }
+}
+
+// Spec and IE10+
+@keyframes progress-bar-stripes {
+ from { background-position: 40px 0; }
+ to { background-position: 0 0; }
+}
+
+
+// Bar itself
+// -------------------------
+
+// Outer container
+.progress {
+ height: $line-height-computed;
+ margin-bottom: $line-height-computed;
+ overflow: hidden;
+ background-color: $progress-bg;
+ border-radius: $progress-border-radius;
+ @include box-shadow(inset 0 1px 2px rgba(0, 0, 0, .1));
+}
+
+// Bar of progress
+.progress-bar {
+ float: left;
+ width: 0%;
+ height: 100%;
+ font-size: $font-size-small;
+ line-height: $line-height-computed;
+ color: $progress-bar-color;
+ text-align: center;
+ background-color: $progress-bar-bg;
+ @include box-shadow(inset 0 -1px 0 rgba(0, 0, 0, .15));
+ @include transition(width .6s ease);
+}
+
+// Striped bars
+//
+// `.progress-striped .progress-bar` is deprecated as of v3.2.0 in favor of the
+// `.progress-bar-striped` class, which you just add to an existing
+// `.progress-bar`.
+.progress-striped .progress-bar,
+.progress-bar-striped {
+ @include gradient-striped;
+ background-size: 40px 40px;
+}
+
+// Call animation for the active one
+//
+// `.progress.active .progress-bar` is deprecated as of v3.2.0 in favor of the
+// `.progress-bar.active` approach.
+.progress.active .progress-bar,
+.progress-bar.active {
+ @include animation(progress-bar-stripes 2s linear infinite);
+}
+
+
+// Variations
+// -------------------------
+
+.progress-bar-success {
+ @include progress-bar-variant($progress-bar-success-bg);
+}
+
+.progress-bar-info {
+ @include progress-bar-variant($progress-bar-info-bg);
+}
+
+.progress-bar-warning {
+ @include progress-bar-variant($progress-bar-warning-bg);
+}
+
+.progress-bar-danger {
+ @include progress-bar-variant($progress-bar-danger-bg);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_responsive-embed.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_responsive-embed.scss
new file mode 100644
index 0000000..5a0e0b8
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_responsive-embed.scss
@@ -0,0 +1,35 @@
+// Embeds responsive
+//
+// Credit: Nicolas Gallagher and SUIT CSS.
+
+.embed-responsive {
+ position: relative;
+ display: block;
+ height: 0;
+ padding: 0;
+ overflow: hidden;
+
+ .embed-responsive-item,
+ iframe,
+ embed,
+ object,
+ video {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: 0;
+ }
+}
+
+// Modifier class for 16:9 aspect ratio
+.embed-responsive-16by9 {
+ padding-bottom: 56.25%;
+}
+
+// Modifier class for 4:3 aspect ratio
+.embed-responsive-4by3 {
+ padding-bottom: 75%;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_responsive-utilities.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_responsive-utilities.scss
new file mode 100644
index 0000000..73641aa
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_responsive-utilities.scss
@@ -0,0 +1,179 @@
+//
+// Responsive: Utility classes
+// --------------------------------------------------
+
+
+// IE10 in Windows (Phone) 8
+//
+// Support for responsive views via media queries is kind of borked in IE10, for
+// Surface/desktop in split view and for Windows Phone 8. This particular fix
+// must be accompanied by a snippet of JavaScript to sniff the user agent and
+// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at
+// our Getting Started page for more information on this bug.
+//
+// For more information, see the following:
+//
+// Issue: https://github.com/twbs/bootstrap/issues/10497
+// Docs: https://getbootstrap.com/docs/3.4/getting-started/#support-ie10-width
+// Source: https://timkadlec.com/2013/01/windows-phone-8-and-device-width/
+// Source: https://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/
+
+@at-root {
+ @-ms-viewport {
+ width: device-width;
+ }
+}
+
+
+// Visibility utilities
+// Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0
+
+@include responsive-invisibility('.visible-xs');
+@include responsive-invisibility('.visible-sm');
+@include responsive-invisibility('.visible-md');
+@include responsive-invisibility('.visible-lg');
+
+.visible-xs-block,
+.visible-xs-inline,
+.visible-xs-inline-block,
+.visible-sm-block,
+.visible-sm-inline,
+.visible-sm-inline-block,
+.visible-md-block,
+.visible-md-inline,
+.visible-md-inline-block,
+.visible-lg-block,
+.visible-lg-inline,
+.visible-lg-inline-block {
+ display: none !important;
+}
+
+@media (max-width: $screen-xs-max) {
+ @include responsive-visibility('.visible-xs');
+}
+.visible-xs-block {
+ @media (max-width: $screen-xs-max) {
+ display: block !important;
+ }
+}
+.visible-xs-inline {
+ @media (max-width: $screen-xs-max) {
+ display: inline !important;
+ }
+}
+.visible-xs-inline-block {
+ @media (max-width: $screen-xs-max) {
+ display: inline-block !important;
+ }
+}
+
+@media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
+ @include responsive-visibility('.visible-sm');
+}
+.visible-sm-block {
+ @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
+ display: block !important;
+ }
+}
+.visible-sm-inline {
+ @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
+ display: inline !important;
+ }
+}
+.visible-sm-inline-block {
+ @media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
+ display: inline-block !important;
+ }
+}
+
+@media (min-width: $screen-md-min) and (max-width: $screen-md-max) {
+ @include responsive-visibility('.visible-md');
+}
+.visible-md-block {
+ @media (min-width: $screen-md-min) and (max-width: $screen-md-max) {
+ display: block !important;
+ }
+}
+.visible-md-inline {
+ @media (min-width: $screen-md-min) and (max-width: $screen-md-max) {
+ display: inline !important;
+ }
+}
+.visible-md-inline-block {
+ @media (min-width: $screen-md-min) and (max-width: $screen-md-max) {
+ display: inline-block !important;
+ }
+}
+
+@media (min-width: $screen-lg-min) {
+ @include responsive-visibility('.visible-lg');
+}
+.visible-lg-block {
+ @media (min-width: $screen-lg-min) {
+ display: block !important;
+ }
+}
+.visible-lg-inline {
+ @media (min-width: $screen-lg-min) {
+ display: inline !important;
+ }
+}
+.visible-lg-inline-block {
+ @media (min-width: $screen-lg-min) {
+ display: inline-block !important;
+ }
+}
+
+@media (max-width: $screen-xs-max) {
+ @include responsive-invisibility('.hidden-xs');
+}
+
+@media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
+ @include responsive-invisibility('.hidden-sm');
+}
+
+@media (min-width: $screen-md-min) and (max-width: $screen-md-max) {
+ @include responsive-invisibility('.hidden-md');
+}
+
+@media (min-width: $screen-lg-min) {
+ @include responsive-invisibility('.hidden-lg');
+}
+
+
+// Print utilities
+//
+// Media queries are placed on the inside to be mixin-friendly.
+
+// Note: Deprecated .visible-print as of v3.2.0
+
+@include responsive-invisibility('.visible-print');
+
+@media print {
+ @include responsive-visibility('.visible-print');
+}
+.visible-print-block {
+ display: none !important;
+
+ @media print {
+ display: block !important;
+ }
+}
+.visible-print-inline {
+ display: none !important;
+
+ @media print {
+ display: inline !important;
+ }
+}
+.visible-print-inline-block {
+ display: none !important;
+
+ @media print {
+ display: inline-block !important;
+ }
+}
+
+@media print {
+ @include responsive-invisibility('.hidden-print');
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_scaffolding.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_scaffolding.scss
new file mode 100644
index 0000000..7fda593
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_scaffolding.scss
@@ -0,0 +1,161 @@
+//
+// Scaffolding
+// --------------------------------------------------
+
+
+// Reset the box-sizing
+//
+// Heads up! This reset may cause conflicts with some third-party widgets.
+// For recommendations on resolving such conflicts, see
+// https://getbootstrap.com/docs/3.4/getting-started/#third-box-sizing
+* {
+ @include box-sizing(border-box);
+}
+*:before,
+*:after {
+ @include box-sizing(border-box);
+}
+
+
+// Body reset
+
+html {
+ font-size: 10px;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+body {
+ font-family: $font-family-base;
+ font-size: $font-size-base;
+ line-height: $line-height-base;
+ color: $text-color;
+ background-color: $body-bg;
+}
+
+// Reset fonts for relevant elements
+input,
+button,
+select,
+textarea {
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+
+
+// Links
+
+a {
+ color: $link-color;
+ text-decoration: none;
+
+ &:hover,
+ &:focus {
+ color: $link-hover-color;
+ text-decoration: $link-hover-decoration;
+ }
+
+ &:focus {
+ @include tab-focus;
+ }
+}
+
+
+// Figures
+//
+// We reset this here because previously Normalize had no `figure` margins. This
+// ensures we don't break anyone's use of the element.
+
+figure {
+ margin: 0;
+}
+
+
+// Images
+
+img {
+ vertical-align: middle;
+}
+
+// Responsive images (ensure images don't scale beyond their parents)
+.img-responsive {
+ @include img-responsive;
+}
+
+// Rounded corners
+.img-rounded {
+ border-radius: $border-radius-large;
+}
+
+// Image thumbnails
+//
+// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.
+.img-thumbnail {
+ padding: $thumbnail-padding;
+ line-height: $line-height-base;
+ background-color: $thumbnail-bg;
+ border: 1px solid $thumbnail-border;
+ border-radius: $thumbnail-border-radius;
+ @include transition(all .2s ease-in-out);
+
+ // Keep them at most 100% wide
+ @include img-responsive(inline-block);
+}
+
+// Perfect circle
+.img-circle {
+ border-radius: 50%; // set radius in percents
+}
+
+
+// Horizontal rules
+
+hr {
+ margin-top: $line-height-computed;
+ margin-bottom: $line-height-computed;
+ border: 0;
+ border-top: 1px solid $hr-border;
+}
+
+
+// Only display content to screen readers
+//
+// See: https://a11yproject.com/posts/how-to-hide-content
+
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+
+// Use in conjunction with .sr-only to only display content when it's focused.
+// Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
+// Credit: HTML5 Boilerplate
+
+.sr-only-focusable {
+ &:active,
+ &:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+ }
+}
+
+
+// iOS "clickable elements" fix for role="button"
+//
+// Fixes "clickability" issue (and more generally, the firing of events such as focus as well)
+// for traditionally non-focusable elements with role="button"
+// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
+
+[role="button"] {
+ cursor: pointer;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_tables.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_tables.scss
new file mode 100644
index 0000000..7bff4b0
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_tables.scss
@@ -0,0 +1,234 @@
+//
+// Tables
+// --------------------------------------------------
+
+
+table {
+ background-color: $table-bg;
+
+ // Table cell sizing
+ //
+ // Reset default table behavior
+
+ col[class*="col-"] {
+ position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)
+ display: table-column;
+ float: none;
+ }
+
+ td,
+ th {
+ &[class*="col-"] {
+ position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)
+ display: table-cell;
+ float: none;
+ }
+ }
+}
+
+caption {
+ padding-top: $table-cell-padding;
+ padding-bottom: $table-cell-padding;
+ color: $text-muted;
+ text-align: left;
+}
+
+th {
+ text-align: left;
+}
+
+
+// Baseline styles
+
+.table {
+ width: 100%;
+ max-width: 100%;
+ margin-bottom: $line-height-computed;
+ // Cells
+ > thead,
+ > tbody,
+ > tfoot {
+ > tr {
+ > th,
+ > td {
+ padding: $table-cell-padding;
+ line-height: $line-height-base;
+ vertical-align: top;
+ border-top: 1px solid $table-border-color;
+ }
+ }
+ }
+ // Bottom align for column headings
+ > thead > tr > th {
+ vertical-align: bottom;
+ border-bottom: 2px solid $table-border-color;
+ }
+ // Remove top border from thead by default
+ > caption + thead,
+ > colgroup + thead,
+ > thead:first-child {
+ > tr:first-child {
+ > th,
+ > td {
+ border-top: 0;
+ }
+ }
+ }
+ // Account for multiple tbody instances
+ > tbody + tbody {
+ border-top: 2px solid $table-border-color;
+ }
+
+ // Nesting
+ .table {
+ background-color: $body-bg;
+ }
+}
+
+
+// Condensed table w/ half padding
+
+.table-condensed {
+ > thead,
+ > tbody,
+ > tfoot {
+ > tr {
+ > th,
+ > td {
+ padding: $table-condensed-cell-padding;
+ }
+ }
+ }
+}
+
+
+// Bordered version
+//
+// Add borders all around the table and between all the columns.
+
+.table-bordered {
+ border: 1px solid $table-border-color;
+ > thead,
+ > tbody,
+ > tfoot {
+ > tr {
+ > th,
+ > td {
+ border: 1px solid $table-border-color;
+ }
+ }
+ }
+ > thead > tr {
+ > th,
+ > td {
+ border-bottom-width: 2px;
+ }
+ }
+}
+
+
+// Zebra-striping
+//
+// Default zebra-stripe styles (alternating gray and transparent backgrounds)
+
+.table-striped {
+ > tbody > tr:nth-of-type(odd) {
+ background-color: $table-bg-accent;
+ }
+}
+
+
+// Hover effect
+//
+// Placed here since it has to come after the potential zebra striping
+
+.table-hover {
+ > tbody > tr:hover {
+ background-color: $table-bg-hover;
+ }
+}
+
+
+// Table backgrounds
+//
+// Exact selectors below required to override `.table-striped` and prevent
+// inheritance to nested tables.
+
+// Generate the contextual variants
+@include table-row-variant('active', $table-bg-active);
+@include table-row-variant('success', $state-success-bg);
+@include table-row-variant('info', $state-info-bg);
+@include table-row-variant('warning', $state-warning-bg);
+@include table-row-variant('danger', $state-danger-bg);
+
+
+// Responsive tables
+//
+// Wrap your tables in `.table-responsive` and we'll make them mobile friendly
+// by enabling horizontal scrolling. Only applies <768px. Everything above that
+// will display normally.
+
+.table-responsive {
+ min-height: .01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)
+ overflow-x: auto;
+
+ @media screen and (max-width: $screen-xs-max) {
+ width: 100%;
+ margin-bottom: ($line-height-computed * .75);
+ overflow-y: hidden;
+ -ms-overflow-style: -ms-autohiding-scrollbar;
+ border: 1px solid $table-border-color;
+
+ // Tighten up spacing
+ > .table {
+ margin-bottom: 0;
+
+ // Ensure the content doesn't wrap
+ > thead,
+ > tbody,
+ > tfoot {
+ > tr {
+ > th,
+ > td {
+ white-space: nowrap;
+ }
+ }
+ }
+ }
+
+ // Special overrides for the bordered tables
+ > .table-bordered {
+ border: 0;
+
+ // Nuke the appropriate borders so that the parent can handle them
+ > thead,
+ > tbody,
+ > tfoot {
+ > tr {
+ > th:first-child,
+ > td:first-child {
+ border-left: 0;
+ }
+ > th:last-child,
+ > td:last-child {
+ border-right: 0;
+ }
+ }
+ }
+
+ // Only nuke the last row's bottom-border in `tbody` and `tfoot` since
+ // chances are there will be only one `tr` in a `thead` and that would
+ // remove the border altogether.
+ > tbody,
+ > tfoot {
+ > tr:last-child {
+ > th,
+ > td {
+ border-bottom: 0;
+ }
+ }
+ }
+
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_theme.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_theme.scss
new file mode 100644
index 0000000..046eed7
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_theme.scss
@@ -0,0 +1,295 @@
+/*!
+ * Bootstrap v3.4.1 (https://getbootstrap.com/)
+ * Copyright 2011-2019 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+//
+// Load core variables and mixins
+// --------------------------------------------------
+
+@import "variables";
+@import "mixins";
+
+
+//
+// Buttons
+// --------------------------------------------------
+
+// Common styles
+.btn-default,
+.btn-primary,
+.btn-success,
+.btn-info,
+.btn-warning,
+.btn-danger {
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
+ $shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
+ @include box-shadow($shadow);
+
+ // Reset the shadow
+ &:active,
+ &.active {
+ @include box-shadow(inset 0 3px 5px rgba(0, 0, 0, .125));
+ }
+
+ &.disabled,
+ &[disabled],
+ fieldset[disabled] & {
+ @include box-shadow(none);
+ }
+
+ .badge {
+ text-shadow: none;
+ }
+}
+
+// Mixin for generating new styles
+@mixin btn-styles($btn-color: #555) {
+ @include gradient-vertical($start-color: $btn-color, $end-color: darken($btn-color, 12%));
+ @include reset-filter; // Disable gradients for IE9 because filter bleeds through rounded corners; see https://github.com/twbs/bootstrap/issues/10620
+ background-repeat: repeat-x;
+ border-color: darken($btn-color, 14%);
+
+ &:hover,
+ &:focus {
+ background-color: darken($btn-color, 12%);
+ background-position: 0 -15px;
+ }
+
+ &:active,
+ &.active {
+ background-color: darken($btn-color, 12%);
+ border-color: darken($btn-color, 14%);
+ }
+
+ &.disabled,
+ &[disabled],
+ fieldset[disabled] & {
+ &,
+ &:hover,
+ &:focus,
+ &.focus,
+ &:active,
+ &.active {
+ background-color: darken($btn-color, 12%);
+ background-image: none;
+ }
+ }
+}
+
+// Common styles
+.btn {
+ // Remove the gradient for the pressed/active state
+ &:active,
+ &.active {
+ background-image: none;
+ }
+}
+
+// Apply the mixin to the buttons
+.btn-default {
+ @include btn-styles($btn-default-bg);
+ text-shadow: 0 1px 0 #fff;
+ border-color: #ccc;
+}
+.btn-primary { @include btn-styles($btn-primary-bg); }
+.btn-success { @include btn-styles($btn-success-bg); }
+.btn-info { @include btn-styles($btn-info-bg); }
+.btn-warning { @include btn-styles($btn-warning-bg); }
+.btn-danger { @include btn-styles($btn-danger-bg); }
+
+
+//
+// Images
+// --------------------------------------------------
+
+.thumbnail,
+.img-thumbnail {
+ @include box-shadow(0 1px 2px rgba(0, 0, 0, .075));
+}
+
+
+//
+// Dropdowns
+// --------------------------------------------------
+
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+ @include gradient-vertical($start-color: $dropdown-link-hover-bg, $end-color: darken($dropdown-link-hover-bg, 5%));
+ background-color: darken($dropdown-link-hover-bg, 5%);
+}
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+ @include gradient-vertical($start-color: $dropdown-link-active-bg, $end-color: darken($dropdown-link-active-bg, 5%));
+ background-color: darken($dropdown-link-active-bg, 5%);
+}
+
+
+//
+// Navbar
+// --------------------------------------------------
+
+// Default navbar
+.navbar-default {
+ @include gradient-vertical($start-color: lighten($navbar-default-bg, 10%), $end-color: $navbar-default-bg);
+ @include reset-filter; // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered
+ border-radius: $navbar-border-radius;
+ $shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
+ @include box-shadow($shadow);
+
+ .navbar-nav > .open > a,
+ .navbar-nav > .active > a {
+ @include gradient-vertical($start-color: darken($navbar-default-link-active-bg, 5%), $end-color: darken($navbar-default-link-active-bg, 2%));
+ @include box-shadow(inset 0 3px 9px rgba(0, 0, 0, .075));
+ }
+}
+.navbar-brand,
+.navbar-nav > li > a {
+ text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
+}
+
+// Inverted navbar
+.navbar-inverse {
+ @include gradient-vertical($start-color: lighten($navbar-inverse-bg, 10%), $end-color: $navbar-inverse-bg);
+ @include reset-filter; // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered; see https://github.com/twbs/bootstrap/issues/10257
+ border-radius: $navbar-border-radius;
+ .navbar-nav > .open > a,
+ .navbar-nav > .active > a {
+ @include gradient-vertical($start-color: $navbar-inverse-link-active-bg, $end-color: lighten($navbar-inverse-link-active-bg, 2.5%));
+ @include box-shadow(inset 0 3px 9px rgba(0, 0, 0, .25));
+ }
+
+ .navbar-brand,
+ .navbar-nav > li > a {
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
+ }
+}
+
+// Undo rounded corners in static and fixed navbars
+.navbar-static-top,
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ border-radius: 0;
+}
+
+// Fix active state of dropdown items in collapsed mode
+@media (max-width: $grid-float-breakpoint-max) {
+ .navbar .navbar-nav .open .dropdown-menu > .active > a {
+ &,
+ &:hover,
+ &:focus {
+ color: #fff;
+ @include gradient-vertical($start-color: $dropdown-link-active-bg, $end-color: darken($dropdown-link-active-bg, 5%));
+ }
+ }
+}
+
+
+//
+// Alerts
+// --------------------------------------------------
+
+// Common styles
+.alert {
+ text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
+ $shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
+ @include box-shadow($shadow);
+}
+
+// Mixin for generating new styles
+@mixin alert-styles($color) {
+ @include gradient-vertical($start-color: $color, $end-color: darken($color, 7.5%));
+ border-color: darken($color, 15%);
+}
+
+// Apply the mixin to the alerts
+.alert-success { @include alert-styles($alert-success-bg); }
+.alert-info { @include alert-styles($alert-info-bg); }
+.alert-warning { @include alert-styles($alert-warning-bg); }
+.alert-danger { @include alert-styles($alert-danger-bg); }
+
+
+//
+// Progress bars
+// --------------------------------------------------
+
+// Give the progress background some depth
+.progress {
+ @include gradient-vertical($start-color: darken($progress-bg, 4%), $end-color: $progress-bg)
+}
+
+// Mixin for generating new styles
+@mixin progress-bar-styles($color) {
+ @include gradient-vertical($start-color: $color, $end-color: darken($color, 10%));
+}
+
+// Apply the mixin to the progress bars
+.progress-bar { @include progress-bar-styles($progress-bar-bg); }
+.progress-bar-success { @include progress-bar-styles($progress-bar-success-bg); }
+.progress-bar-info { @include progress-bar-styles($progress-bar-info-bg); }
+.progress-bar-warning { @include progress-bar-styles($progress-bar-warning-bg); }
+.progress-bar-danger { @include progress-bar-styles($progress-bar-danger-bg); }
+
+// Reset the striped class because our mixins don't do multiple gradients and
+// the above custom styles override the new `.progress-bar-striped` in v3.2.0.
+.progress-bar-striped {
+ @include gradient-striped;
+}
+
+
+//
+// List groups
+// --------------------------------------------------
+
+.list-group {
+ border-radius: $border-radius-base;
+ @include box-shadow(0 1px 2px rgba(0, 0, 0, .075));
+}
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+ text-shadow: 0 -1px 0 darken($list-group-active-bg, 10%);
+ @include gradient-vertical($start-color: $list-group-active-bg, $end-color: darken($list-group-active-bg, 7.5%));
+ border-color: darken($list-group-active-border, 7.5%);
+
+ .badge {
+ text-shadow: none;
+ }
+}
+
+
+//
+// Panels
+// --------------------------------------------------
+
+// Common styles
+.panel {
+ @include box-shadow(0 1px 2px rgba(0, 0, 0, .05));
+}
+
+// Mixin for generating new styles
+@mixin panel-heading-styles($color) {
+ @include gradient-vertical($start-color: $color, $end-color: darken($color, 5%));
+}
+
+// Apply the mixin to the panel headings only
+.panel-default > .panel-heading { @include panel-heading-styles($panel-default-heading-bg); }
+.panel-primary > .panel-heading { @include panel-heading-styles($panel-primary-heading-bg); }
+.panel-success > .panel-heading { @include panel-heading-styles($panel-success-heading-bg); }
+.panel-info > .panel-heading { @include panel-heading-styles($panel-info-heading-bg); }
+.panel-warning > .panel-heading { @include panel-heading-styles($panel-warning-heading-bg); }
+.panel-danger > .panel-heading { @include panel-heading-styles($panel-danger-heading-bg); }
+
+
+//
+// Wells
+// --------------------------------------------------
+
+.well {
+ @include gradient-vertical($start-color: darken($well-bg, 5%), $end-color: $well-bg);
+ border-color: darken($well-bg, 10%);
+ $shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
+ @include box-shadow($shadow);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_thumbnails.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_thumbnails.scss
new file mode 100644
index 0000000..835452f
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_thumbnails.scss
@@ -0,0 +1,38 @@
+//
+// Thumbnails
+// --------------------------------------------------
+
+
+// Mixin and adjust the regular image class
+.thumbnail {
+ display: block;
+ padding: $thumbnail-padding;
+ margin-bottom: $line-height-computed;
+ line-height: $line-height-base;
+ background-color: $thumbnail-bg;
+ border: 1px solid $thumbnail-border;
+ border-radius: $thumbnail-border-radius;
+ @include transition(border .2s ease-in-out);
+
+ > img,
+ a > img {
+ @include img-responsive;
+ margin-right: auto;
+ margin-left: auto;
+ }
+
+ // [converter] extracted a&:hover, a&:focus, a&.active to a.thumbnail:hover, a.thumbnail:focus, a.thumbnail.active
+
+ // Image captions
+ .caption {
+ padding: $thumbnail-caption-padding;
+ color: $thumbnail-caption-color;
+ }
+}
+
+// Add a hover state for linked versions only
+a.thumbnail:hover,
+a.thumbnail:focus,
+a.thumbnail.active {
+ border-color: $link-color;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_tooltip.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_tooltip.scss
new file mode 100644
index 0000000..fa69a81
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_tooltip.scss
@@ -0,0 +1,112 @@
+//
+// Tooltips
+// --------------------------------------------------
+
+
+// Base class
+.tooltip {
+ position: absolute;
+ z-index: $zindex-tooltip;
+ display: block;
+ // Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
+ // So reset our font and text properties to avoid inheriting weird values.
+ @include reset-text;
+ font-size: $font-size-small;
+
+ @include opacity(0);
+
+ &.in { @include opacity($tooltip-opacity); }
+ &.top {
+ padding: $tooltip-arrow-width 0;
+ margin-top: -3px;
+ }
+ &.right {
+ padding: 0 $tooltip-arrow-width;
+ margin-left: 3px;
+ }
+ &.bottom {
+ padding: $tooltip-arrow-width 0;
+ margin-top: 3px;
+ }
+ &.left {
+ padding: 0 $tooltip-arrow-width;
+ margin-left: -3px;
+ }
+
+ // Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1
+ &.top .tooltip-arrow {
+ bottom: 0;
+ left: 50%;
+ margin-left: -$tooltip-arrow-width;
+ border-width: $tooltip-arrow-width $tooltip-arrow-width 0;
+ border-top-color: $tooltip-arrow-color;
+ }
+ &.top-left .tooltip-arrow {
+ right: $tooltip-arrow-width;
+ bottom: 0;
+ margin-bottom: -$tooltip-arrow-width;
+ border-width: $tooltip-arrow-width $tooltip-arrow-width 0;
+ border-top-color: $tooltip-arrow-color;
+ }
+ &.top-right .tooltip-arrow {
+ bottom: 0;
+ left: $tooltip-arrow-width;
+ margin-bottom: -$tooltip-arrow-width;
+ border-width: $tooltip-arrow-width $tooltip-arrow-width 0;
+ border-top-color: $tooltip-arrow-color;
+ }
+ &.right .tooltip-arrow {
+ top: 50%;
+ left: 0;
+ margin-top: -$tooltip-arrow-width;
+ border-width: $tooltip-arrow-width $tooltip-arrow-width $tooltip-arrow-width 0;
+ border-right-color: $tooltip-arrow-color;
+ }
+ &.left .tooltip-arrow {
+ top: 50%;
+ right: 0;
+ margin-top: -$tooltip-arrow-width;
+ border-width: $tooltip-arrow-width 0 $tooltip-arrow-width $tooltip-arrow-width;
+ border-left-color: $tooltip-arrow-color;
+ }
+ &.bottom .tooltip-arrow {
+ top: 0;
+ left: 50%;
+ margin-left: -$tooltip-arrow-width;
+ border-width: 0 $tooltip-arrow-width $tooltip-arrow-width;
+ border-bottom-color: $tooltip-arrow-color;
+ }
+ &.bottom-left .tooltip-arrow {
+ top: 0;
+ right: $tooltip-arrow-width;
+ margin-top: -$tooltip-arrow-width;
+ border-width: 0 $tooltip-arrow-width $tooltip-arrow-width;
+ border-bottom-color: $tooltip-arrow-color;
+ }
+ &.bottom-right .tooltip-arrow {
+ top: 0;
+ left: $tooltip-arrow-width;
+ margin-top: -$tooltip-arrow-width;
+ border-width: 0 $tooltip-arrow-width $tooltip-arrow-width;
+ border-bottom-color: $tooltip-arrow-color;
+ }
+}
+
+// Wrapper for the tooltip content
+.tooltip-inner {
+ max-width: $tooltip-max-width;
+ padding: 3px 8px;
+ color: $tooltip-color;
+ text-align: center;
+ background-color: $tooltip-bg;
+ border-radius: $border-radius-base;
+}
+
+// Arrows
+.tooltip-arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_type.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_type.scss
new file mode 100644
index 0000000..ac2eccd
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_type.scss
@@ -0,0 +1,299 @@
+@use "sass:math";
+//
+// Typography
+// --------------------------------------------------
+
+
+// Headings
+// -------------------------
+
+h1, h2, h3, h4, h5, h6,
+.h1, .h2, .h3, .h4, .h5, .h6 {
+ font-family: $headings-font-family;
+ font-weight: $headings-font-weight;
+ line-height: $headings-line-height;
+ color: $headings-color;
+
+ small,
+ .small {
+ font-weight: 400;
+ line-height: 1;
+ color: $headings-small-color;
+ }
+}
+
+h1, .h1,
+h2, .h2,
+h3, .h3 {
+ margin-top: $line-height-computed;
+ margin-bottom: math.div($line-height-computed, 2);
+
+ small,
+ .small {
+ font-size: 65%;
+ }
+}
+h4, .h4,
+h5, .h5,
+h6, .h6 {
+ margin-top: math.div($line-height-computed, 2);
+ margin-bottom: math.div($line-height-computed, 2);
+
+ small,
+ .small {
+ font-size: 75%;
+ }
+}
+
+h1, .h1 { font-size: $font-size-h1; }
+h2, .h2 { font-size: $font-size-h2; }
+h3, .h3 { font-size: $font-size-h3; }
+h4, .h4 { font-size: $font-size-h4; }
+h5, .h5 { font-size: $font-size-h5; }
+h6, .h6 { font-size: $font-size-h6; }
+
+
+// Body text
+// -------------------------
+
+p {
+ margin: 0 0 math.div($line-height-computed, 2);
+}
+
+.lead {
+ margin-bottom: $line-height-computed;
+ font-size: floor(($font-size-base * 1.15));
+ font-weight: 300;
+ line-height: 1.4;
+
+ @media (min-width: $screen-sm-min) {
+ font-size: ($font-size-base * 1.5);
+ }
+}
+
+
+// Emphasis & misc
+// -------------------------
+
+// Ex: math.div(12px small font, 14px base font) * 100% = about 85%
+small,
+.small {
+ font-size: floor(math.div(100% * $font-size-small, $font-size-base));
+}
+
+mark,
+.mark {
+ padding: .2em;
+ background-color: $state-warning-bg;
+}
+
+// Alignment
+.text-left { text-align: left; }
+.text-right { text-align: right; }
+.text-center { text-align: center; }
+.text-justify { text-align: justify; }
+.text-nowrap { white-space: nowrap; }
+
+// Transformation
+.text-lowercase { text-transform: lowercase; }
+.text-uppercase { text-transform: uppercase; }
+.text-capitalize { text-transform: capitalize; }
+
+// Contextual colors
+.text-muted {
+ color: $text-muted;
+}
+
+@include text-emphasis-variant('.text-primary', $brand-primary);
+
+@include text-emphasis-variant('.text-success', $state-success-text);
+
+@include text-emphasis-variant('.text-info', $state-info-text);
+
+@include text-emphasis-variant('.text-warning', $state-warning-text);
+
+@include text-emphasis-variant('.text-danger', $state-danger-text);
+
+// Contextual backgrounds
+// For now we'll leave these alongside the text classes until v4 when we can
+// safely shift things around (per SemVer rules).
+.bg-primary {
+ // Given the contrast here, this is the only class to have its color inverted
+ // automatically.
+ color: #fff;
+}
+@include bg-variant('.bg-primary', $brand-primary);
+
+@include bg-variant('.bg-success', $state-success-bg);
+
+@include bg-variant('.bg-info', $state-info-bg);
+
+@include bg-variant('.bg-warning', $state-warning-bg);
+
+@include bg-variant('.bg-danger', $state-danger-bg);
+
+
+// Page header
+// -------------------------
+
+.page-header {
+ padding-bottom: (math.div($line-height-computed, 2) - 1);
+ margin: ($line-height-computed * 2) 0 $line-height-computed;
+ border-bottom: 1px solid $page-header-border-color;
+}
+
+
+// Lists
+// -------------------------
+
+// Unordered and Ordered lists
+ul,
+ol {
+ margin-top: 0;
+ margin-bottom: math.div($line-height-computed, 2);
+ ul,
+ ol {
+ margin-bottom: 0;
+ }
+}
+
+// List options
+
+// [converter] extracted from `.list-unstyled` for libsass compatibility
+@mixin list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
+// [converter] extracted as `@mixin list-unstyled` for libsass compatibility
+.list-unstyled {
+ @include list-unstyled;
+}
+
+
+// Inline turns list items into inline-block
+.list-inline {
+ @include list-unstyled;
+ margin-left: -5px;
+
+ > li {
+ display: inline-block;
+ padding-right: 5px;
+ padding-left: 5px;
+ }
+}
+
+// Description Lists
+dl {
+ margin-top: 0; // Remove browser default
+ margin-bottom: $line-height-computed;
+}
+dt,
+dd {
+ line-height: $line-height-base;
+}
+dt {
+ font-weight: 700;
+}
+dd {
+ margin-left: 0; // Undo browser default
+}
+
+// Horizontal description lists
+//
+// Defaults to being stacked without any of the below styles applied, until the
+// grid breakpoint is reached (default of ~768px).
+
+.dl-horizontal {
+ dd {
+ @include clearfix; // Clear the floated `dt` if an empty `dd` is present
+ }
+
+ @media (min-width: $dl-horizontal-breakpoint) {
+ dt {
+ float: left;
+ width: ($dl-horizontal-offset - 20);
+ clear: left;
+ text-align: right;
+ @include text-overflow;
+ }
+ dd {
+ margin-left: $dl-horizontal-offset;
+ }
+ }
+}
+
+
+// Misc
+// -------------------------
+
+// Abbreviations and acronyms
+// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257
+abbr[title],
+abbr[data-original-title] {
+ cursor: help;
+}
+
+.initialism {
+ font-size: 90%;
+ @extend .text-uppercase;
+}
+
+// Blockquotes
+blockquote {
+ padding: math.div($line-height-computed, 2) $line-height-computed;
+ margin: 0 0 $line-height-computed;
+ font-size: $blockquote-font-size;
+ border-left: 5px solid $blockquote-border-color;
+
+ p,
+ ul,
+ ol {
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ // Note: Deprecated small and .small as of v3.1.0
+ // Context: https://github.com/twbs/bootstrap/issues/11660
+ footer,
+ small,
+ .small {
+ display: block;
+ font-size: 80%; // back to default font-size
+ line-height: $line-height-base;
+ color: $blockquote-small-color;
+
+ &:before {
+ content: "\2014 \00A0"; // em dash, nbsp
+ }
+ }
+}
+
+// Opposite alignment of blockquote
+//
+// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.
+.blockquote-reverse,
+blockquote.pull-right {
+ padding-right: 15px;
+ padding-left: 0;
+ text-align: right;
+ border-right: 5px solid $blockquote-border-color;
+ border-left: 0;
+
+ // Account for citation
+ footer,
+ small,
+ .small {
+ &:before { content: ""; }
+ &:after {
+ content: "\00A0 \2014"; // nbsp, em dash
+ }
+ }
+}
+
+// Addresses
+address {
+ margin-bottom: $line-height-computed;
+ font-style: normal;
+ line-height: $line-height-base;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_utilities.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_utilities.scss
new file mode 100644
index 0000000..8c99c71
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_utilities.scss
@@ -0,0 +1,55 @@
+//
+// Utility classes
+// --------------------------------------------------
+
+
+// Floats
+// -------------------------
+
+.clearfix {
+ @include clearfix;
+}
+.center-block {
+ @include center-block;
+}
+.pull-right {
+ float: right !important;
+}
+.pull-left {
+ float: left !important;
+}
+
+
+// Toggling content
+// -------------------------
+
+// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1
+.hide {
+ display: none !important;
+}
+.show {
+ display: block !important;
+}
+.invisible {
+ visibility: hidden;
+}
+.text-hide {
+ @include text-hide;
+}
+
+
+// Hide from screenreaders and browsers
+//
+// Credit: HTML5 Boilerplate
+
+.hidden {
+ display: none !important;
+}
+
+
+// For Affix plugin
+// -------------------------
+
+.affix {
+ position: fixed;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_variables.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_variables.scss
new file mode 100644
index 0000000..5153e1b
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_variables.scss
@@ -0,0 +1,883 @@
+$bootstrap-sass-asset-helper: false !default;
+@use "sass:math";
+//
+// Variables
+// --------------------------------------------------
+
+:root {
+ --main-bg-color: brown;
+ --h1: 26px;
+ --h2: 22px;
+ --h3: 18px;
+ --text-base: 16px;
+ --carousel-bg: var(--main-bg-color);
+}
+
+//== Colors
+//
+//## Gray and brand colors for use across Bootstrap.
+
+$gray-base: #000 !default;
+$gray-darker: lighten($gray-base, 13.5%) !default; // #222
+$gray-dark: lighten($gray-base, 20%) !default; // #333
+$gray: lighten($gray-base, 33.5%) !default; // #555
+$gray-light: lighten($gray-base, 46.7%) !default; // #777
+$gray-lighter: lighten($gray-base, 93.5%) !default; // #eee
+
+$brand-primary: darken(#428bca, 6.5%) !default; // #337ab7
+$brand-success: #5cb85c !default;
+$brand-info: #5bc0de !default;
+$brand-warning: #f0ad4e !default;
+$brand-danger: #d9534f !default;
+
+
+//== Scaffolding
+//
+//## Settings for some of the most global styles.
+
+//** Background color for ``.
+$body-bg: #fff !default;
+//** Global text color on ``.
+$text-color: $gray-dark !default;
+
+//** Global textual link color.
+$link-color: $brand-primary !default;
+//** Link hover color set via `darken()` function.
+$link-hover-color: darken($link-color, 15%) !default;
+//** Link hover decoration.
+$link-hover-decoration: underline !default;
+
+
+//== Typography
+//
+//## Font, line-height, and color for body text, headings, and more.
+
+$font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif !default;
+$font-family-serif: Georgia, "Times New Roman", Times, serif !default;
+//** Default monospace fonts for `
`, ``, and ``.
+$font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace !default;
+$font-family-base: $font-family-sans-serif !default;
+
+$font-size-base: 14px !default;
+$font-size-large: ceil(($font-size-base * 1.25)) !default; // ~18px
+$font-size-small: ceil(($font-size-base * .85)) !default; // ~12px
+
+$font-size-h1: floor(($font-size-base * 2.6)) !default; // ~36px
+$font-size-h2: floor(($font-size-base * 2.15)) !default; // ~30px
+$font-size-h3: ceil(($font-size-base * 1.7)) !default; // ~24px
+$font-size-h4: ceil(($font-size-base * 1.25)) !default; // ~18px
+$font-size-h5: $font-size-base !default;
+$font-size-h6: ceil(($font-size-base * .85)) !default; // ~12px
+
+//** Unit-less `line-height` for use in components like buttons.
+$line-height-base: 1.428571429 !default; // 20/14
+//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
+$line-height-computed: floor(($font-size-base * $line-height-base)) !default; // ~20px
+
+//** By default, this inherits from the ``.
+$headings-font-family: inherit !default;
+$headings-font-weight: 500 !default;
+$headings-line-height: 1.1 !default;
+$headings-color: inherit !default;
+
+
+//== Iconography
+//
+//## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via Bower.
+
+//** Load fonts from this directory.
+
+// [converter] If $bootstrap-sass-asset-helper if used, provide path relative to the assets load path.
+// [converter] This is because some asset helpers, such as Sprockets, do not work with file-relative paths.
+$icon-font-path: if($bootstrap-sass-asset-helper, "bootstrap/", "../fonts/bootstrap/") !default;
+
+//** File name for all font files.
+$icon-font-name: "glyphicons-halflings-regular" !default;
+//** Element ID within SVG icon file.
+$icon-font-svg-id: "glyphicons_halflingsregular" !default;
+
+
+//== Components
+//
+//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
+
+$padding-base-vertical: 6px !default;
+$padding-base-horizontal: 12px !default;
+
+$padding-large-vertical: 10px !default;
+$padding-large-horizontal: 16px !default;
+
+$padding-small-vertical: 5px !default;
+$padding-small-horizontal: 10px !default;
+
+$padding-xs-vertical: 1px !default;
+$padding-xs-horizontal: 5px !default;
+
+$line-height-large: 1.3333333 !default; // extra decimals for Win 8.1 Chrome
+$line-height-small: 1.5 !default;
+
+$border-radius-base: 4px !default;
+$border-radius-large: 6px !default;
+$border-radius-small: 3px !default;
+
+//** Global color for active items (e.g., navs or dropdowns).
+$component-active-color: #fff !default;
+//** Global background color for active items (e.g., navs or dropdowns).
+$component-active-bg: $brand-primary !default;
+
+//** Width of the `border` for generating carets that indicate dropdowns.
+$caret-width-base: 4px !default;
+//** Carets increase slightly in size for larger components.
+$caret-width-large: 5px !default;
+
+
+//== Tables
+//
+//## Customizes the `.table` component with basic values, each used across all table variations.
+
+//** Padding for ``s and ` `s.
+$table-cell-padding: 8px !default;
+//** Padding for cells in `.table-condensed`.
+$table-condensed-cell-padding: 5px !default;
+
+//** Default background color used for all tables.
+$table-bg: transparent !default;
+//** Background color used for `.table-striped`.
+$table-bg-accent: #f9f9f9 !default;
+//** Background color used for `.table-hover`.
+$table-bg-hover: #f5f5f5 !default;
+$table-bg-active: $table-bg-hover !default;
+
+//** Border color for table and cell borders.
+$table-border-color: #ddd !default;
+
+
+//== Buttons
+//
+//## For each of Bootstrap's buttons, define text, background and border color.
+
+$btn-font-weight: normal !default;
+
+$btn-default-color: #333 !default;
+$btn-default-bg: #fff !default;
+$btn-default-border: #ccc !default;
+
+$btn-primary-color: #fff !default;
+$btn-primary-bg: $brand-primary !default;
+$btn-primary-border: darken($btn-primary-bg, 5%) !default;
+
+$btn-success-color: #fff !default;
+$btn-success-bg: $brand-success !default;
+$btn-success-border: darken($btn-success-bg, 5%) !default;
+
+$btn-info-color: #fff !default;
+$btn-info-bg: $brand-info !default;
+$btn-info-border: darken($btn-info-bg, 5%) !default;
+
+$btn-warning-color: #fff !default;
+$btn-warning-bg: $brand-warning !default;
+$btn-warning-border: darken($btn-warning-bg, 5%) !default;
+
+$btn-danger-color: #fff !default;
+$btn-danger-bg: $brand-danger !default;
+$btn-danger-border: darken($btn-danger-bg, 5%) !default;
+
+$btn-link-disabled-color: $gray-light !default;
+
+// Allows for customizing button radius independently from global border radius
+$btn-border-radius-base: $border-radius-base !default;
+$btn-border-radius-large: $border-radius-large !default;
+$btn-border-radius-small: $border-radius-small !default;
+
+
+//== Forms
+//
+//##
+
+//** ` ` background color
+$input-bg: #fff !default;
+//** ` ` background color
+$input-bg-disabled: $gray-lighter !default;
+
+//** Text color for ` `s
+$input-color: $gray !default;
+//** ` ` border color
+$input-border: #ccc !default;
+
+// TODO: Rename `$input-border-radius` to `$input-border-radius-base` in v4
+//** Default `.form-control` border radius
+// This has no effect on ``s in some browsers, due to the limited stylability of ``s in CSS.
+$input-border-radius: $border-radius-base !default;
+//** Large `.form-control` border radius
+$input-border-radius-large: $border-radius-large !default;
+//** Small `.form-control` border radius
+$input-border-radius-small: $border-radius-small !default;
+
+//** Border color for inputs on focus
+$input-border-focus: #66afe9 !default;
+
+//** Placeholder text color
+$input-color-placeholder: #999 !default;
+
+//** Default `.form-control` height
+$input-height-base: ($line-height-computed + ($padding-base-vertical * 2) + 2) !default;
+//** Large `.form-control` height
+$input-height-large: (ceil($font-size-large * $line-height-large) + ($padding-large-vertical * 2) + 2) !default;
+//** Small `.form-control` height
+$input-height-small: (floor($font-size-small * $line-height-small) + ($padding-small-vertical * 2) + 2) !default;
+
+//** `.form-group` margin
+$form-group-margin-bottom: 15px !default;
+
+$legend-color: $gray-dark !default;
+$legend-border-color: #e5e5e5 !default;
+
+//** Background color for textual input addons
+$input-group-addon-bg: $gray-lighter !default;
+//** Border color for textual input addons
+$input-group-addon-border-color: $input-border !default;
+
+//** Disabled cursor for form controls and buttons.
+$cursor-disabled: not-allowed !default;
+
+
+//== Dropdowns
+//
+//## Dropdown menu container and contents.
+
+//** Background for the dropdown menu.
+$dropdown-bg: #fff !default;
+//** Dropdown menu `border-color`.
+$dropdown-border: rgba(0, 0, 0, .15) !default;
+//** Dropdown menu `border-color` **for IE8**.
+$dropdown-fallback-border: #ccc !default;
+//** Divider color for between dropdown items.
+$dropdown-divider-bg: #e5e5e5 !default;
+
+//** Dropdown link text color.
+$dropdown-link-color: $gray-dark !default;
+//** Hover color for dropdown links.
+$dropdown-link-hover-color: darken($gray-dark, 5%) !default;
+//** Hover background for dropdown links.
+$dropdown-link-hover-bg: #f5f5f5 !default;
+
+//** Active dropdown menu item text color.
+$dropdown-link-active-color: $component-active-color !default;
+//** Active dropdown menu item background color.
+$dropdown-link-active-bg: $component-active-bg !default;
+
+//** Disabled dropdown menu item background color.
+$dropdown-link-disabled-color: $gray-light !default;
+
+//** Text color for headers within dropdown menus.
+$dropdown-header-color: $gray-light !default;
+
+//** Deprecated `$dropdown-caret-color` as of v3.1.0
+$dropdown-caret-color: #000 !default;
+
+
+//-- Z-index master list
+//
+// Warning: Avoid customizing these values. They're used for a bird's eye view
+// of components dependent on the z-axis and are designed to all work together.
+//
+// Note: These variables are not generated into the Customizer.
+
+$zindex-navbar: 1000 !default;
+$zindex-dropdown: 1000 !default;
+$zindex-popover: 1060 !default;
+$zindex-tooltip: 1070 !default;
+$zindex-navbar-fixed: 1030 !default;
+$zindex-modal-background: 1040 !default;
+$zindex-modal: 1050 !default;
+
+
+//== Media queries breakpoints
+//
+//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
+
+// Extra small screen / phone
+//** Deprecated `$screen-xs` as of v3.0.1
+$screen-xs: 480px !default;
+//** Deprecated `$screen-xs-min` as of v3.2.0
+$screen-xs-min: $screen-xs !default;
+//** Deprecated `$screen-phone` as of v3.0.1
+$screen-phone: $screen-xs-min !default;
+
+// Small screen / tablet
+//** Deprecated `$screen-sm` as of v3.0.1
+$screen-sm: 768px !default;
+$screen-sm-min: $screen-sm !default;
+//** Deprecated `$screen-tablet` as of v3.0.1
+$screen-tablet: $screen-sm-min !default;
+
+// Medium screen / desktop
+//** Deprecated `$screen-md` as of v3.0.1
+$screen-md: 992px !default;
+$screen-md-min: $screen-md !default;
+//** Deprecated `$screen-desktop` as of v3.0.1
+$screen-desktop: $screen-md-min !default;
+
+// Large screen / wide desktop
+//** Deprecated `$screen-lg` as of v3.0.1
+$screen-lg: 1200px !default;
+$screen-lg-min: $screen-lg !default;
+//** Deprecated `$screen-lg-desktop` as of v3.0.1
+$screen-lg-desktop: $screen-lg-min !default;
+
+// So media queries don't overlap when required, provide a maximum
+$screen-xs-max: ($screen-sm-min - 1) !default;
+$screen-sm-max: ($screen-md-min - 1) !default;
+$screen-md-max: ($screen-lg-min - 1) !default;
+
+
+//== Grid system
+//
+//## Define your custom responsive grid.
+
+//** Number of columns in the grid.
+$grid-columns: 12 !default;
+//** Padding between columns. Gets divided in half for the left and right.
+$grid-gutter-width: 30px !default;
+// Navbar collapse
+//** Point at which the navbar becomes uncollapsed.
+$grid-float-breakpoint: $screen-sm-min !default;
+//** Point at which the navbar begins collapsing.
+$grid-float-breakpoint-max: ($grid-float-breakpoint - 1) !default;
+
+
+//== Container sizes
+//
+//## Define the maximum width of `.container` for different screen sizes.
+
+// Small screen / tablet
+$container-tablet: (720px + $grid-gutter-width) !default;
+//** For `$screen-sm-min` and up.
+$container-sm: $container-tablet !default;
+
+// Medium screen / desktop
+$container-desktop: (940px + $grid-gutter-width) !default;
+//** For `$screen-md-min` and up.
+$container-md: $container-desktop !default;
+
+// Large screen / wide desktop
+$container-large-desktop: (1140px + $grid-gutter-width) !default;
+//** For `$screen-lg-min` and up.
+$container-lg: $container-large-desktop !default;
+
+
+//== Navbar
+//
+//##
+
+// Basics of a navbar
+$navbar-height: 50px !default;
+$navbar-margin-bottom: $line-height-computed !default;
+$navbar-border-radius: $border-radius-base !default;
+$navbar-padding-horizontal: floor(math.div($grid-gutter-width, 2)) !default;
+$navbar-padding-vertical: math.div(($navbar-height - $line-height-computed), 2) !default;
+$navbar-collapse-max-height: 340px !default;
+
+$navbar-default-color: #777 !default;
+$navbar-default-bg: #f8f8f8 !default;
+$navbar-default-border: darken($navbar-default-bg, 6.5%) !default;
+
+// Navbar links
+$navbar-default-link-color: #777 !default;
+$navbar-default-link-hover-color: #333 !default;
+$navbar-default-link-hover-bg: transparent !default;
+$navbar-default-link-active-color: #555 !default;
+$navbar-default-link-active-bg: darken($navbar-default-bg, 6.5%) !default;
+$navbar-default-link-disabled-color: #ccc !default;
+$navbar-default-link-disabled-bg: transparent !default;
+
+// Navbar brand label
+$navbar-default-brand-color: $navbar-default-link-color !default;
+$navbar-default-brand-hover-color: darken($navbar-default-brand-color, 10%) !default;
+$navbar-default-brand-hover-bg: transparent !default;
+
+// Navbar toggle
+$navbar-default-toggle-hover-bg: #ddd !default;
+$navbar-default-toggle-icon-bar-bg: #888 !default;
+$navbar-default-toggle-border-color: #ddd !default;
+
+
+//=== Inverted navbar
+// Reset inverted navbar basics
+$navbar-inverse-color: lighten($gray-light, 15%) !default;
+$navbar-inverse-bg: #222 !default;
+$navbar-inverse-border: darken($navbar-inverse-bg, 10%) !default;
+
+// Inverted navbar links
+$navbar-inverse-link-color: lighten($gray-light, 15%) !default;
+$navbar-inverse-link-hover-color: #fff !default;
+$navbar-inverse-link-hover-bg: transparent !default;
+$navbar-inverse-link-active-color: $navbar-inverse-link-hover-color !default;
+$navbar-inverse-link-active-bg: darken($navbar-inverse-bg, 10%) !default;
+$navbar-inverse-link-disabled-color: #444 !default;
+$navbar-inverse-link-disabled-bg: transparent !default;
+
+// Inverted navbar brand label
+$navbar-inverse-brand-color: $navbar-inverse-link-color !default;
+$navbar-inverse-brand-hover-color: #fff !default;
+$navbar-inverse-brand-hover-bg: transparent !default;
+
+// Inverted navbar toggle
+$navbar-inverse-toggle-hover-bg: #333 !default;
+$navbar-inverse-toggle-icon-bar-bg: #fff !default;
+$navbar-inverse-toggle-border-color: #333 !default;
+
+
+//== Navs
+//
+//##
+
+//=== Shared nav styles
+$nav-link-padding: 10px 15px !default;
+$nav-link-hover-bg: $gray-lighter !default;
+
+$nav-disabled-link-color: $gray-light !default;
+$nav-disabled-link-hover-color: $gray-light !default;
+
+//== Tabs
+$nav-tabs-border-color: #ddd !default;
+
+$nav-tabs-link-hover-border-color: $gray-lighter !default;
+
+$nav-tabs-active-link-hover-bg: $body-bg !default;
+$nav-tabs-active-link-hover-color: $gray !default;
+$nav-tabs-active-link-hover-border-color: #ddd !default;
+
+$nav-tabs-justified-link-border-color: #ddd !default;
+$nav-tabs-justified-active-link-border-color: $body-bg !default;
+
+//== Pills
+$nav-pills-border-radius: $border-radius-base !default;
+$nav-pills-active-link-hover-bg: $component-active-bg !default;
+$nav-pills-active-link-hover-color: $component-active-color !default;
+
+
+//== Pagination
+//
+//##
+
+$pagination-color: $link-color !default;
+$pagination-bg: #fff !default;
+$pagination-border: #ddd !default;
+
+$pagination-hover-color: $link-hover-color !default;
+$pagination-hover-bg: $gray-lighter !default;
+$pagination-hover-border: #ddd !default;
+
+$pagination-active-color: #fff !default;
+$pagination-active-bg: $brand-primary !default;
+$pagination-active-border: $brand-primary !default;
+
+$pagination-disabled-color: $gray-light !default;
+$pagination-disabled-bg: #fff !default;
+$pagination-disabled-border: #ddd !default;
+
+
+//== Pager
+//
+//##
+
+$pager-bg: $pagination-bg !default;
+$pager-border: $pagination-border !default;
+$pager-border-radius: 15px !default;
+
+$pager-hover-bg: $pagination-hover-bg !default;
+
+$pager-active-bg: $pagination-active-bg !default;
+$pager-active-color: $pagination-active-color !default;
+
+$pager-disabled-color: $pagination-disabled-color !default;
+
+
+//== Jumbotron
+//
+//##
+
+$jumbotron-padding: 30px !default;
+$jumbotron-color: inherit !default;
+$jumbotron-bg: $gray-lighter !default;
+$jumbotron-heading-color: inherit !default;
+$jumbotron-font-size: ceil(($font-size-base * 1.5)) !default;
+$jumbotron-heading-font-size: ceil(($font-size-base * 4.5)) !default;
+
+
+//== Form states and alerts
+//
+//## Define colors for form feedback states and, by default, alerts.
+
+$state-success-text: #3c763d !default;
+$state-success-bg: #dff0d8 !default;
+$state-success-border: darken(adjust-hue($state-success-bg, -10), 5%) !default;
+
+$state-info-text: #31708f !default;
+$state-info-bg: #d9edf7 !default;
+$state-info-border: darken(adjust-hue($state-info-bg, -10), 7%) !default;
+
+$state-warning-text: #8a6d3b !default;
+$state-warning-bg: #fcf8e3 !default;
+$state-warning-border: darken(adjust-hue($state-warning-bg, -10), 5%) !default;
+
+$state-danger-text: #a94442 !default;
+$state-danger-bg: #f2dede !default;
+$state-danger-border: darken(adjust-hue($state-danger-bg, -10), 5%) !default;
+
+
+//== Tooltips
+//
+//##
+
+//** Tooltip max width
+$tooltip-max-width: 200px !default;
+//** Tooltip text color
+$tooltip-color: #fff !default;
+//** Tooltip background color
+$tooltip-bg: #000 !default;
+$tooltip-opacity: .9 !default;
+
+//** Tooltip arrow width
+$tooltip-arrow-width: 5px !default;
+//** Tooltip arrow color
+$tooltip-arrow-color: $tooltip-bg !default;
+
+
+//== Popovers
+//
+//##
+
+//** Popover body background color
+$popover-bg: #fff !default;
+//** Popover maximum width
+$popover-max-width: 276px !default;
+//** Popover border color
+$popover-border-color: rgba(0, 0, 0, .2) !default;
+//** Popover fallback border color
+$popover-fallback-border-color: #ccc !default;
+
+//** Popover title background color
+$popover-title-bg: darken($popover-bg, 3%) !default;
+
+//** Popover arrow width
+$popover-arrow-width: 10px !default;
+//** Popover arrow color
+$popover-arrow-color: $popover-bg !default;
+
+//** Popover outer arrow width
+$popover-arrow-outer-width: ($popover-arrow-width + 1) !default;
+//** Popover outer arrow color
+$popover-arrow-outer-color: fade_in($popover-border-color, 0.05) !default;
+//** Popover outer arrow fallback color
+$popover-arrow-outer-fallback-color: darken($popover-fallback-border-color, 20%) !default;
+
+
+//== Labels
+//
+//##
+
+//** Default label background color
+$label-default-bg: $gray-light !default;
+//** Primary label background color
+$label-primary-bg: $brand-primary !default;
+//** Success label background color
+$label-success-bg: $brand-success !default;
+//** Info label background color
+$label-info-bg: $brand-info !default;
+//** Warning label background color
+$label-warning-bg: $brand-warning !default;
+//** Danger label background color
+$label-danger-bg: $brand-danger !default;
+
+//** Default label text color
+$label-color: #fff !default;
+//** Default text color of a linked label
+$label-link-hover-color: #fff !default;
+
+
+//== Modals
+//
+//##
+
+//** Padding applied to the modal body
+$modal-inner-padding: 15px !default;
+
+//** Padding applied to the modal title
+$modal-title-padding: 15px !default;
+//** Modal title line-height
+$modal-title-line-height: $line-height-base !default;
+
+//** Background color of modal content area
+$modal-content-bg: #fff !default;
+//** Modal content border color
+$modal-content-border-color: rgba(0, 0, 0, .2) !default;
+//** Modal content border color **for IE8**
+$modal-content-fallback-border-color: #999 !default;
+
+//** Modal backdrop background color
+$modal-backdrop-bg: #000 !default;
+//** Modal backdrop opacity
+$modal-backdrop-opacity: .5 !default;
+//** Modal header border color
+$modal-header-border-color: #e5e5e5 !default;
+//** Modal footer border color
+$modal-footer-border-color: $modal-header-border-color !default;
+
+$modal-lg: 900px !default;
+$modal-md: 600px !default;
+$modal-sm: 300px !default;
+
+
+//== Alerts
+//
+//## Define alert colors, border radius, and padding.
+
+$alert-padding: 15px !default;
+$alert-border-radius: $border-radius-base !default;
+$alert-link-font-weight: bold !default;
+
+$alert-success-bg: $state-success-bg !default;
+$alert-success-text: $state-success-text !default;
+$alert-success-border: $state-success-border !default;
+
+$alert-info-bg: $state-info-bg !default;
+$alert-info-text: $state-info-text !default;
+$alert-info-border: $state-info-border !default;
+
+$alert-warning-bg: $state-warning-bg !default;
+$alert-warning-text: $state-warning-text !default;
+$alert-warning-border: $state-warning-border !default;
+
+$alert-danger-bg: $state-danger-bg !default;
+$alert-danger-text: $state-danger-text !default;
+$alert-danger-border: $state-danger-border !default;
+
+
+//== Progress bars
+//
+//##
+
+//** Background color of the whole progress component
+$progress-bg: #f5f5f5 !default;
+//** Progress bar text color
+$progress-bar-color: #fff !default;
+//** Variable for setting rounded corners on progress bar.
+$progress-border-radius: $border-radius-base !default;
+
+//** Default progress bar color
+$progress-bar-bg: $brand-primary !default;
+//** Success progress bar color
+$progress-bar-success-bg: $brand-success !default;
+//** Warning progress bar color
+$progress-bar-warning-bg: $brand-warning !default;
+//** Danger progress bar color
+$progress-bar-danger-bg: $brand-danger !default;
+//** Info progress bar color
+$progress-bar-info-bg: $brand-info !default;
+
+
+//== List group
+//
+//##
+
+//** Background color on `.list-group-item`
+$list-group-bg: #fff !default;
+//** `.list-group-item` border color
+$list-group-border: #ddd !default;
+//** List group border radius
+$list-group-border-radius: $border-radius-base !default;
+
+//** Background color of single list items on hover
+$list-group-hover-bg: #f5f5f5 !default;
+//** Text color of active list items
+$list-group-active-color: $component-active-color !default;
+//** Background color of active list items
+$list-group-active-bg: $component-active-bg !default;
+//** Border color of active list elements
+$list-group-active-border: $list-group-active-bg !default;
+//** Text color for content within active list items
+$list-group-active-text-color: lighten($list-group-active-bg, 40%) !default;
+
+//** Text color of disabled list items
+$list-group-disabled-color: $gray-light !default;
+//** Background color of disabled list items
+$list-group-disabled-bg: $gray-lighter !default;
+//** Text color for content within disabled list items
+$list-group-disabled-text-color: $list-group-disabled-color !default;
+
+$list-group-link-color: #555 !default;
+$list-group-link-hover-color: $list-group-link-color !default;
+$list-group-link-heading-color: #333 !default;
+
+
+//== Panels
+//
+//##
+
+$panel-bg: #fff !default;
+$panel-body-padding: 15px !default;
+$panel-heading-padding: 10px 15px !default;
+$panel-footer-padding: $panel-heading-padding !default;
+$panel-border-radius: $border-radius-base !default;
+
+//** Border color for elements within panels
+$panel-inner-border: #ddd !default;
+$panel-footer-bg: #f5f5f5 !default;
+
+$panel-default-text: $gray-dark !default;
+$panel-default-border: #ddd !default;
+$panel-default-heading-bg: #f5f5f5 !default;
+
+$panel-primary-text: #fff !default;
+$panel-primary-border: $brand-primary !default;
+$panel-primary-heading-bg: $brand-primary !default;
+
+$panel-success-text: $state-success-text !default;
+$panel-success-border: $state-success-border !default;
+$panel-success-heading-bg: $state-success-bg !default;
+
+$panel-info-text: $state-info-text !default;
+$panel-info-border: $state-info-border !default;
+$panel-info-heading-bg: $state-info-bg !default;
+
+$panel-warning-text: $state-warning-text !default;
+$panel-warning-border: $state-warning-border !default;
+$panel-warning-heading-bg: $state-warning-bg !default;
+
+$panel-danger-text: $state-danger-text !default;
+$panel-danger-border: $state-danger-border !default;
+$panel-danger-heading-bg: $state-danger-bg !default;
+
+
+//== Thumbnails
+//
+//##
+
+//** Padding around the thumbnail image
+$thumbnail-padding: 4px !default;
+//** Thumbnail background color
+$thumbnail-bg: $body-bg !default;
+//** Thumbnail border color
+$thumbnail-border: #ddd !default;
+//** Thumbnail border radius
+$thumbnail-border-radius: $border-radius-base !default;
+
+//** Custom text color for thumbnail captions
+$thumbnail-caption-color: $text-color !default;
+//** Padding around the thumbnail caption
+$thumbnail-caption-padding: 9px !default;
+
+
+//== Wells
+//
+//##
+
+$well-bg: #f5f5f5 !default;
+$well-border: darken($well-bg, 7%) !default;
+
+
+//== Badges
+//
+//##
+
+$badge-color: #fff !default;
+//** Linked badge text color on hover
+$badge-link-hover-color: #fff !default;
+$badge-bg: $gray-light !default;
+
+//** Badge text color in active nav link
+$badge-active-color: $link-color !default;
+//** Badge background color in active nav link
+$badge-active-bg: #fff !default;
+
+$badge-font-weight: bold !default;
+$badge-line-height: 1 !default;
+$badge-border-radius: 10px !default;
+
+
+//== Breadcrumbs
+//
+//##
+
+$breadcrumb-padding-vertical: 8px !default;
+$breadcrumb-padding-horizontal: 15px !default;
+//** Breadcrumb background color
+$breadcrumb-bg: #f5f5f5 !default;
+//** Breadcrumb text color
+$breadcrumb-color: #ccc !default;
+//** Text color of current page in the breadcrumb
+$breadcrumb-active-color: $gray-light !default;
+//** Textual separator for between breadcrumb elements
+$breadcrumb-separator: "/" !default;
+
+
+//== Carousel
+//
+//##
+
+$carousel-text-shadow: 0 1px 2px rgba(0, 0, 0, .6) !default;
+
+$carousel-control-color: #fff !default;
+$carousel-control-width: 15% !default;
+$carousel-control-opacity: .5 !default;
+$carousel-control-font-size: 20px !default;
+
+$carousel-indicator-active-bg: #fff !default;
+$carousel-indicator-border-color: #fff !default;
+
+$carousel-caption-color: #fff !default;
+
+
+//== Close
+//
+//##
+
+$close-font-weight: bold !default;
+$close-color: #000 !default;
+$close-text-shadow: 0 1px 0 #fff !default;
+
+
+//== Code
+//
+//##
+
+$code-color: #c7254e !default;
+$code-bg: #f9f2f4 !default;
+
+$kbd-color: #fff !default;
+$kbd-bg: #333 !default;
+
+$pre-bg: #f5f5f5 !default;
+$pre-color: $gray-dark !default;
+$pre-border-color: #ccc !default;
+$pre-scrollable-max-height: 340px !default;
+
+
+//== Type
+//
+//##
+
+//** Horizontal offset for forms and lists.
+$component-offset-horizontal: 180px !default;
+//** Text muted color
+$text-muted: $gray-light !default;
+//** Abbreviations and acronyms border color
+$abbr-border-color: $gray-light !default;
+//** Headings small color
+$headings-small-color: $gray-light !default;
+//** Blockquote small color
+$blockquote-small-color: $gray-light !default;
+//** Blockquote font size
+$blockquote-font-size: ($font-size-base * 1.25) !default;
+//** Blockquote border color
+$blockquote-border-color: $gray-lighter !default;
+//** Page header border color
+$page-header-border-color: $gray-lighter !default;
+//** Width of horizontal description list titles
+$dl-horizontal-offset: $component-offset-horizontal !default;
+//** Point at which .dl-horizontal becomes horizontal
+$dl-horizontal-breakpoint: $grid-float-breakpoint !default;
+//** Horizontal line color.
+$hr-border: $gray-lighter !default;
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_wells.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_wells.scss
new file mode 100644
index 0000000..9a048bd
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/_wells.scss
@@ -0,0 +1,29 @@
+//
+// Wells
+// --------------------------------------------------
+
+
+// Base class
+.well {
+ min-height: 20px;
+ padding: 19px;
+ margin-bottom: 20px;
+ background-color: $well-bg;
+ border: 1px solid $well-border;
+ border-radius: $border-radius-base;
+ @include box-shadow(inset 0 1px 1px rgba(0, 0, 0, .05));
+ blockquote {
+ border-color: #ddd;
+ border-color: rgba(0, 0, 0, .15);
+ }
+}
+
+// Sizes
+.well-lg {
+ padding: 24px;
+ border-radius: $border-radius-large;
+}
+.well-sm {
+ padding: 9px;
+ border-radius: $border-radius-small;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_alerts.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_alerts.scss
new file mode 100644
index 0000000..b1e6df9
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_alerts.scss
@@ -0,0 +1,15 @@
+// Alerts
+
+@mixin alert-variant($background, $border, $text-color) {
+ color: $text-color;
+ background-color: $background;
+ border-color: $border;
+
+ hr {
+ border-top-color: darken($border, 5%);
+ }
+
+ .alert-link {
+ color: darken($text-color, 10%);
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_background-variant.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_background-variant.scss
new file mode 100644
index 0000000..4c7769e
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_background-variant.scss
@@ -0,0 +1,12 @@
+// Contextual backgrounds
+
+// [converter] $parent hack
+@mixin bg-variant($parent, $color) {
+ #{$parent} {
+ background-color: $color;
+ }
+ a#{$parent}:hover,
+ a#{$parent}:focus {
+ background-color: darken($color, 10%);
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_border-radius.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_border-radius.scss
new file mode 100644
index 0000000..e03c390
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_border-radius.scss
@@ -0,0 +1,18 @@
+// Single side border-radius
+
+@mixin border-top-radius($radius) {
+ border-top-left-radius: $radius;
+ border-top-right-radius: $radius;
+}
+@mixin border-right-radius($radius) {
+ border-top-right-radius: $radius;
+ border-bottom-right-radius: $radius;
+}
+@mixin border-bottom-radius($radius) {
+ border-bottom-right-radius: $radius;
+ border-bottom-left-radius: $radius;
+}
+@mixin border-left-radius($radius) {
+ border-top-left-radius: $radius;
+ border-bottom-left-radius: $radius;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_buttons.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_buttons.scss
new file mode 100644
index 0000000..5afa735
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_buttons.scss
@@ -0,0 +1,61 @@
+// Button variants
+//
+// Easily pump out default styles, as well as :hover, :focus, :active,
+// and disabled options for all buttons
+
+@mixin button-variant($color, $background, $border) {
+ color: $color;
+ background-color: $background;
+ border-color: $border;
+
+ &:focus,
+ &.focus {
+ color: $color;
+ background-color: darken($background, 10%);
+ border-color: darken($border, 25%);
+ }
+ &:hover {
+ color: $color;
+ background-color: darken($background, 10%);
+ border-color: darken($border, 12%);
+ }
+ &:active,
+ &.active,
+ .open > &.dropdown-toggle {
+ color: $color;
+ background-color: darken($background, 10%);
+ background-image: none;
+ border-color: darken($border, 12%);
+
+ &:hover,
+ &:focus,
+ &.focus {
+ color: $color;
+ background-color: darken($background, 17%);
+ border-color: darken($border, 25%);
+ }
+ }
+ &.disabled,
+ &[disabled],
+ fieldset[disabled] & {
+ &:hover,
+ &:focus,
+ &.focus {
+ background-color: $background;
+ border-color: $border;
+ }
+ }
+
+ .badge {
+ color: $background;
+ background-color: $color;
+ }
+}
+
+// Button sizes
+@mixin button-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) {
+ padding: $padding-vertical $padding-horizontal;
+ font-size: $font-size;
+ line-height: $line-height;
+ border-radius: $border-radius;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_center-block.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_center-block.scss
new file mode 100644
index 0000000..ed69097
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_center-block.scss
@@ -0,0 +1,7 @@
+// Center-align a block level element
+
+@mixin center-block() {
+ display: block;
+ margin-right: auto;
+ margin-left: auto;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_clearfix.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_clearfix.scss
new file mode 100644
index 0000000..e45eca5
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_clearfix.scss
@@ -0,0 +1,22 @@
+// Clearfix
+//
+// For modern browsers
+// 1. The space content is one way to avoid an Opera bug when the
+// contenteditable attribute is included anywhere else in the document.
+// Otherwise it causes space to appear at the top and bottom of elements
+// that are clearfixed.
+// 2. The use of `table` rather than `block` is only necessary if using
+// `:before` to contain the top-margins of child elements.
+//
+// Source: http://nicolasgallagher.com/micro-clearfix-hack/
+
+@mixin clearfix() {
+ &:before,
+ &:after {
+ display: table; // 2
+ content: " "; // 1
+ }
+ &:after {
+ clear: both;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_forms.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_forms.scss
new file mode 100644
index 0000000..46578a1
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_forms.scss
@@ -0,0 +1,88 @@
+// Form validation states
+//
+// Used in forms.less to generate the form validation CSS for warnings, errors,
+// and successes.
+
+@mixin form-control-validation($text-color: #555, $border-color: #ccc, $background-color: #f5f5f5) {
+ // Color the label and help text
+ .help-block,
+ .control-label,
+ .radio,
+ .checkbox,
+ .radio-inline,
+ .checkbox-inline,
+ &.radio label,
+ &.checkbox label,
+ &.radio-inline label,
+ &.checkbox-inline label {
+ color: $text-color;
+ }
+ // Set the border and box shadow on specific inputs to match
+ .form-control {
+ border-color: $border-color;
+ @include box-shadow(inset 0 1px 1px rgba(0, 0, 0, .075)); // Redeclare so transitions work
+ &:focus {
+ border-color: darken($border-color, 10%);
+ $shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px lighten($border-color, 20%);
+ @include box-shadow($shadow);
+ }
+ }
+ // Set validation states also for addons
+ .input-group-addon {
+ color: $text-color;
+ background-color: $background-color;
+ border-color: $border-color;
+ }
+ // Optional feedback icon
+ .form-control-feedback {
+ color: $text-color;
+ }
+}
+
+
+// Form control focus state
+//
+// Generate a customized focus state and for any input with the specified color,
+// which defaults to the `$input-border-focus` variable.
+//
+// We highly encourage you to not customize the default value, but instead use
+// this to tweak colors on an as-needed basis. This aesthetic change is based on
+// WebKit's default styles, but applicable to a wider range of browsers. Its
+// usability and accessibility should be taken into account with any change.
+//
+// Example usage: change the default blue border and shadow to white for better
+// contrast against a dark gray background.
+@mixin form-control-focus($color: $input-border-focus) {
+ $color-rgba: rgba(red($color), green($color), blue($color), .6);
+ &:focus {
+ border-color: $color;
+ outline: 0;
+ @include box-shadow(inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px $color-rgba);
+ }
+}
+
+// Form control sizing
+//
+// Relative text size, padding, and border-radii changes for form controls. For
+// horizontal sizing, wrap controls in the predefined grid classes. ``
+// element gets special love because it's special, and that's a fact!
+// [converter] $parent hack
+@mixin input-size($parent, $input-height, $padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) {
+ #{$parent} {
+ height: $input-height;
+ padding: $padding-vertical $padding-horizontal;
+ font-size: $font-size;
+ line-height: $line-height;
+ border-radius: $border-radius;
+ }
+
+ select#{$parent} {
+ height: $input-height;
+ line-height: $input-height;
+ }
+
+ textarea#{$parent},
+ select[multiple]#{$parent} {
+ height: auto;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_gradients.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_gradients.scss
new file mode 100644
index 0000000..fd81440
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_gradients.scss
@@ -0,0 +1,56 @@
+
+
+// Horizontal gradient, from left to right
+//
+// Creates two color stops, start and end, by specifying a color and position for each color stop.
+// Color stops are not available in IE9 and below.
+@mixin gradient-horizontal($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
+ background-image: -webkit-linear-gradient(left, $start-color $start-percent, $end-color $end-percent); // Safari 5.1-6, Chrome 10+
+ background-image: -o-linear-gradient(left, $start-color $start-percent, $end-color $end-percent); // Opera 12
+ background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=1); // IE9 and down
+ background-repeat: repeat-x;
+}
+
+// Vertical gradient, from top to bottom
+//
+// Creates two color stops, start and end, by specifying a color and position for each color stop.
+// Color stops are not available in IE9 and below.
+@mixin gradient-vertical($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) {
+ background-image: -webkit-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // Safari 5.1-6, Chrome 10+
+ background-image: -o-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // Opera 12
+ background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=0); // IE9 and down
+ background-repeat: repeat-x;
+}
+
+@mixin gradient-directional($start-color: #555, $end-color: #333, $deg: 45deg) {
+ background-image: -webkit-linear-gradient($deg, $start-color, $end-color); // Safari 5.1-6, Chrome 10+
+ background-image: -o-linear-gradient($deg, $start-color, $end-color); // Opera 12
+ background-image: linear-gradient($deg, $start-color, $end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
+ background-repeat: repeat-x;
+}
+@mixin gradient-horizontal-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
+ background-image: -webkit-linear-gradient(left, $start-color, $mid-color $color-stop, $end-color);
+ background-image: -o-linear-gradient(left, $start-color, $mid-color $color-stop, $end-color);
+ background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=1); // IE9 and down, gets no color-stop at all for proper fallback
+ background-repeat: no-repeat;
+}
+@mixin gradient-vertical-three-colors($start-color: #00b3ee, $mid-color: #7a43b6, $color-stop: 50%, $end-color: #c3325f) {
+ background-image: -webkit-linear-gradient($start-color, $mid-color $color-stop, $end-color);
+ background-image: -o-linear-gradient($start-color, $mid-color $color-stop, $end-color);
+ background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=0); // IE9 and down, gets no color-stop at all for proper fallback
+ background-repeat: no-repeat;
+}
+@mixin gradient-radial($inner-color: #555, $outer-color: #333) {
+ background-image: -webkit-radial-gradient(circle, $inner-color, $outer-color);
+ background-image: radial-gradient(circle, $inner-color, $outer-color);
+ background-repeat: no-repeat;
+}
+@mixin gradient-striped($color: rgba(255, 255, 255, .15), $angle: 45deg) {
+ background-image: -webkit-linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
+ background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_grid-framework.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_grid-framework.scss
new file mode 100644
index 0000000..6160a04
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_grid-framework.scss
@@ -0,0 +1,82 @@
+@use "sass:math";
+// Framework grid generation
+//
+// Used only by Bootstrap to generate the correct number of grid classes given
+// any value of `$grid-columns`.
+
+// [converter] This is defined recursively in LESS, but Sass supports real loops
+@mixin make-grid-columns($i: 1, $list: ".col-xs-#{$i}, .col-sm-#{$i}, .col-md-#{$i}, .col-lg-#{$i}") {
+ @for $i from (1 + 1) through $grid-columns {
+ $list: "#{$list}, .col-xs-#{$i}, .col-sm-#{$i}, .col-md-#{$i}, .col-lg-#{$i}";
+ }
+ #{$list} {
+ position: relative;
+ // Prevent columns from collapsing when empty
+ min-height: 1px;
+ // Inner gutter via padding
+ padding-right: floor(math.div($grid-gutter-width, 2));
+ padding-left: ceil(math.div($grid-gutter-width, 2));
+ }
+}
+
+
+// [converter] This is defined recursively in LESS, but Sass supports real loops
+@mixin float-grid-columns($class, $i: 1, $list: ".col-#{$class}-#{$i}") {
+ @for $i from (1 + 1) through $grid-columns {
+ $list: "#{$list}, .col-#{$class}-#{$i}";
+ }
+ #{$list} {
+ float: left;
+ }
+}
+
+
+@mixin calc-grid-column($index, $class, $type) {
+ @if ($type == width) and ($index > 0) {
+ .col-#{$class}-#{$index} {
+ width: percentage(math.div($index, $grid-columns));
+ }
+ }
+ @if ($type == push) and ($index > 0) {
+ .col-#{$class}-push-#{$index} {
+ left: percentage(math.div($index, $grid-columns));
+ }
+ }
+ @if ($type == push) and ($index == 0) {
+ .col-#{$class}-push-0 {
+ left: auto;
+ }
+ }
+ @if ($type == pull) and ($index > 0) {
+ .col-#{$class}-pull-#{$index} {
+ right: percentage(math.div($index, $grid-columns));
+ }
+ }
+ @if ($type == pull) and ($index == 0) {
+ .col-#{$class}-pull-0 {
+ right: auto;
+ }
+ }
+ @if ($type == offset) {
+ .col-#{$class}-offset-#{$index} {
+ margin-left: percentage(math.div($index, $grid-columns));
+ }
+ }
+}
+
+// [converter] This is defined recursively in LESS, but Sass supports real loops
+@mixin loop-grid-columns($columns, $class, $type) {
+ @for $i from 0 through $columns {
+ @include calc-grid-column($i, $class, $type);
+ }
+}
+
+
+// Create grid for specific class
+@mixin make-grid($class) {
+ @include float-grid-columns($class);
+ @include loop-grid-columns($grid-columns, $class, width);
+ @include loop-grid-columns($grid-columns, $class, pull);
+ @include loop-grid-columns($grid-columns, $class, push);
+ @include loop-grid-columns($grid-columns, $class, offset);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_grid.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_grid.scss
new file mode 100644
index 0000000..0cee189
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_grid.scss
@@ -0,0 +1,123 @@
+@use "sass:math";
+// Grid system
+//
+// Generate semantic grid columns with these mixins.
+
+// Centered container element
+@mixin container-fixed($gutter: $grid-gutter-width) {
+ padding-right: ceil(math.div($gutter, 2));
+ padding-left: floor(math.div($gutter, 2));
+ margin-right: auto;
+ margin-left: auto;
+ @include clearfix;
+}
+
+// Creates a wrapper for a series of columns
+@mixin make-row($gutter: $grid-gutter-width) {
+ margin-right: floor(math.div($gutter, -2));
+ margin-left: ceil(math.div($gutter, -2));
+ @include clearfix;
+}
+
+// Generate the extra small columns
+@mixin make-xs-column($columns, $gutter: $grid-gutter-width) {
+ position: relative;
+ float: left;
+ width: percentage(math.div($columns, $grid-columns));
+ min-height: 1px;
+ padding-right: math.div($gutter, 2);
+ padding-left: math.div($gutter, 2);
+}
+@mixin make-xs-column-offset($columns) {
+ margin-left: percentage(math.div($columns, $grid-columns));
+}
+@mixin make-xs-column-push($columns) {
+ left: percentage(math.div($columns, $grid-columns));
+}
+@mixin make-xs-column-pull($columns) {
+ right: percentage(math.div($columns, $grid-columns));
+}
+
+// Generate the small columns
+@mixin make-sm-column($columns, $gutter: $grid-gutter-width) {
+ position: relative;
+ min-height: 1px;
+ padding-right: math.div($gutter, 2);
+ padding-left: math.div($gutter, 2);
+
+ @media (min-width: $screen-sm-min) {
+ float: left;
+ width: percentage(math.div($columns, $grid-columns));
+ }
+}
+@mixin make-sm-column-offset($columns) {
+ @media (min-width: $screen-sm-min) {
+ margin-left: percentage(math.div($columns, $grid-columns));
+ }
+}
+@mixin make-sm-column-push($columns) {
+ @media (min-width: $screen-sm-min) {
+ left: percentage(math.div($columns, $grid-columns));
+ }
+}
+@mixin make-sm-column-pull($columns) {
+ @media (min-width: $screen-sm-min) {
+ right: percentage(math.div($columns, $grid-columns));
+ }
+}
+
+// Generate the medium columns
+@mixin make-md-column($columns, $gutter: $grid-gutter-width) {
+ position: relative;
+ min-height: 1px;
+ padding-right: math.div($gutter, 2);
+ padding-left: math.div($gutter, 2);
+
+ @media (min-width: $screen-md-min) {
+ float: left;
+ width: percentage(math.div($columns, $grid-columns));
+ }
+}
+@mixin make-md-column-offset($columns) {
+ @media (min-width: $screen-md-min) {
+ margin-left: percentage(math.div($columns, $grid-columns));
+ }
+}
+@mixin make-md-column-push($columns) {
+ @media (min-width: $screen-md-min) {
+ left: percentage(math.div($columns, $grid-columns));
+ }
+}
+@mixin make-md-column-pull($columns) {
+ @media (min-width: $screen-md-min) {
+ right: percentage(math.div($columns, $grid-columns));
+ }
+}
+
+// Generate the large columns
+@mixin make-lg-column($columns, $gutter: $grid-gutter-width) {
+ position: relative;
+ min-height: 1px;
+ padding-right: math.div($gutter, 2);
+ padding-left: math.div($gutter, 2);
+
+ @media (min-width: $screen-lg-min) {
+ float: left;
+ width: percentage(math.div($columns, $grid-columns));
+ }
+}
+@mixin make-lg-column-offset($columns) {
+ @media (min-width: $screen-lg-min) {
+ margin-left: percentage(math.div($columns, $grid-columns));
+ }
+}
+@mixin make-lg-column-push($columns) {
+ @media (min-width: $screen-lg-min) {
+ left: percentage(math.div($columns, $grid-columns));
+ }
+}
+@mixin make-lg-column-pull($columns) {
+ @media (min-width: $screen-lg-min) {
+ right: percentage(math.div($columns, $grid-columns));
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_hide-text.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_hide-text.scss
new file mode 100644
index 0000000..1767e02
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_hide-text.scss
@@ -0,0 +1,21 @@
+// CSS image replacement
+//
+// Heads up! v3 launched with only `.hide-text()`, but per our pattern for
+// mixins being reused as classes with the same name, this doesn't hold up. As
+// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.
+//
+// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
+
+// Deprecated as of v3.0.1 (has been removed in v4)
+@mixin hide-text() {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+
+// New mixin to use as of v3.0.1
+@mixin text-hide() {
+ @include hide-text;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_image.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_image.scss
new file mode 100644
index 0000000..b5a109b
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_image.scss
@@ -0,0 +1,28 @@
+// Responsive image
+//
+// Keep images from scaling beyond the width of their parents.
+@mixin img-responsive($display: block) {
+ display: $display;
+ max-width: 100%; // Part 1: Set a maximum relative to the parent
+ height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching
+}
+
+
+// Retina image
+//
+// Short retina mixin for setting background-image and -size. Note that the
+// spelling of `min--moz-device-pixel-ratio` is intentional.
+@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {
+ background-image: url(if($bootstrap-sass-asset-helper, twbs-image-path("#{$file-1x}"), "#{$file-1x}"));
+
+ @media
+ only screen and (-webkit-min-device-pixel-ratio: 2),
+ only screen and ( min--moz-device-pixel-ratio: 2),
+ only screen and ( -o-min-device-pixel-ratio: 2/1),
+ only screen and ( min-device-pixel-ratio: 2),
+ only screen and ( min-resolution: 192dpi),
+ only screen and ( min-resolution: 2dppx) {
+ background-image: url(if($bootstrap-sass-asset-helper, twbs-image-path("#{$file-2x}"), "#{$file-2x}"));
+ background-size: $width-1x $height-1x;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_labels.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_labels.scss
new file mode 100644
index 0000000..eda6dfd
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_labels.scss
@@ -0,0 +1,12 @@
+// Labels
+
+@mixin label-variant($color) {
+ background-color: $color;
+
+ &[href] {
+ &:hover,
+ &:focus {
+ background-color: darken($color, 10%);
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_list-group.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_list-group.scss
new file mode 100644
index 0000000..c478eeb
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_list-group.scss
@@ -0,0 +1,32 @@
+// List Groups
+
+@mixin list-group-item-variant($state, $background, $color) {
+ .list-group-item-#{$state} {
+ color: $color;
+ background-color: $background;
+
+ // [converter] extracted a&, button& to a.list-group-item-#{$state}, button.list-group-item-#{$state}
+ }
+
+ a.list-group-item-#{$state},
+ button.list-group-item-#{$state} {
+ color: $color;
+
+ .list-group-item-heading {
+ color: inherit;
+ }
+
+ &:hover,
+ &:focus {
+ color: $color;
+ background-color: darken($background, 5%);
+ }
+ &.active,
+ &.active:hover,
+ &.active:focus {
+ color: #fff;
+ background-color: $color;
+ border-color: $color;
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_nav-divider.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_nav-divider.scss
new file mode 100644
index 0000000..80a39d4
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_nav-divider.scss
@@ -0,0 +1,11 @@
+@use "sass:math";
+// Horizontal dividers
+//
+// Dividers (basically an hr) within dropdowns and nav lists
+
+@mixin nav-divider($color: #e5e5e5) {
+ height: 1px;
+ margin: (math.div($line-height-computed, 2) - 1) 0;
+ overflow: hidden;
+ background-color: $color;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_nav-vertical-align.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_nav-vertical-align.scss
new file mode 100644
index 0000000..146d996
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_nav-vertical-align.scss
@@ -0,0 +1,10 @@
+@use "sass:math";
+// Navbar vertical align
+//
+// Vertically center elements in the navbar.
+// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.
+
+@mixin navbar-vertical-align($element-height) {
+ margin-top: math.div(($navbar-height - $element-height), 2);
+ margin-bottom: math.div(($navbar-height - $element-height), 2);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_opacity.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_opacity.scss
new file mode 100644
index 0000000..e9c5573
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_opacity.scss
@@ -0,0 +1,7 @@
+// Opacity
+
+@mixin opacity($opacity) {
+ $opacity-ie: ($opacity * 100); // IE8 filter
+ filter: alpha(opacity=$opacity-ie);
+ opacity: $opacity;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_pagination.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_pagination.scss
new file mode 100644
index 0000000..d4a5404
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_pagination.scss
@@ -0,0 +1,24 @@
+// Pagination
+
+@mixin pagination-size($padding-vertical, $padding-horizontal, $font-size, $line-height, $border-radius) {
+ > li {
+ > a,
+ > span {
+ padding: $padding-vertical $padding-horizontal;
+ font-size: $font-size;
+ line-height: $line-height;
+ }
+ &:first-child {
+ > a,
+ > span {
+ @include border-left-radius($border-radius);
+ }
+ }
+ &:last-child {
+ > a,
+ > span {
+ @include border-right-radius($border-radius);
+ }
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_panels.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_panels.scss
new file mode 100644
index 0000000..3ff31ae
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_panels.scss
@@ -0,0 +1,24 @@
+// Panels
+
+@mixin panel-variant($border, $heading-text-color, $heading-bg-color, $heading-border) {
+ border-color: $border;
+
+ & > .panel-heading {
+ color: $heading-text-color;
+ background-color: $heading-bg-color;
+ border-color: $heading-border;
+
+ + .panel-collapse > .panel-body {
+ border-top-color: $border;
+ }
+ .badge {
+ color: $heading-bg-color;
+ background-color: $heading-text-color;
+ }
+ }
+ & > .panel-footer {
+ + .panel-collapse > .panel-body {
+ border-bottom-color: $border;
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_progress-bar.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_progress-bar.scss
new file mode 100644
index 0000000..90a62af
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_progress-bar.scss
@@ -0,0 +1,10 @@
+// Progress bars
+
+@mixin progress-bar-variant($color) {
+ background-color: $color;
+
+ // Deprecated parent class requirement as of v3.2.0
+ .progress-striped & {
+ @include gradient-striped;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_reset-filter.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_reset-filter.scss
new file mode 100644
index 0000000..bf73051
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_reset-filter.scss
@@ -0,0 +1,8 @@
+// Reset filters for IE
+//
+// When you need to remove a gradient background, do not forget to use this to reset
+// the IE filter for IE9 and below.
+
+@mixin reset-filter() {
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_reset-text.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_reset-text.scss
new file mode 100644
index 0000000..8997eca
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_reset-text.scss
@@ -0,0 +1,18 @@
+@mixin reset-text() {
+ font-family: $font-family-base;
+ // We deliberately do NOT reset font-size.
+ font-style: normal;
+ font-weight: 400;
+ line-height: $line-height-base;
+ line-break: auto;
+ text-align: left; // Fallback for where `start` is not supported
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ word-wrap: normal;
+ white-space: normal;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_resize.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_resize.scss
new file mode 100644
index 0000000..66f233a
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_resize.scss
@@ -0,0 +1,6 @@
+// Resize anything
+
+@mixin resizable($direction) {
+ overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible`
+ resize: $direction; // Options: horizontal, vertical, both
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_responsive-visibility.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_responsive-visibility.scss
new file mode 100644
index 0000000..d25ef97
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_responsive-visibility.scss
@@ -0,0 +1,17 @@
+// [converter] $parent hack
+@mixin responsive-visibility($parent) {
+ #{$parent} {
+ display: block !important;
+ }
+ table#{$parent} { display: table !important; }
+ tr#{$parent} { display: table-row !important; }
+ th#{$parent},
+ td#{$parent} { display: table-cell !important; }
+}
+
+// [converter] $parent hack
+@mixin responsive-invisibility($parent) {
+ #{$parent} {
+ display: none !important;
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_size.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_size.scss
new file mode 100644
index 0000000..abbe246
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_size.scss
@@ -0,0 +1,10 @@
+// Sizing shortcuts
+
+@mixin size($width, $height) {
+ width: $width;
+ height: $height;
+}
+
+@mixin square($size) {
+ @include size($size, $size);
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_tab-focus.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_tab-focus.scss
new file mode 100644
index 0000000..f16ed64
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_tab-focus.scss
@@ -0,0 +1,9 @@
+// WebKit-style focus
+
+@mixin tab-focus() {
+ // WebKit-specific. Other browsers will keep their default outline style.
+ // (Initially tried to also force default via `outline: initial`,
+ // but that seems to erroneously remove the outline in Firefox altogether.)
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_table-row.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_table-row.scss
new file mode 100644
index 0000000..1367950
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_table-row.scss
@@ -0,0 +1,28 @@
+// Tables
+
+@mixin table-row-variant($state, $background) {
+ // Exact selectors below required to override `.table-striped` and prevent
+ // inheritance to nested tables.
+ .table > thead > tr,
+ .table > tbody > tr,
+ .table > tfoot > tr {
+ > td.#{$state},
+ > th.#{$state},
+ &.#{$state} > td,
+ &.#{$state} > th {
+ background-color: $background;
+ }
+ }
+
+ // Hover states for `.table-hover`
+ // Note: this is not available for cells or rows within `thead` or `tfoot`.
+ .table-hover > tbody > tr {
+ > td.#{$state}:hover,
+ > th.#{$state}:hover,
+ &.#{$state}:hover > td,
+ &:hover > .#{$state},
+ &.#{$state}:hover > th {
+ background-color: darken($background, 5%);
+ }
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_text-emphasis.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_text-emphasis.scss
new file mode 100644
index 0000000..3b446c4
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_text-emphasis.scss
@@ -0,0 +1,12 @@
+// Typography
+
+// [converter] $parent hack
+@mixin text-emphasis-variant($parent, $color) {
+ #{$parent} {
+ color: $color;
+ }
+ a#{$parent}:hover,
+ a#{$parent}:focus {
+ color: darken($color, 10%);
+ }
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_text-overflow.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_text-overflow.scss
new file mode 100644
index 0000000..1593b25
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_text-overflow.scss
@@ -0,0 +1,8 @@
+// Text overflow
+// Requires inline-block or block for proper styling
+
+@mixin text-overflow() {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
diff --git a/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_vendor-prefixes.scss b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_vendor-prefixes.scss
new file mode 100644
index 0000000..93d5775
--- /dev/null
+++ b/packages/css-variables-language-server/src/tests/fixtures/scss-nested/stylesheets/bootstrap/mixins/_vendor-prefixes.scss
@@ -0,0 +1,222 @@
+// Vendor Prefixes
+//
+// All vendor mixins are deprecated as of v3.2.0 due to the introduction of
+// Autoprefixer in our Gruntfile. They have been removed in v4.
+
+// - Animations
+// - Backface visibility
+// - Box shadow
+// - Box sizing
+// - Content columns
+// - Hyphens
+// - Placeholder text
+// - Transformations
+// - Transitions
+// - User Select
+
+
+// Animations
+@mixin animation($animation) {
+ -webkit-animation: $animation;
+ -o-animation: $animation;
+ animation: $animation;
+}
+@mixin animation-name($name) {
+ -webkit-animation-name: $name;
+ animation-name: $name;
+}
+@mixin animation-duration($duration) {
+ -webkit-animation-duration: $duration;
+ animation-duration: $duration;
+}
+@mixin animation-timing-function($timing-function) {
+ -webkit-animation-timing-function: $timing-function;
+ animation-timing-function: $timing-function;
+}
+@mixin animation-delay($delay) {
+ -webkit-animation-delay: $delay;
+ animation-delay: $delay;
+}
+@mixin animation-iteration-count($iteration-count) {
+ -webkit-animation-iteration-count: $iteration-count;
+ animation-iteration-count: $iteration-count;
+}
+@mixin animation-direction($direction) {
+ -webkit-animation-direction: $direction;
+ animation-direction: $direction;
+}
+@mixin animation-fill-mode($fill-mode) {
+ -webkit-animation-fill-mode: $fill-mode;
+ animation-fill-mode: $fill-mode;
+}
+
+// Backface visibility
+// Prevent browsers from flickering when using CSS 3D transforms.
+// Default value is `visible`, but can be changed to `hidden`
+
+@mixin backface-visibility($visibility) {
+ -webkit-backface-visibility: $visibility;
+ -moz-backface-visibility: $visibility;
+ backface-visibility: $visibility;
+}
+
+// Drop shadows
+//
+// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's
+// supported browsers that have box shadow capabilities now support it.
+
+@mixin box-shadow($shadow...) {
+ -webkit-box-shadow: $shadow; // iOS <4.3 & Android <4.1
+ box-shadow: $shadow;
+}
+
+// Box sizing
+@mixin box-sizing($boxmodel) {
+ -webkit-box-sizing: $boxmodel;
+ -moz-box-sizing: $boxmodel;
+ box-sizing: $boxmodel;
+}
+
+// CSS3 Content Columns
+@mixin content-columns($column-count, $column-gap: $grid-gutter-width) {
+ -webkit-column-count: $column-count;
+ -moz-column-count: $column-count;
+ column-count: $column-count;
+ -webkit-column-gap: $column-gap;
+ -moz-column-gap: $column-gap;
+ column-gap: $column-gap;
+}
+
+// Optional hyphenation
+@mixin hyphens($mode: auto) {
+ -webkit-hyphens: $mode;
+ -moz-hyphens: $mode;
+ -ms-hyphens: $mode; // IE10+
+ -o-hyphens: $mode;
+ hyphens: $mode;
+ word-wrap: break-word;
+}
+
+// Placeholder text
+@mixin placeholder($color: $input-color-placeholder) {
+ // Firefox
+ &::-moz-placeholder {
+ color: $color;
+ opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526
+ }
+ &:-ms-input-placeholder { color: $color; } // Internet Explorer 10+
+ &::-webkit-input-placeholder { color: $color; } // Safari and Chrome
+}
+
+// Transformations
+@mixin scale($ratio...) {
+ -webkit-transform: scale($ratio);
+ -ms-transform: scale($ratio); // IE9 only
+ -o-transform: scale($ratio);
+ transform: scale($ratio);
+}
+
+@mixin scaleX($ratio) {
+ -webkit-transform: scaleX($ratio);
+ -ms-transform: scaleX($ratio); // IE9 only
+ -o-transform: scaleX($ratio);
+ transform: scaleX($ratio);
+}
+@mixin scaleY($ratio) {
+ -webkit-transform: scaleY($ratio);
+ -ms-transform: scaleY($ratio); // IE9 only
+ -o-transform: scaleY($ratio);
+ transform: scaleY($ratio);
+}
+@mixin skew($x, $y) {
+ -webkit-transform: skewX($x) skewY($y);
+ -ms-transform: skewX($x) skewY($y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+
+ -o-transform: skewX($x) skewY($y);
+ transform: skewX($x) skewY($y);
+}
+@mixin translate($x, $y) {
+ -webkit-transform: translate($x, $y);
+ -ms-transform: translate($x, $y); // IE9 only
+ -o-transform: translate($x, $y);
+ transform: translate($x, $y);
+}
+@mixin translate3d($x, $y, $z) {
+ -webkit-transform: translate3d($x, $y, $z);
+ transform: translate3d($x, $y, $z);
+}
+@mixin rotate($degrees) {
+ -webkit-transform: rotate($degrees);
+ -ms-transform: rotate($degrees); // IE9 only
+ -o-transform: rotate($degrees);
+ transform: rotate($degrees);
+}
+@mixin rotateX($degrees) {
+ -webkit-transform: rotateX($degrees);
+ -ms-transform: rotateX($degrees); // IE9 only
+ -o-transform: rotateX($degrees);
+ transform: rotateX($degrees);
+}
+@mixin rotateY($degrees) {
+ -webkit-transform: rotateY($degrees);
+ -ms-transform: rotateY($degrees); // IE9 only
+ -o-transform: rotateY($degrees);
+ transform: rotateY($degrees);
+}
+@mixin perspective($perspective) {
+ -webkit-perspective: $perspective;
+ -moz-perspective: $perspective;
+ perspective: $perspective;
+}
+@mixin perspective-origin($perspective) {
+ -webkit-perspective-origin: $perspective;
+ -moz-perspective-origin: $perspective;
+ perspective-origin: $perspective;
+}
+@mixin transform-origin($origin) {
+ -webkit-transform-origin: $origin;
+ -moz-transform-origin: $origin;
+ -ms-transform-origin: $origin; // IE9 only
+ transform-origin: $origin;
+}
+
+
+// Transitions
+
+@mixin transition($transition...) {
+ -webkit-transition: $transition;
+ -o-transition: $transition;
+ transition: $transition;
+}
+@mixin transition-property($transition-property...) {
+ -webkit-transition-property: $transition-property;
+ transition-property: $transition-property;
+}
+@mixin transition-delay($transition-delay) {
+ -webkit-transition-delay: $transition-delay;
+ transition-delay: $transition-delay;
+}
+@mixin transition-duration($transition-duration...) {
+ -webkit-transition-duration: $transition-duration;
+ transition-duration: $transition-duration;
+}
+@mixin transition-timing-function($timing-function) {
+ -webkit-transition-timing-function: $timing-function;
+ transition-timing-function: $timing-function;
+}
+@mixin transition-transform($transition...) {
+ -webkit-transition: -webkit-transform $transition;
+ -moz-transition: -moz-transform $transition;
+ -o-transition: -o-transform $transition;
+ transition: transform $transition;
+}
+
+
+// User select
+// For selecting text on the page
+
+@mixin user-select($select) {
+ -webkit-user-select: $select;
+ -moz-user-select: $select;
+ -ms-user-select: $select; // IE10+
+ user-select: $select;
+}