]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Update Sass and Theme docs to document mixins and functions better (#42173)
authorMark Otto <markd.otto@gmail.com>
Sat, 21 Mar 2026 21:04:24 +0000 (14:04 -0700)
committerGitHub <noreply@github.com>
Sat, 21 Mar 2026 21:04:24 +0000 (14:04 -0700)
* Update Sass and Theme docs to document mixins and functions better

Also remove some unused functions while we're here.

* document it instead

* Fix cspell, add local cspell so i can test in dev

.cspell.json
package-lock.json
package.json
scss/_theme.scss
scss/forms/_validation.scss
scss/mixins/_forms.scss
site/src/content/docs/customize/color.mdx
site/src/content/docs/customize/sass.mdx
site/src/content/docs/migration.mdx

index 0b993929e98a10d46b3c36d1e38a5d5d1dc23896..92233df585f243eb0ff920c13953a12d15a68456 100644 (file)
@@ -74,6 +74,7 @@
     "navbars",
     "navs",
     "navoverflow",
+    "negativify",
     "Neue",
     "noindex",
     "Noto",
index 0dfa1b76670a485e05615bbb8912c5f8ffc28e42..cab4843fa277fccb8b2c64376bb9e29a3d9d5547 100644 (file)
@@ -43,6 +43,7 @@
         "bundlewatch": "^0.4.1",
         "clipboard": "^2.0.11",
         "cross-env": "^10.1.0",
+        "cspell": "^9.7.0",
         "eslint": "^10.1.0",
         "eslint-config-xo": "^0.50.0",
         "eslint-plugin-html": "^8.1.4",
         "node": ">=0.1.90"
       }
     },
+    "node_modules/@cspell/cspell-bundled-dicts": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-9.7.0.tgz",
+      "integrity": "sha512-s7h1vo++Q3AsfQa3cs0u/KGwm3SYInuIlC4kjlCBWjQmb4KddiZB5O1u0+3TlA7GycHb5M4CR7MDfHUICgJf+w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@cspell/dict-ada": "^4.1.1",
+        "@cspell/dict-al": "^1.1.1",
+        "@cspell/dict-aws": "^4.0.17",
+        "@cspell/dict-bash": "^4.2.2",
+        "@cspell/dict-companies": "^3.2.10",
+        "@cspell/dict-cpp": "^7.0.2",
+        "@cspell/dict-cryptocurrencies": "^5.0.5",
+        "@cspell/dict-csharp": "^4.0.8",
+        "@cspell/dict-css": "^4.0.19",
+        "@cspell/dict-dart": "^2.3.2",
+        "@cspell/dict-data-science": "^2.0.13",
+        "@cspell/dict-django": "^4.1.6",
+        "@cspell/dict-docker": "^1.1.17",
+        "@cspell/dict-dotnet": "^5.0.12",
+        "@cspell/dict-elixir": "^4.0.8",
+        "@cspell/dict-en_us": "^4.4.29",
+        "@cspell/dict-en-common-misspellings": "^2.1.12",
+        "@cspell/dict-en-gb-mit": "^3.1.18",
+        "@cspell/dict-filetypes": "^3.0.15",
+        "@cspell/dict-flutter": "^1.1.1",
+        "@cspell/dict-fonts": "^4.0.5",
+        "@cspell/dict-fsharp": "^1.1.1",
+        "@cspell/dict-fullstack": "^3.2.8",
+        "@cspell/dict-gaming-terms": "^1.1.2",
+        "@cspell/dict-git": "^3.1.0",
+        "@cspell/dict-golang": "^6.0.26",
+        "@cspell/dict-google": "^1.0.9",
+        "@cspell/dict-haskell": "^4.0.6",
+        "@cspell/dict-html": "^4.0.14",
+        "@cspell/dict-html-symbol-entities": "^4.0.5",
+        "@cspell/dict-java": "^5.0.12",
+        "@cspell/dict-julia": "^1.1.1",
+        "@cspell/dict-k8s": "^1.0.12",
+        "@cspell/dict-kotlin": "^1.1.1",
+        "@cspell/dict-latex": "^5.0.0",
+        "@cspell/dict-lorem-ipsum": "^4.0.5",
+        "@cspell/dict-lua": "^4.0.8",
+        "@cspell/dict-makefile": "^1.0.5",
+        "@cspell/dict-markdown": "^2.0.14",
+        "@cspell/dict-monkeyc": "^1.0.12",
+        "@cspell/dict-node": "^5.0.9",
+        "@cspell/dict-npm": "^5.2.34",
+        "@cspell/dict-php": "^4.1.1",
+        "@cspell/dict-powershell": "^5.0.15",
+        "@cspell/dict-public-licenses": "^2.0.15",
+        "@cspell/dict-python": "^4.2.25",
+        "@cspell/dict-r": "^2.1.1",
+        "@cspell/dict-ruby": "^5.1.0",
+        "@cspell/dict-rust": "^4.1.2",
+        "@cspell/dict-scala": "^5.0.9",
+        "@cspell/dict-shell": "^1.1.2",
+        "@cspell/dict-software-terms": "^5.1.21",
+        "@cspell/dict-sql": "^2.2.1",
+        "@cspell/dict-svelte": "^1.0.7",
+        "@cspell/dict-swift": "^2.0.6",
+        "@cspell/dict-terraform": "^1.1.3",
+        "@cspell/dict-typescript": "^3.2.3",
+        "@cspell/dict-vue": "^3.0.5",
+        "@cspell/dict-zig": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/@cspell/cspell-json-reporter": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-9.7.0.tgz",
+      "integrity": "sha512-6xpGXlMtQA3hV2BCAQcPkpx9eI12I0o01i9eRqSSEDKtxuAnnrejbcCpL+5OboAjTp3/BSeNYSnhuWYLkSITWQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@cspell/cspell-types": "9.7.0"
+      },
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/@cspell/cspell-performance-monitor": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/@cspell/cspell-performance-monitor/-/cspell-performance-monitor-9.7.0.tgz",
+      "integrity": "sha512-w1PZIFXuvjnC6mQHyYAFnrsn5MzKnEcEkcK1bj4OG00bAt7WX2VUA/eNNt9c1iHozCQ+FcRYlfbGxuBmNyzSgw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=20.18"
+      }
+    },
+    "node_modules/@cspell/cspell-pipe": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-9.7.0.tgz",
+      "integrity": "sha512-iiisyRpJciU9SOHNSi0ZEK0pqbEMFRatI/R4O+trVKb+W44p4MNGClLVRWPGUmsFbZKPJL3jDtz0wPlG0/JCZA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/@cspell/cspell-resolver": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-9.7.0.tgz",
+      "integrity": "sha512-uiEgS238mdabDnwavo6HXt8K98jlh/jpm7NONroM9NTr9rzck2VZKD2kXEj85wDNMtRsRXNoywTjwQ8WTB6/+w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "global-directory": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/@cspell/cspell-service-bus": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-9.7.0.tgz",
+      "integrity": "sha512-fkqtaCkg4jY/FotmzjhIavbXuH0AgUJxZk78Ktf4XlhqOZ4wDeUWrCf220bva4mh3TWiLx/ae9lIlpl59Vx6hA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/@cspell/cspell-types": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-9.7.0.tgz",
+      "integrity": "sha512-Tdfx4eH2uS+gv9V9NCr3Rz+c7RSS6ntXp3Blliud18ibRUlRxO9dTaOjG4iv4x0nAmMeedP1ORkEpeXSkh2QiQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/@cspell/cspell-worker": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/@cspell/cspell-worker/-/cspell-worker-9.7.0.tgz",
+      "integrity": "sha512-cjEApFF0aOAa1vTUk+e7xP8ofK7iC7hsRzj1FmvvVQz8PoLWPRaq+1bT89ypPsZQvavqm5sIgb97S60/aW4TVg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "cspell-lib": "9.7.0"
+      },
+      "engines": {
+        "node": ">=20.18"
+      }
+    },
+    "node_modules/@cspell/dict-ada": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-ada/-/dict-ada-4.1.1.tgz",
+      "integrity": "sha512-E+0YW9RhZod/9Qy2gxfNZiHJjCYFlCdI69br1eviQQWB8yOTJX0JHXLs79kOYhSW0kINPVUdvddEBe6Lu6CjGQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-al": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-al/-/dict-al-1.1.1.tgz",
+      "integrity": "sha512-sD8GCaZetgQL4+MaJLXqbzWcRjfKVp8x+px3HuCaaiATAAtvjwUQ5/Iubiqwfd1boIh2Y1/3EgM3TLQ7Q8e0wQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-aws": {
+      "version": "4.0.17",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-aws/-/dict-aws-4.0.17.tgz",
+      "integrity": "sha512-ORcblTWcdlGjIbWrgKF+8CNEBQiLVKdUOFoTn0KPNkAYnFcdPP0muT4892h7H4Xafh3j72wqB4/loQ6Nti9E/w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-bash": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-bash/-/dict-bash-4.2.2.tgz",
+      "integrity": "sha512-kyWbwtX3TsCf5l49gGQIZkRLaB/P8g73GDRm41Zu8Mv51kjl2H7Au0TsEvHv7jzcsRLS6aUYaZv6Zsvk1fOz+Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@cspell/dict-shell": "1.1.2"
+      }
+    },
+    "node_modules/@cspell/dict-companies": {
+      "version": "3.2.11",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.2.11.tgz",
+      "integrity": "sha512-0cmafbcz2pTHXLd59eLR1gvDvN6aWAOM0+cIL4LLF9GX9yB2iKDNrKsvs4tJRqutoaTdwNFBbV0FYv+6iCtebQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-cpp": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-7.0.2.tgz",
+      "integrity": "sha512-dfbeERiVNeqmo/npivdR6rDiBCqZi3QtjH2Z0HFcXwpdj6i97dX1xaKyK2GUsO/p4u1TOv63Dmj5Vm48haDpuA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-cryptocurrencies": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-cryptocurrencies/-/dict-cryptocurrencies-5.0.5.tgz",
+      "integrity": "sha512-R68hYYF/rtlE6T/dsObStzN5QZw+0aQBinAXuWCVqwdS7YZo0X33vGMfChkHaiCo3Z2+bkegqHlqxZF4TD3rUA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-csharp": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-csharp/-/dict-csharp-4.0.8.tgz",
+      "integrity": "sha512-qmk45pKFHSxckl5mSlbHxmDitSsGMlk/XzFgt7emeTJWLNSTUK//MbYAkBNRtfzB4uD7pAFiKgpKgtJrTMRnrQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-css": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-css/-/dict-css-4.1.1.tgz",
+      "integrity": "sha512-y/Vgo6qY08e1t9OqR56qjoFLBCpi4QfWMf2qzD1l9omRZwvSMQGRPz4x0bxkkkU4oocMAeztjzCsmLew//c/8w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-dart": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-dart/-/dict-dart-2.3.2.tgz",
+      "integrity": "sha512-sUiLW56t9gfZcu8iR/5EUg+KYyRD83Cjl3yjDEA2ApVuJvK1HhX+vn4e4k4YfjpUQMag8XO2AaRhARE09+/rqw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-data-science": {
+      "version": "2.0.13",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-2.0.13.tgz",
+      "integrity": "sha512-l1HMEhBJkPmw4I2YGVu2eBSKM89K9pVF+N6qIr5Uo5H3O979jVodtuwP8I7LyPrJnC6nz28oxeGRCLh9xC5CVA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-django": {
+      "version": "4.1.6",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-django/-/dict-django-4.1.6.tgz",
+      "integrity": "sha512-SdbSFDGy9ulETqNz15oWv2+kpWLlk8DJYd573xhIkeRdcXOjskRuxjSZPKfW7O3NxN/KEf3gm3IevVOiNuFS+w==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-docker": {
+      "version": "1.1.17",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.17.tgz",
+      "integrity": "sha512-OcnVTIpHIYYKhztNTyK8ShAnXTfnqs43hVH6p0py0wlcwRIXe5uj4f12n7zPf2CeBI7JAlPjEsV0Rlf4hbz/xQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-dotnet": {
+      "version": "5.0.12",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-dotnet/-/dict-dotnet-5.0.12.tgz",
+      "integrity": "sha512-FiV934kNieIjGTkiApu/WKvLYi/KBpvfWB2TSqpDQtmXZlt3uSa5blwblO1ZC8OvjH8RCq/31H5IdEYmTaZS7A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-elixir": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-elixir/-/dict-elixir-4.0.8.tgz",
+      "integrity": "sha512-CyfphrbMyl4Ms55Vzuj+mNmd693HjBFr9hvU+B2YbFEZprE5AG+EXLYTMRWrXbpds4AuZcvN3deM2XVB80BN/Q==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-en_us": {
+      "version": "4.4.31",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.4.31.tgz",
+      "integrity": "sha512-MdV6mbrSkyIqn9+6F5poCyHIPqWB3H/wlDL9LXfjgAxNFBdYRE767xJtIYunzUqhUiJHSJgZajEFdTtMDw441Q==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-en-common-misspellings": {
+      "version": "2.1.12",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.1.12.tgz",
+      "integrity": "sha512-14Eu6QGqyksqOd4fYPuRb58lK1Va7FQK9XxFsRKnZU8LhL3N+kj7YKDW+7aIaAN/0WGEqslGP6lGbQzNti8Akw==",
+      "dev": true,
+      "license": "CC BY-SA 4.0"
+    },
+    "node_modules/@cspell/dict-en-gb-mit": {
+      "version": "3.1.20",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb-mit/-/dict-en-gb-mit-3.1.20.tgz",
+      "integrity": "sha512-rcWEKb1mwgK13CSHu6GwwFA/sWLRkB0twTzSfPxUOULJkhcUrL93ixohk416SBa0BVxixub+lOpTXKcCTbTXsA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-filetypes": {
+      "version": "3.0.17",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-filetypes/-/dict-filetypes-3.0.17.tgz",
+      "integrity": "sha512-6f1gZf9o60fGQXGi/fZaryISUNDRmmJwGyr4QU1UvgUgOdpDHLVJtv/0wSL9q5F0wAkYhbXo/fNG8CcUTaf7Ww==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-flutter": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-flutter/-/dict-flutter-1.1.1.tgz",
+      "integrity": "sha512-UlOzRcH2tNbFhZmHJN48Za/2/MEdRHl2BMkCWZBYs+30b91mWvBfzaN4IJQU7dUZtowKayVIF9FzvLZtZokc5A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-fonts": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-fonts/-/dict-fonts-4.0.6.tgz",
+      "integrity": "sha512-aR/0csY01dNb0A1tw/UmN9rKgHruUxsYsvXu6YlSBJFu60s26SKr/k1o4LavpHTQ+lznlYMqAvuxGkE4Flliqw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-fsharp": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-fsharp/-/dict-fsharp-1.1.1.tgz",
+      "integrity": "sha512-imhs0u87wEA4/cYjgzS0tAyaJpwG7vwtC8UyMFbwpmtw+/bgss+osNfyqhYRyS/ehVCWL17Ewx2UPkexjKyaBA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-fullstack": {
+      "version": "3.2.8",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-fullstack/-/dict-fullstack-3.2.8.tgz",
+      "integrity": "sha512-J6EeoeThvx/DFrcA2rJiCA6vfqwJMbkG0IcXhlsmRZmasIpanmxgt90OEaUazbZahFiuJT8wrhgQ1QgD1MsqBw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-gaming-terms": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-gaming-terms/-/dict-gaming-terms-1.1.2.tgz",
+      "integrity": "sha512-9XnOvaoTBscq0xuD6KTEIkk9hhdfBkkvJAIsvw3JMcnp1214OCGW8+kako5RqQ2vTZR3Tnf3pc57o7VgkM0q1Q==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-git": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-git/-/dict-git-3.1.0.tgz",
+      "integrity": "sha512-KEt9zGkxqGy2q1nwH4CbyqTSv5nadpn8BAlDnzlRcnL0Xb3LX9xTgSGShKvzb0bw35lHoYyLWN2ZKAqbC4pgGQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-golang": {
+      "version": "6.0.26",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.26.tgz",
+      "integrity": "sha512-YKA7Xm5KeOd14v5SQ4ll6afe9VSy3a2DWM7L9uBq4u3lXToRBQ1W5PRa+/Q9udd+DTURyVVnQ+7b9cnOlNxaRg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-google": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-google/-/dict-google-1.0.9.tgz",
+      "integrity": "sha512-biL65POqialY0i4g6crj7pR6JnBkbsPovB2WDYkj3H4TuC/QXv7Pu5pdPxeUJA6TSCHI7T5twsO4VSVyRxD9CA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-haskell": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-haskell/-/dict-haskell-4.0.6.tgz",
+      "integrity": "sha512-ib8SA5qgftExpYNjWhpYIgvDsZ/0wvKKxSP+kuSkkak520iPvTJumEpIE+qPcmJQo4NzdKMN8nEfaeci4OcFAQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-html": {
+      "version": "4.0.15",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-html/-/dict-html-4.0.15.tgz",
+      "integrity": "sha512-GJYnYKoD9fmo2OI0aySEGZOjThnx3upSUvV7mmqUu8oG+mGgzqm82P/f7OqsuvTaInZZwZbo+PwJQd/yHcyFIw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-html-symbol-entities": {
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-4.0.5.tgz",
+      "integrity": "sha512-429alTD4cE0FIwpMucvSN35Ld87HCyuM8mF731KU5Rm4Je2SG6hmVx7nkBsLyrmH3sQukTcr1GaiZsiEg8svPA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-java": {
+      "version": "5.0.12",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-java/-/dict-java-5.0.12.tgz",
+      "integrity": "sha512-qPSNhTcl7LGJ5Qp6VN71H8zqvRQK04S08T67knMq9hTA8U7G1sTKzLmBaDOFhq17vNX/+rT+rbRYp+B5Nwza1A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-julia": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-julia/-/dict-julia-1.1.1.tgz",
+      "integrity": "sha512-WylJR9TQ2cgwd5BWEOfdO3zvDB+L7kYFm0I9u0s9jKHWQ6yKmfKeMjU9oXxTBxIufhCXm92SKwwVNAC7gjv+yA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-k8s": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-k8s/-/dict-k8s-1.0.12.tgz",
+      "integrity": "sha512-2LcllTWgaTfYC7DmkMPOn9GsBWsA4DZdlun4po8s2ysTP7CPEnZc1ZfK6pZ2eI4TsZemlUQQ+NZxMe9/QutQxg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-kotlin": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-kotlin/-/dict-kotlin-1.1.1.tgz",
+      "integrity": "sha512-J3NzzfgmxRvEeOe3qUXnSJQCd38i/dpF9/t3quuWh6gXM+krsAXP75dY1CzDmS8mrJAlBdVBeAW5eAZTD8g86Q==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-latex": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-latex/-/dict-latex-5.1.0.tgz",
+      "integrity": "sha512-qxT4guhysyBt0gzoliXYEBYinkAdEtR2M7goRaUH0a7ltCsoqqAeEV8aXYRIdZGcV77gYSobvu3jJL038tlPAw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-lorem-ipsum": {
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-lorem-ipsum/-/dict-lorem-ipsum-4.0.5.tgz",
+      "integrity": "sha512-9a4TJYRcPWPBKkQAJ/whCu4uCAEgv/O2xAaZEI0n4y1/l18Yyx8pBKoIX5QuVXjjmKEkK7hi5SxyIsH7pFEK9Q==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-lua": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-lua/-/dict-lua-4.0.8.tgz",
+      "integrity": "sha512-N4PkgNDMu9JVsRu7JBS/3E/dvfItRgk9w5ga2dKq+JupP2Y3lojNaAVFhXISh4Y0a6qXDn2clA6nvnavQ/jjLA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-makefile": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-makefile/-/dict-makefile-1.0.5.tgz",
+      "integrity": "sha512-4vrVt7bGiK8Rx98tfRbYo42Xo2IstJkAF4tLLDMNQLkQ86msDlYSKG1ZCk8Abg+EdNcFAjNhXIiNO+w4KflGAQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-markdown": {
+      "version": "2.0.16",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-markdown/-/dict-markdown-2.0.16.tgz",
+      "integrity": "sha512-976RRqKv6cwhrxdFCQP2DdnBVB86BF57oQtPHy4Zbf4jF/i2Oy29MCrxirnOBalS1W6KQeto7NdfDXRAwkK4PQ==",
+      "dev": true,
+      "license": "MIT",
+      "peerDependencies": {
+        "@cspell/dict-css": "^4.1.1",
+        "@cspell/dict-html": "^4.0.15",
+        "@cspell/dict-html-symbol-entities": "^4.0.5",
+        "@cspell/dict-typescript": "^3.2.3"
+      }
+    },
+    "node_modules/@cspell/dict-monkeyc": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-monkeyc/-/dict-monkeyc-1.0.12.tgz",
+      "integrity": "sha512-MN7Vs11TdP5mbdNFQP5x2Ac8zOBm97ARg6zM5Sb53YQt/eMvXOMvrep7+/+8NJXs0jkp70bBzjqU4APcqBFNAw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-node": {
+      "version": "5.0.9",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-node/-/dict-node-5.0.9.tgz",
+      "integrity": "sha512-hO+ga+uYZ/WA4OtiMEyKt5rDUlUyu3nXMf8KVEeqq2msYvAPdldKBGH7lGONg6R/rPhv53Rb+0Y1SLdoK1+7wQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-npm": {
+      "version": "5.2.37",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.2.37.tgz",
+      "integrity": "sha512-dYKrD0bI08YgebJcbjsIDpTMK6EH0wTkEyQLsaH0T4tmsLJE95coTYb3eE7giRRGJADvBqrjH4fz5+INd85QqQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-php": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-php/-/dict-php-4.1.1.tgz",
+      "integrity": "sha512-EXelI+4AftmdIGtA8HL8kr4WlUE11OqCSVlnIgZekmTkEGSZdYnkFdiJ5IANSALtlQ1mghKjz+OFqVs6yowgWA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-powershell": {
+      "version": "5.0.15",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-powershell/-/dict-powershell-5.0.15.tgz",
+      "integrity": "sha512-l4S5PAcvCFcVDMJShrYD0X6Huv9dcsQPlsVsBGbH38wvuN7gS7+GxZFAjTNxDmTY1wrNi1cCatSg6Pu2BW4rgg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-public-licenses": {
+      "version": "2.0.16",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-public-licenses/-/dict-public-licenses-2.0.16.tgz",
+      "integrity": "sha512-EQRrPvEOmwhwWezV+W7LjXbIBjiy6y/shrET6Qcpnk3XANTzfvWflf9PnJ5kId/oKWvihFy0za0AV1JHd03pSQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-python": {
+      "version": "4.2.25",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.2.25.tgz",
+      "integrity": "sha512-hDdN0YhKgpbtZVRjQ2c8jk+n0wQdidAKj1Fk8w7KEHb3YlY5uPJ0mAKJk7AJKPNLOlILoUmN+HAVJz+cfSbWYg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@cspell/dict-data-science": "^2.0.13"
+      }
+    },
+    "node_modules/@cspell/dict-r": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-r/-/dict-r-2.1.1.tgz",
+      "integrity": "sha512-71Ka+yKfG4ZHEMEmDxc6+blFkeTTvgKbKAbwiwQAuKl3zpqs1Y0vUtwW2N4b3LgmSPhV3ODVY0y4m5ofqDuKMw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-ruby": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-ruby/-/dict-ruby-5.1.1.tgz",
+      "integrity": "sha512-LHrp84oEV6q1ZxPPyj4z+FdKyq1XAKYPtmGptrd+uwHbrF/Ns5+fy6gtSi7pS+uc0zk3JdO9w/tPK+8N1/7WUA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-rust": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-rust/-/dict-rust-4.1.2.tgz",
+      "integrity": "sha512-O1FHrumYcO+HZti3dHfBPUdnDFkI+nbYK3pxYmiM1sr+G0ebOd6qchmswS0Wsc6ZdEVNiPYJY/gZQR6jfW3uOg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-scala": {
+      "version": "5.0.9",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-scala/-/dict-scala-5.0.9.tgz",
+      "integrity": "sha512-AjVcVAELgllybr1zk93CJ5wSUNu/Zb5kIubymR/GAYkMyBdYFCZ3Zbwn4Zz8GJlFFAbazABGOu0JPVbeY59vGg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-shell": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-shell/-/dict-shell-1.1.2.tgz",
+      "integrity": "sha512-WqOUvnwcHK1X61wAfwyXq04cn7KYyskg90j4lLg3sGGKMW9Sq13hs91pqrjC44Q+lQLgCobrTkMDw9Wyl9nRFA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-software-terms": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-5.2.0.tgz",
+      "integrity": "sha512-jyucc8KKxH5ClC4FPICISgcKAZU7UwgFdPkuuuK5nYIw0+l1umnUSn9IKCcOaurvXujvVP6mBfclXpUtmT6Vrw==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-sql": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-sql/-/dict-sql-2.2.1.tgz",
+      "integrity": "sha512-qDHF8MpAYCf4pWU8NKbnVGzkoxMNrFqBHyG/dgrlic5EQiKANCLELYtGlX5auIMDLmTf1inA0eNtv74tyRJ/vg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-svelte": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-svelte/-/dict-svelte-1.0.7.tgz",
+      "integrity": "sha512-hGZsGqP0WdzKkdpeVLBivRuSNzOTvN036EBmpOwxH+FTY2DuUH7ecW+cSaMwOgmq5JFSdTcbTNFlNC8HN8lhaQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-swift": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-swift/-/dict-swift-2.0.6.tgz",
+      "integrity": "sha512-PnpNbrIbex2aqU1kMgwEKvCzgbkHtj3dlFLPMqW1vSniop7YxaDTtvTUO4zA++ugYAEL+UK8vYrBwDPTjjvSnA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-terraform": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-terraform/-/dict-terraform-1.1.3.tgz",
+      "integrity": "sha512-gr6wxCydwSFyyBKhBA2xkENXtVFToheqYYGFvlMZXWjviynXmh+NK/JTvTCk/VHk3+lzbO9EEQKee6VjrAUSbA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-typescript": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.2.3.tgz",
+      "integrity": "sha512-zXh1wYsNljQZfWWdSPYwQhpwiuW0KPW1dSd8idjMRvSD0aSvWWHoWlrMsmZeRl4qM4QCEAjua8+cjflm41cQBg==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-vue": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-vue/-/dict-vue-3.0.5.tgz",
+      "integrity": "sha512-Mqutb8jbM+kIcywuPQCCaK5qQHTdaByoEO2J9LKFy3sqAdiBogNkrplqUK0HyyRFgCfbJUgjz3N85iCMcWH0JA==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dict-zig": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@cspell/dict-zig/-/dict-zig-1.0.0.tgz",
+      "integrity": "sha512-XibBIxBlVosU06+M6uHWkFeT0/pW5WajDRYdXG2CgHnq85b0TI/Ks0FuBJykmsgi2CAD3Qtx8UHFEtl/DSFnAQ==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/@cspell/dynamic-import": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-9.7.0.tgz",
+      "integrity": "sha512-Ws36IYvtS/8IN3x6K9dPLvTmaArodRJmzTn2Rkf2NaTnIYWhRuFzsP3SVVO59NN3fXswAEbmz5DSbVUe8bPZHg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@cspell/url": "9.7.0",
+        "import-meta-resolve": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/@cspell/filetypes": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-9.7.0.tgz",
+      "integrity": "sha512-Ln9e/8wGOyTeL3DCCs6kwd18TSpTw3kxsANjTrzLDASrX4cNmAdvc9J5dcIuBHPaqOAnRQxuZbzUlpRh73Y24w==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/@cspell/rpc": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/@cspell/rpc/-/rpc-9.7.0.tgz",
+      "integrity": "sha512-VnZ4ABgQeoS4RwofcePkDP7L6tf3Kh5D7LQKoyRM4R6XtfSsYefym6XKaRl3saGtthH5YyjgNJ0Tgdjen4wAAw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=20.18"
+      }
+    },
+    "node_modules/@cspell/strong-weak-map": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-9.7.0.tgz",
+      "integrity": "sha512-5xbvDASjklrmy88O6gmGXgYhpByCXqOj5wIgyvwZe2l83T1bE+iOfGI4pGzZJ/mN+qTn1DNKq8BPBPtDgb7Q2Q==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/@cspell/url": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/@cspell/url/-/url-9.7.0.tgz",
+      "integrity": "sha512-ZaaBr0pTvNxmyUbIn+nVPXPr383VqJzfUDMWicgTjJIeo2+T2hOq2kNpgpvTIrWtZrsZnSP8oXms1+sKTjcvkw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=20"
+      }
+    },
     "node_modules/@csstools/css-parser-algorithms": {
       "version": "3.0.5",
       "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz",
         "url": "https://github.com/sponsors/wooorm"
       }
     },
+    "node_modules/array-timsort": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz",
+      "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/array-union": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
         "node": "*"
       }
     },
+    "node_modules/chalk": {
+      "version": "5.6.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+      "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": "^12.17.0 || ^14.13 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/chalk-template": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-1.1.2.tgz",
+      "integrity": "sha512-2bxTP2yUH7AJj/VAXfcA+4IcWGdQ87HwBANLt5XxGTeomo8yG0y95N1um9i5StvhT/Bl0/2cARA5v1PpPXUxUA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "chalk": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=14.16"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk-template?sponsor=1"
+      }
+    },
     "node_modules/change-case": {
       "version": "5.4.4",
       "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz",
         "node": ">=0.8.0"
       }
     },
+    "node_modules/clear-module": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/clear-module/-/clear-module-4.1.2.tgz",
+      "integrity": "sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "parent-module": "^2.0.0",
+        "resolve-from": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/clear-module/node_modules/parent-module": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-2.0.0.tgz",
+      "integrity": "sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "callsites": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/clear-module/node_modules/resolve-from": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/clipboard": {
       "version": "2.0.11",
       "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.11.tgz",
         "node": ">= 6"
       }
     },
+    "node_modules/comment-json": {
+      "version": "4.6.2",
+      "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.6.2.tgz",
+      "integrity": "sha512-R2rze/hDX30uul4NZoIZ76ImSJLFxn/1/ZxtKC1L77y2X1k+yYu1joKbAtMA2Fg3hZrTOiw0I5mwVMo0cf250w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "array-timsort": "^1.0.3",
+        "esprima": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/comment-parser": {
       "version": "1.4.5",
       "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.5.tgz",
         "uncrypto": "^0.1.3"
       }
     },
+    "node_modules/cspell": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/cspell/-/cspell-9.7.0.tgz",
+      "integrity": "sha512-ftxOnkd+scAI7RZ1/ksgBZRr0ouC7QRKtPQhD/PbLTKwAM62sSvRhE1bFsuW3VKBn/GilWzTjkJ40WmnDqH5iQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@cspell/cspell-json-reporter": "9.7.0",
+        "@cspell/cspell-performance-monitor": "9.7.0",
+        "@cspell/cspell-pipe": "9.7.0",
+        "@cspell/cspell-types": "9.7.0",
+        "@cspell/cspell-worker": "9.7.0",
+        "@cspell/dynamic-import": "9.7.0",
+        "@cspell/url": "9.7.0",
+        "ansi-regex": "^6.2.2",
+        "chalk": "^5.6.2",
+        "chalk-template": "^1.1.2",
+        "commander": "^14.0.3",
+        "cspell-config-lib": "9.7.0",
+        "cspell-dictionary": "9.7.0",
+        "cspell-gitignore": "9.7.0",
+        "cspell-glob": "9.7.0",
+        "cspell-io": "9.7.0",
+        "cspell-lib": "9.7.0",
+        "fast-json-stable-stringify": "^2.1.0",
+        "flatted": "^3.3.3",
+        "semver": "^7.7.4",
+        "tinyglobby": "^0.2.15"
+      },
+      "bin": {
+        "cspell": "bin.mjs",
+        "cspell-esm": "bin.mjs"
+      },
+      "engines": {
+        "node": ">=20.18"
+      },
+      "funding": {
+        "url": "https://github.com/streetsidesoftware/cspell?sponsor=1"
+      }
+    },
+    "node_modules/cspell-config-lib": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-9.7.0.tgz",
+      "integrity": "sha512-pguh8A3+bSJ1OOrKCiQan8bvaaY125de76OEFz7q1Pq309lIcDrkoL/W4aYbso/NjrXaIw6OjkgPMGRBI/IgGg==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@cspell/cspell-types": "9.7.0",
+        "comment-json": "^4.5.1",
+        "smol-toml": "^1.6.0",
+        "yaml": "^2.8.2"
+      },
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/cspell-dictionary": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-9.7.0.tgz",
+      "integrity": "sha512-k/Wz0so32+0QEqQe21V9m4BNXM5ZN6lz3Ix/jLCbMxFIPl6wT711ftjOWIEMFhvUOP0TWXsbzcuE9mKtS5mTig==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@cspell/cspell-performance-monitor": "9.7.0",
+        "@cspell/cspell-pipe": "9.7.0",
+        "@cspell/cspell-types": "9.7.0",
+        "cspell-trie-lib": "9.7.0",
+        "fast-equals": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/cspell-gitignore": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-9.7.0.tgz",
+      "integrity": "sha512-MtoYuH4ah4K6RrmaF834npMcRsTKw0658mC6yvmBacUQOmwB/olqyuxF3fxtbb55HDb7cXDQ35t1XuwwGEQeZw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@cspell/url": "9.7.0",
+        "cspell-glob": "9.7.0",
+        "cspell-io": "9.7.0"
+      },
+      "bin": {
+        "cspell-gitignore": "bin.mjs"
+      },
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/cspell-glob": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-9.7.0.tgz",
+      "integrity": "sha512-LUeAoEsoCJ+7E3TnUmWBscpVQOmdwBejMlFn0JkXy6LQzxrybxXBKf65RSdIv1o5QtrhQIMa358xXYQG0sv/tA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@cspell/url": "9.7.0",
+        "picomatch": "^4.0.3"
+      },
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/cspell-grammar": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-9.7.0.tgz",
+      "integrity": "sha512-oEYME+7MJztfVY1C06aGcJgEYyqBS/v/ETkQGPzf/c6ObSAPRcUbVtsXZgnR72Gru9aBckc70xJcD6bELdoWCA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@cspell/cspell-pipe": "9.7.0",
+        "@cspell/cspell-types": "9.7.0"
+      },
+      "bin": {
+        "cspell-grammar": "bin.mjs"
+      },
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/cspell-io": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-9.7.0.tgz",
+      "integrity": "sha512-V7x0JHAUCcJPRCH8c0MQkkaKmZD2yotxVyrNEx2SZTpvnKrYscLEnUUTWnGJIIf9znzISqw116PLnYu2c+zd6Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@cspell/cspell-service-bus": "9.7.0",
+        "@cspell/url": "9.7.0"
+      },
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/cspell-lib": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-9.7.0.tgz",
+      "integrity": "sha512-aTx/aLRpnuY1RJnYAu+A8PXfm1oIUdvAQ4W9E66bTgp1LWI+2G2++UtaPxRIgI0olxE9vcXqUnKpjOpO+5W9bQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@cspell/cspell-bundled-dicts": "9.7.0",
+        "@cspell/cspell-performance-monitor": "9.7.0",
+        "@cspell/cspell-pipe": "9.7.0",
+        "@cspell/cspell-resolver": "9.7.0",
+        "@cspell/cspell-types": "9.7.0",
+        "@cspell/dynamic-import": "9.7.0",
+        "@cspell/filetypes": "9.7.0",
+        "@cspell/rpc": "9.7.0",
+        "@cspell/strong-weak-map": "9.7.0",
+        "@cspell/url": "9.7.0",
+        "clear-module": "^4.1.2",
+        "cspell-config-lib": "9.7.0",
+        "cspell-dictionary": "9.7.0",
+        "cspell-glob": "9.7.0",
+        "cspell-grammar": "9.7.0",
+        "cspell-io": "9.7.0",
+        "cspell-trie-lib": "9.7.0",
+        "env-paths": "^4.0.0",
+        "gensequence": "^8.0.8",
+        "import-fresh": "^3.3.1",
+        "resolve-from": "^5.0.0",
+        "vscode-languageserver-textdocument": "^1.0.12",
+        "vscode-uri": "^3.1.0",
+        "xdg-basedir": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/cspell-lib/node_modules/env-paths": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-4.0.0.tgz",
+      "integrity": "sha512-pxP8eL2SwwaTRi/KHYwLYXinDs7gL3jxFcBYmEdYfZmZXbaVDvdppd0XBU8qVz03rDfKZMXg1omHCbsJjZrMsw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "is-safe-filename": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=20"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/cspell-lib/node_modules/resolve-from": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/cspell-trie-lib": {
+      "version": "9.7.0",
+      "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-9.7.0.tgz",
+      "integrity": "sha512-a2YqmcraL3g6I/4gY7SYWEZfP73oLluUtxO7wxompk/kOG2K1FUXyQfZXaaR7HxVv10axT1+NrjhOmXpfbI6LA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=20"
+      },
+      "peerDependencies": {
+        "@cspell/cspell-types": "9.7.0"
+      }
+    },
+    "node_modules/cspell/node_modules/ansi-regex": {
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+      "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+      }
+    },
+    "node_modules/cspell/node_modules/commander": {
+      "version": "14.0.3",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
+      "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=20"
+      }
+    },
+    "node_modules/cspell/node_modules/semver": {
+      "version": "7.7.4",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+      "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/css-functions-list": {
       "version": "3.2.3",
       "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz",
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/fast-equals": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-6.0.0.tgz",
+      "integrity": "sha512-PFhhIGgdM79r5Uztdj9Zb6Tt1zKafqVfdMGwVca1z5z6fbX7DmsySSuJd8HiP6I1j505DCS83cLxo5rmSNeVEA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
     "node_modules/fast-glob": {
       "version": "3.3.3",
       "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/gensequence": {
+      "version": "8.0.8",
+      "resolved": "https://registry.npmjs.org/gensequence/-/gensequence-8.0.8.tgz",
+      "integrity": "sha512-omMVniXEXpdx/vKxGnPRoO2394Otlze28TyxECbFVyoSpZ9H3EO7lemjcB12OpQJzRW4e5tt/dL1rOxry6aMHg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=20"
+      }
+    },
     "node_modules/gensync": {
       "version": "1.0.0-beta.2",
       "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
         "node": ">=10.13.0"
       }
     },
+    "node_modules/global-directory": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-5.0.0.tgz",
+      "integrity": "sha512-1pgFdhK3J2LeM+dVf2Pd424yHx2ou338lC0ErNP2hPx4j8eW1Sp0XqSjNxtk6Tc4Kr5wlWtSvz8cn2yb7/SG/w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "ini": "6.0.0"
+      },
+      "engines": {
+        "node": ">=20"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/global-directory/node_modules/ini": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz",
+      "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==",
+      "dev": true,
+      "license": "ISC",
+      "engines": {
+        "node": "^20.17.0 || >=22.9.0"
+      }
+    },
     "node_modules/global-modules": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/import-meta-resolve": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz",
+      "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==",
+      "dev": true,
+      "license": "MIT",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
     "node_modules/imurmurhash": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/is-safe-filename": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-safe-filename/-/is-safe-filename-0.1.1.tgz",
+      "integrity": "sha512-4SrR7AdnY11LHfDKTZY1u6Ga3RuxZdl3YKWWShO5iyuG5h8QS4GD2tOb04peBJ5I7pXbR+CGBNEhTcwK+FzN3g==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=20"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/is-stream": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
         }
       }
     },
+    "node_modules/xdg-basedir": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz",
+      "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/xxhash-wasm": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz",
index a5a5cb97c49db50e5a36e246fa308044d7f1031b..0946e6f7fe686abdd0edff1347449bc92ad8d16d 100644 (file)
     "watch-js-docs": "nodemon --watch site/src/assets/ --ext js --exec \"npm run js-lint\"",
     "astro-dev": "astro dev --root site --port 9001",
     "astro-build": "astro build --root site && rm -rf _site && cp -r site/dist _site",
-    "astro-preview": "astro preview --root site --port 9001"
+    "astro-preview": "astro preview --root site --port 9001",
+    "spellcheck": "cspell --config .cspell.json \"**/*.{md,mdx}\""
   },
   "peerDependencies": {
     "@floating-ui/dom": "^1.7.6",
     "bundlewatch": "^0.4.1",
     "clipboard": "^2.0.11",
     "cross-env": "^10.1.0",
+    "cspell": "^9.7.0",
     "eslint": "^10.1.0",
     "eslint-config-xo": "^0.50.0",
     "eslint-plugin-html": "^8.1.4",
index 7378f22fe372b5e14ad2d2b49f25ff96dcc0a4c8..d2b3ee6b6213a4b480e6ff6738d401c3aaf9d488 100644 (file)
@@ -1,4 +1,3 @@
-@use "sass:meta";
 @use "sass:map";
 
 @function theme-color-values($key) {
   }
 }
 
-// Recursive mixin to handle nested maps
-@mixin create-css-vars($map, $parent-key: "") {
-  @each $key, $value in $map {
-    // stylelint-disable-next-line scss/at-function-named-arguments
-    $current-key: if(sass($parent-key == ""): $key; else: "#{$parent-key}-#{$key}");
-
-    @if meta.type-of($value) == "map" {
-      @include create-css-vars($value, $current-key);
-    } @else {
-      --#{$current-key}: #{$value};
-    }
-  }
-}
-
 // scss-docs-start theme-colors
 $theme-colors: (
   "primary": (
index 75897491f291fab288fc3027c775da953794836f..228c5c9876cfa9cbf4859d09a8a86bb4b34b4924 100644 (file)
   .form-control-color {
     @include form-validation-state-selector($state) {
       @if $enable-validation-icons {
-        // width: add($form-color-width, $input-height-inner);
+        // width: calc($form-color-width + $input-height-inner);
       }
     }
   }
index ea1b9e8d14b5bc5bf4b85521dca74eed5ac9f37f..8924a53e181d72bdb5d53ae97dd637459aabe908 100644 (file)
   .form-control-color {
     @include form-validation-state-selector($state) {
       @if $enable-validation-icons {
-        width: add($form-color-width, $input-height-inner);
+        width: calc($form-color-width + $input-height-inner);
       }
     }
   }
index 7c4cd7057118a7fc7629c186739f059059e09bc0..f7eae6ea3d0b8d082457f87caef345a402df0edc 100644 (file)
@@ -77,6 +77,24 @@ Those options and the `$colors` map are used to generate a `$color-tokens` map,
 
 <ScssDocs name="color-tokens" file="scss/_colors.scss" />
 
+In practice, our CSS variables that get output from this looks like this:
+
+```scss
+// Example generated custom properties from _colors.scss
+--bs-blue-025: color-mix(in lab, var(--bs-white) 94%, oklch(60% 0.24 240));
+--bs-blue-050: color-mix(in lab, var(--bs-white) 90%, oklch(60% 0.24 240));
+--bs-blue-100: color-mix(in lab, var(--bs-white) 80%, oklch(60% 0.24 240));
+// ...
+--bs-blue-500: oklch(60% 0.24 240);
+// ...
+--bs-blue-900: color-mix(in lab, var(--bs-black) 64%, oklch(60% 0.24 240));
+--bs-blue-975: color-mix(in lab, var(--bs-black) 88%, oklch(60% 0.24 240));
+```
+
+<Callout type="info">
+We use CSS variables `var(--bs-white)` and `var(--bs-black)` to prevent LightningCSS from converting the real-time mixing into static `lab()` values. Unfortunately, this feature cannot be disabled in LightningCSS at this time.
+</Callout>
+
 ## Customizing
 
 You can customize the colors by adding or removing colors from the `$colors` map. You can also customize the tint and shade stops, the `color-mix()` color space, and the mix colors. Say you want to add another blue-gray color, like slate.
index e5ff4d7054143dd006b55442a9f4fa49bd2d28ff..1b1ea5e927f1f5f8976432dadf2e5df420abc72b 100644 (file)
@@ -360,7 +360,7 @@ For `$theme-colors`, the `primary`, `success`, and `danger` keys are required fo
 
 ### Defaults
 
-The `defaults()` function is the backbone of Bootstrap's customization system. It merges user overrides on top of built-in defaults and strips any `null` entries from the result. Every token map, size map, and variant map uses it:
+The `defaults()` function is the backbone of Bootstrap's customization system. It merges user overrides on top of built-in default tokens and strips any `null` entries from the result. Every token map, size map, and variant map uses it:
 
 ```scss
 @function defaults($defaults, $overrides) { ... }
@@ -368,23 +368,7 @@ The `defaults()` function is the backbone of Bootstrap's customization system. I
 
 It accepts either a map or a list as the first argument. Lists are automatically converted to maps with `true` values, which is how size maps like `$button-sizes` work with a clean `("xs", "sm", "lg")` syntax.
 
-### Colors
-
-Base colors are defined as `oklch()` values and expanded into full scales via `color-mix()`. Each hue generates steps from `025` to `975`:
-
-```scss
-// Example generated custom properties from _colors.scss
---blue-025: color-mix(in lab, #fff 94%, oklch(60% 0.24 240));
---blue-050: color-mix(in lab, #fff 90%, oklch(60% 0.24 240));
---blue-100: color-mix(in lab, #fff 80%, oklch(60% 0.24 240));
-// ...
---blue-500: oklch(60% 0.24 240);
-// ...
---blue-900: color-mix(in lab, #000 64%, oklch(60% 0.24 240));
---blue-975: color-mix(in lab, #000 88%, oklch(60% 0.24 240));
-```
-
-You can reference any color scale step as a CSS custom property: `var(--blue-500)`, `var(--red-200)`, `var(--gray-900)`, etc.
+`defaults()` are generated on specific selectors with the [`tokens()` mixin](#tokens).
 
 ### Color contrast
 
@@ -406,47 +390,119 @@ For example, to generate color swatches from our `$theme-colors` map:
 
 We use the `escape-svg` function to escape the `<`, `>` and `#` characters for SVG background images. When using the `escape-svg` function, data URIs must be quoted.
 
-### Add and Subtract functions
+```scss
+// Input — an inline SVG with special characters
+$icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='none' stroke='#00000080' stroke-width='2' d='m2 5 6 6 6-6'/></svg>");
+
+// After escape-svg(), the <, >, and # characters are percent-encoded
+// so the data URI works reliably as a CSS background-image
+.element {
+  background-image: escape-svg($icon);
+}
+```
+
+### Map helpers
 
-We use the `add` and `subtract` functions to wrap the CSS `calc` function. The primary purpose of these functions is to avoid errors when a "unitless" `0` value is passed into a `calc` expression. Expressions like `calc(10px - 0)` will return an error in all browsers, despite being mathematically correct.
+We include several Sass functions for working with maps beyond what Sass provides natively.
 
-Example where the calc is valid:
+<BsTable>
+| Function | Description |
+| --- | --- |
+| `map-merge-multiple($maps...)` | Merges any number of maps into one, processing them left to right. |
+| `map-get-multiple($map, $values)` | Returns a subset of a map filtered to only the keys listed in `$values`. |
+| `map-get-nested($map, $nested-key)` | Extracts a single property from every nested map entry, returning a flat map. |
+</BsTable>
+
+#### `map-merge-multiple($maps...)`
 
 ```scss
-$border-radius: .25rem;
-$border-width: 1px;
+@function map-merge-multiple($maps...) { ... }
 
-.element {
-  // Output calc(.25rem - 1px) is valid
-  border-radius: calc($border-radius - $border-width);
-}
+// Example: combine spacers, negative spacers, and auto into a single values map
+values: map-merge-multiple($spacers, $negative-spacers, (auto: auto))
+```
 
-.element {
-  // Output the same calc(.25rem - 1px) as above
-  border-radius: subtract($border-radius, $border-width);
-}
+#### `map-get-multiple($map, $values)`
+
+```scss
+@function map-get-multiple($map, $values) { ... }
+
+// Example: extract only the flex and order utilities
+$utilities: map-get-multiple(
+  $utilities,
+  ("flex", "flex-direction", "flex-grow", "order")
+);
 ```
 
-Example where the calc is invalid:
+#### `map-get-nested($map, $nested-key)`
 
 ```scss
-$border-radius: .25rem;
-$border-width: 0;
+@function map-get-nested($map, $nested-key) { ... }
 
-.element {
-  // Output calc(.25rem - 0) is invalid
-  border-radius: calc($border-radius - $border-width);
-}
+// Example: pull just the "font-size" value from each entry in $font-sizes
+values: map-get-nested($font-sizes, "font-size")
+// Returns: ("xs": clamp(...), "sm": clamp(...), ...)
+```
 
-.element {
-  // Output .25rem
-  border-radius: subtract($border-radius, $border-width);
-}
+#### `negativify-map($map)`
+
+Turns a map into its negative variant by prefixing each key with `n` and negating the value. Keys equal to `0` are skipped. This is used internally to generate negative spacer utilities (e.g., `n1`, `n2`, etc.) from the `$spacers` map.
+
+```scss
+@function negativify-map($map) { ... }
+
+// Example: generate negative spacers from a spacers map
+$spacers: (0: 0, 1: .25rem, 2: .5rem, 3: 1rem);
+$negative-spacers: negativify-map($spacers);
+// Returns: ("n1": -.25rem, "n2": -.5rem, "n3": -1rem)
+```
+
+### Theme color values
+
+The [`theme-color-values($key)`]([[docsref:/customize/theme]]) function in `scss/_theme.scss` extracts a specific sub-key from every entry in the `$theme-colors` map, returning a flat map of color names to values. Since each theme color is a nested map with sub-keys like `base`, `text`, `bg`, `border`, etc., this function lets you pull one of those sub-keys across all colors at once. It powers most of the color-related utilities in `_utilities.scss`:
+
+```scss
+// In _utilities.scss — generate .focus-ring-{color} classes
+"focus-ring": (
+  property: --focus-ring-color,
+  class: focus-ring,
+  values: theme-color-values("focus-ring"),
+),
+
+// Merge theme color backgrounds with semantic border tokens for .border-{color} classes
+"border-color": (
+  property: (
+    "--border-color": null,
+    "border-color": var(--border-color)
+  ),
+  class: border,
+  values: map.merge(theme-color-values("bg"), $theme-borders),
+),
+```
+
+### Theme opacity values
+
+The [`theme-opacity-values($color-var, $opacities)`]([[docsref:/customize/theme]]) function in `scss/_theme.scss` generates a map of opacity variants for a CSS custom property using `color-mix()`. The `$opacities` argument defaults to `$util-opacity` (10 through 100 in steps of 10). At `100`, it returns the variable directly; for all other steps, it mixes the variable against `transparent`:
+
+```scss
+// In _utilities.scss — generate .border-{opacity} classes
+"border-opacity": (
+  class: border,
+  property: border-color,
+  values: theme-opacity-values(--border-color)
+),
+
+// Generate .fg-{opacity} classes
+"fg-opacity": (
+  class: fg,
+  property: color,
+  values: theme-opacity-values(--fg)
+),
 ```
 
 ## Mixins
 
-Our `scss/mixins/` directory has a ton of mixins that power parts of Bootstrap and can also be used across your own project.
+Our `scss/mixins/` directory has snippets of code that power Bootstrap and can also be used across your own project.
 
 ### Tokens
 
@@ -478,3 +534,15 @@ A shorthand mixin for the `prefers-color-scheme` media query is available with s
   }
 }
 ```
+
+### Theme classes
+
+The `generate-theme-classes()` mixin loops over the `$theme-colors` map and outputs a `.theme-*` class for each color. Each class maps generic `--theme-*` custom properties to the color's specific values, so components can reference `--theme-base`, `--theme-bg`, etc., and pick up the right palette from a parent `.theme-*` class:
+
+```scss
+@include generate-theme-classes();
+// Outputs:
+// .theme-primary { --theme-base: var(--primary-base); --theme-bg: var(--primary-bg); ... }
+// .theme-success { --theme-base: var(--success-base); --theme-bg: var(--success-bg); ... }
+// ...
+```
index ccf6ab82500dadd6b862a01fd4ec0e8d7bc72bb6..c3938ba6d15c7f70357c6d335641d9226a76400d 100644 (file)
@@ -69,6 +69,7 @@ Bootstrap 6 is a major release with many breaking changes to modernize our codeb
 - Dropped support for Node Sass, including no longer testing any of our source CSS against it.
   - Rearranged several Sass files in the process.
 - Removed `add()` and `subtract()` functions. Use `calc()` instead.
+- Removed `create-css-vars()` mixin (unused).
 - **CSS variable prefixing now handled by PostCSS.** The `$prefix` Sass variable has been removed. CSS custom properties are now written without a prefix in the Sass source and prefixed automatically via `postcss-prefix-custom-properties` during the build. To customize the prefix, update your PostCSS configuration instead of Sass.
 - **Removes all deprecated Sass variables and values:**
   - Removed `$nested-kbd-font-weight`, no replacement.