Bladeren bron

first commit just ui

gdias 1 maand geleden
commit
a6181756bb

+ 23 - 0
.gitignore

@@ -0,0 +1,23 @@
+node_modules
+
+# Output
+.output
+.vercel
+.netlify
+.wrangler
+/.svelte-kit
+/build
+
+# OS
+.DS_Store
+Thumbs.db
+
+# Env
+.env
+.env.*
+!.env.example
+!.env.test
+
+# Vite
+vite.config.js.timestamp-*
+vite.config.ts.timestamp-*

+ 1 - 0
.npmrc

@@ -0,0 +1 @@
+engine-strict=true

+ 9 - 0
.prettierignore

@@ -0,0 +1,9 @@
+# Package Managers
+package-lock.json
+pnpm-lock.yaml
+yarn.lock
+bun.lock
+bun.lockb
+
+# Miscellaneous
+/static/

+ 16 - 0
.prettierrc

@@ -0,0 +1,16 @@
+{
+	"useTabs": true,
+	"singleQuote": true,
+	"trailingComma": "none",
+	"printWidth": 100,
+	"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
+	"overrides": [
+		{
+			"files": "*.svelte",
+			"options": {
+				"parser": "svelte"
+			}
+		}
+	],
+	"tailwindStylesheet": "./src/routes/layout.css"
+}

+ 3 - 0
.vscode/extensions.json

@@ -0,0 +1,3 @@
+{
+	"recommendations": ["svelte.svelte-vscode", "esbenp.prettier-vscode", "bradlc.vscode-tailwindcss"]
+}

+ 5 - 0
.vscode/settings.json

@@ -0,0 +1,5 @@
+{
+	"files.associations": {
+		"*.css": "tailwindcss"
+	}
+}

+ 42 - 0
README.md

@@ -0,0 +1,42 @@
+# sv
+
+Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).
+
+## Creating a project
+
+If you're seeing this, you've probably already done this step. Congrats!
+
+```sh
+# create a new project
+npx sv create my-app
+```
+
+To recreate this project with the same configuration:
+
+```sh
+# recreate this project
+npx sv@0.15.2 create --template minimal --no-types --add prettier tailwindcss="plugins:none" sveltekit-adapter="adapter:static" --install npm ./
+```
+
+## Developing
+
+Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
+
+```sh
+npm run dev
+
+# or start the server and open the app in a new browser tab
+npm run dev -- --open
+```
+
+## Building
+
+To create a production version of your app:
+
+```sh
+npm run build
+```
+
+You can preview the production build with `npm run preview`.
+
+> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.

+ 13 - 0
jsconfig.json

@@ -0,0 +1,13 @@
+{
+	"extends": "./.svelte-kit/tsconfig.json",
+	"compilerOptions": {
+		"allowJs": true,
+		"checkJs": false,
+		"moduleResolution": "bundler"
+	}
+	// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
+	// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
+	//
+	// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
+	// from the referenced tsconfig.json - TypeScript does not merge them in
+}

+ 3109 - 0
package-lock.json

@@ -0,0 +1,3109 @@
+{
+	"name": "nettown-front",
+	"version": "0.0.1",
+	"lockfileVersion": 3,
+	"requires": true,
+	"packages": {
+		"": {
+			"name": "nettown-front",
+			"version": "0.0.1",
+			"dependencies": {
+				"clsx": "^2.1.1",
+				"d3-array": "^3.2.4",
+				"d3-format": "^3.1.2",
+				"d3-scale": "^4.0.2",
+				"d3-shape": "^3.2.0",
+				"d3-time-format": "^4.1.0",
+				"layerchart": "^1.0.13",
+				"lucide-svelte": "^1.0.1",
+				"tailwind-merge": "^3.5.0"
+			},
+			"devDependencies": {
+				"@sveltejs/adapter-static": "^3.0.10",
+				"@sveltejs/kit": "^2.57.0",
+				"@sveltejs/vite-plugin-svelte": "^7.0.0",
+				"@tailwindcss/vite": "^4.2.2",
+				"prettier": "^3.8.1",
+				"prettier-plugin-svelte": "^3.5.1",
+				"prettier-plugin-tailwindcss": "^0.7.2",
+				"svelte": "^5.55.2",
+				"tailwindcss": "^4.2.2",
+				"vite": "^8.0.7"
+			}
+		},
+		"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==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/@dagrejs/dagre": {
+			"version": "1.1.8",
+			"resolved": "https://registry.npmjs.org/@dagrejs/dagre/-/dagre-1.1.8.tgz",
+			"integrity": "sha512-5SEDlndt4W/LaVzPYJW+bSmSEZc9EzTf8rJ20WCKvjS5EAZAN0b+x0Yww7VMT4R3Wootkg+X9bUfUxazYw6Blw==",
+			"license": "MIT",
+			"dependencies": {
+				"@dagrejs/graphlib": "2.2.4"
+			}
+		},
+		"node_modules/@dagrejs/graphlib": {
+			"version": "2.2.4",
+			"resolved": "https://registry.npmjs.org/@dagrejs/graphlib/-/graphlib-2.2.4.tgz",
+			"integrity": "sha512-mepCf/e9+SKYy1d02/UkvSy6+6MoyXhVxP8lLDfA7BPE1X1d4dR0sZznmbM8/XVJ1GPM+Svnx7Xj6ZweByWUkw==",
+			"license": "MIT",
+			"engines": {
+				"node": ">17.0.0"
+			}
+		},
+		"node_modules/@emnapi/core": {
+			"version": "1.10.0",
+			"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
+			"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"dependencies": {
+				"@emnapi/wasi-threads": "1.2.1",
+				"tslib": "^2.4.0"
+			}
+		},
+		"node_modules/@emnapi/runtime": {
+			"version": "1.10.0",
+			"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
+			"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"dependencies": {
+				"tslib": "^2.4.0"
+			}
+		},
+		"node_modules/@emnapi/wasi-threads": {
+			"version": "1.2.1",
+			"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
+			"integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"dependencies": {
+				"tslib": "^2.4.0"
+			}
+		},
+		"node_modules/@floating-ui/core": {
+			"version": "1.7.5",
+			"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
+			"integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==",
+			"license": "MIT",
+			"dependencies": {
+				"@floating-ui/utils": "^0.2.11"
+			}
+		},
+		"node_modules/@floating-ui/dom": {
+			"version": "1.7.6",
+			"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz",
+			"integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==",
+			"license": "MIT",
+			"dependencies": {
+				"@floating-ui/core": "^1.7.5",
+				"@floating-ui/utils": "^0.2.11"
+			}
+		},
+		"node_modules/@floating-ui/utils": {
+			"version": "0.2.11",
+			"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz",
+			"integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==",
+			"license": "MIT"
+		},
+		"node_modules/@jridgewell/gen-mapping": {
+			"version": "0.3.13",
+			"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+			"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+			"license": "MIT",
+			"dependencies": {
+				"@jridgewell/sourcemap-codec": "^1.5.0",
+				"@jridgewell/trace-mapping": "^0.3.24"
+			}
+		},
+		"node_modules/@jridgewell/remapping": {
+			"version": "2.3.5",
+			"resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
+			"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+			"license": "MIT",
+			"dependencies": {
+				"@jridgewell/gen-mapping": "^0.3.5",
+				"@jridgewell/trace-mapping": "^0.3.24"
+			}
+		},
+		"node_modules/@jridgewell/resolve-uri": {
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+			"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=6.0.0"
+			}
+		},
+		"node_modules/@jridgewell/sourcemap-codec": {
+			"version": "1.5.5",
+			"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+			"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+			"license": "MIT"
+		},
+		"node_modules/@jridgewell/trace-mapping": {
+			"version": "0.3.31",
+			"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+			"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+			"license": "MIT",
+			"dependencies": {
+				"@jridgewell/resolve-uri": "^3.1.0",
+				"@jridgewell/sourcemap-codec": "^1.4.14"
+			}
+		},
+		"node_modules/@layerstack/svelte-actions": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/@layerstack/svelte-actions/-/svelte-actions-1.0.1.tgz",
+			"integrity": "sha512-Tv8B3TeT7oaghx0R0I4avnSdfAT6GxEK+StL8k/hEaa009iNOIGFl3f76kfvNvPioQHAMFGtnWGLPHfsfD41nQ==",
+			"license": "MIT",
+			"dependencies": {
+				"@floating-ui/dom": "^1.6.13",
+				"@layerstack/utils": "1.0.1",
+				"d3-array": "^3.2.4",
+				"d3-scale": "^4.0.2",
+				"date-fns": "^4.1.0",
+				"lodash-es": "^4.17.21"
+			}
+		},
+		"node_modules/@layerstack/svelte-stores": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/@layerstack/svelte-stores/-/svelte-stores-1.0.2.tgz",
+			"integrity": "sha512-IxK0UKD0PVxg1VsyaR+n7NyJ+NlvyqvYYAp+J10lkjDQxm0yx58CaF2LBV08T22C3aY1iTlqJaatn/VHV4SoQg==",
+			"license": "MIT",
+			"dependencies": {
+				"@layerstack/utils": "1.0.1",
+				"d3-array": "^3.2.4",
+				"date-fns": "^4.1.0",
+				"immer": "^10.1.1",
+				"lodash-es": "^4.17.21",
+				"zod": "^3.24.2"
+			}
+		},
+		"node_modules/@layerstack/tailwind": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/@layerstack/tailwind/-/tailwind-1.0.1.tgz",
+			"integrity": "sha512-nlshEkUCfaV0zYzrFXVVYRnS8bnBjs4M7iui6l/tu6NeBBlxDivIyRraJkdYGCSL1lZHi6FqacLQ3eerHtz90A==",
+			"license": "MIT",
+			"dependencies": {
+				"@layerstack/utils": "^1.0.1",
+				"clsx": "^2.1.1",
+				"culori": "^4.0.1",
+				"d3-array": "^3.2.4",
+				"date-fns": "^4.1.0",
+				"lodash-es": "^4.17.21",
+				"tailwind-merge": "^2.5.4",
+				"tailwindcss": "^3.4.15"
+			}
+		},
+		"node_modules/@layerstack/tailwind/node_modules/jiti": {
+			"version": "1.21.7",
+			"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
+			"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
+			"license": "MIT",
+			"bin": {
+				"jiti": "bin/jiti.js"
+			}
+		},
+		"node_modules/@layerstack/tailwind/node_modules/tailwind-merge": {
+			"version": "2.6.1",
+			"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.1.tgz",
+			"integrity": "sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ==",
+			"license": "MIT",
+			"funding": {
+				"type": "github",
+				"url": "https://github.com/sponsors/dcastil"
+			}
+		},
+		"node_modules/@layerstack/tailwind/node_modules/tailwindcss": {
+			"version": "3.4.19",
+			"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz",
+			"integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==",
+			"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.7",
+				"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 || ^5.0 || ^6.0",
+				"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/@layerstack/utils": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/@layerstack/utils/-/utils-1.0.1.tgz",
+			"integrity": "sha512-sWP9b+SFMkJYMZyYFI01aLxbg2ZUrix6Tv+BCDmeOrcLNxtWFsMYAomMhALzTMHbb+Vis/ua5vXhpdNXEw8a2Q==",
+			"license": "MIT",
+			"dependencies": {
+				"d3-array": "^3.2.4",
+				"date-fns": "^4.1.0",
+				"lodash-es": "^4.17.21"
+			}
+		},
+		"node_modules/@napi-rs/wasm-runtime": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz",
+			"integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"dependencies": {
+				"@tybys/wasm-util": "^0.10.1"
+			},
+			"funding": {
+				"type": "github",
+				"url": "https://github.com/sponsors/Brooooooklyn"
+			},
+			"peerDependencies": {
+				"@emnapi/core": "^1.7.1",
+				"@emnapi/runtime": "^1.7.1"
+			}
+		},
+		"node_modules/@nodelib/fs.scandir": {
+			"version": "2.1.5",
+			"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+			"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+			"license": "MIT",
+			"dependencies": {
+				"@nodelib/fs.stat": "2.0.5",
+				"run-parallel": "^1.1.9"
+			},
+			"engines": {
+				"node": ">= 8"
+			}
+		},
+		"node_modules/@nodelib/fs.stat": {
+			"version": "2.0.5",
+			"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+			"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+			"license": "MIT",
+			"engines": {
+				"node": ">= 8"
+			}
+		},
+		"node_modules/@nodelib/fs.walk": {
+			"version": "1.2.8",
+			"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+			"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+			"license": "MIT",
+			"dependencies": {
+				"@nodelib/fs.scandir": "2.1.5",
+				"fastq": "^1.6.0"
+			},
+			"engines": {
+				"node": ">= 8"
+			}
+		},
+		"node_modules/@oxc-project/types": {
+			"version": "0.127.0",
+			"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.127.0.tgz",
+			"integrity": "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==",
+			"dev": true,
+			"license": "MIT",
+			"funding": {
+				"url": "https://github.com/sponsors/Boshen"
+			}
+		},
+		"node_modules/@polka/url": {
+			"version": "1.0.0-next.29",
+			"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
+			"integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/@rolldown/binding-android-arm64": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.17.tgz",
+			"integrity": "sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"android"
+			],
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/binding-darwin-arm64": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.17.tgz",
+			"integrity": "sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"darwin"
+			],
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/binding-darwin-x64": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.17.tgz",
+			"integrity": "sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"darwin"
+			],
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/binding-freebsd-x64": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.17.tgz",
+			"integrity": "sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"freebsd"
+			],
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.17.tgz",
+			"integrity": "sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==",
+			"cpu": [
+				"arm"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/binding-linux-arm64-gnu": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.17.tgz",
+			"integrity": "sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/binding-linux-arm64-musl": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.17.tgz",
+			"integrity": "sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/binding-linux-ppc64-gnu": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.17.tgz",
+			"integrity": "sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==",
+			"cpu": [
+				"ppc64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/binding-linux-s390x-gnu": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.17.tgz",
+			"integrity": "sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==",
+			"cpu": [
+				"s390x"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/binding-linux-x64-gnu": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.17.tgz",
+			"integrity": "sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/binding-linux-x64-musl": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.17.tgz",
+			"integrity": "sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/binding-openharmony-arm64": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.17.tgz",
+			"integrity": "sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"openharmony"
+			],
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/binding-wasm32-wasi": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.17.tgz",
+			"integrity": "sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==",
+			"cpu": [
+				"wasm32"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"dependencies": {
+				"@emnapi/core": "1.10.0",
+				"@emnapi/runtime": "1.10.0",
+				"@napi-rs/wasm-runtime": "^1.1.4"
+			},
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/binding-win32-arm64-msvc": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.17.tgz",
+			"integrity": "sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"win32"
+			],
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/binding-win32-x64-msvc": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.17.tgz",
+			"integrity": "sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"win32"
+			],
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			}
+		},
+		"node_modules/@rolldown/pluginutils": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.17.tgz",
+			"integrity": "sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/@standard-schema/spec": {
+			"version": "1.1.0",
+			"resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
+			"integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/@sveltejs/acorn-typescript": {
+			"version": "1.0.9",
+			"resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.9.tgz",
+			"integrity": "sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA==",
+			"license": "MIT",
+			"peerDependencies": {
+				"acorn": "^8.9.0"
+			}
+		},
+		"node_modules/@sveltejs/adapter-static": {
+			"version": "3.0.10",
+			"resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.10.tgz",
+			"integrity": "sha512-7D9lYFWJmB7zxZyTE/qxjksvMqzMuYrrsyh1f4AlZqeZeACPRySjbC3aFiY55wb1tWUaKOQG9PVbm74JcN2Iew==",
+			"dev": true,
+			"license": "MIT",
+			"peerDependencies": {
+				"@sveltejs/kit": "^2.0.0"
+			}
+		},
+		"node_modules/@sveltejs/kit": {
+			"version": "2.59.0",
+			"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.59.0.tgz",
+			"integrity": "sha512-WeJaGKvDf3uVQB4bnDHhM+BXCY34LC1v0HiPqnSpvNkjB54r8DAUP1rpk73s+5zprIirEKtUcVfgh6+fPODjzQ==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@standard-schema/spec": "^1.0.0",
+				"@sveltejs/acorn-typescript": "^1.0.5",
+				"@types/cookie": "^0.6.0",
+				"acorn": "^8.14.1",
+				"cookie": "^0.6.0",
+				"devalue": "^5.6.4",
+				"esm-env": "^1.2.2",
+				"kleur": "^4.1.5",
+				"magic-string": "^0.30.5",
+				"mrmime": "^2.0.0",
+				"set-cookie-parser": "^3.0.0",
+				"sirv": "^3.0.0"
+			},
+			"bin": {
+				"svelte-kit": "svelte-kit.js"
+			},
+			"engines": {
+				"node": ">=18.13"
+			},
+			"peerDependencies": {
+				"@opentelemetry/api": "^1.0.0",
+				"@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0",
+				"svelte": "^4.0.0 || ^5.0.0-next.0",
+				"typescript": "^5.3.3 || ^6.0.0",
+				"vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0"
+			},
+			"peerDependenciesMeta": {
+				"@opentelemetry/api": {
+					"optional": true
+				},
+				"typescript": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/@sveltejs/vite-plugin-svelte": {
+			"version": "7.0.0",
+			"resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-7.0.0.tgz",
+			"integrity": "sha512-ILXmxC7HAsnkK2eslgPetrqqW1BKSL7LktsFgqzNj83MaivMGZzluWq32m25j2mDOjmSKX7GGWahePhuEs7P/g==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"deepmerge": "^4.3.1",
+				"magic-string": "^0.30.21",
+				"obug": "^2.1.0",
+				"vitefu": "^1.1.2"
+			},
+			"engines": {
+				"node": "^20.19 || ^22.12 || >=24"
+			},
+			"peerDependencies": {
+				"svelte": "^5.46.4",
+				"vite": "^8.0.0-beta.7 || ^8.0.0"
+			}
+		},
+		"node_modules/@tailwindcss/node": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.4.tgz",
+			"integrity": "sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@jridgewell/remapping": "^2.3.5",
+				"enhanced-resolve": "^5.19.0",
+				"jiti": "^2.6.1",
+				"lightningcss": "1.32.0",
+				"magic-string": "^0.30.21",
+				"source-map-js": "^1.2.1",
+				"tailwindcss": "4.2.4"
+			}
+		},
+		"node_modules/@tailwindcss/oxide": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.4.tgz",
+			"integrity": "sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">= 20"
+			},
+			"optionalDependencies": {
+				"@tailwindcss/oxide-android-arm64": "4.2.4",
+				"@tailwindcss/oxide-darwin-arm64": "4.2.4",
+				"@tailwindcss/oxide-darwin-x64": "4.2.4",
+				"@tailwindcss/oxide-freebsd-x64": "4.2.4",
+				"@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.4",
+				"@tailwindcss/oxide-linux-arm64-gnu": "4.2.4",
+				"@tailwindcss/oxide-linux-arm64-musl": "4.2.4",
+				"@tailwindcss/oxide-linux-x64-gnu": "4.2.4",
+				"@tailwindcss/oxide-linux-x64-musl": "4.2.4",
+				"@tailwindcss/oxide-wasm32-wasi": "4.2.4",
+				"@tailwindcss/oxide-win32-arm64-msvc": "4.2.4",
+				"@tailwindcss/oxide-win32-x64-msvc": "4.2.4"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-android-arm64": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.4.tgz",
+			"integrity": "sha512-e7MOr1SAn9U8KlZzPi1ZXGZHeC5anY36qjNwmZv9pOJ8E4Q6jmD1vyEHkQFmNOIN7twGPEMXRHmitN4zCMN03g==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"android"
+			],
+			"engines": {
+				"node": ">= 20"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-darwin-arm64": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.4.tgz",
+			"integrity": "sha512-tSC/Kbqpz/5/o/C2sG7QvOxAKqyd10bq+ypZNf+9Fi2TvbVbv1zNpcEptcsU7DPROaSbVgUXmrzKhurFvo5eDg==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"darwin"
+			],
+			"engines": {
+				"node": ">= 20"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-darwin-x64": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.4.tgz",
+			"integrity": "sha512-yPyUXn3yO/ufR6+Kzv0t4fCg2qNr90jxXc5QqBpjlPNd0NqyDXcmQb/6weunH/MEDXW5dhyEi+agTDiqa3WsGg==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"darwin"
+			],
+			"engines": {
+				"node": ">= 20"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-freebsd-x64": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.4.tgz",
+			"integrity": "sha512-BoMIB4vMQtZsXdGLVc2z+P9DbETkiopogfWZKbWwM8b/1Vinbs4YcUwo+kM/KeLkX3Ygrf4/PsRndKaYhS8Eiw==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"freebsd"
+			],
+			"engines": {
+				"node": ">= 20"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.4.tgz",
+			"integrity": "sha512-7pIHBLTHYRAlS7V22JNuTh33yLH4VElwKtB3bwchK/UaKUPpQ0lPQiOWcbm4V3WP2I6fNIJ23vABIvoy2izdwA==",
+			"cpu": [
+				"arm"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 20"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.4.tgz",
+			"integrity": "sha512-+E4wxJ0ZGOzSH325reXTWB48l42i93kQqMvDyz5gqfRzRZ7faNhnmvlV4EPGJU3QJM/3Ab5jhJ5pCRUsKn6OQw==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 20"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-linux-arm64-musl": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.4.tgz",
+			"integrity": "sha512-bBADEGAbo4ASnppIziaQJelekCxdMaxisrk+fB7Thit72IBnALp9K6ffA2G4ruj90G9XRS2VQ6q2bCKbfFV82g==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 20"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-linux-x64-gnu": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.4.tgz",
+			"integrity": "sha512-7Mx25E4WTfnht0TVRTyC00j3i0M+EeFe7wguMDTlX4mRxafznw0CA8WJkFjWYH5BlgELd1kSjuU2JiPnNZbJDA==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 20"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-linux-x64-musl": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.4.tgz",
+			"integrity": "sha512-2wwJRF7nyhOR0hhHoChc04xngV3iS+akccHTGtz965FwF0up4b2lOdo6kI1EbDaEXKgvcrFBYcYQQ/rrnWFVfA==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"linux"
+			],
+			"engines": {
+				"node": ">= 20"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-wasm32-wasi": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.4.tgz",
+			"integrity": "sha512-FQsqApeor8Fo6gUEklzmaa9994orJZZDBAlQpK2Mq+DslRKFJeD6AjHpBQ0kZFQohVr8o85PPh8eOy86VlSCmw==",
+			"bundleDependencies": [
+				"@napi-rs/wasm-runtime",
+				"@emnapi/core",
+				"@emnapi/runtime",
+				"@tybys/wasm-util",
+				"@emnapi/wasi-threads",
+				"tslib"
+			],
+			"cpu": [
+				"wasm32"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"dependencies": {
+				"@emnapi/core": "^1.8.1",
+				"@emnapi/runtime": "^1.8.1",
+				"@emnapi/wasi-threads": "^1.1.0",
+				"@napi-rs/wasm-runtime": "^1.1.1",
+				"@tybys/wasm-util": "^0.10.1",
+				"tslib": "^2.8.1"
+			},
+			"engines": {
+				"node": ">=14.0.0"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.4.tgz",
+			"integrity": "sha512-L9BXqxC4ToVgwMFqj3pmZRqyHEztulpUJzCxUtLjobMCzTPsGt1Fa9enKbOpY2iIyVtaHNeNvAK8ERP/64sqGQ==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"win32"
+			],
+			"engines": {
+				"node": ">= 20"
+			}
+		},
+		"node_modules/@tailwindcss/oxide-win32-x64-msvc": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.4.tgz",
+			"integrity": "sha512-ESlKG0EpVJQwRjXDDa9rLvhEAh0mhP1sF7sap9dNZT0yyl9SAG6T7gdP09EH0vIv0UNTlo6jPWyujD6559fZvw==",
+			"cpu": [
+				"x64"
+			],
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"win32"
+			],
+			"engines": {
+				"node": ">= 20"
+			}
+		},
+		"node_modules/@tailwindcss/vite": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.4.tgz",
+			"integrity": "sha512-pCvohwOCspk3ZFn6eJzrrX3g4n2JY73H6MmYC87XfGPyTty4YsCjYTMArRZm/zOI8dIt3+EcrLHAFPe5A4bgtw==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@tailwindcss/node": "4.2.4",
+				"@tailwindcss/oxide": "4.2.4",
+				"tailwindcss": "4.2.4"
+			},
+			"peerDependencies": {
+				"vite": "^5.2.0 || ^6 || ^7 || ^8"
+			}
+		},
+		"node_modules/@tybys/wasm-util": {
+			"version": "0.10.1",
+			"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
+			"integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
+			"dev": true,
+			"license": "MIT",
+			"optional": true,
+			"dependencies": {
+				"tslib": "^2.4.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.8",
+			"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+			"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+			"license": "MIT"
+		},
+		"node_modules/@types/trusted-types": {
+			"version": "2.0.7",
+			"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+			"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+			"license": "MIT"
+		},
+		"node_modules/acorn": {
+			"version": "8.16.0",
+			"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
+			"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
+			"license": "MIT",
+			"bin": {
+				"acorn": "bin/acorn"
+			},
+			"engines": {
+				"node": ">=0.4.0"
+			}
+		},
+		"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==",
+			"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==",
+			"license": "ISC",
+			"dependencies": {
+				"normalize-path": "^3.0.0",
+				"picomatch": "^2.0.4"
+			},
+			"engines": {
+				"node": ">= 8"
+			}
+		},
+		"node_modules/anymatch/node_modules/picomatch": {
+			"version": "2.3.2",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+			"integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=8.6"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/jonschlinkert"
+			}
+		},
+		"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==",
+			"license": "MIT"
+		},
+		"node_modules/aria-query": {
+			"version": "5.3.1",
+			"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz",
+			"integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==",
+			"license": "Apache-2.0",
+			"engines": {
+				"node": ">= 0.4"
+			}
+		},
+		"node_modules/axobject-query": {
+			"version": "4.1.0",
+			"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
+			"integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
+			"license": "Apache-2.0",
+			"engines": {
+				"node": ">= 0.4"
+			}
+		},
+		"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==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=8"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/braces": {
+			"version": "3.0.3",
+			"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+			"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+			"license": "MIT",
+			"dependencies": {
+				"fill-range": "^7.1.1"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"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==",
+			"license": "MIT",
+			"engines": {
+				"node": ">= 6"
+			}
+		},
+		"node_modules/chokidar": {
+			"version": "3.6.0",
+			"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+			"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+			"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/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==",
+			"license": "ISC",
+			"dependencies": {
+				"is-glob": "^4.0.1"
+			},
+			"engines": {
+				"node": ">= 6"
+			}
+		},
+		"node_modules/clsx": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+			"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=6"
+			}
+		},
+		"node_modules/commander": {
+			"version": "7.2.0",
+			"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+			"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+			"license": "MIT",
+			"engines": {
+				"node": ">= 10"
+			}
+		},
+		"node_modules/cookie": {
+			"version": "0.6.0",
+			"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
+			"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">= 0.6"
+			}
+		},
+		"node_modules/cssesc": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+			"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+			"license": "MIT",
+			"bin": {
+				"cssesc": "bin/cssesc"
+			},
+			"engines": {
+				"node": ">=4"
+			}
+		},
+		"node_modules/culori": {
+			"version": "4.0.2",
+			"resolved": "https://registry.npmjs.org/culori/-/culori-4.0.2.tgz",
+			"integrity": "sha512-1+BhOB8ahCn4O0cep0Sh2l9KCOfOdY+BXJnKMHFFzDEouSr/el18QwXEMRlOj9UY5nCeA8UN3a/82rUWRBeyBw==",
+			"license": "MIT",
+			"engines": {
+				"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+			}
+		},
+		"node_modules/d3-array": {
+			"version": "3.2.4",
+			"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
+			"integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
+			"license": "ISC",
+			"dependencies": {
+				"internmap": "1 - 2"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-color": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
+			"integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
+			"license": "ISC",
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-delaunay": {
+			"version": "6.0.4",
+			"resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz",
+			"integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==",
+			"license": "ISC",
+			"dependencies": {
+				"delaunator": "5"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-dispatch": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
+			"integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
+			"license": "ISC",
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-dsv": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz",
+			"integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==",
+			"license": "ISC",
+			"dependencies": {
+				"commander": "7",
+				"iconv-lite": "0.6",
+				"rw": "1"
+			},
+			"bin": {
+				"csv2json": "bin/dsv2json.js",
+				"csv2tsv": "bin/dsv2dsv.js",
+				"dsv2dsv": "bin/dsv2dsv.js",
+				"dsv2json": "bin/dsv2json.js",
+				"json2csv": "bin/json2dsv.js",
+				"json2dsv": "bin/json2dsv.js",
+				"json2tsv": "bin/json2dsv.js",
+				"tsv2csv": "bin/dsv2dsv.js",
+				"tsv2json": "bin/dsv2json.js"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-force": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
+			"integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==",
+			"license": "ISC",
+			"dependencies": {
+				"d3-dispatch": "1 - 3",
+				"d3-quadtree": "1 - 3",
+				"d3-timer": "1 - 3"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-format": {
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz",
+			"integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==",
+			"license": "ISC",
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-geo": {
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz",
+			"integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==",
+			"license": "ISC",
+			"dependencies": {
+				"d3-array": "2.5.0 - 3"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-geo-voronoi": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/d3-geo-voronoi/-/d3-geo-voronoi-2.1.0.tgz",
+			"integrity": "sha512-kqE4yYuOjPbKdBXG0xztCacPwkVSK2REF1opSNrnqqtXJmNcM++UbwQ8SxvwP6IQTj9RvIjjK4qeiVsEfj0Z2Q==",
+			"license": "ISC",
+			"dependencies": {
+				"d3-array": "3",
+				"d3-delaunay": "6",
+				"d3-geo": "3",
+				"d3-tricontour": "1"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-hierarchy": {
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",
+			"integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==",
+			"license": "ISC",
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-interpolate": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
+			"integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
+			"license": "ISC",
+			"dependencies": {
+				"d3-color": "1 - 3"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-interpolate-path": {
+			"version": "2.3.0",
+			"resolved": "https://registry.npmjs.org/d3-interpolate-path/-/d3-interpolate-path-2.3.0.tgz",
+			"integrity": "sha512-tZYtGXxBmbgHsIc9Wms6LS5u4w6KbP8C09a4/ZYc4KLMYYqub57rRBUgpUr2CIarIrJEpdAWWxWQvofgaMpbKQ==",
+			"license": "BSD-3-Clause"
+		},
+		"node_modules/d3-path": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
+			"integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
+			"license": "ISC",
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-quadtree": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz",
+			"integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==",
+			"license": "ISC",
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-random": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz",
+			"integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==",
+			"license": "ISC",
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-sankey": {
+			"version": "0.12.3",
+			"resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz",
+			"integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==",
+			"license": "BSD-3-Clause",
+			"dependencies": {
+				"d3-array": "1 - 2",
+				"d3-shape": "^1.2.0"
+			}
+		},
+		"node_modules/d3-sankey/node_modules/d3-array": {
+			"version": "2.12.1",
+			"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
+			"integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
+			"license": "BSD-3-Clause",
+			"dependencies": {
+				"internmap": "^1.0.0"
+			}
+		},
+		"node_modules/d3-sankey/node_modules/d3-path": {
+			"version": "1.0.9",
+			"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
+			"integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==",
+			"license": "BSD-3-Clause"
+		},
+		"node_modules/d3-sankey/node_modules/d3-shape": {
+			"version": "1.3.7",
+			"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
+			"integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
+			"license": "BSD-3-Clause",
+			"dependencies": {
+				"d3-path": "1"
+			}
+		},
+		"node_modules/d3-sankey/node_modules/internmap": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz",
+			"integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==",
+			"license": "ISC"
+		},
+		"node_modules/d3-scale": {
+			"version": "4.0.2",
+			"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+			"integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
+			"license": "ISC",
+			"dependencies": {
+				"d3-array": "2.10.0 - 3",
+				"d3-format": "1 - 3",
+				"d3-interpolate": "1.2.0 - 3",
+				"d3-time": "2.1.1 - 3",
+				"d3-time-format": "2 - 4"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-scale-chromatic": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz",
+			"integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==",
+			"license": "ISC",
+			"dependencies": {
+				"d3-color": "1 - 3",
+				"d3-interpolate": "1 - 3"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-shape": {
+			"version": "3.2.0",
+			"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
+			"integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
+			"license": "ISC",
+			"dependencies": {
+				"d3-path": "^3.1.0"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-tile": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/d3-tile/-/d3-tile-1.0.0.tgz",
+			"integrity": "sha512-79fnTKpPMPDS5xQ0xuS9ir0165NEwwkFpe/DSOmc2Gl9ldYzKKRDWogmTTE8wAJ8NA7PMapNfEcyKhI9Lxdu5Q==",
+			"license": "BSD-3-Clause"
+		},
+		"node_modules/d3-time": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
+			"integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
+			"license": "ISC",
+			"dependencies": {
+				"d3-array": "2 - 3"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-time-format": {
+			"version": "4.1.0",
+			"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
+			"integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
+			"license": "ISC",
+			"dependencies": {
+				"d3-time": "1 - 3"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-timer": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
+			"integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
+			"license": "ISC",
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/d3-tricontour": {
+			"version": "1.1.0",
+			"resolved": "https://registry.npmjs.org/d3-tricontour/-/d3-tricontour-1.1.0.tgz",
+			"integrity": "sha512-G7gHKj89n2owmkGb6WX6ixcnQ0Kf/0wpa9VIh9DGdbHu8wdrlaHU4ir3/bFNERl8N8nn4G7e7qbtBG8N9caihQ==",
+			"license": "ISC",
+			"dependencies": {
+				"d3-delaunay": "6",
+				"d3-scale": "4"
+			},
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"node_modules/date-fns": {
+			"version": "4.1.0",
+			"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
+			"integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
+			"license": "MIT",
+			"funding": {
+				"type": "github",
+				"url": "https://github.com/sponsors/kossnocorp"
+			}
+		},
+		"node_modules/deepmerge": {
+			"version": "4.3.1",
+			"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+			"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/delaunator": {
+			"version": "5.1.0",
+			"resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.1.0.tgz",
+			"integrity": "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==",
+			"license": "ISC",
+			"dependencies": {
+				"robust-predicates": "^3.0.2"
+			}
+		},
+		"node_modules/detect-libc": {
+			"version": "2.1.2",
+			"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+			"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+			"dev": true,
+			"license": "Apache-2.0",
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/devalue": {
+			"version": "5.8.0",
+			"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.8.0.tgz",
+			"integrity": "sha512-2zA9pFEsnp7vWBZbXF5JAgAq0fsUIt/1XPbRiAmRV3lp/2C3upzH+sADiyy66aFCihoLEsrQHxNM5w1gIDfsBg==",
+			"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==",
+			"license": "Apache-2.0"
+		},
+		"node_modules/dlv": {
+			"version": "1.1.3",
+			"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
+			"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
+			"license": "MIT"
+		},
+		"node_modules/enhanced-resolve": {
+			"version": "5.21.0",
+			"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz",
+			"integrity": "sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"graceful-fs": "^4.2.4",
+				"tapable": "^2.3.3"
+			},
+			"engines": {
+				"node": ">=10.13.0"
+			}
+		},
+		"node_modules/es-errors": {
+			"version": "1.3.0",
+			"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+			"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+			"license": "MIT",
+			"engines": {
+				"node": ">= 0.4"
+			}
+		},
+		"node_modules/esm-env": {
+			"version": "1.2.2",
+			"resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz",
+			"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==",
+			"license": "MIT"
+		},
+		"node_modules/esrap": {
+			"version": "2.2.5",
+			"resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.5.tgz",
+			"integrity": "sha512-/yLB1538mag+dn0wsePTe8C0rDIjUOaJpMs2McodSzmM2msWcZsBSdRtg6HOBt0A/r82BN+Md3pgwSc/uWt2Ig==",
+			"license": "MIT",
+			"dependencies": {
+				"@jridgewell/sourcemap-codec": "^1.4.15"
+			},
+			"peerDependencies": {
+				"@typescript-eslint/types": "^8.2.0"
+			},
+			"peerDependenciesMeta": {
+				"@typescript-eslint/types": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/fast-glob": {
+			"version": "3.3.3",
+			"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+			"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+			"license": "MIT",
+			"dependencies": {
+				"@nodelib/fs.stat": "^2.0.2",
+				"@nodelib/fs.walk": "^1.2.3",
+				"glob-parent": "^5.1.2",
+				"merge2": "^1.3.0",
+				"micromatch": "^4.0.8"
+			},
+			"engines": {
+				"node": ">=8.6.0"
+			}
+		},
+		"node_modules/fast-glob/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==",
+			"license": "ISC",
+			"dependencies": {
+				"is-glob": "^4.0.1"
+			},
+			"engines": {
+				"node": ">= 6"
+			}
+		},
+		"node_modules/fastq": {
+			"version": "1.20.1",
+			"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
+			"integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
+			"license": "ISC",
+			"dependencies": {
+				"reusify": "^1.0.4"
+			}
+		},
+		"node_modules/fdir": {
+			"version": "6.5.0",
+			"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+			"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=12.0.0"
+			},
+			"peerDependencies": {
+				"picomatch": "^3 || ^4"
+			},
+			"peerDependenciesMeta": {
+				"picomatch": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/fill-range": {
+			"version": "7.1.1",
+			"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+			"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+			"license": "MIT",
+			"dependencies": {
+				"to-regex-range": "^5.0.1"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/fsevents": {
+			"version": "2.3.3",
+			"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+			"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+			"hasInstallScript": true,
+			"license": "MIT",
+			"optional": true,
+			"os": [
+				"darwin"
+			],
+			"engines": {
+				"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==",
+			"license": "MIT",
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/glob-parent": {
+			"version": "6.0.2",
+			"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+			"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+			"license": "ISC",
+			"dependencies": {
+				"is-glob": "^4.0.3"
+			},
+			"engines": {
+				"node": ">=10.13.0"
+			}
+		},
+		"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/hasown": {
+			"version": "2.0.3",
+			"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz",
+			"integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==",
+			"license": "MIT",
+			"dependencies": {
+				"function-bind": "^1.1.2"
+			},
+			"engines": {
+				"node": ">= 0.4"
+			}
+		},
+		"node_modules/iconv-lite": {
+			"version": "0.6.3",
+			"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+			"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+			"license": "MIT",
+			"dependencies": {
+				"safer-buffer": ">= 2.1.2 < 3.0.0"
+			},
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/immer": {
+			"version": "10.2.0",
+			"resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz",
+			"integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==",
+			"license": "MIT",
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/immer"
+			}
+		},
+		"node_modules/internmap": {
+			"version": "2.0.3",
+			"resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
+			"integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
+			"license": "ISC",
+			"engines": {
+				"node": ">=12"
+			}
+		},
+		"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==",
+			"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==",
+			"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",
+			"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/is-glob": {
+			"version": "4.0.3",
+			"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+			"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+			"license": "MIT",
+			"dependencies": {
+				"is-extglob": "^2.1.1"
+			},
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/is-number": {
+			"version": "7.0.0",
+			"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+			"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=0.12.0"
+			}
+		},
+		"node_modules/is-reference": {
+			"version": "3.0.3",
+			"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",
+			"integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
+			"license": "MIT",
+			"dependencies": {
+				"@types/estree": "^1.0.6"
+			}
+		},
+		"node_modules/jiti": {
+			"version": "2.6.1",
+			"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
+			"integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
+			"devOptional": true,
+			"license": "MIT",
+			"bin": {
+				"jiti": "lib/jiti-cli.mjs"
+			}
+		},
+		"node_modules/kleur": {
+			"version": "4.1.5",
+			"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+			"integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=6"
+			}
+		},
+		"node_modules/layercake": {
+			"version": "8.4.3",
+			"resolved": "https://registry.npmjs.org/layercake/-/layercake-8.4.3.tgz",
+			"integrity": "sha512-PZDduaPFxgHHkxlmsz5MVBECf6ZCT39DI3LgMVvuMwrmlrtlXwXUM/elJp46zHYzCE1j+cGyDuBDxnANv94tOQ==",
+			"license": "MIT",
+			"dependencies": {
+				"d3-array": "^3.2.4",
+				"d3-color": "^3.1.0",
+				"d3-scale": "^4.0.2",
+				"d3-shape": "^3.2.0"
+			},
+			"peerDependencies": {
+				"svelte": "3 - 5 || >=5.0.0-next.120",
+				"typescript": "^5.0.2"
+			}
+		},
+		"node_modules/layerchart": {
+			"version": "1.0.13",
+			"resolved": "https://registry.npmjs.org/layerchart/-/layerchart-1.0.13.tgz",
+			"integrity": "sha512-bjcrfyTdHtfYZn7yj26dvA1qUjM+R6+akp2VeBJ4JWKmDGhb5WvT9nMCs52Rb+gSd/omFq5SjZLz49MqlVljZw==",
+			"license": "MIT",
+			"dependencies": {
+				"@dagrejs/dagre": "^1.1.4",
+				"@layerstack/svelte-actions": "^1.0.1",
+				"@layerstack/svelte-stores": "^1.0.2",
+				"@layerstack/tailwind": "^1.0.1",
+				"@layerstack/utils": "^1.0.1",
+				"d3-array": "^3.2.4",
+				"d3-color": "^3.1.0",
+				"d3-delaunay": "^6.0.4",
+				"d3-dsv": "^3.0.1",
+				"d3-force": "^3.0.0",
+				"d3-geo": "^3.1.1",
+				"d3-geo-voronoi": "^2.1.0",
+				"d3-hierarchy": "^3.1.2",
+				"d3-interpolate": "^3.0.1",
+				"d3-interpolate-path": "^2.3.0",
+				"d3-path": "^3.1.0",
+				"d3-quadtree": "^3.0.1",
+				"d3-random": "^3.0.1",
+				"d3-sankey": "^0.12.3",
+				"d3-scale": "^4.0.2",
+				"d3-scale-chromatic": "^3.1.0",
+				"d3-shape": "^3.2.0",
+				"d3-tile": "^1.0.0",
+				"d3-time": "^3.1.0",
+				"date-fns": "^4.1.0",
+				"layercake": "8.4.3",
+				"lodash-es": "^4.17.21"
+			},
+			"peerDependencies": {
+				"svelte": "^3.56.0 || ^4.0.0 || ^5.0.0"
+			}
+		},
+		"node_modules/lightningcss": {
+			"version": "1.32.0",
+			"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
+			"integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
+			"dev": true,
+			"license": "MPL-2.0",
+			"dependencies": {
+				"detect-libc": "^2.0.3"
+			},
+			"engines": {
+				"node": ">= 12.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/parcel"
+			},
+			"optionalDependencies": {
+				"lightningcss-android-arm64": "1.32.0",
+				"lightningcss-darwin-arm64": "1.32.0",
+				"lightningcss-darwin-x64": "1.32.0",
+				"lightningcss-freebsd-x64": "1.32.0",
+				"lightningcss-linux-arm-gnueabihf": "1.32.0",
+				"lightningcss-linux-arm64-gnu": "1.32.0",
+				"lightningcss-linux-arm64-musl": "1.32.0",
+				"lightningcss-linux-x64-gnu": "1.32.0",
+				"lightningcss-linux-x64-musl": "1.32.0",
+				"lightningcss-win32-arm64-msvc": "1.32.0",
+				"lightningcss-win32-x64-msvc": "1.32.0"
+			}
+		},
+		"node_modules/lightningcss-android-arm64": {
+			"version": "1.32.0",
+			"resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
+			"integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
+			"cpu": [
+				"arm64"
+			],
+			"dev": true,
+			"license": "MPL-2.0",
+			"optional": true,
+			"os": [
+				"android"
+			],
+			"engines": {
+				"node": ">= 12.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/parcel"
+			}
+		},
+		"node_modules/lightningcss-darwin-arm64": {
+			"version": "1.32.0",
+			"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
+			"integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
+			"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.32.0",
+			"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
+			"integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
+			"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.32.0",
+			"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
+			"integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
+			"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.32.0",
+			"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
+			"integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
+			"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.32.0",
+			"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
+			"integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
+			"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.32.0",
+			"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
+			"integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
+			"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.32.0",
+			"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
+			"integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
+			"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.32.0",
+			"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
+			"integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
+			"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.32.0",
+			"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
+			"integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
+			"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.32.0",
+			"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
+			"integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
+			"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": "3.1.3",
+			"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+			"integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=14"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/antonk52"
+			}
+		},
+		"node_modules/lines-and-columns": {
+			"version": "1.2.4",
+			"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+			"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+			"license": "MIT"
+		},
+		"node_modules/locate-character": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
+			"integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
+			"license": "MIT"
+		},
+		"node_modules/lodash-es": {
+			"version": "4.18.1",
+			"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz",
+			"integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==",
+			"license": "MIT"
+		},
+		"node_modules/lucide-svelte": {
+			"version": "1.0.1",
+			"resolved": "https://registry.npmjs.org/lucide-svelte/-/lucide-svelte-1.0.1.tgz",
+			"integrity": "sha512-WvzZgk0pqzgda+AErLvgWxHkfg/+GgUwqKMRHvzt0IqyMdmyEDzDCk3Z+Wo/3y753oIgx8u9Q4eUbWkghFa8Jg==",
+			"license": "ISC",
+			"peerDependencies": {
+				"svelte": "^3 || ^4 || ^5.0.0-next.42"
+			}
+		},
+		"node_modules/magic-string": {
+			"version": "0.30.21",
+			"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+			"integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+			"license": "MIT",
+			"dependencies": {
+				"@jridgewell/sourcemap-codec": "^1.5.5"
+			}
+		},
+		"node_modules/merge2": {
+			"version": "1.4.1",
+			"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+			"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+			"license": "MIT",
+			"engines": {
+				"node": ">= 8"
+			}
+		},
+		"node_modules/micromatch": {
+			"version": "4.0.8",
+			"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+			"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+			"license": "MIT",
+			"dependencies": {
+				"braces": "^3.0.3",
+				"picomatch": "^2.3.1"
+			},
+			"engines": {
+				"node": ">=8.6"
+			}
+		},
+		"node_modules/micromatch/node_modules/picomatch": {
+			"version": "2.3.2",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+			"integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=8.6"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/jonschlinkert"
+			}
+		},
+		"node_modules/mrmime": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
+			"integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=10"
+			}
+		},
+		"node_modules/mz": {
+			"version": "2.7.0",
+			"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+			"integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+			"license": "MIT",
+			"dependencies": {
+				"any-promise": "^1.0.0",
+				"object-assign": "^4.0.1",
+				"thenify-all": "^1.0.0"
+			}
+		},
+		"node_modules/nanoid": {
+			"version": "3.3.12",
+			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
+			"integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
+			"funding": [
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/ai"
+				}
+			],
+			"license": "MIT",
+			"bin": {
+				"nanoid": "bin/nanoid.cjs"
+			},
+			"engines": {
+				"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+			}
+		},
+		"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==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/object-assign": {
+			"version": "4.1.1",
+			"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+			"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+			"license": "MIT",
+			"engines": {
+				"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==",
+			"license": "MIT",
+			"engines": {
+				"node": ">= 6"
+			}
+		},
+		"node_modules/obug": {
+			"version": "2.1.1",
+			"resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz",
+			"integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==",
+			"dev": true,
+			"funding": [
+				"https://github.com/sponsors/sxzz",
+				"https://opencollective.com/debug"
+			],
+			"license": "MIT"
+		},
+		"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==",
+			"license": "MIT"
+		},
+		"node_modules/picocolors": {
+			"version": "1.1.1",
+			"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+			"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+			"license": "ISC"
+		},
+		"node_modules/picomatch": {
+			"version": "4.0.4",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+			"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=12"
+			},
+			"funding": {
+				"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==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/pirates": {
+			"version": "4.0.7",
+			"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
+			"integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
+			"license": "MIT",
+			"engines": {
+				"node": ">= 6"
+			}
+		},
+		"node_modules/postcss": {
+			"version": "8.5.13",
+			"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.13.tgz",
+			"integrity": "sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag==",
+			"funding": [
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/postcss/"
+				},
+				{
+					"type": "tidelift",
+					"url": "https://tidelift.com/funding/github/npm/postcss"
+				},
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/ai"
+				}
+			],
+			"license": "MIT",
+			"dependencies": {
+				"nanoid": "^3.3.11",
+				"picocolors": "^1.1.1",
+				"source-map-js": "^1.2.1"
+			},
+			"engines": {
+				"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==",
+			"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.1.0",
+			"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz",
+			"integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
+			"funding": [
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/postcss/"
+				},
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/ai"
+				}
+			],
+			"license": "MIT",
+			"dependencies": {
+				"camelcase-css": "^2.0.1"
+			},
+			"engines": {
+				"node": "^12 || ^14 || >= 16"
+			},
+			"peerDependencies": {
+				"postcss": "^8.4.21"
+			}
+		},
+		"node_modules/postcss-load-config": {
+			"version": "6.0.1",
+			"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
+			"integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
+			"funding": [
+				{
+					"type": "opencollective",
+					"url": "https://opencollective.com/postcss/"
+				},
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/ai"
+				}
+			],
+			"license": "MIT",
+			"dependencies": {
+				"lilconfig": "^3.1.1"
+			},
+			"engines": {
+				"node": ">= 18"
+			},
+			"peerDependencies": {
+				"jiti": ">=1.21.0",
+				"postcss": ">=8.0.9",
+				"tsx": "^4.8.1",
+				"yaml": "^2.4.2"
+			},
+			"peerDependenciesMeta": {
+				"jiti": {
+					"optional": true
+				},
+				"postcss": {
+					"optional": true
+				},
+				"tsx": {
+					"optional": true
+				},
+				"yaml": {
+					"optional": true
+				}
+			}
+		},
+		"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==",
+			"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-selector-parser": {
+			"version": "6.1.2",
+			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+			"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+			"license": "MIT",
+			"dependencies": {
+				"cssesc": "^3.0.0",
+				"util-deprecate": "^1.0.2"
+			},
+			"engines": {
+				"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==",
+			"license": "MIT"
+		},
+		"node_modules/prettier": {
+			"version": "3.8.3",
+			"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz",
+			"integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==",
+			"dev": true,
+			"license": "MIT",
+			"bin": {
+				"prettier": "bin/prettier.cjs"
+			},
+			"engines": {
+				"node": ">=14"
+			},
+			"funding": {
+				"url": "https://github.com/prettier/prettier?sponsor=1"
+			}
+		},
+		"node_modules/prettier-plugin-svelte": {
+			"version": "3.5.1",
+			"resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.5.1.tgz",
+			"integrity": "sha512-65+fr5+cgIKWKiqM1Doum4uX6bY8iFCdztvvp2RcF+AJoieaw9kJOFMNcJo/bkmKYsxFaM9OsVZK/gWauG/5mg==",
+			"dev": true,
+			"license": "MIT",
+			"peerDependencies": {
+				"prettier": "^3.0.0",
+				"svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0"
+			}
+		},
+		"node_modules/prettier-plugin-tailwindcss": {
+			"version": "0.7.4",
+			"resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.7.4.tgz",
+			"integrity": "sha512-UKii4RjY05SNt/WQi6/NcOn/LsT0/ILLXsxygjbRg5/YZelsSu5jTqorYHPDGq4nZy5q5hpCu+XdGZ1xaJEQgw==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=20.19"
+			},
+			"peerDependencies": {
+				"@ianvs/prettier-plugin-sort-imports": "*",
+				"@prettier/plugin-hermes": "*",
+				"@prettier/plugin-oxc": "*",
+				"@prettier/plugin-pug": "*",
+				"@shopify/prettier-plugin-liquid": "*",
+				"@trivago/prettier-plugin-sort-imports": "*",
+				"@zackad/prettier-plugin-twig": "*",
+				"prettier": "^3.0",
+				"prettier-plugin-astro": "*",
+				"prettier-plugin-css-order": "*",
+				"prettier-plugin-jsdoc": "*",
+				"prettier-plugin-marko": "*",
+				"prettier-plugin-multiline-arrays": "*",
+				"prettier-plugin-organize-attributes": "*",
+				"prettier-plugin-organize-imports": "*",
+				"prettier-plugin-sort-imports": "*",
+				"prettier-plugin-svelte": "*"
+			},
+			"peerDependenciesMeta": {
+				"@ianvs/prettier-plugin-sort-imports": {
+					"optional": true
+				},
+				"@prettier/plugin-hermes": {
+					"optional": true
+				},
+				"@prettier/plugin-oxc": {
+					"optional": true
+				},
+				"@prettier/plugin-pug": {
+					"optional": true
+				},
+				"@shopify/prettier-plugin-liquid": {
+					"optional": true
+				},
+				"@trivago/prettier-plugin-sort-imports": {
+					"optional": true
+				},
+				"@zackad/prettier-plugin-twig": {
+					"optional": true
+				},
+				"prettier-plugin-astro": {
+					"optional": true
+				},
+				"prettier-plugin-css-order": {
+					"optional": true
+				},
+				"prettier-plugin-jsdoc": {
+					"optional": true
+				},
+				"prettier-plugin-marko": {
+					"optional": true
+				},
+				"prettier-plugin-multiline-arrays": {
+					"optional": true
+				},
+				"prettier-plugin-organize-attributes": {
+					"optional": true
+				},
+				"prettier-plugin-organize-imports": {
+					"optional": true
+				},
+				"prettier-plugin-sort-imports": {
+					"optional": true
+				},
+				"prettier-plugin-svelte": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/queue-microtask": {
+			"version": "1.2.3",
+			"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+			"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+			"funding": [
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/feross"
+				},
+				{
+					"type": "patreon",
+					"url": "https://www.patreon.com/feross"
+				},
+				{
+					"type": "consulting",
+					"url": "https://feross.org/support"
+				}
+			],
+			"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==",
+			"license": "MIT",
+			"dependencies": {
+				"pify": "^2.3.0"
+			}
+		},
+		"node_modules/readdirp": {
+			"version": "3.6.0",
+			"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+			"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+			"license": "MIT",
+			"dependencies": {
+				"picomatch": "^2.2.1"
+			},
+			"engines": {
+				"node": ">=8.10.0"
+			}
+		},
+		"node_modules/readdirp/node_modules/picomatch": {
+			"version": "2.3.2",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+			"integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=8.6"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/jonschlinkert"
+			}
+		},
+		"node_modules/resolve": {
+			"version": "1.22.12",
+			"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz",
+			"integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==",
+			"license": "MIT",
+			"dependencies": {
+				"es-errors": "^1.3.0",
+				"is-core-module": "^2.16.1",
+				"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/reusify": {
+			"version": "1.1.0",
+			"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+			"integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+			"license": "MIT",
+			"engines": {
+				"iojs": ">=1.0.0",
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/robust-predicates": {
+			"version": "3.0.3",
+			"resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz",
+			"integrity": "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==",
+			"license": "Unlicense"
+		},
+		"node_modules/rolldown": {
+			"version": "1.0.0-rc.17",
+			"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.17.tgz",
+			"integrity": "sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@oxc-project/types": "=0.127.0",
+				"@rolldown/pluginutils": "1.0.0-rc.17"
+			},
+			"bin": {
+				"rolldown": "bin/cli.mjs"
+			},
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			},
+			"optionalDependencies": {
+				"@rolldown/binding-android-arm64": "1.0.0-rc.17",
+				"@rolldown/binding-darwin-arm64": "1.0.0-rc.17",
+				"@rolldown/binding-darwin-x64": "1.0.0-rc.17",
+				"@rolldown/binding-freebsd-x64": "1.0.0-rc.17",
+				"@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.17",
+				"@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.17",
+				"@rolldown/binding-linux-arm64-musl": "1.0.0-rc.17",
+				"@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.17",
+				"@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.17",
+				"@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17",
+				"@rolldown/binding-linux-x64-musl": "1.0.0-rc.17",
+				"@rolldown/binding-openharmony-arm64": "1.0.0-rc.17",
+				"@rolldown/binding-wasm32-wasi": "1.0.0-rc.17",
+				"@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.17",
+				"@rolldown/binding-win32-x64-msvc": "1.0.0-rc.17"
+			}
+		},
+		"node_modules/run-parallel": {
+			"version": "1.2.0",
+			"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+			"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+			"funding": [
+				{
+					"type": "github",
+					"url": "https://github.com/sponsors/feross"
+				},
+				{
+					"type": "patreon",
+					"url": "https://www.patreon.com/feross"
+				},
+				{
+					"type": "consulting",
+					"url": "https://feross.org/support"
+				}
+			],
+			"license": "MIT",
+			"dependencies": {
+				"queue-microtask": "^1.2.2"
+			}
+		},
+		"node_modules/rw": {
+			"version": "1.3.3",
+			"resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
+			"integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==",
+			"license": "BSD-3-Clause"
+		},
+		"node_modules/safer-buffer": {
+			"version": "2.1.2",
+			"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+			"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+			"license": "MIT"
+		},
+		"node_modules/set-cookie-parser": {
+			"version": "3.1.0",
+			"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.0.tgz",
+			"integrity": "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/sirv": {
+			"version": "3.0.2",
+			"resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz",
+			"integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"@polka/url": "^1.0.0-next.24",
+				"mrmime": "^2.0.0",
+				"totalist": "^3.0.0"
+			},
+			"engines": {
+				"node": ">=18"
+			}
+		},
+		"node_modules/source-map-js": {
+			"version": "1.2.1",
+			"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+			"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+			"license": "BSD-3-Clause",
+			"engines": {
+				"node": ">=0.10.0"
+			}
+		},
+		"node_modules/sucrase": {
+			"version": "3.35.1",
+			"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz",
+			"integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==",
+			"license": "MIT",
+			"dependencies": {
+				"@jridgewell/gen-mapping": "^0.3.2",
+				"commander": "^4.0.0",
+				"lines-and-columns": "^1.1.6",
+				"mz": "^2.7.0",
+				"pirates": "^4.0.1",
+				"tinyglobby": "^0.2.11",
+				"ts-interface-checker": "^0.1.9"
+			},
+			"bin": {
+				"sucrase": "bin/sucrase",
+				"sucrase-node": "bin/sucrase-node"
+			},
+			"engines": {
+				"node": ">=16 || 14 >=14.17"
+			}
+		},
+		"node_modules/sucrase/node_modules/commander": {
+			"version": "4.1.1",
+			"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+			"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+			"license": "MIT",
+			"engines": {
+				"node": ">= 6"
+			}
+		},
+		"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==",
+			"license": "MIT",
+			"engines": {
+				"node": ">= 0.4"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
+		},
+		"node_modules/svelte": {
+			"version": "5.55.5",
+			"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.55.5.tgz",
+			"integrity": "sha512-2uCs/LZ9us+AktdzYJM8OcxQ8qnPS1kpaO7syGT/MgO+6Qr1Ybl+TqPq+97u7PHqmmMlye5ZkoyXONy5mjjAbw==",
+			"license": "MIT",
+			"dependencies": {
+				"@jridgewell/remapping": "^2.3.4",
+				"@jridgewell/sourcemap-codec": "^1.5.0",
+				"@sveltejs/acorn-typescript": "^1.0.5",
+				"@types/estree": "^1.0.5",
+				"@types/trusted-types": "^2.0.7",
+				"acorn": "^8.12.1",
+				"aria-query": "5.3.1",
+				"axobject-query": "^4.1.0",
+				"clsx": "^2.1.1",
+				"devalue": "^5.6.4",
+				"esm-env": "^1.2.1",
+				"esrap": "^2.2.4",
+				"is-reference": "^3.0.3",
+				"locate-character": "^3.0.0",
+				"magic-string": "^0.30.11",
+				"zimmerframe": "^1.1.2"
+			},
+			"engines": {
+				"node": ">=18"
+			}
+		},
+		"node_modules/tailwind-merge": {
+			"version": "3.5.0",
+			"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.5.0.tgz",
+			"integrity": "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==",
+			"license": "MIT",
+			"funding": {
+				"type": "github",
+				"url": "https://github.com/sponsors/dcastil"
+			}
+		},
+		"node_modules/tailwindcss": {
+			"version": "4.2.4",
+			"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.4.tgz",
+			"integrity": "sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA==",
+			"dev": true,
+			"license": "MIT"
+		},
+		"node_modules/tapable": {
+			"version": "2.3.3",
+			"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz",
+			"integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=6"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/webpack"
+			}
+		},
+		"node_modules/thenify": {
+			"version": "3.3.1",
+			"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+			"integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+			"license": "MIT",
+			"dependencies": {
+				"any-promise": "^1.0.0"
+			}
+		},
+		"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==",
+			"license": "MIT",
+			"dependencies": {
+				"thenify": ">= 3.1.0 < 4"
+			},
+			"engines": {
+				"node": ">=0.8"
+			}
+		},
+		"node_modules/tinyglobby": {
+			"version": "0.2.16",
+			"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
+			"integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
+			"license": "MIT",
+			"dependencies": {
+				"fdir": "^6.5.0",
+				"picomatch": "^4.0.4"
+			},
+			"engines": {
+				"node": ">=12.0.0"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/SuperchupuDev"
+			}
+		},
+		"node_modules/to-regex-range": {
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+			"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+			"license": "MIT",
+			"dependencies": {
+				"is-number": "^7.0.0"
+			},
+			"engines": {
+				"node": ">=8.0"
+			}
+		},
+		"node_modules/totalist": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
+			"integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
+			"dev": true,
+			"license": "MIT",
+			"engines": {
+				"node": ">=6"
+			}
+		},
+		"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==",
+			"license": "Apache-2.0"
+		},
+		"node_modules/tslib": {
+			"version": "2.8.1",
+			"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+			"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+			"dev": true,
+			"license": "0BSD",
+			"optional": true
+		},
+		"node_modules/typescript": {
+			"version": "5.9.3",
+			"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+			"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+			"license": "Apache-2.0",
+			"peer": true,
+			"bin": {
+				"tsc": "bin/tsc",
+				"tsserver": "bin/tsserver"
+			},
+			"engines": {
+				"node": ">=14.17"
+			}
+		},
+		"node_modules/util-deprecate": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+			"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+			"license": "MIT"
+		},
+		"node_modules/vite": {
+			"version": "8.0.10",
+			"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.10.tgz",
+			"integrity": "sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==",
+			"dev": true,
+			"license": "MIT",
+			"dependencies": {
+				"lightningcss": "^1.32.0",
+				"picomatch": "^4.0.4",
+				"postcss": "^8.5.10",
+				"rolldown": "1.0.0-rc.17",
+				"tinyglobby": "^0.2.16"
+			},
+			"bin": {
+				"vite": "bin/vite.js"
+			},
+			"engines": {
+				"node": "^20.19.0 || >=22.12.0"
+			},
+			"funding": {
+				"url": "https://github.com/vitejs/vite?sponsor=1"
+			},
+			"optionalDependencies": {
+				"fsevents": "~2.3.3"
+			},
+			"peerDependencies": {
+				"@types/node": "^20.19.0 || >=22.12.0",
+				"@vitejs/devtools": "^0.1.0",
+				"esbuild": "^0.27.0 || ^0.28.0",
+				"jiti": ">=1.21.0",
+				"less": "^4.0.0",
+				"sass": "^1.70.0",
+				"sass-embedded": "^1.70.0",
+				"stylus": ">=0.54.8",
+				"sugarss": "^5.0.0",
+				"terser": "^5.16.0",
+				"tsx": "^4.8.1",
+				"yaml": "^2.4.2"
+			},
+			"peerDependenciesMeta": {
+				"@types/node": {
+					"optional": true
+				},
+				"@vitejs/devtools": {
+					"optional": true
+				},
+				"esbuild": {
+					"optional": true
+				},
+				"jiti": {
+					"optional": true
+				},
+				"less": {
+					"optional": true
+				},
+				"sass": {
+					"optional": true
+				},
+				"sass-embedded": {
+					"optional": true
+				},
+				"stylus": {
+					"optional": true
+				},
+				"sugarss": {
+					"optional": true
+				},
+				"terser": {
+					"optional": true
+				},
+				"tsx": {
+					"optional": true
+				},
+				"yaml": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/vitefu": {
+			"version": "1.1.3",
+			"resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz",
+			"integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==",
+			"dev": true,
+			"license": "MIT",
+			"workspaces": [
+				"tests/deps/*",
+				"tests/projects/*",
+				"tests/projects/workspace/packages/*"
+			],
+			"peerDependencies": {
+				"vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
+			},
+			"peerDependenciesMeta": {
+				"vite": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/zimmerframe": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz",
+			"integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==",
+			"license": "MIT"
+		},
+		"node_modules/zod": {
+			"version": "3.25.76",
+			"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+			"integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+			"license": "MIT",
+			"funding": {
+				"url": "https://github.com/sponsors/colinhacks"
+			}
+		}
+	}
+}

+ 37 - 0
package.json

@@ -0,0 +1,37 @@
+{
+	"name": "nettown-front",
+	"private": true,
+	"version": "0.0.1",
+	"type": "module",
+	"scripts": {
+		"dev": "vite dev",
+		"build": "vite build",
+		"preview": "vite preview",
+		"prepare": "svelte-kit sync || echo ''",
+		"lint": "prettier --check .",
+		"format": "prettier --write ."
+	},
+	"devDependencies": {
+		"@sveltejs/adapter-static": "^3.0.10",
+		"@sveltejs/kit": "^2.57.0",
+		"@sveltejs/vite-plugin-svelte": "^7.0.0",
+		"@tailwindcss/vite": "^4.2.2",
+		"prettier": "^3.8.1",
+		"prettier-plugin-svelte": "^3.5.1",
+		"prettier-plugin-tailwindcss": "^0.7.2",
+		"svelte": "^5.55.2",
+		"tailwindcss": "^4.2.2",
+		"vite": "^8.0.7"
+	},
+	"dependencies": {
+		"clsx": "^2.1.1",
+		"d3-array": "^3.2.4",
+		"d3-format": "^3.1.2",
+		"d3-scale": "^4.0.2",
+		"d3-shape": "^3.2.0",
+		"d3-time-format": "^4.1.0",
+		"layerchart": "^1.0.13",
+		"lucide-svelte": "^1.0.1",
+		"tailwind-merge": "^3.5.0"
+	}
+}

+ 12 - 0
src/app.html

@@ -0,0 +1,12 @@
+<!doctype html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8" />
+		<meta name="viewport" content="width=device-width, initial-scale=1" />
+		<meta name="text-scale" content="scale" />
+		%sveltekit.head%
+	</head>
+	<body data-sveltekit-preload-data="hover">
+		<div style="display: contents">%sveltekit.body%</div>
+	</body>
+</html>

BIN
src/lib/assets/favicon.ico


+ 16 - 0
src/lib/assets/images/nettown_black_logo.svg.svg

@@ -0,0 +1,16 @@
+<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 416" width="1920" height="416">
+	<style>
+		.s0 { fill: #2b2929 } 
+		.s1 { fill: #e73c37 } 
+	</style>
+	<g>
+		<path class="s0" d="m491.55 317.91v-177.77c0-26.94 17.43-40.88 36.12-40.88 11.72 0 24.4 4.75 32.64 16.79l43.1 62.11c21.86 31.69 29.47 42.14 38.34 62.74 0.95 2.54 1.58 3.49 2.22 3.49 0.95 0 1.58-1.58-0.63-8.24-3.8-12.36-4.44-28.84-4.44-63.38v-68.76h55.45v177.77c0 27.25-16.16 40.88-35.49 40.88-12.04 0-25.03-5.07-33.27-17.11l-42.14-60.84c-22.18-32-31.05-41.83-38.98-62.74-0.95-2.53-1.9-3.49-2.53-3.49-0.95 0-1.58 1.58 0.63 8.24 4.12 12.36 4.12 28.84 4.12 63.38v67.81z"/>
+		<path class="s0" d="m712.23 236.79c0-45.63 34.22-83.66 84.29-83.66 50.07 0 80.8 38.66 80.8 81.12v14.26h-110.27c3.8 15.84 15.84 25.35 33.27 25.35 15.21 0 27.25-8.24 32.95-20.6l43.73 21.86c-13.63 29.47-40.56 47.22-76.05 47.22-50.7 0-88.73-33.59-88.73-85.56zm108.38-17.75c-2.53-8.87-11.41-17.11-24.72-17.11-13.31 0-22.82 7.92-26.3 17.11z"/>
+		<path class="s0" d="m912.18 250.42l0.96-43.41h-27.89v-47.53h26.93v-39.61h57.04v39.61h51.97v47.53h-51.97v41.51c0 15.21 9.19 23.77 24.08 23.77 7.92 0 20.28-2.22 27.89-6.34v50.38c-7.92 4.44-22.5 6.65-33.27 6.65-51.65 0-75.73-30.42-75.73-72.57z"/>
+		<path class="s0" d="m1233.6 157.89h-60.52v160.02h-58.62v-160.02h-60.52v-53.87h179.67v53.87z"/>
+		<path class="s0" d="m1208.97 238.37c0-45.95 37.71-83.97 87.14-83.97 49.43 0 87.14 38.03 87.14 83.97 0 45.94-37.71 84.29-87.14 84.29-49.43 0-87.14-38.03-87.14-84.29zm117.25 0.32c0-16.79-12.04-30.74-30.1-30.74-18.06 0-30.1 13.94-30.1 30.74 0 16.8 12.04 30.42 30.1 30.42 18.06 0 30.1-13.94 30.1-30.42z"/>
+		<path class="s0" d="m1383.35 159.47h53.23l16.79 67.81c5.07 19.96 6.66 33.91 6.66 38.03 0 1.27 0.63 1.9 1.27 1.9 0.64 0 1.27-0.63 1.27-1.9 0-4.12 3.49-18.38 8.24-38.03l8.87-36.12c6.02-24.08 20.6-37.07 42.78-37.07 22.18 0 34.54 12.04 40.24 37.07l8.24 36.12c4.44 19.96 8.24 33.91 8.24 38.03 0 1.27 0.63 1.9 1.27 1.9 0.64 0 1.27-0.63 1.27-1.9 0-4.12 2.22-18.06 6.66-38.03l15.53-67.81h53.23l-29.79 125.17c-6.02 25.67-21.86 38.34-44.05 38.34-22.19 0-42.14-13.31-47.21-38.34l-6.66-33.27c-1.9-10.14-4.75-27.25-6.34-35.17-0.32-1.59-0.63-2.53-1.9-2.53-1.27 0-1.58 1.27-1.9 2.53-1.9 7.92-5.7 25.03-7.92 35.17l-7.29 33.27c-5.39 25.03-19.65 38.34-42.78 38.34-23.13 0-42.14-12.67-48.16-38.34z"/>
+		<path class="s0" d="m1718.92 246.93v70.98h-57.04v-77.95c0-46.58 27.25-85.24 85.87-85.24 58.62 0 85.87 38.66 85.87 85.24v77.95h-57.04v-70.98c0-19.96-7.92-36.76-28.84-36.76-20.92 0-28.84 16.79-28.84 36.76z"/>
+	</g>
+	<path class="s1" d="m370.74 68.08h-114.05c-15.2 0-27.52 12.32-27.52 27.52v97.79l-99.73-80.2q-2.37-1.91-5.2-3.06c-8.5-3.46-18.12-2.47-25.73 2.65-7.61 5.12-12.16 13.66-12.16 22.83v179.24c0 15.2 12.32 27.52 27.52 27.52h129.39c15.2 0 27.52-12.32 27.52-27.52v-34.6l84.41 62.76c4.6 3.15 9.97 4.81 15.53 4.81 4.45 0 8.89-1.1 12.84-3.19 9.05-4.78 14.68-14.1 14.68-24.34v-224.69c0-15.2-12.32-27.52-27.52-27.52z"/>
+</svg>

+ 24 - 0
src/lib/assets/images/nettown_white_logo.svg

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg id="Camada_1" data-name="Camada 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 415.91">
+  <defs>
+    <style>
+      .cls-1 {
+        fill: #e73c37;
+      }
+
+      .cls-2 {
+        fill: #efefef;
+      }
+    </style>
+  </defs>
+  <g>
+    <path class="cls-2" d="M491.55,317.91v-177.77c0-26.94,17.43-40.88,36.12-40.88,11.72,0,24.4,4.75,32.64,16.79l43.1,62.11c21.86,31.69,29.47,42.14,38.34,62.74.95,2.54,1.58,3.49,2.22,3.49.95,0,1.58-1.58-.63-8.24-3.8-12.36-4.44-28.84-4.44-63.38v-68.76h55.45v177.77c0,27.25-16.16,40.88-35.49,40.88-12.04,0-25.03-5.07-33.27-17.11l-42.14-60.84c-22.18-32-31.05-41.83-38.98-62.74-.95-2.53-1.9-3.49-2.53-3.49-.95,0-1.58,1.58.63,8.24,4.12,12.36,4.12,28.84,4.12,63.38v67.81h-55.14Z"/>
+    <path class="cls-2" d="M712.23,236.79c0-45.63,34.22-83.66,84.29-83.66s80.8,38.66,80.8,81.12v14.26h-110.27c3.8,15.84,15.84,25.35,33.27,25.35,15.21,0,27.25-8.24,32.95-20.6l43.73,21.86c-13.63,29.47-40.56,47.22-76.05,47.22-50.7,0-88.73-33.59-88.73-85.56ZM820.61,219.04c-2.53-8.87-11.41-17.11-24.72-17.11s-22.82,7.92-26.3,17.11h51.02Z"/>
+    <path class="cls-2" d="M912.18,250.42l.96-43.41h-27.89v-47.53h26.93v-39.61h57.04v39.61h51.97v47.53h-51.97v41.51c0,15.21,9.19,23.77,24.08,23.77,7.92,0,20.28-2.22,27.89-6.34v50.38c-7.92,4.44-22.5,6.65-33.27,6.65-51.65,0-75.73-30.42-75.73-72.57Z"/>
+    <path class="cls-2" d="M1233.6,157.89h-60.52v160.02h-58.62v-160.02h-60.52v-53.87h179.67v53.87Z"/>
+    <path class="cls-2" d="M1208.97,238.37c0-45.95,37.71-83.97,87.14-83.97s87.14,38.03,87.14,83.97-37.71,84.29-87.14,84.29-87.14-38.03-87.14-84.29ZM1326.22,238.69c0-16.79-12.04-30.74-30.1-30.74s-30.1,13.94-30.1,30.74,12.04,30.42,30.1,30.42,30.1-13.94,30.1-30.42Z"/>
+    <path class="cls-2" d="M1383.35,159.47h53.23l16.79,67.81c5.07,19.96,6.66,33.91,6.66,38.03,0,1.27.63,1.9,1.27,1.9s1.27-.63,1.27-1.9c0-4.12,3.49-18.38,8.24-38.03l8.87-36.12c6.02-24.08,20.6-37.07,42.78-37.07s34.54,12.04,40.24,37.07l8.24,36.12c4.44,19.96,8.24,33.91,8.24,38.03,0,1.27.63,1.9,1.27,1.9s1.27-.63,1.27-1.9c0-4.12,2.22-18.06,6.66-38.03l15.53-67.81h53.23l-29.79,125.17c-6.02,25.67-21.86,38.34-44.05,38.34s-42.14-13.31-47.21-38.34l-6.66-33.27c-1.9-10.14-4.75-27.25-6.34-35.17-.32-1.59-.63-2.53-1.9-2.53s-1.58,1.27-1.9,2.53c-1.9,7.92-5.7,25.03-7.92,35.17l-7.29,33.27c-5.39,25.03-19.65,38.34-42.78,38.34s-42.14-12.67-48.16-38.34l-29.79-125.17Z"/>
+    <path class="cls-2" d="M1718.92,246.93v70.98h-57.04v-77.95c0-46.58,27.25-85.24,85.87-85.24s85.87,38.66,85.87,85.24v77.95h-57.04v-70.98c0-19.96-7.92-36.76-28.84-36.76s-28.84,16.79-28.84,36.76Z"/>
+  </g>
+  <path class="cls-1" d="M370.74,68.08h-114.05c-15.2,0-27.52,12.32-27.52,27.52v97.79l-99.73-80.2c-1.57-1.27-3.32-2.3-5.2-3.06h0c-8.5-3.46-18.12-2.47-25.73,2.65-7.61,5.12-12.16,13.66-12.16,22.83v179.24c0,15.2,12.32,27.52,27.52,27.52h129.39c15.2,0,27.52-12.32,27.52-27.52v-34.6l84.41,62.76c4.6,3.15,9.97,4.81,15.53,4.81,4.45,0,8.89-1.1,12.84-3.19,9.05-4.78,14.68-14.1,14.68-24.34V95.6c0-15.2-12.32-27.52-27.52-27.52Z"/>
+</svg>

+ 118 - 0
src/lib/core/models/mock-data.js

@@ -0,0 +1,118 @@
+// Mock Data for Nettown Analytics Dashboard
+
+export const mockKpis = {
+    whatsappMessages: { current: 418, total: 17481 },
+    crmLines: { current: 0, total: 149682 },
+    newPeople: { new: 55, recurring: 1 },
+    generalSentiment: { value: 0.1 },
+    activeSources: { value: 2 },
+    activeService: { value: 4 }
+};
+
+export const mockPriorityQueue = [
+    {
+        id: 1,
+        customerName: 'Carolina Ribeiro',
+        segment: 'Elegante Estratégica',
+        status: 'VENDEDORA NÃO RESPONDEU',
+        statusReason: 'causa: tamanho',
+        slaStatus: 'SLA 12h estourado',
+        timeAgo: 'há 18h',
+        sellerName: 'Maria',
+        lastMessage: 'Não tem no meu tamanho 40?',
+        motive: 'Pediu tamanho indisponível — reservar/repor',
+        impact: 8639,
+        ticket: 879,
+        chance: 82,
+        optimumWindow: '6h',
+        score: 7084
+    },
+    {
+        id: 2,
+        customerName: 'Juliana Mendes',
+        segment: 'Premium Contemporânea',
+        status: 'VENDEDORA NÃO RESPONDEU',
+        statusReason: 'causa: tamanho',
+        slaStatus: 'SLA 6h estourado',
+        timeAgo: 'há 12h',
+        sellerName: 'Lívia',
+        lastMessage: 'Vocês têm a bolsa em outra cor?',
+        motive: 'Pediu cor indisponível — sugerir alternativa',
+        impact: 6986,
+        ticket: 649,
+        chance: 90,
+        optimumWindow: '6h',
+        score: 6287
+    },
+    {
+        id: 3,
+        customerName: 'Patrícia Nunes',
+        segment: 'Premium Contemporânea',
+        status: 'VENDEDORA NÃO RESPONDEU',
+        statusReason: 'causa: preço',
+        slaStatus: 'SLA 14h estourado',
+        timeAgo: 'há 26h',
+        sellerName: 'Maria',
+        lastMessage: 'Achei o preço alto pro material',
+        motive: 'Objeção de preço — quebrar com prova de valor',
+        impact: 7006,
+        ticket: 923,
+        chance: 63,
+        optimumWindow: '12h',
+        score: 4414
+    }
+];
+
+export const mockRadarData = [
+    { name: 'Confiança', value: 45 },
+    { name: 'Alegria', value: 100 },
+    { name: 'Antecipação', value: 41 },
+    { name: 'Medo', value: 18 },
+    { name: 'Tristeza', value: 3 },
+    { name: 'Raiva', value: 13 }
+];
+
+export const mockInteractions = [
+    { client: '554196690452', agent: '-', sentiment: 'CONTENTAMENTO', score: 0.5, aspect: 'Atendimento', subaspect: 'Informativo', datetime: '02/05/26, 19:59' },
+    { client: '5521969638304', agent: '-', sentiment: 'FRUSTRAÇÃO', score: -0.5, aspect: 'Atendimento', subaspect: 'Demora', datetime: '02/05/26, 13:38' },
+    { client: '554497471636', agent: '-', sentiment: 'NEUTRO', score: 0, aspect: 'Neutro', subaspect: 'Informativo', datetime: '02/05/26, 14:14' },
+    { client: '554599574801', agent: '-', sentiment: 'CONTENTAMENTO', score: 0.6, aspect: 'Produto', subaspect: 'Variedade', datetime: '02/05/26, 13:15' },
+    { client: '554191033079', agent: 'Leticia', sentiment: 'CONTENTAMENTO', score: 0.9, aspect: 'Atendimento', subaspect: 'Cordialidade', datetime: '02/05/26, 12:38' },
+    { client: '556281126723', agent: '-', sentiment: 'NEUTRO', score: 0, aspect: 'Produto', subaspect: 'Preço', datetime: '02/05/26, 12:34' },
+];
+
+export const mockChatLog = [
+    { isAgent: false, text: 'Onde fica a loja', time: '19:58', date: 'ONTEM' },
+    { isAgent: true, text: 'Oiie, aqui é a Júlia 💕 pra eu te direcionar melhor, me confirme sua numeração de jeans e sua altura?', time: '19:59' },
+    { isAgent: true, text: 'Oieee Camila, boa noite 🥰', time: '19:59' },
+    { isAgent: true, text: 'Nossa loja fica localizada em Maringá-PR', time: '19:59' },
+    { isAgent: false, text: 'Haaaa que legal', time: '20:07' },
+];
+
+export const mockVolumeData = [
+    { date: new Date('2026-05-02T11:00:00'), whatsapp: 10, sentiment: 0.1, crm: 0 },
+    { date: new Date('2026-05-02T12:00:00'), whatsapp: 230, sentiment: 0.5, crm: 0 },
+    { date: new Date('2026-05-02T13:00:00'), whatsapp: 80, sentiment: 0.2, crm: 0 },
+    { date: new Date('2026-05-02T14:00:00'), whatsapp: 60, sentiment: -0.1, crm: 0 },
+    { date: new Date('2026-05-02T15:00:00'), whatsapp: 50, sentiment: 0.3, crm: 0 },
+    { date: new Date('2026-05-02T16:00:00'), whatsapp: 80, sentiment: 0.4, crm: 0 },
+    { date: new Date('2026-05-02T17:00:00'), whatsapp: 40, sentiment: 0.1, crm: 0 },
+    { date: new Date('2026-05-02T18:00:00'), whatsapp: 10, sentiment: 0, crm: 0 },
+    { date: new Date('2026-05-02T19:00:00'), whatsapp: 5, sentiment: -0.2, crm: 0 },
+    { date: new Date('2026-05-02T20:00:00'), whatsapp: 8, sentiment: -0.1, crm: 0 },
+    { date: new Date('2026-05-02T21:00:00'), whatsapp: 2, sentiment: 0, crm: 0 },
+    { date: new Date('2026-05-02T22:00:00'), whatsapp: 15, sentiment: 0.2, crm: 0 },
+];
+
+export const mockSentimentDistribution = [
+    { sentiment: 'Positivo', value: 53, color: '#166534' },
+    { sentiment: 'Neutro', value: 11, color: '#475569' },
+    { sentiment: 'Negativo', value: 37, color: '#991b1b' },
+];
+
+export const mockAspectsData = [
+    { aspect: 'Atendimento', positive: 350, negative: 20 },
+    { aspect: 'Produto', positive: 130, negative: 40 },
+    { aspect: 'Entrega', positive: 60, negative: 40 },
+    { aspect: 'Monetário', positive: 30, negative: 20 },
+];

+ 23 - 0
src/lib/core/stores/theme.js

@@ -0,0 +1,23 @@
+import { writable } from 'svelte/store';
+import { browser } from '$app/environment';
+
+// Default to light mode or respect user's system preference if available
+const defaultValue = 'light';
+const initialValue = browser ? window.localStorage.getItem('theme') ?? defaultValue : defaultValue;
+
+export const theme = writable(initialValue);
+
+theme.subscribe((value) => {
+    if (browser) {
+        window.localStorage.setItem('theme', value);
+        if (value === 'dark') {
+            document.documentElement.classList.add('dark');
+        } else {
+            document.documentElement.classList.remove('dark');
+        }
+    }
+});
+
+export function toggleTheme() {
+    theme.update((current) => current === 'dark' ? 'light' : 'dark');
+}

+ 1 - 0
src/lib/index.js

@@ -0,0 +1 @@
+// place files you want to import through the `$lib` alias in this folder.

+ 161 - 0
src/routes/(app)/+layout.svelte

@@ -0,0 +1,161 @@
+<script>
+    import { page } from '$app/stores';
+    import { LayoutDashboard, MessageSquare, BarChart2, Settings, LogOut, Bell, Search, Menu, X, TrendingUp, ChevronLeft, ChevronRight, Moon, Sun } from 'lucide-svelte';
+    import { goto } from '$app/navigation';
+    import logoWhite from '$lib/assets/images/nettown_white_logo.svg';
+    import logoBlack from '$lib/assets/images/nettown_black_logo.svg.svg';
+    import { theme, toggleTheme } from '$lib/core/stores/theme';
+    import { onMount } from 'svelte';
+
+    let { children } = $props();
+    let isMobileMenuOpen = $state(false);
+    let isSidebarCollapsed = $state(false);
+    let currentTheme = $state('light');
+
+    onMount(() => {
+        theme.subscribe(val => {
+            currentTheme = val;
+        });
+    });
+
+    const navItems = [
+        { name: 'Visão Geral', href: '/dashboard', icon: LayoutDashboard },
+        { name: 'Interações', href: '/dashboard/interactions', icon: MessageSquare },
+        { name: 'Análise de Sentimento', href: '/dashboard/analytics', icon: BarChart2 },
+        { name: 'Configurações', href: '/dashboard/settings', icon: Settings },
+    ];
+
+    function handleLogout() {
+        goto('/');
+    }
+
+    function toggleMobileMenu() {
+        isMobileMenuOpen = !isMobileMenuOpen;
+    }
+
+    function toggleSidebar() {
+        isSidebarCollapsed = !isSidebarCollapsed;
+    }
+</script>
+
+<div class="h-screen w-screen bg-slate-50 dark:bg-[#0f172a] text-slate-900 dark:text-slate-300 font-sans flex overflow-hidden transition-colors duration-200">
+    <!-- Mobile Sidebar Overlay -->
+    {#if isMobileMenuOpen}
+        <div class="fixed inset-0 bg-slate-950/80 z-40 lg:hidden" onclick={toggleMobileMenu} onkeydown={(e) => e.key === 'Escape' && toggleMobileMenu()} tabindex="0" role="button" aria-label="Fechar menu"></div>
+    {/if}
+
+    <!-- Sidebar -->
+    <aside class="fixed lg:static inset-y-0 left-0 z-50 h-full bg-white dark:bg-[#1e293b] border-r border-slate-200 dark:border-slate-800 flex flex-col transition-all duration-300 ease-in-out {isSidebarCollapsed ? 'w-20' : 'w-64'} {isMobileMenuOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'} shrink-0 shadow-sm dark:shadow-none">
+        <div class="h-16 flex items-center justify-between px-4 border-b border-slate-200 dark:border-slate-800 shrink-0">
+            <div class="flex items-center gap-2 text-indigo-600 dark:text-indigo-400 overflow-hidden">
+                <div class="h-6 flex items-center shrink-0 {isSidebarCollapsed ? 'w-8 justify-center' : 'w-auto'}">
+                    {#if isSidebarCollapsed}
+                        <TrendingUp size={24} strokeWidth={2.5} class="text-indigo-600 dark:text-indigo-500" />
+                    {:else}
+                        <img src={currentTheme === 'dark' ? logoWhite : logoBlack} alt="NetTown Analytics" class="h-full w-auto" />
+                    {/if}
+                </div>
+            </div>
+            
+            <button class="hidden lg:flex items-center justify-center p-1.5 text-slate-400 hover:text-slate-700 dark:hover:text-white rounded-lg hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors shrink-0" onclick={toggleSidebar}>
+                {#if isSidebarCollapsed}
+                    <ChevronRight size={18} />
+                {:else}
+                    <ChevronLeft size={18} />
+                {/if}
+            </button>
+
+            <button class="lg:hidden text-slate-400 hover:text-slate-700 dark:hover:text-white p-1 shrink-0" onclick={toggleMobileMenu}>
+                <X size={20} />
+            </button>
+        </div>
+
+        <div class="flex-1 py-6 flex flex-col gap-2 overflow-y-auto overflow-x-hidden {isSidebarCollapsed ? 'px-2' : 'px-4'}">
+            <div class="text-xs font-semibold text-slate-500 uppercase tracking-wider mb-2 px-2 whitespace-nowrap {isSidebarCollapsed ? 'text-center text-[10px]' : ''}">
+                {isSidebarCollapsed ? 'Menu' : 'Menu Principal'}
+            </div>
+            {#each navItems as item}
+                {@const Icon = item.icon}
+                <a 
+                    href={item.href} 
+                    title={isSidebarCollapsed ? item.name : ''}
+                    class="flex items-center gap-3 py-2.5 rounded-lg transition-colors {$page.url.pathname === item.href || $page.url.pathname.startsWith(item.href + '/') ? 'bg-indigo-50 dark:bg-indigo-500/10 text-indigo-700 dark:text-indigo-400 font-medium' : 'text-slate-600 dark:text-slate-400 hover:bg-slate-100 dark:hover:bg-slate-800 hover:text-slate-900 dark:hover:text-slate-200'} {isSidebarCollapsed ? 'justify-center px-0' : 'px-3'}"
+                    onclick={() => isMobileMenuOpen = false}
+                >
+                    <Icon size={isSidebarCollapsed ? 22 : 18} strokeWidth={$page.url.pathname === item.href ? 2.5 : 2} class="shrink-0" />
+                    {#if !isSidebarCollapsed}
+                        <span class="truncate">{item.name}</span>
+                    {/if}
+                </a>
+            {/each}
+        </div>
+
+        <div class="p-4 border-t border-slate-200 dark:border-slate-800 shrink-0">
+            <button 
+                onclick={handleLogout} 
+                title={isSidebarCollapsed ? 'Sair' : ''}
+                class="w-full flex items-center gap-3 py-2.5 rounded-lg text-slate-600 dark:text-slate-400 hover:bg-red-50 dark:hover:bg-slate-800 hover:text-red-600 dark:hover:text-red-400 transition-colors {isSidebarCollapsed ? 'justify-center px-0' : 'px-3'}"
+            >
+                <LogOut size={18} class="shrink-0" />
+                {#if !isSidebarCollapsed}
+                    <span>Sair</span>
+                {/if}
+            </button>
+        </div>
+    </aside>
+
+    <!-- Main Wrapper -->
+    <div class="flex-1 flex flex-col min-w-0 h-full overflow-hidden relative">
+        <!-- Top Header -->
+        <header class="h-16 flex items-center justify-between px-4 lg:px-8 bg-white/95 dark:bg-[#1e293b]/95 backdrop-blur-sm border-b border-slate-200 dark:border-slate-800 shrink-0 w-full z-30 transition-colors duration-200">
+            <div class="flex items-center gap-4">
+                <button class="lg:hidden text-slate-400 hover:text-slate-700 dark:hover:text-white" onclick={toggleMobileMenu}>
+                    <Menu size={24} />
+                </button>
+                <div class="hidden sm:flex items-center relative">
+                    <Search size={18} class="absolute left-3 text-slate-400 dark:text-slate-500" />
+                    <input 
+                        type="text" 
+                        placeholder="Buscar cliente, número..." 
+                        class="w-64 pl-10 pr-4 py-1.5 bg-slate-100 dark:bg-slate-900 border border-transparent dark:border-slate-700 rounded-lg text-sm text-slate-900 dark:text-slate-200 placeholder-slate-500 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 focus:bg-white transition-all"
+                    />
+                </div>
+            </div>
+
+            <div class="flex items-center gap-4">
+                <!-- Theme Toggle -->
+                <button 
+                    onclick={toggleTheme} 
+                    class="relative p-2 text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 rounded-lg hover:bg-indigo-50 dark:hover:bg-slate-800 transition-colors"
+                    title={currentTheme === 'dark' ? 'Mudar para modo claro' : 'Mudar para modo escuro'}
+                >
+                    {#if currentTheme === 'dark'}
+                        <Sun size={20} />
+                    {:else}
+                        <Moon size={20} />
+                    {/if}
+                </button>
+            
+                <button class="relative p-2 text-slate-400 hover:text-slate-700 dark:hover:text-white rounded-full hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors">
+                    <Bell size={20} />
+                    <span class="absolute top-1.5 right-1.5 w-2 h-2 rounded-full bg-red-500 border-2 border-white dark:border-[#1e293b]"></span>
+                </button>
+                <div class="h-8 w-px bg-slate-200 dark:bg-slate-700 mx-1"></div>
+                <div class="flex items-center gap-3">
+                    <div class="text-right hidden sm:block">
+                        <div class="text-sm font-medium text-slate-900 dark:text-white">Admin</div>
+                        <div class="text-xs text-slate-500">Gestor de Vendas</div>
+                    </div>
+                    <div class="w-9 h-9 rounded-full bg-indigo-600 flex items-center justify-center text-white font-bold text-sm shadow-sm shadow-indigo-900/20">
+                        AD
+                    </div>
+                </div>
+            </div>
+        </header>
+
+        <!-- Page Content Scrollable Area -->
+        <main class="flex-1 overflow-y-auto overflow-x-hidden p-4 lg:p-8 relative">
+            {@render children()}
+        </main>
+    </div>
+</div>

+ 316 - 0
src/routes/(app)/dashboard/+page.svelte

@@ -0,0 +1,316 @@
+<script>
+    import { Users, MessageSquare, AlertTriangle, ThumbsUp, Activity, Smartphone, Monitor } from 'lucide-svelte';
+    import { Chart, Svg, Axis, Bar, Line, Spline, Highlight, Group } from 'layerchart';
+    import { scaleTime, scaleLinear, scaleBand } from 'd3-scale';
+    import { format } from 'date-fns';
+    import { ptBR } from 'date-fns/locale';
+    
+    import { 
+        mockKpis, 
+        mockPriorityQueue, 
+        mockRadarData, 
+        mockVolumeData,
+        mockSentimentDistribution,
+        mockAspectsData
+    } from '$lib/core/models/mock-data.js';
+
+    // Map KPIs to UI format
+    const kpis = [
+        { title: 'Mensagens WhatsApp', value: mockKpis.whatsappMessages.current, subvalue: `${mockKpis.whatsappMessages.total} Total`, icon: MessageSquare, color: 'text-sky-600 dark:text-sky-400', bg: 'bg-sky-50 dark:bg-sky-400/10', border: 'border-sky-200 dark:border-sky-400/20' },
+        { title: 'Linhas CRM', value: mockKpis.crmLines.current, subvalue: `${mockKpis.crmLines.total} Total`, icon: Activity, color: 'text-indigo-600 dark:text-indigo-400', bg: 'bg-indigo-50 dark:bg-indigo-400/10', border: 'border-indigo-200 dark:border-indigo-400/20' },
+        { title: 'Pessoas Novas', value: mockKpis.newPeople.new, subvalue: `${mockKpis.newPeople.recurring} Recorrente`, icon: Users, color: 'text-emerald-600 dark:text-emerald-400', bg: 'bg-emerald-50 dark:bg-emerald-400/10', border: 'border-emerald-200 dark:border-emerald-400/20' },
+        { title: 'Sentimento Geral', value: mockKpis.generalSentiment.value, subvalue: 'Média', icon: ThumbsUp, color: 'text-amber-600 dark:text-amber-400', bg: 'bg-amber-50 dark:bg-amber-400/10', border: 'border-amber-200 dark:border-amber-400/20' },
+        { title: 'Fontes Ativas', value: mockKpis.activeSources.value, subvalue: 'Conectadas', icon: Smartphone, color: 'text-blue-600 dark:text-blue-400', bg: 'bg-blue-50 dark:bg-blue-400/10', border: 'border-blue-200 dark:border-blue-400/20' },
+        { title: 'Atendimento Ativo', value: mockKpis.activeService.value, subvalue: 'Agentes online', icon: Monitor, color: 'text-purple-600 dark:text-purple-400', bg: 'bg-purple-50 dark:bg-purple-400/10', border: 'border-purple-200 dark:border-purple-400/20' },
+    ];
+
+    // Data-driven Radar Chart logic
+    const radarRadius = 80;
+    const radarCenter = 100;
+    const angleStep = (Math.PI * 2) / mockRadarData.length;
+    
+    const radarPoints = $derived(mockRadarData.map((d, i) => {
+        const angle = i * angleStep - Math.PI / 2;
+        const r = (d.value / 100) * radarRadius;
+        return {
+            ...d,
+            x: radarCenter + r * Math.cos(angle),
+            y: radarCenter + r * Math.sin(angle),
+            labelX: radarCenter + (radarRadius + 18) * Math.cos(angle),
+            labelY: radarCenter + (radarRadius + 15) * Math.sin(angle),
+            axisX: radarCenter + radarRadius * Math.cos(angle),
+            axisY: radarCenter + radarRadius * Math.sin(angle),
+        };
+    }));
+
+    const radarPath = $derived(radarPoints.map(p => `${p.x},${p.y}`).join(' '));
+
+    const gridLevels = [0.2, 0.4, 0.6, 0.8, 1].map(level => {
+        return mockRadarData.map((_, i) => {
+            const angle = i * angleStep - Math.PI / 2;
+            const r = level * radarRadius;
+            return `${radarCenter + r * Math.cos(angle)},${radarCenter + r * Math.sin(angle)}`;
+        }).join(' ');
+    });
+</script>
+
+<svelte:head>
+    <title>Dashboard - Nettown Analytics</title>
+</svelte:head>
+
+<div class="space-y-6 max-w-[1600px] mx-auto">
+    <!-- Header/Filters -->
+    <div class="bg-white dark:bg-[#1e293b] p-4 rounded-xl border border-slate-200 dark:border-slate-800 flex flex-wrap items-center gap-4 text-sm shadow-sm transition-colors duration-200">
+        <div class="flex items-center gap-2">
+            <span class="text-slate-600 dark:text-slate-400 font-medium">Período:</span>
+            <select class="bg-slate-50 dark:bg-slate-900 border border-slate-300 dark:border-slate-700 text-slate-900 dark:text-slate-200 rounded-lg px-3 py-1.5 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-colors">
+                <option>Hoje (24h)</option>
+                <option>Ontem</option>
+                <option>Últimos 7 dias</option>
+            </select>
+        </div>
+        <div class="flex items-center gap-2">
+            <span class="text-slate-600 dark:text-slate-400 font-medium">Unidade:</span>
+            <select class="bg-slate-50 dark:bg-slate-900 border border-slate-300 dark:border-slate-700 text-slate-900 dark:text-slate-200 rounded-lg px-3 py-1.5 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-colors">
+                <option>Sem segmento</option>
+            </select>
+        </div>
+        <div class="flex items-center gap-2">
+            <span class="text-slate-600 dark:text-slate-400 font-medium">Área:</span>
+            <select class="bg-slate-50 dark:bg-slate-900 border border-slate-300 dark:border-slate-700 text-slate-900 dark:text-slate-200 rounded-lg px-3 py-1.5 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-colors">
+                <option>Sem segmento de setor</option>
+            </select>
+        </div>
+        <div class="flex items-center gap-2">
+            <span class="text-slate-600 dark:text-slate-400 font-medium">Sentimento:</span>
+            <select class="bg-slate-50 dark:bg-slate-900 border border-slate-300 dark:border-slate-700 text-slate-900 dark:text-slate-200 rounded-lg px-3 py-1.5 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-colors">
+                <option>Todos</option>
+                <option>Positivo</option>
+                <option>Neutro</option>
+                <option>Negativo</option>
+            </select>
+        </div>
+    </div>
+
+    <!-- KPIs -->
+    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 gap-4">
+        {#each kpis as kpi}
+            {@const Icon = kpi.icon}
+            <div class="bg-white dark:bg-[#1e293b] p-5 rounded-xl border {kpi.border} hover:border-indigo-200 dark:hover:border-slate-600 transition-colors shadow-sm duration-200">
+                <div class="flex items-start gap-4">
+                    <div class="w-10 h-10 rounded-lg {kpi.bg} {kpi.color} flex items-center justify-center shrink-0">
+                        <Icon size={20} strokeWidth={2.5} />
+                    </div>
+                    <div>
+                        <div class="text-xs font-semibold text-slate-500 dark:text-slate-400 uppercase tracking-wider mb-1">{kpi.title}</div>
+                        <div class="text-2xl font-bold text-slate-900 dark:text-white mb-0.5">{kpi.value}</div>
+                        <div class="text-xs text-slate-500">{kpi.subvalue}</div>
+                    </div>
+                </div>
+            </div>
+        {/each}
+    </div>
+
+    <!-- Main Content Area -->
+    <div class="grid grid-cols-1 xl:grid-cols-3 gap-6">
+        <!-- Fila Priorizada / Alertas -->
+        <div class="xl:col-span-2 bg-white dark:bg-[#1e293b] rounded-xl border border-slate-200 dark:border-slate-800 shadow-sm overflow-hidden flex flex-col h-[500px] transition-colors duration-200">
+            <div class="p-4 border-b border-slate-200 dark:border-slate-800 flex justify-between items-center bg-slate-50 dark:bg-[#1e293b]">
+                <div class="flex items-center gap-2">
+                    <AlertTriangle size={18} class="text-amber-600 dark:text-amber-500" />
+                    <h2 class="text-base font-bold text-slate-900 dark:text-white">Fila Priorizada • Conversas Inacabadas</h2>
+                </div>
+                <div class="flex gap-2">
+                    <span class="px-2.5 py-1 rounded-md bg-red-50 dark:bg-red-500/10 text-red-600 dark:text-red-400 text-xs font-medium border border-red-200 dark:border-red-500/20">22 fora da janela</span>
+                    <span class="px-2.5 py-1 rounded-md bg-amber-50 dark:bg-amber-500/10 text-amber-700 dark:text-amber-400 text-xs font-medium border border-amber-200 dark:border-amber-500/20">Potencial: R$ 81.004</span>
+                </div>
+            </div>
+            
+            <div class="p-4 bg-slate-50/50 dark:bg-slate-900 border-b border-slate-200 dark:border-slate-800 flex gap-2">
+                <button class="px-4 py-1.5 bg-white dark:bg-[#1e293b] text-slate-900 dark:text-white text-sm font-medium rounded-lg border border-slate-300 dark:border-slate-700 shadow-sm dark:shadow-none">Todas (22)</button>
+                <button class="px-4 py-1.5 bg-transparent text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white text-sm font-medium rounded-lg border border-transparent hover:border-slate-300 dark:hover:border-slate-700 transition-colors">Pela vendedora (13)</button>
+                <button class="px-4 py-1.5 bg-transparent text-slate-600 dark:text-slate-400 hover:text-slate-900 dark:hover:text-white text-sm font-medium rounded-lg border border-transparent hover:border-slate-300 dark:hover:border-slate-700 transition-colors">Pelo cliente (9)</button>
+            </div>
+
+            <div class="flex-1 overflow-y-auto p-4 space-y-4">
+                {#each mockPriorityQueue as item}
+                    <div class="p-4 rounded-lg bg-white dark:bg-slate-900 border border-red-200 dark:border-red-500/30 relative overflow-hidden group hover:border-red-300 dark:hover:border-red-500/60 shadow-sm dark:shadow-none transition-colors">
+                        <div class="absolute left-0 top-0 bottom-0 w-1 bg-red-500"></div>
+                        <div class="flex justify-between items-start mb-3">
+                            <div>
+                                <div class="flex items-center gap-2 mb-1">
+                                    <span class="font-bold text-slate-900 dark:text-white">#{item.id} {item.customerName}</span>
+                                    <span class="px-2 py-0.5 rounded text-[10px] font-bold bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 border border-slate-200 dark:border-slate-700">{item.segment}</span>
+                                    <span class="px-2 py-0.5 rounded text-[10px] font-bold bg-red-50 dark:bg-red-500/20 text-red-600 dark:text-red-400 border border-red-100 dark:border-transparent">{item.status}</span>
+                                </div>
+                                <div class="text-sm text-slate-600 dark:text-slate-400">Vendedora: <span class="text-slate-900 dark:text-slate-200 font-medium">{item.sellerName}</span> · {item.lastMessage}</div>
+                            </div>
+                            <div class="text-right">
+                                <div class="text-xs text-red-600 dark:text-red-400 font-medium mb-1">{item.slaStatus}</div>
+                                <div class="text-xs text-slate-500">{item.timeAgo}</div>
+                            </div>
+                        </div>
+                        <div class="flex items-center gap-2 text-sm text-slate-600 dark:text-slate-300 mb-3 bg-slate-50 dark:bg-transparent p-2 dark:p-0 rounded-md">
+                            <Activity size={14} class="text-slate-400 dark:text-slate-500 shrink-0" />
+                            <span>Motivo: <span class="font-medium">{item.motive}</span></span>
+                        </div>
+                        <div class="flex items-center justify-between text-xs">
+                            <div class="flex gap-4">
+                                <span class="text-slate-500 dark:text-slate-400">Impacto: <span class="text-red-600 dark:text-red-400 font-bold">R$ {item.impact.toLocaleString('pt-BR')}</span></span>
+                                <span class="text-slate-500 dark:text-slate-400">Ticket: <span class="text-slate-900 dark:text-slate-200 font-medium">R$ {item.ticket}</span></span>
+                                <span class="text-slate-500 dark:text-slate-400">Chance: <span class="text-emerald-600 dark:text-emerald-400 font-bold">{item.chance}%</span></span>
+                            </div>
+                            <div class="flex gap-2">
+                                <button class="px-3 py-1.5 bg-white dark:bg-slate-800 hover:bg-slate-50 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-200 rounded-md transition-colors font-medium border border-slate-300 dark:border-slate-700 shadow-sm dark:shadow-none">Sugerir mensagem</button>
+                                <button class="px-3 py-1.5 bg-emerald-50 dark:bg-emerald-500/10 hover:bg-emerald-100 dark:hover:bg-emerald-500/20 text-emerald-700 dark:text-emerald-400 rounded-md transition-colors font-medium border border-emerald-200 dark:border-emerald-500/20">Resolver</button>
+                            </div>
+                        </div>
+                    </div>
+                {/each}
+            </div>
+        </div>
+
+        <!-- Radar Chart / Humor da base -->
+        <div class="bg-white dark:bg-[#1e293b] rounded-xl border border-slate-200 dark:border-slate-800 shadow-sm p-4 flex flex-col h-[500px] transition-colors duration-200">
+            <div class="flex justify-between items-center mb-6">
+                <div class="flex items-center gap-2">
+                    <div class="w-8 h-8 rounded-lg bg-indigo-50 dark:bg-indigo-500/10 text-indigo-600 dark:text-indigo-400 flex items-center justify-center border border-indigo-100 dark:border-transparent">
+                        <Activity size={18} />
+                    </div>
+                    <h2 class="text-base font-bold text-slate-900 dark:text-white">Humor da Base</h2>
+                </div>
+                <span class="text-xs font-medium text-slate-600 dark:text-slate-400 bg-slate-100 dark:bg-slate-800 px-2 py-1 rounded">Hoje</span>
+            </div>
+            
+            <div class="flex-1 w-full h-full relative flex items-center justify-center">
+                <!-- Pure SVG Data-driven Radar Chart -->
+                <svg viewBox="0 0 200 200" class="w-full max-w-[300px] h-auto overflow-visible">
+                    <defs>
+                        <linearGradient id="radarArea" x1="0%" y1="0%" x2="100%" y2="100%">
+                            <stop offset="0%" stop-color="#10b981" stop-opacity="0.4" />
+                            <stop offset="100%" stop-color="#3b82f6" stop-opacity="0.1" />
+                        </linearGradient>
+                    </defs>
+                    
+                    <!-- Background Grid -->
+                    {#each gridLevels as points, i}
+                        <polygon 
+                            {points} 
+                            class="stroke-slate-300 dark:stroke-slate-700 fill-none" 
+                            stroke-width={i === 4 ? "1.5" : "0.5"}
+                            stroke-dasharray={i === 4 ? "none" : "2 2"}
+                        />
+                    {/each}
+
+                    <!-- Axes -->
+                    {#each radarPoints as point}
+                        <line 
+                            x1={radarCenter} 
+                            y1={radarCenter} 
+                            x2={point.axisX} 
+                            y2={point.axisY} 
+                            class="stroke-slate-300 dark:stroke-slate-700" 
+                            stroke-width="1"
+                        />
+                        <!-- Labels -->
+                        <text 
+                            x={point.labelX} 
+                            y={point.labelY} 
+                            text-anchor="middle" 
+                            dominant-baseline="middle"
+                            class="text-[8px] font-medium fill-slate-500 dark:fill-slate-400"
+                        >
+                            {point.name}
+                        </text>
+                        <!-- Value Labels -->
+                        <text 
+                            x={point.labelX} 
+                            y={point.labelY + 12} 
+                            text-anchor="middle" 
+                            dominant-baseline="middle"
+                            class="text-[9px] font-bold fill-slate-900 dark:fill-white"
+                        >
+                            {point.value}%
+                        </text>
+                    {/each}
+
+                    <!-- Data Polygon -->
+                    <polygon 
+                        points={radarPath} 
+                        class="fill-[url(#radarArea)] stroke-emerald-500 dark:stroke-emerald-400 drop-shadow-md origin-center transition-all duration-700 ease-out hover:scale-105"
+                        stroke-width="2.5"
+                    />
+
+                    <!-- Data Points -->
+                    {#each radarPoints as point}
+                        <circle 
+                            cx={point.x} 
+                            cy={point.y} 
+                            r="3" 
+                            class="fill-white dark:fill-slate-900 stroke-emerald-500 dark:stroke-emerald-400 transition-all duration-300 hover:r-[5]"
+                            stroke-width="2"
+                        >
+                            <title>{point.name}: {point.value}%</title>
+                        </circle>
+                    {/each}
+                </svg>
+            </div>
+        </div>
+    </div>
+    
+    <!-- Secondary Charts Row -->
+    <div class="grid grid-cols-1 xl:grid-cols-2 gap-6">
+        <!-- Volume over time -->
+        <div class="bg-white dark:bg-[#1e293b] rounded-xl border border-slate-200 dark:border-slate-800 shadow-sm p-4 flex flex-col h-[400px] transition-colors duration-200">
+            <div class="flex justify-between items-center mb-6">
+                <h2 class="text-base font-bold text-slate-900 dark:text-white">Volume por Canal</h2>
+                <select class="bg-slate-50 dark:bg-slate-900 border border-slate-300 dark:border-slate-700 text-slate-900 dark:text-slate-200 text-xs rounded-lg px-2 py-1 focus:outline-none focus:border-indigo-500">
+                    <option>Por Hora</option>
+                </select>
+            </div>
+            
+            <div class="flex-1 w-full h-full">
+                <Chart data={mockVolumeData} x="date" y="whatsapp" yDomain={[0, 250]} padding={{ top: 10, right: 10, bottom: 20, left: 30 }}>
+                    <Svg>
+                        <Axis placement="left" grid={{ class: 'stroke-slate-200 dark:stroke-slate-700', strokeDasharray: '2 2' }} class="text-xs fill-slate-500 dark:fill-slate-400" />
+                        <Axis 
+                            placement="bottom" 
+                            format={(d) => format(d, 'HH:mm')}
+                            class="text-xs fill-slate-500 dark:fill-slate-400"
+                        />
+                        <Spline stroke="#38bdf8" strokeWidth={2} />
+                        <Highlight points={{ fill: '#38bdf8', class: 'stroke-white dark:stroke-slate-900', strokeWidth: 2 }} />
+                    </Svg>
+                </Chart>
+            </div>
+        </div>
+        
+        <!-- Sentiment and Aspects distribution -->
+        <div class="bg-white dark:bg-[#1e293b] rounded-xl border border-slate-200 dark:border-slate-800 shadow-sm p-4 flex flex-col h-[400px] transition-colors duration-200">
+            <h2 class="text-base font-bold text-slate-900 dark:text-white mb-6">Distribuição de Aspectos</h2>
+            
+            <div class="flex-1 w-full h-full relative overflow-y-auto pr-2 custom-scrollbar">
+                <div class="space-y-4">
+                    {#each mockAspectsData as aspect}
+                        <div>
+                            <div class="flex justify-between text-xs text-slate-600 dark:text-slate-300 mb-1">
+                                <span class="font-medium">{aspect.aspect}</span>
+                                <span>{aspect.positive + aspect.negative} interações</span>
+                            </div>
+                            <div class="h-6 w-full bg-slate-100 dark:bg-slate-800 rounded overflow-hidden flex shadow-inner">
+                                <div 
+                                    class="h-full bg-emerald-500" 
+                                    style="width: {(aspect.positive / (aspect.positive + aspect.negative)) * 100}%"
+                                ></div>
+                                <div 
+                                    class="h-full bg-red-500" 
+                                    style="width: {(aspect.negative / (aspect.positive + aspect.negative)) * 100}%"
+                                ></div>
+                            </div>
+                        </div>
+                    {/each}
+                </div>
+            </div>
+        </div>
+    </div>
+</div>

+ 303 - 0
src/routes/(app)/dashboard/interactions/+page.svelte

@@ -0,0 +1,303 @@
+<script>
+    import { Search, Download, Filter, Eye, X, MessageCircle } from 'lucide-svelte';
+    import { mockInteractions, mockChatLog } from '$lib/core/models/mock-data.js';
+
+    let searchQuery = $state('');
+    let selectedInteraction = $state(null);
+    let isChatModalOpen = $state(false);
+
+    // Filters state
+    let activeFilter = $state('all'); // all, my_clients, new, unfinished
+
+    const filteredInteractions = $derived(
+        mockInteractions.filter(interaction => {
+            if (searchQuery && !interaction.client.includes(searchQuery)) return false;
+            return true;
+        })
+    );
+
+    function getSentimentColor(sentiment) {
+        switch (sentiment) {
+            case 'CONTENTAMENTO': return 'text-emerald-600 bg-emerald-50 border-emerald-200 dark:text-emerald-400 dark:bg-emerald-400/10 dark:border-emerald-400/20';
+            case 'FRUSTRAÇÃO': return 'text-red-600 bg-red-50 border-red-200 dark:text-red-400 dark:bg-red-400/10 dark:border-red-400/20';
+            case 'NEUTRO': return 'text-slate-600 bg-slate-100 border-slate-200 dark:text-slate-400 dark:bg-slate-400/10 dark:border-slate-400/20';
+            default: return 'text-slate-600 bg-slate-100 border-slate-200 dark:text-slate-400 dark:bg-slate-800 dark:border-slate-700';
+        }
+    }
+
+    function openChat(interaction) {
+        selectedInteraction = interaction;
+        isChatModalOpen = true;
+    }
+
+    function closeChat() {
+        isChatModalOpen = false;
+        setTimeout(() => {
+            selectedInteraction = null;
+        }, 300);
+    }
+</script>
+
+<svelte:head>
+    <title>Interações Analisadas - Nettown Analytics</title>
+</svelte:head>
+
+<div class="space-y-6 max-w-[1600px] mx-auto transition-colors duration-200">
+    <!-- Header/Filters -->
+    <div class="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 mb-8">
+        <h1 class="text-2xl font-bold text-slate-900 dark:text-white transition-colors">Últimas Interações Analisadas</h1>
+        
+        <div class="flex flex-wrap items-center gap-3">
+            <button 
+                class="px-4 py-2 rounded-lg text-sm font-medium transition-colors border {activeFilter === 'my_clients' ? 'bg-indigo-50 dark:bg-indigo-500/20 text-indigo-700 dark:text-indigo-400 border-indigo-200 dark:border-indigo-500/30 shadow-inner' : 'bg-white dark:bg-[#1e293b] text-slate-700 dark:text-slate-300 border-slate-200 dark:border-slate-700 hover:border-slate-300 dark:hover:border-slate-500 shadow-sm dark:shadow-none'}"
+                onclick={() => activeFilter = activeFilter === 'my_clients' ? 'all' : 'my_clients'}
+            >
+                Meus Clientes
+            </button>
+            <button 
+                class="px-4 py-2 rounded-lg text-sm font-medium transition-colors border {activeFilter === 'new' ? 'bg-emerald-50 dark:bg-emerald-500/20 text-emerald-700 dark:text-emerald-400 border-emerald-200 dark:border-emerald-500/30 shadow-inner' : 'bg-white dark:bg-[#1e293b] text-slate-700 dark:text-slate-300 border-slate-200 dark:border-slate-700 hover:border-slate-300 dark:hover:border-slate-500 shadow-sm dark:shadow-none'}"
+                onclick={() => activeFilter = activeFilter === 'new' ? 'all' : 'new'}
+            >
+                Relatório Pessoas Novas
+            </button>
+            <button 
+                class="px-4 py-2 rounded-lg text-sm font-medium transition-colors border {activeFilter === 'unfinished' ? 'bg-amber-50 dark:bg-amber-500/20 text-amber-700 dark:text-amber-400 border-amber-200 dark:border-amber-500/30 shadow-inner' : 'bg-white dark:bg-[#1e293b] text-slate-700 dark:text-slate-300 border-slate-200 dark:border-slate-700 hover:border-slate-300 dark:hover:border-slate-500 shadow-sm dark:shadow-none'}"
+                onclick={() => activeFilter = activeFilter === 'unfinished' ? 'all' : 'unfinished'}
+            >
+                Conversas Inacabadas
+            </button>
+            
+            <button class="flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium bg-indigo-600 hover:bg-indigo-700 dark:bg-indigo-600 dark:hover:bg-indigo-500 text-white transition-colors shadow-sm dark:shadow-none ml-auto sm:ml-0">
+                <Download size={16} />
+                Download
+            </button>
+        </div>
+    </div>
+
+    <!-- Table Container -->
+    <div class="bg-white dark:bg-[#1e293b] rounded-xl border border-slate-200 dark:border-slate-800 shadow-sm overflow-hidden flex flex-col transition-colors duration-200">
+        <!-- Table Toolbar -->
+        <div class="p-4 border-b border-slate-200 dark:border-slate-800 flex justify-between items-center bg-slate-50 dark:bg-[#1e293b] transition-colors duration-200">
+            <div class="relative">
+                <Search size={16} class="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400 dark:text-slate-500" />
+                <input 
+                    type="text" 
+                    bind:value={searchQuery}
+                    placeholder="Buscar cliente..." 
+                    class="w-64 pl-9 pr-4 py-2 bg-white dark:bg-slate-900 border border-slate-300 dark:border-slate-700 rounded-lg text-sm text-slate-900 dark:text-slate-200 placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-all shadow-sm dark:shadow-none"
+                />
+            </div>
+            <div class="text-sm text-slate-500 dark:text-slate-400 font-medium">
+                Exibindo 0 - {filteredInteractions.length} (Página 1)
+            </div>
+        </div>
+
+        <!-- Table -->
+        <div class="overflow-x-auto custom-scrollbar">
+            <table class="w-full text-left border-collapse">
+                <thead>
+                    <tr class="bg-slate-100/50 dark:bg-slate-900/50 text-xs font-semibold text-slate-500 dark:text-slate-400 uppercase tracking-wider border-b border-slate-200 dark:border-slate-800 transition-colors duration-200">
+                        <th class="p-4">Cliente</th>
+                        <th class="p-4">Agente</th>
+                        <th class="p-4">Sentimento Geral</th>
+                        <th class="p-4">Score</th>
+                        <th class="p-4">Aspectos Detectados</th>
+                        <th class="p-4">Subaspectos Detectados</th>
+                        <th class="p-4">Data e Hora</th>
+                        <th class="p-4 text-right">Análise Avançada</th>
+                    </tr>
+                </thead>
+                <tbody class="divide-y divide-slate-100 dark:divide-slate-800/50 transition-colors duration-200">
+                    {#each filteredInteractions as item}
+                        <tr class="hover:bg-slate-50 dark:hover:bg-slate-800/30 transition-colors group">
+                            <td class="p-4">
+                                <span class="font-bold text-slate-900 dark:text-white">{item.client}</span>
+                            </td>
+                            <td class="p-4 text-slate-600 dark:text-slate-300 font-medium">{item.agent}</td>
+                            <td class="p-4">
+                                <span class="px-2.5 py-1 rounded-md text-xs font-bold border {getSentimentColor(item.sentiment)} transition-colors duration-200">
+                                    {item.sentiment}
+                                </span>
+                            </td>
+                            <td class="p-4 text-slate-700 dark:text-slate-300 font-bold">{item.score}</td>
+                            <td class="p-4 text-slate-600 dark:text-slate-300 font-medium">{item.aspect}</td>
+                            <td class="p-4 text-slate-500 dark:text-slate-400">{item.subaspect}</td>
+                            <td class="p-4 text-slate-500 dark:text-slate-400 text-sm font-medium">{item.datetime}</td>
+                            <td class="p-4 text-right">
+                                <button 
+                                    onclick={() => openChat(item)}
+                                    class="inline-flex items-center gap-1.5 px-3 py-1.5 bg-indigo-50 hover:bg-indigo-100 dark:bg-indigo-500/10 dark:hover:bg-indigo-500/20 text-indigo-600 dark:text-indigo-400 border border-indigo-200 dark:border-indigo-500/20 rounded-md text-sm font-semibold transition-colors shadow-sm dark:shadow-none"
+                                >
+                                    <Eye size={14} />
+                                    Ver Chat
+                                </button>
+                            </td>
+                        </tr>
+                    {/each}
+                    
+                    {#if filteredInteractions.length === 0}
+                        <tr>
+                            <td colspan="8" class="p-8 text-center text-slate-500 font-medium">
+                                Nenhuma interação encontrada.
+                            </td>
+                        </tr>
+                    {/if}
+                </tbody>
+            </table>
+        </div>
+        
+        <!-- Pagination -->
+        <div class="p-4 border-t border-slate-200 dark:border-slate-800 bg-slate-50 dark:bg-[#1e293b] flex items-center justify-center gap-4 transition-colors duration-200">
+            <button class="text-sm font-medium text-slate-400 dark:text-slate-500 hover:text-slate-600 dark:hover:text-slate-300 disabled:opacity-50" disabled>Anterior</button>
+            <span class="text-sm font-bold text-slate-900 dark:text-white">Página 1</span>
+            <button class="text-sm font-medium text-indigo-600 dark:text-indigo-400 hover:text-indigo-700 dark:hover:text-indigo-300">Próxima</button>
+        </div>
+    </div>
+</div>
+
+<!-- Chat Modal -->
+{#if isChatModalOpen}
+    <div class="fixed inset-0 z-[100] flex items-center justify-center p-4 sm:p-6 transition-colors duration-200" role="dialog" aria-modal="true">
+        <!-- Backdrop -->
+        <div 
+            class="absolute inset-0 bg-slate-900/60 dark:bg-slate-950/80 backdrop-blur-sm transition-opacity" 
+            onclick={closeChat}
+            onkeydown={(e) => e.key === 'Escape' && closeChat()}
+            tabindex="0"
+            role="button"
+            aria-label="Close modal"
+        ></div>
+        
+        <!-- Modal Content -->
+        <div class="relative bg-white dark:bg-[#0f172a] rounded-2xl border border-slate-200 dark:border-slate-800 shadow-2xl w-full max-w-6xl max-h-[90vh] flex flex-col md:flex-row overflow-hidden animate-in fade-in zoom-in-95 duration-200">
+            
+            <!-- Chat Area -->
+            <div class="flex-1 flex flex-col border-r border-slate-200 dark:border-slate-800 bg-slate-50 dark:bg-[#0b1120] min-h-[50vh] md:min-h-[600px] transition-colors duration-200">
+                <!-- Chat Header -->
+                <div class="h-16 px-6 border-b border-slate-200 dark:border-slate-800 flex items-center justify-between bg-white dark:bg-[#1e293b] transition-colors duration-200">
+                    <div class="flex items-center gap-3">
+                        <div class="w-10 h-10 rounded-full bg-slate-100 dark:bg-slate-800 flex items-center justify-center text-slate-500 dark:text-slate-400">
+                            <MessageCircle size={20} />
+                        </div>
+                        <div>
+                            <div class="font-bold text-slate-900 dark:text-white">{selectedInteraction?.client}</div>
+                            <div class="text-xs font-medium text-slate-500 dark:text-slate-400">WhatsApp</div>
+                        </div>
+                    </div>
+                    <button 
+                        onclick={closeChat}
+                        class="md:hidden p-2 text-slate-400 hover:text-slate-700 dark:hover:text-white rounded-lg hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors"
+                    >
+                        <X size={20} />
+                    </button>
+                </div>
+                
+                <!-- Chat Messages -->
+                <div class="flex-1 overflow-y-auto p-6 space-y-6 custom-scrollbar">
+                    <div class="flex justify-center">
+                        <span class="px-3 py-1 rounded-full bg-white dark:bg-slate-800 text-xs font-bold text-slate-500 dark:text-slate-400 border border-slate-200 dark:border-slate-700 shadow-sm dark:shadow-none">
+                            ONTEM
+                        </span>
+                    </div>
+                    
+                    {#each mockChatLog as msg}
+                        <div class="flex flex-col {msg.isAgent ? 'items-end' : 'items-start'}">
+                            <div class="max-w-[80%] {msg.isAgent ? 'bg-indigo-600 text-white rounded-2xl rounded-tr-sm shadow-md shadow-indigo-600/20' : 'bg-white dark:bg-slate-800 text-slate-700 dark:text-slate-200 border border-slate-200 dark:border-transparent rounded-2xl rounded-tl-sm shadow-sm'} p-3.5">
+                                {#if msg.isAgent}
+                                    <div class="text-[10px] font-bold text-indigo-200 mb-1">Ativadora</div>
+                                {/if}
+                                <p class="text-sm leading-relaxed whitespace-pre-wrap">{msg.text}</p>
+                                <div class="text-[10px] text-right mt-1.5 {msg.isAgent ? 'opacity-70' : 'text-slate-400 font-medium'}">{msg.time}</div>
+                            </div>
+                        </div>
+                    {/each}
+                </div>
+            </div>
+            
+            <!-- Analysis Area -->
+            <div class="w-full md:w-[400px] flex flex-col bg-white dark:bg-[#1e293b] shrink-0 transition-colors duration-200">
+                <div class="h-16 px-6 border-b border-slate-200 dark:border-slate-800 flex items-center justify-between">
+                    <h2 class="font-bold text-slate-900 dark:text-white text-lg">Relatório</h2>
+                    <button 
+                        onclick={closeChat}
+                        class="hidden md:flex px-3 py-1.5 bg-slate-100 hover:bg-slate-200 dark:bg-slate-800 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-300 rounded-md text-sm font-bold transition-colors"
+                    >
+                        Fechar
+                    </button>
+                </div>
+                
+                <div class="flex-1 overflow-y-auto p-6 space-y-8 custom-scrollbar">
+                    <!-- Mini chart placeholder -->
+                    <div class="h-32 bg-slate-50 dark:bg-slate-900 rounded-lg border border-slate-200 dark:border-slate-800 relative p-4 flex items-end overflow-hidden shadow-inner">
+                        <!-- Decorative chart lines matching the UI -->
+                        <svg class="absolute inset-0 w-full h-full" preserveAspectRatio="none">
+                            <path d="M0,20 L40,100 L200,100 L300,100 L350,60" fill="none" stroke="#38bdf8" stroke-width="2" vector-effect="non-scaling-stroke" />
+                            <path d="M0,60 L40,100 L200,100 L300,100 L350,40" fill="none" stroke="#10b981" stroke-width="2" vector-effect="non-scaling-stroke" />
+                            <!-- Dots -->
+                            <circle cx="0" cy="20" r="3" fill="#38bdf8" />
+                            <circle cx="40" cy="100" r="3" fill="#38bdf8" />
+                            <circle cx="120" cy="100" r="3" fill="#38bdf8" />
+                            <circle cx="200" cy="100" r="3" fill="#38bdf8" />
+                            <circle cx="300" cy="100" r="3" fill="#38bdf8" />
+                            <circle cx="350" cy="60" r="3" fill="#38bdf8" />
+                        </svg>
+                        <div class="w-full flex justify-between text-[10px] font-medium text-slate-400 dark:text-slate-500 absolute bottom-2 left-0 px-4">
+                            <span>22:58</span>
+                            <span>23:00</span>
+                            <span>23:02</span>
+                            <span>23:04</span>
+                            <span>23:06</span>
+                        </div>
+                    </div>
+                    
+                    <div class="grid grid-cols-2 gap-y-6 gap-x-4">
+                        <div>
+                            <div class="text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider mb-1">MÉDIA RESPOSTA</div>
+                            <div class="text-lg font-extrabold text-slate-900 dark:text-white">04:03</div>
+                        </div>
+                        <div>
+                            <div class="text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider mb-1">DURAÇÃO TOTAL</div>
+                            <div class="text-lg font-extrabold text-slate-900 dark:text-white">08:28</div>
+                        </div>
+                        <div>
+                            <div class="text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider mb-1">MÉDIA AGENTE</div>
+                            <div class="text-lg font-extrabold text-slate-900 dark:text-white">00:00</div>
+                        </div>
+                        <div>
+                            <div class="text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider mb-1">MÉDIA CLIENTE</div>
+                            <div class="text-lg font-extrabold text-slate-900 dark:text-white">08:05</div>
+                        </div>
+                    </div>
+                    
+                    <div class="space-y-4">
+                        <div>
+                            <div class="text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider mb-1">ASPECTO PRINCIPAL</div>
+                            <div class="text-base font-semibold text-indigo-600 dark:text-indigo-400">{selectedInteraction?.aspect || 'Atendimento'}</div>
+                        </div>
+                        <div>
+                            <div class="text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider mb-1">SUBASPECTO</div>
+                            <div class="text-base font-semibold text-slate-700 dark:text-slate-200">{selectedInteraction?.subaspect || 'Informativo'}</div>
+                        </div>
+                    </div>
+                    
+                    <div class="grid grid-cols-2 gap-4 pt-4 border-t border-slate-200 dark:border-slate-800">
+                        <div>
+                            <div class="text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider mb-1">ÚLTIMA MENSAGEM</div>
+                            <div class="text-sm font-semibold text-slate-900 dark:text-white">Cliente</div>
+                        </div>
+                        <div>
+                            <div class="text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-wider mb-1">CONSECUTIVAS</div>
+                            <div class="text-sm font-semibold text-slate-900 dark:text-white">Não</div>
+                        </div>
+                    </div>
+                    
+                    <div class="text-center pt-4">
+                        <button class="text-sm font-bold text-indigo-600 dark:text-indigo-400 hover:text-indigo-700 dark:hover:text-indigo-300 transition-colors">
+                            Detalhes Extraídos
+                        </button>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+{/if}

+ 410 - 0
src/routes/(public)/+page.svelte

@@ -0,0 +1,410 @@
+<script>
+    import { onMount } from 'svelte';
+    import { LayoutGrid, TrendingUp, Users, MessageSquare, BarChart3, ShieldCheck, ArrowRight, Activity, Smartphone, Monitor, ThumbsUp, AlertTriangle, Moon, Sun } from 'lucide-svelte';
+    import logoWhite from '$lib/assets/images/nettown_white_logo.svg';
+    import logoBlack from '$lib/assets/images/nettown_black_logo.svg.svg';
+    import { theme, toggleTheme } from '$lib/core/stores/theme';
+
+    let isScrolled = $state(false);
+    let currentTheme = $state('light');
+
+    onMount(() => {
+        const handleScroll = () => {
+            isScrolled = window.scrollY > 20;
+        };
+        window.addEventListener('scroll', handleScroll);
+        
+        const unsubscribe = theme.subscribe(val => {
+            currentTheme = val;
+        });
+        
+        return () => {
+            window.removeEventListener('scroll', handleScroll);
+            unsubscribe();
+        };
+    });
+</script>
+
+<div class="min-h-screen bg-slate-50 dark:bg-[#0f172a] font-sans text-slate-900 dark:text-slate-300 selection:bg-indigo-100 dark:selection:bg-indigo-500/30 selection:text-indigo-900 dark:selection:text-indigo-200 transition-colors duration-200">
+    <!-- Navigation -->
+    <nav class="fixed top-0 left-0 right-0 z-50 transition-all duration-300 {isScrolled ? 'bg-white/80 dark:bg-[#1e293b]/80 backdrop-blur-md shadow-sm border-b border-slate-200/50 dark:border-slate-800/50 py-3' : 'bg-transparent py-5'}">
+        <div class="max-w-7xl mx-auto px-6 flex items-center justify-between">
+            <div class="flex items-center gap-2">
+                <div class="h-8 flex items-center">
+                    <img src={currentTheme === 'dark' ? logoWhite : logoBlack} alt="NetTown Analytics" class="h-full w-auto transition-opacity" />
+                </div>
+            </div>
+            
+            <div class="hidden md:flex items-center gap-8">
+                <a href="#features" class="text-sm font-medium text-slate-600 dark:text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors">Recursos</a>
+                <a href="#solutions" class="text-sm font-medium text-slate-600 dark:text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors">Soluções</a>
+            </div>
+
+            <div class="flex items-center gap-4">
+                <button 
+                    onclick={toggleTheme} 
+                    class="p-2 text-slate-500 dark:text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 rounded-full hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors"
+                    title={currentTheme === 'dark' ? 'Mudar para modo claro' : 'Mudar para modo escuro'}
+                >
+                    {#if currentTheme === 'dark'}
+                        <Sun size={18} />
+                    {:else}
+                        <Moon size={18} />
+                    {/if}
+                </button>
+                <div class="w-px h-5 bg-slate-300 dark:bg-slate-700 hidden sm:block"></div>
+                <a href="/login" class="text-sm font-medium text-slate-700 dark:text-slate-300 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors hidden sm:block">Entrar</a>
+                <a href="/login" class="px-5 py-2.5 text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 dark:bg-indigo-500 dark:hover:bg-indigo-600 rounded-full shadow-sm shadow-indigo-200 dark:shadow-none transition-all hover:-translate-y-0.5">
+                    Começar Agora
+                </a>
+            </div>
+        </div>
+    </nav>
+
+    <!-- Hero Section -->
+    <section class="relative pt-32 pb-20 md:pt-48 md:pb-32 overflow-hidden">
+        <!-- Background decorative elements -->
+        <div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[800px] h-[800px] bg-indigo-50/50 dark:bg-indigo-500/10 rounded-full blur-3xl -z-10 transition-colors duration-500"></div>
+        <div class="absolute top-0 right-0 w-[400px] h-[400px] bg-sky-50 dark:bg-sky-500/10 rounded-full blur-3xl -z-10 translate-x-1/3 -translate-y-1/3 transition-colors duration-500"></div>
+
+        <div class="max-w-7xl mx-auto px-6 text-center">
+            <div class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-indigo-50 dark:bg-indigo-500/10 border border-indigo-100 dark:border-indigo-500/20 text-indigo-700 dark:text-indigo-400 text-sm font-medium mb-8 transition-colors">
+                <span class="relative flex h-2 w-2">
+                  <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-indigo-400 dark:bg-indigo-500 opacity-75"></span>
+                  <span class="relative inline-flex rounded-full h-2 w-2 bg-indigo-500 dark:bg-indigo-400"></span>
+                </span>
+                Nova IA de Análise de Sentimento
+            </div>
+            
+            <h1 class="text-5xl md:text-7xl font-extrabold tracking-tight text-slate-900 dark:text-white mb-8 max-w-4xl mx-auto leading-tight transition-colors">
+                Entenda seus clientes além dos <span class="text-transparent bg-clip-text bg-gradient-to-r from-indigo-600 to-sky-500 dark:from-indigo-400 dark:to-sky-400">números</span>
+            </h1>
+            
+            <p class="text-lg md:text-xl text-slate-600 dark:text-slate-400 mb-10 max-w-2xl mx-auto leading-relaxed transition-colors">
+                Plataforma inteligente para gestores que transforma conversas do WhatsApp em insights acionáveis sobre satisfação, humor e probabilidade de conversão.
+            </p>
+            
+            <div class="flex flex-col sm:flex-row items-center justify-center gap-4">
+                <a href="/login" class="px-8 py-4 text-base font-semibold text-white bg-indigo-600 hover:bg-indigo-700 dark:bg-indigo-500 dark:hover:bg-indigo-600 rounded-full shadow-lg shadow-indigo-200 dark:shadow-none transition-all hover:-translate-y-1 flex items-center gap-2 w-full sm:w-auto justify-center">
+                    Acessar Dashboard
+                    <ArrowRight size={20} />
+                </a>
+                <a href="#features" class="px-8 py-4 text-base font-semibold text-slate-700 dark:text-slate-300 bg-white dark:bg-[#1e293b] border border-slate-200 dark:border-slate-700 hover:bg-slate-50 dark:hover:bg-slate-800 hover:border-slate-300 dark:hover:border-slate-600 rounded-full transition-all w-full sm:w-auto justify-center">
+                    Conhecer a Plataforma
+                </a>
+            </div>
+        </div>
+
+        <!-- Dashboard Preview Mockup Enhanced -->
+        <div class="max-w-6xl mx-auto px-6 mt-20">
+            <div class="relative rounded-2xl bg-slate-900 shadow-[0_20px_50px_rgba(8,_112,_184,_0.15)] dark:shadow-[0_20px_50px_rgba(0,_0,_0,_0.5)] overflow-hidden border border-slate-800 p-2 transition-shadow">
+                <div class="absolute inset-0 bg-gradient-to-b from-slate-800/50 to-transparent pointer-events-none z-0"></div>
+                <div class="relative bg-[#0f172a] rounded-xl overflow-hidden aspect-[16/9] flex flex-col border border-slate-800 z-10">
+                    <!-- Faux Dashboard Header -->
+                    <div class="h-12 bg-[#1e293b] border-b border-slate-800 flex items-center justify-between px-6 shrink-0">
+                        <div class="flex items-center gap-2">
+                            <div class="w-6 h-6 bg-red-500 rounded-md"></div>
+                            <div class="h-4 w-24 bg-slate-700 rounded-md"></div>
+                        </div>
+                        <div class="flex gap-4 items-center">
+                            <div class="h-6 w-48 bg-slate-800 rounded-md hidden sm:block"></div>
+                            <div class="h-6 w-6 bg-slate-800 rounded-full"></div>
+                            <div class="h-8 w-8 bg-indigo-500 rounded-full flex items-center justify-center text-xs text-white font-bold">AD</div>
+                        </div>
+                    </div>
+                    
+                    <!-- Faux Dashboard Content -->
+                    <div class="flex-1 p-6 flex flex-col gap-6 overflow-hidden">
+                        <!-- Top Filters Mock -->
+                        <div class="h-12 bg-[#1e293b] rounded-lg border border-slate-800 flex items-center px-4 gap-4 w-full shrink-0">
+                            <div class="h-6 w-32 bg-slate-800 rounded-md"></div>
+                            <div class="h-6 w-32 bg-slate-800 rounded-md"></div>
+                            <div class="h-6 w-32 bg-slate-800 rounded-md"></div>
+                            <div class="h-6 w-32 bg-slate-800 rounded-md"></div>
+                        </div>
+                        
+                        <!-- KPIs Mock -->
+                        <div class="grid grid-cols-2 md:grid-cols-4 gap-4 shrink-0">
+                            <div class="h-24 bg-[#1e293b] rounded-lg border border-slate-800 p-4 flex gap-3">
+                                <div class="w-10 h-10 rounded-lg bg-sky-400/10 text-sky-400 flex items-center justify-center"><MessageSquare size={20} /></div>
+                                <div class="flex flex-col justify-center">
+                                    <div class="h-3 w-20 bg-slate-700 rounded mb-2"></div>
+                                    <div class="h-6 w-16 bg-slate-200 rounded"></div>
+                                </div>
+                            </div>
+                            <div class="h-24 bg-[#1e293b] rounded-lg border border-slate-800 p-4 flex gap-3">
+                                <div class="w-10 h-10 rounded-lg bg-emerald-400/10 text-emerald-400 flex items-center justify-center"><Users size={20} /></div>
+                                <div class="flex flex-col justify-center">
+                                    <div class="h-3 w-24 bg-slate-700 rounded mb-2"></div>
+                                    <div class="h-6 w-12 bg-slate-200 rounded"></div>
+                                </div>
+                            </div>
+                            <div class="h-24 bg-[#1e293b] rounded-lg border border-slate-800 p-4 flex gap-3">
+                                <div class="w-10 h-10 rounded-lg bg-amber-400/10 text-amber-400 flex items-center justify-center"><ThumbsUp size={20} /></div>
+                                <div class="flex flex-col justify-center">
+                                    <div class="h-3 w-24 bg-slate-700 rounded mb-2"></div>
+                                    <div class="h-6 w-20 bg-slate-200 rounded"></div>
+                                </div>
+                            </div>
+                            <div class="h-24 bg-[#1e293b] rounded-lg border border-slate-800 p-4 flex gap-3">
+                                <div class="w-10 h-10 rounded-lg bg-indigo-400/10 text-indigo-400 flex items-center justify-center"><Activity size={20} /></div>
+                                <div class="flex flex-col justify-center">
+                                    <div class="h-3 w-16 bg-slate-700 rounded mb-2"></div>
+                                    <div class="h-6 w-24 bg-slate-200 rounded"></div>
+                                </div>
+                            </div>
+                        </div>
+                        
+                        <!-- Main Charts Mock -->
+                        <div class="grid grid-cols-1 md:grid-cols-3 gap-6 flex-1 min-h-0">
+                            <div class="col-span-2 bg-[#1e293b] rounded-lg border border-slate-800 flex flex-col p-4 relative overflow-hidden">
+                                <div class="flex items-center gap-2 mb-4">
+                                    <AlertTriangle size={16} class="text-amber-500" />
+                                    <div class="h-4 w-48 bg-slate-700 rounded-md"></div>
+                                </div>
+                                <div class="flex-1 space-y-3 relative z-10">
+                                    <div class="h-20 bg-slate-900 border border-red-500/30 rounded-lg border-l-4 border-l-red-500 p-3">
+                                        <div class="h-4 w-32 bg-slate-200 rounded mb-2"></div>
+                                        <div class="h-3 w-48 bg-slate-600 rounded"></div>
+                                    </div>
+                                    <div class="h-20 bg-slate-900 border border-red-500/30 rounded-lg border-l-4 border-l-red-500 p-3">
+                                        <div class="h-4 w-40 bg-slate-200 rounded mb-2"></div>
+                                        <div class="h-3 w-56 bg-slate-600 rounded"></div>
+                                    </div>
+                                </div>
+                                <!-- Fade out gradient for overflowing content -->
+                                <div class="absolute bottom-0 left-0 right-0 h-12 bg-gradient-to-t from-[#1e293b] to-transparent z-20"></div>
+                            </div>
+                            
+                            <div class="col-span-1 bg-[#1e293b] rounded-lg border border-slate-800 flex flex-col items-center justify-center p-4">
+                                <div class="w-full flex justify-start mb-auto">
+                                    <div class="h-4 w-32 bg-slate-700 rounded-md"></div>
+                                </div>
+                                <div class="w-40 h-40 border border-slate-700 rounded-full flex items-center justify-center relative">
+                                    <div class="absolute w-28 h-28 border border-slate-700 rounded-full"></div>
+                                    <div class="absolute w-16 h-16 border border-slate-700 rounded-full"></div>
+                                    <svg viewBox="0 0 100 100" class="w-full h-full text-emerald-500/20 fill-current stroke-emerald-500 stroke-2">
+                                        <polygon points="50,10 90,40 70,90 30,90 10,40" />
+                                    </svg>
+                                </div>
+                                <div class="w-full flex justify-end mt-auto">
+                                    <div class="h-3 w-16 bg-slate-700 rounded-md"></div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </section>
+
+    <!-- Features Section -->
+    <section id="features" class="py-24 bg-white dark:bg-[#0f172a] relative overflow-hidden transition-colors duration-200">
+        <div class="max-w-7xl mx-auto px-6 relative z-10">
+            <div class="text-center mb-16">
+                <span class="text-indigo-600 dark:text-indigo-400 font-semibold tracking-wider uppercase text-sm mb-3 block">Poder Tecnológico</span>
+                <h2 class="text-3xl md:text-5xl font-extrabold text-slate-900 dark:text-white mb-6 tracking-tight">Recursos Extraordinários</h2>
+                <p class="text-lg text-slate-600 dark:text-slate-400 max-w-2xl mx-auto leading-relaxed">
+                    Descubra como nossa inteligência artificial revoluciona a maneira como você enxerga os dados do seu negócio, transformando conversas em inteligência competitiva pura.
+                </p>
+            </div>
+
+            <div class="grid md:grid-cols-3 gap-8">
+                <!-- Feature 1 -->
+                <div class="p-10 rounded-3xl bg-white dark:bg-[#1e293b] border border-slate-100 dark:border-slate-800 hover:border-indigo-100 dark:hover:border-slate-700 shadow-[0_4px_20px_-4px_rgba(0,0,0,0.05)] dark:shadow-none hover:shadow-[0_8px_30px_-4px_rgba(79,70,229,0.1)] dark:hover:shadow-[0_8px_30px_-4px_rgba(0,0,0,0.3)] transition-all duration-300 group">
+                    <div class="w-16 h-16 rounded-2xl bg-indigo-50 dark:bg-indigo-500/10 flex items-center justify-center text-indigo-600 dark:text-indigo-400 mb-8 group-hover:scale-110 group-hover:bg-indigo-600 group-hover:text-white dark:group-hover:bg-indigo-500 transition-all duration-300">
+                        <MessageSquare size={32} strokeWidth={1.5} />
+                    </div>
+                    <h3 class="text-2xl font-bold text-slate-900 dark:text-white mb-4">Análise de Conversas com IA</h3>
+                    <p class="text-slate-600 dark:text-slate-400 leading-relaxed">
+                        Nossa IA lê e interpreta milhares de interações no WhatsApp instantaneamente. Detecte o real motivo do contato, objeções de venda e categorize o sentimento do cliente (alegria, frustração, raiva) de forma totalmente automatizada.
+                    </p>
+                </div>
+
+                <!-- Feature 2 -->
+                <div class="p-10 rounded-3xl bg-white dark:bg-[#1e293b] border border-slate-100 dark:border-slate-800 hover:border-sky-100 dark:hover:border-slate-700 shadow-[0_4px_20px_-4px_rgba(0,0,0,0.05)] dark:shadow-none hover:shadow-[0_8px_30px_-4px_rgba(14,165,233,0.1)] dark:hover:shadow-[0_8px_30px_-4px_rgba(0,0,0,0.3)] transition-all duration-300 group">
+                    <div class="w-16 h-16 rounded-2xl bg-sky-50 dark:bg-sky-500/10 flex items-center justify-center text-sky-500 dark:text-sky-400 mb-8 group-hover:scale-110 group-hover:bg-sky-500 group-hover:text-white dark:group-hover:bg-sky-500 transition-all duration-300">
+                        <TrendingUp size={32} strokeWidth={1.5} />
+                    </div>
+                    <h3 class="text-2xl font-bold text-slate-900 dark:text-white mb-4">Insights para Aumento de Vendas</h3>
+                    <p class="text-slate-600 dark:text-slate-400 leading-relaxed">
+                        Transforme dados ocultos em faturamento. Identifique padrões de compra, entenda por que os clientes desistem e descubra oportunidades de upsell cruzando o humor do cliente com o ticket médio da conversa.
+                    </p>
+                </div>
+
+                <!-- Feature 3 -->
+                <div class="p-10 rounded-3xl bg-white dark:bg-[#1e293b] border border-slate-100 dark:border-slate-800 hover:border-emerald-100 dark:hover:border-slate-700 shadow-[0_4px_20px_-4px_rgba(0,0,0,0.05)] dark:shadow-none hover:shadow-[0_8px_30px_-4px_rgba(16,185,129,0.1)] dark:hover:shadow-[0_8px_30px_-4px_rgba(0,0,0,0.3)] transition-all duration-300 group">
+                    <div class="w-16 h-16 rounded-2xl bg-emerald-50 dark:bg-emerald-500/10 flex items-center justify-center text-emerald-500 dark:text-emerald-400 mb-8 group-hover:scale-110 group-hover:bg-emerald-500 group-hover:text-white dark:group-hover:bg-emerald-500 transition-all duration-300">
+                        <ShieldCheck size={32} strokeWidth={1.5} />
+                    </div>
+                    <h3 class="text-2xl font-bold text-slate-900 dark:text-white mb-4">Gestão Ativa de Atendimento</h3>
+                    <p class="text-slate-600 dark:text-slate-400 leading-relaxed">
+                        Tenha controle total da sua operação. Saiba exatamente quais clientes estão esperando resposta há muito tempo através do nosso sistema de Fila Priorizada, mitigando o risco financeiro de conversas abandonadas.
+                    </p>
+                </div>
+            </div>
+        </div>
+    </section>
+
+    <!-- Solutions Section -->
+    <section id="solutions" class="py-24 bg-slate-50 dark:bg-[#1e293b]/30 relative overflow-hidden border-t border-slate-100 dark:border-slate-800/50 transition-colors duration-200">
+        <!-- Background decorative elements -->
+        <div class="absolute top-0 left-0 w-full h-px bg-gradient-to-r from-transparent via-slate-200 dark:via-slate-700 to-transparent"></div>
+        <div class="absolute -top-40 -right-40 w-96 h-96 bg-indigo-400/10 dark:bg-indigo-500/10 rounded-full blur-[100px] pointer-events-none"></div>
+        <div class="absolute -bottom-40 -left-40 w-96 h-96 bg-sky-400/10 dark:bg-sky-500/10 rounded-full blur-[100px] pointer-events-none"></div>
+
+        <div class="max-w-7xl mx-auto px-6 relative z-10">
+            <div class="grid lg:grid-cols-2 gap-16 items-center">
+                <div>
+                    <span class="text-indigo-600 dark:text-indigo-400 font-semibold tracking-wider uppercase text-sm mb-3 block">Nossas Soluções</span>
+                    <h2 class="text-3xl md:text-5xl font-extrabold text-slate-900 dark:text-white mb-6 tracking-tight leading-tight">Visão de Gestor de Alto Nível</h2>
+                    <p class="text-lg text-slate-600 dark:text-slate-400 mb-8 leading-relaxed">
+                        Dashboards limpos e diretos construídos para líderes que não têm tempo a perder. Entenda a saúde das suas vendas e atendimento sem precisar de relatórios complexos.
+                    </p>
+                    
+                    <ul class="space-y-6">
+                        <li class="flex items-start gap-4">
+                            <div class="w-12 h-12 rounded-xl bg-white dark:bg-slate-800 border border-slate-100 dark:border-slate-700 shadow-sm dark:shadow-none flex items-center justify-center text-emerald-500 dark:text-emerald-400 shrink-0 mt-1">
+                                <Activity size={24} />
+                            </div>
+                            <div>
+                                <h4 class="text-xl font-bold text-slate-900 dark:text-white mb-2">Monitoramento de Humor</h4>
+                                <p class="text-slate-600 dark:text-slate-400 leading-relaxed">Visualize instantaneamente o estado emocional predominante da sua base de clientes através de um gráfico de radar inovador. Entenda os níveis de confiança, alegria ou frustração em tempo real.</p>
+                            </div>
+                        </li>
+                        <li class="flex items-start gap-4">
+                            <div class="w-12 h-12 rounded-xl bg-white dark:bg-slate-800 border border-slate-100 dark:border-slate-700 shadow-sm dark:shadow-none flex items-center justify-center text-sky-500 dark:text-sky-400 shrink-0 mt-1">
+                                <BarChart3 size={24} />
+                            </div>
+                            <div>
+                                <h4 class="text-xl font-bold text-slate-900 dark:text-white mb-2">Distribuição de Aspectos</h4>
+                                <p class="text-slate-600 dark:text-slate-400 leading-relaxed">Avalie o desempenho do seu produto, atendimento e logística separadamente. Veja claramente onde estão os maiores pontos de atrito (negativos) e de sucesso (positivos) da operação.</p>
+                            </div>
+                        </li>
+                        <li class="flex items-start gap-4">
+                            <div class="w-12 h-12 rounded-xl bg-white dark:bg-slate-800 border border-slate-100 dark:border-slate-700 shadow-sm dark:shadow-none flex items-center justify-center text-indigo-500 dark:text-indigo-400 shrink-0 mt-1">
+                                <Monitor size={24} />
+                            </div>
+                            <div>
+                                <h4 class="text-xl font-bold text-slate-900 dark:text-white mb-2">Fila Priorizada por Impacto $</h4>
+                                <p class="text-slate-600 dark:text-slate-400 leading-relaxed">Nosso algoritmo não ordena conversas apenas por tempo de espera, mas pelo risco financeiro atrelado à venda perdida e à probabilidade de fechamento.</p>
+                            </div>
+                        </li>
+                    </ul>
+                </div>
+
+                <!-- Abstract UI element representing the solutions -->
+                <div class="relative group">
+                    <div class="absolute inset-0 bg-gradient-to-tr from-indigo-500/10 to-sky-500/10 dark:from-indigo-500/20 dark:to-sky-500/20 rounded-3xl transform rotate-2 scale-105 blur-lg opacity-70 group-hover:rotate-3 transition-transform duration-500"></div>
+                    <div class="relative bg-white dark:bg-slate-800 border border-slate-100 dark:border-slate-700 rounded-3xl p-8 shadow-2xl dark:shadow-none transition-transform duration-500 hover:-translate-y-2">
+                        <!-- Mockup Radar Chart -->
+                        <div class="flex justify-between items-center mb-10">
+                            <div class="flex items-center gap-3">
+                                <div class="w-12 h-12 rounded-xl bg-indigo-50 dark:bg-indigo-500/10 text-indigo-600 dark:text-indigo-400 flex items-center justify-center border border-indigo-100 dark:border-transparent">
+                                    <Activity size={24} />
+                                </div>
+                                <div>
+                                    <h3 class="text-lg font-bold text-slate-900 dark:text-white">Humor da Base</h3>
+                                    <p class="text-xs text-slate-500 dark:text-slate-400 font-medium">Atualizado agora</p>
+                                </div>
+                            </div>
+                            <span class="px-3 py-1.5 bg-indigo-50 dark:bg-indigo-500/10 text-indigo-700 dark:text-indigo-400 rounded-lg text-xs font-semibold border border-indigo-100 dark:border-transparent">Tempo Real</span>
+                        </div>
+                        
+                        <div class="h-[280px] flex items-center justify-center relative mb-10 mt-6">
+                            <!-- Radar Hexagon Grid -->
+                            <div class="absolute w-[240px] h-[240px] flex items-center justify-center pointer-events-none opacity-20">
+                                <svg viewBox="0 0 100 100" class="w-full h-full stroke-slate-400 dark:stroke-slate-300 stroke-[0.5] fill-none">
+                                    <polygon points="50,5 95,28 95,72 50,95 5,72 5,28" />
+                                    <polygon points="50,20 80,38 80,62 50,80 20,62 20,38" />
+                                    <polygon points="50,35 65,44 65,56 50,65 35,56 35,44" />
+                                    
+                                    <!-- Axes -->
+                                    <line x1="50" y1="50" x2="50" y2="5" />
+                                    <line x1="50" y1="50" x2="95" y2="28" />
+                                    <line x1="50" y1="50" x2="95" y2="72" />
+                                    <line x1="50" y1="50" x2="50" y2="95" />
+                                    <line x1="50" y1="50" x2="5" y2="72" />
+                                    <line x1="50" y1="50" x2="5" y2="28" />
+                                </svg>
+                            </div>
+                            
+                            <!-- Radar Data Path -->
+                            <div class="absolute w-[240px] h-[240px] flex items-center justify-center drop-shadow-md">
+                                <svg viewBox="0 0 100 100" class="w-full h-full overflow-visible">
+                                    <!-- Area fill with gradient -->
+                                    <defs>
+                                        <linearGradient id="radarGrad" x1="0%" y1="0%" x2="100%" y2="100%">
+                                            <stop offset="0%" stop-color="#10b981" stop-opacity="0.4" />
+                                            <stop offset="100%" stop-color="#3b82f6" stop-opacity="0.1" />
+                                        </linearGradient>
+                                    </defs>
+                                    
+                                    <polygon points="50,15 85,35 70,80 40,70 15,45 25,25" 
+                                             class="fill-[url(#radarGrad)] stroke-emerald-500 dark:stroke-emerald-400 stroke-[1.5] transition-all duration-1000 ease-in-out group-hover:scale-105 origin-center animate-[pulse_4s_ease-in-out_infinite]" />
+                                    
+                                    <!-- Points -->
+                                    <circle cx="50" cy="15" r="2.5" class="fill-white dark:fill-slate-900 stroke-emerald-500 dark:stroke-emerald-400 stroke-2" />
+                                    <circle cx="85" cy="35" r="2.5" class="fill-white dark:fill-slate-900 stroke-emerald-500 dark:stroke-emerald-400 stroke-2" />
+                                    <circle cx="70" cy="80" r="2.5" class="fill-white dark:fill-slate-900 stroke-emerald-500 dark:stroke-emerald-400 stroke-2" />
+                                    <circle cx="40" cy="70" r="2.5" class="fill-white dark:fill-slate-900 stroke-emerald-500 dark:stroke-emerald-400 stroke-2" />
+                                    <circle cx="15" cy="45" r="2.5" class="fill-white dark:fill-slate-900 stroke-emerald-500 dark:stroke-emerald-400 stroke-2" />
+                                    <circle cx="25" cy="25" r="2.5" class="fill-white dark:fill-slate-900 stroke-emerald-500 dark:stroke-emerald-400 stroke-2" />
+                                </svg>
+                            </div>
+                            
+                            <!-- Labels -->
+                            <div class="absolute inset-0 font-semibold text-[11px] text-slate-500 dark:text-slate-400">
+                                <span class="absolute top-[-10px] left-1/2 -translate-x-1/2 text-slate-800 dark:text-slate-200">Confiança <span class="text-indigo-600 dark:text-indigo-400 block text-center">85%</span></span>
+                                <span class="absolute top-[20%] right-[-20px] text-slate-800 dark:text-slate-200">Alegria <span class="text-emerald-500 dark:text-emerald-400 block">92%</span></span>
+                                <span class="absolute bottom-[20%] right-[-20px] text-slate-800 dark:text-slate-200">Surpresa <span class="text-sky-500 dark:text-sky-400 block">60%</span></span>
+                                <span class="absolute bottom-[-15px] left-1/2 -translate-x-1/2 text-slate-800 dark:text-slate-200">Tristeza <span class="text-red-500 dark:text-red-400 block text-center">15%</span></span>
+                                <span class="absolute bottom-[20%] left-[-15px] text-slate-800 dark:text-slate-200">Raiva <span class="text-red-500 dark:text-red-400 block text-right">25%</span></span>
+                                <span class="absolute top-[20%] left-[-15px] text-slate-800 dark:text-slate-200">Medo <span class="text-amber-500 dark:text-amber-400 block text-right">40%</span></span>
+                            </div>
+                        </div>
+
+                        <!-- Mockup Progress Bars -->
+                        <div class="space-y-5 bg-slate-50 dark:bg-slate-900/50 p-5 rounded-2xl border border-slate-100 dark:border-slate-700/50">
+                            <div>
+                                <div class="flex justify-between text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
+                                    <span>Atendimento</span>
+                                    <span class="text-slate-500 dark:text-slate-400 font-medium">370 interações</span>
+                                </div>
+                                <div class="h-2.5 w-full bg-slate-200 dark:bg-slate-700 rounded-full overflow-hidden flex shadow-inner">
+                                    <div class="h-full bg-emerald-500 w-[85%]"></div>
+                                    <div class="h-full bg-red-500 w-[15%]"></div>
+                                </div>
+                            </div>
+                            <div>
+                                <div class="flex justify-between text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
+                                    <span>Produto</span>
+                                    <span class="text-slate-500 dark:text-slate-400 font-medium">170 interações</span>
+                                </div>
+                                <div class="h-2.5 w-full bg-slate-200 dark:bg-slate-700 rounded-full overflow-hidden flex shadow-inner">
+                                    <div class="h-full bg-emerald-500 w-[65%]"></div>
+                                    <div class="h-full bg-amber-400 w-[20%]"></div>
+                                    <div class="h-full bg-red-500 w-[15%]"></div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </section>
+    
+    <!-- Footer -->
+    <footer class="bg-slate-900 text-slate-400 py-12 border-t border-slate-800">
+        <div class="max-w-7xl mx-auto px-6 flex flex-col md:flex-row justify-between items-center gap-6">
+            <div class="flex items-center gap-2">
+                <div class="h-6 flex items-center opacity-70 hover:opacity-100 transition-opacity grayscale hover:grayscale-0">
+                    <img src={logoWhite} alt="NetTown Analytics" class="h-full w-auto" />
+                </div>
+            </div>
+            <p class="text-sm">
+                &copy; {new Date().getFullYear()} Nettown Analytics. Todos os direitos reservados.
+            </p>
+        </div>
+    </footer>
+</div>

+ 144 - 0
src/routes/(public)/login/+page.svelte

@@ -0,0 +1,144 @@
+<script>
+    import { ArrowRight, Mail, Lock, AlertCircle, TrendingUp, Moon, Sun } from 'lucide-svelte';
+    import { goto } from '$app/navigation';
+    import { onMount } from 'svelte';
+    import { theme, toggleTheme } from '$lib/core/stores/theme';
+    import logoWhite from '$lib/assets/images/nettown_white_logo.svg';
+    import logoBlack from '$lib/assets/images/nettown_black_logo.svg.svg';
+
+    let email = $state('');
+    let password = $state('');
+    let isLoading = $state(false);
+    let error = $state('');
+    let currentTheme = $state('light');
+
+    onMount(() => {
+        const unsubscribe = theme.subscribe(val => {
+            currentTheme = val;
+        });
+        return unsubscribe;
+    });
+
+    async function handleLogin(e) {
+        e.preventDefault();
+        isLoading = true;
+        error = '';
+
+        // Mock login
+        setTimeout(() => {
+            if (email === 'admin@nettown.com' && password === 'admin') {
+                goto('/dashboard');
+            } else {
+                error = 'Credenciais inválidas. Use admin@nettown.com / admin';
+                isLoading = false;
+            }
+        }, 1000);
+    }
+</script>
+
+<svelte:head>
+    <title>Login - Nettown Analytics</title>
+</svelte:head>
+
+<!-- Theme Toggle Button Top Right -->
+<div class="fixed top-6 right-6 z-50">
+    <button 
+        onclick={toggleTheme} 
+        class="p-2.5 text-slate-500 dark:text-slate-400 hover:text-indigo-600 dark:hover:text-indigo-400 rounded-full hover:bg-slate-200 dark:hover:bg-slate-800 transition-colors bg-white dark:bg-slate-900 shadow-sm border border-slate-200 dark:border-slate-800"
+        title={currentTheme === 'dark' ? 'Mudar para modo claro' : 'Mudar para modo escuro'}
+    >
+        {#if currentTheme === 'dark'}
+            <Sun size={20} />
+        {:else}
+            <Moon size={20} />
+        {/if}
+    </button>
+</div>
+
+<div class="min-h-screen bg-slate-50 dark:bg-[#0f172a] flex items-center justify-center p-6 selection:bg-indigo-100 dark:selection:bg-indigo-500/30 selection:text-indigo-900 dark:selection:text-indigo-200 transition-colors duration-200">
+    <div class="w-full max-w-md">
+        <!-- Logo -->
+        <div class="flex flex-col items-center justify-center mb-8">
+            <div class="h-10 flex items-center mb-4">
+                <img src={currentTheme === 'dark' ? logoWhite : logoBlack} alt="NetTown Analytics" class="h-full w-auto transition-opacity" />
+            </div>
+            <p class="text-slate-500 dark:text-slate-400 mt-1">Inteligência em conversões e atendimento</p>
+        </div>
+
+        <!-- Login Card -->
+        <div class="bg-white dark:bg-[#1e293b] rounded-2xl shadow-xl shadow-slate-200/50 dark:shadow-none border border-slate-100 dark:border-slate-800 overflow-hidden transition-colors duration-200">
+            <div class="p-8">
+                <h2 class="text-xl font-bold text-slate-900 dark:text-white mb-6">Acesse sua conta</h2>
+
+                {#if error}
+                    <div class="mb-6 p-4 rounded-xl bg-red-50 dark:bg-red-500/10 border border-red-100 dark:border-red-500/20 flex items-start gap-3 text-red-600 dark:text-red-400 text-sm transition-colors duration-200">
+                        <AlertCircle size={18} class="shrink-0 mt-0.5" />
+                        <p>{error}</p>
+                    </div>
+                {/if}
+
+                <form onsubmit={handleLogin} class="space-y-5">
+                    <div class="space-y-1.5">
+                        <label for="email" class="text-sm font-medium text-slate-700 dark:text-slate-300">Email corporativo</label>
+                        <div class="relative">
+                            <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-slate-400 dark:text-slate-500">
+                                <Mail size={18} />
+                            </div>
+                            <input 
+                                type="email" 
+                                id="email" 
+                                bind:value={email}
+                                required
+                                class="block w-full pl-10 pr-3 py-2.5 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-900 dark:text-white placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 dark:focus:ring-indigo-500/40 focus:border-indigo-500 dark:focus:border-indigo-400 transition-colors"
+                                placeholder="voce@empresa.com"
+                            />
+                        </div>
+                    </div>
+
+                    <div class="space-y-1.5">
+                        <div class="flex items-center justify-between">
+                            <label for="password" class="text-sm font-medium text-slate-700 dark:text-slate-300">Senha</label>
+                            <a href="/" class="text-sm font-medium text-indigo-600 dark:text-indigo-400 hover:text-indigo-700 dark:hover:text-indigo-300 transition-colors">Esqueceu a senha?</a>
+                        </div>
+                        <div class="relative">
+                            <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-slate-400 dark:text-slate-500">
+                                <Lock size={18} />
+                            </div>
+                            <input 
+                                type="password" 
+                                id="password" 
+                                bind:value={password}
+                                required
+                                class="block w-full pl-10 pr-3 py-2.5 border border-slate-200 dark:border-slate-700 rounded-xl bg-slate-50 dark:bg-slate-900 text-slate-900 dark:text-white placeholder-slate-400 dark:placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-indigo-500/20 dark:focus:ring-indigo-500/40 focus:border-indigo-500 dark:focus:border-indigo-400 transition-colors"
+                                placeholder="••••••••"
+                            />
+                        </div>
+                    </div>
+
+                    <button 
+                        type="submit" 
+                        disabled={isLoading}
+                        class="w-full flex items-center justify-center gap-2 py-3 px-4 border border-transparent rounded-xl shadow-sm dark:shadow-none text-sm font-semibold text-white bg-indigo-600 hover:bg-indigo-700 dark:bg-indigo-500 dark:hover:bg-indigo-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-70 disabled:cursor-not-allowed transition-all mt-2"
+                    >
+                        {#if isLoading}
+                            <span class="w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin"></span>
+                            <span>Entrando...</span>
+                        {:else}
+                            <span>Entrar no Dashboard</span>
+                            <ArrowRight size={18} />
+                        {/if}
+                    </button>
+                </form>
+            </div>
+            <div class="bg-slate-50 dark:bg-slate-800/50 px-8 py-4 border-t border-slate-100 dark:border-slate-800 text-center transition-colors duration-200">
+                <p class="text-sm text-slate-500 dark:text-slate-400">
+                    Ainda não tem uma conta? <a href="/" class="font-medium text-indigo-600 dark:text-indigo-400 hover:text-indigo-700 dark:hover:text-indigo-300 transition-colors">Fale com vendas</a>
+                </p>
+            </div>
+        </div>
+        
+        <div class="mt-8 text-center text-xs text-slate-400 dark:text-slate-500 transition-colors">
+            <p>Dica para testar: use admin@nettown.com / admin</p>
+        </div>
+    </div>
+</div>

+ 9 - 0
src/routes/+layout.svelte

@@ -0,0 +1,9 @@
+<script>
+	import './layout.css';
+	import favicon from '$lib/assets/favicon.ico';
+
+	let { children } = $props();
+</script>
+
+<svelte:head><link rel="icon" href={favicon} /></svelte:head>
+{@render children()}

+ 48 - 0
src/routes/layout.css

@@ -0,0 +1,48 @@
+@import 'tailwindcss';
+
+@theme {
+    --color-background: var(--bg-color);
+    --color-foreground: var(--text-color);
+}
+
+@custom-variant dark (&:is(.dark *));
+
+@layer base {
+    :root {
+        --bg-color: #f8fafc; /* slate-50 */
+        --text-color: #0f172a; /* slate-900 */
+        --scrollbar-thumb: #818cf8; /* indigo-400 */
+        --scrollbar-track: transparent;
+    }
+
+    .dark {
+        --bg-color: #0f172a; /* slate-900 */
+        --text-color: #f8fafc; /* slate-50 */
+        --scrollbar-thumb: #4f46e5; /* indigo-600 */
+        --scrollbar-track: transparent;
+    }
+
+    body {
+        background-color: var(--bg-color);
+        color: var(--text-color);
+    }
+    
+    /* Custom Scrollbar Styles */
+    ::-webkit-scrollbar {
+        width: 6px;
+        height: 6px;
+    }
+
+    ::-webkit-scrollbar-track {
+        background: var(--scrollbar-track);
+    }
+
+    ::-webkit-scrollbar-thumb {
+        background: var(--scrollbar-thumb);
+        border-radius: 10px;
+    }
+
+    ::-webkit-scrollbar-thumb:hover {
+        background: #6366f1; /* indigo-500 */
+    }
+}

+ 3 - 0
static/robots.txt

@@ -0,0 +1,3 @@
+# allow crawling everything by default
+User-agent: *
+Disallow:

+ 12 - 0
svelte.config.js

@@ -0,0 +1,12 @@
+import adapter from '@sveltejs/adapter-static';
+
+/** @type {import('@sveltejs/kit').Config} */
+const config = {
+	compilerOptions: {
+		// Force runes mode for the project, except for libraries. Can be removed in svelte 6.
+		runes: ({ filename }) => (filename.split(/[/\\]/).includes('node_modules') ? undefined : true)
+	},
+	kit: { adapter: adapter() }
+};
+
+export default config;

+ 5 - 0
vite.config.js

@@ -0,0 +1,5 @@
+import tailwindcss from '@tailwindcss/vite';
+import { sveltekit } from '@sveltejs/kit/vite';
+import { defineConfig } from 'vite';
+
+export default defineConfig({ plugins: [tailwindcss(), sveltekit()] });