From 1421152a9356c7def86143dfb31a3586d5491d55 Mon Sep 17 00:00:00 2001
From: Wolfgang Müller
Date: Fri, 14 Feb 2025 11:57:03 +0100
Subject: frontend: Migrate to Tailwind 4.0

---
 frontend/package-lock.json                         | 1753 +++++++++-----------
 frontend/package.json                              |    9 +-
 frontend/postcss.config.cjs                        |    6 -
 frontend/src/app.css                               |  285 ++--
 frontend/src/lib/components/Badge.svelte           |    2 +-
 frontend/src/lib/components/Card.svelte            |    2 +-
 frontend/src/lib/components/Cardlet.svelte         |    2 +-
 frontend/src/lib/components/Dropdown.svelte        |    2 +-
 frontend/src/lib/components/Spinner.svelte         |   25 +-
 frontend/src/lib/containers/Cardlets.svelte        |    2 +-
 frontend/src/lib/containers/Cards.svelte           |    2 +-
 frontend/src/lib/filter/ComicFilterForm.svelte     |   16 +-
 frontend/src/lib/filter/components/Filter.svelte   |   27 +-
 .../src/lib/filter/components/FilterForm.svelte    |    4 +-
 frontend/src/lib/gallery/GalleryPage.svelte        |    2 +-
 frontend/src/lib/icons/Artist.svelte               |    1 +
 frontend/src/lib/icons/Character.svelte            |    1 +
 frontend/src/lib/icons/Circle.svelte               |    1 +
 frontend/src/lib/icons/World.svelte                |    1 +
 frontend/src/lib/pagination/Target.svelte          |    5 +-
 frontend/src/lib/pills/AssociationPill.svelte      |   34 +-
 frontend/src/lib/pills/Pill.svelte                 |    4 +-
 .../src/lib/reader/components/PageIndicator.svelte |    2 +-
 .../lib/scraper/components/SelectorButton.svelte   |    2 +-
 frontend/src/lib/selection/SelectionOverlay.svelte |    4 +-
 frontend/src/lib/statistics/StatGroup.svelte       |    2 +-
 frontend/src/lib/tabs/AddOverlay.svelte            |    2 +-
 frontend/src/lib/tabs/Tabs.svelte                  |   12 +-
 frontend/src/lib/toolbar/MarkSelection.svelte      |    2 +-
 frontend/tailwind.config.cjs                       |    5 +-
 frontend/vite.config.ts                            |    3 +-
 31 files changed, 984 insertions(+), 1236 deletions(-)
 delete mode 100644 frontend/postcss.config.cjs
 create mode 100644 frontend/src/lib/icons/Artist.svelte
 create mode 100644 frontend/src/lib/icons/Character.svelte
 create mode 100644 frontend/src/lib/icons/Circle.svelte
 create mode 100644 frontend/src/lib/icons/World.svelte

(limited to 'frontend')

diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index d40a916..1a613b6 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -23,14 +23,14 @@
 				"@graphql-codegen/typed-document-node": "^5.0.11",
 				"@graphql-codegen/typescript-operations": "^4.3.1",
 				"@iconify-json/material-symbols": "^1.2.6",
-				"@iconify/tailwind": "^1.1.3",
+				"@iconify/tailwind4": "^1.0.3",
 				"@sveltejs/adapter-static": "^3.0.6",
 				"@sveltejs/kit": "^2.8.1",
 				"@sveltejs/vite-plugin-svelte": "^5.0.0",
+				"@tailwindcss/vite": "^4.0.6",
 				"@typescript-eslint/eslint-plugin": "^8.14.0",
 				"@typescript-eslint/parser": "^8.14.0",
 				"@zerodevx/svelte-toast": "^0.9.6",
-				"autoprefixer": "^10.4.20",
 				"date-fns": "^4.1.0",
 				"eslint": "^9.14.0",
 				"eslint-config-prettier": "^10.0.0",
@@ -39,13 +39,12 @@
 				"globals": "^15.14.0",
 				"jsdom": "^26.0.0",
 				"npm-check-updates": "^17.1.11",
-				"postcss": "^8.4.49",
 				"prettier": "^3.3.3",
 				"prettier-plugin-svelte": "^3.2.8",
-				"prettier-plugin-tailwindcss": "^0.6.8",
+				"prettier-plugin-tailwindcss": "^0.6.11",
 				"svelte": "^5.5.0",
 				"svelte-check": "^4.0.0",
-				"tailwindcss": "^3.4.14",
+				"tailwindcss": "^4.0.0",
 				"tslib": "^2.8.1",
 				"typescript": "^5.6.3",
 				"vite": "^6.0.0",
@@ -66,19 +65,6 @@
 				}
 			}
 		},
-		"node_modules/@alloc/quick-lru": {
-			"version": "5.2.0",
-			"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
-			"integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">=10"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/sindresorhus"
-			}
-		},
 		"node_modules/@ampproject/remapping": {
 			"version": "2.3.0",
 			"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
@@ -92,6 +78,30 @@
 				"node": ">=6.0.0"
 			}
 		},
+		"node_modules/@antfu/install-pkg": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.0.0.tgz",
+			"integrity": "sha512-xvX6P/lo1B3ej0OsaErAjqgFYzYVcJpamjLAFLYh9vRJngBrMoUG7aVnrGTeqM7yxbyTD5p3F2+0/QUEh8Vzhw==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"package-manager-detector": "^0.2.8",
+				"tinyexec": "^0.3.2"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/antfu"
+			}
+		},
+		"node_modules/@antfu/utils": {
+			"version": "8.1.0",
+			"resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.0.tgz",
+			"integrity": "sha512-XPR7Jfwp0FFl/dFYPX8ZjpmU4/1mIXTjnZ1ba48BLMyKOV62/tiRjdsFcPs2hsYcSud4tzk7w3a3LjX8Fu3huA==",
+			"dev": true,
+			"license": "MIT",
+			"funding": {
+				"url": "https://github.com/sponsors/antfu"
+			}
+		},
 		"node_modules/@ardatan/relay-compiler": {
 			"version": "12.0.2",
 			"resolved": "https://registry.npmjs.org/@ardatan/relay-compiler/-/relay-compiler-12.0.2.tgz",
@@ -2048,17 +2058,21 @@
 				"@iconify/types": "*"
 			}
 		},
-		"node_modules/@iconify/tailwind": {
-			"version": "1.2.0",
-			"resolved": "https://registry.npmjs.org/@iconify/tailwind/-/tailwind-1.2.0.tgz",
-			"integrity": "sha512-KgpIHWOTcRYw1XcoUqyNSrmYyfLLqZYu3AmP8zdfLk0F5TqRO8YerhlvlQmGfn7rJXgPeZN569xPAJnJ53zZxA==",
+		"node_modules/@iconify/tailwind4": {
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/@iconify/tailwind4/-/tailwind4-1.0.3.tgz",
+			"integrity": "sha512-qhgEBFwbhoWWGo3X27KInvNQOjt7UwmZTuLpjYQlYMTkcXzwPnomqmxzsBUC2L0ySA105BFDppYBv4CuWBQKwA==",
 			"dev": true,
 			"license": "MIT",
 			"dependencies": {
-				"@iconify/types": "^2.0.0"
+				"@iconify/types": "^2.0.0",
+				"@iconify/utils": "^2.2.1"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/cyberalien"
+			},
+			"peerDependencies": {
+				"tailwindcss": ">= 4"
 			}
 		},
 		"node_modules/@iconify/types": {
@@ -2068,107 +2082,21 @@
 			"dev": true,
 			"license": "MIT"
 		},
-		"node_modules/@isaacs/cliui": {
-			"version": "8.0.2",
-			"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
-			"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
-			"dev": true,
-			"license": "ISC",
-			"dependencies": {
-				"string-width": "^5.1.2",
-				"string-width-cjs": "npm:string-width@^4.2.0",
-				"strip-ansi": "^7.0.1",
-				"strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
-				"wrap-ansi": "^8.1.0",
-				"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
-			},
-			"engines": {
-				"node": ">=12"
-			}
-		},
-		"node_modules/@isaacs/cliui/node_modules/ansi-regex": {
-			"version": "6.1.0",
-			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
-			"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">=12"
-			},
-			"funding": {
-				"url": "https://github.com/chalk/ansi-regex?sponsor=1"
-			}
-		},
-		"node_modules/@isaacs/cliui/node_modules/ansi-styles": {
-			"version": "6.2.1",
-			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
-			"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">=12"
-			},
-			"funding": {
-				"url": "https://github.com/chalk/ansi-styles?sponsor=1"
-			}
-		},
-		"node_modules/@isaacs/cliui/node_modules/emoji-regex": {
-			"version": "9.2.2",
-			"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
-			"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
-			"dev": true,
-			"license": "MIT"
-		},
-		"node_modules/@isaacs/cliui/node_modules/string-width": {
-			"version": "5.1.2",
-			"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
-			"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"eastasianwidth": "^0.2.0",
-				"emoji-regex": "^9.2.2",
-				"strip-ansi": "^7.0.1"
-			},
-			"engines": {
-				"node": ">=12"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/sindresorhus"
-			}
-		},
-		"node_modules/@isaacs/cliui/node_modules/strip-ansi": {
-			"version": "7.1.0",
-			"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
-			"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"ansi-regex": "^6.0.1"
-			},
-			"engines": {
-				"node": ">=12"
-			},
-			"funding": {
-				"url": "https://github.com/chalk/strip-ansi?sponsor=1"
-			}
-		},
-		"node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
-			"version": "8.1.0",
-			"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
-			"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+		"node_modules/@iconify/utils": {
+			"version": "2.3.0",
+			"resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.3.0.tgz",
+			"integrity": "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==",
 			"dev": true,
 			"license": "MIT",
 			"dependencies": {
-				"ansi-styles": "^6.1.0",
-				"string-width": "^5.0.1",
-				"strip-ansi": "^7.0.1"
-			},
-			"engines": {
-				"node": ">=12"
-			},
-			"funding": {
-				"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+				"@antfu/install-pkg": "^1.0.0",
+				"@antfu/utils": "^8.1.0",
+				"@iconify/types": "^2.0.0",
+				"debug": "^4.4.0",
+				"globals": "^15.14.0",
+				"kolorist": "^1.8.0",
+				"local-pkg": "^1.0.0",
+				"mlly": "^1.7.4"
 			}
 		},
 		"node_modules/@jridgewell/gen-mapping": {
@@ -2263,17 +2191,6 @@
 				"node": ">= 8"
 			}
 		},
-		"node_modules/@pkgjs/parseargs": {
-			"version": "0.11.0",
-			"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
-			"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
-			"dev": true,
-			"license": "MIT",
-			"optional": true,
-			"engines": {
-				"node": ">=14"
-			}
-		},
 		"node_modules/@polka/url": {
 			"version": "1.0.0-next.28",
 			"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz",
@@ -2635,158 +2552,406 @@
 				"vite": "^6.0.0"
 			}
 		},
-		"node_modules/@types/cookie": {
-			"version": "0.6.0",
-			"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
-			"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
-			"dev": true,
-			"license": "MIT"
-		},
-		"node_modules/@types/estree": {
-			"version": "1.0.6",
-			"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
-			"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
-			"license": "MIT"
-		},
-		"node_modules/@types/gensync": {
-			"version": "1.0.4",
-			"resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.4.tgz",
-			"integrity": "sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA==",
-			"dev": true,
-			"license": "MIT"
-		},
-		"node_modules/@types/js-yaml": {
-			"version": "4.0.9",
-			"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz",
-			"integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==",
-			"dev": true,
-			"license": "MIT"
-		},
-		"node_modules/@types/json-schema": {
-			"version": "7.0.15",
-			"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
-			"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
-			"dev": true,
-			"license": "MIT"
-		},
-		"node_modules/@types/node": {
-			"version": "22.13.2",
-			"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.2.tgz",
-			"integrity": "sha512-Z+r8y3XL9ZpI2EY52YYygAFmo2/oWfNSj4BCpAXE2McAexDk8VcnBMGC9Djn9gTKt4d2T/hhXqmPzo4hfIXtTg==",
+		"node_modules/@tailwindcss/node": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.0.6.tgz",
+			"integrity": "sha512-jb6E0WeSq7OQbVYcIJ6LxnZTeC4HjMvbzFBMCrQff4R50HBlo/obmYNk6V2GCUXDeqiXtvtrQgcIbT+/boB03Q==",
 			"dev": true,
 			"license": "MIT",
 			"dependencies": {
-				"undici-types": "~6.20.0"
+				"enhanced-resolve": "^5.18.0",
+				"jiti": "^2.4.2",
+				"tailwindcss": "4.0.6"
 			}
 		},
-		"node_modules/@types/ws": {
-			"version": "8.5.14",
-			"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz",
-			"integrity": "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==",
+		"node_modules/@tailwindcss/node/node_modules/jiti": {
+			"version": "2.4.2",
+			"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
+			"integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
 			"dev": true,
 			"license": "MIT",
-			"dependencies": {
-				"@types/node": "*"
+			"bin": {
+				"jiti": "lib/jiti-cli.mjs"
 			}
 		},
-		"node_modules/@typescript-eslint/eslint-plugin": {
-			"version": "8.24.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.24.0.tgz",
-			"integrity": "sha512-aFcXEJJCI4gUdXgoo/j9udUYIHgF23MFkg09LFz2dzEmU0+1Plk4rQWv/IYKvPHAtlkkGoB3m5e6oUp+JPsNaQ==",
+		"node_modules/@tailwindcss/oxide": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.0.6.tgz",
+			"integrity": "sha512-lVyKV2y58UE9CeKVcYykULe9QaE1dtKdxDEdrTPIdbzRgBk6bdxHNAoDqvcqXbIGXubn3VOl1O/CFF77v/EqSA==",
 			"dev": true,
 			"license": "MIT",
-			"dependencies": {
-				"@eslint-community/regexpp": "^4.10.0",
-				"@typescript-eslint/scope-manager": "8.24.0",
-				"@typescript-eslint/type-utils": "8.24.0",
-				"@typescript-eslint/utils": "8.24.0",
-				"@typescript-eslint/visitor-keys": "8.24.0",
-				"graphemer": "^1.4.0",
-				"ignore": "^5.3.1",
-				"natural-compare": "^1.4.0",
-				"ts-api-utils": "^2.0.1"
-			},
 			"engines": {
-				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-			},
-			"funding": {
-				"type": "opencollective",
-				"url": "https://opencollective.com/typescript-eslint"
+				"node": ">= 10"
 			},
-			"peerDependencies": {
-				"@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
-				"eslint": "^8.57.0 || ^9.0.0",
-				"typescript": ">=4.8.4 <5.8.0"
-			}
-		},
-		"node_modules/@typescript-eslint/parser": {
-			"version": "8.24.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.24.0.tgz",
-			"integrity": "sha512-MFDaO9CYiard9j9VepMNa9MTcqVvSny2N4hkY6roquzj8pdCBRENhErrteaQuu7Yjn1ppk0v1/ZF9CG3KIlrTA==",
+			"optionalDependencies": {
+				"@tailwindcss/oxide-android-arm64": "4.0.6",
+				"@tailwindcss/oxide-darwin-arm64": "4.0.6",
+				"@tailwindcss/oxide-darwin-x64": "4.0.6",
+				"@tailwindcss/oxide-freebsd-x64": "4.0.6",
+				"@tailwindcss/oxide-linux-arm-gnueabihf": "4.0.6",
+				"@tailwindcss/oxide-linux-arm64-gnu": "4.0.6",
+				"@tailwindcss/oxide-linux-arm64-musl": "4.0.6",
+				"@tailwindcss/oxide-linux-x64-gnu": "4.0.6",
+				"@tailwindcss/oxide-linux-x64-musl": "4.0.6",
+				"@tailwindcss/oxide-win32-arm64-msvc": "4.0.6",
+				"@tailwindcss/oxide-win32-x64-msvc": "4.0.6"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-android-arm64": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.0.6.tgz",
+			"integrity": "sha512-xDbym6bDPW3D2XqQqX3PjqW3CKGe1KXH7Fdkc60sX5ZLVUbzPkFeunQaoP+BuYlLc2cC1FoClrIRYnRzof9Sow==",
+			"cpu": [
+				"arm64"
+			],
 			"dev": true,
 			"license": "MIT",
-			"dependencies": {
-				"@typescript-eslint/scope-manager": "8.24.0",
-				"@typescript-eslint/types": "8.24.0",
-				"@typescript-eslint/typescript-estree": "8.24.0",
-				"@typescript-eslint/visitor-keys": "8.24.0",
-				"debug": "^4.3.4"
-			},
+			"optional": true,
+			"os": [
+				"android"
+			],
 			"engines": {
-				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-			},
-			"funding": {
-				"type": "opencollective",
-				"url": "https://opencollective.com/typescript-eslint"
-			},
-			"peerDependencies": {
-				"eslint": "^8.57.0 || ^9.0.0",
-				"typescript": ">=4.8.4 <5.8.0"
+				"node": ">= 10"
 			}
 		},
-		"node_modules/@typescript-eslint/scope-manager": {
-			"version": "8.24.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.24.0.tgz",
-			"integrity": "sha512-HZIX0UByphEtdVBKaQBgTDdn9z16l4aTUz8e8zPQnyxwHBtf5vtl1L+OhH+m1FGV9DrRmoDuYKqzVrvWDcDozw==",
+		"node_modules/@tailwindcss/oxide-darwin-arm64": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.0.6.tgz",
+			"integrity": "sha512-1f71/ju/tvyGl5c2bDkchZHy8p8EK/tDHCxlpYJ1hGNvsYihZNurxVpZ0DefpN7cNc9RTT8DjrRoV8xXZKKRjg==",
+			"cpu": [
+				"arm64"
+			],
 			"dev": true,
 			"license": "MIT",
-			"dependencies": {
-				"@typescript-eslint/types": "8.24.0",
-				"@typescript-eslint/visitor-keys": "8.24.0"
-			},
+			"optional": true,
+			"os": [
+				"darwin"
+			],
 			"engines": {
-				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-			},
-			"funding": {
-				"type": "opencollective",
-				"url": "https://opencollective.com/typescript-eslint"
+				"node": ">= 10"
 			}
 		},
-		"node_modules/@typescript-eslint/type-utils": {
-			"version": "8.24.0",
-			"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.24.0.tgz",
-			"integrity": "sha512-8fitJudrnY8aq0F1wMiPM1UUgiXQRJ5i8tFjq9kGfRajU+dbPyOuHbl0qRopLEidy0MwqgTHDt6CnSeXanNIwA==",
+		"node_modules/@tailwindcss/oxide-darwin-x64": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.0.6.tgz",
+			"integrity": "sha512-s/hg/ZPgxFIrGMb0kqyeaqZt505P891buUkSezmrDY6lxv2ixIELAlOcUVTkVh245SeaeEiUVUPiUN37cwoL2g==",
+			"cpu": [
+				"x64"
+			],
 			"dev": true,
 			"license": "MIT",
-			"dependencies": {
-				"@typescript-eslint/typescript-estree": "8.24.0",
-				"@typescript-eslint/utils": "8.24.0",
-				"debug": "^4.3.4",
-				"ts-api-utils": "^2.0.1"
-			},
+			"optional": true,
+			"os": [
+				"darwin"
+			],
 			"engines": {
-				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
-			},
-			"funding": {
-				"type": "opencollective",
-				"url": "https://opencollective.com/typescript-eslint"
-			},
-			"peerDependencies": {
-				"eslint": "^8.57.0 || ^9.0.0",
-				"typescript": ">=4.8.4 <5.8.0"
+				"node": ">= 10"
 			}
 		},
-		"node_modules/@typescript-eslint/types": {
+		"node_modules/@tailwindcss/oxide-freebsd-x64": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.0.6.tgz",
+			"integrity": "sha512-Z3Wo8FWZnmio8+xlcbb7JUo/hqRMSmhQw8IGIRoRJ7GmLR0C+25Wq+bEX/135xe/yEle2lFkhu9JBHd4wZYiig==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"freebsd"
+			],
+			"engines": {
+				"node": ">= 10"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.0.6.tgz",
+			"integrity": "sha512-SNSwkkim1myAgmnbHs4EjXsPL7rQbVGtjcok5EaIzkHkCAVK9QBQsWeP2Jm2/JJhq4wdx8tZB9Y7psMzHYWCkA==",
+			"cpu": [
+				"arm"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 10"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.0.6.tgz",
+			"integrity": "sha512-tJ+mevtSDMQhKlwCCuhsFEFg058kBiSy4TkoeBG921EfrHKmexOaCyFKYhVXy4JtkaeeOcjJnCLasEeqml4i+Q==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 10"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-linux-arm64-musl": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.0.6.tgz",
+			"integrity": "sha512-IoArz1vfuTR4rALXMUXI/GWWfx2EaO4gFNtBNkDNOYhlTD4NVEwE45nbBoojYiTulajI4c2XH8UmVEVJTOJKxA==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 10"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-linux-x64-gnu": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.0.6.tgz",
+			"integrity": "sha512-QtsUfLkEAeWAC3Owx9Kg+7JdzE+k9drPhwTAXbXugYB9RZUnEWWx5x3q/au6TvUYcL+n0RBqDEO2gucZRvRFgQ==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 10"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-linux-x64-musl": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.0.6.tgz",
+			"integrity": "sha512-QthvJqIji2KlGNwLcK/PPYo7w1Wsi/8NK0wAtRGbv4eOPdZHkQ9KUk+oCoP20oPO7i2a6X1aBAFQEL7i08nNMA==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 10"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.0.6.tgz",
+			"integrity": "sha512-+oka+dYX8jy9iP00DJ9Y100XsqvbqR5s0yfMZJuPR1H/lDVtDfsZiSix1UFBQ3X1HWxoEEl6iXNJHWd56TocVw==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"win32"
+			],
+			"engines": {
+				"node": ">= 10"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-win32-x64-msvc": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.0.6.tgz",
+			"integrity": "sha512-+o+juAkik4p8Ue/0LiflQXPmVatl6Av3LEZXpBTfg4qkMIbZdhCGWFzHdt2NjoMiLOJCFDddoV6GYaimvK1Olw==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"win32"
+			],
+			"engines": {
+				"node": ">= 10"
+			}
+		},
+		"node_modules/@tailwindcss/vite": {
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.0.6.tgz",
+			"integrity": "sha512-O25vZ/URWbZ2JHdk2o8wH7jOKqEGCsYmX3GwGmYS5DjE4X3mpf93a72Rn7VRnefldNauBzr5z2hfZptmBNtTUQ==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@tailwindcss/node": "^4.0.6",
+				"@tailwindcss/oxide": "^4.0.6",
+				"lightningcss": "^1.29.1",
+				"tailwindcss": "4.0.6"
+			},
+			"peerDependencies": {
+				"vite": "^5.2.0 || ^6"
+			}
+		},
+		"node_modules/@types/cookie": {
+			"version": "0.6.0",
+			"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
+			"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/@types/estree": {
+			"version": "1.0.6",
+			"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+			"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+			"license": "MIT"
+		},
+		"node_modules/@types/gensync": {
+			"version": "1.0.4",
+			"resolved": "https://registry.npmjs.org/@types/gensync/-/gensync-1.0.4.tgz",
+			"integrity": "sha512-C3YYeRQWp2fmq9OryX+FoDy8nXS6scQ7dPptD8LnFDAUNcKWJjXQKDNJD3HVm+kOUsXhTOkpi69vI4EuAr95bA==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/@types/js-yaml": {
+			"version": "4.0.9",
+			"resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz",
+			"integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/@types/json-schema": {
+			"version": "7.0.15",
+			"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+			"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/@types/node": {
+			"version": "22.13.2",
+			"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.2.tgz",
+			"integrity": "sha512-Z+r8y3XL9ZpI2EY52YYygAFmo2/oWfNSj4BCpAXE2McAexDk8VcnBMGC9Djn9gTKt4d2T/hhXqmPzo4hfIXtTg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"undici-types": "~6.20.0"
+			}
+		},
+		"node_modules/@types/ws": {
+			"version": "8.5.14",
+			"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz",
+			"integrity": "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@types/node": "*"
+			}
+		},
+		"node_modules/@typescript-eslint/eslint-plugin": {
+			"version": "8.24.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.24.0.tgz",
+			"integrity": "sha512-aFcXEJJCI4gUdXgoo/j9udUYIHgF23MFkg09LFz2dzEmU0+1Plk4rQWv/IYKvPHAtlkkGoB3m5e6oUp+JPsNaQ==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@eslint-community/regexpp": "^4.10.0",
+				"@typescript-eslint/scope-manager": "8.24.0",
+				"@typescript-eslint/type-utils": "8.24.0",
+				"@typescript-eslint/utils": "8.24.0",
+				"@typescript-eslint/visitor-keys": "8.24.0",
+				"graphemer": "^1.4.0",
+				"ignore": "^5.3.1",
+				"natural-compare": "^1.4.0",
+				"ts-api-utils": "^2.0.1"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
+				"eslint": "^8.57.0 || ^9.0.0",
+				"typescript": ">=4.8.4 <5.8.0"
+			}
+		},
+		"node_modules/@typescript-eslint/parser": {
+			"version": "8.24.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.24.0.tgz",
+			"integrity": "sha512-MFDaO9CYiard9j9VepMNa9MTcqVvSny2N4hkY6roquzj8pdCBRENhErrteaQuu7Yjn1ppk0v1/ZF9CG3KIlrTA==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@typescript-eslint/scope-manager": "8.24.0",
+				"@typescript-eslint/types": "8.24.0",
+				"@typescript-eslint/typescript-estree": "8.24.0",
+				"@typescript-eslint/visitor-keys": "8.24.0",
+				"debug": "^4.3.4"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"eslint": "^8.57.0 || ^9.0.0",
+				"typescript": ">=4.8.4 <5.8.0"
+			}
+		},
+		"node_modules/@typescript-eslint/scope-manager": {
+			"version": "8.24.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.24.0.tgz",
+			"integrity": "sha512-HZIX0UByphEtdVBKaQBgTDdn9z16l4aTUz8e8zPQnyxwHBtf5vtl1L+OhH+m1FGV9DrRmoDuYKqzVrvWDcDozw==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@typescript-eslint/types": "8.24.0",
+				"@typescript-eslint/visitor-keys": "8.24.0"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@typescript-eslint/type-utils": {
+			"version": "8.24.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.24.0.tgz",
+			"integrity": "sha512-8fitJudrnY8aq0F1wMiPM1UUgiXQRJ5i8tFjq9kGfRajU+dbPyOuHbl0qRopLEidy0MwqgTHDt6CnSeXanNIwA==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@typescript-eslint/typescript-estree": "8.24.0",
+				"@typescript-eslint/utils": "8.24.0",
+				"debug": "^4.3.4",
+				"ts-api-utils": "^2.0.1"
+			},
+			"engines": {
+				"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"eslint": "^8.57.0 || ^9.0.0",
+				"typescript": ">=4.8.4 <5.8.0"
+			}
+		},
+		"node_modules/@typescript-eslint/types": {
 			"version": "8.24.0",
 			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.24.0.tgz",
 			"integrity": "sha512-VacJCBTyje7HGAw7xp11q439A+zeGG0p0/p2zsZwpnMzjPB5WteaWqt4g2iysgGFafrqvyLWqq6ZPZAOCoefCw==",
@@ -3224,34 +3389,6 @@
 				"url": "https://github.com/chalk/ansi-styles?sponsor=1"
 			}
 		},
-		"node_modules/any-promise": {
-			"version": "1.3.0",
-			"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
-			"integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
-			"dev": true,
-			"license": "MIT"
-		},
-		"node_modules/anymatch": {
-			"version": "3.1.3",
-			"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
-			"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
-			"dev": true,
-			"license": "ISC",
-			"dependencies": {
-				"normalize-path": "^3.0.0",
-				"picomatch": "^2.0.4"
-			},
-			"engines": {
-				"node": ">= 8"
-			}
-		},
-		"node_modules/arg": {
-			"version": "5.0.2",
-			"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
-			"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
-			"dev": true,
-			"license": "MIT"
-		},
 		"node_modules/argparse": {
 			"version": "2.0.1",
 			"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -3325,44 +3462,6 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
-		"node_modules/autoprefixer": {
-			"version": "10.4.20",
-			"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
-			"integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
-			"dev": true,
-			"funding": [
-				{
-					"type": "opencollective",
-					"url": "https://opencollective.com/postcss/"
-				},
-				{
-					"type": "tidelift",
-					"url": "https://tidelift.com/funding/github/npm/autoprefixer"
-				},
-				{
-					"type": "github",
-					"url": "https://github.com/sponsors/ai"
-				}
-			],
-			"license": "MIT",
-			"dependencies": {
-				"browserslist": "^4.23.3",
-				"caniuse-lite": "^1.0.30001646",
-				"fraction.js": "^4.3.7",
-				"normalize-range": "^0.1.2",
-				"picocolors": "^1.0.1",
-				"postcss-value-parser": "^4.2.0"
-			},
-			"bin": {
-				"autoprefixer": "bin/autoprefixer"
-			},
-			"engines": {
-				"node": "^10 || ^12 || >=14"
-			},
-			"peerDependencies": {
-				"postcss": "^8.1.0"
-			}
-		},
 		"node_modules/axobject-query": {
 			"version": "4.1.0",
 			"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
@@ -3400,19 +3499,6 @@
 			],
 			"license": "MIT"
 		},
-		"node_modules/binary-extensions": {
-			"version": "2.3.0",
-			"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
-			"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">=8"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/sindresorhus"
-			}
-		},
 		"node_modules/bl": {
 			"version": "4.1.0",
 			"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
@@ -3560,16 +3646,6 @@
 				"tslib": "^2.0.3"
 			}
 		},
-		"node_modules/camelcase-css": {
-			"version": "2.0.1",
-			"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
-			"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">= 6"
-			}
-		},
 		"node_modules/caniuse-lite": {
 			"version": "1.0.30001699",
 			"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz",
@@ -3865,16 +3941,6 @@
 				"node": ">= 0.8"
 			}
 		},
-		"node_modules/commander": {
-			"version": "4.1.1",
-			"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
-			"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">= 6"
-			}
-		},
 		"node_modules/common-tags": {
 			"version": "1.8.2",
 			"resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
@@ -3892,6 +3958,13 @@
 			"dev": true,
 			"license": "MIT"
 		},
+		"node_modules/confbox": {
+			"version": "0.1.8",
+			"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
+			"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
+			"dev": true,
+			"license": "MIT"
+		},
 		"node_modules/constant-case": {
 			"version": "3.0.4",
 			"resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz",
@@ -4157,6 +4230,19 @@
 				"node": ">=8"
 			}
 		},
+		"node_modules/detect-libc": {
+			"version": "1.0.3",
+			"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+			"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
+			"dev": true,
+			"license": "Apache-2.0",
+			"bin": {
+				"detect-libc": "bin/detect-libc.js"
+			},
+			"engines": {
+				"node": ">=0.10"
+			}
+		},
 		"node_modules/devalue": {
 			"version": "5.1.1",
 			"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz",
@@ -4164,13 +4250,6 @@
 			"dev": true,
 			"license": "MIT"
 		},
-		"node_modules/didyoumean": {
-			"version": "1.2.2",
-			"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
-			"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
-			"dev": true,
-			"license": "Apache-2.0"
-		},
 		"node_modules/dir-glob": {
 			"version": "3.0.1",
 			"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -4184,13 +4263,6 @@
 				"node": ">=8"
 			}
 		},
-		"node_modules/dlv": {
-			"version": "1.1.3",
-			"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
-			"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
-			"dev": true,
-			"license": "MIT"
-		},
 		"node_modules/dot-case": {
 			"version": "3.0.4",
 			"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
@@ -4225,13 +4297,6 @@
 				"node": ">=4"
 			}
 		},
-		"node_modules/eastasianwidth": {
-			"version": "0.2.0",
-			"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
-			"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
-			"dev": true,
-			"license": "MIT"
-		},
 		"node_modules/electron-to-chromium": {
 			"version": "1.5.98",
 			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.98.tgz",
@@ -4246,6 +4311,20 @@
 			"dev": true,
 			"license": "MIT"
 		},
+		"node_modules/enhanced-resolve": {
+			"version": "5.18.1",
+			"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
+			"integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"graceful-fs": "^4.2.4",
+				"tapable": "^2.2.0"
+			},
+			"engines": {
+				"node": ">=10.13.0"
+			}
+		},
 		"node_modules/entities": {
 			"version": "4.5.0",
 			"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@@ -4890,36 +4969,6 @@
 			"dev": true,
 			"license": "ISC"
 		},
-		"node_modules/foreground-child": {
-			"version": "3.3.0",
-			"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
-			"integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
-			"dev": true,
-			"license": "ISC",
-			"dependencies": {
-				"cross-spawn": "^7.0.0",
-				"signal-exit": "^4.0.1"
-			},
-			"engines": {
-				"node": ">=14"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/isaacs"
-			}
-		},
-		"node_modules/foreground-child/node_modules/signal-exit": {
-			"version": "4.1.0",
-			"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
-			"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
-			"dev": true,
-			"license": "ISC",
-			"engines": {
-				"node": ">=14"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/isaacs"
-			}
-		},
 		"node_modules/form-data": {
 			"version": "4.0.1",
 			"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
@@ -4948,20 +4997,6 @@
 				"node": ">=12.20.0"
 			}
 		},
-		"node_modules/fraction.js": {
-			"version": "4.3.7",
-			"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
-			"integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": "*"
-			},
-			"funding": {
-				"type": "patreon",
-				"url": "https://github.com/sponsors/rawify"
-			}
-		},
 		"node_modules/fsevents": {
 			"version": "2.3.3",
 			"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -4977,16 +5012,6 @@
 				"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
 			}
 		},
-		"node_modules/function-bind": {
-			"version": "1.1.2",
-			"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
-			"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
-			"dev": true,
-			"license": "MIT",
-			"funding": {
-				"url": "https://github.com/sponsors/ljharb"
-			}
-		},
 		"node_modules/gensync": {
 			"version": "1.0.0-beta.2",
 			"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -5007,27 +5032,6 @@
 				"node": "6.* || 8.* || >= 10.*"
 			}
 		},
-		"node_modules/glob": {
-			"version": "10.4.5",
-			"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
-			"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
-			"dev": true,
-			"license": "ISC",
-			"dependencies": {
-				"foreground-child": "^3.1.0",
-				"jackspeak": "^3.1.2",
-				"minimatch": "^9.0.4",
-				"minipass": "^7.1.2",
-				"package-json-from-dist": "^1.0.0",
-				"path-scurry": "^1.11.1"
-			},
-			"bin": {
-				"glob": "dist/esm/bin.mjs"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/isaacs"
-			}
-		},
 		"node_modules/glob-parent": {
 			"version": "6.0.2",
 			"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -5035,36 +5039,10 @@
 			"dev": true,
 			"license": "ISC",
 			"dependencies": {
-				"is-glob": "^4.0.3"
-			},
-			"engines": {
-				"node": ">=10.13.0"
-			}
-		},
-		"node_modules/glob/node_modules/brace-expansion": {
-			"version": "2.0.1",
-			"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
-			"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"balanced-match": "^1.0.0"
-			}
-		},
-		"node_modules/glob/node_modules/minimatch": {
-			"version": "9.0.5",
-			"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
-			"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
-			"dev": true,
-			"license": "ISC",
-			"dependencies": {
-				"brace-expansion": "^2.0.1"
+				"is-glob": "^4.0.3"
 			},
 			"engines": {
-				"node": ">=16 || 14 >=14.17"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/isaacs"
+				"node": ">=10.13.0"
 			}
 		},
 		"node_modules/globals": {
@@ -5101,6 +5079,13 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
+		"node_modules/graceful-fs": {
+			"version": "4.2.11",
+			"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+			"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+			"dev": true,
+			"license": "ISC"
+		},
 		"node_modules/graphemer": {
 			"version": "1.4.0",
 			"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
@@ -5252,19 +5237,6 @@
 				"node": ">=8"
 			}
 		},
-		"node_modules/hasown": {
-			"version": "2.0.2",
-			"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
-			"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"function-bind": "^1.1.2"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			}
-		},
 		"node_modules/header-case": {
 			"version": "2.0.4",
 			"resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz",
@@ -5507,35 +5479,6 @@
 			"dev": true,
 			"license": "MIT"
 		},
-		"node_modules/is-binary-path": {
-			"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,
-			"license": "MIT",
-			"dependencies": {
-				"binary-extensions": "^2.0.0"
-			},
-			"engines": {
-				"node": ">=8"
-			}
-		},
-		"node_modules/is-core-module": {
-			"version": "2.16.1",
-			"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
-			"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"hasown": "^2.0.2"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/ljharb"
-			}
-		},
 		"node_modules/is-extglob": {
 			"version": "2.1.1",
 			"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -5691,22 +5634,6 @@
 				"ws": "*"
 			}
 		},
-		"node_modules/jackspeak": {
-			"version": "3.4.3",
-			"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
-			"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
-			"dev": true,
-			"license": "BlueOak-1.0.0",
-			"dependencies": {
-				"@isaacs/cliui": "^8.0.2"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/isaacs"
-			},
-			"optionalDependencies": {
-				"@pkgjs/parseargs": "^0.11.0"
-			}
-		},
 		"node_modules/jiti": {
 			"version": "1.21.7",
 			"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
@@ -5883,6 +5810,13 @@
 			"dev": true,
 			"license": "MIT"
 		},
+		"node_modules/kolorist": {
+			"version": "1.8.0",
+			"resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz",
+			"integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==",
+			"dev": true,
+			"license": "MIT"
+		},
 		"node_modules/levn": {
 			"version": "0.4.1",
 			"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -5897,6 +5831,245 @@
 				"node": ">= 0.8.0"
 			}
 		},
+		"node_modules/lightningcss": {
+			"version": "1.29.1",
+			"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.1.tgz",
+			"integrity": "sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==",
+			"dev": true,
+			"license": "MPL-2.0",
+			"dependencies": {
+				"detect-libc": "^1.0.3"
+			},
+			"engines": {
+				"node": ">= 12.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/parcel"
+			},
+			"optionalDependencies": {
+				"lightningcss-darwin-arm64": "1.29.1",
+				"lightningcss-darwin-x64": "1.29.1",
+				"lightningcss-freebsd-x64": "1.29.1",
+				"lightningcss-linux-arm-gnueabihf": "1.29.1",
+				"lightningcss-linux-arm64-gnu": "1.29.1",
+				"lightningcss-linux-arm64-musl": "1.29.1",
+				"lightningcss-linux-x64-gnu": "1.29.1",
+				"lightningcss-linux-x64-musl": "1.29.1",
+				"lightningcss-win32-arm64-msvc": "1.29.1",
+				"lightningcss-win32-x64-msvc": "1.29.1"
+			}
+		},
+		"node_modules/lightningcss-darwin-arm64": {
+			"version": "1.29.1",
+			"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.1.tgz",
+			"integrity": "sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MPL-2.0",
+			"optional": true,
+			"os": [
+				"darwin"
+			],
+			"engines": {
+				"node": ">= 12.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/parcel"
+			}
+		},
+		"node_modules/lightningcss-darwin-x64": {
+			"version": "1.29.1",
+			"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.1.tgz",
+			"integrity": "sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MPL-2.0",
+			"optional": true,
+			"os": [
+				"darwin"
+			],
+			"engines": {
+				"node": ">= 12.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/parcel"
+			}
+		},
+		"node_modules/lightningcss-freebsd-x64": {
+			"version": "1.29.1",
+			"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.1.tgz",
+			"integrity": "sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MPL-2.0",
+			"optional": true,
+			"os": [
+				"freebsd"
+			],
+			"engines": {
+				"node": ">= 12.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/parcel"
+			}
+		},
+		"node_modules/lightningcss-linux-arm-gnueabihf": {
+			"version": "1.29.1",
+			"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.1.tgz",
+			"integrity": "sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==",
+			"cpu": [
+				"arm"
+			],
+			"dev": true,
+			"license": "MPL-2.0",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 12.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/parcel"
+			}
+		},
+		"node_modules/lightningcss-linux-arm64-gnu": {
+			"version": "1.29.1",
+			"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.1.tgz",
+			"integrity": "sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MPL-2.0",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 12.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/parcel"
+			}
+		},
+		"node_modules/lightningcss-linux-arm64-musl": {
+			"version": "1.29.1",
+			"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.1.tgz",
+			"integrity": "sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MPL-2.0",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 12.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/parcel"
+			}
+		},
+		"node_modules/lightningcss-linux-x64-gnu": {
+			"version": "1.29.1",
+			"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.1.tgz",
+			"integrity": "sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MPL-2.0",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 12.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/parcel"
+			}
+		},
+		"node_modules/lightningcss-linux-x64-musl": {
+			"version": "1.29.1",
+			"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.1.tgz",
+			"integrity": "sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MPL-2.0",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 12.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/parcel"
+			}
+		},
+		"node_modules/lightningcss-win32-arm64-msvc": {
+			"version": "1.29.1",
+			"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.1.tgz",
+			"integrity": "sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MPL-2.0",
+			"optional": true,
+			"os": [
+				"win32"
+			],
+			"engines": {
+				"node": ">= 12.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/parcel"
+			}
+		},
+		"node_modules/lightningcss-win32-x64-msvc": {
+			"version": "1.29.1",
+			"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.1.tgz",
+			"integrity": "sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MPL-2.0",
+			"optional": true,
+			"os": [
+				"win32"
+			],
+			"engines": {
+				"node": ">= 12.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/parcel"
+			}
+		},
 		"node_modules/lilconfig": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
@@ -5960,6 +6133,23 @@
 				"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
 			}
 		},
+		"node_modules/local-pkg": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.0.0.tgz",
+			"integrity": "sha512-bbgPw/wmroJsil/GgL4qjDzs5YLTBMQ99weRsok1XCDccQeehbHA/I1oRvk2NPtr7KGZgT/Y5tPRnAtMqeG2Kg==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"mlly": "^1.7.3",
+				"pkg-types": "^1.3.0"
+			},
+			"engines": {
+				"node": ">=14"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/antfu"
+			}
+		},
 		"node_modules/locate-character": {
 			"version": "3.0.0",
 			"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
@@ -6214,14 +6404,17 @@
 				"node": "*"
 			}
 		},
-		"node_modules/minipass": {
-			"version": "7.1.2",
-			"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
-			"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+		"node_modules/mlly": {
+			"version": "1.7.4",
+			"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz",
+			"integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==",
 			"dev": true,
-			"license": "ISC",
-			"engines": {
-				"node": ">=16 || 14 >=14.17"
+			"license": "MIT",
+			"dependencies": {
+				"acorn": "^8.14.0",
+				"pathe": "^2.0.1",
+				"pkg-types": "^1.3.0",
+				"ufo": "^1.5.4"
 			}
 		},
 		"node_modules/mri": {
@@ -6258,18 +6451,6 @@
 			"dev": true,
 			"license": "ISC"
 		},
-		"node_modules/mz": {
-			"version": "2.7.0",
-			"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
-			"integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"any-promise": "^1.0.0",
-				"object-assign": "^4.0.1",
-				"thenify-all": "^1.0.0"
-			}
-		},
 		"node_modules/nanoid": {
 			"version": "3.3.8",
 			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
@@ -6387,26 +6568,6 @@
 			"dev": true,
 			"license": "MIT"
 		},
-		"node_modules/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,
-			"license": "MIT",
-			"engines": {
-				"node": ">=0.10.0"
-			}
-		},
-		"node_modules/normalize-range": {
-			"version": "0.1.2",
-			"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
-			"integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">=0.10.0"
-			}
-		},
 		"node_modules/npm-check-updates": {
 			"version": "17.1.14",
 			"resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-17.1.14.tgz",
@@ -6446,16 +6607,6 @@
 				"node": ">=0.10.0"
 			}
 		},
-		"node_modules/object-hash": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
-			"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">= 6"
-			}
-		},
 		"node_modules/onetime": {
 			"version": "5.1.2",
 			"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
@@ -6572,12 +6723,12 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
-		"node_modules/package-json-from-dist": {
-			"version": "1.0.1",
-			"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
-			"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+		"node_modules/package-manager-detector": {
+			"version": "0.2.9",
+			"resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.9.tgz",
+			"integrity": "sha512-+vYvA/Y31l8Zk8dwxHhL3JfTuHPm6tlxM2A3GeQyl7ovYnSp1+mzAxClxaOr0qO1TtPxbQxetI7v5XqKLJZk7Q==",
 			"dev": true,
-			"license": "BlueOak-1.0.0"
+			"license": "MIT"
 		},
 		"node_modules/param-case": {
 			"version": "3.0.4",
@@ -6692,13 +6843,6 @@
 				"node": ">=8"
 			}
 		},
-		"node_modules/path-parse": {
-			"version": "1.0.7",
-			"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
-			"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
-			"dev": true,
-			"license": "MIT"
-		},
 		"node_modules/path-root": {
 			"version": "0.1.1",
 			"resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
@@ -6719,33 +6863,9 @@
 			"dev": true,
 			"license": "MIT",
 			"engines": {
-				"node": ">=0.10.0"
-			}
-		},
-		"node_modules/path-scurry": {
-			"version": "1.11.1",
-			"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
-			"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
-			"dev": true,
-			"license": "BlueOak-1.0.0",
-			"dependencies": {
-				"lru-cache": "^10.2.0",
-				"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
-			},
-			"engines": {
-				"node": ">=16 || 14 >=14.18"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/isaacs"
+				"node": ">=0.10.0"
 			}
 		},
-		"node_modules/path-scurry/node_modules/lru-cache": {
-			"version": "10.4.3",
-			"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
-			"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
-			"dev": true,
-			"license": "ISC"
-		},
 		"node_modules/path-type": {
 			"version": "4.0.0",
 			"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
@@ -6793,24 +6913,16 @@
 				"url": "https://github.com/sponsors/jonschlinkert"
 			}
 		},
-		"node_modules/pify": {
-			"version": "2.3.0",
-			"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-			"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">=0.10.0"
-			}
-		},
-		"node_modules/pirates": {
-			"version": "4.0.6",
-			"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
-			"integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
+		"node_modules/pkg-types": {
+			"version": "1.3.1",
+			"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
+			"integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
 			"dev": true,
 			"license": "MIT",
-			"engines": {
-				"node": ">= 6"
+			"dependencies": {
+				"confbox": "^0.1.8",
+				"mlly": "^1.7.4",
+				"pathe": "^2.0.1"
 			}
 		},
 		"node_modules/postcss": {
@@ -6842,44 +6954,6 @@
 				"node": "^10 || ^12 || >=14"
 			}
 		},
-		"node_modules/postcss-import": {
-			"version": "15.1.0",
-			"resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
-			"integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"postcss-value-parser": "^4.0.0",
-				"read-cache": "^1.0.0",
-				"resolve": "^1.1.7"
-			},
-			"engines": {
-				"node": ">=14.0.0"
-			},
-			"peerDependencies": {
-				"postcss": "^8.0.0"
-			}
-		},
-		"node_modules/postcss-js": {
-			"version": "4.0.1",
-			"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
-			"integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"camelcase-css": "^2.0.1"
-			},
-			"engines": {
-				"node": "^12 || ^14 || >= 16"
-			},
-			"funding": {
-				"type": "opencollective",
-				"url": "https://opencollective.com/postcss/"
-			},
-			"peerDependencies": {
-				"postcss": "^8.4.21"
-			}
-		},
 		"node_modules/postcss-load-config": {
 			"version": "3.1.4",
 			"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz",
@@ -6920,32 +6994,6 @@
 				"node": ">= 6"
 			}
 		},
-		"node_modules/postcss-nested": {
-			"version": "6.2.0",
-			"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
-			"integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
-			"dev": true,
-			"funding": [
-				{
-					"type": "opencollective",
-					"url": "https://opencollective.com/postcss/"
-				},
-				{
-					"type": "github",
-					"url": "https://github.com/sponsors/ai"
-				}
-			],
-			"license": "MIT",
-			"dependencies": {
-				"postcss-selector-parser": "^6.1.1"
-			},
-			"engines": {
-				"node": ">=12.0"
-			},
-			"peerDependencies": {
-				"postcss": "^8.2.14"
-			}
-		},
 		"node_modules/postcss-safe-parser": {
 			"version": "6.0.0",
 			"resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
@@ -7004,13 +7052,6 @@
 				"node": ">=4"
 			}
 		},
-		"node_modules/postcss-value-parser": {
-			"version": "4.2.0",
-			"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
-			"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
-			"dev": true,
-			"license": "MIT"
-		},
 		"node_modules/prelude-ls": {
 			"version": "1.2.1",
 			"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -7168,16 +7209,6 @@
 			],
 			"license": "MIT"
 		},
-		"node_modules/read-cache": {
-			"version": "1.0.0",
-			"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
-			"integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"pify": "^2.3.0"
-			}
-		},
 		"node_modules/readable-stream": {
 			"version": "3.6.2",
 			"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -7260,27 +7291,6 @@
 				"node": ">=0.10.0"
 			}
 		},
-		"node_modules/resolve": {
-			"version": "1.22.10",
-			"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
-			"integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"is-core-module": "^2.16.0",
-				"path-parse": "^1.0.7",
-				"supports-preserve-symlinks-flag": "^1.0.0"
-			},
-			"bin": {
-				"resolve": "bin/resolve"
-			},
-			"engines": {
-				"node": ">= 0.4"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/ljharb"
-			}
-		},
 		"node_modules/resolve-from": {
 			"version": "5.0.0",
 			"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
@@ -7693,22 +7703,6 @@
 				"node": ">=8"
 			}
 		},
-		"node_modules/string-width-cjs": {
-			"name": "string-width",
-			"version": "4.2.3",
-			"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-			"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"emoji-regex": "^8.0.0",
-				"is-fullwidth-code-point": "^3.0.0",
-				"strip-ansi": "^6.0.1"
-			},
-			"engines": {
-				"node": ">=8"
-			}
-		},
 		"node_modules/strip-ansi": {
 			"version": "6.0.1",
 			"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -7722,20 +7716,6 @@
 				"node": ">=8"
 			}
 		},
-		"node_modules/strip-ansi-cjs": {
-			"name": "strip-ansi",
-			"version": "6.0.1",
-			"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-			"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"ansi-regex": "^5.0.1"
-			},
-			"engines": {
-				"node": ">=8"
-			}
-		},
 		"node_modules/strip-json-comments": {
 			"version": "3.1.1",
 			"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -7749,29 +7729,6 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
-		"node_modules/sucrase": {
-			"version": "3.35.0",
-			"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
-			"integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"@jridgewell/gen-mapping": "^0.3.2",
-				"commander": "^4.0.0",
-				"glob": "^10.3.10",
-				"lines-and-columns": "^1.1.6",
-				"mz": "^2.7.0",
-				"pirates": "^4.0.1",
-				"ts-interface-checker": "^0.1.9"
-			},
-			"bin": {
-				"sucrase": "bin/sucrase",
-				"sucrase-node": "bin/sucrase-node"
-			},
-			"engines": {
-				"node": ">=16 || 14 >=14.17"
-			}
-		},
 		"node_modules/supports-color": {
 			"version": "7.2.0",
 			"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -7785,19 +7742,6 @@
 				"node": ">=8"
 			}
 		},
-		"node_modules/supports-preserve-symlinks-flag": {
-			"version": "1.0.0",
-			"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
-			"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">= 0.4"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/ljharb"
-			}
-		},
 		"node_modules/svelecte": {
 			"version": "5.1.4",
 			"resolved": "https://registry.npmjs.org/svelecte/-/svelecte-5.1.4.tgz",
@@ -8010,164 +7954,20 @@
 			}
 		},
 		"node_modules/tailwindcss": {
-			"version": "3.4.17",
-			"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
-			"integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"@alloc/quick-lru": "^5.2.0",
-				"arg": "^5.0.2",
-				"chokidar": "^3.6.0",
-				"didyoumean": "^1.2.2",
-				"dlv": "^1.1.3",
-				"fast-glob": "^3.3.2",
-				"glob-parent": "^6.0.2",
-				"is-glob": "^4.0.3",
-				"jiti": "^1.21.6",
-				"lilconfig": "^3.1.3",
-				"micromatch": "^4.0.8",
-				"normalize-path": "^3.0.0",
-				"object-hash": "^3.0.0",
-				"picocolors": "^1.1.1",
-				"postcss": "^8.4.47",
-				"postcss-import": "^15.1.0",
-				"postcss-js": "^4.0.1",
-				"postcss-load-config": "^4.0.2",
-				"postcss-nested": "^6.2.0",
-				"postcss-selector-parser": "^6.1.2",
-				"resolve": "^1.22.8",
-				"sucrase": "^3.35.0"
-			},
-			"bin": {
-				"tailwind": "lib/cli.js",
-				"tailwindcss": "lib/cli.js"
-			},
-			"engines": {
-				"node": ">=14.0.0"
-			}
-		},
-		"node_modules/tailwindcss/node_modules/chokidar": {
-			"version": "3.6.0",
-			"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
-			"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"anymatch": "~3.1.2",
-				"braces": "~3.0.2",
-				"glob-parent": "~5.1.2",
-				"is-binary-path": "~2.1.0",
-				"is-glob": "~4.0.1",
-				"normalize-path": "~3.0.0",
-				"readdirp": "~3.6.0"
-			},
-			"engines": {
-				"node": ">= 8.10.0"
-			},
-			"funding": {
-				"url": "https://paulmillr.com/funding/"
-			},
-			"optionalDependencies": {
-				"fsevents": "~2.3.2"
-			}
-		},
-		"node_modules/tailwindcss/node_modules/chokidar/node_modules/glob-parent": {
-			"version": "5.1.2",
-			"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-			"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-			"dev": true,
-			"license": "ISC",
-			"dependencies": {
-				"is-glob": "^4.0.1"
-			},
-			"engines": {
-				"node": ">= 6"
-			}
-		},
-		"node_modules/tailwindcss/node_modules/lilconfig": {
-			"version": "3.1.3",
-			"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
-			"integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
-			"dev": true,
-			"license": "MIT",
-			"engines": {
-				"node": ">=14"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/antonk52"
-			}
-		},
-		"node_modules/tailwindcss/node_modules/postcss-load-config": {
-			"version": "4.0.2",
-			"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
-			"integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
-			"dev": true,
-			"funding": [
-				{
-					"type": "opencollective",
-					"url": "https://opencollective.com/postcss/"
-				},
-				{
-					"type": "github",
-					"url": "https://github.com/sponsors/ai"
-				}
-			],
-			"license": "MIT",
-			"dependencies": {
-				"lilconfig": "^3.0.0",
-				"yaml": "^2.3.4"
-			},
-			"engines": {
-				"node": ">= 14"
-			},
-			"peerDependencies": {
-				"postcss": ">=8.0.9",
-				"ts-node": ">=9.0.0"
-			},
-			"peerDependenciesMeta": {
-				"postcss": {
-					"optional": true
-				},
-				"ts-node": {
-					"optional": true
-				}
-			}
-		},
-		"node_modules/tailwindcss/node_modules/readdirp": {
-			"version": "3.6.0",
-			"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
-			"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"picomatch": "^2.2.1"
-			},
-			"engines": {
-				"node": ">=8.10.0"
-			}
-		},
-		"node_modules/thenify": {
-			"version": "3.3.1",
-			"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
-			"integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+			"version": "4.0.6",
+			"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.6.tgz",
+			"integrity": "sha512-mysewHYJKaXgNOW6pp5xon/emCsfAMnO8WMaGKZZ35fomnR/T5gYnRg2/yRTTrtXiEl1tiVkeRt0eMO6HxEZqw==",
 			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"any-promise": "^1.0.0"
-			}
+			"license": "MIT"
 		},
-		"node_modules/thenify-all": {
-			"version": "1.6.0",
-			"resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
-			"integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+		"node_modules/tapable": {
+			"version": "2.2.1",
+			"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+			"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
 			"dev": true,
 			"license": "MIT",
-			"dependencies": {
-				"thenify": ">= 3.1.0 < 4"
-			},
 			"engines": {
-				"node": ">=0.8"
+				"node": ">=6"
 			}
 		},
 		"node_modules/through": {
@@ -8336,13 +8136,6 @@
 				"typescript": ">=4.8.4"
 			}
 		},
-		"node_modules/ts-interface-checker": {
-			"version": "0.1.13",
-			"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
-			"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
-			"dev": true,
-			"license": "Apache-2.0"
-		},
 		"node_modules/ts-log": {
 			"version": "2.2.7",
 			"resolved": "https://registry.npmjs.org/ts-log/-/ts-log-2.2.7.tgz",
@@ -8424,6 +8217,13 @@
 				"node": "*"
 			}
 		},
+		"node_modules/ufo": {
+			"version": "1.5.4",
+			"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz",
+			"integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==",
+			"dev": true,
+			"license": "MIT"
+		},
 		"node_modules/unc-path-regex": {
 			"version": "0.1.2",
 			"resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
@@ -8893,25 +8693,6 @@
 				"node": ">=8"
 			}
 		},
-		"node_modules/wrap-ansi-cjs": {
-			"name": "wrap-ansi",
-			"version": "7.0.0",
-			"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
-			"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
-			"dev": true,
-			"license": "MIT",
-			"dependencies": {
-				"ansi-styles": "^4.0.0",
-				"string-width": "^4.1.0",
-				"strip-ansi": "^6.0.0"
-			},
-			"engines": {
-				"node": ">=10"
-			},
-			"funding": {
-				"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
-			}
-		},
 		"node_modules/ws": {
 			"version": "8.18.0",
 			"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 605f884..f5e4d25 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -21,14 +21,14 @@
 		"@graphql-codegen/typed-document-node": "^5.0.11",
 		"@graphql-codegen/typescript-operations": "^4.3.1",
 		"@iconify-json/material-symbols": "^1.2.6",
-		"@iconify/tailwind": "^1.1.3",
+		"@iconify/tailwind4": "^1.0.3",
 		"@sveltejs/adapter-static": "^3.0.6",
 		"@sveltejs/kit": "^2.8.1",
 		"@sveltejs/vite-plugin-svelte": "^5.0.0",
+		"@tailwindcss/vite": "^4.0.6",
 		"@typescript-eslint/eslint-plugin": "^8.14.0",
 		"@typescript-eslint/parser": "^8.14.0",
 		"@zerodevx/svelte-toast": "^0.9.6",
-		"autoprefixer": "^10.4.20",
 		"date-fns": "^4.1.0",
 		"eslint": "^9.14.0",
 		"eslint-config-prettier": "^10.0.0",
@@ -37,13 +37,12 @@
 		"globals": "^15.14.0",
 		"jsdom": "^26.0.0",
 		"npm-check-updates": "^17.1.11",
-		"postcss": "^8.4.49",
 		"prettier": "^3.3.3",
 		"prettier-plugin-svelte": "^3.2.8",
-		"prettier-plugin-tailwindcss": "^0.6.8",
+		"prettier-plugin-tailwindcss": "^0.6.11",
 		"svelte": "^5.5.0",
 		"svelte-check": "^4.0.0",
-		"tailwindcss": "^3.4.14",
+		"tailwindcss": "^4.0.0",
 		"tslib": "^2.8.1",
 		"typescript": "^5.6.3",
 		"vite": "^6.0.0",
diff --git a/frontend/postcss.config.cjs b/frontend/postcss.config.cjs
deleted file mode 100644
index 054c147..0000000
--- a/frontend/postcss.config.cjs
+++ /dev/null
@@ -1,6 +0,0 @@
-module.exports = {
-	plugins: {
-		tailwindcss: {},
-		autoprefixer: {}
-	}
-};
diff --git a/frontend/src/app.css b/frontend/src/app.css
index f8322d0..ea2f05a 100644
--- a/frontend/src/app.css
+++ b/frontend/src/app.css
@@ -1,213 +1,242 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
+@import 'tailwindcss';
+@config '../tailwind.config.cjs';
+@plugin "@iconify/tailwind4";
+
+@theme {
+	--breakpoint-3xl: 120rem;
+}
 
 @layer base {
-	body {
-		display: grid;
-		grid-template-columns: 3rem 1fr;
-		scrollbar-color: theme('colors.gray.500') rgba(0, 0, 0, 0);
-		font-family: 'Noto Sans', sans-serif;
+	button:not(:disabled),
+	[role='button']:not(:disabled) {
+		cursor: pointer;
 	}
+}
 
-	input,
-	textarea {
-		@apply w-full rounded bg-slate-900 p-[.4rem];
-	}
+@utility btn {
+	@apply focus-thick focus-slate flex items-center justify-center rounded-xs p-2 text-white transition-colors disabled:opacity-40;
+}
 
-	input,
-	textarea,
-	select {
-		@apply focus-thin focus-slate;
-	}
+@utility btn-xs {
+	@apply btn rounded-xs p-0.5 py-0;
+}
 
-	button {
-		@apply focus-thick focus-slate;
-	}
+@utility btn-blue {
+	@apply btn bg-blue-700 hover:bg-blue-600 disabled:bg-blue-900;
+}
 
-	a {
-		@apply focus-thick focus-blue;
-	}
+@utility btn-rose {
+	@apply btn bg-rose-700 hover:bg-rose-600 disabled:bg-rose-900;
+}
 
-	label {
-		@apply mb-0.5 inline-block;
-	}
+@utility btn-slate {
+	@apply btn bg-slate-700 hover:bg-slate-600 disabled:bg-slate-800;
+}
 
-	form {
-		@apply flex flex-col gap-4 p-px text-sm;
-	}
+@utility btn-indigo {
+	@apply btn bg-indigo-700 hover:bg-indigo-600 disabled:bg-indigo-800;
+}
 
-	.rounded-group > * {
-		@apply rounded-none first:rounded-l-sm last:rounded-r-sm !important;
-	}
+@utility icon-xs {
+	@apply text-[18px];
+}
 
-	.rounded-group-start > * {
-		@apply rounded-none first:rounded-l-sm !important;
-	}
+@utility icon-base {
+	@apply text-[24px];
+}
 
-	.rounded-group-end > * {
-		@apply rounded-none last:rounded-r-sm !important;
-	}
+@utility icon-lg {
+	@apply text-[28px];
+}
 
-	.grid-labels {
-		@apply grid grid-cols-[1fr_5fr] gap-2;
+@utility icon-2xl {
+	@apply text-[48px];
+}
+
+@utility icon-gray {
+	&.hoverable:hover {
+		@apply text-gray-200/80;
 	}
 
-	header {
-		grid-area: header;
+	&.dim {
+		@apply text-gray-100/40;
 	}
+}
 
-	aside {
-		overflow: auto;
-		grid-area: sidebar;
-		@apply lg:w-[28rem] xl:w-[32rem] min-[1920px]:w-[36rem];
+@utility hoverable {
+	&.icon-gray:hover {
+		@apply text-gray-200/80;
 	}
 
-	main {
-		grid-area: main;
+	&.icon-yellow:hover {
+		@apply text-yellow-300/80;
 	}
 }
 
-@layer components {
-	.btn {
-		@apply focus-thick focus-slate flex items-center justify-center rounded-sm p-2 text-white transition-colors disabled:opacity-40;
+@utility dim {
+	&.icon-gray {
+		@apply text-gray-100/40;
 	}
 
-	.btn-xs {
-		@apply btn rounded-sm p-0.5 py-0;
+	&.icon-yellow {
+		@apply text-slate-100/40;
 	}
+}
 
-	.btn-blue {
-		@apply btn bg-blue-700 hover:bg-blue-600 disabled:bg-blue-900;
-	}
+@utility icon-yellow {
+	@apply text-yellow-300;
 
-	.btn-rose {
-		@apply btn bg-rose-700 hover:bg-rose-600 disabled:bg-rose-900;
+	&.hoverable:hover {
+		@apply text-yellow-300/80;
 	}
 
-	.btn-slate {
-		@apply btn bg-slate-700 hover:bg-slate-600 disabled:bg-slate-800;
+	&.dim {
+		@apply text-slate-100/40;
 	}
+}
 
-	.btn-indigo {
-		@apply btn bg-indigo-700 hover:bg-indigo-600 disabled:bg-indigo-800;
-	}
+@utility toggled {
+	@apply bg-indigo-700 hover:bg-indigo-600;
+}
 
-	.icon-xs {
-		@apply text-[18px];
-	}
+@utility floating {
+	@apply rounded-full bg-black/50 p-1 text-white/80 backdrop-blur-xs hover:bg-black/50 hover:text-white;
+}
 
-	.icon-base {
-		@apply text-[24px];
-	}
+@utility ellipsis-nowrap {
+	@apply overflow-hidden text-ellipsis whitespace-nowrap;
+}
 
-	.icon-lg {
-		@apply text-[28px];
-	}
+@utility rounded-inherit {
+	border-radius: inherit;
+}
 
-	.icon-2xl {
-		@apply text-[48px];
-	}
+@utility grid-card-h {
+	grid-template-columns: 210px 1fr;
+	grid-template-rows: 300px;
+}
 
-	.icon-gray.hoverable:hover {
-		@apply text-gray-200/80;
-	}
+@utility grid-card-cover-only {
+	@apply !grid-card-h;
+}
 
-	.icon-gray.dim {
-		@apply text-gray-100/40;
-	}
+@utility grid-card-v {
+	grid-template-columns: 1fr;
+	grid-template-rows: 500px 1fr;
+}
 
-	.icon-yellow {
-		@apply text-yellow-300;
-	}
+@utility focus-thin {
+	@apply focus:isolate focus:outline;
+}
 
-	.icon-yellow.hoverable:hover {
-		@apply text-yellow-300/80;
+@utility focus-thick {
+	@apply focus-visible:isolate focus-visible:outline;
+}
+
+@utility focus-background {
+	@apply focus-visible:bg-indigo-600 focus-visible:outline-hidden;
+}
+
+@utility focus-slate {
+	@apply focus:outline-slate-400 focus-visible:outline-slate-400;
+}
+
+@utility focus-blue {
+	@apply focus:outline-blue-600 focus-visible:outline-blue-600;
+}
+
+@layer base {
+	body {
+		display: grid;
+		grid-template-columns: 3rem 1fr;
+		scrollbar-color: var(--color-gray-500) rgba(0, 0, 0, 0);
+		font-family: 'Noto Sans', sans-serif;
 	}
 
-	.icon-yellow.dim {
-		@apply text-slate-100/40;
+	input,
+	textarea {
+		@apply w-full rounded-sm bg-slate-900 p-[.4rem];
 	}
-}
 
-@layer utilities {
-	.toggled {
-		@apply bg-indigo-700 hover:bg-indigo-600;
+	input,
+	textarea,
+	select {
+		@apply focus-thin focus-slate;
 	}
 
-	.floating {
-		@apply rounded-full bg-black/50 p-1 text-white/80 backdrop-blur-sm hover:bg-black/50 hover:text-white;
+	button {
+		@apply focus-thick focus-slate;
 	}
 
-	.ellipsis-nowrap {
-		@apply overflow-hidden text-ellipsis whitespace-nowrap;
+	a {
+		@apply focus-thick focus-blue;
 	}
 
-	.rounded-inherit {
-		border-radius: inherit;
+	label {
+		@apply mb-0.5 inline-block;
 	}
 
-	.grid-card-h {
-		grid-template-columns: 210px 1fr;
-		grid-template-rows: 300px;
+	form {
+		@apply flex flex-col gap-4 p-px text-sm;
 	}
 
-	.grid-card-cover-only {
-		@apply !grid-card-h;
+	.rounded-group > * {
+		@apply rounded-none! first:rounded-l-xs! last:rounded-r-xs!;
 	}
 
-	.grid-card-v {
-		grid-template-columns: 1fr;
-		grid-template-rows: 500px 1fr;
+	.rounded-group-start > * {
+		@apply rounded-none! first:rounded-l-xs!;
 	}
 
-	.focus-thin {
-		@apply focus:isolate focus:outline focus:outline-1;
+	.rounded-group-end > * {
+		@apply rounded-none! last:rounded-r-xs!;
 	}
 
-	.focus-thick {
-		@apply focus-visible:isolate focus-visible:outline;
+	.grid-labels {
+		@apply grid grid-cols-[1fr_5fr] gap-2;
 	}
 
-	.focus-background {
-		@apply focus-visible:bg-indigo-600 focus-visible:outline-none;
+	header {
+		grid-area: header;
 	}
 
-	.focus-slate {
-		@apply focus:outline-slate-400 focus-visible:outline-slate-400;
+	aside {
+		overflow: auto;
+		grid-area: sidebar;
+		@apply 3xl:w-[36rem] lg:w-[28rem] xl:w-[32rem];
 	}
 
-	.focus-blue {
-		@apply focus:outline-blue-600 focus-visible:outline-blue-600;
+	main {
+		grid-area: main;
 	}
 }
 
 .svelecte {
-	--sv-bg: theme(colors.slate.900);
-	--sv-disabled-bg: theme(colors.slate.900);
+	--sv-bg: var(--color-slate-900);
+	--sv-disabled-bg: var(--color-slate-900);
 	--sv-border: 1px solid rgba(0, 0, 0, 0);
-	--sv-dropdown-active-bg: theme(colors.indigo.800);
-	--sv-item-selected-bg: theme(colors.indigo.800);
-	--sv-item-btn-bg-hover: theme(colors.rose.900);
-	--sv-item-btn-color-hover: theme(colors.rose.100);
-	--sv-separator-bg: theme(colors.gray.700);
+	--sv-dropdown-active-bg: var(--color-indigo-800);
+	--sv-item-selected-bg: var(--color-indigo-800);
+	--sv-item-btn-bg-hover: var(--color-rose-900);
+	--sv-item-btn-color-hover: var(--color-rose-100);
+	--sv-separator-bg: var(--color-gray-700);
 	--sv-min-height: 38px;
 	--sv-item-wrap-padding: 3px 3px 3px 5px;
 	--sv-selection-multi-wrap-padding: 3px 3px 3px 5px;
 }
 
 .svelecte.is-focused {
-	--sv-border: 1px solid theme(colors.slate.400);
+	--sv-border: 1px solid var(--color-slate-400);
 }
 
 .svelecte input::placeholder {
-	color: theme(colors.gray.500);
+	color: var(--color-gray-500);
 }
 
 .exclude .svelecte {
-	--sv-border: 1px solid theme(colors.red.900);
-	--sv-item-selected-bg: theme(colors.rose.800);
-	--sv-dropdown-active-bg: theme(colors.rose.800);
+	--sv-border: 1px solid var(--color-red-900);
+	--sv-item-selected-bg: var(--color-rose-800);
+	--sv-dropdown-active-bg: var(--color-rose-800);
 }
 
 .sv-item--btn {
diff --git a/frontend/src/lib/components/Badge.svelte b/frontend/src/lib/components/Badge.svelte
index 60cf727..8de5e34 100644
--- a/frontend/src/lib/components/Badge.svelte
+++ b/frontend/src/lib/components/Badge.svelte
@@ -7,7 +7,7 @@
 
 {#if number > 0}
 	<span
-		class="absolute -right-[3px] -top-[6px] z-[1] rounded-sm bg-teal-600 px-1 text-xs font-semibold drop-shadow"
+		class="absolute -top-1.5 -right-1 z-1 rounded-xs bg-teal-600 px-1 text-xs font-semibold drop-shadow-sm"
 		transition:fade={fadeDefault}
 	>
 		{number}
diff --git a/frontend/src/lib/components/Card.svelte b/frontend/src/lib/components/Card.svelte
index 45e1662..8066b42 100644
--- a/frontend/src/lib/components/Card.svelte
+++ b/frontend/src/lib/components/Card.svelte
@@ -49,7 +49,7 @@
 
 <a
 	{href}
-	class="grid-card-v sm:grid-card-h focus-thick focus-blue relative grid overflow-hidden rounded bg-slate-900 shadow-md shadow-slate-950/30"
+	class="grid-card-v sm:grid-card-h focus-thick focus-blue relative grid overflow-hidden rounded-sm bg-slate-900 shadow-md shadow-slate-950/30"
 	class:compact
 	class:grid-card-cover-only={coverOnly}
 	{onclick}
diff --git a/frontend/src/lib/components/Cardlet.svelte b/frontend/src/lib/components/Cardlet.svelte
index d0c0509..cfbbd58 100644
--- a/frontend/src/lib/components/Cardlet.svelte
+++ b/frontend/src/lib/components/Cardlet.svelte
@@ -14,7 +14,7 @@
 
 <button
 	type="button"
-	class="relative flex overflow-hidden rounded bg-slate-900 text-left shadow-md shadow-slate-950/20"
+	class="relative flex overflow-hidden rounded-sm bg-slate-900 text-left shadow-md shadow-slate-950/20"
 	{title}
 	{onclick}
 	{onauxclick}
diff --git a/frontend/src/lib/components/Dropdown.svelte b/frontend/src/lib/components/Dropdown.svelte
index ddd20a0..e2979e6 100644
--- a/frontend/src/lib/components/Dropdown.svelte
+++ b/frontend/src/lib/components/Dropdown.svelte
@@ -28,7 +28,7 @@
 	{@render button(() => (visible = !visible))}
 	{#if visible}
 		<div
-			class="absolute z-[1] mt-1 w-max rounded bg-slate-700 p-1 shadow-sm shadow-slate-900"
+			class="absolute z-1 mt-1 w-max rounded-sm bg-slate-700 p-1 shadow-xs shadow-slate-900"
 			transition:fade={fadeFast}
 		>
 			{@render children?.()}
diff --git a/frontend/src/lib/components/Spinner.svelte b/frontend/src/lib/components/Spinner.svelte
index 1a471a7..d85c4f4 100644
--- a/frontend/src/lib/components/Spinner.svelte
+++ b/frontend/src/lib/components/Spinner.svelte
@@ -9,28 +9,7 @@
 
 {#if show}
 	<div class="flex h-full w-full items-center justify-center">
-		<span class="spinner"></span>
+		<span class="h-16 w-16 animate-spin rounded-full border-4 border-white/80 border-b-transparent"
+		></span>
 	</div>
 {/if}
-
-<style lang="postcss">
-	.spinner {
-		width: 64px;
-		height: 64px;
-		border: 5px solid theme(colors.gray.200);
-		border-bottom-color: transparent;
-		border-radius: 50%;
-		display: inline-block;
-		box-sizing: border-box;
-		animation: rotation 1s linear infinite;
-	}
-
-	@keyframes rotation {
-		0% {
-			transform: rotate(0deg);
-		}
-		100% {
-			transform: rotate(360deg);
-		}
-	}
-</style>
diff --git a/frontend/src/lib/containers/Cardlets.svelte b/frontend/src/lib/containers/Cardlets.svelte
index 5997a69..107ebee 100644
--- a/frontend/src/lib/containers/Cardlets.svelte
+++ b/frontend/src/lib/containers/Cardlets.svelte
@@ -6,7 +6,7 @@
 </script>
 
 <div
-	class="grid gap-4 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 min-[1600px]:grid-cols-8 min-[1920px]:grid-cols-10"
+	class="3xl:grid-cols-10 grid gap-4 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 2xl:grid-cols-8"
 	in:fade={fadeDefault}
 >
 	{@render children?.()}
diff --git a/frontend/src/lib/containers/Cards.svelte b/frontend/src/lib/containers/Cards.svelte
index 36a4b86..ab1f0fb 100644
--- a/frontend/src/lib/containers/Cards.svelte
+++ b/frontend/src/lib/containers/Cards.svelte
@@ -5,6 +5,6 @@
 	let { children } = $props();
 </script>
 
-<div class="grid gap-4 xl:grid-cols-2 min-[1920px]:grid-cols-3" in:fade|global={fadeDefault}>
+<div class="3xl:grid-cols-3 grid gap-4 xl:grid-cols-2" in:fade|global={fadeDefault}>
 	{@render children?.()}
 </div>
diff --git a/frontend/src/lib/filter/ComicFilterForm.svelte b/frontend/src/lib/filter/ComicFilterForm.svelte
index 7f0058d..8bf7af3 100644
--- a/frontend/src/lib/filter/ComicFilterForm.svelte
+++ b/frontend/src/lib/filter/ComicFilterForm.svelte
@@ -25,13 +25,7 @@
 
 <FilterForm type="grid" apply={filter.apply} expanded={filter.excludes > 0}>
 	{#snippet include(type)}
-		<Filter
-			{type}
-			title="Tags"
-			options={tags}
-			filter={filter.include.tags}
-			--grid-column="span 2"
-		/>
+		<Filter {type} wide title="Tags" options={tags} filter={filter.include.tags} />
 		<Filter {type} title="Artists" options={artists} filter={filter.include.artists} />
 		<Filter {type} title="Circles" options={circles} filter={filter.include.circles} />
 		<Filter {type} title="Characters" options={characters} filter={filter.include.characters} />
@@ -42,13 +36,7 @@
 		<Filter {type} title="Languages" options={languages} filter={filter.include.languages} />
 	{/snippet}
 	{#snippet exclude(type)}
-		<Filter
-			{type}
-			title="Tags"
-			options={tags}
-			filter={filter.exclude.tags}
-			--grid-column="span 2"
-		/>
+		<Filter {type} wide title="Tags" options={tags} filter={filter.exclude.tags} />
 		<Filter {type} title="Artists" options={artists} filter={filter.exclude.artists} />
 		<Filter {type} title="Circles" options={circles} filter={filter.exclude.circles} />
 		<Filter {type} title="Characters" options={characters} filter={filter.exclude.characters} />
diff --git a/frontend/src/lib/filter/components/Filter.svelte b/frontend/src/lib/filter/components/Filter.svelte
index c164cbb..4b39589 100644
--- a/frontend/src/lib/filter/components/Filter.svelte
+++ b/frontend/src/lib/filter/components/Filter.svelte
@@ -8,15 +8,16 @@
 		type: FilterType;
 		options: ListItem[] | undefined;
 		filter: Association<string> | Enum<string>;
+		wide?: boolean;
 	}
 
-	let { title, type, options, filter }: Props = $props();
+	let { title, type, options, filter, wide = false }: Props = $props();
 	let exclude = $derived(type === 'exclude');
 
 	const id = `${type}-${title.toLowerCase()}`;
 </script>
 
-<div class:exclude class="filter-container">
+<div class:exclude class:wide class="filter-container [&.wide]:col-span-2">
 	<div class="flex gap-2">
 		<label for={id}>{title}</label>
 		<div class="ml-auto flex items-center gap-1 self-center text-xs">
@@ -25,7 +26,7 @@
 					type="button"
 					title="matches all"
 					class:active={filter.mode === 'all'}
-					class="btn btn-xs"
+					class="btn-xs hover:bg-slate-700 [&.active]:bg-indigo-800"
 					onclick={() => (filter.mode = 'all')}
 				>
 					&forall;
@@ -34,7 +35,7 @@
 					type="button"
 					title="matches any of"
 					class:active={filter.mode === 'any'}
-					class="btn btn-xs"
+					class="btn-xs hover:bg-slate-700 [&.active]:bg-indigo-800"
 					onclick={() => (filter.mode = 'any')}
 				>
 					&exist;
@@ -43,7 +44,7 @@
 					type="button"
 					title="matches exactly"
 					class:active={filter.mode === 'exact'}
-					class="btn btn-xs"
+					class="btn-xs hover:bg-slate-700 [&.active]:bg-indigo-800"
 					onclick={() => (filter.mode = 'exact')}
 				>
 					&equals;
@@ -54,7 +55,7 @@
 				type="button"
 				title="empty"
 				class:active={filter.empty}
-				class="btn btn-xs"
+				class="btn-xs hover:bg-slate-700 [&.active]:bg-indigo-800"
 				onclick={() => (filter.empty = !filter.empty)}
 			>
 				&empty;
@@ -63,17 +64,3 @@
 	</div>
 	<Select multi clearable {options} {id} bind:value={filter.values} />
 </div>
-
-<style lang="postcss">
-	button:hover {
-		@apply bg-slate-700;
-	}
-
-	button.active {
-		@apply bg-indigo-800;
-	}
-
-	.filter-container {
-		grid-column: var(--grid-column);
-	}
-</style>
diff --git a/frontend/src/lib/filter/components/FilterForm.svelte b/frontend/src/lib/filter/components/FilterForm.svelte
index ed58ed9..a32faf8 100644
--- a/frontend/src/lib/filter/components/FilterForm.svelte
+++ b/frontend/src/lib/filter/components/FilterForm.svelte
@@ -38,9 +38,7 @@
 			</div>
 		{/if}
 	{:else}
-		<div
-			class="flex flex-wrap justify-center gap-2 [&>*]:basis-full xl:[&>*]:basis-1/3 2xl:[&>*]:basis-1/5"
-		>
+		<div class="flex flex-wrap justify-center gap-2 *:basis-full xl:*:basis-1/3 2xl:*:basis-1/5">
 			<div class="p-2">
 				{@render include?.('include')}
 			</div>
diff --git a/frontend/src/lib/gallery/GalleryPage.svelte b/frontend/src/lib/gallery/GalleryPage.svelte
index 3169d6d..f8a81a6 100644
--- a/frontend/src/lib/gallery/GalleryPage.svelte
+++ b/frontend/src/lib/gallery/GalleryPage.svelte
@@ -56,7 +56,7 @@
 	class:dim
 	role="button"
 	tabindex="0"
-	class="{span} focus-thick focus-blue relative overflow-hidden rounded"
+	class="{span} focus-thick focus-blue relative overflow-hidden rounded-sm"
 	onclick={press}
 	onkeydown={press}
 >
diff --git a/frontend/src/lib/icons/Artist.svelte b/frontend/src/lib/icons/Artist.svelte
new file mode 100644
index 0000000..04886ce
--- /dev/null
+++ b/frontend/src/lib/icons/Artist.svelte
@@ -0,0 +1 @@
+<span class="icon-xs icon-[material-symbols--person] -mx-px"></span>
diff --git a/frontend/src/lib/icons/Character.svelte b/frontend/src/lib/icons/Character.svelte
new file mode 100644
index 0000000..fbb3ecc
--- /dev/null
+++ b/frontend/src/lib/icons/Character.svelte
@@ -0,0 +1 @@
+<span class="icon-xs icon-[material-symbols--face]"></span>
diff --git a/frontend/src/lib/icons/Circle.svelte b/frontend/src/lib/icons/Circle.svelte
new file mode 100644
index 0000000..b54135c
--- /dev/null
+++ b/frontend/src/lib/icons/Circle.svelte
@@ -0,0 +1 @@
+<span class="icon-xs icon-[material-symbols--group] mx-px"></span>
diff --git a/frontend/src/lib/icons/World.svelte b/frontend/src/lib/icons/World.svelte
new file mode 100644
index 0000000..2d0320f
--- /dev/null
+++ b/frontend/src/lib/icons/World.svelte
@@ -0,0 +1 @@
+<span class="icon-xs icon-[material-symbols--public]"></span>
diff --git a/frontend/src/lib/pagination/Target.svelte b/frontend/src/lib/pagination/Target.svelte
index 6cbacbb..76e0d9e 100644
--- a/frontend/src/lib/pagination/Target.svelte
+++ b/frontend/src/lib/pagination/Target.svelte
@@ -19,9 +19,8 @@
 
 <button
 	{onclick}
-	class:bg-slate-700={active}
-	class:bg-slate-800={!active}
-	class="flex h-8 w-8 items-center justify-center rounded-sm p-0 text-base hover:text-white disabled:text-slate-600"
+	class:active
+	class="flex h-8 w-8 items-center justify-center rounded-sm p-0 text-base font-medium hover:bg-slate-700/50 hover:text-white disabled:text-slate-600 disabled:hover:bg-inherit [&.active]:bg-slate-700 [&:not(active)]:bg-slate-800"
 	{disabled}
 >
 	{@render children?.()}
diff --git a/frontend/src/lib/pills/AssociationPill.svelte b/frontend/src/lib/pills/AssociationPill.svelte
index ffbc8c4..fec59b8 100644
--- a/frontend/src/lib/pills/AssociationPill.svelte
+++ b/frontend/src/lib/pills/AssociationPill.svelte
@@ -1,31 +1,27 @@
 <script lang="ts">
+	import Artist from '$lib/icons/Artist.svelte';
+	import Character from '$lib/icons/Character.svelte';
+	import Circle from '$lib/icons/Circle.svelte';
+	import World from '$lib/icons/World.svelte';
+	import type { Component } from 'svelte';
 	import Pill from './Pill.svelte';
 
 	type Association = 'artist' | 'circle' | 'world' | 'character';
 
 	let { name, type }: { name: string; type: Association } = $props();
+
+	const icons: Record<Association, Component> = {
+		artist: Artist,
+		character: Character,
+		circle: Circle,
+		world: World
+	};
+
+	const Icon = icons[type];
 </script>
 
 <Pill {name}>
 	{#snippet icon()}
-		<span class={`${type} icon-xs`}></span>
+		<Icon />
 	{/snippet}
 </Pill>
-
-<style lang="postcss">
-	.artist {
-		@apply icon-[material-symbols--person] -mx-px;
-	}
-
-	.character {
-		@apply icon-[material-symbols--face];
-	}
-
-	.circle {
-		@apply icon-[material-symbols--group] mx-px;
-	}
-
-	.world {
-		@apply icon-[material-symbols--public];
-	}
-</style>
diff --git a/frontend/src/lib/pills/Pill.svelte b/frontend/src/lib/pills/Pill.svelte
index 24d617d..5d5b5a8 100644
--- a/frontend/src/lib/pills/Pill.svelte
+++ b/frontend/src/lib/pills/Pill.svelte
@@ -15,12 +15,14 @@
 	let { name, tooltip, colour = 'zinc', icon }: Props = $props();
 </script>
 
-<div class="flex items-center rounded border p-0.5 {colour}" title={tooltip}>
+<div class="flex items-center rounded-sm border p-0.5 {colour}" title={tooltip}>
 	{@render icon?.()}
 	<span>{name}</span>
 </div>
 
 <style lang="postcss">
+	@reference "tailwindcss/theme"
+
 	.pink {
 		@apply border-pink-800 bg-pink-800/20 text-pink-200;
 	}
diff --git a/frontend/src/lib/reader/components/PageIndicator.svelte b/frontend/src/lib/reader/components/PageIndicator.svelte
index 35190b3..3b11389 100644
--- a/frontend/src/lib/reader/components/PageIndicator.svelte
+++ b/frontend/src/lib/reader/components/PageIndicator.svelte
@@ -4,6 +4,6 @@
 	const reader = getReaderContext();
 </script>
 
-<div class="floating !p-2">
+<div class="floating p-2!">
 	{reader.page + 1}/{reader.pages.length}
 </div>
diff --git a/frontend/src/lib/scraper/components/SelectorButton.svelte b/frontend/src/lib/scraper/components/SelectorButton.svelte
index e976f91..48b2d66 100644
--- a/frontend/src/lib/scraper/components/SelectorButton.svelte
+++ b/frontend/src/lib/scraper/components/SelectorButton.svelte
@@ -6,7 +6,7 @@
 
 <button
 	type="button"
-	class="ml-1 flex rounded-sm border-slate-700 bg-slate-900 hover:brightness-110"
+	class="ml-1 flex rounded-xs border-slate-700 bg-slate-900 hover:brightness-110"
 	onclick={selector.toggle}
 >
 	<div class="flex self-center pl-1">
diff --git a/frontend/src/lib/selection/SelectionOverlay.svelte b/frontend/src/lib/selection/SelectionOverlay.svelte
index 97421b0..e172e16 100644
--- a/frontend/src/lib/selection/SelectionOverlay.svelte
+++ b/frontend/src/lib/selection/SelectionOverlay.svelte
@@ -11,9 +11,9 @@
 {#if selected}
 	<div
 		class:items-center={centered}
-		class="{position} pointer-events-none absolute z-[1] flex bg-emerald-700/95"
+		class="{position} pointer-events-none absolute z-1 flex bg-emerald-700/95"
 	>
-		<span class="icon-base icon-[material-symbols--check] text-[2rem]"></span>
+		<span class="icon-[material-symbols--check] text-[2rem]"></span>
 	</div>
 {/if}
 
diff --git a/frontend/src/lib/statistics/StatGroup.svelte b/frontend/src/lib/statistics/StatGroup.svelte
index e84c555..91f8d3d 100644
--- a/frontend/src/lib/statistics/StatGroup.svelte
+++ b/frontend/src/lib/statistics/StatGroup.svelte
@@ -5,7 +5,7 @@
 </script>
 
 <section
-	class="flex flex-col gap-2 rounded bg-slate-900 p-2 font-medium shadow-md shadow-slate-950/30"
+	class="flex flex-col gap-2 rounded-sm bg-slate-900 p-2 font-medium shadow-md shadow-slate-950/30"
 >
 	<h2 class="text-2xl">{title}</h2>
 	<div class="flex flex-row flex-wrap gap-10">
diff --git a/frontend/src/lib/tabs/AddOverlay.svelte b/frontend/src/lib/tabs/AddOverlay.svelte
index 329b259..4d5ec49 100644
--- a/frontend/src/lib/tabs/AddOverlay.svelte
+++ b/frontend/src/lib/tabs/AddOverlay.svelte
@@ -28,7 +28,7 @@
 	<div class="absolute left-1 top-1" transition:fade={fadeDefault}>
 		<button
 			type="button"
-			class="btn-blue rounded-full shadow-sm shadow-black"
+			class="btn-blue rounded-full shadow-xs shadow-black"
 			title="Add to this comic"
 			aria-label="Add to this comic"
 			{onclick}
diff --git a/frontend/src/lib/tabs/Tabs.svelte b/frontend/src/lib/tabs/Tabs.svelte
index 1ae7c32..3c5611e 100644
--- a/frontend/src/lib/tabs/Tabs.svelte
+++ b/frontend/src/lib/tabs/Tabs.svelte
@@ -30,18 +30,18 @@
 
 <div class="flex h-full max-h-full flex-col">
 	<nav>
-		<ul class="me-3 ms-1 flex border-b-2 border-slate-700 text-sm">
+		<ul class="ms-1 me-3 flex border-b-2 border-slate-700 text-sm">
 			{#each Object.entries(context.tabs) as [id, { title }]}
 				<li class="-mb-0.5">
 					<button
 						type="button"
 						class:active={context.current === id}
-						class="focus-background relative flex gap-1 p-1 px-3 hover:border-b-2 hover:border-slate-200"
+						class="relative flex gap-1 p-1 px-3 hover:border-b-2 hover:border-slate-200 [&.active]:border-b-2 [&.active]:border-indigo-500"
 						onclick={() => (context.current = id)}
 					>
 						{#if badges[id]}
 							<div
-								class="absolute right-0 top-1 h-2 w-2 rounded-full bg-emerald-400"
+								class="absolute top-1 right-0 h-2 w-2 rounded-full bg-emerald-400"
 								title="There are pending changes"
 								transition:fade={fadeFast}
 							></div>
@@ -54,9 +54,3 @@
 	</nav>
 	{@render children?.()}
 </div>
-
-<style lang="postcss">
-	button.active {
-		@apply border-b-2 border-indigo-500;
-	}
-</style>
diff --git a/frontend/src/lib/toolbar/MarkSelection.svelte b/frontend/src/lib/toolbar/MarkSelection.svelte
index 1af36ca..8985369 100644
--- a/frontend/src/lib/toolbar/MarkSelection.svelte
+++ b/frontend/src/lib/toolbar/MarkSelection.svelte
@@ -9,7 +9,7 @@
 	{#snippet button(onclick)}
 		<button
 			type="button"
-			class="btn-slate rounded-inherit relative hover:bg-blue-700 [&:not(:only-child)]:bg-blue-700"
+			class="btn-slate rounded-inherit relative not-only:bg-blue-700 hover:bg-blue-700"
 			title="Set flag..."
 			aria-label="Set flag..."
 			{onclick}
diff --git a/frontend/tailwind.config.cjs b/frontend/tailwind.config.cjs
index 99307cd..d8b3776 100644
--- a/frontend/tailwind.config.cjs
+++ b/frontend/tailwind.config.cjs
@@ -1,7 +1,4 @@
-const { addDynamicIconSelectors } = require('@iconify/tailwind');
-
 /** @type {import('tailwindcss').Config} */
 module.exports = {
-	content: ['./src/**/*.{html,js,svelte,ts}'],
-	plugins: [addDynamicIconSelectors()]
+	content: ['./src/**/*.{html,js,svelte,ts}']
 };
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
index 7905397..eeabcf6 100644
--- a/frontend/vite.config.ts
+++ b/frontend/vite.config.ts
@@ -1,8 +1,9 @@
 import { sveltekit } from '@sveltejs/kit/vite';
+import tailwindcss from '@tailwindcss/vite';
 import { defineConfig } from 'vite';
 
 export default defineConfig({
-	plugins: [sveltekit()],
+	plugins: [tailwindcss(), sveltekit()],
 	server: { fs: { allow: ['objects'] } },
 	test: { environment: 'jsdom' }
 });
-- 
cgit v1.2.3-2-gb3c3