Index: frontend/.gitignore
===================================================================
--- frontend/.gitignore	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ frontend/.gitignore	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -12,5 +12,4 @@
 dist-ssr
 *.local
-.env.local
 
 # Editor directories and files
Index: frontend/Dockerfile
===================================================================
--- frontend/Dockerfile	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,11 +1,0 @@
-FROM node:22-alpine AS build
-WORKDIR /app
-COPY package*.json ./
-RUN npm ci --legacy-peer-deps
-COPY . .
-RUN VITE_API_BASE_URL=/api npm run build
-
-FROM nginx:alpine
-COPY --from=build /app/dist /usr/share/nginx/html
-COPY nginx.conf /etc/nginx/conf.d/default.conf
-EXPOSE 80
Index: frontend/index.html
===================================================================
--- frontend/index.html	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ frontend/index.html	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -3,7 +3,7 @@
   <head>
     <meta charset="UTF-8" />
-    <link rel="icon" type="image/svg+xml" href="/favicon.png" />
+    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>Trekr</title>
+    <title>frontend</title>
   </head>
   <body>
Index: frontend/nginx.conf
===================================================================
--- frontend/nginx.conf	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,31 +1,0 @@
-server {
-    listen 80;
-
-    root /usr/share/nginx/html;
-    index index.html;
-
-    # Proxy API calls to the backend container
-    location /api/ {
-        proxy_pass http://backend:8080/api/;
-        proxy_set_header Host $host;
-        proxy_set_header X-Real-IP $remote_addr;
-    }
-
-    # Yahoo Finance proxy (replaces the Vite dev proxy)
-    location /yahoo/ {
-        proxy_pass https://query1.finance.yahoo.com/;
-        proxy_ssl_server_name on;
-        proxy_set_header Host query1.finance.yahoo.com;
-    }
-
-    location /yahoo2/ {
-        proxy_pass https://query2.finance.yahoo.com/;
-        proxy_ssl_server_name on;
-        proxy_set_header Host query2.finance.yahoo.com;
-    }
-
-    # SPA fallback
-    location / {
-        try_files $uri $uri/ /index.html;
-    }
-}
Index: frontend/package-lock.json
===================================================================
--- frontend/package-lock.json	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ frontend/package-lock.json	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -9,48 +9,19 @@
       "version": "0.0.0",
       "dependencies": {
-        "@dnd-kit/core": "^6.3.1",
-        "@dnd-kit/sortable": "^10.0.0",
-        "@dnd-kit/utilities": "^3.2.2",
-        "@relume_io/relume-tailwind": "^1.3.0",
-        "@relume_io/relume-ui": "^1.3.1",
-        "@tailwindcss/vite": "^4.1.18",
-        "apexcharts": "^5.10.6",
         "axios": "^1.13.4",
-        "daisyui": "^5.5.18",
         "react": "^19.2.0",
-        "react-apexcharts": "^2.1.0",
         "react-dom": "^19.2.0",
-        "react-icons": "^5.5.0",
-        "react-is": "^19.2.5",
         "react-router-dom": "^7.13.0"
       },
       "devDependencies": {
         "@eslint/js": "^9.39.1",
-        "@tailwindcss/cli": "^4.1.18",
-        "@tailwindcss/postcss": "^4.1.18",
         "@types/react": "^19.2.5",
         "@types/react-dom": "^19.2.3",
         "@vitejs/plugin-react": "^5.1.1",
-        "autoprefixer": "^10.4.24",
         "eslint": "^9.39.1",
         "eslint-plugin-react-hooks": "^7.0.1",
         "eslint-plugin-react-refresh": "^0.4.24",
         "globals": "^16.5.0",
-        "postcss": "^8.5.6",
-        "tailwindcss": "^4.1.18",
         "vite": "^7.2.4"
-      }
-    },
-    "node_modules/@alloc/quick-lru": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
-      "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
@@ -337,63 +308,4 @@
       }
     },
-    "node_modules/@date-fns/tz": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/@date-fns/tz/-/tz-1.4.1.tgz",
-      "integrity": "sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==",
-      "license": "MIT"
-    },
-    "node_modules/@dnd-kit/accessibility": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz",
-      "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==",
-      "license": "MIT",
-      "dependencies": {
-        "tslib": "^2.0.0"
-      },
-      "peerDependencies": {
-        "react": ">=16.8.0"
-      }
-    },
-    "node_modules/@dnd-kit/core": {
-      "version": "6.3.1",
-      "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz",
-      "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@dnd-kit/accessibility": "^3.1.1",
-        "@dnd-kit/utilities": "^3.2.2",
-        "tslib": "^2.0.0"
-      },
-      "peerDependencies": {
-        "react": ">=16.8.0",
-        "react-dom": ">=16.8.0"
-      }
-    },
-    "node_modules/@dnd-kit/sortable": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-10.0.0.tgz",
-      "integrity": "sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==",
-      "license": "MIT",
-      "dependencies": {
-        "@dnd-kit/utilities": "^3.2.2",
-        "tslib": "^2.0.0"
-      },
-      "peerDependencies": {
-        "@dnd-kit/core": "^6.3.0",
-        "react": ">=16.8.0"
-      }
-    },
-    "node_modules/@dnd-kit/utilities": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz",
-      "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==",
-      "license": "MIT",
-      "dependencies": {
-        "tslib": "^2.0.0"
-      },
-      "peerDependencies": {
-        "react": ">=16.8.0"
-      }
-    },
     "node_modules/@esbuild/aix-ppc64": {
       "version": "0.27.3",
@@ -995,51 +907,4 @@
       }
     },
-    "node_modules/@floating-ui/core": {
-      "version": "1.7.4",
-      "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.4.tgz",
-      "integrity": "sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==",
-      "license": "MIT",
-      "dependencies": {
-        "@floating-ui/utils": "^0.2.10"
-      }
-    },
-    "node_modules/@floating-ui/dom": {
-      "version": "1.7.5",
-      "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.5.tgz",
-      "integrity": "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==",
-      "license": "MIT",
-      "dependencies": {
-        "@floating-ui/core": "^1.7.4",
-        "@floating-ui/utils": "^0.2.10"
-      }
-    },
-    "node_modules/@floating-ui/react-dom": {
-      "version": "2.1.7",
-      "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.7.tgz",
-      "integrity": "sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg==",
-      "license": "MIT",
-      "dependencies": {
-        "@floating-ui/dom": "^1.7.5"
-      },
-      "peerDependencies": {
-        "react": ">=16.8.0",
-        "react-dom": ">=16.8.0"
-      }
-    },
-    "node_modules/@floating-ui/utils": {
-      "version": "0.2.10",
-      "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
-      "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==",
-      "license": "MIT"
-    },
-    "node_modules/@hookform/resolvers": {
-      "version": "3.10.0",
-      "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.10.0.tgz",
-      "integrity": "sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==",
-      "license": "MIT",
-      "peerDependencies": {
-        "react-hook-form": "^7.0.0"
-      }
-    },
     "node_modules/@humanfs/core": {
       "version": "0.19.1",
@@ -1098,4 +963,5 @@
       "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
       "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -1108,4 +974,5 @@
       "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
       "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -1118,4 +985,5 @@
       "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
       "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+      "dev": true,
       "license": "MIT",
       "engines": {
@@ -1127,4 +995,5 @@
       "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
       "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+      "dev": true,
       "license": "MIT"
     },
@@ -1133,3778 +1002,9 @@
       "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
       "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@jridgewell/resolve-uri": "^3.1.0",
         "@jridgewell/sourcemap-codec": "^1.4.14"
-      }
-    },
-    "node_modules/@parcel/watcher": {
-      "version": "2.5.6",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz",
-      "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==",
-      "dev": true,
-      "hasInstallScript": true,
-      "license": "MIT",
-      "dependencies": {
-        "detect-libc": "^2.0.3",
-        "is-glob": "^4.0.3",
-        "node-addon-api": "^7.0.0",
-        "picomatch": "^4.0.3"
-      },
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      },
-      "optionalDependencies": {
-        "@parcel/watcher-android-arm64": "2.5.6",
-        "@parcel/watcher-darwin-arm64": "2.5.6",
-        "@parcel/watcher-darwin-x64": "2.5.6",
-        "@parcel/watcher-freebsd-x64": "2.5.6",
-        "@parcel/watcher-linux-arm-glibc": "2.5.6",
-        "@parcel/watcher-linux-arm-musl": "2.5.6",
-        "@parcel/watcher-linux-arm64-glibc": "2.5.6",
-        "@parcel/watcher-linux-arm64-musl": "2.5.6",
-        "@parcel/watcher-linux-x64-glibc": "2.5.6",
-        "@parcel/watcher-linux-x64-musl": "2.5.6",
-        "@parcel/watcher-win32-arm64": "2.5.6",
-        "@parcel/watcher-win32-ia32": "2.5.6",
-        "@parcel/watcher-win32-x64": "2.5.6"
-      }
-    },
-    "node_modules/@parcel/watcher-android-arm64": {
-      "version": "2.5.6",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz",
-      "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-darwin-arm64": {
-      "version": "2.5.6",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz",
-      "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-darwin-x64": {
-      "version": "2.5.6",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz",
-      "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-freebsd-x64": {
-      "version": "2.5.6",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz",
-      "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-linux-arm-glibc": {
-      "version": "2.5.6",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz",
-      "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-linux-arm-musl": {
-      "version": "2.5.6",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz",
-      "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==",
-      "cpu": [
-        "arm"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-linux-arm64-glibc": {
-      "version": "2.5.6",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz",
-      "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-linux-arm64-musl": {
-      "version": "2.5.6",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz",
-      "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-linux-x64-glibc": {
-      "version": "2.5.6",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz",
-      "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-linux-x64-musl": {
-      "version": "2.5.6",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz",
-      "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-win32-arm64": {
-      "version": "2.5.6",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz",
-      "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==",
-      "cpu": [
-        "arm64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-win32-ia32": {
-      "version": "2.5.6",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz",
-      "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==",
-      "cpu": [
-        "ia32"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@parcel/watcher-win32-x64": {
-      "version": "2.5.6",
-      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz",
-      "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==",
-      "cpu": [
-        "x64"
-      ],
-      "dev": true,
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">= 10.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
-    "node_modules/@radix-ui/number": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz",
-      "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==",
-      "license": "MIT"
-    },
-    "node_modules/@radix-ui/primitive": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
-      "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==",
-      "license": "MIT"
-    },
-    "node_modules/@radix-ui/react-accordion": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.2.tgz",
-      "integrity": "sha512-b1oh54x4DMCdGsB4/7ahiSrViXxaBwRPotiZNnYXjLha9vfuURSAZErki6qjDoSIV0eXx5v57XnTGVtGwnfp2g==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.1",
-        "@radix-ui/react-collapsible": "1.1.2",
-        "@radix-ui/react-collection": "1.1.1",
-        "@radix-ui/react-compose-refs": "1.1.1",
-        "@radix-ui/react-context": "1.1.1",
-        "@radix-ui/react-direction": "1.1.0",
-        "@radix-ui/react-id": "1.1.0",
-        "@radix-ui/react-primitive": "2.0.1",
-        "@radix-ui/react-use-controllable-state": "1.1.0"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-collapsible": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.2.tgz",
-      "integrity": "sha512-PliMB63vxz7vggcyq0IxNYk8vGDrLXVWw4+W4B8YnwI1s18x7YZYqlG9PLX7XxAJUi0g2DxP4XKJMFHh/iVh9A==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.1",
-        "@radix-ui/react-compose-refs": "1.1.1",
-        "@radix-ui/react-context": "1.1.1",
-        "@radix-ui/react-id": "1.1.0",
-        "@radix-ui/react-presence": "1.1.2",
-        "@radix-ui/react-primitive": "2.0.1",
-        "@radix-ui/react-use-controllable-state": "1.1.0",
-        "@radix-ui/react-use-layout-effect": "1.1.0"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-use-layout-effect": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
-      "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-arrow": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz",
-      "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-primitive": "2.1.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
-      "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-primitive": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
-      "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-arrow/node_modules/@radix-ui/react-slot": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
-      "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-checkbox": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.3.tgz",
-      "integrity": "sha512-HD7/ocp8f1B3e6OHygH0n7ZKjONkhciy1Nh0yuBgObqThc3oyx+vuMfFHKAknXRHHWVE9XvXStxJFyjUmB8PIw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.1",
-        "@radix-ui/react-compose-refs": "1.1.1",
-        "@radix-ui/react-context": "1.1.1",
-        "@radix-ui/react-presence": "1.1.2",
-        "@radix-ui/react-primitive": "2.0.1",
-        "@radix-ui/react-use-controllable-state": "1.1.0",
-        "@radix-ui/react-use-previous": "1.1.0",
-        "@radix-ui/react-use-size": "1.1.0"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-collapsible": {
-      "version": "1.1.12",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz",
-      "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.3",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-id": "1.1.1",
-        "@radix-ui/react-presence": "1.1.5",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-controllable-state": "1.2.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/primitive": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
-      "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
-      "license": "MIT"
-    },
-    "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
-      "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-context": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
-      "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-id": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
-      "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-presence": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
-      "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-primitive": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
-      "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-slot": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
-      "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-use-controllable-state": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
-      "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-effect-event": "0.0.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-collection": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.1.tgz",
-      "integrity": "sha512-LwT3pSho9Dljg+wY2KN2mrrh6y3qELfftINERIzBUO9e0N+t0oMTyn3k9iv+ZqgrwGkRnLpNJrsMv9BZlt2yuA==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.1",
-        "@radix-ui/react-context": "1.1.1",
-        "@radix-ui/react-primitive": "2.0.1",
-        "@radix-ui/react-slot": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz",
-      "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz",
-      "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-context": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
-      "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-dialog": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.4.tgz",
-      "integrity": "sha512-Ur7EV1IwQGCyaAuyDRiOLA5JIUZxELJljF+MbM/2NC0BYwfuRrbpS30BiQBJrVruscgUkieKkqXYDOoByaxIoA==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.1",
-        "@radix-ui/react-compose-refs": "1.1.1",
-        "@radix-ui/react-context": "1.1.1",
-        "@radix-ui/react-dismissable-layer": "1.1.3",
-        "@radix-ui/react-focus-guards": "1.1.1",
-        "@radix-ui/react-focus-scope": "1.1.1",
-        "@radix-ui/react-id": "1.1.0",
-        "@radix-ui/react-portal": "1.1.3",
-        "@radix-ui/react-presence": "1.1.2",
-        "@radix-ui/react-primitive": "2.0.1",
-        "@radix-ui/react-slot": "1.1.1",
-        "@radix-ui/react-use-controllable-state": "1.1.0",
-        "aria-hidden": "^1.1.1",
-        "react-remove-scroll": "^2.6.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz",
-      "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-direction": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz",
-      "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-dismissable-layer": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz",
-      "integrity": "sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.1",
-        "@radix-ui/react-compose-refs": "1.1.1",
-        "@radix-ui/react-primitive": "2.0.1",
-        "@radix-ui/react-use-callback-ref": "1.1.0",
-        "@radix-ui/react-use-escape-keydown": "1.1.0"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-dropdown-menu": {
-      "version": "2.1.16",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz",
-      "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.3",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-id": "1.1.1",
-        "@radix-ui/react-menu": "2.1.16",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-controllable-state": "1.2.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/primitive": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
-      "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
-      "license": "MIT"
-    },
-    "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
-      "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-context": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
-      "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-id": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
-      "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-primitive": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
-      "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-slot": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
-      "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-use-controllable-state": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
-      "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-effect-event": "0.0.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-focus-guards": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz",
-      "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-focus-scope": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.1.tgz",
-      "integrity": "sha512-01omzJAYRxXdG2/he/+xy+c8a8gCydoQ1yOxnWNcRhrrBW5W+RQJ22EK1SaO8tb3WoUsuEw7mJjBozPzihDFjA==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.1",
-        "@radix-ui/react-primitive": "2.0.1",
-        "@radix-ui/react-use-callback-ref": "1.1.0"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-id": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
-      "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-layout-effect": "1.1.0"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-id/node_modules/@radix-ui/react-use-layout-effect": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
-      "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-label": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.1.tgz",
-      "integrity": "sha512-UUw5E4e/2+4kFMH7+YxORXGWggtY6sM8WIwh5RZchhLuUg2H1hc98Py+pr8HMz6rdaYrK2t296ZEjYLOCO5uUw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-primitive": "2.0.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu": {
-      "version": "2.1.16",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz",
-      "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.3",
-        "@radix-ui/react-collection": "1.1.7",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-direction": "1.1.1",
-        "@radix-ui/react-dismissable-layer": "1.1.11",
-        "@radix-ui/react-focus-guards": "1.1.3",
-        "@radix-ui/react-focus-scope": "1.1.7",
-        "@radix-ui/react-id": "1.1.1",
-        "@radix-ui/react-popper": "1.2.8",
-        "@radix-ui/react-portal": "1.1.9",
-        "@radix-ui/react-presence": "1.1.5",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-roving-focus": "1.1.11",
-        "@radix-ui/react-slot": "1.2.3",
-        "@radix-ui/react-use-callback-ref": "1.1.1",
-        "aria-hidden": "^1.2.4",
-        "react-remove-scroll": "^2.6.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/primitive": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
-      "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
-      "license": "MIT"
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-collection": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
-      "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
-      "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-context": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
-      "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-direction": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
-      "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-dismissable-layer": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
-      "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.3",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-callback-ref": "1.1.1",
-        "@radix-ui/react-use-escape-keydown": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-focus-guards": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz",
-      "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-focus-scope": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz",
-      "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-callback-ref": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-id": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
-      "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-portal": {
-      "version": "1.1.9",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
-      "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-presence": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
-      "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-primitive": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
-      "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-slot": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
-      "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-use-callback-ref": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
-      "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-use-escape-keydown": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz",
-      "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-callback-ref": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popover": {
-      "version": "1.1.15",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz",
-      "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.3",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-dismissable-layer": "1.1.11",
-        "@radix-ui/react-focus-guards": "1.1.3",
-        "@radix-ui/react-focus-scope": "1.1.7",
-        "@radix-ui/react-id": "1.1.1",
-        "@radix-ui/react-popper": "1.2.8",
-        "@radix-ui/react-portal": "1.1.9",
-        "@radix-ui/react-presence": "1.1.5",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-slot": "1.2.3",
-        "@radix-ui/react-use-controllable-state": "1.2.2",
-        "aria-hidden": "^1.2.4",
-        "react-remove-scroll": "^2.6.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/primitive": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
-      "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
-      "license": "MIT"
-    },
-    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
-      "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-context": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
-      "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-dismissable-layer": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
-      "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.3",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-callback-ref": "1.1.1",
-        "@radix-ui/react-use-escape-keydown": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-focus-guards": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz",
-      "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-focus-scope": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz",
-      "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-callback-ref": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-id": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
-      "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-portal": {
-      "version": "1.1.9",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
-      "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-presence": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
-      "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-primitive": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
-      "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
-      "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-callback-ref": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
-      "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-controllable-state": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
-      "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-effect-event": "0.0.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-escape-keydown": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz",
-      "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-callback-ref": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popper": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz",
-      "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==",
-      "license": "MIT",
-      "dependencies": {
-        "@floating-ui/react-dom": "^2.0.0",
-        "@radix-ui/react-arrow": "1.1.7",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-callback-ref": "1.1.1",
-        "@radix-ui/react-use-layout-effect": "1.1.1",
-        "@radix-ui/react-use-rect": "1.1.1",
-        "@radix-ui/react-use-size": "1.1.1",
-        "@radix-ui/rect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
-      "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-context": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
-      "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-primitive": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
-      "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-slot": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
-      "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-use-callback-ref": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
-      "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-use-size": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz",
-      "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-portal": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz",
-      "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-primitive": "2.0.1",
-        "@radix-ui/react-use-layout-effect": "1.1.0"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-portal/node_modules/@radix-ui/react-use-layout-effect": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
-      "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-presence": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz",
-      "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.1",
-        "@radix-ui/react-use-layout-effect": "1.1.0"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-presence/node_modules/@radix-ui/react-use-layout-effect": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
-      "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-primitive": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz",
-      "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz",
-      "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-radio-group": {
-      "version": "1.3.8",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.8.tgz",
-      "integrity": "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.3",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-direction": "1.1.1",
-        "@radix-ui/react-presence": "1.1.5",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-roving-focus": "1.1.11",
-        "@radix-ui/react-use-controllable-state": "1.2.2",
-        "@radix-ui/react-use-previous": "1.1.1",
-        "@radix-ui/react-use-size": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/primitive": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
-      "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
-      "license": "MIT"
-    },
-    "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
-      "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-context": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
-      "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-direction": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
-      "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-presence": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
-      "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-primitive": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
-      "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-slot": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
-      "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-use-controllable-state": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
-      "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-effect-event": "0.0.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-use-previous": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz",
-      "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-use-size": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz",
-      "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-roving-focus": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz",
-      "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.3",
-        "@radix-ui/react-collection": "1.1.7",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-direction": "1.1.1",
-        "@radix-ui/react-id": "1.1.1",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-callback-ref": "1.1.1",
-        "@radix-ui/react-use-controllable-state": "1.2.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/primitive": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
-      "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
-      "license": "MIT"
-    },
-    "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-collection": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
-      "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
-      "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-context": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
-      "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-direction": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
-      "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-id": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
-      "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-primitive": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
-      "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-slot": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
-      "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-use-callback-ref": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
-      "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-use-controllable-state": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
-      "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-effect-event": "0.0.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select": {
-      "version": "2.2.6",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz",
-      "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/number": "1.1.1",
-        "@radix-ui/primitive": "1.1.3",
-        "@radix-ui/react-collection": "1.1.7",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-direction": "1.1.1",
-        "@radix-ui/react-dismissable-layer": "1.1.11",
-        "@radix-ui/react-focus-guards": "1.1.3",
-        "@radix-ui/react-focus-scope": "1.1.7",
-        "@radix-ui/react-id": "1.1.1",
-        "@radix-ui/react-popper": "1.2.8",
-        "@radix-ui/react-portal": "1.1.9",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-slot": "1.2.3",
-        "@radix-ui/react-use-callback-ref": "1.1.1",
-        "@radix-ui/react-use-controllable-state": "1.2.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1",
-        "@radix-ui/react-use-previous": "1.1.1",
-        "@radix-ui/react-visually-hidden": "1.2.3",
-        "aria-hidden": "^1.2.4",
-        "react-remove-scroll": "^2.6.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/primitive": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
-      "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
-      "license": "MIT"
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-collection": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
-      "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
-      "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-context": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
-      "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-direction": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
-      "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-dismissable-layer": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
-      "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.3",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-callback-ref": "1.1.1",
-        "@radix-ui/react-use-escape-keydown": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-focus-guards": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz",
-      "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-focus-scope": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz",
-      "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-callback-ref": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-id": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
-      "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-portal": {
-      "version": "1.1.9",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
-      "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-primitive": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
-      "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
-      "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-callback-ref": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
-      "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-controllable-state": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
-      "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-effect-event": "0.0.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-escape-keydown": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz",
-      "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-callback-ref": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-previous": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz",
-      "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-separator": {
-      "version": "1.1.8",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.8.tgz",
-      "integrity": "sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-primitive": "2.1.4"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive": {
-      "version": "2.1.4",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz",
-      "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.2.4"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-slider": {
-      "version": "1.3.6",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.6.tgz",
-      "integrity": "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/number": "1.1.1",
-        "@radix-ui/primitive": "1.1.3",
-        "@radix-ui/react-collection": "1.1.7",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-direction": "1.1.1",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-controllable-state": "1.2.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1",
-        "@radix-ui/react-use-previous": "1.1.1",
-        "@radix-ui/react-use-size": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/primitive": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
-      "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
-      "license": "MIT"
-    },
-    "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-collection": {
-      "version": "1.1.7",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
-      "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
-      "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-context": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
-      "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-direction": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
-      "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-primitive": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
-      "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-slot": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
-      "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-use-controllable-state": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
-      "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-effect-event": "0.0.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-use-previous": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz",
-      "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-use-size": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz",
-      "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-slot": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz",
-      "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-slot/node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
-      "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-switch": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz",
-      "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.3",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-controllable-state": "1.2.2",
-        "@radix-ui/react-use-previous": "1.1.1",
-        "@radix-ui/react-use-size": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/primitive": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
-      "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
-      "license": "MIT"
-    },
-    "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
-      "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-context": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
-      "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-primitive": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
-      "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-slot": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
-      "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-controllable-state": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
-      "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-effect-event": "0.0.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-previous": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz",
-      "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-size": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz",
-      "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-tabs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.2.tgz",
-      "integrity": "sha512-9u/tQJMcC2aGq7KXpGivMm1mgq7oRJKXphDwdypPd/j21j/2znamPU8WkXgnhUaTrSFNIt8XhOyCAupg8/GbwQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.1",
-        "@radix-ui/react-context": "1.1.1",
-        "@radix-ui/react-direction": "1.1.0",
-        "@radix-ui/react-id": "1.1.0",
-        "@radix-ui/react-presence": "1.1.2",
-        "@radix-ui/react-primitive": "2.0.1",
-        "@radix-ui/react-roving-focus": "1.1.1",
-        "@radix-ui/react-use-controllable-state": "1.1.0"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-roving-focus": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.1.tgz",
-      "integrity": "sha512-QE1RoxPGJ/Nm8Qmk0PxP8ojmoaS67i0s7hVssS7KuI2FQoc/uzVlZsqKfQvxPE6D8hICCPHJ4D88zNhT3OOmkw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.1",
-        "@radix-ui/react-collection": "1.1.1",
-        "@radix-ui/react-compose-refs": "1.1.1",
-        "@radix-ui/react-context": "1.1.1",
-        "@radix-ui/react-direction": "1.1.0",
-        "@radix-ui/react-id": "1.1.0",
-        "@radix-ui/react-primitive": "2.0.1",
-        "@radix-ui/react-use-callback-ref": "1.1.0",
-        "@radix-ui/react-use-controllable-state": "1.1.0"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-tooltip": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz",
-      "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.3",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-context": "1.1.2",
-        "@radix-ui/react-dismissable-layer": "1.1.11",
-        "@radix-ui/react-id": "1.1.1",
-        "@radix-ui/react-popper": "1.2.8",
-        "@radix-ui/react-portal": "1.1.9",
-        "@radix-ui/react-presence": "1.1.5",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-slot": "1.2.3",
-        "@radix-ui/react-use-controllable-state": "1.2.2",
-        "@radix-ui/react-visually-hidden": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/primitive": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
-      "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
-      "license": "MIT"
-    },
-    "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
-      "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-context": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
-      "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-dismissable-layer": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
-      "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/primitive": "1.1.3",
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-callback-ref": "1.1.1",
-        "@radix-ui/react-use-escape-keydown": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-id": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
-      "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-portal": {
-      "version": "1.1.9",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
-      "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-primitive": "2.1.3",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-presence": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
-      "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-primitive": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
-      "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
-      "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-callback-ref": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
-      "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-controllable-state": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
-      "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-effect-event": "0.0.2",
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-escape-keydown": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz",
-      "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-callback-ref": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-use-callback-ref": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
-      "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-use-controllable-state": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
-      "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-callback-ref": "1.1.0"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-use-effect-event": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz",
-      "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-layout-effect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-use-escape-keydown": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz",
-      "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-callback-ref": "1.1.0"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-use-layout-effect": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
-      "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-use-previous": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz",
-      "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-use-rect": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz",
-      "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/rect": "1.1.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-use-size": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
-      "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-use-layout-effect": "1.1.0"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-use-size/node_modules/@radix-ui/react-use-layout-effect": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
-      "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-visually-hidden": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz",
-      "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-primitive": "2.1.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-visually-hidden/node_modules/@radix-ui/react-compose-refs": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
-      "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
-      "license": "MIT",
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-visually-hidden/node_modules/@radix-ui/react-primitive": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
-      "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-slot": "1.2.3"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
-        "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/react-visually-hidden/node_modules/@radix-ui/react-slot": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
-      "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
-      "license": "MIT",
-      "dependencies": {
-        "@radix-ui/react-compose-refs": "1.1.2"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@radix-ui/rect": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz",
-      "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==",
-      "license": "MIT"
-    },
-    "node_modules/@relume_io/relume-tailwind": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/@relume_io/relume-tailwind/-/relume-tailwind-1.3.0.tgz",
-      "integrity": "sha512-29muspmGOgBWyCDNZhIGsfTP1nkgnF335h3dmV+3aG/mml10+ERIz3dEjoYtc6D81xADoZWVhNZ/xqqy4dWDSA==",
-      "dependencies": {
-        "@tailwindcss/typography": "0.5.15",
-        "tailwindcss-animate": "1.0.7"
-      }
-    },
-    "node_modules/@relume_io/relume-ui": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/@relume_io/relume-ui/-/relume-ui-1.3.1.tgz",
-      "integrity": "sha512-efrl8I4pQB1Pxh4dtWdB5niWh0dSp0gsVTIV8eRMGA9GGCoBcc5EdmKxO4tS6dhCaO07+wiKtU8HhrSr98jGNQ==",
-      "dependencies": {
-        "@hookform/resolvers": "^3.10.0",
-        "@radix-ui/react-accordion": "1.2.2",
-        "@radix-ui/react-checkbox": "1.1.3",
-        "@radix-ui/react-collapsible": "^1.1.2",
-        "@radix-ui/react-dialog": "1.1.4",
-        "@radix-ui/react-dropdown-menu": "^2.1.4",
-        "@radix-ui/react-label": "2.1.1",
-        "@radix-ui/react-popover": "^1.1.4",
-        "@radix-ui/react-radio-group": "^1.2.2",
-        "@radix-ui/react-select": "^2.1.4",
-        "@radix-ui/react-separator": "^1.1.1",
-        "@radix-ui/react-slider": "^1.2.2",
-        "@radix-ui/react-slot": "^1.1.1",
-        "@radix-ui/react-switch": "^1.1.2",
-        "@radix-ui/react-tabs": "1.1.2",
-        "@radix-ui/react-tooltip": "^1.1.6",
-        "@relume_io/relume-tailwind": "1.3.0",
-        "class-variance-authority": "0.7.1",
-        "clsx": "2.1.1",
-        "embla-carousel-react": "^8.5.2",
-        "framer-motion": "^11.16.7",
-        "install": "^0.13.0",
-        "luxon": "^3.5.0",
-        "npm": "^11.0.0",
-        "react-day-picker": "9.5.0",
-        "react-hook-form": "^7.54.2",
-        "react-icons": "5.4.0",
-        "react-resizable-panels": "^2.0.19",
-        "tailwind-merge": "2.6.0",
-        "zod": "^3.24.1"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "@types/react-dom": "*",
-        "react": "^18.2.0",
-        "react-dom": "^18.2.0",
-        "tailwindcss": "*"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        },
-        "@types/react-dom": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@relume_io/relume-ui/node_modules/react-icons": {
-      "version": "5.4.0",
-      "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.4.0.tgz",
-      "integrity": "sha512-7eltJxgVt7X64oHh6wSWNwwbKTCtMfK35hcjvJS0yxEAhPM8oUKdS3+kqaW1vicIltw+kR2unHaa12S9pPALoQ==",
-      "license": "MIT",
-      "peerDependencies": {
-        "react": "*"
-      }
-    },
-    "node_modules/@relume_io/relume-ui/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"
       }
     },
@@ -5265,309 +1365,4 @@
         "win32"
       ]
-    },
-    "node_modules/@tailwindcss/cli": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/cli/-/cli-4.1.18.tgz",
-      "integrity": "sha512-sMZ+lZbDyxwjD2E0L7oRUjJ01Ffjtme5OtjvvnC+cV4CEDcbqzbp25TCpxHj6kWLU9+DlqJOiNgSOgctC2aZmg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@parcel/watcher": "^2.5.1",
-        "@tailwindcss/node": "4.1.18",
-        "@tailwindcss/oxide": "4.1.18",
-        "enhanced-resolve": "^5.18.3",
-        "mri": "^1.2.0",
-        "picocolors": "^1.1.1",
-        "tailwindcss": "4.1.18"
-      },
-      "bin": {
-        "tailwindcss": "dist/index.mjs"
-      }
-    },
-    "node_modules/@tailwindcss/node": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz",
-      "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==",
-      "license": "MIT",
-      "dependencies": {
-        "@jridgewell/remapping": "^2.3.4",
-        "enhanced-resolve": "^5.18.3",
-        "jiti": "^2.6.1",
-        "lightningcss": "1.30.2",
-        "magic-string": "^0.30.21",
-        "source-map-js": "^1.2.1",
-        "tailwindcss": "4.1.18"
-      }
-    },
-    "node_modules/@tailwindcss/oxide": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz",
-      "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10"
-      },
-      "optionalDependencies": {
-        "@tailwindcss/oxide-android-arm64": "4.1.18",
-        "@tailwindcss/oxide-darwin-arm64": "4.1.18",
-        "@tailwindcss/oxide-darwin-x64": "4.1.18",
-        "@tailwindcss/oxide-freebsd-x64": "4.1.18",
-        "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18",
-        "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18",
-        "@tailwindcss/oxide-linux-arm64-musl": "4.1.18",
-        "@tailwindcss/oxide-linux-x64-gnu": "4.1.18",
-        "@tailwindcss/oxide-linux-x64-musl": "4.1.18",
-        "@tailwindcss/oxide-wasm32-wasi": "4.1.18",
-        "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18",
-        "@tailwindcss/oxide-win32-x64-msvc": "4.1.18"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-android-arm64": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz",
-      "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "android"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-darwin-arm64": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz",
-      "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-darwin-x64": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz",
-      "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "darwin"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-freebsd-x64": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz",
-      "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "freebsd"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz",
-      "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==",
-      "cpu": [
-        "arm"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz",
-      "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz",
-      "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz",
-      "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-linux-x64-musl": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz",
-      "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "linux"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-wasm32-wasi": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz",
-      "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==",
-      "bundleDependencies": [
-        "@napi-rs/wasm-runtime",
-        "@emnapi/core",
-        "@emnapi/runtime",
-        "@tybys/wasm-util",
-        "@emnapi/wasi-threads",
-        "tslib"
-      ],
-      "cpu": [
-        "wasm32"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "@emnapi/core": "^1.7.1",
-        "@emnapi/runtime": "^1.7.1",
-        "@emnapi/wasi-threads": "^1.1.0",
-        "@napi-rs/wasm-runtime": "^1.1.0",
-        "@tybys/wasm-util": "^0.10.1",
-        "tslib": "^2.4.0"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz",
-      "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==",
-      "cpu": [
-        "arm64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz",
-      "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MIT",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tailwindcss/postcss": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.18.tgz",
-      "integrity": "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@alloc/quick-lru": "^5.2.0",
-        "@tailwindcss/node": "4.1.18",
-        "@tailwindcss/oxide": "4.1.18",
-        "postcss": "^8.4.41",
-        "tailwindcss": "4.1.18"
-      }
-    },
-    "node_modules/@tailwindcss/typography": {
-      "version": "0.5.15",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.15.tgz",
-      "integrity": "sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==",
-      "license": "MIT",
-      "dependencies": {
-        "lodash.castarray": "^4.4.0",
-        "lodash.isplainobject": "^4.0.6",
-        "lodash.merge": "^4.6.2",
-        "postcss-selector-parser": "6.0.10"
-      },
-      "peerDependencies": {
-        "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20"
-      }
-    },
-    "node_modules/@tailwindcss/vite": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.18.tgz",
-      "integrity": "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==",
-      "license": "MIT",
-      "dependencies": {
-        "@tailwindcss/node": "4.1.18",
-        "@tailwindcss/oxide": "4.1.18",
-        "tailwindcss": "4.1.18"
-      },
-      "peerDependencies": {
-        "vite": "^5.2.0 || ^6 || ^7"
-      }
     },
     "node_modules/@types/babel__core": {
@@ -5727,10 +1522,4 @@
       }
     },
-    "node_modules/apexcharts": {
-      "version": "5.10.6",
-      "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-5.10.6.tgz",
-      "integrity": "sha512-FJQGbso3iRuOwUYnj0yUhkWeKeJE6aboVol+ae09lsc+lbLMWZqSRbrAWVa/qishLiaeG2icxdvmVkm+9n6kOQ==",
-      "license": "SEE LICENSE IN LICENSE"
-    },
     "node_modules/argparse": {
       "version": "2.0.1",
@@ -5739,16 +1528,4 @@
       "dev": true,
       "license": "Python-2.0"
-    },
-    "node_modules/aria-hidden": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz",
-      "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==",
-      "license": "MIT",
-      "dependencies": {
-        "tslib": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
     },
     "node_modules/asynckit": {
@@ -5757,41 +1534,4 @@
       "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
       "license": "MIT"
-    },
-    "node_modules/autoprefixer": {
-      "version": "10.4.24",
-      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.24.tgz",
-      "integrity": "sha512-uHZg7N9ULTVbutaIsDRoUkoS8/h3bdsmVJYZ5l3wv8Cp/6UIIoRDm90hZ+BwxUj/hGBEzLxdHNSKuFpn8WOyZw==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/autoprefixer"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "browserslist": "^4.28.1",
-        "caniuse-lite": "^1.0.30001766",
-        "fraction.js": "^5.3.4",
-        "picocolors": "^1.1.1",
-        "postcss-value-parser": "^4.2.0"
-      },
-      "bin": {
-        "autoprefixer": "bin/autoprefixer"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      },
-      "peerDependencies": {
-        "postcss": "^8.1.0"
-      }
     },
     "node_modules/axios": {
@@ -5929,25 +1669,4 @@
       }
     },
-    "node_modules/class-variance-authority": {
-      "version": "0.7.1",
-      "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz",
-      "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "clsx": "^2.1.1"
-      },
-      "funding": {
-        "url": "https://polar.sh/cva"
-      }
-    },
-    "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/color-convert": {
       "version": "2.0.1",
@@ -6024,16 +1743,4 @@
       }
     },
-    "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/csstype": {
       "version": "3.2.3",
@@ -6043,29 +1750,4 @@
       "license": "MIT"
     },
-    "node_modules/daisyui": {
-      "version": "5.5.18",
-      "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-5.5.18.tgz",
-      "integrity": "sha512-VVzjpOitMGB6DWIBeRSapbjdOevFqyzpk9u5Um6a4tyId3JFrU5pbtF0vgjXDth76mJZbueN/j9Ok03SPrh/og==",
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/saadeghi/daisyui?sponsor=1"
-      }
-    },
-    "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/date-fns-jalali": {
-      "version": "4.1.0-0",
-      "resolved": "https://registry.npmjs.org/date-fns-jalali/-/date-fns-jalali-4.1.0-0.tgz",
-      "integrity": "sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==",
-      "license": "MIT"
-    },
     "node_modules/debug": {
       "version": "4.4.3",
@@ -6102,19 +1784,4 @@
       }
     },
-    "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==",
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/detect-node-es": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
-      "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
-      "license": "MIT"
-    },
     "node_modules/dunder-proto": {
       "version": "1.0.1",
@@ -6137,45 +1804,4 @@
       "dev": true,
       "license": "ISC"
-    },
-    "node_modules/embla-carousel": {
-      "version": "8.6.0",
-      "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz",
-      "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==",
-      "license": "MIT"
-    },
-    "node_modules/embla-carousel-react": {
-      "version": "8.6.0",
-      "resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.6.0.tgz",
-      "integrity": "sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==",
-      "license": "MIT",
-      "dependencies": {
-        "embla-carousel": "8.6.0",
-        "embla-carousel-reactive-utils": "8.6.0"
-      },
-      "peerDependencies": {
-        "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
-      }
-    },
-    "node_modules/embla-carousel-reactive-utils": {
-      "version": "8.6.0",
-      "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.6.0.tgz",
-      "integrity": "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==",
-      "license": "MIT",
-      "peerDependencies": {
-        "embla-carousel": "8.6.0"
-      }
-    },
-    "node_modules/enhanced-resolve": {
-      "version": "5.19.0",
-      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz",
-      "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==",
-      "license": "MIT",
-      "dependencies": {
-        "graceful-fs": "^4.2.4",
-        "tapable": "^2.3.0"
-      },
-      "engines": {
-        "node": ">=10.13.0"
-      }
     },
     "node_modules/es-define-property": {
@@ -6599,45 +2225,4 @@
       }
     },
-    "node_modules/fraction.js": {
-      "version": "5.3.4",
-      "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz",
-      "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": "*"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/rawify"
-      }
-    },
-    "node_modules/framer-motion": {
-      "version": "11.18.2",
-      "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.18.2.tgz",
-      "integrity": "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w==",
-      "license": "MIT",
-      "dependencies": {
-        "motion-dom": "^11.18.1",
-        "motion-utils": "^11.18.1",
-        "tslib": "^2.4.0"
-      },
-      "peerDependencies": {
-        "@emotion/is-prop-valid": "*",
-        "react": "^18.0.0 || ^19.0.0",
-        "react-dom": "^18.0.0 || ^19.0.0"
-      },
-      "peerDependenciesMeta": {
-        "@emotion/is-prop-valid": {
-          "optional": true
-        },
-        "react": {
-          "optional": true
-        },
-        "react-dom": {
-          "optional": true
-        }
-      }
-    },
     "node_modules/fsevents": {
       "version": "2.3.3",
@@ -6698,13 +2283,4 @@
       }
     },
-    "node_modules/get-nonce": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
-      "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/get-proto": {
       "version": "1.0.1",
@@ -6758,10 +2334,4 @@
       }
     },
-    "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==",
-      "license": "ISC"
-    },
     "node_modules/has-flag": {
       "version": "4.0.0",
@@ -6867,13 +2437,4 @@
       }
     },
-    "node_modules/install": {
-      "version": "0.13.0",
-      "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz",
-      "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.10"
-      }
-    },
     "node_modules/is-extglob": {
       "version": "2.1.1",
@@ -6906,17 +2467,9 @@
       "license": "ISC"
     },
-    "node_modules/jiti": {
-      "version": "2.6.1",
-      "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
-      "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
-      "license": "MIT",
-      "bin": {
-        "jiti": "lib/jiti-cli.mjs"
-      }
-    },
     "node_modules/js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
       "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "dev": true,
       "license": "MIT"
     },
@@ -7005,253 +2558,4 @@
       }
     },
-    "node_modules/lightningcss": {
-      "version": "1.30.2",
-      "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz",
-      "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==",
-      "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.30.2",
-        "lightningcss-darwin-arm64": "1.30.2",
-        "lightningcss-darwin-x64": "1.30.2",
-        "lightningcss-freebsd-x64": "1.30.2",
-        "lightningcss-linux-arm-gnueabihf": "1.30.2",
-        "lightningcss-linux-arm64-gnu": "1.30.2",
-        "lightningcss-linux-arm64-musl": "1.30.2",
-        "lightningcss-linux-x64-gnu": "1.30.2",
-        "lightningcss-linux-x64-musl": "1.30.2",
-        "lightningcss-win32-arm64-msvc": "1.30.2",
-        "lightningcss-win32-x64-msvc": "1.30.2"
-      }
-    },
-    "node_modules/lightningcss-android-arm64": {
-      "version": "1.30.2",
-      "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz",
-      "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==",
-      "cpu": [
-        "arm64"
-      ],
-      "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.30.2",
-      "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz",
-      "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==",
-      "cpu": [
-        "arm64"
-      ],
-      "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.30.2",
-      "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz",
-      "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==",
-      "cpu": [
-        "x64"
-      ],
-      "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.30.2",
-      "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz",
-      "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==",
-      "cpu": [
-        "x64"
-      ],
-      "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.30.2",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz",
-      "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==",
-      "cpu": [
-        "arm"
-      ],
-      "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.30.2",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz",
-      "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==",
-      "cpu": [
-        "arm64"
-      ],
-      "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.30.2",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz",
-      "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==",
-      "cpu": [
-        "arm64"
-      ],
-      "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.30.2",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz",
-      "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==",
-      "cpu": [
-        "x64"
-      ],
-      "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.30.2",
-      "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz",
-      "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==",
-      "cpu": [
-        "x64"
-      ],
-      "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.30.2",
-      "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz",
-      "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==",
-      "cpu": [
-        "arm64"
-      ],
-      "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.30.2",
-      "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz",
-      "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==",
-      "cpu": [
-        "x64"
-      ],
-      "license": "MPL-2.0",
-      "optional": true,
-      "os": [
-        "win32"
-      ],
-      "engines": {
-        "node": ">= 12.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/parcel"
-      }
-    },
     "node_modules/locate-path": {
       "version": "6.0.0",
@@ -7270,33 +2574,10 @@
       }
     },
-    "node_modules/lodash.castarray": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
-      "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
-      "license": "MIT"
-    },
-    "node_modules/lodash.isplainobject": {
-      "version": "4.0.6",
-      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
-      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
-      "license": "MIT"
-    },
     "node_modules/lodash.merge": {
       "version": "4.6.2",
       "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
       "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+      "dev": true,
       "license": "MIT"
-    },
-    "node_modules/loose-envify": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
-      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
-      "license": "MIT",
-      "dependencies": {
-        "js-tokens": "^3.0.0 || ^4.0.0"
-      },
-      "bin": {
-        "loose-envify": "cli.js"
-      }
     },
     "node_modules/lru-cache": {
@@ -7310,22 +2591,4 @@
       }
     },
-    "node_modules/luxon": {
-      "version": "3.7.2",
-      "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz",
-      "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "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/math-intrinsics": {
       "version": "1.1.0",
@@ -7369,29 +2632,4 @@
       "engines": {
         "node": "*"
-      }
-    },
-    "node_modules/motion-dom": {
-      "version": "11.18.1",
-      "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz",
-      "integrity": "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==",
-      "license": "MIT",
-      "dependencies": {
-        "motion-utils": "^11.18.1"
-      }
-    },
-    "node_modules/motion-utils": {
-      "version": "11.18.1",
-      "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-11.18.1.tgz",
-      "integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==",
-      "license": "MIT"
-    },
-    "node_modules/mri": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
-      "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
       }
     },
@@ -7429,11 +2667,4 @@
       "license": "MIT"
     },
-    "node_modules/node-addon-api": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
-      "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/node-releases": {
       "version": "2.0.27",
@@ -7442,1942 +2673,4 @@
       "dev": true,
       "license": "MIT"
-    },
-    "node_modules/npm": {
-      "version": "11.9.0",
-      "resolved": "https://registry.npmjs.org/npm/-/npm-11.9.0.tgz",
-      "integrity": "sha512-BBZoU926FCypj4b7V7ElinxsWcy4Kss88UG3ejFYmKyq7Uc5XnT34Me2nEhgCOaL5qY4HvGu5aI92C4OYd7NaA==",
-      "bundleDependencies": [
-        "@isaacs/string-locale-compare",
-        "@npmcli/arborist",
-        "@npmcli/config",
-        "@npmcli/fs",
-        "@npmcli/map-workspaces",
-        "@npmcli/metavuln-calculator",
-        "@npmcli/package-json",
-        "@npmcli/promise-spawn",
-        "@npmcli/redact",
-        "@npmcli/run-script",
-        "@sigstore/tuf",
-        "abbrev",
-        "archy",
-        "cacache",
-        "chalk",
-        "ci-info",
-        "cli-columns",
-        "fastest-levenshtein",
-        "fs-minipass",
-        "glob",
-        "graceful-fs",
-        "hosted-git-info",
-        "ini",
-        "init-package-json",
-        "is-cidr",
-        "json-parse-even-better-errors",
-        "libnpmaccess",
-        "libnpmdiff",
-        "libnpmexec",
-        "libnpmfund",
-        "libnpmorg",
-        "libnpmpack",
-        "libnpmpublish",
-        "libnpmsearch",
-        "libnpmteam",
-        "libnpmversion",
-        "make-fetch-happen",
-        "minimatch",
-        "minipass",
-        "minipass-pipeline",
-        "ms",
-        "node-gyp",
-        "nopt",
-        "npm-audit-report",
-        "npm-install-checks",
-        "npm-package-arg",
-        "npm-pick-manifest",
-        "npm-profile",
-        "npm-registry-fetch",
-        "npm-user-validate",
-        "p-map",
-        "pacote",
-        "parse-conflict-json",
-        "proc-log",
-        "qrcode-terminal",
-        "read",
-        "semver",
-        "spdx-expression-parse",
-        "ssri",
-        "supports-color",
-        "tar",
-        "text-table",
-        "tiny-relative-date",
-        "treeverse",
-        "validate-npm-package-name",
-        "which"
-      ],
-      "license": "Artistic-2.0",
-      "workspaces": [
-        "docs",
-        "smoke-tests",
-        "mock-globals",
-        "mock-registry",
-        "workspaces/*"
-      ],
-      "dependencies": {
-        "@isaacs/string-locale-compare": "^1.1.0",
-        "@npmcli/arborist": "^9.2.0",
-        "@npmcli/config": "^10.6.0",
-        "@npmcli/fs": "^5.0.0",
-        "@npmcli/map-workspaces": "^5.0.3",
-        "@npmcli/metavuln-calculator": "^9.0.3",
-        "@npmcli/package-json": "^7.0.4",
-        "@npmcli/promise-spawn": "^9.0.1",
-        "@npmcli/redact": "^4.0.0",
-        "@npmcli/run-script": "^10.0.3",
-        "@sigstore/tuf": "^4.0.1",
-        "abbrev": "^4.0.0",
-        "archy": "~1.0.0",
-        "cacache": "^20.0.3",
-        "chalk": "^5.6.2",
-        "ci-info": "^4.4.0",
-        "cli-columns": "^4.0.0",
-        "fastest-levenshtein": "^1.0.16",
-        "fs-minipass": "^3.0.3",
-        "glob": "^13.0.0",
-        "graceful-fs": "^4.2.11",
-        "hosted-git-info": "^9.0.2",
-        "ini": "^6.0.0",
-        "init-package-json": "^8.2.4",
-        "is-cidr": "^6.0.1",
-        "json-parse-even-better-errors": "^5.0.0",
-        "libnpmaccess": "^10.0.3",
-        "libnpmdiff": "^8.1.0",
-        "libnpmexec": "^10.2.0",
-        "libnpmfund": "^7.0.14",
-        "libnpmorg": "^8.0.1",
-        "libnpmpack": "^9.1.0",
-        "libnpmpublish": "^11.1.3",
-        "libnpmsearch": "^9.0.1",
-        "libnpmteam": "^8.0.2",
-        "libnpmversion": "^8.0.3",
-        "make-fetch-happen": "^15.0.3",
-        "minimatch": "^10.1.1",
-        "minipass": "^7.1.1",
-        "minipass-pipeline": "^1.2.4",
-        "ms": "^2.1.2",
-        "node-gyp": "^12.2.0",
-        "nopt": "^9.0.0",
-        "npm-audit-report": "^7.0.0",
-        "npm-install-checks": "^8.0.0",
-        "npm-package-arg": "^13.0.2",
-        "npm-pick-manifest": "^11.0.3",
-        "npm-profile": "^12.0.1",
-        "npm-registry-fetch": "^19.1.1",
-        "npm-user-validate": "^4.0.0",
-        "p-map": "^7.0.4",
-        "pacote": "^21.1.0",
-        "parse-conflict-json": "^5.0.1",
-        "proc-log": "^6.1.0",
-        "qrcode-terminal": "^0.12.0",
-        "read": "^5.0.1",
-        "semver": "^7.7.3",
-        "spdx-expression-parse": "^4.0.0",
-        "ssri": "^13.0.0",
-        "supports-color": "^10.2.2",
-        "tar": "^7.5.7",
-        "text-table": "~0.2.0",
-        "tiny-relative-date": "^2.0.2",
-        "treeverse": "^3.0.0",
-        "validate-npm-package-name": "^7.0.2",
-        "which": "^6.0.0"
-      },
-      "bin": {
-        "npm": "bin/npm-cli.js",
-        "npx": "bin/npx-cli.js"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@isaacs/balanced-match": {
-      "version": "4.0.1",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": "20 || >=22"
-      }
-    },
-    "node_modules/npm/node_modules/@isaacs/brace-expansion": {
-      "version": "5.0.1",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "@isaacs/balanced-match": "^4.0.1"
-      },
-      "engines": {
-        "node": "20 || >=22"
-      }
-    },
-    "node_modules/npm/node_modules/@isaacs/fs-minipass": {
-      "version": "4.0.1",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "minipass": "^7.0.4"
-      },
-      "engines": {
-        "node": ">=18.0.0"
-      }
-    },
-    "node_modules/npm/node_modules/@isaacs/string-locale-compare": {
-      "version": "1.1.0",
-      "inBundle": true,
-      "license": "ISC"
-    },
-    "node_modules/npm/node_modules/@npmcli/agent": {
-      "version": "4.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "agent-base": "^7.1.0",
-        "http-proxy-agent": "^7.0.0",
-        "https-proxy-agent": "^7.0.1",
-        "lru-cache": "^11.2.1",
-        "socks-proxy-agent": "^8.0.3"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@npmcli/arborist": {
-      "version": "9.2.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@isaacs/string-locale-compare": "^1.1.0",
-        "@npmcli/fs": "^5.0.0",
-        "@npmcli/installed-package-contents": "^4.0.0",
-        "@npmcli/map-workspaces": "^5.0.0",
-        "@npmcli/metavuln-calculator": "^9.0.2",
-        "@npmcli/name-from-folder": "^4.0.0",
-        "@npmcli/node-gyp": "^5.0.0",
-        "@npmcli/package-json": "^7.0.0",
-        "@npmcli/query": "^5.0.0",
-        "@npmcli/redact": "^4.0.0",
-        "@npmcli/run-script": "^10.0.0",
-        "bin-links": "^6.0.0",
-        "cacache": "^20.0.1",
-        "common-ancestor-path": "^2.0.0",
-        "hosted-git-info": "^9.0.0",
-        "json-stringify-nice": "^1.1.4",
-        "lru-cache": "^11.2.1",
-        "minimatch": "^10.0.3",
-        "nopt": "^9.0.0",
-        "npm-install-checks": "^8.0.0",
-        "npm-package-arg": "^13.0.0",
-        "npm-pick-manifest": "^11.0.1",
-        "npm-registry-fetch": "^19.0.0",
-        "pacote": "^21.0.2",
-        "parse-conflict-json": "^5.0.1",
-        "proc-log": "^6.0.0",
-        "proggy": "^4.0.0",
-        "promise-all-reject-late": "^1.0.0",
-        "promise-call-limit": "^3.0.1",
-        "semver": "^7.3.7",
-        "ssri": "^13.0.0",
-        "treeverse": "^3.0.0",
-        "walk-up-path": "^4.0.0"
-      },
-      "bin": {
-        "arborist": "bin/index.js"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@npmcli/config": {
-      "version": "10.6.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/map-workspaces": "^5.0.0",
-        "@npmcli/package-json": "^7.0.0",
-        "ci-info": "^4.0.0",
-        "ini": "^6.0.0",
-        "nopt": "^9.0.0",
-        "proc-log": "^6.0.0",
-        "semver": "^7.3.5",
-        "walk-up-path": "^4.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@npmcli/fs": {
-      "version": "5.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "semver": "^7.3.5"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@npmcli/git": {
-      "version": "7.0.1",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/promise-spawn": "^9.0.0",
-        "ini": "^6.0.0",
-        "lru-cache": "^11.2.1",
-        "npm-pick-manifest": "^11.0.1",
-        "proc-log": "^6.0.0",
-        "promise-retry": "^2.0.1",
-        "semver": "^7.3.5",
-        "which": "^6.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@npmcli/installed-package-contents": {
-      "version": "4.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "npm-bundled": "^5.0.0",
-        "npm-normalize-package-bin": "^5.0.0"
-      },
-      "bin": {
-        "installed-package-contents": "bin/index.js"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@npmcli/map-workspaces": {
-      "version": "5.0.3",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/name-from-folder": "^4.0.0",
-        "@npmcli/package-json": "^7.0.0",
-        "glob": "^13.0.0",
-        "minimatch": "^10.0.3"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@npmcli/metavuln-calculator": {
-      "version": "9.0.3",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "cacache": "^20.0.0",
-        "json-parse-even-better-errors": "^5.0.0",
-        "pacote": "^21.0.0",
-        "proc-log": "^6.0.0",
-        "semver": "^7.3.5"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@npmcli/name-from-folder": {
-      "version": "4.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@npmcli/node-gyp": {
-      "version": "5.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@npmcli/package-json": {
-      "version": "7.0.4",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/git": "^7.0.0",
-        "glob": "^13.0.0",
-        "hosted-git-info": "^9.0.0",
-        "json-parse-even-better-errors": "^5.0.0",
-        "proc-log": "^6.0.0",
-        "semver": "^7.5.3",
-        "validate-npm-package-license": "^3.0.4"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@npmcli/promise-spawn": {
-      "version": "9.0.1",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "which": "^6.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@npmcli/query": {
-      "version": "5.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "postcss-selector-parser": "^7.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@npmcli/redact": {
-      "version": "4.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@npmcli/run-script": {
-      "version": "10.0.3",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/node-gyp": "^5.0.0",
-        "@npmcli/package-json": "^7.0.0",
-        "@npmcli/promise-spawn": "^9.0.0",
-        "node-gyp": "^12.1.0",
-        "proc-log": "^6.0.0",
-        "which": "^6.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@sigstore/bundle": {
-      "version": "4.0.0",
-      "inBundle": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@sigstore/protobuf-specs": "^0.5.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@sigstore/core": {
-      "version": "3.1.0",
-      "inBundle": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@sigstore/protobuf-specs": {
-      "version": "0.5.0",
-      "inBundle": true,
-      "license": "Apache-2.0",
-      "engines": {
-        "node": "^18.17.0 || >=20.5.0"
-      }
-    },
-    "node_modules/npm/node_modules/@sigstore/sign": {
-      "version": "4.1.0",
-      "inBundle": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@sigstore/bundle": "^4.0.0",
-        "@sigstore/core": "^3.1.0",
-        "@sigstore/protobuf-specs": "^0.5.0",
-        "make-fetch-happen": "^15.0.3",
-        "proc-log": "^6.1.0",
-        "promise-retry": "^2.0.1"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@sigstore/tuf": {
-      "version": "4.0.1",
-      "inBundle": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@sigstore/protobuf-specs": "^0.5.0",
-        "tuf-js": "^4.1.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@sigstore/verify": {
-      "version": "3.1.0",
-      "inBundle": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@sigstore/bundle": "^4.0.0",
-        "@sigstore/core": "^3.1.0",
-        "@sigstore/protobuf-specs": "^0.5.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/@tufjs/canonical-json": {
-      "version": "2.0.0",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^16.14.0 || >=18.0.0"
-      }
-    },
-    "node_modules/npm/node_modules/@tufjs/models": {
-      "version": "4.1.0",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "@tufjs/canonical-json": "2.0.0",
-        "minimatch": "^10.1.1"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/abbrev": {
-      "version": "4.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/agent-base": {
-      "version": "7.1.4",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/npm/node_modules/ansi-regex": {
-      "version": "5.0.1",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/npm/node_modules/aproba": {
-      "version": "2.1.0",
-      "inBundle": true,
-      "license": "ISC"
-    },
-    "node_modules/npm/node_modules/archy": {
-      "version": "1.0.0",
-      "inBundle": true,
-      "license": "MIT"
-    },
-    "node_modules/npm/node_modules/bin-links": {
-      "version": "6.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "cmd-shim": "^8.0.0",
-        "npm-normalize-package-bin": "^5.0.0",
-        "proc-log": "^6.0.0",
-        "read-cmd-shim": "^6.0.0",
-        "write-file-atomic": "^7.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/binary-extensions": {
-      "version": "3.1.0",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18.20"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/npm/node_modules/cacache": {
-      "version": "20.0.3",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/fs": "^5.0.0",
-        "fs-minipass": "^3.0.0",
-        "glob": "^13.0.0",
-        "lru-cache": "^11.1.0",
-        "minipass": "^7.0.3",
-        "minipass-collect": "^2.0.1",
-        "minipass-flush": "^1.0.5",
-        "minipass-pipeline": "^1.2.4",
-        "p-map": "^7.0.2",
-        "ssri": "^13.0.0",
-        "unique-filename": "^5.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/chalk": {
-      "version": "5.6.2",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^12.17.0 || ^14.13 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
-      }
-    },
-    "node_modules/npm/node_modules/chownr": {
-      "version": "3.0.0",
-      "inBundle": true,
-      "license": "BlueOak-1.0.0",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/npm/node_modules/ci-info": {
-      "version": "4.4.0",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/sibiraj-s"
-        }
-      ],
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/npm/node_modules/cidr-regex": {
-      "version": "5.0.1",
-      "inBundle": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "ip-regex": "5.0.0"
-      },
-      "engines": {
-        "node": ">=20"
-      }
-    },
-    "node_modules/npm/node_modules/cli-columns": {
-      "version": "4.0.0",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "string-width": "^4.2.3",
-        "strip-ansi": "^6.0.1"
-      },
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/npm/node_modules/cmd-shim": {
-      "version": "8.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/common-ancestor-path": {
-      "version": "2.0.0",
-      "inBundle": true,
-      "license": "BlueOak-1.0.0",
-      "engines": {
-        "node": ">= 18"
-      }
-    },
-    "node_modules/npm/node_modules/cssesc": {
-      "version": "3.0.0",
-      "inBundle": true,
-      "license": "MIT",
-      "bin": {
-        "cssesc": "bin/cssesc"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/npm/node_modules/debug": {
-      "version": "4.4.3",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/npm/node_modules/diff": {
-      "version": "8.0.3",
-      "inBundle": true,
-      "license": "BSD-3-Clause",
-      "engines": {
-        "node": ">=0.3.1"
-      }
-    },
-    "node_modules/npm/node_modules/emoji-regex": {
-      "version": "8.0.0",
-      "inBundle": true,
-      "license": "MIT"
-    },
-    "node_modules/npm/node_modules/encoding": {
-      "version": "0.1.13",
-      "inBundle": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "iconv-lite": "^0.6.2"
-      }
-    },
-    "node_modules/npm/node_modules/env-paths": {
-      "version": "2.2.1",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/npm/node_modules/err-code": {
-      "version": "2.0.3",
-      "inBundle": true,
-      "license": "MIT"
-    },
-    "node_modules/npm/node_modules/exponential-backoff": {
-      "version": "3.1.3",
-      "inBundle": true,
-      "license": "Apache-2.0"
-    },
-    "node_modules/npm/node_modules/fastest-levenshtein": {
-      "version": "1.0.16",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 4.9.1"
-      }
-    },
-    "node_modules/npm/node_modules/fs-minipass": {
-      "version": "3.0.3",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "minipass": "^7.0.3"
-      },
-      "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
-      }
-    },
-    "node_modules/npm/node_modules/glob": {
-      "version": "13.0.1",
-      "inBundle": true,
-      "license": "BlueOak-1.0.0",
-      "dependencies": {
-        "minimatch": "^10.1.2",
-        "minipass": "^7.1.2",
-        "path-scurry": "^2.0.0"
-      },
-      "engines": {
-        "node": "20 || >=22"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/npm/node_modules/graceful-fs": {
-      "version": "4.2.11",
-      "inBundle": true,
-      "license": "ISC"
-    },
-    "node_modules/npm/node_modules/hosted-git-info": {
-      "version": "9.0.2",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "lru-cache": "^11.1.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/http-cache-semantics": {
-      "version": "4.2.0",
-      "inBundle": true,
-      "license": "BSD-2-Clause"
-    },
-    "node_modules/npm/node_modules/http-proxy-agent": {
-      "version": "7.0.2",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "agent-base": "^7.1.0",
-        "debug": "^4.3.4"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/npm/node_modules/https-proxy-agent": {
-      "version": "7.0.6",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "agent-base": "^7.1.2",
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/npm/node_modules/iconv-lite": {
-      "version": "0.6.3",
-      "inBundle": true,
-      "license": "MIT",
-      "optional": true,
-      "dependencies": {
-        "safer-buffer": ">= 2.1.2 < 3.0.0"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/npm/node_modules/ignore-walk": {
-      "version": "8.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "minimatch": "^10.0.3"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/imurmurhash": {
-      "version": "0.1.4",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.8.19"
-      }
-    },
-    "node_modules/npm/node_modules/ini": {
-      "version": "6.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/init-package-json": {
-      "version": "8.2.4",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/package-json": "^7.0.0",
-        "npm-package-arg": "^13.0.0",
-        "promzard": "^3.0.1",
-        "read": "^5.0.1",
-        "semver": "^7.7.2",
-        "validate-npm-package-license": "^3.0.4",
-        "validate-npm-package-name": "^7.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/ip-address": {
-      "version": "10.1.0",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 12"
-      }
-    },
-    "node_modules/npm/node_modules/ip-regex": {
-      "version": "5.0.0",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/npm/node_modules/is-cidr": {
-      "version": "6.0.2",
-      "inBundle": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "cidr-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=20"
-      }
-    },
-    "node_modules/npm/node_modules/is-fullwidth-code-point": {
-      "version": "3.0.0",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/npm/node_modules/isexe": {
-      "version": "3.1.1",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=16"
-      }
-    },
-    "node_modules/npm/node_modules/json-parse-even-better-errors": {
-      "version": "5.0.0",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/json-stringify-nice": {
-      "version": "1.1.4",
-      "inBundle": true,
-      "license": "ISC",
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/npm/node_modules/jsonparse": {
-      "version": "1.3.1",
-      "engines": [
-        "node >= 0.2.0"
-      ],
-      "inBundle": true,
-      "license": "MIT"
-    },
-    "node_modules/npm/node_modules/just-diff": {
-      "version": "6.0.2",
-      "inBundle": true,
-      "license": "MIT"
-    },
-    "node_modules/npm/node_modules/just-diff-apply": {
-      "version": "5.5.0",
-      "inBundle": true,
-      "license": "MIT"
-    },
-    "node_modules/npm/node_modules/libnpmaccess": {
-      "version": "10.0.3",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "npm-package-arg": "^13.0.0",
-        "npm-registry-fetch": "^19.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/libnpmdiff": {
-      "version": "8.1.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/arborist": "^9.2.0",
-        "@npmcli/installed-package-contents": "^4.0.0",
-        "binary-extensions": "^3.0.0",
-        "diff": "^8.0.2",
-        "minimatch": "^10.0.3",
-        "npm-package-arg": "^13.0.0",
-        "pacote": "^21.0.2",
-        "tar": "^7.5.1"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/libnpmexec": {
-      "version": "10.2.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/arborist": "^9.2.0",
-        "@npmcli/package-json": "^7.0.0",
-        "@npmcli/run-script": "^10.0.0",
-        "ci-info": "^4.0.0",
-        "npm-package-arg": "^13.0.0",
-        "pacote": "^21.0.2",
-        "proc-log": "^6.0.0",
-        "promise-retry": "^2.0.1",
-        "read": "^5.0.1",
-        "semver": "^7.3.7",
-        "signal-exit": "^4.1.0",
-        "walk-up-path": "^4.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/libnpmfund": {
-      "version": "7.0.14",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/arborist": "^9.2.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/libnpmorg": {
-      "version": "8.0.1",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "aproba": "^2.0.0",
-        "npm-registry-fetch": "^19.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/libnpmpack": {
-      "version": "9.1.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/arborist": "^9.2.0",
-        "@npmcli/run-script": "^10.0.0",
-        "npm-package-arg": "^13.0.0",
-        "pacote": "^21.0.2"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/libnpmpublish": {
-      "version": "11.1.3",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/package-json": "^7.0.0",
-        "ci-info": "^4.0.0",
-        "npm-package-arg": "^13.0.0",
-        "npm-registry-fetch": "^19.0.0",
-        "proc-log": "^6.0.0",
-        "semver": "^7.3.7",
-        "sigstore": "^4.0.0",
-        "ssri": "^13.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/libnpmsearch": {
-      "version": "9.0.1",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "npm-registry-fetch": "^19.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/libnpmteam": {
-      "version": "8.0.2",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "aproba": "^2.0.0",
-        "npm-registry-fetch": "^19.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/libnpmversion": {
-      "version": "8.0.3",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/git": "^7.0.0",
-        "@npmcli/run-script": "^10.0.0",
-        "json-parse-even-better-errors": "^5.0.0",
-        "proc-log": "^6.0.0",
-        "semver": "^7.3.7"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/lru-cache": {
-      "version": "11.2.5",
-      "inBundle": true,
-      "license": "BlueOak-1.0.0",
-      "engines": {
-        "node": "20 || >=22"
-      }
-    },
-    "node_modules/npm/node_modules/make-fetch-happen": {
-      "version": "15.0.3",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/agent": "^4.0.0",
-        "cacache": "^20.0.1",
-        "http-cache-semantics": "^4.1.1",
-        "minipass": "^7.0.2",
-        "minipass-fetch": "^5.0.0",
-        "minipass-flush": "^1.0.5",
-        "minipass-pipeline": "^1.2.4",
-        "negotiator": "^1.0.0",
-        "proc-log": "^6.0.0",
-        "promise-retry": "^2.0.1",
-        "ssri": "^13.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/minimatch": {
-      "version": "10.1.2",
-      "inBundle": true,
-      "license": "BlueOak-1.0.0",
-      "dependencies": {
-        "@isaacs/brace-expansion": "^5.0.1"
-      },
-      "engines": {
-        "node": "20 || >=22"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/npm/node_modules/minipass": {
-      "version": "7.1.2",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      }
-    },
-    "node_modules/npm/node_modules/minipass-collect": {
-      "version": "2.0.1",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "minipass": "^7.0.3"
-      },
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      }
-    },
-    "node_modules/npm/node_modules/minipass-fetch": {
-      "version": "5.0.1",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "minipass": "^7.0.3",
-        "minipass-sized": "^2.0.0",
-        "minizlib": "^3.0.1"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      },
-      "optionalDependencies": {
-        "encoding": "^0.1.13"
-      }
-    },
-    "node_modules/npm/node_modules/minipass-flush": {
-      "version": "1.0.5",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "minipass": "^3.0.0"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": {
-      "version": "3.3.6",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "yallist": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/npm/node_modules/minipass-pipeline": {
-      "version": "1.2.4",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "minipass": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": {
-      "version": "3.3.6",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "yallist": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/npm/node_modules/minipass-sized": {
-      "version": "2.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "minipass": "^7.1.2"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/npm/node_modules/minizlib": {
-      "version": "3.1.0",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "minipass": "^7.1.2"
-      },
-      "engines": {
-        "node": ">= 18"
-      }
-    },
-    "node_modules/npm/node_modules/ms": {
-      "version": "2.1.3",
-      "inBundle": true,
-      "license": "MIT"
-    },
-    "node_modules/npm/node_modules/mute-stream": {
-      "version": "3.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/negotiator": {
-      "version": "1.0.0",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/npm/node_modules/node-gyp": {
-      "version": "12.2.0",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "env-paths": "^2.2.0",
-        "exponential-backoff": "^3.1.1",
-        "graceful-fs": "^4.2.6",
-        "make-fetch-happen": "^15.0.0",
-        "nopt": "^9.0.0",
-        "proc-log": "^6.0.0",
-        "semver": "^7.3.5",
-        "tar": "^7.5.4",
-        "tinyglobby": "^0.2.12",
-        "which": "^6.0.0"
-      },
-      "bin": {
-        "node-gyp": "bin/node-gyp.js"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/nopt": {
-      "version": "9.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "abbrev": "^4.0.0"
-      },
-      "bin": {
-        "nopt": "bin/nopt.js"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/npm-audit-report": {
-      "version": "7.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/npm-bundled": {
-      "version": "5.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "npm-normalize-package-bin": "^5.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/npm-install-checks": {
-      "version": "8.0.0",
-      "inBundle": true,
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "semver": "^7.1.1"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/npm-normalize-package-bin": {
-      "version": "5.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/npm-package-arg": {
-      "version": "13.0.2",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "hosted-git-info": "^9.0.0",
-        "proc-log": "^6.0.0",
-        "semver": "^7.3.5",
-        "validate-npm-package-name": "^7.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/npm-packlist": {
-      "version": "10.0.3",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "ignore-walk": "^8.0.0",
-        "proc-log": "^6.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/npm-pick-manifest": {
-      "version": "11.0.3",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "npm-install-checks": "^8.0.0",
-        "npm-normalize-package-bin": "^5.0.0",
-        "npm-package-arg": "^13.0.0",
-        "semver": "^7.3.5"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/npm-profile": {
-      "version": "12.0.1",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "npm-registry-fetch": "^19.0.0",
-        "proc-log": "^6.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/npm-registry-fetch": {
-      "version": "19.1.1",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/redact": "^4.0.0",
-        "jsonparse": "^1.3.1",
-        "make-fetch-happen": "^15.0.0",
-        "minipass": "^7.0.2",
-        "minipass-fetch": "^5.0.0",
-        "minizlib": "^3.0.1",
-        "npm-package-arg": "^13.0.0",
-        "proc-log": "^6.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/npm-user-validate": {
-      "version": "4.0.0",
-      "inBundle": true,
-      "license": "BSD-2-Clause",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/p-map": {
-      "version": "7.0.4",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/npm/node_modules/pacote": {
-      "version": "21.1.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "@npmcli/git": "^7.0.0",
-        "@npmcli/installed-package-contents": "^4.0.0",
-        "@npmcli/package-json": "^7.0.0",
-        "@npmcli/promise-spawn": "^9.0.0",
-        "@npmcli/run-script": "^10.0.0",
-        "cacache": "^20.0.0",
-        "fs-minipass": "^3.0.0",
-        "minipass": "^7.0.2",
-        "npm-package-arg": "^13.0.0",
-        "npm-packlist": "^10.0.1",
-        "npm-pick-manifest": "^11.0.1",
-        "npm-registry-fetch": "^19.0.0",
-        "proc-log": "^6.0.0",
-        "promise-retry": "^2.0.1",
-        "sigstore": "^4.0.0",
-        "ssri": "^13.0.0",
-        "tar": "^7.4.3"
-      },
-      "bin": {
-        "pacote": "bin/index.js"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/parse-conflict-json": {
-      "version": "5.0.1",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "json-parse-even-better-errors": "^5.0.0",
-        "just-diff": "^6.0.0",
-        "just-diff-apply": "^5.2.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/path-scurry": {
-      "version": "2.0.1",
-      "inBundle": true,
-      "license": "BlueOak-1.0.0",
-      "dependencies": {
-        "lru-cache": "^11.0.0",
-        "minipass": "^7.1.2"
-      },
-      "engines": {
-        "node": "20 || >=22"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/npm/node_modules/postcss-selector-parser": {
-      "version": "7.1.1",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "cssesc": "^3.0.0",
-        "util-deprecate": "^1.0.2"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/npm/node_modules/proc-log": {
-      "version": "6.1.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/proggy": {
-      "version": "4.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/promise-all-reject-late": {
-      "version": "1.0.1",
-      "inBundle": true,
-      "license": "ISC",
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/npm/node_modules/promise-call-limit": {
-      "version": "3.0.2",
-      "inBundle": true,
-      "license": "ISC",
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/npm/node_modules/promise-retry": {
-      "version": "2.0.1",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "err-code": "^2.0.2",
-        "retry": "^0.12.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/npm/node_modules/promzard": {
-      "version": "3.0.1",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "read": "^5.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/qrcode-terminal": {
-      "version": "0.12.0",
-      "inBundle": true,
-      "bin": {
-        "qrcode-terminal": "bin/qrcode-terminal.js"
-      }
-    },
-    "node_modules/npm/node_modules/read": {
-      "version": "5.0.1",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "mute-stream": "^3.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/read-cmd-shim": {
-      "version": "6.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/retry": {
-      "version": "0.12.0",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "node_modules/npm/node_modules/safer-buffer": {
-      "version": "2.1.2",
-      "inBundle": true,
-      "license": "MIT",
-      "optional": true
-    },
-    "node_modules/npm/node_modules/semver": {
-      "version": "7.7.3",
-      "inBundle": true,
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/npm/node_modules/signal-exit": {
-      "version": "4.1.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": ">=14"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/npm/node_modules/sigstore": {
-      "version": "4.1.0",
-      "inBundle": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@sigstore/bundle": "^4.0.0",
-        "@sigstore/core": "^3.1.0",
-        "@sigstore/protobuf-specs": "^0.5.0",
-        "@sigstore/sign": "^4.1.0",
-        "@sigstore/tuf": "^4.0.1",
-        "@sigstore/verify": "^3.1.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/smart-buffer": {
-      "version": "4.2.0",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 6.0.0",
-        "npm": ">= 3.0.0"
-      }
-    },
-    "node_modules/npm/node_modules/socks": {
-      "version": "2.8.7",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "ip-address": "^10.0.1",
-        "smart-buffer": "^4.2.0"
-      },
-      "engines": {
-        "node": ">= 10.0.0",
-        "npm": ">= 3.0.0"
-      }
-    },
-    "node_modules/npm/node_modules/socks-proxy-agent": {
-      "version": "8.0.5",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "agent-base": "^7.1.2",
-        "debug": "^4.3.4",
-        "socks": "^2.8.3"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/npm/node_modules/spdx-correct": {
-      "version": "3.2.0",
-      "inBundle": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "spdx-expression-parse": "^3.0.0",
-        "spdx-license-ids": "^3.0.0"
-      }
-    },
-    "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": {
-      "version": "3.0.1",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "spdx-exceptions": "^2.1.0",
-        "spdx-license-ids": "^3.0.0"
-      }
-    },
-    "node_modules/npm/node_modules/spdx-exceptions": {
-      "version": "2.5.0",
-      "inBundle": true,
-      "license": "CC-BY-3.0"
-    },
-    "node_modules/npm/node_modules/spdx-expression-parse": {
-      "version": "4.0.0",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "spdx-exceptions": "^2.1.0",
-        "spdx-license-ids": "^3.0.0"
-      }
-    },
-    "node_modules/npm/node_modules/spdx-license-ids": {
-      "version": "3.0.22",
-      "inBundle": true,
-      "license": "CC0-1.0"
-    },
-    "node_modules/npm/node_modules/ssri": {
-      "version": "13.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "minipass": "^7.0.3"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/string-width": {
-      "version": "4.2.3",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "emoji-regex": "^8.0.0",
-        "is-fullwidth-code-point": "^3.0.0",
-        "strip-ansi": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/npm/node_modules/strip-ansi": {
-      "version": "6.0.1",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/npm/node_modules/supports-color": {
-      "version": "10.2.2",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/supports-color?sponsor=1"
-      }
-    },
-    "node_modules/npm/node_modules/tar": {
-      "version": "7.5.7",
-      "inBundle": true,
-      "license": "BlueOak-1.0.0",
-      "dependencies": {
-        "@isaacs/fs-minipass": "^4.0.0",
-        "chownr": "^3.0.0",
-        "minipass": "^7.1.2",
-        "minizlib": "^3.1.0",
-        "yallist": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/npm/node_modules/tar/node_modules/yallist": {
-      "version": "5.0.0",
-      "inBundle": true,
-      "license": "BlueOak-1.0.0",
-      "engines": {
-        "node": ">=18"
-      }
-    },
-    "node_modules/npm/node_modules/text-table": {
-      "version": "0.2.0",
-      "inBundle": true,
-      "license": "MIT"
-    },
-    "node_modules/npm/node_modules/tiny-relative-date": {
-      "version": "2.0.2",
-      "inBundle": true,
-      "license": "MIT"
-    },
-    "node_modules/npm/node_modules/tinyglobby": {
-      "version": "0.2.15",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "fdir": "^6.5.0",
-        "picomatch": "^4.0.3"
-      },
-      "engines": {
-        "node": ">=12.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/SuperchupuDev"
-      }
-    },
-    "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": {
-      "version": "6.5.0",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12.0.0"
-      },
-      "peerDependencies": {
-        "picomatch": "^3 || ^4"
-      },
-      "peerDependenciesMeta": {
-        "picomatch": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": {
-      "version": "4.0.3",
-      "inBundle": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=12"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/npm/node_modules/treeverse": {
-      "version": "3.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
-      }
-    },
-    "node_modules/npm/node_modules/tuf-js": {
-      "version": "4.1.0",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "@tufjs/models": "4.1.0",
-        "debug": "^4.4.3",
-        "make-fetch-happen": "^15.0.1"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/unique-filename": {
-      "version": "5.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "unique-slug": "^6.0.0"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/unique-slug": {
-      "version": "6.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "imurmurhash": "^0.1.4"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/util-deprecate": {
-      "version": "1.0.2",
-      "inBundle": true,
-      "license": "MIT"
-    },
-    "node_modules/npm/node_modules/validate-npm-package-license": {
-      "version": "3.0.4",
-      "inBundle": true,
-      "license": "Apache-2.0",
-      "dependencies": {
-        "spdx-correct": "^3.0.0",
-        "spdx-expression-parse": "^3.0.0"
-      }
-    },
-    "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": {
-      "version": "3.0.1",
-      "inBundle": true,
-      "license": "MIT",
-      "dependencies": {
-        "spdx-exceptions": "^2.1.0",
-        "spdx-license-ids": "^3.0.0"
-      }
-    },
-    "node_modules/npm/node_modules/validate-npm-package-name": {
-      "version": "7.0.2",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/walk-up-path": {
-      "version": "4.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "engines": {
-        "node": "20 || >=22"
-      }
-    },
-    "node_modules/npm/node_modules/which": {
-      "version": "6.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "isexe": "^3.1.1"
-      },
-      "bin": {
-        "node-which": "bin/which.js"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/write-file-atomic": {
-      "version": "7.0.0",
-      "inBundle": true,
-      "license": "ISC",
-      "dependencies": {
-        "imurmurhash": "^0.1.4",
-        "signal-exit": "^4.0.1"
-      },
-      "engines": {
-        "node": "^20.17.0 || >=22.9.0"
-      }
-    },
-    "node_modules/npm/node_modules/yallist": {
-      "version": "4.0.0",
-      "inBundle": true,
-      "license": "ISC"
-    },
-    "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/optionator": {
@@ -9513,24 +2806,4 @@
       }
     },
-    "node_modules/postcss-selector-parser": {
-      "version": "6.0.10",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
-      "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
-      "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==",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/prelude-ls": {
       "version": "1.2.1",
@@ -9542,21 +2815,4 @@
         "node": ">= 0.8.0"
       }
-    },
-    "node_modules/prop-types": {
-      "version": "15.8.1",
-      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
-      "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
-      "license": "MIT",
-      "dependencies": {
-        "loose-envify": "^1.4.0",
-        "object-assign": "^4.1.1",
-        "react-is": "^16.13.1"
-      }
-    },
-    "node_modules/prop-types/node_modules/react-is": {
-      "version": "16.13.1",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
-      "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
-      "license": "MIT"
     },
     "node_modules/proxy-from-env": {
@@ -9585,38 +2841,4 @@
       }
     },
-    "node_modules/react-apexcharts": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-2.1.0.tgz",
-      "integrity": "sha512-xrmeTKRKHh3cvvLc8SasqFjlOgIqGpyHc81qjnRtcjUM0Fu7qEjgVRWGPokGFjqhwRZVgEym8zmuEyYr5LMYIg==",
-      "license": "SEE LICENSE IN LICENSE",
-      "dependencies": {
-        "prop-types": "^15.8.1"
-      },
-      "peerDependencies": {
-        "apexcharts": ">=5.10.1",
-        "react": ">=16.8.0"
-      }
-    },
-    "node_modules/react-day-picker": {
-      "version": "9.5.0",
-      "resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.5.0.tgz",
-      "integrity": "sha512-WmJnPFVLnKh5Qscm7wavMNg86rqPverSWjx+zgK8/ZmGRSQ8c8OoqW10RI+AzAfT2atIxImpCUU2R9Z7Xb2SUA==",
-      "license": "MIT",
-      "dependencies": {
-        "@date-fns/tz": "^1.2.0",
-        "date-fns": "^4.1.0",
-        "date-fns-jalali": "^4.1.0-0"
-      },
-      "engines": {
-        "node": ">=18"
-      },
-      "funding": {
-        "type": "individual",
-        "url": "https://github.com/sponsors/gpbl"
-      },
-      "peerDependencies": {
-        "react": ">=16.8.0"
-      }
-    },
     "node_modules/react-dom": {
       "version": "19.2.4",
@@ -9631,35 +2853,4 @@
       }
     },
-    "node_modules/react-hook-form": {
-      "version": "7.71.1",
-      "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.1.tgz",
-      "integrity": "sha512-9SUJKCGKo8HUSsCO+y0CtqkqI5nNuaDqTxyqPsZPqIwudpj4rCrAz/jZV+jn57bx5gtZKOh3neQu94DXMc+w5w==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=18.0.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/react-hook-form"
-      },
-      "peerDependencies": {
-        "react": "^16.8.0 || ^17 || ^18 || ^19"
-      }
-    },
-    "node_modules/react-icons": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
-      "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
-      "license": "MIT",
-      "peerDependencies": {
-        "react": "*"
-      }
-    },
-    "node_modules/react-is": {
-      "version": "19.2.5",
-      "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.5.tgz",
-      "integrity": "sha512-Dn0t8IQhCmeIT3wu+Apm1/YVsJXsGWi6k4sPdnBIdqMVtHtv0IGi6dcpNpNkNac0zB2uUAqNX3MHzN8c+z2rwQ==",
-      "license": "MIT"
-    },
     "node_modules/react-refresh": {
       "version": "0.18.0",
@@ -9672,61 +2863,4 @@
       }
     },
-    "node_modules/react-remove-scroll": {
-      "version": "2.7.2",
-      "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz",
-      "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==",
-      "license": "MIT",
-      "dependencies": {
-        "react-remove-scroll-bar": "^2.3.7",
-        "react-style-singleton": "^2.2.3",
-        "tslib": "^2.1.0",
-        "use-callback-ref": "^1.3.3",
-        "use-sidecar": "^1.1.3"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/react-remove-scroll-bar": {
-      "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",
-      "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",
-      "license": "MIT",
-      "dependencies": {
-        "react-style-singleton": "^2.2.2",
-        "tslib": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/react-resizable-panels": {
-      "version": "2.1.9",
-      "resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-2.1.9.tgz",
-      "integrity": "sha512-z77+X08YDIrgAes4jl8xhnUu1LNIRp4+E7cv4xHmLOxxUPO/ML7PSrE813b90vj7xvQ1lcf7g2uA9GeMZonjhQ==",
-      "license": "MIT",
-      "peerDependencies": {
-        "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc",
-        "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
-      }
-    },
     "node_modules/react-router": {
       "version": "7.13.0",
@@ -9765,26 +2899,4 @@
         "react": ">=18",
         "react-dom": ">=18"
-      }
-    },
-    "node_modules/react-style-singleton": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
-      "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",
-      "license": "MIT",
-      "dependencies": {
-        "get-nonce": "^1.0.0",
-        "tslib": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
       }
     },
@@ -9893,4 +3005,5 @@
       "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
       "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+      "dev": true,
       "license": "BSD-3-Clause",
       "engines": {
@@ -9924,42 +3037,4 @@
       }
     },
-    "node_modules/tailwind-merge": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz",
-      "integrity": "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==",
-      "license": "MIT",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/dcastil"
-      }
-    },
-    "node_modules/tailwindcss": {
-      "version": "4.1.18",
-      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz",
-      "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==",
-      "license": "MIT"
-    },
-    "node_modules/tailwindcss-animate": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz",
-      "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==",
-      "license": "MIT",
-      "peerDependencies": {
-        "tailwindcss": ">=3.0.0 || insiders"
-      }
-    },
-    "node_modules/tapable": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz",
-      "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/webpack"
-      }
-    },
     "node_modules/tinyglobby": {
       "version": "0.2.15",
@@ -9978,10 +3053,4 @@
         "url": "https://github.com/sponsors/SuperchupuDev"
       }
-    },
-    "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==",
-      "license": "0BSD"
     },
     "node_modules/type-check": {
@@ -10038,53 +3107,4 @@
         "punycode": "^2.1.0"
       }
-    },
-    "node_modules/use-callback-ref": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",
-      "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",
-      "license": "MIT",
-      "dependencies": {
-        "tslib": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/use-sidecar": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
-      "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",
-      "license": "MIT",
-      "dependencies": {
-        "detect-node-es": "^1.1.0",
-        "tslib": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "peerDependencies": {
-        "@types/react": "*",
-        "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
-      },
-      "peerDependenciesMeta": {
-        "@types/react": {
-          "optional": true
-        }
-      }
-    },
-    "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": {
Index: frontend/package.json
===================================================================
--- frontend/package.json	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ frontend/package.json	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -11,34 +11,18 @@
   },
   "dependencies": {
-    "@dnd-kit/core": "^6.3.1",
-    "@dnd-kit/sortable": "^10.0.0",
-    "@dnd-kit/utilities": "^3.2.2",
-    "@relume_io/relume-tailwind": "^1.3.0",
-    "@relume_io/relume-ui": "^1.3.1",
-    "@tailwindcss/vite": "^4.1.18",
-    "apexcharts": "^5.10.6",
     "axios": "^1.13.4",
-    "daisyui": "^5.5.18",
     "react": "^19.2.0",
-    "react-apexcharts": "^2.1.0",
     "react-dom": "^19.2.0",
-    "react-icons": "^5.5.0",
-    "react-is": "^19.2.5",
     "react-router-dom": "^7.13.0"
   },
   "devDependencies": {
     "@eslint/js": "^9.39.1",
-    "@tailwindcss/cli": "^4.1.18",
-    "@tailwindcss/postcss": "^4.1.18",
     "@types/react": "^19.2.5",
     "@types/react-dom": "^19.2.3",
     "@vitejs/plugin-react": "^5.1.1",
-    "autoprefixer": "^10.4.24",
     "eslint": "^9.39.1",
     "eslint-plugin-react-hooks": "^7.0.1",
     "eslint-plugin-react-refresh": "^0.4.24",
     "globals": "^16.5.0",
-    "postcss": "^8.5.6",
-    "tailwindcss": "^4.1.18",
     "vite": "^7.2.4"
   }
Index: frontend/postcss.config.js
===================================================================
--- frontend/postcss.config.js	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,6 +1,0 @@
-export default {
-  plugins: {
-    "@tailwindcss/postcss": {},
-    autoprefixer: {},
-  },
-};
Index: frontend/src/App.css
===================================================================
--- frontend/src/App.css	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ frontend/src/App.css	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -1,5 +1,42 @@
+#root {
+  max-width: 1280px;
+  margin: 0 auto;
+  padding: 2rem;
+  text-align: center;
+}
 
-@import "tailwindcss";
-@plugin "daisyui" {
-    themes: light --default;
+.logo {
+  height: 6em;
+  padding: 1.5em;
+  will-change: filter;
+  transition: filter 300ms;
 }
+.logo:hover {
+  filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.react:hover {
+  filter: drop-shadow(0 0 2em #61dafbaa);
+}
+
+@keyframes logo-spin {
+  from {
+    transform: rotate(0deg);
+  }
+  to {
+    transform: rotate(360deg);
+  }
+}
+
+@media (prefers-reduced-motion: no-preference) {
+  a:nth-of-type(2) .logo {
+    animation: logo-spin infinite 20s linear;
+  }
+}
+
+.card {
+  padding: 2em;
+}
+
+.read-the-docs {
+  color: #888;
+}
Index: frontend/src/App.jsx
===================================================================
--- frontend/src/App.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ frontend/src/App.jsx	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -1,77 +1,35 @@
-import { Navigate, Route, Routes } from "react-router-dom";
-import { clearAuthSession, getAuthToken, isTokenExpired } from "./utils/authSession";
+import { useState } from 'react'
+import reactLogo from './assets/react.svg'
+import viteLogo from '/vite.svg'
+import './App.css'
 
-import LandingPage from "./pages/LandingPage/LandingPage.jsx";
-import Login from "./pages/Login/Login.jsx";
-import Register from "./pages/Register/Register.jsx";
-import DashboardLayout from "./pages/Dashboard/DashboardLayout.jsx";
-import ControlCenter from "./pages/Dashboard/pages/ControlCenter/ControlCenter.jsx";
-import Training from "./pages/Dashboard/pages/Training/Training.jsx";
-import TrainingTracking from "./pages/Dashboard/pages/Training/TrainingTracking.jsx";
-import NewTrainingSession from "./pages/Dashboard/pages/Training/NewTrainingSession.jsx";
-import Weight from "./pages/Dashboard/pages/Weight/Weight.jsx";
-import WeightTracking from "./pages/Dashboard/pages/Weight/WeightTracking.jsx";
-import NewWeightIntake from "./pages/Dashboard/pages/Weight/NewWeightIntake.jsx";
-import Finance from "./pages/Dashboard/pages/Finance/Finance.jsx";
-import FinanceTracking from "./pages/Dashboard/pages/Finance/FinanceTracking.jsx";
-import NewIncome from "./pages/Dashboard/pages/Finance/NewIncome.jsx";
-import Investing from "./pages/Dashboard/pages/Investing/Investing.jsx";
-import InvestingTracking from "./pages/Dashboard/pages/Investing/InvestingTracking.jsx";
-import NewInvestment from "./pages/Dashboard/pages/Investing/NewInvestment.jsx";
-import Discipline from "./pages/Dashboard/pages/Discipline/Discipline.jsx";
-import DisciplineTracking from "./pages/Dashboard/pages/Discipline/DisciplineTracking.jsx";
-import CustomCategoryKanban from "./pages/Dashboard/pages/CustomCategory/CustomCategoryKanban.jsx";
+function App() {
+  const [count, setCount] = useState(0)
 
-function RequireAuth({ children }) {
-  const token = getAuthToken();
-  if (token && isTokenExpired(token)) {
-    clearAuthSession();
-    return <Navigate to="/login" replace />;
-  }
-  if (!token) return <Navigate to="/login" replace />;
-  return children;
+  return (
+    <>
+      <div>
+        <a href="https://vite.dev" target="_blank">
+          <img src={viteLogo} className="logo" alt="Vite logo" />
+        </a>
+        <a href="https://react.dev" target="_blank">
+          <img src={reactLogo} className="logo react" alt="React logo" />
+        </a>
+      </div>
+      <h1>Vite + React</h1>
+      <div className="card">
+        <button onClick={() => setCount((count) => count + 1)}>
+          count is {count}
+        </button>
+        <p>
+          Edit <code>src/App.jsx</code> and save to test HMR
+        </p>
+      </div>
+      <p className="read-the-docs">
+        Click on the Vite and React logos to learn more
+      </p>
+    </>
+  )
 }
 
-function App() {
-  return (
-    <div data-theme="forest" className="min-h-screen w-full">
-      <Routes>
-        <Route path="/" element={<LandingPage />} />
-        <Route path="/login" element={<Login />} />
-        <Route path="/register" element={<Register />} />
-        <Route
-          path="/dashboard"
-          element={
-            <RequireAuth>
-              <DashboardLayout />
-            </RequireAuth>
-          }
-        >
-          <Route index element={<Navigate to="control-center" replace />} />
-          <Route path="control-center" element={<ControlCenter />} />
-          <Route path="training" element={<Training />} />
-          <Route path="training/tracking" element={<TrainingTracking />} />
-          <Route
-            path="training/sessions/new"
-            element={<NewTrainingSession />}
-          />
-          <Route path="weight" element={<Weight />} />
-          <Route path="weight/tracking" element={<WeightTracking />} />
-          <Route path="weight/intakes/new" element={<NewWeightIntake />} />
-          <Route path="finance" element={<Finance />} />
-           <Route path="finance/tracking" element={<FinanceTracking />} />
-           <Route path="finance/incomes/new" element={<NewIncome />} />
-          <Route path="investing" element={<Investing />} />
-          <Route path="investing/tracking" element={<InvestingTracking />} />
-          <Route path="investing/assets/new" element={<NewInvestment />} />
-          <Route path="discipline" element={<Discipline />} />
-           <Route path="discipline/tracking" element={<DisciplineTracking />} />
-           <Route path="custom/:customTrackingId" element={<CustomCategoryKanban />} />
-        </Route>
-        <Route path="*" element={<Navigate to="/" replace />} />
-      </Routes>
-    </div>
-  );
-}
-
-export default App;
+export default App
Index: frontend/src/api/axios.js
===================================================================
--- frontend/src/api/axios.js	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ frontend/src/api/axios.js	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -1,32 +1,6 @@
 import axios from "axios";
-import { getAuthToken, isTokenExpired, logoutAndRedirect } from "../utils/authSession";
 
-const api = axios.create({
-  baseURL: import.meta.env.VITE_API_BASE_URL ?? "http://localhost:8080/api",
+export default axios.create({
+  baseURL: "http://localhost:8080/api",
+  withCredentials: true, // important if using cookies
 });
-
-api.interceptors.request.use((config) => {
-  const token = getAuthToken();
-  if (token) {
-    if (isTokenExpired(token)) {
-      logoutAndRedirect("/dashboard");
-      return Promise.reject(new Error("Authentication session expired"));
-    }
-    config.headers = config.headers ?? {};
-    config.headers.Authorization = `Bearer ${token}`;
-  }
-  return config;
-});
-
-api.interceptors.response.use(
-  (response) => response,
-  (error) => {
-    const status = error?.response?.status;
-    if (status === 401 || status === 403) {
-      logoutAndRedirect("/dashboard");
-    }
-    return Promise.reject(error);
-  },
-);
-
-export default api;
Index: frontend/src/api/dailyCompletion.js
===================================================================
--- frontend/src/api/dailyCompletion.js	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,16 +1,0 @@
-import api from "./axios";
-
-export async function computeDailyCompletion(date /* yyyy-mm-dd or undefined */) {
-  const res = await api.post("/discipline/daily-completions/compute", null, {
-    params: date ? { date } : {},
-  });
-  return res?.data;
-}
-
-export async function getDailyCompletions({ page = 0, size = 14 } = {}) {
-  const res = await api.get("/discipline/daily-completions", {
-    params: { page, size },
-  });
-  return res?.data;
-}
-
Index: frontend/src/api/discipline.js
===================================================================
--- frontend/src/api/discipline.js	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,96 +1,0 @@
-import api from "./axios";
-
-export async function getDisciplineStatus() {
-  const res = await api.get("/discipline/status");
-  return Boolean(res?.data?.tracking);
-}
-
-export async function startDisciplineTracking() {
-  return api.post("/discipline/start", {});
-}
-
-export async function getTasks({ page = 0, size = 50 } = {}) {
-  const res = await api.get("/discipline/tasks", { params: { page, size } });
-  return res?.data;
-}
-
-export async function createTask(payload) {
-  const res = await api.post("/discipline/tasks", payload);
-  return res?.data;
-}
-
-export async function updateTask(taskId, payload) {
-  const res = await api.put(`/discipline/tasks/${taskId}`, payload);
-  return res?.data;
-}
-
-export async function updateTaskFinished(taskId, isFinished) {
-  const res = await api.patch(`/discipline/tasks/${taskId}/finished`, {
-    isFinished,
-  });
-  return res?.data;
-}
-
-export async function deleteTask(taskId) {
-  return api.delete(`/discipline/tasks/${taskId}`);
-}
-
-export async function getCustomTrackingCategories() {
-  const res = await api.get("/discipline/custom-tracking-categories");
-  return res?.data;
-}
-
-export async function createCustomTrackingCategory(payload) {
-  const res = await api.post("/discipline/custom-tracking-categories", payload);
-  return res?.data;
-}
-
-export async function getCustomCategoryTasks(customTrackingId) {
-  const res = await api.get(
-    `/discipline/custom-tracking-categories/${customTrackingId}/tasks`
-  );
-  return res?.data;
-}
-
-export async function createCustomCategoryTask(customTrackingId, payload) {
-  const res = await api.post(
-    `/discipline/custom-tracking-categories/${customTrackingId}/tasks`,
-    payload
-  );
-  return res?.data;
-}
-
-export async function updateCustomCategoryTask(customTrackingId, taskId, payload) {
-  const res = await api.put(
-    `/discipline/custom-tracking-categories/${customTrackingId}/tasks/${taskId}`,
-    payload
-  );
-  return res?.data;
-}
-
-export async function updateCustomCategoryTaskFinished(
-  customTrackingId,
-  taskId,
-  isFinished
-) {
-  const res = await api.patch(
-    `/discipline/custom-tracking-categories/${customTrackingId}/tasks/${taskId}/finished`,
-    { isFinished }
-  );
-  return res?.data;
-}
-
-export async function updateCustomCategoryTaskStatus(customTrackingId, taskId, status) {
-  const res = await api.patch(
-    `/discipline/custom-tracking-categories/${customTrackingId}/tasks/${taskId}/status`,
-    { status }
-  );
-  return res?.data;
-}
-
-export async function deleteCustomCategoryTask(customTrackingId, taskId) {
-  return api.delete(
-    `/discipline/custom-tracking-categories/${customTrackingId}/tasks/${taskId}`
-  );
-}
-
Index: frontend/src/api/finance.js
===================================================================
--- frontend/src/api/finance.js	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,26 +1,0 @@
-import api from "./axios";
-
-export async function getFinanceStatus() {
-  const res = await api.get("/finance/status");
-  return Boolean(res?.data?.tracking);
-}
-
-export async function startFinanceTracking(payload) {
-  return api.post("/finance/start", payload);
-}
-
-export async function getFinanceProfile() {
-  const res = await api.get("/finance/profile");
-  return res?.data;
-}
-
-export async function getIncomes({ page = 0, size = 5 } = {}) {
-  const res = await api.get("/finance/incomes", { params: { page, size } });
-  return res?.data;
-}
-
-export async function createIncome(payload) {
-  const res = await api.post("/finance/incomes", payload);
-  return res?.data;
-}
-
Index: frontend/src/api/twelveData.js
===================================================================
--- frontend/src/api/twelveData.js	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,284 +1,0 @@
-const BASE_URL =
-  import.meta.env.VITE_TWELVE_DATA_BASE_URL ?? "https://api.twelvedata.com";
-
-const API_KEY = import.meta.env.VITE_TWELVE_DATA_API_KEY ?? "";
-
-const CACHE_TTL_MS = 5 * 60_000;
-const MAX_SYMBOLS_PER_REQUEST = 20;
-
-// Cache by Twelve Data symbol (normalized)
-const priceCache = new Map();
-const inFlight = new Map();
-
-function getCachedPrice(twelveSymbol) {
-  const item = priceCache.get(twelveSymbol);
-  if (!item) return null;
-  if (Date.now() - item.ts > CACHE_TTL_MS) return null;
-  return item.price;
-}
-
-function setCachedPrice(twelveSymbol, price) {
-  if (!twelveSymbol || typeof price !== "number" || !Number.isFinite(price)) return;
-  priceCache.set(twelveSymbol, { price, ts: Date.now() });
-}
-
-function parsePriceJson(json, requestedSymbols) {
-  const out = {};
-  if (!json || typeof json !== "object" || Array.isArray(json)) return out;
-
-  // Single symbol response
-  if (json.price !== undefined && requestedSymbols.length === 1) {
-    const n = Number(json.price);
-    if (Number.isFinite(n)) out[requestedSymbols[0]] = n;
-    return out;
-  }
-
-  // Multi symbol response: object keyed by symbol
-  for (const sym of requestedSymbols) {
-    const n = Number(json?.[sym]?.price);
-    if (Number.isFinite(n)) out[sym] = n;
-  }
-
-  return out;
-}
-
-async function fetchBatchPrices(twelveSymbols) {
-  const params = new URLSearchParams();
-  params.set("symbol", twelveSymbols.join(","));
-  params.set("apikey", API_KEY);
-
-  const url = `${BASE_URL}/price?${params.toString()}`;
-  const resp = await fetch(url, { method: "GET" });
-
-  if (!resp.ok) {
-    const text = await resp.text().catch(() => "");
-    throw new Error(`Twelve Data request failed (HTTP ${resp.status}) ${text}`);
-  }
-
-  const json = await resp.json();
-  if (json?.status === "error") {
-    throw new Error(String(json?.message ?? "Twelve Data error"));
-  }
-
-  return parsePriceJson(json, twelveSymbols);
-}
-
-async function fetchSinglePrice(twelveSymbol) {
-  const cached = getCachedPrice(twelveSymbol);
-  if (typeof cached === "number") return cached;
-
-  if (inFlight.has(twelveSymbol)) return inFlight.get(twelveSymbol);
-
-  const p = (async () => {
-    const params = new URLSearchParams();
-    params.set("symbol", twelveSymbol);
-    params.set("apikey", API_KEY);
-    const url = `${BASE_URL}/price?${params.toString()}`;
-    const resp = await fetch(url, { method: "GET" });
-    if (!resp.ok) {
-      const text = await resp.text().catch(() => "");
-      throw new Error(`Twelve Data request failed (HTTP ${resp.status}) ${text}`);
-    }
-    const json = await resp.json();
-    if (json?.status === "error") {
-      throw new Error(String(json?.message ?? "Twelve Data error"));
-    }
-    const n = Number(json?.price);
-    if (!Number.isFinite(n)) throw new Error("Twelve Data returned no price");
-    setCachedPrice(twelveSymbol, n);
-    return n;
-  })();
-
-  inFlight.set(twelveSymbol, p);
-  try {
-    return await p;
-  } finally {
-    inFlight.delete(twelveSymbol);
-  }
-}
-
-async function fetchSingleExchangeRate(pairSymbol) {
-  const cached = getCachedPrice(pairSymbol);
-  if (typeof cached === "number") return cached;
-
-  if (inFlight.has(pairSymbol)) return inFlight.get(pairSymbol);
-
-  const p = (async () => {
-    const params = new URLSearchParams();
-    params.set("symbol", pairSymbol);
-    params.set("apikey", API_KEY);
-    const url = `${BASE_URL}/exchange_rate?${params.toString()}`;
-    const resp = await fetch(url, { method: "GET" });
-    if (!resp.ok) {
-      const text = await resp.text().catch(() => "");
-      throw new Error(`Twelve Data request failed (HTTP ${resp.status}) ${text}`);
-    }
-    const json = await resp.json();
-    if (json?.status === "error") {
-      throw new Error(String(json?.message ?? "Twelve Data error"));
-    }
-
-    const n = Number(json?.rate);
-    if (!Number.isFinite(n)) throw new Error("Twelve Data returned no rate");
-    setCachedPrice(pairSymbol, n);
-    return n;
-  })();
-
-  inFlight.set(pairSymbol, p);
-  try {
-    return await p;
-  } finally {
-    inFlight.delete(pairSymbol);
-  }
-}
-
-export function toTwelveSymbol(symbol) {
-  if (!symbol) return "";
-  const s = String(symbol).trim().toUpperCase();
-  if (!s) return "";
-
-  // Already Twelve format (common for FX/crypto)
-  if (s.includes("/")) return s;
-
-  // Common Yahoo-style crypto tickers
-  const cryptoMap = {
-    "BTC-USD": "BTC/USD",
-    "ETH-USD": "ETH/USD",
-    "SOL-USD": "SOL/USD",
-    "BNB-USD": "BNB/USD",
-    "XRP-USD": "XRP/USD",
-    "ADA-USD": "ADA/USD",
-    "DOGE-USD": "DOGE/USD",
-    "AVAX-USD": "AVAX/USD",
-    "DOT-USD": "DOT/USD",
-    "LINK-USD": "LINK/USD",
-    "MATIC-USD": "MATIC/USD",
-    "LTC-USD": "LTC/USD",
-  };
-
-  if (cryptoMap[s]) return cryptoMap[s];
-
-  // Default: assume it's a stock/ETF symbol (AAPL, SPY, BRK-B, ...)
-  return s;
-}
-
-/**
- * Fetch current prices for one or more symbols.
- * Returns an object keyed by *original input symbols* (uppercased), with numeric prices.
- */
-export async function fetchCurrentPricesBySymbol(symbols) {
-  const input = Array.isArray(symbols) ? symbols : [];
-  const uniqueOriginal = Array.from(
-    new Set(input.map((s) => String(s ?? "").trim()).filter(Boolean)),
-  );
-
-  if (uniqueOriginal.length === 0) return {};
-
-  if (!API_KEY) {
-    throw new Error(
-      "Missing Twelve Data API key (set VITE_TWELVE_DATA_API_KEY in frontend/.env.local)",
-    );
-  }
-
-  // Map original -> twelve
-  const originalToTwelve = new Map();
-  for (const orig of uniqueOriginal) {
-    originalToTwelve.set(orig, toTwelveSymbol(orig));
-  }
-
-  const allTwelveSymbols = Array.from(
-    new Set(Array.from(originalToTwelve.values()).filter(Boolean)),
-  );
-
-  const pairSymbols = allTwelveSymbols.filter((s) => String(s).includes("/"));
-  const priceSymbols = allTwelveSymbols.filter((s) => !String(s).includes("/"));
-
-  // Gather prices with cache + resilient fetch (batch first, fall back to per-symbol)
-  const twelvePrices = {};
-  const missing = [];
-  let hadAnyError = false;
-  let lastErrorMessage = "";
-
-  for (const sym of allTwelveSymbols) {
-    const cached = getCachedPrice(sym);
-    if (typeof cached === "number") {
-      twelvePrices[sym] = cached;
-    } else {
-      missing.push(sym);
-    }
-  }
-
-  // Fetch pair symbols via exchange_rate (generally the most reliable for FX/crypto pairs)
-  for (const sym of pairSymbols) {
-    if (twelvePrices[sym] !== undefined) continue;
-    try {
-      const n = await fetchSingleExchangeRate(sym);
-      if (Number.isFinite(n)) twelvePrices[sym] = n;
-    } catch (e) {
-      hadAnyError = true;
-      lastErrorMessage = e?.message || lastErrorMessage;
-    }
-  }
-
-  // Chunk batch requests to avoid overly long URLs; if a batch fails, we continue
-  // with per-symbol fetches so one invalid symbol doesn't break everything.
-  const missingPrices = missing.filter((s) => priceSymbols.includes(s));
-
-  for (let i = 0; i < missingPrices.length; i += MAX_SYMBOLS_PER_REQUEST) {
-    const chunk = missingPrices.slice(i, i + MAX_SYMBOLS_PER_REQUEST);
-    try {
-      const got = await fetchBatchPrices(chunk);
-      for (const [sym, price] of Object.entries(got)) {
-        const n = Number(price);
-        if (Number.isFinite(n)) {
-          twelvePrices[sym] = n;
-          setCachedPrice(sym, n);
-        }
-      }
-
-      // Some symbols might not come back in a multi-symbol response; fetch them individually.
-      for (const sym of chunk) {
-        if (twelvePrices[sym] !== undefined) continue;
-        try {
-          const n = await fetchSinglePrice(sym);
-          if (Number.isFinite(n)) twelvePrices[sym] = n;
-        } catch (e) {
-          // ignore single-symbol failures
-          hadAnyError = true;
-          lastErrorMessage = e?.message || lastErrorMessage;
-        }
-      }
-    } catch (e) {
-      // Fall back to per-symbol if the whole batch failed.
-      hadAnyError = true;
-      lastErrorMessage = e?.message || lastErrorMessage;
-      await Promise.all(
-        chunk.map(async (sym) => {
-          try {
-            const n = await fetchSinglePrice(sym);
-            if (Number.isFinite(n)) twelvePrices[sym] = n;
-          } catch (e2) {
-            // ignore
-            hadAnyError = true;
-            lastErrorMessage = e2?.message || lastErrorMessage;
-          }
-        }),
-      );
-    }
-  }
-
-  // Convert back to original symbols
-  const out = {};
-  for (const [orig, twelve] of originalToTwelve.entries()) {
-    const p = twelvePrices[twelve];
-    if (typeof p === "number") {
-      out[String(orig).toUpperCase()] = p;
-    }
-  }
-
-  if (Object.keys(out).length === 0 && hadAnyError) {
-    throw new Error(lastErrorMessage || "Could not fetch any current prices");
-  }
-
-  return out;
-}
Index: frontend/src/api/yahooFinance.js
===================================================================
--- frontend/src/api/yahooFinance.js	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,148 +1,0 @@
-import { LOCAL_TICKER_SYMBOLS } from "../data/tickers";
-
-const tickerSearchCache = new Map();
-const TICKER_CACHE_TTL_MS = 15 * 60 * 1000;
-
-const quoteCache = new Map();
-const QUOTE_CACHE_TTL_MS = 5 * 60 * 1000;
-let quoteBackoffUntilMs = 0;
-
-async function tryFetchJson(url) {
-  // Note: We intentionally do NOT set custom headers here.
-  // Custom headers usually trigger a CORS preflight which Yahoo won't allow.
-  const resp = await fetch(url, { method: "GET" });
-  if (!resp.ok) {
-    throw new Error(`Yahoo Finance HTTP ${resp.status}`);
-  }
-  return resp.json();
-}
-
-function toTickerOption(raw) {
-  const symbol = raw?.symbol ? String(raw.symbol) : "";
-  if (!symbol) return null;
-
-  const name = raw?.shortname || raw?.longname || raw?.name || "";
-  const exchange = raw?.exchDisp || raw?.exchange || "";
-
-  return {
-    symbol,
-    name: name ? String(name) : "",
-    exchange: exchange ? String(exchange) : "",
-    quoteType: raw?.quoteType ? String(raw.quoteType) : "",
-  };
-}
-
-/**
- * Direct Yahoo Finance search (yfinance data source).
- * Falls back to backend proxy if the browser blocks CORS.
- */
-export async function searchTickers(query, limit = 20) {
-  const q = String(query ?? "").trim();
-  if (!q) return [];
-  const safeLimit = Math.max(1, Math.min(Number(limit) || 20, 25));
-
-  const cacheKey = `${q.toUpperCase()}:${safeLimit}`;
-  const cached = tickerSearchCache.get(cacheKey);
-  const now = Date.now();
-  if (cached && cached.expiresAt > now) {
-    return cached.value;
-  }
-
-  // Offline/local ticker search: avoids Yahoo 429s and keeps the dropdown reliable.
-  const upperQ = q.toUpperCase();
-  const symbols = Array.isArray(LOCAL_TICKER_SYMBOLS) ? LOCAL_TICKER_SYMBOLS : [];
-  const out = symbols
-    .map((s) => String(s ?? "").trim())
-    .filter(Boolean)
-    .filter((s) => s.toUpperCase().includes(upperQ))
-    .slice(0, safeLimit)
-    .map((symbol) => ({ symbol, name: "", exchange: "" }));
-
-  tickerSearchCache.set(cacheKey, {
-    value: out,
-    expiresAt: now + TICKER_CACHE_TTL_MS,
-  });
-  return out;
-}
-
-/**
- * Direct Yahoo Finance quotes (yfinance data source).
- * Returns a map { SYMBOL: priceNumber }.
- * Falls back to backend proxy if the browser blocks CORS.
- */
-export async function getQuotesBySymbol(symbols) {
-  const list = Array.isArray(symbols) ? symbols : [];
-  const unique = Array.from(
-    new Set(
-      list
-        .map((s) => String(s ?? "").trim())
-        .filter(Boolean)
-        .map((s) => s.toUpperCase()),
-    ),
-  );
-
-  if (unique.length === 0) return {};
-
-  const parseYahoo = (json) => {
-    const results = Array.isArray(json?.quoteResponse?.result)
-      ? json.quoteResponse.result
-      : [];
-    const map = {};
-    for (const r of results) {
-      const sym = r?.symbol ? String(r.symbol).toUpperCase() : "";
-      const price = r?.regularMarketPrice;
-      if (!sym) continue;
-      if (typeof price !== "number") continue;
-      map[sym] = price;
-    }
-    return map;
-  };
-
-  const now = Date.now();
-  const out = {};
-
-  // Serve cache first.
-  const toFetch = [];
-  for (const sym of unique) {
-    const cached = quoteCache.get(sym);
-    if (cached && cached.expiresAt > now && typeof cached.price === "number") {
-      out[sym] = cached.price;
-    } else {
-      toFetch.push(sym);
-    }
-  }
-
-  // Production builds: browser CORS blocks Yahoo, so quotes are unavailable without a proxy.
-  if (!import.meta.env.DEV) {
-    return out;
-  }
-
-  // Backoff after 429s.
-  if (now < quoteBackoffUntilMs) {
-    return out;
-  }
-
-  if (toFetch.length === 0) {
-    return out;
-  }
-
-  const yahooUrl = `/yahoo/v7/finance/quote?symbols=${encodeURIComponent(
-    toFetch.join(","),
-  )}`;
-
-  try {
-    const json = await tryFetchJson(yahooUrl);
-    const fresh = parseYahoo(json);
-    for (const [sym, price] of Object.entries(fresh)) {
-      quoteCache.set(sym, { price, expiresAt: Date.now() + QUOTE_CACHE_TTL_MS });
-      out[sym] = price;
-    }
-    return out;
-  } catch (e) {
-    const msg = String(e?.message ?? "");
-    if (msg.includes("HTTP 429")) {
-      quoteBackoffUntilMs = Date.now() + 60_000;
-    }
-    return out;
-  }
-}
Index: frontend/src/assets/graph-placeholder.svg
===================================================================
--- frontend/src/assets/graph-placeholder.svg	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,52 +1,0 @@
-<svg width="1200" height="500" viewBox="0 0 1200 500" fill="none" xmlns="http://www.w3.org/2000/svg">
-  <defs>
-    <linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
-      <stop offset="0" stop-color="#0b1f14"/>
-      <stop offset="1" stop-color="#0f2a1c"/>
-    </linearGradient>
-    <linearGradient id="line" x1="0" y1="0" x2="1" y2="0">
-      <stop offset="0" stop-color="#34d399"/>
-      <stop offset="1" stop-color="#22c55e"/>
-    </linearGradient>
-  </defs>
-
-  <rect x="0" y="0" width="1200" height="500" rx="24" fill="url(#bg)"/>
-
-  <!-- grid -->
-  <g opacity="0.15" stroke="#FFFFFF">
-    <path d="M96 80H1120"/>
-    <path d="M96 160H1120"/>
-    <path d="M96 240H1120"/>
-    <path d="M96 320H1120"/>
-    <path d="M96 400H1120"/>
-
-    <path d="M192 64V432"/>
-    <path d="M320 64V432"/>
-    <path d="M448 64V432"/>
-    <path d="M576 64V432"/>
-    <path d="M704 64V432"/>
-    <path d="M832 64V432"/>
-    <path d="M960 64V432"/>
-    <path d="M1088 64V432"/>
-  </g>
-
-  <!-- axes -->
-  <path d="M96 432H1120" stroke="#FFFFFF" opacity="0.35"/>
-  <path d="M96 64V432" stroke="#FFFFFF" opacity="0.35"/>
-
-  <!-- line -->
-  <path d="M96 360 C 220 310, 280 240, 384 260 C 480 280, 560 180, 640 190 C 740 205, 820 120, 928 140 C 1010 155, 1060 120, 1120 110" stroke="url(#line)" stroke-width="6" fill="none"/>
-
-  <!-- points -->
-  <g fill="#34d399">
-    <circle cx="96" cy="360" r="7"/>
-    <circle cx="384" cy="260" r="7"/>
-    <circle cx="640" cy="190" r="7"/>
-    <circle cx="928" cy="140" r="7"/>
-    <circle cx="1120" cy="110" r="7"/>
-  </g>
-
-  <text x="96" y="44" fill="#E5E7EB" font-family="ui-sans-serif, system-ui" font-size="18" opacity="0.9">
-    Graph placeholder
-  </text>
-</svg>
Index: frontend/src/components/graphs/MultiPercentChangeAreaChart.jsx
===================================================================
--- frontend/src/components/graphs/MultiPercentChangeAreaChart.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,104 +1,0 @@
-import React, { Suspense, lazy, useMemo } from "react";
-
-import { formatBucketLabel } from "../../utils/timeSeries.js";
-
-// Lazy-load ApexCharts (same as PercentChangeAreaChart)
-const ApexChart = lazy(() => import("react-apexcharts"));
-
-/**
- * Multi-series % change area chart.
- *
- * seriesList: [{ name: string, points: [{ts, value}], color: string }]
- * granularity: daily | weekly | monthly | yearly
- */
-export default function MultiPercentChangeAreaChart({
-  seriesList,
-  granularity,
-  height = 320,
-}) {
-  const series = useMemo(() => {
-    return (seriesList ?? []).map((s) => ({
-      name: s.name,
-      data: (s.points ?? []).map((p) => ({ x: p.ts, y: Number(p.value ?? 0) })),
-    }));
-  }, [seriesList]);
-
-  const colors = useMemo(() => (seriesList ?? []).map((s) => s.color), [seriesList]);
-
-  const options = useMemo(() => {
-    return {
-      chart: {
-        type: "area",
-        stacked: false,
-        toolbar: { show: false },
-        zoom: { enabled: false },
-        animations: { enabled: true, easing: "easeinout", speed: 450 },
-        fontFamily: "inherit",
-        foreColor: "rgba(255,255,255,0.72)",
-      },
-      stroke: { curve: "smooth", width: 2 },
-      fill: {
-        type: "gradient",
-        gradient: {
-          shadeIntensity: 0.18,
-          opacityFrom: 0.22,
-          opacityTo: 0.03,
-          stops: [0, 90, 100],
-        },
-      },
-      dataLabels: { enabled: false },
-      grid: {
-        borderColor: "rgba(255,255,255,0.08)",
-        strokeDashArray: 4,
-      },
-      legend: {
-        show: false, // we render our own legend outside for better layout
-      },
-      xaxis: {
-        type: "datetime",
-        labels: {
-          datetimeUTC: false,
-          formatter: (value, timestamp) => formatBucketLabel(timestamp, granularity),
-        },
-        axisBorder: { color: "rgba(255,255,255,0.10)" },
-        axisTicks: { color: "rgba(255,255,255,0.10)" },
-      },
-      yaxis: {
-        labels: {
-          formatter: (v) => `${Math.round(v)}%`,
-        },
-      },
-      tooltip: {
-        theme: "dark",
-        y: {
-          formatter: (v) => `${Number(v ?? 0).toFixed(1)}%`,
-        },
-      },
-      colors,
-      annotations: {
-        yaxis: [
-          {
-            y: 0,
-            borderColor: "rgba(255,255,255,0.25)",
-            strokeDashArray: 4,
-          },
-        ],
-      },
-    };
-  }, [colors, granularity]);
-
-  return (
-    <div className="w-full">
-      <Suspense
-        fallback={
-          <div className="flex items-center justify-center" style={{ height }}>
-            <span className="loading loading-spinner loading-md" />
-          </div>
-        }
-      >
-        <ApexChart options={options} series={series} type="area" height={height} />
-      </Suspense>
-    </div>
-  );
-}
-
Index: frontend/src/components/graphs/PercentChangeAreaChart.jsx
===================================================================
--- frontend/src/components/graphs/PercentChangeAreaChart.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,103 +1,0 @@
-import React, { Suspense, lazy, useMemo } from "react";
-
-import { formatBucketLabel } from "../../utils/timeSeries.js";
-
-// Code-split the charting library (ApexCharts) so it doesn't bloat the initial bundle.
-const ApexChart = lazy(() => import("react-apexcharts"));
-
-export default function PercentChangeAreaChart({
-  points,
-  granularity,
-  height = 260,
-  positiveColor = "#22c55e",
-}) {
-  const series = useMemo(() => {
-    const data = (points ?? []).map((p) => ({ x: p.ts, y: Number(p.value ?? 0) }));
-    return [{ name: "% change", data }];
-  }, [points]);
-
-  const options = useMemo(() => {
-    return {
-      chart: {
-        type: "area",
-        toolbar: { show: false },
-        zoom: { enabled: false },
-        animations: { enabled: true, easing: "easeinout", speed: 450 },
-        fontFamily: "inherit",
-        foreColor: "rgba(255,255,255,0.72)",
-      },
-      stroke: {
-        curve: "smooth",
-        width: 2,
-      },
-      fill: {
-        type: "gradient",
-        gradient: {
-          shadeIntensity: 0.2,
-          opacityFrom: 0.35,
-          opacityTo: 0.05,
-          stops: [0, 90, 100],
-        },
-      },
-      dataLabels: { enabled: false },
-      grid: {
-        borderColor: "rgba(255,255,255,0.08)",
-        strokeDashArray: 4,
-      },
-      xaxis: {
-        type: "datetime",
-        labels: {
-          datetimeUTC: false,
-          formatter: (value, timestamp) => formatBucketLabel(timestamp, granularity),
-        },
-        axisBorder: { color: "rgba(255,255,255,0.10)" },
-        axisTicks: { color: "rgba(255,255,255,0.10)" },
-      },
-      yaxis: {
-        labels: {
-          formatter: (v) => `${Math.round(v)}%`,
-        },
-      },
-      tooltip: {
-        theme: "dark",
-        y: {
-          formatter: (_v, opts) => {
-            const p = points?.[opts.dataPointIndex];
-            const pct = Number(p?.value ?? 0);
-            const base = Number(p?.base ?? 0);
-            return `${pct.toFixed(1)}% (base ${Math.round(base)})`;
-          },
-        },
-      },
-      colors: [positiveColor],
-      annotations: {
-        yaxis: [
-          {
-            y: 0,
-            borderColor: "rgba(255,255,255,0.25)",
-            strokeDashArray: 4,
-          },
-        ],
-      },
-      // Color negative area differently by using a second series-like trick is overkill;
-      // we keep a single color and rely on the 0% line for readability.
-    };
-  }, [granularity, points, positiveColor]);
-
-  return (
-    <div className="w-full">
-      <Suspense
-        fallback={
-          <div className="flex items-center justify-center" style={{ height }}>
-            <span className="loading loading-spinner loading-md" />
-          </div>
-        }
-      >
-        <ApexChart options={options} series={series} type="area" height={height} />
-      </Suspense>
-    </div>
-  );
-}
-
-
-
Index: frontend/src/components/graphs/TimeRangeToggle.jsx
===================================================================
--- frontend/src/components/graphs/TimeRangeToggle.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,30 +1,0 @@
-import React from "react";
-
-export default function TimeRangeToggle({ value, onChange }) {
-  const TIME_RANGES = [
-    { key: "daily", label: "Daily" },
-    { key: "weekly", label: "Weekly" },
-    { key: "monthly", label: "Monthly" },
-    { key: "yearly", label: "Yearly" },
-  ];
-
-  return (
-    <div className="join">
-      {TIME_RANGES.map((r) => (
-        <button
-          key={r.key}
-          type="button"
-          className={
-            "btn btn-xs join-item " +
-            (value === r.key ? "btn-success" : "btn-ghost")
-          }
-          onClick={() => onChange?.(r.key)}
-        >
-          {r.label}
-        </button>
-      ))}
-    </div>
-  );
-}
-
-
Index: frontend/src/data/tickers.js
===================================================================
--- frontend/src/data/tickers.js	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,173 +1,0 @@
-// A pragmatic, hardcoded list to keep ticker selection reliable.
-// Add/remove symbols as needed.
-// Symbols use Yahoo Finance format (e.g., BTC-USD, BRK-B).
-
-export const LOCAL_TICKER_SYMBOLS = [
-  // Crypto (USD pairs)
-  "BTC/USD",
-  "ETH/USD",
-  "SOL/USD",
-  "BNB/USD",
-  "XRP/USD",
-  "ADA/USD",
-  "DOGE/USD",
-  "AVAX/USD",
-  "DOT/USD",
-  "LINK/USD",
-  "MATIC/USD",
-  "LTC/USD",
-
-  // Major ETFs / indices proxies
-  "SPY",
-  "VOO",
-  "IVV",
-  "QQQ",
-  "VTI",
-  "IWM",
-  "DIA",
-  "VEA",
-  "VWO",
-  "EFA",
-  "EEM",
-  "SCHD",
-  "VIG",
-  "VNQ",
-  "TLT",
-  "IEF",
-  "SHY",
-  "HYG",
-  "LQD",
-  "GLD",
-  "SLV",
-  "USO",
-
-  // Mega-cap / large-cap US
-  "AAPL",
-  "MSFT",
-  "NVDA",
-  "AMZN",
-  "GOOGL",
-  "GOOG",
-  "META",
-  "TSLA",
-  "BRK-B",
-  "JPM",
-  "V",
-  "MA",
-  "LLY",
-  "AVGO",
-  "UNH",
-  "XOM",
-  "COST",
-  "HD",
-  "PG",
-  "JNJ",
-  "ORCL",
-  "KO",
-  "PEP",
-  "BAC",
-  "WMT",
-  "ABBV",
-  "MRK",
-  "CVX",
-  "CRM",
-  "ADBE",
-  "NFLX",
-  "AMD",
-  "INTC",
-  "CSCO",
-  "QCOM",
-  "TXN",
-  "IBM",
-  "INTU",
-  "AMAT",
-  "NOW",
-  "ISRG",
-  "GE",
-  "CAT",
-  "BA",
-  "DE",
-  "MMM",
-  "HON",
-  "LOW",
-  "SBUX",
-  "NKE",
-  "MCD",
-  "DIS",
-  "CMCSA",
-  "T",
-  "VZ",
-  "PFE",
-  "TMO",
-  "ABT",
-  "DHR",
-  "LIN",
-  "NEE",
-  "DUK",
-  "SO",
-  "PLD",
-  "AMT",
-  "CCI",
-
-  // Popular growth / tech
-  "SHOP",
-  "SNOW",
-  "PLTR",
-  "UBER",
-  "ABNB",
-  "RBLX",
-  "SQ",
-  "PYPL",
-  "ROKU",
-  "ZM",
-  "DOCU",
-  "CRWD",
-  "PANW",
-  "ZS",
-  "NET",
-  "DDOG",
-  "MDB",
-
-  // Finance
-  "GS",
-  "MS",
-  "C",
-  "WFC",
-  "AXP",
-  "BLK",
-
-  // Energy
-  "COP",
-  "SLB",
-  "OXY",
-
-  // Consumer / retail
-  "TGT",
-  "TJX",
-  "C",
-  "CROX",
-  "LULU",
-  "COST",
-  "WMT",
-  "AMZN",
-
-  // Autos
-  "F",
-  "GM",
-
-  // Semis
-  "ASML",
-  "TSM",
-  "MU",
-  "LRCX",
-  "KLAC",
-
-  // Misc
-  "SPOT",
-  "BABA",
-  "JD",
-  "PDD",
-  "NVO",
-  "TM",
-  "SONY",
-];
Index: frontend/src/index.css
===================================================================
--- frontend/src/index.css	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ frontend/src/index.css	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -1,8 +1,68 @@
-@source "../node_modules/@relume_io/relume-ui/dist/**/*.mjs";
-@source "../node_modules/@relume_io/relume-ui/dist/**/*.js";
+:root {
+  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
+  line-height: 1.5;
+  font-weight: 400;
 
-@import "tailwindcss";
+  color-scheme: light dark;
+  color: rgba(255, 255, 255, 0.87);
+  background-color: #242424;
 
-@plugin "daisyui" {
-    themes: forest --default;
+  font-synthesis: none;
+  text-rendering: optimizeLegibility;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
 }
+
+a {
+  font-weight: 500;
+  color: #646cff;
+  text-decoration: inherit;
+}
+a:hover {
+  color: #535bf2;
+}
+
+body {
+  margin: 0;
+  display: flex;
+  place-items: center;
+  min-width: 320px;
+  min-height: 100vh;
+}
+
+h1 {
+  font-size: 3.2em;
+  line-height: 1.1;
+}
+
+button {
+  border-radius: 8px;
+  border: 1px solid transparent;
+  padding: 0.6em 1.2em;
+  font-size: 1em;
+  font-weight: 500;
+  font-family: inherit;
+  background-color: #1a1a1a;
+  cursor: pointer;
+  transition: border-color 0.25s;
+}
+button:hover {
+  border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+  outline: 4px auto -webkit-focus-ring-color;
+}
+
+@media (prefers-color-scheme: light) {
+  :root {
+    color: #213547;
+    background-color: #ffffff;
+  }
+  a:hover {
+    color: #747bff;
+  }
+  button {
+    background-color: #f9f9f9;
+  }
+}
Index: frontend/src/main.jsx
===================================================================
--- frontend/src/main.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ frontend/src/main.jsx	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -1,14 +1,10 @@
-import { StrictMode } from "react";
-import { createRoot } from "react-dom/client";
-import { BrowserRouter } from "react-router-dom";
+import { StrictMode } from 'react'
+import { createRoot } from 'react-dom/client'
+import './index.css'
+import App from './App.jsx'
 
-import "./index.css";
-import App from "./App.jsx";
-
-createRoot(document.getElementById("root")).render(
+createRoot(document.getElementById('root')).render(
   <StrictMode>
-    <BrowserRouter>
-      <App />
-    </BrowserRouter>
+    <App />
   </StrictMode>,
-);
+)
Index: frontend/src/pages/Dashboard.jsx
===================================================================
--- frontend/src/pages/Dashboard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,61 +1,0 @@
-import React, { useMemo } from "react";
-import { Link, useNavigate } from "react-router-dom";
-
-const Dashboard = () => {
-  const navigate = useNavigate();
-
-  const user = useMemo(() => {
-    try {
-      const raw = localStorage.getItem("authUser");
-      return raw ? JSON.parse(raw) : null;
-    } catch {
-      return null;
-    }
-  }, []);
-
-  const onLogout = () => {
-    localStorage.removeItem("authToken");
-    localStorage.removeItem("authUser");
-    navigate("/", { replace: true });
-  };
-
-  return (
-    <div className="min-h-screen p-6">
-      <div className="max-w-3xl mx-auto">
-        <div className="flex items-center justify-between gap-3">
-          <h1 className="text-2xl font-bold">Dashboard</h1>
-          <div className="flex items-center gap-2">
-            <Link className="btn btn-ghost" to="/">
-              Landing
-            </Link>
-            <button className="btn btn-outline" onClick={onLogout}>
-              Logout
-            </button>
-          </div>
-        </div>
-
-        <div className="mt-6 card bg-base-200 border border-base-300">
-          <div className="card-body">
-            <h2 className="card-title">Account</h2>
-            <div className="text-sm leading-7">
-              <div>
-                <span className="opacity-70">Username:</span>{" "}
-                <span className="font-medium">{user?.username ?? "—"}</span>
-              </div>
-              <div>
-                <span className="opacity-70">Email:</span>{" "}
-                <span className="font-medium">{user?.email ?? "—"}</span>
-              </div>
-              <div>
-                <span className="opacity-70">User ID:</span>{" "}
-                <span className="font-medium">{user?.userId ?? "—"}</span>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  );
-};
-
-export default Dashboard;
Index: frontend/src/pages/Dashboard/DashboardLayout.jsx
===================================================================
--- frontend/src/pages/Dashboard/DashboardLayout.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,58 +1,0 @@
-import React, { useMemo } from "react";
-import { Outlet, useNavigate } from "react-router-dom";
-
-import { SidebarInset, SidebarProvider } from "@relume_io/relume-ui";
-
-import DashboardSidebar from "./components/DashboardSidebar.jsx";
-import DashboardTopbar from "./components/DashboardTopbar.jsx";
-import { clearAuthSession } from "../../utils/authSession";
-
-const DashboardLayout = () => {
-  const navigate = useNavigate();
-
-  const user = useMemo(() => {
-    try {
-      const raw = localStorage.getItem("authUser");
-      return raw ? JSON.parse(raw) : null;
-    } catch {
-      return null;
-    }
-  }, []);
-
-  const username = user?.username ?? "";
-
-  const onLogout = () => {
-    clearAuthSession();
-    navigate("/", { replace: true });
-  };
-
-  return (
-    <SidebarProvider>
-      {/* App shell background */}
-      <div className="pointer-events-none fixed inset-0 -z-10">
-        <div className="absolute inset-0 bg-base-300/10" />
-        <div className="absolute inset-0 bg-radial-[circle_at_20%_20%] from-green-400/10 via-transparent to-transparent" />
-        <div className="absolute inset-0 bg-radial-[circle_at_80%_30%] from-blue-400/10 via-transparent to-transparent" />
-        <div className="absolute inset-0 bg-linear-to-b from-black/10 via-transparent to-black/25" />
-      </div>
-
-      <DashboardSidebar />
-
-      <SidebarInset className="pt-16 lg:pt-0">
-        <DashboardTopbar username={username} onLogout={onLogout} />
-
-        <div className="h-[calc(100vh-4rem)] overflow-auto">
-          <div className="mx-auto w-full max-w-7xl px-4 py-6 sm:px-6 sm:py-8 lg:px-8 lg:py-10">
-            <div className="rounded-3xl border border-white/10 bg-base-100/60 shadow-[0_0_0_1px_rgba(255,255,255,0.04),0_24px_90px_rgba(0,0,0,0.35)] backdrop-blur-xl">
-              <div className="p-4 sm:p-6 lg:p-8">
-                <Outlet />
-              </div>
-            </div>
-          </div>
-        </div>
-      </SidebarInset>
-    </SidebarProvider>
-  );
-};
-
-export default DashboardLayout;
Index: frontend/src/pages/Dashboard/components/AddCustomCategoryModal.jsx
===================================================================
--- frontend/src/pages/Dashboard/components/AddCustomCategoryModal.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,101 +1,0 @@
-import React, { useEffect, useMemo, useState } from "react";
-import { createPortal } from "react-dom";
-
-export default function AddCustomCategoryModal({ open, onClose, onSubmit }) {
-  const [name, setName] = useState("");
-  const [submitting, setSubmitting] = useState(false);
-  const [error, setError] = useState(null);
-
-  // Reset the form whenever the modal is opened.
-  // NOTE: Hooks must be called in the same order on every render; do not early-return before hooks.
-  useEffect(() => {
-    if (!open) return;
-    setName("");
-    setError(null);
-    setSubmitting(false);
-  }, [open]);
-
-  const canSubmit = useMemo(() => {
-    return name.trim().length > 0 && name.trim().length <= 100 && !submitting;
-  }, [name, submitting]);
-
-  async function handleSubmit(e) {
-    e.preventDefault();
-    if (!canSubmit) return;
-
-    setSubmitting(true);
-    setError(null);
-    try {
-      await onSubmit({ name: name.trim() });
-      onClose?.();
-    } catch (err) {
-      setError(
-        err?.response?.data?.message ||
-          err?.message ||
-          "Failed to create custom category"
-      );
-      setSubmitting(false);
-    }
-  }
-
-  if (!open) return null;
-
-  return createPortal(
-    <div className="fixed inset-0 z-[100] flex items-center justify-center p-4">
-      <button
-        type="button"
-        className="absolute inset-0 bg-black/60"
-        aria-label="Close modal"
-        onClick={onClose}
-      />
-
-      <div className="relative w-full max-w-md rounded-xl bg-neutral-900 p-5 text-white shadow-xl">
-        <div className="flex items-center justify-between gap-4">
-          <h2 className="text-lg font-semibold">Add Custom Category</h2>
-          <button
-            type="button"
-            onClick={onClose}
-            className="rounded-md px-2 py-1 text-sm text-white/80 hover:bg-white/10"
-          >
-            Close
-          </button>
-        </div>
-
-        <form onSubmit={handleSubmit} className="mt-4 space-y-3">
-          <div>
-            <label className="mb-1 block text-sm text-white/80">Name</label>
-            <input
-              value={name}
-              onChange={(e) => setName(e.target.value)}
-              maxLength={100}
-              autoFocus
-              className="w-full rounded-lg border border-white/10 bg-black/40 px-3 py-2 text-sm outline-none focus:border-green-400"
-              placeholder="e.g. My Habit Tracking"
-            />
-            <div className="mt-1 text-xs text-white/50">
-              {name.trim().length}/100
-            </div>
-          </div>
-
-          {error ? (
-            <div className="rounded-lg border border-red-500/30 bg-red-500/10 p-2 text-sm text-red-200">
-              {error}
-            </div>
-          ) : null}
-
-          <button
-            type="submit"
-            disabled={!canSubmit}
-            className="w-full rounded-lg bg-green-400 px-3 py-2 text-sm font-medium text-black disabled:cursor-not-allowed disabled:opacity-60"
-          >
-            {submitting ? "Creating..." : "Create"}
-          </button>
-        </form>
-      </div>
-    </div>,
-    document.body
-  );
-}
-
-
-
Index: frontend/src/pages/Dashboard/components/DashboardSidebar.jsx
===================================================================
--- frontend/src/pages/Dashboard/components/DashboardSidebar.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,209 +1,0 @@
-import React, { useEffect, useMemo, useState } from "react";
-import { NavLink, useLocation } from "react-router-dom";
-
-import {
-  Button,
-  Sidebar,
-  SidebarContent,
-  SidebarHeader,
-  SidebarMenu,
-  SidebarMenuButton,
-  SidebarMenuItem,
-} from "@relume_io/relume-ui";
-
-import {
-  MdTune,
-  MdFitnessCenter,
-  MdMonitorWeight,
-  MdAccountBalanceWallet,
-  MdTrendingUp,
-  MdChecklist,
-  MdAdd,
-  MdBook,
-  MdFlag,
-  MdStar,
-  MdBolt,
-  MdNoteAlt,
-  MdAutoGraph,
-} from "react-icons/md";
-
-import logo from "../../../assets/logo.png";
-
-import AddCustomCategoryModal from "./AddCustomCategoryModal.jsx";
-import {
-  createCustomTrackingCategory,
-  getCustomTrackingCategories,
-} from "../../../api/discipline.js";
-
-const navItems = [
-  { title: "Control Center", to: "/dashboard/control-center", icon: MdTune },
-  { title: "Training", to: "/dashboard/training", icon: MdFitnessCenter },
-  { title: "Weight", to: "/dashboard/weight", icon: MdMonitorWeight },
-  { title: "Finance", to: "/dashboard/finance", icon: MdAccountBalanceWallet },
-  { title: "Investing", to: "/dashboard/investing", icon: MdTrendingUp },
-  { title: "Discipline", to: "/dashboard/discipline", icon: MdChecklist },
-];
-
-const CUSTOM_ICONS = [MdBook, MdFlag, MdStar, MdBolt, MdNoteAlt, MdAutoGraph];
-
-function stableIconForId(id) {
-  const n = Number(id);
-  if (!Number.isFinite(n)) return CUSTOM_ICONS[0];
-  return CUSTOM_ICONS[Math.abs(n) % CUSTOM_ICONS.length];
-}
-
-const DashboardSidebar = () => {
-  const location = useLocation();
-  const [customOpen, setCustomOpen] = useState(false);
-  const [customCategories, setCustomCategories] = useState([]);
-
-  useEffect(() => {
-    let mounted = true;
-    (async () => {
-      try {
-        const res = await getCustomTrackingCategories();
-        const items = res?.items ?? [];
-        if (mounted) setCustomCategories(items);
-      } catch {
-        // If the user isn't authenticated yet or the endpoint fails,
-        // keep the sidebar usable (no custom categories).
-        if (mounted) setCustomCategories([]);
-      }
-    })();
-    return () => {
-      mounted = false;
-    };
-  }, []);
-
-  const customNavItems = useMemo(() => {
-    return (customCategories ?? []).map((c) => {
-      const Icon = stableIconForId(c.customTrackingId);
-      return {
-        title: c.name,
-        to: `/dashboard/custom/${c.customTrackingId}`,
-        icon: Icon,
-      };
-    });
-  }, [customCategories]);
-
-  return (
-    <Sidebar
-      className="py-6 border-r border-white/10 bg-base-100/60 backdrop-blur-xl"
-      closeButtonClassName="fixed top-4 right-4"
-      collapsible="none"
-    >
-      <SidebarHeader className="hidden lg:block">
-        <NavLink to="/" className="flex items-center gap-3 px-2">
-          <img src={logo} alt="Trekr" className="h-10 w-auto rounded-2xl" />
-        </NavLink>
-      </SidebarHeader>
-
-      <SidebarContent className="mt-6">
-        <SidebarMenu>
-          {navItems.map((item) => (
-            <SidebarMenuItem key={item.title}>
-              {(() => {
-                const isActive =
-                  location.pathname === item.to ||
-                  location.pathname.startsWith(`${item.to}/`);
-
-                return (
-                  <SidebarMenuButton
-                    asChild
-                    isActive={isActive}
-                    className={
-                      isActive
-                        ? "bg-green-400! text-black! hover:bg-green-400! active:bg-green-400!"
-                        : "hover:bg-white/10!"
-                    }
-                  >
-                    <NavLink
-                      to={item.to}
-                      className="flex w-full items-center gap-3"
-                    >
-                      <item.icon
-                        className={
-                          isActive
-                            ? "size-6 shrink-0 text-black"
-                            : "size-6 shrink-0"
-                        }
-                      />
-                      <span className={isActive ? "text-black" : ""}>
-                        {item.title}
-                      </span>
-                    </NavLink>
-                  </SidebarMenuButton>
-                );
-              })()}
-            </SidebarMenuItem>
-          ))}
-
-          {customNavItems.length > 0 ? (
-            <div className="my-4 border-t border-white/10" />
-          ) : null}
-
-          {customNavItems.map((item) => (
-            <SidebarMenuItem key={`custom-${item.to}`}>
-              {(() => {
-                const isActive =
-                  location.pathname === item.to ||
-                  location.pathname.startsWith(`${item.to}/`);
-
-                return (
-                  <SidebarMenuButton
-                    asChild
-                    isActive={isActive}
-                    className={
-                      isActive
-                        ? "bg-green-400! text-black! hover:bg-green-400! active:bg-green-400!"
-                        : "hover:bg-white/10!"
-                    }
-                  >
-                    <NavLink
-                      to={item.to}
-                      className="flex w-full items-center gap-3"
-                    >
-                      <item.icon
-                        className={
-                          isActive
-                            ? "size-6 shrink-0 text-black"
-                            : "size-6 shrink-0"
-                        }
-                      />
-                      <span className={isActive ? "text-black" : ""}>
-                        {item.title}
-                      </span>
-                    </NavLink>
-                  </SidebarMenuButton>
-                );
-              })()}
-            </SidebarMenuItem>
-          ))}
-        </SidebarMenu>
-
-        <div className="mt-6 px-2">
-          <Button
-            variant="secondary"
-            className="w-full justify-start gap-2 bg-green-400! text-black! hover:bg-green-500!"
-            type="button"
-            onClick={() => setCustomOpen(true)}
-          >
-            <MdAdd className="size-5" />
-            <span>Add Custom</span>
-          </Button>
-        </div>
-
-        <AddCustomCategoryModal
-          open={customOpen}
-          onClose={() => setCustomOpen(false)}
-          onSubmit={async (payload) => {
-            const created = await createCustomTrackingCategory(payload);
-            setCustomCategories((prev) => [created, ...(prev ?? [])]);
-          }}
-        />
-      </SidebarContent>
-    </Sidebar>
-  );
-};
-
-export default DashboardSidebar;
Index: frontend/src/pages/Dashboard/components/DashboardTopbar.jsx
===================================================================
--- frontend/src/pages/Dashboard/components/DashboardTopbar.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,59 +1,0 @@
-import React from "react";
-import { Link } from "react-router-dom";
-
-import { MdLogout } from "react-icons/md";
-
-import logo from "../../../assets/logo.png";
-
-const DashboardTopbar = ({ username, onLogout }) => {
-  return (
-    <>
-      {/* Desktop */}
-      <div className="sticky top-0 z-30 hidden min-h-16 w-full items-center border-b border-white/10 bg-base-100/70 px-6 backdrop-blur-xl lg:flex lg:px-8">
-        <div className="mx-auto grid size-full grid-cols-1 items-center justify-end justify-items-end gap-4 lg:grid-cols-[1fr_max-content] lg:justify-between lg:justify-items-stretch">
-          <div className="flex items-center gap-3"></div>
-
-          <div className="flex items-center gap-3">
-            <span className="text-sm opacity-80">{username || "—"}</span>
-            <button
-              type="button"
-              className="btn btn-ghost btn-sm hover:bg-white/10 transition"
-              onClick={onLogout}
-              aria-label="Log out"
-              title="Log out"
-            >
-              <MdLogout className="size-5" />
-            </button>
-          </div>
-        </div>
-      </div>
-
-      {/* Mobile */}
-      <div className="fixed left-0 right-0 top-0 z-30 flex min-h-16 w-full items-center justify-between border-b border-white/10 bg-base-100/70 px-4 backdrop-blur-xl sm:px-6 lg:hidden">
-        <div className="flex items-center gap-4">
-          <Link
-            to="/dashboard"
-            className="flex items-center gap-3"
-            aria-label="Trekr dashboard"
-          >
-            <img src={logo} alt="Trekr" className="h-10 w-auto rounded-2xl" />
-          </Link>
-        </div>
-        <div className="flex items-center gap-3">
-          <span className="text-sm opacity-80">{username || "—"}</span>
-          <button
-            type="button"
-            className="btn btn-ghost btn-sm hover:bg-white/10 transition"
-            onClick={onLogout}
-            aria-label="Log out"
-            title="Log out"
-          >
-            <MdLogout className="size-5" />
-          </button>
-        </div>
-      </div>
-    </>
-  );
-};
-
-export default DashboardTopbar;
Index: frontend/src/pages/Dashboard/pages/ControlCenter/ControlCenter.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/ControlCenter/ControlCenter.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,581 +1,0 @@
-import React, { useCallback, useEffect, useMemo, useState } from "react";
-
-import api from "../../../../api/axios";
-import { getFinanceStatus, getIncomes } from "../../../../api/finance";
-import { getDisciplineStatus } from "../../../../api/discipline";
-import { getDailyCompletions } from "../../../../api/dailyCompletion";
-
-import MultiPercentChangeAreaChart from "../../../../components/graphs/MultiPercentChangeAreaChart.jsx";
-import TimeRangeToggle from "../../../../components/graphs/TimeRangeToggle.jsx";
-import { percentChangeSeries, sumByTimeBucket } from "../../../../utils/timeSeries.js";
-
-import TrainingProgressCard from "../Training/components/TrainingProgressCard.jsx";
-import WeightProgressCard from "../Weight/components/WeightProgressCard.jsx";
-import FinanceProgressCard from "../Finance/components/FinanceProgressCard.jsx";
-import DisciplineProgressCard from "../Discipline/components/DisciplineProgressCard.jsx";
-import InvestingProgressCard from "../Investing/components/InvestingProgressCard.jsx";
-
-function Legend({ items, enabledKeys, onToggle, onShowAll, onHideAll }) {
-  if (!items?.length) return null;
-
-  return (
-    <div className="flex flex-col gap-2">
-      <div className="flex flex-wrap justify-end gap-2">
-        <button
-          type="button"
-          className="btn btn-ghost btn-xs hover:bg-white/10"
-          onClick={onShowAll}
-        >
-          Show all
-        </button>
-        <button
-          type="button"
-          className="btn btn-ghost btn-xs hover:bg-white/10"
-          onClick={onHideAll}
-        >
-          Hide all
-        </button>
-      </div>
-
-      <div className="flex flex-wrap gap-x-4 gap-y-2 text-xs">
-        {items.map((it) => {
-          const enabled = enabledKeys?.has(it.key);
-          return (
-            <button
-              key={it.key}
-              type="button"
-              onClick={() => onToggle?.(it.key)}
-              className={
-                "flex items-center gap-2 rounded-full border px-2.5 py-1 transition " +
-                (enabled
-                  ? "border-base-300 bg-base-100 hover:bg-base-100/70"
-                  : "border-transparent bg-base-300/30 opacity-60 hover:opacity-80")
-              }
-              title={enabled ? "Click to hide" : "Click to show"}
-            >
-              <span
-                className="inline-block h-2.5 w-2.5 rounded-full"
-                style={{ backgroundColor: it.color }}
-                aria-hidden
-              />
-              <span className="opacity-90">{it.label}</span>
-            </button>
-          );
-        })}
-      </div>
-    </div>
-  );
-}
-
-export default function ControlCenter() {
-  const [range, setRange] = useState("weekly");
-
-  const [visibleSeries, setVisibleSeries] = useState(() => new Set());
-
-  const [isLoading, setIsLoading] = useState(true);
-  const [error, setError] = useState("");
-
-  const [tracking, setTracking] = useState({
-    weight: false,
-    training: false,
-    finance: false,
-    discipline: false,
-    investing: false,
-  });
-
-  const [trainingSessions, setTrainingSessions] = useState([]);
-  const [weightProfile, setWeightProfile] = useState(null);
-  const [weightIntakes, setWeightIntakes] = useState([]);
-  const [financeIncomes, setFinanceIncomes] = useState([]);
-  const [disciplineCompletions, setDisciplineCompletions] = useState([]);
-  const [investingAssets, setInvestingAssets] = useState([]);
-
-  const fetchAllPaged = useCallback(async (fnPage, pageSize, maxPages = 400) => {
-    let p = 0;
-    let hasMorePages = true;
-    const all = [];
-    while (hasMorePages) {
-      const res = await fnPage(p, pageSize);
-      const items = res.items;
-      all.push(...items);
-      hasMorePages = Boolean(res.hasMore) && items.length > 0;
-      p += 1;
-      if (p > maxPages) break;
-    }
-    return all;
-  }, []);
-
-  useEffect(() => {
-    let cancelled = false;
-    (async () => {
-      try {
-        setIsLoading(true);
-        setError("");
-
-        // Determine tracking flags (cheap endpoints)
-        const [weightRes, trainingRes, investingRes, financeTracking, disciplineTracking] =
-          await Promise.all([
-            api.get("/weight/status"),
-            api.get("/training/status"),
-            api.get("/investing/status"),
-            getFinanceStatus(),
-            getDisciplineStatus(),
-          ]);
-
-        const nextTracking = {
-          weight: Boolean(weightRes?.data?.tracking),
-          training: Boolean(trainingRes?.data?.tracking),
-          investing: Boolean(investingRes?.data?.tracking),
-          finance: Boolean(financeTracking),
-          discipline: Boolean(disciplineTracking),
-        };
-
-        if (cancelled) return;
-        setTracking(nextTracking);
-
-        // Data fetches (only for tracked features)
-        const tasks = [];
-
-        if (nextTracking.training) {
-          tasks.push(
-            fetchAllPaged(
-              async (page, size) => {
-                const resp = await api.get("/training/sessions", { params: { page, size } });
-                const data = resp?.data ?? {};
-                return {
-                  items: Array.isArray(data.sessions) ? data.sessions : [],
-                  hasMore: Boolean(data.hasMore),
-                };
-              },
-              500,
-              200,
-            ).then((all) => setTrainingSessions(all)),
-          );
-        }
-
-        if (nextTracking.weight) {
-          tasks.push(
-            api.get("/weight/profile").then((res) => setWeightProfile(res?.data ?? null)),
-          );
-          tasks.push(
-            fetchAllPaged(
-              async (page, size) => {
-                const resp = await api.get("/weight/intakes", { params: { page, size } });
-                const data = resp?.data ?? {};
-                return {
-                  items: Array.isArray(data.intakes) ? data.intakes : [],
-                  hasMore: Boolean(data.hasMore),
-                };
-              },
-              500,
-              200,
-            ).then((all) => setWeightIntakes(all)),
-          );
-        }
-
-        if (nextTracking.finance) {
-          tasks.push(
-            fetchAllPaged(
-              async (page, size) => {
-                const data = await getIncomes({ page, size });
-                return {
-                  items: Array.isArray(data?.incomes) ? data.incomes : [],
-                  hasMore: Boolean(data?.hasMore),
-                };
-              },
-              500,
-              200,
-            ).then((all) => setFinanceIncomes(all)),
-          );
-        }
-
-        if (nextTracking.discipline) {
-          tasks.push(
-            fetchAllPaged(
-              async (page, size) => {
-                const data = await getDailyCompletions({ page, size });
-                return {
-                  items: Array.isArray(data?.completions) ? data.completions : [],
-                  hasMore: Boolean(data?.hasMore),
-                };
-              },
-              500,
-              400,
-            ).then((all) => setDisciplineCompletions(all)),
-          );
-        }
-
-        if (nextTracking.investing) {
-          tasks.push(
-            fetchAllPaged(
-              async (page, size) => {
-                const resp = await api.get("/investing/assets", { params: { page, size } });
-                const data = resp?.data ?? {};
-                return {
-                  items: Array.isArray(data.assets) ? data.assets : [],
-                  hasMore: Boolean(data.hasMore),
-                };
-              },
-              200,
-              200,
-            ).then((all) => setInvestingAssets(all)),
-          );
-        }
-
-        await Promise.all(tasks);
-      } catch (e) {
-        if (cancelled) return;
-        setError(e?.response?.data?.message || "Failed to load Control Center.");
-      } finally {
-        if (!cancelled) setIsLoading(false);
-      }
-    })();
-
-    return () => {
-      cancelled = true;
-    };
-  }, [fetchAllPaged]);
-
-  const weightGoalCalories = weightProfile?.goalCalories ?? null;
-  const isBulking = useMemo(() => {
-    const current = Number(weightProfile?.weight);
-    const goal = Number(weightProfile?.goalWeight);
-    if (!Number.isFinite(current) || !Number.isFinite(goal)) return null;
-    return goal > current;
-  }, [weightProfile]);
-
-  const combinedLegend = useMemo(
-    () =>
-      [
-        tracking.training ? { key: "training", label: "Training", color: "#22c55e" } : null,
-        tracking.weight ? { key: "weight", label: "Weight", color: "#60a5fa" } : null,
-        tracking.finance ? { key: "finance", label: "Finance", color: "#a855f7" } : null,
-        tracking.discipline ? { key: "discipline", label: "Discipline", color: "#fbbf24" } : null,
-        tracking.investing ? { key: "investing", label: "Investing", color: "#14b8a6" } : null,
-      ].filter(Boolean),
-    [tracking],
-  );
-
-  // Initialize visible series to "all tracked" whenever tracking changes.
-  useEffect(() => {
-    setVisibleSeries(new Set((combinedLegend ?? []).map((x) => x.key)));
-  }, [combinedLegend]);
-
-  const onToggleSeries = useCallback((key) => {
-    setVisibleSeries((prev) => {
-      const next = new Set(prev);
-      if (next.has(key)) next.delete(key);
-      else next.add(key);
-      return next;
-    });
-  }, []);
-
-  const onShowAllSeries = useCallback(() => {
-    setVisibleSeries(new Set((combinedLegend ?? []).map((x) => x.key)));
-  }, [combinedLegend]);
-
-  const onHideAllSeries = useCallback(() => {
-    setVisibleSeries(new Set());
-  }, []);
-
-  const combinedSeriesList = useMemo(() => {
-    const out = [];
-
-    if (tracking.training) {
-      const buckets = sumByTimeBucket(
-        trainingSessions,
-        range,
-        (s) => s.date,
-        (s) => s.calories,
-      );
-      out.push({
-        name: "Training",
-        key: "training",
-        color: "#22c55e",
-        points: percentChangeSeries(buckets),
-      });
-    }
-
-    if (tracking.finance) {
-      const buckets = sumByTimeBucket(
-        financeIncomes,
-        range,
-        (i) => i.date,
-        (i) => i.amount,
-      );
-      out.push({
-        name: "Finance",
-        key: "finance",
-        color: "#a855f7",
-        points: percentChangeSeries(buckets),
-      });
-    }
-
-    if (tracking.discipline) {
-      // average completion per bucket
-      const sums = sumByTimeBucket(
-        disciplineCompletions,
-        range,
-        (c) => c.date,
-        (c) => Number(c?.procent) || 0,
-      );
-      const counts = sumByTimeBucket(
-        disciplineCompletions,
-        range,
-        (c) => c.date,
-        () => 1,
-      );
-      const countByTs = new Map(counts.map((p) => [p.ts, p.value]));
-      const avgPoints = sums.map((p) => {
-        const count = Number(countByTs.get(p.ts) ?? 0);
-        const avg = count > 0 ? Number(p.value ?? 0) / count : 0;
-        return { ts: p.ts, value: avg };
-      });
-
-      out.push({
-        name: "Discipline",
-        key: "discipline",
-        color: "#fbbf24",
-        points: percentChangeSeries(avgPoints),
-      });
-    }
-
-    if (tracking.investing) {
-      const buckets = sumByTimeBucket(
-        investingAssets,
-        range,
-        (a) => a.buyDate,
-        (a) => (Number(a?.quantity) || 0) * (Number(a?.buyPrice) || 0),
-      );
-      out.push({
-        name: "Investing",
-        key: "investing",
-        color: "#14b8a6",
-        points: percentChangeSeries(buckets),
-      });
-    }
-
-    if (tracking.weight) {
-      // replicate WeightProgressCard base series (closeness %) then % change.
-      const totals = sumByTimeBucket(
-        weightIntakes,
-        range,
-        (i) => i.date,
-        (i) => Number(i?.calories) || 0,
-      );
-      const goalTotals = sumByTimeBucket(
-        weightIntakes,
-        range,
-        (i) => i.date,
-        (i) => {
-          const goal = Number(weightGoalCalories);
-          if (!Number.isFinite(goal) || goal <= 0) return 0;
-          const burned = Number(i?.burnedCalories) || 0;
-          const trained = Boolean(i?.trainedThatDay);
-          return trained ? goal + burned : goal;
-        },
-      );
-      const goalByTs = new Map(goalTotals.map((p) => [p.ts, p.value]));
-      const closeness = totals.map((p) => {
-        const adjustedGoal = Number(goalByTs.get(p.ts) ?? 0);
-        const calories = Number(p.value ?? 0);
-        if (!Number.isFinite(adjustedGoal) || adjustedGoal <= 0) return { ts: p.ts, value: 0 };
-        const pct = 100 - (Math.abs(calories - adjustedGoal) / adjustedGoal) * 100;
-        const clamped = Math.min(200, Math.max(0, pct));
-        return { ts: p.ts, value: clamped };
-      });
-      let weightSeries = percentChangeSeries(closeness);
-      if (isBulking === false) {
-        weightSeries = weightSeries.map((p) => ({ ...p, value: -Number(p.value ?? 0) }));
-      }
-      // Weight graph is reversed (matches WeightProgressCard)
-      weightSeries = weightSeries.map((p) => ({ ...p, value: -Number(p.value ?? 0) }));
-
-      out.push({
-        name: "Weight",
-        key: "weight",
-        color: "#60a5fa",
-        points: weightSeries,
-      });
-    }
-
-    return out;
-  }, [
-    disciplineCompletions,
-    financeIncomes,
-    investingAssets,
-    isBulking,
-    range,
-    tracking,
-    trainingSessions,
-    weightGoalCalories,
-    weightIntakes,
-  ]);
-
-  const filteredCombinedSeriesList = useMemo(() => {
-    return (combinedSeriesList ?? []).filter((s) => visibleSeries.has(s.key));
-  }, [combinedSeriesList, visibleSeries]);
-
-  const trackedCount = Object.values(tracking).filter(Boolean).length;
-
-  if (isLoading) {
-    return (
-      <div className="space-y-6">
-        <h1 className="text-2xl font-bold">Control Center</h1>
-        <div className="card bg-base-200 border border-base-300">
-          <div className="card-body">
-            <p className="opacity-80">Loading…</p>
-          </div>
-        </div>
-      </div>
-    );
-  }
-
-  if (error) {
-    return (
-      <div className="space-y-6">
-        <h1 className="text-2xl font-bold">Control Center</h1>
-        <div className="alert alert-error">
-          <span>{error}</span>
-        </div>
-      </div>
-    );
-  }
-
-  if (trackedCount === 0) {
-    return (
-      <div className="space-y-6">
-        <h1 className="text-2xl font-bold">Control Center</h1>
-        <div className="card bg-base-200 border border-base-300">
-          <div className="card-body">
-            <p className="opacity-80">
-              Start tracking at least one area (Weight / Training / Finance / Discipline / Investing) to see your dashboard.
-            </p>
-          </div>
-        </div>
-      </div>
-    );
-  }
-
-  return (
-    <div className="space-y-8">
-      <div className="flex items-start justify-between gap-4 flex-wrap">
-        <div>
-          <h1 className="text-2xl font-bold tracking-tight">Control Center</h1>
-          <p className="mt-1 text-sm opacity-70">
-            Correlate your progress across everything you track.
-          </p>
-        </div>
-        <TimeRangeToggle value={range} onChange={setRange} />
-      </div>
-
-      <div className="card bg-base-200/60 border border-white/10 shadow-[0_0_0_1px_rgba(255,255,255,0.04)] backdrop-blur">
-        <div className="card-body">
-          <div className="flex items-start justify-between gap-4 flex-wrap">
-            <div>
-              <h2 className="card-title">Correlation</h2>
-              <p className="mt-1 text-xs opacity-70">
-                Toggle lines to isolate signals. All metrics are % change per {range} bucket.
-              </p>
-            </div>
-            <Legend
-              items={combinedLegend}
-              enabledKeys={visibleSeries}
-              onToggle={onToggleSeries}
-              onShowAll={onShowAllSeries}
-              onHideAll={onHideAllSeries}
-            />
-          </div>
-
-          <div className="mt-4 w-full overflow-hidden rounded-xl border border-base-300 bg-base-100 p-2">
-            {filteredCombinedSeriesList.length === 0 ? (
-              <div className="flex h-80 items-center justify-center text-sm opacity-70">
-                Toggle at least one line in the legend to display the chart.
-              </div>
-            ) : filteredCombinedSeriesList.every((s) => (s.points?.length ?? 0) < 2) ? (
-              <div className="flex h-80 items-center justify-center text-sm opacity-70">
-                Add more history to see correlations.
-              </div>
-            ) : (
-              <MultiPercentChangeAreaChart
-                seriesList={filteredCombinedSeriesList}
-                granularity={range}
-                height={340}
-              />
-            )}
-          </div>
-
-          <div className="mt-3 text-xs opacity-70">
-            Each line uses the same time bucket toggle, but has its own base metric (calories, income totals, completion average, etc.).
-          </div>
-        </div>
-      </div>
-
-      <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-2 gap-6">
-        {tracking.training ? (
-          <div>
-            <div className="mb-2 flex items-center justify-between">
-              <h3 className="font-semibold">Training</h3>
-              <span className="badge badge-ghost" style={{ borderColor: "#22c55e" }}>
-                % change
-              </span>
-            </div>
-            <TrainingProgressCard sessions={trainingSessions} />
-          </div>
-        ) : null}
-
-        {tracking.weight ? (
-          <div>
-            <div className="mb-2 flex items-center justify-between">
-              <h3 className="font-semibold">Weight</h3>
-              <span className="badge badge-ghost" style={{ borderColor: "#60a5fa" }}>
-                % change
-              </span>
-            </div>
-            <WeightProgressCard
-              intakes={weightIntakes}
-              goalCalories={weightGoalCalories}
-              isBulking={isBulking}
-            />
-          </div>
-        ) : null}
-
-        {tracking.finance ? (
-          <div>
-            <div className="mb-2 flex items-center justify-between">
-              <h3 className="font-semibold">Finance</h3>
-              <span className="badge badge-ghost" style={{ borderColor: "#a855f7" }}>
-                % change
-              </span>
-            </div>
-            <FinanceProgressCard incomes={financeIncomes} />
-          </div>
-        ) : null}
-
-        {tracking.discipline ? (
-          <div>
-            <div className="mb-2 flex items-center justify-between">
-              <h3 className="font-semibold">Discipline</h3>
-              <span className="badge badge-ghost" style={{ borderColor: "#fbbf24" }}>
-                % change
-              </span>
-            </div>
-            <DisciplineProgressCard completions={disciplineCompletions} />
-          </div>
-        ) : null}
-
-        {tracking.investing ? (
-          <div>
-            <div className="mb-2 flex items-center justify-between">
-              <h3 className="font-semibold">Investing</h3>
-              <span className="badge badge-ghost" style={{ borderColor: "#14b8a6" }}>
-                % change
-              </span>
-            </div>
-            <InvestingProgressCard assets={investingAssets} />
-          </div>
-        ) : null}
-      </div>
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/CustomCategory/CustomCategoryKanban.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/CustomCategory/CustomCategoryKanban.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,118 +1,0 @@
-import React, { useEffect, useMemo, useState } from "react";
-import { useParams } from "react-router-dom";
-
-import {
-  createCustomCategoryTask,
-  deleteCustomCategoryTask,
-  getCustomCategoryTasks,
-  getCustomTrackingCategories,
-  updateCustomCategoryTask,
-  updateCustomCategoryTaskStatus,
-} from "../../../../api/discipline.js";
-
-import CustomCategoryKanbanBoard from "./components/CustomCategoryKanbanBoard";
-
-export default function CustomCategoryKanban() {
-  const params = useParams();
-  const customTrackingId = Number(params.customTrackingId);
-
-  const [loading, setLoading] = useState(true);
-  const [categoryName, setCategoryName] = useState("Custom Category");
-  const [tasks, setTasks] = useState([]);
-  const [error, setError] = useState(null);
-
-  const lanes = useMemo(() => {
-    const all = tasks ?? [];
-    return {
-      notStarted: all.filter((t) => t.status === "NOT_STARTED"),
-      inProgress: all.filter((t) => t.status === "IN_PROGRESS"),
-      finished: all.filter((t) => t.status === "FINISHED"),
-    };
-  }, [tasks]);
-
-  async function refresh() {
-    setLoading(true);
-    setError(null);
-    try {
-      const [catsRes, tasksRes] = await Promise.all([
-        getCustomTrackingCategories(),
-        getCustomCategoryTasks(customTrackingId),
-      ]);
-      const cats = catsRes?.items ?? [];
-      const found = cats.find((c) => Number(c.customTrackingId) === customTrackingId);
-      setCategoryName(found?.name ?? "Custom Category");
-      setTasks(tasksRes?.tasks ?? []);
-    } catch (e) {
-      setError(e?.response?.data?.message || e?.message || "Failed to load category");
-    } finally {
-      setLoading(false);
-    }
-  }
-
-  useEffect(() => {
-    if (!Number.isFinite(customTrackingId)) {
-      setLoading(false);
-      setError("Invalid category id");
-      return;
-    }
-    refresh();
-    // eslint-disable-next-line react-hooks/exhaustive-deps
-  }, [customTrackingId]);
-
-  async function handleAddTask(payload) {
-    const created = await createCustomCategoryTask(customTrackingId, payload);
-    setTasks((prev) => [created, ...(prev ?? [])]);
-  }
-
-  async function handleEditTask(taskId, payload) {
-    const updated = await updateCustomCategoryTask(customTrackingId, taskId, payload);
-    setTasks((prev) => (prev ?? []).map((t) => (t.taskId === taskId ? updated : t)));
-  }
-
-  async function handleDeleteTask(taskId) {
-    await deleteCustomCategoryTask(customTrackingId, taskId);
-    setTasks((prev) => (prev ?? []).filter((t) => t.taskId !== taskId));
-  }
-
-  async function handleMoveTask(taskId, toStatus) {
-    setTasks((prev) =>
-      (prev ?? []).map((t) => (t.taskId === taskId ? { ...t, status: toStatus } : t))
-    );
-    try {
-      const saved = await updateCustomCategoryTaskStatus(customTrackingId, taskId, toStatus);
-      setTasks((prev) => (prev ?? []).map((t) => (t.taskId === taskId ? saved : t)));
-    } catch {
-      await refresh();
-    }
-  }
-
-  return (
-    <div className="space-y-6">
-      <div className="flex flex-col gap-2 md:flex-row md:items-end md:justify-between">
-        <div>
-          <h1 className="text-2xl font-bold">{categoryName}</h1>
-          <p className="text-sm opacity-80">
-            Drag tickets between columns or use the edit form to update status.
-          </p>
-        </div>
-      </div>
-
-      {error ? (
-        <div className="rounded-xl border border-red-500/30 bg-red-500/10 p-4 text-red-200">
-          {error}
-        </div>
-      ) : null}
-
-      <CustomCategoryKanbanBoard
-        loading={loading}
-        notStarted={lanes.notStarted}
-        inProgress={lanes.inProgress}
-        finished={lanes.finished}
-        onAddTask={handleAddTask}
-        onEditTask={handleEditTask}
-        onDeleteTask={handleDeleteTask}
-        onMoveTask={handleMoveTask}
-      />
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/CustomCategory/components/CustomCategoryKanbanBoard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/CustomCategory/components/CustomCategoryKanbanBoard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,194 +1,0 @@
-import React, { useMemo, useState } from "react";
-import { DndContext, PointerSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
-import { SortableContext, rectSortingStrategy } from "@dnd-kit/sortable";
-import { MdAdd, MdSort } from "react-icons/md";
-
-import KanbanColumn from "./KanbanColumn";
-import TaskTicketCard from "./TaskTicketCard";
-import TaskFormModal from "./TaskFormModal";
-
-const LANES = [
-  { id: "NOT_STARTED", droppableId: "lane:NOT_STARTED", title: "Not Started" },
-  { id: "IN_PROGRESS", droppableId: "lane:IN_PROGRESS", title: "In Progress" },
-  { id: "FINISHED",    droppableId: "lane:FINISHED",    title: "Finished" },
-];
-
-const PRIORITY_ORDER = { HIGH: 0, MEDIUM: 1, LOW: 2, null: 3, undefined: 3 };
-
-function sortTasks(tasks, sortBy) {
-  if (!tasks || tasks.length === 0) return tasks;
-  const arr = [...tasks];
-  if (sortBy === "dueDate") {
-    arr.sort((a, b) => {
-      if (!a.dueDate && !b.dueDate) return 0;
-      if (!a.dueDate) return 1;
-      if (!b.dueDate) return -1;
-      return new Date(a.dueDate) - new Date(b.dueDate);
-    });
-  } else if (sortBy === "priority") {
-    arr.sort((a, b) => (PRIORITY_ORDER[a.priority] ?? 3) - (PRIORITY_ORDER[b.priority] ?? 3));
-  }
-  return arr;
-}
-
-function statusForDropId(dropId) {
-  return dropId.replace("lane:", "");
-}
-
-export default function CustomCategoryKanbanBoard({
-  loading, notStarted, inProgress, finished,
-  onAddTask, onEditTask, onDeleteTask, onMoveTask,
-}) {
-  const [modalOpen, setModalOpen] = useState(false);
-  const [editingTask, setEditingTask] = useState(null);
-  const [modalLoading, setModalLoading] = useState(false);
-  const [sortBy, setSortBy] = useState("default");
-
-  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 6 } }));
-
-  const tasksByLane = useMemo(() => ({
-    NOT_STARTED: sortTasks(notStarted ?? [], sortBy),
-    IN_PROGRESS: sortTasks(inProgress ?? [], sortBy),
-    FINISHED:    sortTasks(finished ?? [], sortBy),
-  }), [notStarted, inProgress, finished, sortBy]);
-
-  const allTasks = useMemo(() => [
-    ...(notStarted ?? []),
-    ...(inProgress ?? []),
-    ...(finished ?? []),
-  ], [notStarted, inProgress, finished]);
-
-  function findTask(id) {
-    return allTasks.find((t) => String(t.taskId) === String(id));
-  }
-
-  async function handleDragEnd({ active, over }) {
-    if (!over) return;
-    const activeId = String(active.id);
-    const overId = String(over.id);
-    if (activeId === overId) return;
-
-    const task = findTask(activeId);
-    if (!task) return;
-
-    if (overId.startsWith("lane:")) {
-      const toStatus = statusForDropId(overId);
-      if (task.status !== toStatus) await onMoveTask(task.taskId, toStatus);
-      return;
-    }
-
-    const overTask = findTask(overId);
-    if (!overTask) return;
-
-    if (task.status !== overTask.status) {
-      await onMoveTask(task.taskId, overTask.status);
-    }
-  }
-
-  async function handleModalSubmit(payload) {
-    setModalLoading(true);
-    try {
-      if (editingTask) {
-        await onEditTask(editingTask.taskId, payload);
-      } else {
-        await onAddTask(payload);
-      }
-      setModalOpen(false);
-      setEditingTask(null);
-    } finally {
-      setModalLoading(false);
-    }
-  }
-
-  const total = allTasks.length;
-
-  return (
-    <div className="space-y-4">
-      <div className="flex flex-wrap items-center justify-between gap-3 rounded-xl border border-white/10 bg-neutral-900/40 px-4 py-3">
-        <div className="flex flex-wrap items-center gap-3 text-xs text-white/70">
-          <span className="rounded-full bg-slate-500/20 px-2 py-1 text-slate-200">
-            Not started: {(notStarted ?? []).length}
-          </span>
-          <span className="rounded-full bg-amber-500/15 px-2 py-1 text-amber-200">
-            In progress: {(inProgress ?? []).length}
-          </span>
-          <span className="rounded-full bg-emerald-500/15 px-2 py-1 text-emerald-200">
-            Finished: {(finished ?? []).length}
-          </span>
-          <span className="text-white/40">/ {total} total</span>
-        </div>
-
-        <div className="flex items-center gap-2">
-          <div className="flex items-center gap-1.5 rounded-lg border border-white/10 bg-black/30 px-2 py-1.5">
-            <MdSort className="size-4 text-white/50" />
-            <span className="text-xs text-white/50">Sort:</span>
-            <select
-              value={sortBy}
-              onChange={(e) => setSortBy(e.target.value)}
-              className="bg-transparent text-xs text-white/80 outline-none cursor-pointer"
-            >
-              <option value="default">Default</option>
-              <option value="dueDate">Due date</option>
-              <option value="priority">Priority</option>
-            </select>
-          </div>
-
-          <button
-            onClick={() => { setEditingTask(null); setModalOpen(true); }}
-            className="flex items-center gap-1.5 rounded-lg bg-green-400 px-3 py-1.5 text-sm font-medium text-black hover:bg-green-300"
-          >
-            <MdAdd className="size-4" />
-            New ticket
-          </button>
-        </div>
-      </div>
-
-      <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
-        <div className="grid grid-cols-1 gap-4 md:grid-cols-3">
-          {LANES.map((lane) => {
-            const tasks = tasksByLane[lane.id] ?? [];
-            return (
-              <KanbanColumn
-                key={lane.id}
-                laneId={lane.id}
-                title={lane.title}
-                droppableId={lane.droppableId}
-                count={tasks.length}
-              >
-                <SortableContext
-                  items={tasks.map((t) => String(t.taskId))}
-                  strategy={rectSortingStrategy}
-                >
-                  <div className="space-y-3">
-                    {loading ? (
-                      <div className="text-sm opacity-70">Loading...</div>
-                    ) : tasks.length === 0 ? (
-                      <div className="text-sm opacity-40">No tickets.</div>
-                    ) : (
-                      tasks.map((t) => (
-                        <TaskTicketCard
-                          key={t.taskId}
-                          task={t}
-                          onEdit={() => { setEditingTask(t); setModalOpen(true); }}
-                          onDelete={() => onDeleteTask(t.taskId)}
-                        />
-                      ))
-                    )}
-                  </div>
-                </SortableContext>
-              </KanbanColumn>
-            );
-          })}
-        </div>
-      </DndContext>
-
-      <TaskFormModal
-        isOpen={modalOpen}
-        onClose={() => { setModalOpen(false); setEditingTask(null); }}
-        onSubmit={handleModalSubmit}
-        task={editingTask}
-        isLoading={modalLoading}
-      />
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/CustomCategory/components/KanbanColumn.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/CustomCategory/components/KanbanColumn.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,66 +1,0 @@
-import React, { useMemo } from "react";
-import { useDroppable } from "@dnd-kit/core";
-import { MdCheckCircle, MdRadioButtonUnchecked, MdAutorenew } from "react-icons/md";
-
-const VARIANTS = {
-  NOT_STARTED: {
-    Icon: MdRadioButtonUnchecked,
-    header: "from-slate-500/20 via-slate-500/8 to-transparent",
-    badge: "bg-slate-500/15 text-slate-200 border-slate-500/30",
-    ring: "group-hover:ring-slate-500/25",
-    drop: "border-slate-400/60 bg-slate-400/10",
-    border: "border-slate-500/20",
-  },
-  IN_PROGRESS: {
-    Icon: MdAutorenew,
-    header: "from-amber-500/20 via-amber-500/8 to-transparent",
-    badge: "bg-amber-500/15 text-amber-200 border-amber-500/30",
-    ring: "group-hover:ring-amber-500/25",
-    drop: "border-amber-400/60 bg-amber-400/10",
-    border: "border-amber-500/20",
-  },
-  FINISHED: {
-    Icon: MdCheckCircle,
-    header: "from-emerald-500/25 via-emerald-500/10 to-transparent",
-    badge: "bg-emerald-500/15 text-emerald-200 border-emerald-500/30",
-    ring: "group-hover:ring-emerald-500/25",
-    drop: "border-emerald-400/60 bg-emerald-400/10",
-    border: "border-emerald-500/20",
-  },
-};
-
-export default function KanbanColumn({ laneId, title, droppableId, count, children }) {
-  const { setNodeRef, isOver } = useDroppable({ id: droppableId });
-  const v = VARIANTS[laneId] ?? VARIANTS.NOT_STARTED;
-
-  return (
-    <div
-      className={
-        "group overflow-hidden rounded-xl border bg-neutral-900/40 shadow-sm ring-1 ring-white/5 transition " +
-        v.border + " " + v.ring
-      }
-    >
-      <div className={"bg-gradient-to-b " + v.header + " p-4"}>
-        <div className="flex items-center justify-between gap-3">
-          <div className="flex items-center gap-2">
-            <v.Icon className="size-5 text-white/80" />
-            <h2 className="text-sm font-semibold tracking-wide text-white/90">{title}</h2>
-          </div>
-          <span className={"rounded-full border px-2 py-0.5 text-xs font-medium " + v.badge}>
-            {count}
-          </span>
-        </div>
-      </div>
-
-      <div
-        ref={setNodeRef}
-        className={
-          "min-h-[220px] p-4 transition-colors " +
-          (isOver ? v.drop : "border-t border-white/10")
-        }
-      >
-        {children}
-      </div>
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/CustomCategory/components/TaskFormModal.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/CustomCategory/components/TaskFormModal.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,244 +1,0 @@
-import React, { useEffect, useState } from "react";
-import { MdClose } from "react-icons/md";
-
-export default function TaskFormModal({
-  isOpen,
-  onClose,
-  onSubmit,
-  task = null,
-  isLoading = false,
-}) {
-  const isEditing = !!task;
-  const [formData, setFormData] = useState({
-    name: "",
-    description: "",
-    dueDate: "",
-    priority: "MEDIUM",
-    status: "NOT_STARTED",
-  });
-  const [errors, setErrors] = useState({});
-
-  // Initialize form with task data when editing
-  useEffect(() => {
-    if (task) {
-      setFormData({
-        name: task.name || "",
-        description: task.description || "",
-        dueDate: task.dueDate || "",
-        priority: task.priority || "MEDIUM",
-        status: task.status || "NOT_STARTED",
-      });
-    } else {
-      setFormData({
-        name: "",
-        description: "",
-        dueDate: "",
-        priority: "MEDIUM",
-        status: "NOT_STARTED",
-      });
-    }
-    setErrors({});
-  }, [task, isOpen]);
-
-  const handleChange = (e) => {
-    const { name, value } = e.target;
-    setFormData((prev) => ({ ...prev, [name]: value }));
-    // Clear error for this field
-    if (errors[name]) {
-      setErrors((prev) => ({ ...prev, [name]: null }));
-    }
-  };
-
-  const validate = () => {
-    const newErrors = {};
-    if (!formData.name.trim()) {
-      newErrors.name = "Task name is required";
-    }
-    if (formData.name.length > 200) {
-      newErrors.name = "Task name must be 200 characters or less";
-    }
-    if (formData.dueDate && new Date(formData.dueDate) < new Date()) {
-      const today = new Date().toISOString().split('T')[0];
-      if (formData.dueDate < today) {
-        newErrors.dueDate = "Due date cannot be in the past";
-      }
-    }
-    return newErrors;
-  };
-
-  const handleSubmit = async (e) => {
-    e.preventDefault();
-    const newErrors = validate();
-    if (Object.keys(newErrors).length > 0) {
-      setErrors(newErrors);
-      return;
-    }
-
-    const payload = {
-      name: formData.name.trim(),
-      description: formData.description.trim() || null,
-      dueDate: formData.dueDate || null,
-      priority: formData.priority,
-    };
-
-    // Only include status if editing
-    if (isEditing) {
-      payload.status = formData.status;
-    }
-
-    try {
-      await onSubmit(payload);
-      onClose();
-    } catch (error) {
-      console.error("Form submission error:", error);
-    }
-  };
-
-  if (!isOpen) return null;
-
-  return (
-    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4">
-      <div className="w-full max-w-md rounded-lg border border-white/10 bg-neutral-900 p-6 shadow-xl">
-        {/* Header */}
-        <div className="mb-4 flex items-center justify-between">
-          <h2 className="text-lg font-bold text-white">
-            {isEditing ? "Edit Task" : "Create New Task"}
-          </h2>
-          <button
-            onClick={onClose}
-            className="rounded-md p-1 text-white/60 hover:bg-white/10 hover:text-white"
-            title="Close"
-          >
-            <MdClose className="size-5" />
-          </button>
-        </div>
-
-        {/* Form */}
-        <form onSubmit={handleSubmit} className="space-y-4">
-          {/* Name */}
-          <div>
-            <label className="block text-sm font-medium text-white/80 mb-1">
-              Task Name <span className="text-red-400">*</span>
-            </label>
-            <input
-              type="text"
-              name="name"
-              value={formData.name}
-              onChange={handleChange}
-              placeholder="Enter task name"
-              maxLength={200}
-              className={`w-full rounded-lg border bg-black/40 px-3 py-2 text-sm text-white outline-none transition ${
-                errors.name
-                  ? "border-red-500/50 focus:border-red-400"
-                  : "border-white/10 focus:border-green-400"
-              }`}
-              disabled={isLoading}
-            />
-            {errors.name && (
-              <p className="mt-1 text-xs text-red-400">{errors.name}</p>
-            )}
-            <p className="mt-1 text-xs text-white/40">
-              {formData.name.length}/200
-            </p>
-          </div>
-
-          {/* Description */}
-          <div>
-            <label className="block text-sm font-medium text-white/80 mb-1">
-              Description
-            </label>
-            <textarea
-              name="description"
-              value={formData.description}
-              onChange={handleChange}
-              placeholder="Enter task description (optional)"
-              rows={3}
-              className="w-full rounded-lg border border-white/10 bg-black/40 px-3 py-2 text-sm text-white outline-none transition focus:border-green-400"
-              disabled={isLoading}
-            />
-          </div>
-
-          {/* Priority */}
-          <div>
-            <label className="block text-sm font-medium text-white/80 mb-1">
-              Priority
-            </label>
-            <select
-              name="priority"
-              value={formData.priority}
-              onChange={handleChange}
-              className="w-full rounded-lg border border-white/10 bg-black/40 px-3 py-2 text-sm text-white outline-none transition focus:border-green-400"
-              disabled={isLoading}
-            >
-              <option value="LOW">Low</option>
-              <option value="MEDIUM">Medium</option>
-              <option value="HIGH">High</option>
-            </select>
-          </div>
-
-          {/* Due Date */}
-          <div>
-            <label className="block text-sm font-medium text-white/80 mb-1">
-              Due Date
-            </label>
-            <input
-              type="date"
-              name="dueDate"
-              value={formData.dueDate}
-              onChange={handleChange}
-              className={`w-full rounded-lg border bg-black/40 px-3 py-2 text-sm text-white outline-none transition ${
-                errors.dueDate
-                  ? "border-red-500/50 focus:border-red-400"
-                  : "border-white/10 focus:border-green-400"
-              }`}
-              disabled={isLoading}
-            />
-            {errors.dueDate && (
-              <p className="mt-1 text-xs text-red-400">{errors.dueDate}</p>
-            )}
-          </div>
-
-          {/* Status (only for editing) */}
-          {isEditing && (
-            <div>
-              <label className="block text-sm font-medium text-white/80 mb-1">
-                Status
-              </label>
-              <select
-                name="status"
-                value={formData.status}
-                onChange={handleChange}
-                className="w-full rounded-lg border border-white/10 bg-black/40 px-3 py-2 text-sm text-white outline-none transition focus:border-green-400"
-                disabled={isLoading}
-              >
-                <option value="NOT_STARTED">Not Started</option>
-                <option value="IN_PROGRESS">In Progress</option>
-                <option value="FINISHED">Finished</option>
-              </select>
-            </div>
-          )}
-
-          {/* Buttons */}
-          <div className="flex gap-3 pt-4">
-            <button
-              type="button"
-              onClick={onClose}
-              className="flex-1 rounded-lg border border-white/10 bg-transparent px-4 py-2 text-sm font-medium text-white transition hover:bg-white/5"
-              disabled={isLoading}
-            >
-              Cancel
-            </button>
-            <button
-              type="submit"
-              className="flex-1 rounded-lg bg-green-400 px-4 py-2 text-sm font-medium text-black transition hover:bg-green-300 disabled:opacity-50"
-              disabled={isLoading}
-            >
-              {isLoading ? "Saving..." : isEditing ? "Update Task" : "Create Task"}
-            </button>
-          </div>
-        </form>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/CustomCategory/components/TaskTicketCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/CustomCategory/components/TaskTicketCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,111 +1,0 @@
-import React, { useMemo } from "react";
-import { useSortable } from "@dnd-kit/sortable";
-import { CSS } from "@dnd-kit/utilities";
-import { MdDelete, MdDragIndicator, MdEdit, MdCalendarToday } from "react-icons/md";
-
-const PRIORITY_STYLES = {
-  HIGH:   "bg-red-500/15 text-red-300 border-red-500/30",
-  MEDIUM: "bg-amber-500/15 text-amber-300 border-amber-500/30",
-  LOW:    "bg-sky-500/15 text-sky-300 border-sky-500/30",
-};
-
-const STATUS_DOT = {
-  NOT_STARTED: "bg-slate-400",
-  IN_PROGRESS: "bg-amber-400",
-  FINISHED:    "bg-emerald-400",
-};
-
-function formatDate(dateStr) {
-  if (!dateStr) return null;
-  const d = new Date(dateStr);
-  return d.toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" });
-}
-
-function isOverdue(dateStr) {
-  if (!dateStr) return false;
-  return new Date(dateStr) < new Date(new Date().toDateString());
-}
-
-export default function TaskTicketCard({ task, onEdit, onDelete }) {
-  const id = String(task.taskId);
-  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id });
-
-  const style = useMemo(() => ({
-    transform: CSS.Transform.toString(transform),
-    transition,
-  }), [transform, transition]);
-
-  const overdue = task.status !== "FINISHED" && isOverdue(task.dueDate);
-
-  return (
-    <div
-      ref={setNodeRef}
-      style={style}
-      className={
-        "group rounded-lg border border-white/10 bg-black/30 p-3 shadow-sm transition hover:border-white/20 hover:bg-black/35 " +
-        (task.status === "FINISHED" ? "opacity-80" : "") +
-        (isDragging ? " opacity-50 scale-95" : "")
-      }
-    >
-      {/* Header row */}
-      <div className="flex items-start justify-between gap-2">
-        <div className="min-w-0 flex-1">
-          <div className="flex items-center gap-2">
-            <span className={"h-2 w-2 shrink-0 rounded-full " + (STATUS_DOT[task.status] ?? "bg-slate-400")} />
-            <span className="text-sm font-medium text-white/90 leading-snug">{task.name}</span>
-          </div>
-
-          {task.description ? (
-            <p className="mt-1.5 text-xs text-white/50 line-clamp-2">{task.description}</p>
-          ) : null}
-        </div>
-
-        <div className="flex shrink-0 items-center gap-1">
-          <button
-            type="button"
-            onClick={onEdit}
-            className="rounded-md p-1 text-white/50 hover:bg-white/10 hover:text-white"
-            title="Edit"
-          >
-            <MdEdit className="size-4" />
-          </button>
-          <button
-            type="button"
-            onClick={onDelete}
-            className="rounded-md p-1 text-white/50 hover:bg-white/10 hover:text-white"
-            title="Delete"
-          >
-            <MdDelete className="size-4" />
-          </button>
-          <button
-            type="button"
-            className="cursor-grab rounded-md p-1 text-white/50 hover:bg-white/10 hover:text-white active:cursor-grabbing"
-            title="Drag"
-            {...attributes}
-            {...listeners}
-          >
-            <MdDragIndicator className="size-4" />
-          </button>
-        </div>
-      </div>
-
-      {/* Footer row: priority + due date */}
-      <div className="mt-2 flex flex-wrap items-center gap-2">
-        <span className="text-xs text-white/30">#{task.taskId}</span>
-
-        {task.priority ? (
-          <span className={"rounded-full border px-2 py-0.5 text-xs font-medium " + (PRIORITY_STYLES[task.priority] ?? PRIORITY_STYLES.LOW)}>
-            {task.priority.charAt(0) + task.priority.slice(1).toLowerCase()}
-          </span>
-        ) : null}
-
-        {task.dueDate ? (
-          <span className={"flex items-center gap-1 text-xs " + (overdue ? "text-red-400" : "text-white/40")}>
-            <MdCalendarToday className="size-3" />
-            {overdue ? "Overdue · " : ""}{formatDate(task.dueDate)}
-          </span>
-        ) : null}
-      </div>
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/Discipline/Discipline.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Discipline/Discipline.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,85 +1,0 @@
-import React, { useEffect, useState } from "react";
-import { useNavigate } from "react-router-dom";
-
-import {
-  getDisciplineStatus,
-  startDisciplineTracking,
-} from "../../../../api/discipline";
-
-import DisciplineCenteredCard from "./components/DisciplineCenteredCard.jsx";
-import DisciplineStartCtaCard from "./components/DisciplineStartCtaCard.jsx";
-
-export default function Discipline() {
-  const navigate = useNavigate();
-
-  const [isLoading, setIsLoading] = useState(true);
-  const [isTracking, setIsTracking] = useState(false);
-  const [error, setError] = useState("");
-  const [isSubmitting, setIsSubmitting] = useState(false);
-
-  useEffect(() => {
-    let isMounted = true;
-    const run = async () => {
-      setIsLoading(true);
-      setError("");
-      try {
-        const tracking = await getDisciplineStatus();
-        if (!isMounted) return;
-        setIsTracking(tracking);
-        if (tracking) {
-          navigate("/dashboard/discipline/tracking", { replace: true });
-        }
-      } catch (err) {
-        if (!isMounted) return;
-        const message =
-          err?.response?.data?.message || "Failed to load discipline status";
-        setError(message);
-      } finally {
-        if (isMounted) setIsLoading(false);
-      }
-    };
-
-    run();
-    return () => {
-      isMounted = false;
-    };
-  }, [navigate]);
-
-  const onStart = async () => {
-    setError("");
-    setIsSubmitting(true);
-    try {
-      await startDisciplineTracking();
-      setIsTracking(true);
-      navigate("/dashboard/discipline/tracking", { replace: true });
-    } catch (err) {
-      const message =
-        err?.response?.data?.message ||
-        Object.values(err?.response?.data?.errors ?? {})[0] ||
-        "Failed to start tracking";
-      setError(message);
-    } finally {
-      setIsSubmitting(false);
-    }
-  };
-
-  if (isLoading) {
-    return <DisciplineCenteredCard title="Discipline" message="Loading…" />;
-  }
-
-  if (isTracking) {
-    return <DisciplineCenteredCard title="Discipline" message="Redirecting…" />;
-  }
-
-  return (
-    <div className="min-h-[70vh] w-full flex items-center justify-center">
-      <div className="w-full max-w-3xl">
-        <DisciplineStartCtaCard
-          error={error}
-          onStart={onStart}
-          isSubmitting={isSubmitting}
-        />
-      </div>
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/Discipline/DisciplineTracking.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Discipline/DisciplineTracking.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,420 +1,0 @@
-import React, { useCallback, useEffect, useMemo, useState } from "react";
-
-import {
-  createTask,
-  deleteTask,
-  getTasks,
-  updateTask,
-  updateTaskFinished,
-} from "../../../../api/discipline";
-
-import {
-  computeDailyCompletion,
-  getDailyCompletions,
-} from "../../../../api/dailyCompletion";
-
-import TaskList from "./components/TaskList.jsx";
-import DisciplineProgressCard from "./components/DisciplineProgressCard.jsx";
-
-export default function DisciplineTracking() {
-  const pageSize = 50;
-  const completionPageSize = 14;
-  const graphCompletionPageSize = 500;
-
-  const todayIso = useMemo(() => {
-    const d = new Date();
-    return d.toISOString().slice(0, 10);
-  }, []);
-
-  const [tasks, setTasks] = useState([]);
-  const [page, setPage] = useState(0);
-  const [hasMore, setHasMore] = useState(false);
-  const [isLoading, setIsLoading] = useState(true);
-  const [isLoadingMore, setIsLoadingMore] = useState(false);
-  const [error, setError] = useState("");
-  const [completionInfo, setCompletionInfo] = useState(null);
-  const [isComputing, setIsComputing] = useState(false);
-  const [workingTaskIds, setWorkingTaskIds] = useState([]);
-
-  const [dailyCompletions, setDailyCompletions] = useState([]);
-  const [completionPage, setCompletionPage] = useState(0);
-  const [completionHasMore, setCompletionHasMore] = useState(false);
-  const [isLoadingCompletions, setIsLoadingCompletions] = useState(true);
-  const [isLoadingMoreCompletions, setIsLoadingMoreCompletions] = useState(false);
-  const [completionError, setCompletionError] = useState("");
-
-  const workingSet = useMemo(
-    () => new Set(workingTaskIds),
-    [workingTaskIds],
-  );
-
-  const fetchPage = useCallback(async (nextPage) => {
-    const data = await getTasks({ page: nextPage, size: pageSize });
-    return {
-      nextTasks: Array.isArray(data?.tasks) ? data.tasks : [],
-      nextHasMore: Boolean(data?.hasMore),
-    };
-  }, []);
-
-  const fetchCompletionsPage = useCallback(async (nextPage) => {
-    const data = await getDailyCompletions({
-      page: nextPage,
-      size: completionPageSize,
-    });
-    return {
-      nextCompletions: Array.isArray(data?.completions) ? data.completions : [],
-      nextHasMore: Boolean(data?.hasMore),
-    };
-  }, []);
-
-  const [graphCompletions, setGraphCompletions] = useState([]);
-
-  const fetchAllCompletionsForGraph = useCallback(async () => {
-    let p = 0;
-    let hasMorePages = true;
-    const all = [];
-
-    while (hasMorePages) {
-      const data = await getDailyCompletions({ page: p, size: graphCompletionPageSize });
-      const chunk = Array.isArray(data?.completions) ? data.completions : [];
-      all.push(...chunk);
-      hasMorePages = Boolean(data?.hasMore) && chunk.length > 0;
-      p += 1;
-      if (p > 400) break;
-    }
-
-    return all;
-  }, []);
-
-  useEffect(() => {
-    let cancelled = false;
-    (async () => {
-      try {
-        setIsLoading(true);
-        setError("");
-        const { nextTasks, nextHasMore } = await fetchPage(0);
-        if (cancelled) return;
-        setTasks(nextTasks);
-        setHasMore(nextHasMore);
-        setPage(0);
-      } catch (e) {
-        if (cancelled) return;
-        setError(e?.response?.data?.message || "Failed to load tasks.");
-      } finally {
-        if (!cancelled) setIsLoading(false);
-      }
-    })();
-    return () => {
-      cancelled = true;
-    };
-  }, [fetchPage]);
-
-  useEffect(() => {
-    let cancelled = false;
-    (async () => {
-      try {
-        setIsLoadingCompletions(true);
-        setCompletionError("");
-        const [{ nextCompletions, nextHasMore }, allForGraph] = await Promise.all([
-          fetchCompletionsPage(0),
-          fetchAllCompletionsForGraph(),
-        ]);
-        if (cancelled) return;
-        setDailyCompletions(nextCompletions);
-        setGraphCompletions(allForGraph);
-        setCompletionHasMore(nextHasMore);
-        setCompletionPage(0);
-      } catch (e) {
-        if (cancelled) return;
-        setCompletionError(
-          e?.response?.data?.message ||
-            "Failed to load daily completion history.",
-        );
-      } finally {
-        if (!cancelled) setIsLoadingCompletions(false);
-      }
-    })();
-
-    return () => {
-      cancelled = true;
-    };
-  }, [fetchAllCompletionsForGraph, fetchCompletionsPage]);
-
-  const onLoadMoreCompletions = async () => {
-    if (isLoadingMoreCompletions || !completionHasMore) return;
-    const nextPage = completionPage + 1;
-    try {
-      setIsLoadingMoreCompletions(true);
-      setCompletionError("");
-      const { nextCompletions, nextHasMore } =
-        await fetchCompletionsPage(nextPage);
-      setDailyCompletions((prev) => [...prev, ...nextCompletions]);
-      setCompletionHasMore(nextHasMore);
-      setCompletionPage(nextPage);
-    } catch (e) {
-      setCompletionError(
-        e?.response?.data?.message || "Failed to load more completions.",
-      );
-    } finally {
-      setIsLoadingMoreCompletions(false);
-    }
-  };
-
-  const onLoadMore = async () => {
-    if (isLoadingMore || !hasMore) return;
-    const nextPage = page + 1;
-    try {
-      setIsLoadingMore(true);
-      setError("");
-      const { nextTasks, nextHasMore } = await fetchPage(nextPage);
-      setTasks((prev) => [...prev, ...nextTasks]);
-      setHasMore(nextHasMore);
-      setPage(nextPage);
-    } catch (e) {
-      setError(e?.response?.data?.message || "Failed to load more tasks.");
-    } finally {
-      setIsLoadingMore(false);
-    }
-  };
-
-  const withWorking = async (taskId, fn) => {
-    setWorkingTaskIds((prev) => [...prev, taskId]);
-    try {
-      await fn();
-    } finally {
-      setWorkingTaskIds((prev) => prev.filter((id) => id !== taskId));
-    }
-  };
-
-  const onAdd = async (name) => {
-    setError("");
-    try {
-      const created = await createTask({ name });
-      setTasks((prev) => [created, ...prev]);
-    } catch (e) {
-      setError(e?.response?.data?.message || "Failed to create task.");
-    }
-  };
-
-  const onDelete = async (taskId) => {
-    setError("");
-    await withWorking(taskId, async () => {
-      try {
-        await deleteTask(taskId);
-        setTasks((prev) => prev.filter((t) => t.taskId !== taskId));
-      } catch (e) {
-        setError(e?.response?.data?.message || "Failed to delete task.");
-      }
-    });
-  };
-
-  const onToggleFinished = async (taskId, isFinished) => {
-    if (workingSet.has(taskId)) return;
-    setError("");
-
-    // optimistic update
-    setTasks((prev) =>
-      prev.map((t) => (t.taskId === taskId ? { ...t, isFinished } : t)),
-    );
-
-    await withWorking(taskId, async () => {
-      try {
-        const updated = await updateTaskFinished(taskId, isFinished);
-        setTasks((prev) =>
-          prev.map((t) => (t.taskId === taskId ? updated : t)),
-        );
-      } catch (e) {
-        // revert
-        setTasks((prev) =>
-          prev.map((t) =>
-            t.taskId === taskId ? { ...t, isFinished: !isFinished } : t,
-          ),
-        );
-        setError(e?.response?.data?.message || "Failed to update task.");
-      }
-    });
-  };
-
-  const onRename = async (taskId, name) => {
-    setError("");
-    await withWorking(taskId, async () => {
-      try {
-        const updated = await updateTask(taskId, { name });
-        setTasks((prev) =>
-          prev.map((t) => (t.taskId === taskId ? updated : t)),
-        );
-      } catch (e) {
-        setError(e?.response?.data?.message || "Failed to update task.");
-      }
-    });
-  };
-
-  const onComputeToday = async () => {
-    setError("");
-    setCompletionInfo(null);
-    setIsComputing(true);
-    try {
-      const result = await computeDailyCompletion();
-      setCompletionInfo(result?.completion ?? null);
-
-      // refresh daily completion history
-      try {
-        const { nextCompletions, nextHasMore } = await fetchCompletionsPage(0);
-        setDailyCompletions(nextCompletions);
-        setCompletionHasMore(nextHasMore);
-        setCompletionPage(0);
-
-        // also refresh graph dataset
-        try {
-          const allForGraph = await getDailyCompletions({ page: 0, size: 1000 });
-          setGraphCompletions(
-            Array.isArray(allForGraph?.completions) ? allForGraph.completions : [],
-          );
-        } catch {
-          // ignore
-        }
-      } catch {
-        // ignore
-      }
-
-      // refresh tasks as backend will reset finished -> false
-      const { nextTasks, nextHasMore } = await fetchPage(0);
-      setTasks(nextTasks);
-      setHasMore(nextHasMore);
-      setPage(0);
-    } catch (e) {
-      setError(
-        e?.response?.data?.message || "Failed to compute daily completion.",
-      );
-    } finally {
-      setIsComputing(false);
-    }
-  };
-
-  const isTodayClosed = useMemo(() => {
-    console.log('todayIso:', todayIso);
-    return (dailyCompletions ?? []).some((dc) => dc?.date === todayIso);
-  }, [dailyCompletions, todayIso]);
-
-  return (
-    <div className="space-y-6">
-      <div className="flex items-center justify-between gap-3">
-        <h1 className="text-2xl font-bold">Discipline</h1>
-        <button
-          className="btn btn-primary btn-sm"
-          onClick={onComputeToday}
-          disabled={isComputing || isTodayClosed}
-          title="Compute today's completion and reset tasks for the next day"
-        >
-          {isTodayClosed ? "Day closed" : isComputing ? "Computing…" : "Close day"}
-        </button>
-      </div>
-
-      {completionInfo ? (
-        <div className="card bg-base-200 border border-base-300">
-          <div className="card-body">
-            <h2 className="card-title">Daily completion saved</h2>
-            <p className="text-sm opacity-80">
-              Date: {completionInfo.date} — Completion: {completionInfo.procent}%
-            </p>
-          </div>
-        </div>
-      ) : null}
-
-      {isLoading ? (
-        <div className="card bg-base-200 border border-base-300">
-          <div className="card-body">
-            <p className="opacity-80">Loading tasks…</p>
-          </div>
-        </div>
-      ) : (
-        <>
-          <TaskList
-            tasks={tasks}
-            onAdd={onAdd}
-            onDelete={onDelete}
-            onToggleFinished={onToggleFinished}
-            onRename={onRename}
-            isWorkingTaskIds={workingTaskIds}
-          />
-
-          {error ? <p className="text-error text-sm">{error}</p> : null}
-
-          {hasMore ? (
-            <button
-              className="btn btn-outline btn-sm"
-              disabled={isLoadingMore}
-              onClick={onLoadMore}
-            >
-              {isLoadingMore ? "Loading…" : "Load more"}
-            </button>
-          ) : null}
-
-          <DisciplineProgressCard completions={graphCompletions} />
-
-          <div className="card bg-base-200 border border-base-300">
-            <div className="card-body">
-              <h2 className="card-title">Daily completion</h2>
-              <p className="text-sm opacity-80">
-                Previous days completion percentages.
-              </p>
-
-              {completionError ? (
-                <p className="text-error text-sm mt-2">{completionError}</p>
-              ) : null}
-
-              <div className="mt-4 overflow-x-auto">
-                <table className="table table-zebra">
-                  <thead>
-                    <tr>
-                      <th>Date</th>
-                      <th className="text-right">Completion</th>
-                    </tr>
-                  </thead>
-                  <tbody>
-                    {isLoadingCompletions ? (
-                      <tr>
-                        <td colSpan={2} className="opacity-70">
-                          Loading…
-                        </td>
-                      </tr>
-                    ) : (dailyCompletions ?? []).length === 0 ? (
-                      <tr>
-                        <td colSpan={2} className="opacity-70">
-                          No daily completion records yet. Click “Close day” to
-                          save today.
-                        </td>
-                      </tr>
-                    ) : (
-                      (dailyCompletions ?? []).map((dc) => (
-                        <tr key={dc.dailyCompletionId}>
-                          <td>{dc.date ?? "—"}</td>
-                          <td className="text-right tabular-nums">
-                            {dc.procent ?? 0}%
-                          </td>
-                        </tr>
-                      ))
-                    )}
-                  </tbody>
-                </table>
-              </div>
-
-              <div className="mt-4">
-                {completionHasMore ? (
-                  <button
-                    className="btn btn-outline btn-sm"
-                    disabled={isLoadingMoreCompletions}
-                    onClick={onLoadMoreCompletions}
-                  >
-                    {isLoadingMoreCompletions ? "Loading…" : "Load more"}
-                  </button>
-                ) : null}
-              </div>
-            </div>
-          </div>
-        </>
-      )}
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Discipline/components/DisciplineCenteredCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Discipline/components/DisciplineCenteredCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,17 +1,0 @@
-import React from "react";
-
-export default function DisciplineCenteredCard({ title, message }) {
-  return (
-    <div className="min-h-[70vh] w-full flex items-center justify-center">
-      <div className="w-full max-w-3xl">
-        <div className="card bg-base-200 border border-base-300">
-          <div className="card-body">
-            <h1 className="card-title text-2xl">{title}</h1>
-            <p className="opacity-80">{message}</p>
-          </div>
-        </div>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Discipline/components/DisciplineProgressCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Discipline/components/DisciplineProgressCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,78 +1,0 @@
-import React, { useMemo, useState } from "react";
-
-import TimeRangeToggle from "../../../../../components/graphs/TimeRangeToggle.jsx";
-import PercentChangeAreaChart from "../../../../../components/graphs/PercentChangeAreaChart.jsx";
-import { percentChangeSeries, sumByTimeBucket } from "../../../../../utils/timeSeries.js";
-
-export default function DisciplineProgressCard({ completions }) {
-  const [range, setRange] = useState("weekly");
-
-  const points = useMemo(() => {
-    // Bucket daily completion percentages by time range.
-    // For weekly/monthly/yearly we compute the *average* completion % in that period.
-    const sums = sumByTimeBucket(
-      completions,
-      range,
-      (c) => c.date,
-      (c) => Number(c?.procent) || 0,
-    );
-
-    const counts = sumByTimeBucket(
-      completions,
-      range,
-      (c) => c.date,
-      () => 1,
-    );
-
-    const countByTs = new Map(counts.map((p) => [p.ts, p.value]));
-
-    const avgPoints = sums.map((p) => {
-      const count = Number(countByTs.get(p.ts) ?? 0);
-      const avg = count > 0 ? Number(p.value ?? 0) / count : 0;
-      return { ts: p.ts, value: avg };
-    });
-
-    return percentChangeSeries(avgPoints);
-  }, [completions, range]);
-
-  const latest = points?.length ? points[points.length - 1] : null;
-  const latestPct = latest ? Number(latest.value ?? 0) : 0;
-  const latestBase = latest ? Number(latest.base ?? 0) : 0;
-
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <div className="flex items-center justify-between gap-4">
-          <h2 className="card-title">Progress</h2>
-          <div className="flex items-center gap-3">
-            <span className="badge badge-ghost">
-              {latestPct >= 0 ? "+" : ""}
-              {latestPct.toFixed(1)}% (last)
-            </span>
-            <TimeRangeToggle value={range} onChange={setRange} />
-          </div>
-        </div>
-
-        <div className="mt-4 w-full overflow-hidden rounded-xl border border-base-300 bg-base-100 p-2">
-          {points.length < 2 ? (
-            <div className="flex h-65 items-center justify-center text-sm opacity-70">
-              Add at least 2 daily completion records to see % change.
-            </div>
-          ) : (
-            <PercentChangeAreaChart
-              points={points}
-              granularity={range}
-              height={260}
-              positiveColor="#fbbf24"
-            />
-          )}
-        </div>
-
-        <div className="mt-2 text-xs opacity-70">
-          Showing percentage change in average completion % per {range} bucket. Latest bucket avg: {Math.round(latestBase)}%.
-        </div>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Discipline/components/DisciplineStartCtaCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Discipline/components/DisciplineStartCtaCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,26 +1,0 @@
-import React from "react";
-
-export default function DisciplineStartCtaCard({ error, onStart, isSubmitting }) {
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <h1 className="card-title text-2xl">Discipline</h1>
-        <p className="opacity-80">
-          Start tracking your daily discipline tasks. You can add, edit, and mark
-          tasks as completed.
-        </p>
-        {error ? <p className="text-error text-sm mt-2">{error}</p> : null}
-        <div className="mt-4">
-          <button
-            className="btn btn-primary"
-            disabled={isSubmitting}
-            onClick={onStart}
-          >
-            {isSubmitting ? "Starting…" : "Start tracking"}
-          </button>
-        </div>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Discipline/components/TaskList.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Discipline/components/TaskList.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,171 +1,0 @@
-import React, { useMemo, useState } from "react";
-
-function normalizeName(value) {
-  return String(value ?? "").trim();
-}
-
-export default function TaskList({
-  tasks,
-  onAdd,
-  onDelete,
-  onToggleFinished,
-  onRename,
-  isWorkingTaskIds,
-}) {
-  const [newTaskName, setNewTaskName] = useState("");
-  const [editTaskId, setEditTaskId] = useState(null);
-  const [editName, setEditName] = useState("");
-
-  const workingSet = useMemo(
-    () => new Set(isWorkingTaskIds ?? []),
-    [isWorkingTaskIds],
-  );
-
-  const beginEdit = (t) => {
-    setEditTaskId(t.taskId);
-    setEditName(t.name ?? "");
-  };
-
-  const cancelEdit = () => {
-    setEditTaskId(null);
-    setEditName("");
-  };
-
-  const submitRename = async () => {
-    const name = normalizeName(editName);
-    if (!name) return;
-    await onRename(editTaskId, name);
-    cancelEdit();
-  };
-
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <div className="flex items-center justify-between gap-3 flex-wrap">
-          <div>
-            <h2 className="card-title">Daily tasks</h2>
-            <p className="text-sm opacity-80">
-              Check a task to mark it finished. Changes are saved immediately.
-            </p>
-          </div>
-        </div>
-
-        <form
-          className="mt-4 flex gap-2"
-          onSubmit={(e) => {
-            e.preventDefault();
-            const name = normalizeName(newTaskName);
-            if (!name) return;
-            onAdd(name);
-            setNewTaskName("");
-          }}
-        >
-          <input
-            className="input input-bordered w-full"
-            placeholder="New task name…"
-            value={newTaskName}
-            onChange={(e) => setNewTaskName(e.target.value)}
-            maxLength={200}
-          />
-          <button className="btn btn-primary" type="submit">
-            Add
-          </button>
-        </form>
-
-        <div className="mt-4 space-y-2">
-          {(tasks ?? []).length === 0 ? (
-            <p className="opacity-70">No tasks yet.</p>
-          ) : (
-            (tasks ?? []).map((t) => {
-              const isWorking = workingSet.has(t.taskId);
-              const isEditing = editTaskId === t.taskId;
-
-              return (
-                <div
-                  key={t.taskId}
-                  className="flex items-center justify-between gap-3 rounded-lg border border-base-300 bg-base-100 px-3 py-2"
-                >
-                  <div className="flex items-center gap-3 w-full">
-                    <input
-                      type="checkbox"
-                      className="checkbox checkbox-success"
-                      checked={Boolean(t.isFinished)}
-                      disabled={isWorking}
-                      onChange={(e) =>
-                        onToggleFinished(t.taskId, e.target.checked)
-                      }
-                    />
-
-                    {isEditing ? (
-                      <input
-                        className="input input-bordered input-sm w-full"
-                        value={editName}
-                        onChange={(e) => setEditName(e.target.value)}
-                        maxLength={200}
-                      />
-                    ) : (
-                      <div className="w-full">
-                        <div
-                          className={
-                            t.isFinished
-                              ? "line-through opacity-70"
-                              : "font-medium"
-                          }
-                        >
-                          {t.name}
-                        </div>
-                      </div>
-                    )}
-                  </div>
-
-                  <div className="flex items-center gap-2">
-                    {isEditing ? (
-                      <>
-                        <button
-                          className="btn btn-primary btn-xs"
-                          type="button"
-                          disabled={isWorking}
-                          onClick={submitRename}
-                        >
-                          Save
-                        </button>
-                        <button
-                          className="btn btn-ghost btn-xs"
-                          type="button"
-                          disabled={isWorking}
-                          onClick={cancelEdit}
-                        >
-                          Cancel
-                        </button>
-                      </>
-                    ) : (
-                      <>
-                        <button
-                          className="btn btn-outline btn-xs"
-                          type="button"
-                          disabled={isWorking}
-                          onClick={() => beginEdit(t)}
-                        >
-                          Edit
-                        </button>
-                        <button
-                          className="btn btn-error btn-xs"
-                          type="button"
-                          disabled={isWorking}
-                          onClick={() => onDelete(t.taskId)}
-                        >
-                          Delete
-                        </button>
-                      </>
-                    )}
-                  </div>
-                </div>
-              );
-            })
-          )}
-        </div>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Finance/Finance.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Finance/Finance.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,125 +1,0 @@
-import React, { useEffect, useMemo, useState } from "react";
-import { useNavigate } from "react-router-dom";
-
-import { getFinanceStatus, startFinanceTracking } from "../../../../api/finance";
-
-import FinanceCenteredCard from "./components/FinanceCenteredCard.jsx";
-import FinanceStartCtaCard from "./components/FinanceStartCtaCard.jsx";
-import FinanceStartForm from "./components/FinanceStartForm.jsx";
-
-export default function Finance() {
-  const navigate = useNavigate();
-
-  const [isLoading, setIsLoading] = useState(true);
-  const [isTracking, setIsTracking] = useState(false);
-  const [step, setStep] = useState("cta"); // cta | form
-  const [error, setError] = useState("");
-  const [isSubmitting, setIsSubmitting] = useState(false);
-
-  const initialForm = useMemo(
-    () => ({
-      spendingBudget: "50",
-      savingBudget: "20",
-      investingBudget: "20",
-      donationBudget: "5",
-      credit: "5",
-    }),
-    [],
-  );
-
-  const [form, setForm] = useState(initialForm);
-
-  useEffect(() => {
-    let isMounted = true;
-    const run = async () => {
-      setIsLoading(true);
-      setError("");
-      try {
-        const tracking = await getFinanceStatus();
-        if (!isMounted) return;
-        setIsTracking(tracking);
-        if (tracking) {
-          navigate("/dashboard/finance/tracking", { replace: true });
-        }
-      } catch (err) {
-        if (!isMounted) return;
-        const message =
-          err?.response?.data?.message || "Failed to load finance status";
-        setError(message);
-      } finally {
-        if (isMounted) setIsLoading(false);
-      }
-    };
-    run();
-    return () => {
-      isMounted = false;
-    };
-  }, [navigate]);
-
-  const onStart = () => {
-    setError("");
-    setStep("form");
-  };
-
-  const onCancel = () => {
-    setStep("cta");
-    setForm(initialForm);
-    setError("");
-  };
-
-  const onSubmit = async (e) => {
-    e.preventDefault();
-    setError("");
-    setIsSubmitting(true);
-    try {
-      await startFinanceTracking({
-        spendingBudget:
-          form.spendingBudget === "" ? null : Number(form.spendingBudget),
-        savingBudget: form.savingBudget === "" ? null : Number(form.savingBudget),
-        investingBudget:
-          form.investingBudget === "" ? null : Number(form.investingBudget),
-        donationBudget:
-          form.donationBudget === "" ? null : Number(form.donationBudget),
-        credit: form.credit === "" ? null : Number(form.credit),
-      });
-
-      setIsTracking(true);
-      navigate("/dashboard/finance/tracking", { replace: true });
-    } catch (err) {
-      const message =
-        err?.response?.data?.message ||
-        Object.values(err?.response?.data?.errors ?? {})[0] ||
-        "Failed to start tracking";
-      setError(message);
-    } finally {
-      setIsSubmitting(false);
-    }
-  };
-
-  if (isLoading) {
-    return <FinanceCenteredCard title="Finance" message="Loading…" />;
-  }
-
-  if (isTracking) {
-    return <FinanceCenteredCard title="Finance" message="Redirecting…" />;
-  }
-
-  return (
-    <div className="min-h-[70vh] w-full flex items-center justify-center">
-      <div className="w-full max-w-3xl">
-        {step === "cta" ? (
-          <FinanceStartCtaCard error={error} onStart={onStart} />
-        ) : (
-          <FinanceStartForm
-            form={form}
-            setForm={setForm}
-            onSubmit={onSubmit}
-            onCancel={onCancel}
-            error={error}
-            isSubmitting={isSubmitting}
-          />
-        )}
-      </div>
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/Finance/FinanceTracking.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Finance/FinanceTracking.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,246 +1,0 @@
-import React, { useCallback, useEffect, useMemo, useState } from "react";
-import { useNavigate } from "react-router-dom";
-
-import {
-  getFinanceProfile,
-  getIncomes,
-  startFinanceTracking,
-} from "../../../../api/finance";
-
-import FinanceSummaryCard from "./components/FinanceSummaryCard.jsx";
-import FinanceIncomesTable from "./components/FinanceIncomesTable.jsx";
-import FinanceStartForm from "./components/FinanceStartForm.jsx";
-import FinanceProgressCard from "./components/FinanceProgressCard.jsx";
-
-function toNumber(value) {
-  const n = Number(value);
-  return Number.isFinite(n) ? n : 0;
-}
-
-export default function FinanceTracking() {
-  const navigate = useNavigate();
-  const pageSize = 5;
-  const graphPageSize = 500;
-
-  const [profile, setProfile] = useState(null);
-  const [incomes, setIncomes] = useState([]);
-  const [page, setPage] = useState(0);
-  const [hasMore, setHasMore] = useState(false);
-
-  const [isLoading, setIsLoading] = useState(true);
-  const [isLoadingMore, setIsLoadingMore] = useState(false);
-  const [error, setError] = useState("");
-
-  const [isEditing, setIsEditing] = useState(false);
-  const [editError, setEditError] = useState("");
-  const [isSavingProfile, setIsSavingProfile] = useState(false);
-  const [editForm, setEditForm] = useState({
-    spendingBudget: "",
-    savingBudget: "",
-    investingBudget: "",
-    donationBudget: "",
-    credit: "",
-  });
-
-  const segments = useMemo(() => {
-    const p = profile ?? {};
-    return [
-      { key: "spending", label: "Spending", value: toNumber(p.spendingBudget), color: "#22c55e" },
-      { key: "saving", label: "Saving", value: toNumber(p.savingBudget), color: "#3b82f6" },
-      { key: "investing", label: "Investing", value: toNumber(p.investingBudget), color: "#a855f7" },
-      { key: "donation", label: "Donation", value: toNumber(p.donationBudget), color: "#f97316" },
-      { key: "credit", label: "Credit", value: toNumber(p.credit), color: "#ef4444" },
-    ];
-  }, [profile]);
-
-  const totalThisMonth = useMemo(() => {
-    const now = new Date();
-    const y = now.getFullYear();
-    const m = now.getMonth();
-
-    return (incomes ?? []).reduce((acc, i) => {
-      const d = new Date(i?.date);
-      if (Number.isNaN(d.getTime())) return acc;
-      if (d.getFullYear() !== y || d.getMonth() !== m) return acc;
-      const amount = Number(i?.amount);
-      if (!Number.isFinite(amount)) return acc;
-      return acc + amount;
-    }, 0);
-  }, [incomes]);
-
-  const fetchPage = useCallback(async (nextPage) => {
-    const data = await getIncomes({ page: nextPage, size: pageSize });
-    return {
-      nextIncomes: Array.isArray(data?.incomes) ? data.incomes : [],
-      nextHasMore: Boolean(data?.hasMore),
-    };
-  }, []);
-
-  const [graphIncomes, setGraphIncomes] = useState([]);
-
-  const fetchAllIncomesForGraph = useCallback(async () => {
-    let p = 0;
-    let hasMorePages = true;
-    const all = [];
-
-    while (hasMorePages) {
-      const data = await getIncomes({ page: p, size: graphPageSize });
-      const chunk = Array.isArray(data?.incomes) ? data.incomes : [];
-      all.push(...chunk);
-      hasMorePages = Boolean(data?.hasMore) && chunk.length > 0;
-      p += 1;
-      if (p > 200) break;
-    }
-
-    return all;
-  }, []);
-
-  useEffect(() => {
-    let cancelled = false;
-    (async () => {
-      try {
-        setIsLoading(true);
-        setError("");
-
-        const [p, inc, allInc] = await Promise.all([
-          getFinanceProfile(),
-          fetchPage(0),
-          fetchAllIncomesForGraph(),
-        ]);
-        if (cancelled) return;
-        setProfile(p);
-        setEditForm({
-          spendingBudget: p?.spendingBudget ?? "",
-          savingBudget: p?.savingBudget ?? "",
-          investingBudget: p?.investingBudget ?? "",
-          donationBudget: p?.donationBudget ?? "",
-          credit: p?.credit ?? "",
-        });
-        setIncomes(inc.nextIncomes);
-        setGraphIncomes(allInc);
-        setHasMore(inc.nextHasMore);
-        setPage(0);
-      } catch (e) {
-        if (cancelled) return;
-        setError(e?.response?.data?.message || "Failed to load finance dashboard.");
-      } finally {
-        if (!cancelled) setIsLoading(false);
-      }
-    })();
-
-    return () => {
-      cancelled = true;
-    };
-  }, [fetchAllIncomesForGraph, fetchPage]);
-
-  const onEdit = () => {
-    setEditError("");
-    setIsEditing(true);
-  };
-
-  const onCancelEdit = () => {
-    setEditError("");
-    const p = profile ?? {};
-    setEditForm({
-      spendingBudget: p?.spendingBudget ?? "",
-      savingBudget: p?.savingBudget ?? "",
-      investingBudget: p?.investingBudget ?? "",
-      donationBudget: p?.donationBudget ?? "",
-      credit: p?.credit ?? "",
-    });
-    setIsEditing(false);
-  };
-
-  const onSaveProfile = async (e) => {
-    e.preventDefault();
-    setEditError("");
-    setIsSavingProfile(true);
-    try {
-      await startFinanceTracking({
-        spendingBudget:
-          editForm.spendingBudget === "" ? null : Number(editForm.spendingBudget),
-        savingBudget:
-          editForm.savingBudget === "" ? null : Number(editForm.savingBudget),
-        investingBudget:
-          editForm.investingBudget === "" ? null : Number(editForm.investingBudget),
-        donationBudget:
-          editForm.donationBudget === "" ? null : Number(editForm.donationBudget),
-        credit: editForm.credit === "" ? null : Number(editForm.credit),
-      });
-
-      const refreshed = await getFinanceProfile();
-      setProfile(refreshed);
-      setEditForm({
-        spendingBudget: refreshed?.spendingBudget ?? "",
-        savingBudget: refreshed?.savingBudget ?? "",
-        investingBudget: refreshed?.investingBudget ?? "",
-        donationBudget: refreshed?.donationBudget ?? "",
-        credit: refreshed?.credit ?? "",
-      });
-      setIsEditing(false);
-    } catch (err) {
-      const message =
-        err?.response?.data?.message ||
-        Object.values(err?.response?.data?.errors ?? {})[0] ||
-        "Failed to update finance profile";
-      setEditError(message);
-    } finally {
-      setIsSavingProfile(false);
-    }
-  };
-
-  const onLoadMore = async () => {
-    if (isLoadingMore || !hasMore) return;
-    const nextPage = page + 1;
-    try {
-      setIsLoadingMore(true);
-      setError("");
-      const { nextIncomes, nextHasMore } = await fetchPage(nextPage);
-      setIncomes((prev) => [...prev, ...nextIncomes]);
-      setHasMore(nextHasMore);
-      setPage(nextPage);
-    } catch (e) {
-      setError(e?.response?.data?.message || "Failed to load more incomes.");
-    } finally {
-      setIsLoadingMore(false);
-    }
-  };
-
-  return (
-    <div className="space-y-6">
-      <div className="flex items-center justify-between gap-3">
-        <h1 className="text-2xl font-bold">Finance</h1>
-      </div>
-
-      {isEditing ? (
-        <FinanceStartForm
-          form={editForm}
-          setForm={setEditForm}
-          onSubmit={onSaveProfile}
-          onCancel={onCancelEdit}
-          error={editError}
-          isSubmitting={isSavingProfile}
-        />
-      ) : (
-        <FinanceSummaryCard
-          segments={segments}
-          totalThisMonth={totalThisMonth}
-          onEdit={onEdit}
-        />
-      )}
-
-      <FinanceProgressCard incomes={graphIncomes} />
-
-      <FinanceIncomesTable
-        incomes={incomes}
-        isLoading={isLoading}
-        error={error}
-        hasMore={hasMore}
-        isLoadingMore={isLoadingMore}
-        onLoadMore={onLoadMore}
-        onAddIncome={() => navigate("/dashboard/finance/incomes/new")}
-      />
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Finance/NewIncome.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Finance/NewIncome.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,50 +1,0 @@
-import React, { useState } from "react";
-import { useNavigate } from "react-router-dom";
-
-import { createIncome } from "../../../../api/finance";
-import NewIncomeForm from "./components/NewIncomeForm.jsx";
-
-export default function NewIncome() {
-  const navigate = useNavigate();
-  const [isSubmitting, setIsSubmitting] = useState(false);
-  const [error, setError] = useState("");
-
-  const onSubmit = async ({ date, amount }) => {
-    setError("");
-    setIsSubmitting(true);
-    try {
-      await createIncome({
-        date,
-        amount: amount === "" ? null : Number(amount),
-      });
-      navigate("/dashboard/finance/tracking", { replace: true });
-    } catch (e) {
-      const message =
-        e?.response?.data?.message ||
-        Object.values(e?.response?.data?.errors ?? {})[0] ||
-        "Failed to add income";
-      setError(message);
-    } finally {
-      setIsSubmitting(false);
-    }
-  };
-
-  return (
-    <div className="space-y-4">
-      <div className="flex items-center justify-between">
-        <h1 className="text-2xl font-bold">Finance</h1>
-        <button className="btn btn-ghost" onClick={() => navigate(-1)}>
-          Back
-        </button>
-      </div>
-
-      <NewIncomeForm
-        onSubmit={onSubmit}
-        onCancel={() => navigate("/dashboard/finance/tracking")}
-        error={error}
-        isSubmitting={isSubmitting}
-      />
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Finance/components/FinanceCenteredCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Finance/components/FinanceCenteredCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,17 +1,0 @@
-import React from "react";
-
-export default function FinanceCenteredCard({ title, message }) {
-  return (
-    <div className="min-h-[70vh] w-full flex items-center justify-center">
-      <div className="w-full max-w-3xl">
-        <div className="card bg-base-200 border border-base-300">
-          <div className="card-body">
-            <h1 className="card-title text-2xl">{title}</h1>
-            <p className="opacity-80">{message}</p>
-          </div>
-        </div>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Finance/components/FinanceIncomesTable.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Finance/components/FinanceIncomesTable.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,79 +1,0 @@
-import React from "react";
-
-function formatDate(value) {
-  if (!value) return "—";
-  const d = new Date(value);
-  if (Number.isNaN(d.getTime())) return String(value);
-  return d.toLocaleDateString(undefined, {
-    year: "numeric",
-    month: "short",
-    day: "2-digit",
-  });
-}
-
-export default function FinanceIncomesTable({
-  incomes,
-  isLoading,
-  error,
-  hasMore,
-  isLoadingMore,
-  onLoadMore,
-  onAddIncome,
-}) {
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <div className="flex items-center justify-between gap-3">
-          <h2 className="card-title">Incomes</h2>
-          <button className="btn btn-primary btn-sm" onClick={onAddIncome}>
-            Add income
-          </button>
-        </div>
-
-        {error ? <p className="text-error text-sm mt-2">{error}</p> : null}
-
-        <div className="mt-4 overflow-x-auto">
-          <table className="table table-zebra">
-            <thead>
-              <tr>
-                <th>Date</th>
-                <th className="text-right">Amount</th>
-              </tr>
-            </thead>
-            <tbody>
-              {isLoading ? (
-                <tr>
-                  <td colSpan={2} className="opacity-70">
-                    Loading…
-                  </td>
-                </tr>
-              ) : (incomes ?? []).length === 0 ? (
-                <tr>
-                  <td colSpan={2} className="opacity-70">
-                    No incomes yet.
-                  </td>
-                </tr>
-              ) : (
-                (incomes ?? []).map((i) => (
-                  <tr key={i.incomeId}>
-                    <td>{formatDate(i.date)}</td>
-                    <td className="text-right tabular-nums">{Number(i.amount).toFixed?.(2) ?? i.amount}</td>
-                  </tr>
-                ))
-              )}
-            </tbody>
-          </table>
-        </div>
-
-        <div className="mt-4">
-          {hasMore ? (
-            <button className="btn btn-outline btn-sm" disabled={isLoadingMore} onClick={onLoadMore}>
-              {isLoadingMore ? "Loading…" : "Load more"}
-            </button>
-          ) : null}
-        </div>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Finance/components/FinanceLegend.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Finance/components/FinanceLegend.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,21 +1,0 @@
-import React from "react";
-
-export default function FinanceLegend({ segments }) {
-  return (
-    <div className="space-y-2 text-sm">
-      {(segments ?? []).map((s) => (
-        <div key={s.key} className="flex items-center justify-between gap-3">
-          <div className="flex items-center gap-2">
-            <span
-              className="inline-block h-3 w-3 rounded"
-              style={{ backgroundColor: s.color }}
-            />
-            <span className="opacity-80">{s.label}</span>
-          </div>
-          <span className="font-medium tabular-nums">{Number(s.value) || 0}%</span>
-        </div>
-      ))}
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Finance/components/FinancePieChart.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Finance/components/FinancePieChart.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,67 +1,0 @@
-import React, { useMemo } from "react";
-
-function clamp01(n) {
-  if (!Number.isFinite(n)) return 0;
-  return Math.max(0, Math.min(1, n));
-}
-
-function polarToCartesian(cx, cy, r, angleDeg) {
-  const rad = ((angleDeg - 90) * Math.PI) / 180;
-  return { x: cx + r * Math.cos(rad), y: cy + r * Math.sin(rad) };
-}
-
-function arcPath(cx, cy, r, startAngle, endAngle) {
-  const start = polarToCartesian(cx, cy, r, endAngle);
-  const end = polarToCartesian(cx, cy, r, startAngle);
-  const largeArcFlag = endAngle - startAngle <= 180 ? 0 : 1;
-  return `M ${cx} ${cy} L ${start.x} ${start.y} A ${r} ${r} 0 ${largeArcFlag} 0 ${end.x} ${end.y} Z`;
-}
-
-export default function FinancePieChart({ segments, size = 180 }) {
-  const r = size / 2;
-  const cx = r;
-  const cy = r;
-
-  const normalized = useMemo(() => {
-    const values = (segments ?? []).map((s) => ({
-      ...s,
-      value: Math.max(0, Number(s.value) || 0),
-    }));
-    const sum = values.reduce((acc, s) => acc + s.value, 0);
-    if (sum <= 0) return values.map((s) => ({ ...s, frac: 0 }));
-    return values.map((s) => ({ ...s, frac: clamp01(s.value / sum) }));
-  }, [segments]);
-
-  let currentAngle = 0;
-
-  return (
-    <svg
-      width={size}
-      height={size}
-      viewBox={`0 0 ${size} ${size}`}
-      role="img"
-      aria-label="Budget distribution pie chart"
-    >
-      <circle cx={cx} cy={cy} r={r} fill="#111827" opacity="0.15" />
-      {normalized.map((s) => {
-        const start = currentAngle;
-        const sweep = s.frac * 360;
-        const end = start + sweep;
-        currentAngle = end;
-
-        if (sweep <= 0.001) return null;
-        return (
-          <path
-            key={s.key}
-            d={arcPath(cx, cy, r, start, end)}
-            fill={s.color}
-            stroke="rgba(0,0,0,0.2)"
-            strokeWidth="1"
-          />
-        );
-      })}
-      <circle cx={cx} cy={cy} r={r * 0.55} fill="var(--fallback-b1, oklch(var(--b1)/1))" />
-    </svg>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Finance/components/FinanceProgressCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Finance/components/FinanceProgressCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,60 +1,0 @@
-import React, { useMemo, useState } from "react";
-
-import TimeRangeToggle from "../../../../../components/graphs/TimeRangeToggle.jsx";
-import PercentChangeAreaChart from "../../../../../components/graphs/PercentChangeAreaChart.jsx";
-import { percentChangeSeries, sumByTimeBucket } from "../../../../../utils/timeSeries.js";
-
-export default function FinanceProgressCard({ incomes }) {
-  const [range, setRange] = useState("weekly");
-
-  const points = useMemo(() => {
-    const buckets = sumByTimeBucket(
-      incomes,
-      range,
-      (i) => i.date,
-      (i) => i.amount,
-    );
-    return percentChangeSeries(buckets);
-  }, [incomes, range]);
-
-  const latest = points?.length ? points[points.length - 1] : null;
-  const latestPct = latest ? Number(latest.value ?? 0) : 0;
-  const latestBase = latest ? Number(latest.base ?? 0) : 0;
-
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <div className="flex items-center justify-between gap-4">
-          <h2 className="card-title">Progress</h2>
-          <div className="flex items-center gap-3">
-            <span className="badge badge-ghost">
-              {latestPct >= 0 ? "+" : ""}
-              {latestPct.toFixed(1)}% (last)
-            </span>
-            <TimeRangeToggle value={range} onChange={setRange} />
-          </div>
-        </div>
-
-        <div className="mt-4 w-full overflow-hidden rounded-xl border border-base-300 bg-base-100 p-2">
-          {points.length < 2 ? (
-            <div className="flex h-65 items-center justify-center text-sm opacity-70">
-              Add at least 2 incomes to see % change.
-            </div>
-          ) : (
-            <PercentChangeAreaChart
-              points={points}
-              granularity={range}
-              height={260}
-              positiveColor="#a855f7"
-            />
-          )}
-        </div>
-
-        <div className="mt-2 text-xs opacity-70">
-          Showing percentage change in income totals per {range} bucket. Latest bucket total: {Math.round(latestBase)}.
-        </div>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Finance/components/FinanceStartCtaCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Finance/components/FinanceStartCtaCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,22 +1,0 @@
-import React from "react";
-
-export default function FinanceStartCtaCard({ error, onStart }) {
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <h1 className="card-title text-2xl">Finance</h1>
-        <p className="opacity-80">
-          Start tracking your finances by setting your yearly budget distribution
-          percentages.
-        </p>
-        {error ? <p className="text-error text-sm mt-2">{error}</p> : null}
-        <div className="mt-4">
-          <button className="btn btn-primary" onClick={onStart}>
-            Start tracking
-          </button>
-        </div>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Finance/components/FinanceStartForm.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Finance/components/FinanceStartForm.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,155 +1,0 @@
-import React, { useMemo } from "react";
-import FinanceLegend from "./FinanceLegend.jsx";
-import FinancePieChart from "./FinancePieChart.jsx";
-
-function toNumber(value) {
-  if (value === "" || value === null || value === undefined) return 0;
-  const n = Number(value);
-  return Number.isFinite(n) ? n : 0;
-}
-
-export default function FinanceStartForm({ form, setForm, onSubmit, onCancel, error, isSubmitting }) {
-  const segments = useMemo(
-    () => [
-      { key: "spending", label: "Spending", value: toNumber(form.spendingBudget), color: "#22c55e" },
-      { key: "saving", label: "Saving", value: toNumber(form.savingBudget), color: "#3b82f6" },
-      { key: "investing", label: "Investing", value: toNumber(form.investingBudget), color: "#a855f7" },
-      { key: "donation", label: "Donation", value: toNumber(form.donationBudget), color: "#f97316" },
-      { key: "credit", label: "Credit", value: toNumber(form.credit), color: "#ef4444" },
-    ],
-    [form],
-  );
-
-  const sum = segments.reduce((acc, s) => acc + (Number(s.value) || 0), 0);
-  const sumOk = Math.abs(sum - 100) <= 0.01;
-
-  const onChange = (key) => (e) => {
-    const value = e.target.value;
-    setForm((prev) => ({ ...prev, [key]: value }));
-  };
-
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body gap-6">
-        <div>
-          <h2 className="card-title text-xl">Set your budget distribution</h2>
-          <p className="text-sm opacity-80">
-            Enter 5 percentages that sum to 100. You can fine-tune later.
-          </p>
-        </div>
-
-        <form onSubmit={onSubmit} className="grid grid-cols-1 gap-6 lg:grid-cols-2">
-          <div className="space-y-4">
-            <label className="form-control">
-              <div className="label">
-                <span className="label-text">Spending (%)</span>
-              </div>
-              <input
-                className="input input-bordered w-full"
-                type="number"
-                min="0"
-                max="100"
-                step="0.01"
-                value={form.spendingBudget}
-                onChange={onChange("spendingBudget")}
-                required
-              />
-            </label>
-
-            <label className="form-control">
-              <div className="label">
-                <span className="label-text">Saving (%)</span>
-              </div>
-              <input
-                className="input input-bordered w-full"
-                type="number"
-                min="0"
-                max="100"
-                step="0.01"
-                value={form.savingBudget}
-                onChange={onChange("savingBudget")}
-                required
-              />
-            </label>
-
-            <label className="form-control">
-              <div className="label">
-                <span className="label-text">Investing (%)</span>
-              </div>
-              <input
-                className="input input-bordered w-full"
-                type="number"
-                min="0"
-                max="100"
-                step="0.01"
-                value={form.investingBudget}
-                onChange={onChange("investingBudget")}
-                required
-              />
-            </label>
-
-            <label className="form-control">
-              <div className="label">
-                <span className="label-text">Donation (%)</span>
-              </div>
-              <input
-                className="input input-bordered w-full"
-                type="number"
-                min="0"
-                max="100"
-                step="0.01"
-                value={form.donationBudget}
-                onChange={onChange("donationBudget")}
-                required
-              />
-            </label>
-
-            <label className="form-control">
-              <div className="label">
-                <span className="label-text">Credit (%)</span>
-              </div>
-              <input
-                className="input input-bordered w-full"
-                type="number"
-                min="0"
-                max="100"
-                step="0.01"
-                value={form.credit}
-                onChange={onChange("credit")}
-                required
-              />
-            </label>
-
-            <div className="text-sm">
-              <span className={sumOk ? "text-success" : "text-warning"}>
-                Total: {sum.toFixed(2)}%
-              </span>
-              {!sumOk ? (
-                <span className="opacity-70"> (must equal 100%)</span>
-              ) : null}
-            </div>
-
-            {error ? <p className="text-error text-sm">{error}</p> : null}
-
-            <div className="flex gap-2">
-              <button className="btn btn-primary" type="submit" disabled={isSubmitting || !sumOk}>
-                {isSubmitting ? "Saving…" : "Start tracking"}
-              </button>
-              <button className="btn" type="button" onClick={onCancel} disabled={isSubmitting}>
-                Cancel
-              </button>
-            </div>
-          </div>
-
-          <div className="grid grid-cols-1 gap-4 md:grid-cols-[auto_1fr] items-center">
-            <div className="flex justify-center md:justify-start">
-              <FinancePieChart segments={segments} size={200} />
-            </div>
-            <FinanceLegend segments={segments} />
-          </div>
-        </form>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Finance/components/FinanceSummaryCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Finance/components/FinanceSummaryCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,87 +1,0 @@
-import React from "react";
-import FinanceLegend from "./FinanceLegend.jsx";
-import FinancePieChart from "./FinancePieChart.jsx";
-
-function formatMoney(value) {
-  const n = Number(value);
-  if (!Number.isFinite(n)) return "—";
-  try {
-    return new Intl.NumberFormat(undefined, {
-      minimumFractionDigits: 2,
-      maximumFractionDigits: 2,
-    }).format(n);
-  } catch {
-    return n.toFixed(2);
-  }
-}
-
-export default function FinanceSummaryCard({ segments, totalThisMonth, onEdit }) {
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <div className="flex items-start justify-between gap-6 flex-wrap">
-          <div>
-            <h2 className="card-title">Budget distribution</h2>
-            <p className="text-sm opacity-80">
-              Your current percentages (stored in your finance profile).
-            </p>
-          </div>
-
-          <div className="flex items-center gap-2">
-            <button className="btn btn-outline btn-sm" onClick={onEdit}>
-              Edit
-            </button>
-          </div>
-        </div>
-
-        <div className="mt-4">
-          <div className="rounded-lg border border-base-300 bg-base-100 p-4">
-            <div className="text-sm opacity-70">Total money earned this month</div>
-            <div className="text-2xl font-bold tabular-nums">
-              {formatMoney(totalThisMonth)}
-            </div>
-          </div>
-        </div>
-
-        <div className="mt-6 grid grid-cols-1 gap-6 md:grid-cols-[auto_1fr] items-center">
-          <div className="flex justify-center md:justify-start">
-            <FinancePieChart segments={segments} size={180} />
-          </div>
-
-          <div className="space-y-4">
-            <FinanceLegend segments={segments} />
-
-            <div className="divider my-0" />
-
-            <div className="space-y-2 text-sm">
-              {segments.map((s) => {
-                const pct = Number(s.value) || 0;
-                const allocated = ((Number(totalThisMonth) || 0) * pct) / 100;
-                return (
-                  <div
-                    key={s.key}
-                    className="flex items-center justify-between gap-3"
-                  >
-                    <div className="flex items-center gap-2">
-                      <span
-                        className="inline-block h-3 w-3 rounded"
-                        style={{ backgroundColor: s.color }}
-                      />
-                      <span className="opacity-80">
-                        {s.label} allocation
-                      </span>
-                    </div>
-                    <span className="font-medium tabular-nums">
-                      {formatMoney(allocated)}
-                    </span>
-                  </div>
-                );
-              })}
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Finance/components/NewIncomeForm.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Finance/components/NewIncomeForm.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,66 +1,0 @@
-import React, { useState } from "react";
-
-export default function NewIncomeForm({ onSubmit, onCancel, error, isSubmitting }) {
-  const [date, setDate] = useState(() => {
-    const d = new Date();
-    console.log('Date:', d);
-    return d.toISOString().slice(0, 10);
-  });
-  const [amount, setAmount] = useState("");
-
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <h2 className="card-title">Add income</h2>
-
-        <form
-          className="mt-4 grid grid-cols-1 gap-4 max-w-md"
-          onSubmit={(e) => {
-            e.preventDefault();
-            onSubmit({ date, amount });
-          }}
-        >
-          <label className="form-control">
-            <div className="label">
-              <span className="label-text">Date</span>
-            </div>
-            <input
-              className="input input-bordered"
-              type="date"
-              value={date}
-              onChange={(e) => setDate(e.target.value)}
-              required
-            />
-          </label>
-
-          <label className="form-control">
-            <div className="label">
-              <span className="label-text">Amount</span>
-            </div>
-            <input
-              className="input input-bordered"
-              type="number"
-              min="0.01"
-              step="0.01"
-              value={amount}
-              onChange={(e) => setAmount(e.target.value)}
-              required
-            />
-          </label>
-
-          {error ? <p className="text-error text-sm">{error}</p> : null}
-
-          <div className="flex gap-2">
-            <button className="btn btn-primary" type="submit" disabled={isSubmitting}>
-              {isSubmitting ? "Saving…" : "Save"}
-            </button>
-            <button className="btn" type="button" onClick={onCancel} disabled={isSubmitting}>
-              Cancel
-            </button>
-          </div>
-        </form>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Investing/Investing.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Investing/Investing.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,85 +1,0 @@
-import React, { useEffect, useState } from "react";
-import { useNavigate } from "react-router-dom";
-
-import api from "../../../../api/axios";
-
-import InvestingCenteredCard from "./components/InvestingCenteredCard.jsx";
-import InvestingStartCtaCard from "./components/InvestingStartCtaCard.jsx";
-
-const Investing = () => {
-  const navigate = useNavigate();
-
-  const [isLoading, setIsLoading] = useState(true);
-  const [isTracking, setIsTracking] = useState(false);
-  const [error, setError] = useState("");
-  const [isSubmitting, setIsSubmitting] = useState(false);
-
-  useEffect(() => {
-    let isMounted = true;
-    const run = async () => {
-      setIsLoading(true);
-      setError("");
-      try {
-        const res = await api.get("/investing/status");
-        const tracking = Boolean(res?.data?.tracking);
-        if (!isMounted) return;
-        setIsTracking(tracking);
-        if (tracking) {
-          navigate("/dashboard/investing/tracking", { replace: true });
-        }
-      } catch (err) {
-        if (!isMounted) return;
-        const message =
-          err?.response?.data?.message || "Failed to load investing status";
-        setError(message);
-      } finally {
-        if (isMounted) setIsLoading(false);
-      }
-    };
-
-    run();
-    return () => {
-      isMounted = false;
-    };
-  }, [navigate]);
-
-  const onStart = async () => {
-    setError("");
-    setIsSubmitting(true);
-    try {
-      await api.post("/investing/start", {});
-      setIsTracking(true);
-      navigate("/dashboard/investing/tracking", { replace: true });
-    } catch (err) {
-      const message =
-        err?.response?.data?.message ||
-        Object.values(err?.response?.data?.errors ?? {})[0] ||
-        "Failed to start tracking";
-      setError(message);
-    } finally {
-      setIsSubmitting(false);
-    }
-  };
-
-  if (isLoading) {
-    return <InvestingCenteredCard title="Investing" message="Loading…" />;
-  }
-
-  if (isTracking) {
-    return <InvestingCenteredCard title="Investing" message="Redirecting…" />;
-  }
-
-  return (
-    <div className="min-h-[70vh] w-full flex items-center justify-center">
-      <div className="w-full max-w-3xl">
-        <InvestingStartCtaCard
-          error={error}
-          onStart={onStart}
-          isSubmitting={isSubmitting}
-        />
-      </div>
-    </div>
-  );
-};
-
-export default Investing;
Index: frontend/src/pages/Dashboard/pages/Investing/InvestingTracking.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Investing/InvestingTracking.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,288 +1,0 @@
-import React, { useCallback, useEffect, useMemo, useState } from "react";
-import { useNavigate } from "react-router-dom";
-
-import api from "../../../../api/axios";
-import { fetchCurrentPricesBySymbol } from "../../../../api/twelveData";
-
-import InvestingTrackingHeader from "./components/InvestingTrackingHeader.jsx";
-import InvestingProgressCard from "./components/InvestingProgressCard.jsx";
-import InvestingAssetsTable from "./components/InvestingAssetsTable.jsx";
-
-function formatDate(value) {
-  if (!value) return "—";
-  const d = new Date(value);
-  if (Number.isNaN(d.getTime())) return String(value);
-  return d.toLocaleDateString(undefined, {
-    year: "numeric",
-    month: "short",
-    day: "2-digit",
-  });
-}
-
-function formatMoney(value) {
-  if (value === null || value === undefined || value === "") return "—";
-  const num = Number(value);
-  if (Number.isNaN(num)) return String(value);
-  return num.toLocaleString(undefined, {
-    style: "currency",
-    currency: "USD",
-    maximumFractionDigits: 2,
-  });
-}
-
-export default function InvestingTracking() {
-  const navigate = useNavigate();
-  const pageSize = 5;
-  const graphPageSize = 200;
-
-  const [assets, setAssets] = useState([]);
-  const [page, setPage] = useState(0);
-  const [hasMore, setHasMore] = useState(false);
-  const [isLoading, setIsLoading] = useState(true);
-  const [isLoadingMore, setIsLoadingMore] = useState(false);
-  const [isDeletingId, setIsDeletingId] = useState(null);
-  const [pendingDelete, setPendingDelete] = useState(null);
-  const [error, setError] = useState("");
-
-  const [quotesBySymbol, setQuotesBySymbol] = useState({});
-  const [isQuotesLoading, setIsQuotesLoading] = useState(false);
-  const [quotesError, setQuotesError] = useState("");
-
-  const columns = useMemo(
-    () => [
-      { key: "tickerSymbol", label: "Ticker" },
-      { key: "quantity", label: "Quantity" },
-      { key: "buyPrice", label: "Buy Price" },
-      { key: "buyDate", label: "Buy Date" },
-      { key: "currentPrice", label: "Current Price" },
-      { key: "roi", label: "ROI" },
-      { key: "actions", label: "" },
-    ],
-    [],
-  );
-
-  const fetchPage = useCallback(async (nextPage, size = pageSize) => {
-    const resp = await api.get("/investing/assets", {
-      params: { page: nextPage, size },
-    });
-    const data = resp?.data ?? {};
-    const nextAssets = Array.isArray(data.assets) ? data.assets : [];
-    const nextHasMore = Boolean(data.hasMore);
-    return { nextAssets, nextHasMore };
-  }, []);
-
-  const [graphAssets, setGraphAssets] = useState([]);
-
-  const fetchAllAssetsForGraph = useCallback(async () => {
-    let p = 0;
-    let hasMorePages = true;
-    const all = [];
-
-    while (hasMorePages) {
-      const { nextAssets: chunk, nextHasMore } = await fetchPage(p, graphPageSize);
-      all.push(...chunk);
-      hasMorePages = nextHasMore && chunk.length > 0;
-      p += 1;
-      if (p > 200) break;
-    }
-
-    return all;
-  }, [fetchPage]);
-
-  useEffect(() => {
-    let cancelled = false;
-    (async () => {
-      try {
-        setIsLoading(true);
-        setError("");
-        const [tableFirstPage, allForGraph] = await Promise.all([
-          fetchPage(0, pageSize),
-          fetchAllAssetsForGraph(),
-        ]);
-        if (cancelled) return;
-        setAssets(tableFirstPage.nextAssets);
-        setHasMore(tableFirstPage.nextHasMore);
-        setGraphAssets(allForGraph);
-        setPage(0);
-      } catch (e) {
-        if (cancelled) return;
-        setError(e?.response?.data?.message || "Failed to load assets.");
-      } finally {
-        if (!cancelled) setIsLoading(false);
-      }
-    })();
-    return () => {
-      cancelled = true;
-    };
-  }, [fetchAllAssetsForGraph, fetchPage]);
-
-  const tickerSymbols = useMemo(() => {
-    const set = new Set();
-    for (const a of assets) {
-      if (a?.tickerSymbol) set.add(String(a.tickerSymbol).toUpperCase());
-    }
-    return Array.from(set).sort();
-  }, [assets]);
-
-  const tickerSymbolsKey = useMemo(() => tickerSymbols.join(","), [tickerSymbols]);
-
-  useEffect(() => {
-    if (tickerSymbols.length === 0) {
-      setQuotesBySymbol({});
-      setIsQuotesLoading(false);
-      setQuotesError("");
-      return;
-    }
-
-    let cancelled = false;
-    let intervalId;
-
-    const fetchQuotes = async () => {
-      try {
-        setIsQuotesLoading(true);
-        setQuotesError("");
-        if (cancelled) return;
-        const map = await fetchCurrentPricesBySymbol(tickerSymbols);
-        if (cancelled) return;
-        setQuotesBySymbol(map);
-      } catch (err) {
-        if (cancelled) return;
-        const msg =
-          err?.message ||
-          "Could not fetch current prices (check API key / provider availability).";
-        setQuotesError(msg);
-        // Keep any previously loaded quotes instead of wiping the table.
-        // (If this is the first load, quotesBySymbol will already be empty.)
-      } finally {
-        if (!cancelled) setIsQuotesLoading(false);
-      }
-    };
-
-    fetchQuotes();
-    // Keep refresh infrequent to avoid provider rate limits.
-    intervalId = setInterval(fetchQuotes, 5 * 60_000);
-
-    return () => {
-      cancelled = true;
-      if (intervalId) clearInterval(intervalId);
-    };
-  }, [tickerSymbolsKey, tickerSymbols]);
-
-  const onLoadMore = async () => {
-    if (isLoadingMore || !hasMore) return;
-    const nextPage = page + 1;
-    try {
-      setIsLoadingMore(true);
-      setError("");
-      const { nextAssets, nextHasMore } = await fetchPage(nextPage);
-      setAssets((prev) => [...prev, ...nextAssets]);
-      setHasMore(nextHasMore);
-      setPage(nextPage);
-    } catch (e) {
-      setError(e?.response?.data?.message || "Failed to load more assets.");
-    } finally {
-      setIsLoadingMore(false);
-    }
-  };
-
-  const doDelete = async (assetId) => {
-    if (!assetId || isDeletingId) return;
-    try {
-      setIsDeletingId(assetId);
-      setError("");
-      await api.delete(`/investing/assets/${assetId}`);
-      setAssets((prev) => prev.filter((a) => a.assetId !== assetId));
-      setPendingDelete(null);
-    } catch (e) {
-      setError(e?.response?.data?.message || "Failed to delete asset.");
-    } finally {
-      setIsDeletingId(null);
-    }
-  };
-
-  const onRequestDelete = (asset) => {
-    if (!asset?.assetId) return;
-    setPendingDelete({
-      assetId: asset.assetId,
-      tickerSymbol: asset.tickerSymbol,
-    });
-  };
-
-  return (
-    <div className="space-y-6">
-      <InvestingTrackingHeader
-        onAddAsset={() => navigate("/dashboard/investing/assets/new")}
-      />
-       <InvestingProgressCard assets={graphAssets} quotesBySymbol={quotesBySymbol} />
-
-      {quotesError ? (
-        <div className="text-sm opacity-70">
-          Prices unavailable: {quotesError}
-        </div>
-      ) : null}
-
-      {pendingDelete ? (
-        <div className="modal modal-open" role="dialog" aria-modal="true">
-          <div className="modal-box">
-            <h3 className="text-lg font-semibold">Delete investment?</h3>
-            <p className="opacity-80 mt-2">
-              This will permanently delete{" "}
-              <span className="font-semibold">
-                {pendingDelete.tickerSymbol || "this asset"}
-              </span>
-              .
-            </p>
-
-            <div className="modal-action">
-              <button
-                type="button"
-                className="btn btn-ghost"
-                onClick={() => setPendingDelete(null)}
-                disabled={isDeletingId === pendingDelete.assetId}
-              >
-                Cancel
-              </button>
-              <button
-                type="button"
-                className="btn bg-red-500! text-white! hover:bg-red-600! border-0"
-                onClick={() => doDelete(pendingDelete.assetId)}
-                disabled={isDeletingId === pendingDelete.assetId}
-              >
-                {isDeletingId === pendingDelete.assetId
-                  ? "Deleting…"
-                  : "Delete"}
-              </button>
-            </div>
-          </div>
-          <button
-            type="button"
-            className="modal-backdrop"
-            aria-label="Close"
-            onClick={() => {
-              if (isDeletingId === pendingDelete.assetId) return;
-              setPendingDelete(null);
-            }}
-          />
-        </div>
-      ) : null}
-
-      <InvestingAssetsTable
-        columns={columns}
-        assets={assets}
-        isLoading={isLoading}
-        error={error}
-        quotesBySymbol={quotesBySymbol}
-        isQuotesLoading={isQuotesLoading}
-        isLoadingMore={isLoadingMore}
-        hasMore={hasMore}
-        onLoadMore={onLoadMore}
-        pageSize={pageSize}
-        formatDate={formatDate}
-        formatMoney={formatMoney}
-        onAddAsset={() => navigate("/dashboard/investing/assets/new")}
-        onRequestDelete={onRequestDelete}
-        isDeletingId={isDeletingId}
-      />
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/Investing/NewInvestment.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Investing/NewInvestment.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,250 +1,0 @@
-import React, { useEffect, useMemo, useState } from "react";
-import { useNavigate } from "react-router-dom";
-
-import api from "../../../../api/axios";
-import { searchTickers } from "../../../../api/yahooFinance";
-
-export default function NewInvestment() {
-  const navigate = useNavigate();
-
-  const todayIso = useMemo(() => {
-    const now = new Date();
-    const yyyy = now.getFullYear();
-    const mm = String(now.getMonth() + 1).padStart(2, "0");
-    const dd = String(now.getDate()).padStart(2, "0");
-    return `${yyyy}-${mm}-${dd}`;
-  }, []);
-
-  const initialForm = useMemo(
-    () => ({ tickerSymbol: "", quantity: "", buyPrice: "", buyDate: "" }),
-    [],
-  );
-
-  const [form, setForm] = useState(initialForm);
-  const [error, setError] = useState("");
-  const [isSubmitting, setIsSubmitting] = useState(false);
-
-  const [tickerQuery, setTickerQuery] = useState("");
-  const [tickerOptions, setTickerOptions] = useState([]);
-  const [isLoadingTickers, setIsLoadingTickers] = useState(false);
-
-  useEffect(() => {
-    const q = tickerQuery.trim();
-    if (q.length < 2) {
-      setTickerOptions([]);
-      setIsLoadingTickers(false);
-      return;
-    }
-
-    let cancelled = false;
-    const handle = setTimeout(async () => {
-      try {
-        setIsLoadingTickers(true);
-        if (cancelled) return;
-        const data = await searchTickers(q, 20);
-        if (cancelled) return;
-        setTickerOptions(Array.isArray(data) ? data : []);
-      } catch {
-        if (!cancelled) setTickerOptions([]);
-      } finally {
-        if (!cancelled) setIsLoadingTickers(false);
-      }
-    }, 250);
-
-    return () => {
-      cancelled = true;
-      clearTimeout(handle);
-    };
-  }, [tickerQuery]);
-
-  const onSubmit = async (e) => {
-    e.preventDefault();
-    setError("");
-
-    if (!form.tickerSymbol) {
-      setError("Please select a ticker symbol");
-      return;
-    }
-
-    if (form.buyDate && form.buyDate > todayIso) {
-      setError("Buy date cannot be in the future");
-      return;
-    }
-
-    const quantityNum = form.quantity === "" ? null : Number(form.quantity);
-    if (!quantityNum || Number.isNaN(quantityNum) || quantityNum <= 0) {
-      setError("Quantity must be greater than 0");
-      return;
-    }
-
-    const buyPriceNum = form.buyPrice === "" ? null : Number(form.buyPrice);
-    if (
-      buyPriceNum !== null &&
-      (Number.isNaN(buyPriceNum) || buyPriceNum < 0)
-    ) {
-      setError("Buy price must be 0 or greater");
-      return;
-    }
-
-    try {
-      setIsSubmitting(true);
-      await api.post("/investing/assets", {
-        tickerSymbol: form.tickerSymbol,
-        quantity: quantityNum,
-        buyPrice: buyPriceNum,
-        buyDate: form.buyDate === "" ? null : form.buyDate,
-      });
-
-      navigate("/dashboard/investing/tracking", { replace: true });
-    } catch (err) {
-      const message =
-        err?.response?.data?.message ||
-        Object.values(err?.response?.data?.errors ?? {})[0] ||
-        "Failed to add investment";
-      setError(message);
-    } finally {
-      setIsSubmitting(false);
-    }
-  };
-
-  return (
-    <div className="max-w-2xl">
-      <div className="card bg-base-200 border border-base-300">
-        <div className="card-body">
-          <h1 className="text-2xl font-bold">Add new investment</h1>
-          <p className="opacity-80">
-            Add an asset you bought. (We’ll build performance tracking next.)
-          </p>
-
-          {error ? (
-            <div className="alert alert-error mt-4">
-              <span>{error}</span>
-            </div>
-          ) : null}
-
-          <form onSubmit={onSubmit} className="mt-6 space-y-4">
-            <div>
-              <label className="label">
-                <span className="label-text">Ticker symbol</span>
-              </label>
-              <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
-                <input
-                  className="input input-bordered w-full"
-                  placeholder="Search (e.g. AAPL, TSLA, NVDA)"
-                  value={tickerQuery}
-                  onChange={(e) => setTickerQuery(e.target.value)}
-                />
-                <select
-                  className="select select-bordered w-full"
-                  value={form.tickerSymbol}
-                  onChange={(e) =>
-                    setForm((p) => ({ ...p, tickerSymbol: e.target.value }))
-                  }
-                  required
-                >
-                  <option value="" disabled>
-                    {isLoadingTickers
-                      ? "Loading tickers…"
-                      : tickerOptions.length
-                        ? "Select a ticker"
-                        : "Search to load tickers"}
-                  </option>
-                  {tickerOptions.map((o) => {
-                    const symbol = o?.symbol ?? "";
-                    const name = o?.name ?? "";
-                    const exchange = o?.exchange ?? "";
-                    const label = [
-                      symbol,
-                      name ? `— ${name}` : "",
-                      exchange ? `(${exchange})` : "",
-                    ]
-                      .filter(Boolean)
-                      .join(" ");
-                    return (
-                      <option key={symbol} value={symbol}>
-                        {label}
-                      </option>
-                    );
-                  })}
-                </select>
-              </div>
-              <p className="text-xs opacity-70 mt-2">
-                Only tickers returned by Yahoo Finance can be selected.
-              </p>
-            </div>
-
-            <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
-              <div>
-                <label className="label">
-                  <span className="label-text">Quantity</span>
-                </label>
-                <input
-                  type="number"
-                  step="any"
-                  min="0"
-                  className="input input-bordered w-full"
-                  placeholder="10"
-                  value={form.quantity}
-                  onChange={(e) =>
-                    setForm((p) => ({ ...p, quantity: e.target.value }))
-                  }
-                  required
-                />
-              </div>
-
-              <div>
-                <label className="label">
-                  <span className="label-text">Buy price (optional)</span>
-                </label>
-                <input
-                  type="number"
-                  step="any"
-                  min="0"
-                  className="input input-bordered w-full"
-                  placeholder="187.20"
-                  value={form.buyPrice}
-                  onChange={(e) =>
-                    setForm((p) => ({ ...p, buyPrice: e.target.value }))
-                  }
-                />
-              </div>
-            </div>
-
-            <div>
-              <label className="label">
-                <span className="label-text">Buy date (optional)</span>
-              </label>
-              <input
-                type="date"
-                className="input input-bordered w-full"
-                value={form.buyDate}
-                onChange={(e) =>
-                  setForm((p) => ({ ...p, buyDate: e.target.value }))
-                }
-                max={todayIso}
-              />
-            </div>
-
-            <div className="flex flex-col gap-3 sm:flex-row sm:justify-end">
-              <button
-                type="button"
-                className="btn btn-ghost"
-                onClick={() => navigate("/dashboard/investing/tracking")}
-                disabled={isSubmitting}
-              >
-                Cancel
-              </button>
-              <button
-                type="submit"
-                className="btn bg-green-400! text-black! hover:bg-green-500! border-0"
-                disabled={isSubmitting}
-              >
-                {isSubmitting ? "Saving…" : "Save investment"}
-              </button>
-            </div>
-          </form>
-        </div>
-      </div>
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/Investing/components/InvestingAssetsTable.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Investing/components/InvestingAssetsTable.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,237 +1,0 @@
-import React, { useMemo } from "react";
-import { MdDelete } from "react-icons/md";
-
-export default function InvestingAssetsTable({
-  columns,
-  assets,
-  isLoading,
-  error,
-  quotesBySymbol,
-  isQuotesLoading,
-  isLoadingMore,
-  hasMore,
-  onLoadMore,
-  pageSize,
-  formatDate,
-  formatMoney,
-  onAddAsset,
-  onRequestDelete,
-  onDelete,
-  isDeletingId,
-}) {
-  const totals = useMemo(() => {
-    let totalInvested = 0;
-    let totalCurrent = 0;
-    let investedCount = 0;
-    let currentCount = 0;
-
-    for (const a of assets) {
-      const symbol = String(a?.tickerSymbol ?? "").toUpperCase();
-      const quantity = Number(a?.quantity);
-      if (!symbol || Number.isNaN(quantity) || quantity <= 0) continue;
-
-      const buyPrice = Number(a?.buyPrice);
-      if (!Number.isNaN(buyPrice) && buyPrice >= 0) {
-        totalInvested += buyPrice * quantity;
-        investedCount += 1;
-      }
-
-      const currentPrice = Number(quotesBySymbol?.[symbol]);
-      if (!Number.isNaN(currentPrice) && currentPrice >= 0) {
-        totalCurrent += currentPrice * quantity;
-        currentCount += 1;
-      }
-    }
-
-    const hasInvested = investedCount > 0 && totalInvested > 0;
-    const hasCurrent = currentCount > 0;
-    const roiPct =
-      hasInvested && hasCurrent
-        ? ((totalCurrent - totalInvested) / totalInvested) * 100
-        : null;
-
-    return { totalInvested, totalCurrent, roiPct, hasInvested, hasCurrent };
-  }, [assets, quotesBySymbol]);
-
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <div className="flex items-center justify-between gap-4">
-          <h2 className="text-lg font-semibold">Assets</h2>
-          <span className="text-sm opacity-70">
-            Showing {pageSize} per page
-          </span>
-        </div>
-
-        {error ? (
-          <div className="alert alert-error mt-4">
-            <span>{error}</span>
-          </div>
-        ) : null}
-
-        <div className="mt-4 grid grid-cols-1 gap-3 sm:grid-cols-3">
-          <div className="stat bg-base-100 rounded-box border border-base-300">
-            <div className="stat-title">Total invested</div>
-            <div className="stat-value text-xl">
-              {totals.hasInvested ? formatMoney(totals.totalInvested) : "—"}
-            </div>
-            <div className="stat-desc opacity-70">
-              Cost basis (buy price × quantity)
-            </div>
-          </div>
-
-          <div className="stat bg-base-100 rounded-box border border-base-300">
-            <div className="stat-title">Current value</div>
-            <div className="stat-value text-xl">
-              {totals.hasCurrent && !isQuotesLoading
-                ? formatMoney(totals.totalCurrent)
-                : isQuotesLoading
-                  ? "Loading…"
-                  : "—"}
-            </div>
-            <div className="stat-desc opacity-70">Live price × quantity</div>
-          </div>
-
-          <div className="stat bg-base-100 rounded-box border border-base-300">
-            <div className="stat-title">Total ROI</div>
-            <div className="stat-value text-xl">
-              {typeof totals.roiPct === "number" &&
-              !Number.isNaN(totals.roiPct) ? (
-                <span
-                  className={
-                    totals.roiPct > 0
-                      ? "text-green-400 font-semibold"
-                      : totals.roiPct < 0
-                        ? "text-red-400 font-semibold"
-                        : "opacity-80"
-                  }
-                >
-                  {totals.roiPct > 0 ? "+" : ""}
-                  {totals.roiPct.toFixed(2)}%
-                </span>
-              ) : isQuotesLoading ? (
-                "Loading…"
-              ) : (
-                "—"
-              )}
-            </div>
-            <div className="stat-desc opacity-70">
-              (current − invested) ÷ invested
-            </div>
-          </div>
-        </div>
-
-        <div className="mt-4 overflow-x-auto">
-          <table className="table">
-            <thead>
-              <tr>
-                {columns.map((c) => (
-                  <th key={c.key}>{c.label}</th>
-                ))}
-              </tr>
-            </thead>
-            <tbody>
-              {isLoading ? (
-                <tr>
-                  <td colSpan={columns.length} className="opacity-70">
-                    Loading…
-                  </td>
-                </tr>
-              ) : assets.length === 0 ? (
-                <tr>
-                  <td colSpan={columns.length} className="py-10">
-                    <div className="flex flex-col items-center text-center gap-3">
-                      <p className="opacity-80">No investments yet.</p>
-                      <button
-                        type="button"
-                        className="btn bg-green-400! text-black! hover:bg-green-500! border-0"
-                        onClick={onAddAsset}
-                      >
-                        Add your first investment
-                      </button>
-                    </div>
-                  </td>
-                </tr>
-              ) : (
-                assets.map((a) => (
-                  <tr key={a.assetId}>
-                    <td className="font-semibold">{a.tickerSymbol ?? "—"}</td>
-                    <td>{a.quantity ?? "—"}</td>
-                    <td>{formatMoney(a.buyPrice)}</td>
-                    <td>{formatDate(a.buyDate)}</td>
-                    <td>
-                      {isQuotesLoading
-                        ? "Loading…"
-                        : formatMoney(
-                            quotesBySymbol?.[
-                              String(a.tickerSymbol ?? "").toUpperCase()
-                            ],
-                          )}
-                    </td>
-                    <td>
-                      {(() => {
-                        const symbol = String(
-                          a.tickerSymbol ?? "",
-                        ).toUpperCase();
-                        const current = Number(quotesBySymbol?.[symbol]);
-                        const buy = Number(a.buyPrice);
-                        if (!symbol || Number.isNaN(current)) return "—";
-                        if (Number.isNaN(buy) || buy <= 0) return "—";
-                        const roiPct = ((current - buy) / buy) * 100;
-                        const cls =
-                          roiPct > 0
-                            ? "text-green-400 font-semibold"
-                            : roiPct < 0
-                              ? "text-red-400 font-semibold"
-                              : "opacity-80";
-                        const sign = roiPct > 0 ? "+" : "";
-                        return (
-                          <span className={cls}>
-                            {sign}
-                            {roiPct.toFixed(2)}%
-                          </span>
-                        );
-                      })()}
-                    </td>
-                    <td className="text-right">
-                      <button
-                        type="button"
-                        className="btn btn-ghost btn-sm text-red-400 hover:text-red-300"
-                        title="Delete"
-                        onClick={() => {
-                          if (onRequestDelete) {
-                            onRequestDelete(a);
-                            return;
-                          }
-                          onDelete?.(a.assetId);
-                        }}
-                        disabled={isDeletingId === a.assetId}
-                      >
-                        <MdDelete className="size-5" />
-                      </button>
-                    </td>
-                  </tr>
-                ))
-              )}
-            </tbody>
-          </table>
-        </div>
-
-        <div className="mt-4 flex justify-center">
-          {!isLoading && assets.length === 0 ? null : hasMore ? (
-            <button
-              type="button"
-              className="btn"
-              onClick={onLoadMore}
-              disabled={isLoadingMore}
-            >
-              {isLoadingMore ? "Loading…" : "Load more"}
-            </button>
-          ) : (
-            <span className="text-sm opacity-70">No more assets.</span>
-          )}
-        </div>
-      </div>
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/Investing/components/InvestingCenteredCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Investing/components/InvestingCenteredCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,16 +1,0 @@
-import React from "react";
-
-export default function InvestingCenteredCard({ title, message }) {
-  return (
-    <div className="min-h-[60vh] w-full flex items-center justify-center">
-      <div className="w-full max-w-2xl">
-        <div className="card bg-base-200 border border-base-300">
-          <div className="card-body">
-            <h1 className="text-2xl font-bold">{title}</h1>
-            <p className="opacity-80">{message}</p>
-          </div>
-        </div>
-      </div>
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/Investing/components/InvestingProgressCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Investing/components/InvestingProgressCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,204 +1,0 @@
-import React, { useMemo, useState } from "react";
-
-import TimeRangeToggle from "../../../../../components/graphs/TimeRangeToggle.jsx";
-import PercentChangeAreaChart from "../../../../../components/graphs/PercentChangeAreaChart.jsx";
-import { formatBucketLabel } from "../../../../../utils/timeSeries.js";
-
-function bucketKey(date, granularity) {
-  const d = new Date(date);
-  if (Number.isNaN(d.getTime())) return null;
-
-  function startOfDay(d) {
-    return new Date(d.getFullYear(), d.getMonth(), d.getDate());
-  }
-
-  function startOfISOWeek(d) {
-    const date = startOfDay(d);
-    const day = date.getDay();
-    const diff = (day === 0 ? -6 : 1) - day;
-    date.setDate(date.getDate() + diff);
-    return startOfDay(date);
-  }
-
-  function startOfMonth(d) {
-    return new Date(d.getFullYear(), d.getMonth(), 1);
-  }
-
-  function startOfYear(d) {
-    return new Date(d.getFullYear(), 0, 1);
-  }
-
-  let s;
-  switch (granularity) {
-    case "daily":
-      s = startOfDay(d);
-      break;
-    case "weekly":
-      s = startOfISOWeek(d);
-      break;
-    case "monthly":
-      s = startOfMonth(d);
-      break;
-    case "yearly":
-      s = startOfYear(d);
-      break;
-    default:
-      s = startOfDay(d);
-  }
-  return s.getTime();
-}
-
-export default function InvestingProgressCard({ assets, quotesBySymbol = {} }) {
-  const [range, setRange] = useState("weekly");
-
-  const points = useMemo(() => {
-    // Calculate portfolio percentage gain/loss over time using current prices
-    // Display cumulative portfolio value and percentage change between time buckets
-
-    if (!assets || assets.length === 0) {
-      return [];
-    }
-
-    // Group assets by buy date bucket
-    const buckets = new Map();
-    for (const asset of assets) {
-      if (asset?.buyDate) {
-        const ts = bucketKey(asset.buyDate, range);
-        if (ts !== null) {
-          if (!buckets.has(ts)) {
-            buckets.set(ts, []);
-          }
-          buckets.get(ts).push(asset);
-        }
-      }
-    }
-
-    // Sort buckets chronologically
-    const sortedBuckets = Array.from(buckets.entries()).sort((a, b) => a[0] - b[0]);
-
-    // Calculate cumulative portfolio value at each bucket
-    const points = [];
-    let cumulativeAssets = [];
-
-    for (const [ts, assetsInBucket] of sortedBuckets) {
-      cumulativeAssets = [...cumulativeAssets, ...assetsInBucket];
-
-      let totalInvested = 0;
-      let totalCurrentValue = 0;
-
-      for (const asset of cumulativeAssets) {
-        const qty = Number(asset?.quantity) || 0;
-        const buyPrice = Number(asset?.buyPrice) || 0;
-        const ticker = String(asset?.tickerSymbol || "").toUpperCase();
-        const currentPrice = quotesBySymbol[ticker] || buyPrice;
-
-        totalInvested += qty * buyPrice;
-        totalCurrentValue += qty * currentPrice;
-      }
-
-      if (totalInvested > 0) {
-        points.push({
-          ts,
-          invested: totalInvested,
-          current: totalCurrentValue,
-        });
-      }
-    }
-
-    // Calculate percentage gain from invested to current value
-    const result = [];
-    for (const p of points) {
-      const percentageGain = ((p.current - p.invested) / p.invested) * 100;
-      result.push({
-        ts: p.ts,
-        value: percentageGain,
-        base: p.current,
-        invested: p.invested,
-      });
-    }
-
-    return result;
-  }, [assets, range, quotesBySymbol]);
-
-  const latest = points?.length ? points[points.length - 1] : null;
-  const latestPct = latest ? Number(latest.value ?? 0) : 0;
-  const latestCurrentValue = latest ? Number(latest.base ?? 0) : 0;
-  const latestInvested = latest ? Number(latest.invested ?? 0) : 0;
-
-  const totalCurrentPortfolioValue = assets.reduce((sum, asset) => {
-    const qty = Number(asset?.quantity) || 0;
-    const ticker = String(asset?.tickerSymbol || "").toUpperCase();
-    const currentPrice = quotesBySymbol[ticker] || Number(asset?.buyPrice) || 0;
-    return sum + qty * currentPrice;
-  }, 0);
-
-  const totalInvestedAmount = assets.reduce((sum, asset) => {
-    const qty = Number(asset?.quantity) || 0;
-    const buyPrice = Number(asset?.buyPrice) || 0;
-    return sum + qty * buyPrice;
-  }, 0);
-
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <div className="flex items-center justify-between gap-4">
-          <h2 className="card-title">Portfolio Value</h2>
-          <div className="flex items-center gap-3">
-            <div className="flex flex-col items-end gap-1">
-              <span className="text-sm font-semibold">
-                ${totalCurrentPortfolioValue.toFixed(2)}
-              </span>
-              <span
-                className={`text-xs font-bold ${
-                  latestPct >= 0 ? "text-success" : "text-error"
-                }`}
-              >
-                {latestPct >= 0 ? "+" : ""}
-                {latestPct.toFixed(2)}%
-              </span>
-            </div>
-            <TimeRangeToggle value={range} onChange={setRange} />
-          </div>
-        </div>
-
-        <div className="mt-4 w-full overflow-hidden rounded-xl border border-base-300 bg-base-100 p-2">
-          {points.length < 1 ? (
-            <div className="flex h-65 items-center justify-center text-sm opacity-70">
-              Add investments to see portfolio growth.
-            </div>
-          ) : (
-            <PercentChangeAreaChart
-              points={points}
-              granularity={range}
-              height={260}
-              positiveColor="#10b981"
-            />
-          )}
-        </div>
-
-        <div className="mt-3 grid grid-cols-3 gap-2 text-xs">
-          <div className="rounded bg-base-300 p-2">
-            <div className="opacity-70">Invested</div>
-            <div className="font-semibold">${totalInvestedAmount.toFixed(2)}</div>
-          </div>
-          <div className="rounded bg-base-300 p-2">
-            <div className="opacity-70">Current Value</div>
-            <div className="font-semibold">${totalCurrentPortfolioValue.toFixed(2)}</div>
-          </div>
-          <div className="rounded bg-base-300 p-2">
-            <div className="opacity-70">Gain/Loss</div>
-            <div
-              className={`font-semibold ${
-                totalCurrentPortfolioValue >= totalInvestedAmount
-                  ? "text-success"
-                  : "text-error"
-              }`}
-            >
-              ${(totalCurrentPortfolioValue - totalInvestedAmount).toFixed(2)}
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/Investing/components/InvestingStartCtaCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Investing/components/InvestingStartCtaCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,36 +1,0 @@
-import React from "react";
-
-export default function InvestingStartCtaCard({
-  error,
-  onStart,
-  isSubmitting,
-}) {
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <h1 className="text-2xl font-bold">Investing</h1>
-        <p className="opacity-80">
-          You’re not tracking investments yet. Start tracking to log your assets
-          and visualize your progress.
-        </p>
-
-        {error ? (
-          <div className="alert alert-error mt-4">
-            <span>{error}</span>
-          </div>
-        ) : null}
-
-        <div className="mt-6">
-          <button
-            type="button"
-            className="btn btn-lg w-full bg-green-400! text-black! hover:bg-green-500! border-0"
-            onClick={onStart}
-            disabled={isSubmitting}
-          >
-            {isSubmitting ? "Starting…" : "Start Tracking Investments"}
-          </button>
-        </div>
-      </div>
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/Investing/components/InvestingTrackingHeader.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Investing/components/InvestingTrackingHeader.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,19 +1,0 @@
-import React from "react";
-
-export default function InvestingTrackingHeader({ onAddAsset }) {
-  return (
-    <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
-      <div>
-        <h1 className="text-2xl font-bold">Investing</h1>
-        <p className="opacity-80">Track your assets over time.</p>
-      </div>
-      <button
-        type="button"
-        className="btn bg-green-400! text-black! hover:bg-green-500! border-0"
-        onClick={onAddAsset}
-      >
-        + Add new investment
-      </button>
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/Training/NewTrainingSession.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Training/NewTrainingSession.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,264 +1,0 @@
-import React, { useEffect, useMemo, useState } from "react";
-import { useNavigate } from "react-router-dom";
-
-import api from "../../../../api/axios";
-
-import WorkoutTypeSelect from "./components/WorkoutTypeSelect.jsx";
-import CaloriesEstimate from "./components/CaloriesEstimate.jsx";
-
-const NewTrainingSession = () => {
-  const navigate = useNavigate();
-
-  const [workoutTypes, setWorkoutTypes] = useState([]);
-  const [profileWeightKg, setProfileWeightKg] = useState(null);
-  const [isLoading, setIsLoading] = useState(true);
-
-  const [type, setType] = useState("");
-  const [durationMinutes, setDurationMinutes] = useState("");
-  const [autoCalculateCalories, setAutoCalculateCalories] = useState(true);
-  const [calories, setCalories] = useState("");
-  const [date, setDate] = useState(() => new Date().toISOString().slice(0, 10));
-
-  const [error, setError] = useState("");
-  const [isSubmitting, setIsSubmitting] = useState(false);
-
-  useEffect(() => {
-    let cancelled = false;
-    (async () => {
-      try {
-        setIsLoading(true);
-        setError("");
-
-        const [typesRes, profileRes] = await Promise.all([
-          api.get("/training/workout-types"),
-          api.get("/training/profile"),
-        ]);
-
-        if (cancelled) return;
-
-        const types = Array.isArray(typesRes?.data) ? typesRes.data : [];
-        setWorkoutTypes(types);
-
-        const weight = profileRes?.data?.weight;
-        setProfileWeightKg(
-          weight === null || weight === undefined || weight === ""
-            ? null
-            : Number(weight),
-        );
-      } catch (err) {
-        if (cancelled) return;
-        setError(
-          err?.response?.data?.message ||
-            "Failed to load workout types/training profile.",
-        );
-      } finally {
-        if (!cancelled) setIsLoading(false);
-      }
-    })();
-    return () => {
-      cancelled = true;
-    };
-  }, []);
-
-  const selectedWorkout = useMemo(
-    () => workoutTypes.find((t) => t.type === type) ?? null,
-    [workoutTypes, type],
-  );
-
-  const estimatedCalories = useMemo(() => {
-    const met = selectedWorkout?.met;
-    const durationNum = durationMinutes === "" ? NaN : Number(durationMinutes);
-    const weightNum = profileWeightKg;
-    if (!Number.isFinite(Number(met))) return null;
-    if (!Number.isFinite(durationNum) || durationNum <= 0) return null;
-    if (!Number.isFinite(weightNum) || weightNum <= 0) return null;
-
-    const caloriesValue = Number(met) * weightNum * (durationNum / 60);
-    if (!Number.isFinite(caloriesValue)) return null;
-    return Math.round(caloriesValue * 100) / 100;
-  }, [durationMinutes, profileWeightKg, selectedWorkout?.met]);
-
-  const onSubmit = async (e) => {
-    e.preventDefault();
-    setError("");
-
-    if (isLoading) return;
-
-    if (!type) {
-      setError("Please select a workout type.");
-      return;
-    }
-
-    const durationNum = durationMinutes === "" ? NaN : Number(durationMinutes);
-    if (!Number.isFinite(durationNum) || durationNum < 1) {
-      setError("Duration must be at least 1 minute.");
-      return;
-    }
-
-    // Date must not be in the future (allow past or today)
-    const todayStr = new Date().toISOString().slice(0, 10);
-    if (!date || date > todayStr) {
-      setError("Date cannot be in the future.");
-      return;
-    }
-
-    const caloriesNum = calories === "" ? NaN : Number(calories);
-    if (!autoCalculateCalories) {
-      if (!Number.isFinite(caloriesNum) || caloriesNum < 0) {
-        setError("Calories must be 0 or greater.");
-        return;
-      }
-    }
-
-    try {
-      setIsSubmitting(true);
-      await api.post("/training/sessions", {
-        type,
-        durationMinutes: durationNum,
-        date,
-        autoCalculateCalories,
-        calories: autoCalculateCalories ? null : caloriesNum,
-      });
-
-      navigate("/dashboard/training/tracking", { replace: true });
-    } catch (err) {
-      setError(
-        err?.response?.data?.message || "Failed to add training session.",
-      );
-    } finally {
-      setIsSubmitting(false);
-    }
-  };
-
-  return (
-    <div className="min-h-[70vh] w-full flex items-center justify-center">
-      <form
-        onSubmit={onSubmit}
-        className="card bg-base-200 border border-base-300 w-full max-w-2xl"
-      >
-        <div className="card-body">
-          <div className="flex items-start justify-between gap-4">
-            <div>
-              <h1 className="text-2xl font-bold">Add training session</h1>
-              <p className="opacity-80 mt-1">
-                Choose a workout type, enter the duration, and we’ll save your
-                session.
-              </p>
-            </div>
-          </div>
-
-          {error ? <p className="text-error text-sm mt-2">{error}</p> : null}
-
-          {isLoading ? (
-            <p className="opacity-80 mt-2">Loading workout types…</p>
-          ) : null}
-
-          <div className="mt-4 grid grid-cols-1 gap-4 md:grid-cols-3">
-            <WorkoutTypeSelect
-              workoutTypes={workoutTypes}
-              value={type}
-              onChange={(e) => setType(e.target.value)}
-              disabled={isLoading}
-            />
-
-            <div>
-              <label className="label">Duration (minutes)</label>
-              <input
-                type="number"
-                className="input input-bordered w-full"
-                value={durationMinutes}
-                onChange={(e) => setDurationMinutes(e.target.value)}
-                min={1}
-                step={1}
-                required
-                disabled={isLoading}
-              />
-            </div>
-
-            <div>
-              <label className="label">Date</label>
-              <input
-                type="date"
-                className="input input-bordered w-full"
-                value={date}
-                onChange={(e) => setDate(e.target.value)}
-                max={new Date().toISOString().slice(0, 10)}
-                required
-                disabled={isLoading}
-              />
-              <p className="text-xs opacity-70 mt-1">Choose a past date or today (no future dates).</p>
-            </div>
-          </div>
-
-          <div className="mt-4">
-            <label className="label cursor-pointer justify-start gap-3">
-              <input
-                type="checkbox"
-                className="checkbox"
-                checked={autoCalculateCalories}
-                onChange={(e) => {
-                  const next = e.target.checked;
-                  setAutoCalculateCalories(next);
-                  if (
-                    !next &&
-                    (calories === "" || calories === null) &&
-                    estimatedCalories !== null
-                  ) {
-                    setCalories(String(estimatedCalories));
-                  }
-                }}
-              />
-              <span className="label-text">Auto-calculate calories burned</span>
-            </label>
-            <p className="text-xs opacity-70 mt-1">
-              Uses your training profile weight and the workout type.
-            </p>
-            <CaloriesEstimate
-              estimatedCalories={estimatedCalories}
-              profileWeightKg={profileWeightKg}
-            />
-          </div>
-
-          <div className="mt-2">
-            <label className="label">Calories (kcal)</label>
-            <input
-              type="number"
-              className="input input-bordered w-full"
-              value={calories}
-              onChange={(e) => setCalories(e.target.value)}
-              min={0}
-              step={1}
-              disabled={autoCalculateCalories}
-              placeholder={
-                autoCalculateCalories
-                  ? "Calculated automatically"
-                  : "Enter calories"
-              }
-              required={!autoCalculateCalories}
-            />
-          </div>
-
-          <div className="mt-6 flex flex-col gap-3 sm:flex-row sm:justify-end">
-            <button
-              type="button"
-              className="btn btn-ghost"
-              onClick={() => navigate("/dashboard/training/tracking")}
-              disabled={isSubmitting}
-            >
-              Cancel
-            </button>
-            <button
-              type="submit"
-              className="btn bg-green-400! text-black! hover:bg-green-500!"
-              disabled={isSubmitting || isLoading}
-            >
-              {isSubmitting ? "Saving…" : "Save session"}
-            </button>
-          </div>
-        </div>
-      </form>
-    </div>
-  );
-};
-
-export default NewTrainingSession;
Index: frontend/src/pages/Dashboard/pages/Training/Training.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Training/Training.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,114 +1,0 @@
-import React, { useEffect, useMemo, useState } from "react";
-import { useNavigate } from "react-router-dom";
-
-import api from "../../../../api/axios";
-
-import TrainingCenteredCard from "./components/TrainingCenteredCard.jsx";
-import TrainingStartCtaCard from "./components/TrainingStartCtaCard.jsx";
-import TrainingStartForm from "./components/TrainingStartForm.jsx";
-
-const Training = () => {
-  const navigate = useNavigate();
-
-  const [isLoading, setIsLoading] = useState(true);
-  const [isTracking, setIsTracking] = useState(false);
-  const [step, setStep] = useState("cta"); // cta | form
-  const [error, setError] = useState("");
-  const [isSubmitting, setIsSubmitting] = useState(false);
-
-  const initialForm = useMemo(() => ({ gender: "", age: "", weight: "" }), []);
-  const [form, setForm] = useState(initialForm);
-
-  useEffect(() => {
-    let isMounted = true;
-    const run = async () => {
-      setIsLoading(true);
-      setError("");
-      try {
-        const res = await api.get("/training/status");
-        const tracking = Boolean(res?.data?.tracking);
-        if (!isMounted) return;
-        setIsTracking(tracking);
-        if (tracking) {
-          navigate("/dashboard/training/tracking", { replace: true });
-        }
-      } catch (err) {
-        if (!isMounted) return;
-        const message =
-          err?.response?.data?.message || "Failed to load training status";
-        setError(message);
-      } finally {
-        if (isMounted) setIsLoading(false);
-      }
-    };
-
-    run();
-    return () => {
-      isMounted = false;
-    };
-  }, [navigate]);
-
-  const onStart = () => {
-    setError("");
-    setStep("form");
-  };
-
-  const onCancel = () => {
-    setStep("cta");
-    setForm(initialForm);
-    setError("");
-  };
-
-  const onSubmit = async (e) => {
-    e.preventDefault();
-    setError("");
-    setIsSubmitting(true);
-    try {
-      await api.post("/training/start", {
-        gender: form.gender,
-        age: form.age === "" ? null : Number(form.age),
-        weight: form.weight === "" ? null : Number(form.weight),
-      });
-
-      setIsTracking(true);
-      navigate("/dashboard/training/tracking", { replace: true });
-    } catch (err) {
-      const message =
-        err?.response?.data?.message ||
-        Object.values(err?.response?.data?.errors ?? {})[0] ||
-        "Failed to start tracking";
-      setError(message);
-    } finally {
-      setIsSubmitting(false);
-    }
-  };
-
-  if (isLoading) {
-    return <TrainingCenteredCard title="Training" message="Loading…" />;
-  }
-
-  if (isTracking) {
-    return <TrainingCenteredCard title="Training" message="Redirecting…" />;
-  }
-
-  return (
-    <div className="min-h-[70vh] w-full flex items-center justify-center">
-      <div className="w-full max-w-3xl">
-        {step === "cta" ? (
-          <TrainingStartCtaCard error={error} onStart={onStart} />
-        ) : (
-          <TrainingStartForm
-            form={form}
-            setForm={setForm}
-            onSubmit={onSubmit}
-            onCancel={onCancel}
-            error={error}
-            isSubmitting={isSubmitting}
-          />
-        )}
-      </div>
-    </div>
-  );
-};
-
-export default Training;
Index: frontend/src/pages/Dashboard/pages/Training/TrainingTracking.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Training/TrainingTracking.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,143 +1,0 @@
-import React, { useCallback, useEffect, useMemo, useState } from "react";
-import { useNavigate } from "react-router-dom";
-import api from "../../../../api/axios";
-
-import TrainingTrackingHeader from "./components/TrainingTrackingHeader.jsx";
-import TrainingProgressCard from "./components/TrainingProgressCard.jsx";
-import TrainingSessionsTable from "./components/TrainingSessionsTable.jsx";
-
-function formatDate(value) {
-  if (!value) return "—";
-  const d = new Date(value);
-  if (Number.isNaN(d.getTime())) return String(value);
-  return d.toLocaleDateString(undefined, {
-    year: "numeric",
-    month: "short",
-    day: "2-digit",
-  });
-}
-
-function titleCase(value) {
-  if (!value) return "—";
-  const s = String(value);
-  return s.charAt(0).toUpperCase() + s.slice(1);
-}
-
-export default function TrainingTracking() {
-  const navigate = useNavigate();
-  const pageSize = 5;
-  const graphPageSize = 500;
-
-  const [sessions, setSessions] = useState([]);
-  const [page, setPage] = useState(0);
-  const [hasMore, setHasMore] = useState(false);
-  const [isLoading, setIsLoading] = useState(true);
-  const [isLoadingMore, setIsLoadingMore] = useState(false);
-  const [error, setError] = useState("");
-
-  const columns = useMemo(
-    () => [
-      { key: "date", label: "Date" },
-      { key: "type", label: "Type" },
-      { key: "duration", label: "Duration (min)" },
-      { key: "calories", label: "Calories" },
-    ],
-    [],
-  );
-
-  const fetchPage = useCallback(async (nextPage, size = pageSize) => {
-    const resp = await api.get("/training/sessions", {
-      params: { page: nextPage, size },
-    });
-    const data = resp?.data ?? {};
-    const nextSessions = Array.isArray(data.sessions) ? data.sessions : [];
-    const nextHasMore = Boolean(data.hasMore);
-    return { nextSessions, nextHasMore };
-  }, []);
-
-  const fetchAllForGraph = useCallback(async () => {
-    let p = 0;
-    let hasMorePages = true;
-    const all = [];
-
-    while (hasMorePages) {
-      const { nextSessions, nextHasMore } = await fetchPage(p, graphPageSize);
-      all.push(...nextSessions);
-      hasMorePages = nextHasMore && nextSessions.length > 0;
-      p += 1;
-      // Basic safety to avoid accidental infinite loops if backend misbehaves.
-      if (p > 200) break;
-    }
-
-    return all;
-  }, [fetchPage]);
-
-  const [graphSessions, setGraphSessions] = useState([]);
-
-  useEffect(() => {
-    let cancelled = false;
-    (async () => {
-      try {
-        setIsLoading(true);
-        setError("");
-        const [tableFirstPage, allForGraph] = await Promise.all([
-          fetchPage(0, pageSize),
-          fetchAllForGraph(),
-        ]);
-        if (cancelled) return;
-        setSessions(tableFirstPage.nextSessions);
-        setHasMore(tableFirstPage.nextHasMore);
-        setGraphSessions(allForGraph);
-        setPage(0);
-      } catch (e) {
-        if (cancelled) return;
-        setError(
-          e?.response?.data?.message || "Failed to load training sessions.",
-        );
-      } finally {
-        if (!cancelled) setIsLoading(false);
-      }
-    })();
-    return () => {
-      cancelled = true;
-    };
-  }, [fetchAllForGraph, fetchPage]);
-
-  const onLoadMore = async () => {
-    if (isLoadingMore || !hasMore) return;
-    const nextPage = page + 1;
-    try {
-      setIsLoadingMore(true);
-      setError("");
-      const { nextSessions, nextHasMore } = await fetchPage(nextPage);
-      setSessions((prev) => [...prev, ...nextSessions]);
-      setHasMore(nextHasMore);
-      setPage(nextPage);
-    } catch (e) {
-      setError(e?.response?.data?.message || "Failed to load more sessions.");
-    } finally {
-      setIsLoadingMore(false);
-    }
-  };
-
-  return (
-    <div className="space-y-6">
-      <TrainingTrackingHeader
-        onAddSession={() => navigate("/dashboard/training/sessions/new")}
-      />
-      <TrainingProgressCard sessions={graphSessions} />
-      <TrainingSessionsTable
-        columns={columns}
-        sessions={sessions}
-        isLoading={isLoading}
-        error={error}
-        isLoadingMore={isLoadingMore}
-        hasMore={hasMore}
-        onLoadMore={onLoadMore}
-        pageSize={pageSize}
-        formatDate={formatDate}
-        titleCase={titleCase}
-      />
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/Training/components/CaloriesEstimate.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Training/components/CaloriesEstimate.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,21 +1,0 @@
-import React from "react";
-
-const CaloriesEstimate = ({ estimatedCalories, profileWeightKg }) => {
-  return (
-    <div className="mt-2">
-      {estimatedCalories === null ? (
-        <p className="text-xs opacity-70">
-          Estimated calories: —
-          {profileWeightKg === null ? " (missing profile weight)" : ""}
-        </p>
-      ) : (
-        <p className="text-xs opacity-80">
-          Estimated calories:{" "}
-          <span className="font-semibold">{estimatedCalories}</span> kcal
-        </p>
-      )}
-    </div>
-  );
-};
-
-export default CaloriesEstimate;
Index: frontend/src/pages/Dashboard/pages/Training/components/TrainingCenteredCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Training/components/TrainingCenteredCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,17 +1,0 @@
-import React from "react";
-
-const TrainingCenteredCard = ({ title, message, children }) => {
-  return (
-    <div className="min-h-[60vh] w-full flex items-center justify-center">
-      <div className="card bg-base-200 border border-base-300 w-full max-w-xl">
-        <div className="card-body items-center text-center">
-          {title ? <h1 className="text-3xl font-bold">{title}</h1> : null}
-          {message ? <p className="opacity-80">{message}</p> : null}
-          {children}
-        </div>
-      </div>
-    </div>
-  );
-};
-
-export default TrainingCenteredCard;
Index: frontend/src/pages/Dashboard/pages/Training/components/TrainingProgressCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Training/components/TrainingProgressCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,60 +1,0 @@
-import React, { useMemo, useState } from "react";
-
-import TimeRangeToggle from "../../../../../components/graphs/TimeRangeToggle.jsx";
-import PercentChangeAreaChart from "../../../../../components/graphs/PercentChangeAreaChart.jsx";
-import { percentChangeSeries, sumByTimeBucket } from "../../../../../utils/timeSeries.js";
-
-const TrainingProgressCard = ({ sessions }) => {
-  const [range, setRange] = useState("weekly");
-
-  const points = useMemo(() => {
-    const buckets = sumByTimeBucket(
-      sessions,
-      range,
-      (s) => s.date,
-      (s) => s.calories
-    );
-    return percentChangeSeries(buckets);
-  }, [range, sessions]);
-
-  const latest = points?.length ? points[points.length - 1] : null;
-  const latestPct = latest ? Number(latest.value ?? 0) : 0;
-  const latestBase = latest ? Number(latest.base ?? 0) : 0;
-
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <div className="flex items-center justify-between gap-4">
-          <h2 className="card-title">Progress</h2>
-          <div className="flex items-center gap-3">
-            <span className="badge badge-ghost">
-              {latestPct >= 0 ? "+" : ""}
-              {latestPct.toFixed(1)}% (last)
-            </span>
-            <TimeRangeToggle value={range} onChange={setRange} />
-          </div>
-        </div>
-
-        <div className="mt-4 w-full overflow-hidden rounded-xl border border-base-300 bg-base-100 p-2">
-          {points.length < 2 ? (
-            <div className="flex h-65 items-center justify-center text-sm opacity-70">
-              Add at least 2 sessions to see % change.
-            </div>
-          ) : (
-            <PercentChangeAreaChart
-              points={points}
-              granularity={range}
-              height={260}
-            />
-          )}
-        </div>
-
-        <div className="mt-2 text-xs opacity-70">
-          Showing percentage change in calories burned per {range} bucket. Latest bucket total: {Math.round(latestBase)}.
-        </div>
-      </div>
-    </div>
-  );
-};
-
-export default TrainingProgressCard;
Index: frontend/src/pages/Dashboard/pages/Training/components/TrainingSessionsTable.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Training/components/TrainingSessionsTable.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,81 +1,0 @@
-import React from "react";
-
-const TrainingSessionsTable = ({
-  columns,
-  sessions,
-  isLoading,
-  error,
-  isLoadingMore,
-  hasMore,
-  onLoadMore,
-  pageSize,
-  formatDate,
-  titleCase,
-}) => {
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <div className="flex items-center justify-between gap-4">
-          <h2 className="card-title">Recent sessions</h2>
-          <span className="badge badge-ghost">Showing up to {pageSize}</span>
-        </div>
-
-        {error ? <p className="text-error text-sm mt-2">{error}</p> : null}
-
-        <div className="mt-4 overflow-x-auto">
-          <table className="table table-zebra w-full">
-            <thead>
-              <tr>
-                {columns.map((c) => (
-                  <th key={c.key}>{c.label}</th>
-                ))}
-              </tr>
-            </thead>
-            <tbody>
-              {isLoading ? (
-                <tr>
-                  <td colSpan={columns.length}>
-                    <span className="opacity-80">Loading…</span>
-                  </td>
-                </tr>
-              ) : sessions.length === 0 ? (
-                <tr>
-                  <td colSpan={columns.length}>
-                    <span className="opacity-80">No sessions yet.</span>
-                  </td>
-                </tr>
-              ) : (
-                sessions.map((s) => (
-                  <tr
-                    key={
-                      s.trainingId ??
-                      `${s.date}-${s.type}-${s.duration}-${s.calories}`
-                    }
-                  >
-                    <td>{formatDate(s.date)}</td>
-                    <td>{titleCase(s.type)}</td>
-                    <td>{s.duration ?? "—"}</td>
-                    <td>{s.calories ?? "—"}</td>
-                  </tr>
-                ))
-              )}
-            </tbody>
-          </table>
-        </div>
-
-        <div className="mt-4 flex items-center justify-center">
-          <button
-            type="button"
-            className="btn btn-outline"
-            onClick={onLoadMore}
-            disabled={isLoading || isLoadingMore || !hasMore}
-          >
-            {isLoadingMore ? "Loading…" : hasMore ? "Load more" : "No more"}
-          </button>
-        </div>
-      </div>
-    </div>
-  );
-};
-
-export default TrainingSessionsTable;
Index: frontend/src/pages/Dashboard/pages/Training/components/TrainingStartCtaCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Training/components/TrainingStartCtaCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,26 +1,0 @@
-import React from "react";
-
-const TrainingStartCtaCard = ({ error, onStart }) => {
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body items-center text-center">
-        <h1 className="text-4xl font-bold">You are not tracking training</h1>
-        <p className="opacity-80 max-w-xl">
-          Start tracking to log sessions, see trends, and build consistency.
-        </p>
-
-        {error ? <p className="text-error text-sm mt-2">{error}</p> : null}
-
-        <button
-          type="button"
-          className="btn btn-lg mt-6 w-full max-w-md bg-green-400! text-black! hover:bg-green-500!"
-          onClick={onStart}
-        >
-          Start Tracking
-        </button>
-      </div>
-    </div>
-  );
-};
-
-export default TrainingStartCtaCard;
Index: frontend/src/pages/Dashboard/pages/Training/components/TrainingStartForm.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Training/components/TrainingStartForm.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,94 +1,0 @@
-import React from "react";
-
-const TrainingStartForm = ({
-  form,
-  setForm,
-  onSubmit,
-  onCancel,
-  error,
-  isSubmitting,
-}) => {
-  return (
-    <form
-      onSubmit={onSubmit}
-      className="card bg-base-200 border border-base-300"
-    >
-      <div className="card-body items-center text-center">
-        <h1 className="text-3xl font-bold">Start tracking training</h1>
-        <p className="opacity-80 max-w-xl">
-          Fill in a few details to set up your training profile.
-        </p>
-
-        {error ? <p className="text-error text-sm mt-2">{error}</p> : null}
-
-        <div className="mt-4 grid w-full grid-cols-1 gap-4 md:grid-cols-3">
-          <div>
-            <label className="label">Gender</label>
-            <select
-              className="select select-bordered w-full"
-              value={form.gender}
-              onChange={(e) =>
-                setForm((p) => ({ ...p, gender: e.target.value }))
-              }
-              required
-            >
-              <option value="" disabled>
-                Select…
-              </option>
-              <option value="male">Male</option>
-              <option value="female">Female</option>
-              <option value="other">Other</option>
-            </select>
-          </div>
-
-          <div>
-            <label className="label">Age</label>
-            <input
-              type="number"
-              className="input input-bordered w-full"
-              value={form.age}
-              onChange={(e) => setForm((p) => ({ ...p, age: e.target.value }))}
-              min={1}
-              max={120}
-              required
-            />
-          </div>
-
-          <div>
-            <label className="label">Weight (kg)</label>
-            <input
-              type="number"
-              className="input input-bordered w-full"
-              value={form.weight}
-              onChange={(e) =>
-                setForm((p) => ({ ...p, weight: e.target.value }))
-              }
-              min={1}
-              step="0.1"
-              required
-            />
-          </div>
-        </div>
-
-        <div className="mt-6 flex w-full flex-col items-center gap-3 sm:flex-row sm:justify-center">
-          <button
-            className="btn btn-lg w-full sm:w-auto bg-green-400! text-black! hover:bg-green-500!"
-            type="submit"
-            disabled={isSubmitting}
-          >
-            {isSubmitting ? "Starting…" : "Start Tracking"}
-          </button>
-          <button
-            type="button"
-            className="btn btn-ghost btn-lg w-full sm:w-auto"
-            onClick={onCancel}
-          >
-            Cancel
-          </button>
-        </div>
-      </div>
-    </form>
-  );
-};
-
-export default TrainingStartForm;
Index: frontend/src/pages/Dashboard/pages/Training/components/TrainingTrackingHeader.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Training/components/TrainingTrackingHeader.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,22 +1,0 @@
-import React from "react";
-
-const TrainingTrackingHeader = ({ onAddSession }) => {
-  return (
-    <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
-      <div>
-        <h1 className="text-2xl font-bold">Training</h1>
-        <p className="opacity-80 mt-1">Your recent sessions and progress.</p>
-      </div>
-
-      <button
-        type="button"
-        className="btn bg-green-400! text-black! hover:bg-green-500!"
-        onClick={onAddSession}
-      >
-        + Add new training session
-      </button>
-    </div>
-  );
-};
-
-export default TrainingTrackingHeader;
Index: frontend/src/pages/Dashboard/pages/Training/components/WorkoutTypeSelect.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Training/components/WorkoutTypeSelect.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,27 +1,0 @@
-import React from "react";
-
-const WorkoutTypeSelect = ({ workoutTypes, value, onChange, disabled }) => {
-  return (
-    <div>
-      <label className="label">Workout type</label>
-      <select
-        className="select select-bordered w-full"
-        value={value}
-        onChange={onChange}
-        required
-        disabled={disabled}
-      >
-        <option value="" disabled>
-          Select…
-        </option>
-        {workoutTypes.map((t) => (
-          <option key={t.type} value={t.type}>
-            {t.label ?? t.type}
-          </option>
-        ))}
-      </select>
-    </div>
-  );
-};
-
-export default WorkoutTypeSelect;
Index: frontend/src/pages/Dashboard/pages/Weight/NewWeightIntake.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Weight/NewWeightIntake.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,166 +1,0 @@
-import React, { useEffect, useMemo, useState } from "react";
-import { useNavigate } from "react-router-dom";
-
-import api from "../../../../api/axios";
-
-export default function NewWeightIntake() {
-  const navigate = useNavigate();
-  const [goalCalories, setGoalCalories] = useState(null);
-  const [todayTrainingInfo, setTodayTrainingInfo] = useState(null);
-  const [isLoading, setIsLoading] = useState(true);
-  const [calories, setCalories] = useState("");
-  const [error, setError] = useState("");
-  const [isSubmitting, setIsSubmitting] = useState(false);
-
-  const todayLabel = useMemo(
-    () =>
-      new Date().toLocaleDateString(undefined, {
-        year: "numeric",
-        month: "short",
-        day: "2-digit",
-      }),
-    [],
-  );
-
-  const adjustedGoalCalories = useMemo(() => {
-    if (!goalCalories || !todayTrainingInfo) return null;
-    const goal = Number(goalCalories);
-    const burned = Number(todayTrainingInfo.totalBurnedCalories) || 0;
-    if (!Number.isFinite(goal)) return null;
-    return goal + burned;
-  }, [goalCalories, todayTrainingInfo]);
-
-  useEffect(() => {
-    let cancelled = false;
-    (async () => {
-      try {
-        setIsLoading(true);
-        setError("");
-        const [statusRes, profileRes, trainingRes] = await Promise.all([
-          api.get("/weight/status"),
-          api.get("/weight/profile"),
-          api.get("/weight/today-training"),
-        ]);
-        if (cancelled) return;
-        if (!statusRes?.data?.tracking) {
-          navigate("/dashboard/weight", { replace: true });
-          return;
-        }
-        setGoalCalories(profileRes?.data?.goalCalories ?? null);
-        setTodayTrainingInfo(trainingRes?.data ?? null);
-      } catch (err) {
-        if (cancelled) return;
-        const message = err?.response?.data?.message || "Failed to load weight profile.";
-        if (String(message).toLowerCase().includes("not enabled")) {
-          navigate("/dashboard/weight", { replace: true });
-          return;
-        }
-        setError(message);
-      } finally {
-        if (!cancelled) setIsLoading(false);
-      }
-    })();
-    return () => {
-      cancelled = true;
-    };
-  }, [navigate]);
-
-  const onSubmit = async (e) => {
-    e.preventDefault();
-    setError("");
-
-    const caloriesNum = calories === "" ? NaN : Number(calories);
-    if (!Number.isFinite(caloriesNum) || caloriesNum < 0) {
-      setError("Calories must be 0 or greater.");
-      return;
-    }
-
-    try {
-      setIsSubmitting(true);
-      await api.post("/weight/intakes", {
-        calories: caloriesNum,
-      });
-      navigate("/dashboard/weight/tracking", { replace: true });
-    } catch (err) {
-      setError(err?.response?.data?.message || "Failed to add today's intake.");
-    } finally {
-      setIsSubmitting(false);
-    }
-  };
-
-  return (
-    <div className="min-h-[70vh] w-full flex items-center justify-center">
-      <div className="w-full max-w-2xl">
-        <div className="card bg-base-200 border border-base-300">
-          <div className="card-body">
-            <h1 className="text-2xl font-bold">Add today's intake</h1>
-            <p className="opacity-80">
-              Log the calories you consumed today. Only one intake can be stored per day.
-            </p>
-
-            <div className="mt-2 text-sm opacity-70">Today: {todayLabel}</div>
-            <div className="mt-1 text-sm opacity-70">
-              Goal calories: {goalCalories === null ? "—" : `${goalCalories} kcal`}
-            </div>
-            {todayTrainingInfo?.trainedToday && (
-              <>
-                <div className="mt-2 text-sm opacity-70">
-                  Burned during training: {todayTrainingInfo.totalBurnedCalories} kcal
-                </div>
-                <div className="mt-1 text-sm font-semibold text-green-400">
-                  Adjusted goal for today: {adjustedGoalCalories === null ? "—" : `${adjustedGoalCalories} kcal`}
-                </div>
-              </>
-            )}
-
-            {error ? (
-              <div className="alert alert-error mt-4">
-                <span>{error}</span>
-              </div>
-            ) : null}
-
-            {isLoading ? <p className="opacity-80 mt-4">Loading…</p> : null}
-
-            <form onSubmit={onSubmit} className="mt-6 space-y-4">
-              <div>
-                <label className="label">
-                  <span className="label-text">Calories consumed</span>
-                </label>
-                <input
-                  type="number"
-                  step="0.1"
-                  min="0"
-                  className="input input-bordered w-full"
-                  placeholder="2200"
-                  value={calories}
-                  onChange={(e) => setCalories(e.target.value)}
-                  required
-                  disabled={isLoading}
-                />
-              </div>
-
-              <div className="flex flex-col gap-3 sm:flex-row sm:justify-end">
-                <button
-                  type="button"
-                  className="btn btn-ghost"
-                  onClick={() => navigate("/dashboard/weight/tracking")}
-                  disabled={isSubmitting}
-                >
-                  Cancel
-                </button>
-                <button
-                  type="submit"
-                  className="btn bg-green-400! text-black! hover:bg-green-500! border-0"
-                  disabled={isSubmitting || isLoading}
-                >
-                  {isSubmitting ? "Saving…" : "Save intake"}
-                </button>
-              </div>
-            </form>
-          </div>
-        </div>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Weight/Weight.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Weight/Weight.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,168 +1,0 @@
-import React, { useEffect, useMemo, useState } from "react";
-import { useNavigate } from "react-router-dom";
-
-import api from "../../../../api/axios";
-
-import WeightCenteredCard from "./components/WeightCenteredCard.jsx";
-import WeightStartCtaCard from "./components/WeightStartCtaCard.jsx";
-import WeightStartForm from "./components/WeightStartForm.jsx";
-
-function estimateGoalTimeWeeks(currentWeight, goalWeight) {
-  const current = Number(currentWeight);
-  const goal = Number(goalWeight);
-  if (!Number.isFinite(current) || !Number.isFinite(goal) || current <= 0 || goal <= 0) {
-    return null;
-  }
-  const difference = Math.abs(goal - current);
-  return Math.round((difference / 0.5) * 100) / 100;
-}
-
-function estimateGoalCalories(currentWeight, height, goalWeight) {
-  const current = Number(currentWeight);
-  const h = Number(height);
-  const goal = Number(goalWeight);
-  if (!Number.isFinite(current) || !Number.isFinite(h) || !Number.isFinite(goal)) {
-    return null;
-  }
-
-  const maintenance = current * 10 + h * 6.25 + 50;
-  if (goal < current) return Math.max(0, Math.round((maintenance - 500) * 100) / 100);
-  if (goal > current) return Math.round((maintenance + 300) * 100) / 100;
-  return Math.round(maintenance * 100) / 100;
-}
-
-const Weight = () => {
-  const navigate = useNavigate();
-
-  const [isLoading, setIsLoading] = useState(true);
-  const [isTracking, setIsTracking] = useState(false);
-  const [step, setStep] = useState("cta");
-  const [error, setError] = useState("");
-  const [isSubmitting, setIsSubmitting] = useState(false);
-  const [autoCalculateTargets, setAutoCalculateTargets] = useState(true);
-
-  const initialForm = useMemo(
-    () => ({
-      weight: "",
-      height: "",
-      goalWeight: "",
-      goalTimeWeeks: "",
-      goalCalories: "",
-    }),
-    [],
-  );
-  const [form, setForm] = useState(initialForm);
-
-  const estimatedGoalTimeWeeks = useMemo(
-    () => estimateGoalTimeWeeks(form.weight, form.goalWeight),
-    [form.weight, form.goalWeight],
-  );
-  const estimatedGoalCalories = useMemo(
-    () => estimateGoalCalories(form.weight, form.height, form.goalWeight),
-    [form.weight, form.height, form.goalWeight],
-  );
-
-  useEffect(() => {
-    let isMounted = true;
-    const run = async () => {
-      setIsLoading(true);
-      setError("");
-      try {
-        const res = await api.get("/weight/status");
-        const tracking = Boolean(res?.data?.tracking);
-        if (!isMounted) return;
-        setIsTracking(tracking);
-        if (tracking) {
-          navigate("/dashboard/weight/tracking", { replace: true });
-        }
-      } catch (err) {
-        if (!isMounted) return;
-        const message = err?.response?.data?.message || "Failed to load weight status";
-        setError(message);
-      } finally {
-        if (isMounted) setIsLoading(false);
-      }
-    };
-
-    run();
-    return () => {
-      isMounted = false;
-    };
-  }, [navigate]);
-
-  const onStart = () => {
-    setError("");
-    setStep("form");
-  };
-
-  const onCancel = () => {
-    setStep("cta");
-    setForm(initialForm);
-    setAutoCalculateTargets(true);
-    setError("");
-  };
-
-  const onSubmit = async (e) => {
-    e.preventDefault();
-    setError("");
-    setIsSubmitting(true);
-
-    try {
-      await api.post("/weight/start", {
-        weight: form.weight === "" ? null : Number(form.weight),
-        height: form.height === "" ? null : Number(form.height),
-        goalWeight: form.goalWeight === "" ? null : Number(form.goalWeight),
-        goalCalories: autoCalculateTargets
-          ? null
-          : form.goalCalories === ""
-            ? null
-            : Number(form.goalCalories),
-        autoCalculateTargets,
-      });
-
-      setIsTracking(true);
-      navigate("/dashboard/weight/tracking", { replace: true });
-    } catch (err) {
-      const message =
-        err?.response?.data?.message ||
-        Object.values(err?.response?.data?.errors ?? {})[0] ||
-        "Failed to start weight tracking";
-      setError(message);
-    } finally {
-      setIsSubmitting(false);
-    }
-  };
-
-  if (isLoading) {
-    return <WeightCenteredCard title="Weight" message="Loading…" />;
-  }
-
-  if (isTracking) {
-    return <WeightCenteredCard title="Weight" message="Redirecting…" />;
-  }
-
-  return (
-    <div className="min-h-[70vh] w-full flex items-center justify-center">
-      <div className="w-full max-w-4xl">
-        {step === "cta" ? (
-          <WeightStartCtaCard error={error} onStart={onStart} isSubmitting={isSubmitting} />
-        ) : (
-          <WeightStartForm
-            form={form}
-            setForm={setForm}
-            onSubmit={onSubmit}
-            onCancel={onCancel}
-            error={error}
-            isSubmitting={isSubmitting}
-            autoCalculateTargets={autoCalculateTargets}
-            setAutoCalculateTargets={setAutoCalculateTargets}
-            estimatedGoalTimeWeeks={estimatedGoalTimeWeeks}
-            estimatedGoalCalories={estimatedGoalCalories}
-          />
-        )}
-      </div>
-    </div>
-  );
-};
-
-export default Weight;
Index: frontend/src/pages/Dashboard/pages/Weight/WeightTracking.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Weight/WeightTracking.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,263 +1,0 @@
-import React, { useCallback, useEffect, useMemo, useState } from "react";
-import { useNavigate } from "react-router-dom";
-
-import api from "../../../../api/axios";
-
-import WeightProgressCard from "./components/WeightProgressCard.jsx";
-import WeightTrackingHeader from "./components/WeightTrackingHeader.jsx";
-import WeightSummaryCard from "./components/WeightSummaryCard.jsx";
-import WeightIntakesTable from "./components/WeightIntakesTable.jsx";
-import WeightStartForm from "./components/WeightStartForm.jsx";
-
-function estimateGoalTimeWeeks(currentWeight, goalWeight) {
-  const current = Number(currentWeight);
-  const goal = Number(goalWeight);
-  if (!Number.isFinite(current) || !Number.isFinite(goal) || current <= 0 || goal <= 0) {
-    return null;
-  }
-  const difference = Math.abs(goal - current);
-  return Math.round((difference / 0.5) * 100) / 100;
-}
-
-function estimateGoalCalories(currentWeight, height, goalWeight) {
-  const current = Number(currentWeight);
-  const h = Number(height);
-  const goal = Number(goalWeight);
-  if (!Number.isFinite(current) || !Number.isFinite(h) || !Number.isFinite(goal)) {
-    return null;
-  }
-  const maintenance = current * 10 + h * 6.25 + 50;
-  if (goal < current) return Math.max(0, Math.round((maintenance - 500) * 100) / 100);
-  if (goal > current) return Math.round((maintenance + 300) * 100) / 100;
-  return Math.round(maintenance * 100) / 100;
-}
-
-export default function WeightTracking() {
-  const navigate = useNavigate();
-  const pageSize = 5;
-  const graphPageSize = 500;
-
-  const [profile, setProfile] = useState(null);
-  const [intakes, setIntakes] = useState([]);
-  const [page, setPage] = useState(0);
-  const [hasMore, setHasMore] = useState(false);
-  const [hasTodayIntake, setHasTodayIntake] = useState(false);
-  const [todayTrainingInfo, setTodayTrainingInfo] = useState(null);
-  const [isLoading, setIsLoading] = useState(true);
-  const [isLoadingMore, setIsLoadingMore] = useState(false);
-  const [error, setError] = useState("");
-  const [isEditingProfile, setIsEditingProfile] = useState(false);
-  const [editForm, setEditForm] = useState({ weight: "", height: "", goalWeight: "", goalCalories: "" });
-  const [editAutoCalculate, setEditAutoCalculate] = useState(true);
-  const [editError, setEditError] = useState("");
-  const [isSubmittingEdit, setIsSubmittingEdit] = useState(false);
-
-  const fetchPage = useCallback(async (nextPage, size = pageSize) => {
-    const [profileRes, intakesRes, trainingRes] = await Promise.all([
-      api.get("/weight/profile"),
-      api.get("/weight/intakes", {
-        params: { page: nextPage, size },
-      }),
-      api.get("/weight/today-training"),
-    ]);
-
-    return {
-      profileData: profileRes?.data ?? null,
-      intakesData: intakesRes?.data ?? {},
-      trainingData: trainingRes?.data ?? null,
-    };
-  }, []);
-
-  const [graphIntakes, setGraphIntakes] = useState([]);
-
-  const fetchAllIntakesForGraph = useCallback(async () => {
-    let p = 0;
-    let hasMorePages = true;
-    const all = [];
-
-    while (hasMorePages) {
-      const { intakesData } = await fetchPage(p, graphPageSize);
-      const chunk = Array.isArray(intakesData.intakes) ? intakesData.intakes : [];
-      all.push(...chunk);
-      hasMorePages = Boolean(intakesData.hasMore) && chunk.length > 0;
-      p += 1;
-      if (p > 200) break;
-    }
-
-    return all;
-  }, [fetchPage]);
-
-  useEffect(() => {
-    let cancelled = false;
-    (async () => {
-      try {
-        setIsLoading(true);
-        setError("");
-        const [{ profileData, intakesData, trainingData }, allIntakes] = await Promise.all([
-          fetchPage(0, pageSize),
-          fetchAllIntakesForGraph(),
-        ]);
-        if (cancelled) return;
-        setProfile(profileData);
-        setIntakes(Array.isArray(intakesData.intakes) ? intakesData.intakes : []);
-        setGraphIntakes(allIntakes);
-        setHasMore(Boolean(intakesData.hasMore));
-        setHasTodayIntake(Boolean(intakesData.hasTodayIntake));
-        setTodayTrainingInfo(trainingData);
-        setPage(0);
-      } catch (e) {
-        if (cancelled) return;
-        const message =
-          e?.response?.data?.message || "Failed to load weight tracking data.";
-        if (String(message).toLowerCase().includes("not enabled")) {
-          navigate("/dashboard/weight", { replace: true });
-          return;
-        }
-        setError(message);
-      } finally {
-        if (!cancelled) setIsLoading(false);
-      }
-    })();
-
-    return () => {
-      cancelled = true;
-    };
-  }, [fetchAllIntakesForGraph, fetchPage, navigate]);
-
-  const onLoadMore = async () => {
-    if (isLoadingMore || !hasMore) return;
-    const nextPage = page + 1;
-    try {
-      setIsLoadingMore(true);
-      setError("");
-      const { intakesData } = await fetchPage(nextPage);
-      setIntakes((prev) => [...prev, ...(Array.isArray(intakesData.intakes) ? intakesData.intakes : [])]);
-      setHasMore(Boolean(intakesData.hasMore));
-      setHasTodayIntake(Boolean(intakesData.hasTodayIntake));
-      setPage(nextPage);
-    } catch (e) {
-      setError(e?.response?.data?.message || "Failed to load more intakes.");
-    } finally {
-      setIsLoadingMore(false);
-    }
-  };
-
-  const goalCalories = useMemo(() => profile?.goalCalories ?? null, [profile]);
-
-  const editEstimatedGoalCalories = useMemo(
-    () => estimateGoalCalories(editForm.weight, editForm.height, editForm.goalWeight),
-    [editForm.weight, editForm.height, editForm.goalWeight],
-  );
-
-  if (isLoading && !profile) {
-    return <div className="opacity-80">Loading…</div>;
-  }
-
-  const onOpenEditProfile = () => {
-    setEditForm({
-      weight: String(profile?.weight ?? ""),
-      height: String(profile?.height ?? ""),
-      goalWeight: String(profile?.goalWeight ?? ""),
-      goalCalories: String(profile?.goalCalories ?? ""),
-    });
-    setEditAutoCalculate(false);
-    setEditError("");
-    setIsEditingProfile(true);
-  };
-
-  const onCancelEdit = () => {
-    setIsEditingProfile(false);
-    setEditForm({ weight: "", height: "", goalWeight: "", goalCalories: "" });
-    setEditError("");
-  };
-
-  const onSubmitEdit = async (e) => {
-    e.preventDefault();
-    setEditError("");
-    setIsSubmittingEdit(true);
-    try {
-      const res = await api.put("/weight/profile", {
-        weight: editForm.weight === "" ? null : Number(editForm.weight),
-        height: editForm.height === "" ? null : Number(editForm.height),
-        goalWeight: editForm.goalWeight === "" ? null : Number(editForm.goalWeight),
-        goalCalories: editForm.goalCalories === "" ? null : Number(editForm.goalCalories),
-        autoCalculateTargets: editAutoCalculate,
-      });
-      setProfile(res.data);
-      setIsEditingProfile(false);
-    } catch (err) {
-      setEditError(
-        err?.response?.data?.message ||
-        Object.values(err?.response?.data?.errors ?? {})[0] ||
-        "Failed to update profile"
-      );
-    } finally {
-      setIsSubmittingEdit(false);
-    }
-  };
-
-  return (
-    <div className="space-y-6">
-      <WeightSummaryCard 
-        profile={profile} 
-        onEdit={onOpenEditProfile}
-        todayTrainingInfo={todayTrainingInfo}
-      />
-
-      {isEditingProfile ? (
-        <div className="modal modal-open" role="dialog" aria-modal="true">
-          <div className="modal-box max-w-2xl">
-            <WeightStartForm
-              form={editForm}
-              setForm={setEditForm}
-              onSubmit={onSubmitEdit}
-              onCancel={onCancelEdit}
-              error={editError}
-              isSubmitting={isSubmittingEdit}
-              autoCalculateTargets={editAutoCalculate}
-              setAutoCalculateTargets={setEditAutoCalculate}
-              estimatedGoalTimeWeeks={estimateGoalTimeWeeks(editForm.weight, editForm.goalWeight)}
-              estimatedGoalCalories={editEstimatedGoalCalories}
-            />
-            <button
-              type="button"
-              className="modal-backdrop"
-              aria-label="Close"
-              onClick={onCancelEdit}
-              disabled={isSubmittingEdit}
-            />
-          </div>
-        </div>
-      ) : null}
-
-      <WeightTrackingHeader
-        onAddIntake={() => navigate("/dashboard/weight/intakes/new")}
-        isTodayLogged={hasTodayIntake}
-      />
-
-      <WeightProgressCard
-        intakes={graphIntakes}
-        goalCalories={goalCalories}
-        isBulking={
-          Number.isFinite(Number(profile?.weight)) && Number.isFinite(Number(profile?.goalWeight))
-            ? Number(profile.goalWeight) > Number(profile.weight)
-            : null
-        }
-      />
-
-      <WeightIntakesTable
-        intakes={intakes}
-        isLoading={isLoading}
-        error={error}
-        isLoadingMore={isLoadingMore}
-        hasMore={hasMore}
-        onLoadMore={onLoadMore}
-        pageSize={pageSize}
-        goalCalories={goalCalories}
-        onAddIntake={() => navigate("/dashboard/weight/intakes/new")}
-        currentWeight={profile?.weight}
-        goalWeight={profile?.goalWeight}
-      />
-    </div>
-  );
-}
Index: frontend/src/pages/Dashboard/pages/Weight/components/WeightCenteredCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Weight/components/WeightCenteredCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,15 +1,0 @@
-import React from "react";
-
-export default function WeightCenteredCard({ title, message }) {
-  return (
-    <div className="min-h-[70vh] w-full flex items-center justify-center">
-      <div className="card bg-base-200 border border-base-300 w-full max-w-2xl">
-        <div className="card-body items-center text-center">
-          <h1 className="text-3xl font-bold">{title}</h1>
-          <p className="opacity-80">{message}</p>
-        </div>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Weight/components/WeightIntakesTable.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Weight/components/WeightIntakesTable.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,152 +1,0 @@
-import React, { useMemo } from "react";
-
-function formatDate(value) {
-  if (!value) return "—";
-  const d = new Date(value);
-  if (Number.isNaN(d.getTime())) return String(value);
-  return d.toLocaleDateString(undefined, {
-    year: "numeric",
-    month: "short",
-    day: "2-digit",
-  });
-}
-
-function formatNumber(value) {
-  if (value === null || value === undefined || value === "") return "—";
-  const num = Number(value);
-  if (Number.isNaN(num)) return String(value);
-  return Number.isInteger(num) ? String(num) : num.toFixed(2);
-}
-
-export default function WeightIntakesTable({
-  intakes,
-  isLoading,
-  error,
-  isLoadingMore,
-  hasMore,
-  onLoadMore,
-  pageSize,
-  goalCalories,
-  onAddIntake,
-  currentWeight,
-  goalWeight,
-}) {
-  const columns = useMemo(
-    () => [
-      { key: "date", label: "Date" },
-      { key: "calories", label: "Calories" },
-      { key: "delta", label: "Vs goal" },
-    ],
-    [],
-  );
-
-  // Determine if user is bulking (goal > current) or cutting (goal < current)
-  const isBulking = useMemo(() => {
-    const current = Number(currentWeight);
-    const goal = Number(goalWeight);
-    if (!Number.isFinite(current) || !Number.isFinite(goal)) {
-      return null; // Can't determine
-    }
-    return goal > current;
-  }, [currentWeight, goalWeight]);
-
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <div className="flex items-center justify-between gap-4">
-          <h2 className="text-lg font-semibold">Daily intakes</h2>
-          <span className="text-sm opacity-70">Showing {pageSize} per page</span>
-        </div>
-
-        {error ? (
-          <div className="alert alert-error mt-4">
-            <span>{error}</span>
-          </div>
-        ) : null}
-
-        <div className="mt-4 overflow-x-auto">
-          <table className="table">
-            <thead>
-              <tr>
-                {columns.map((c) => (
-                  <th key={c.key}>{c.label}</th>
-                ))}
-              </tr>
-            </thead>
-            <tbody>
-              {isLoading ? (
-                <tr>
-                  <td colSpan={columns.length} className="opacity-70">
-                    Loading…
-                  </td>
-                </tr>
-              ) : intakes.length === 0 ? (
-                <tr>
-                  <td colSpan={columns.length} className="py-10">
-                    <div className="flex flex-col items-center text-center gap-3">
-                      <p className="opacity-80">No daily intakes yet.</p>
-                      <button
-                        type="button"
-                        className="btn bg-green-400! text-black! hover:bg-green-500! border-0"
-                        onClick={onAddIntake}
-                      >
-                        Add your first daily intake
-                      </button>
-                    </div>
-                  </td>
-                </tr>
-              ) : (
-                intakes.map((intake) => {
-                  const calories = Number(intake?.calories);
-                  const goal = Number(goalCalories);
-                  const burned = Number(intake?.burnedCalories) || 0;
-                  // If user trained that day, add burned calories to goal
-                  const adjustedGoal = intake?.trainedThatDay ? goal + burned : goal;
-                  const hasGoal = Number.isFinite(adjustedGoal);
-                  const delta = hasGoal && Number.isFinite(calories) ? calories - adjustedGoal : null;
-                  const deltaLabel =
-                    delta === null
-                      ? "—"
-                      : `${delta > 0 ? "+" : ""}${formatNumber(delta)} kcal`;
-                  
-                  // Determine color based on bulking vs cutting
-                  let deltaClass = "opacity-80";
-                  if (delta !== null) {
-                    if (isBulking === true) {
-                      // Bulking: eating MORE is good (green), eating LESS is bad (red)
-                      deltaClass = delta > 0 ? "text-green-400 font-semibold" : delta < 0 ? "text-red-400 font-semibold" : "opacity-80";
-                    } else if (isBulking === false) {
-                      // Cutting: eating LESS is good (green), eating MORE is bad (red)
-                      deltaClass = delta > 0 ? "text-red-400 font-semibold" : delta < 0 ? "text-green-400 font-semibold" : "opacity-80";
-                    }
-                  }
-
-                  return (
-                    <tr key={intake.dailyIntakeId ?? `${intake.date}-${intake.calories}`}>
-                      <td>{formatDate(intake.date)}</td>
-                      <td>{formatNumber(intake.calories)} kcal</td>
-                      <td className={deltaClass}>{deltaLabel}</td>
-                    </tr>
-                  );
-                })
-              )}
-            </tbody>
-          </table>
-        </div>
-
-        <div className="mt-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
-
-          <button
-            type="button"
-            className="btn btn-outline"
-            onClick={onLoadMore}
-            disabled={isLoading || isLoadingMore || !hasMore}
-          >
-            {isLoadingMore ? "Loading…" : hasMore ? "Load more" : "No more"}
-          </button>
-        </div>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Weight/components/WeightProgressCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Weight/components/WeightProgressCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,114 +1,0 @@
-import React, { useMemo, useState } from "react";
-
-import TimeRangeToggle from "../../../../../components/graphs/TimeRangeToggle.jsx";
-import PercentChangeAreaChart from "../../../../../components/graphs/PercentChangeAreaChart.jsx";
-import { percentChangeSeries, sumByTimeBucket } from "../../../../../utils/timeSeries.js";
-
-function clamp(n, min, max) {
-  const x = Number(n);
-  if (!Number.isFinite(x)) return min;
-  return Math.min(max, Math.max(min, x));
-}
-
-export default function WeightProgressCard({ intakes, goalCalories, isBulking }) {
-  const [range, setRange] = useState("weekly");
-
-
-  const points = useMemo(() => {
-    // For a bucket (week/month/year) we aggregate:
-    // - total calories
-    // - total adjusted goal
-    // then compute bucketCloseness% from those totals.
-    const totals = sumByTimeBucket(
-      intakes,
-      range,
-      (i) => i.date,
-      (i) => Number(i?.calories) || 0,
-    );
-
-    const goalTotals = sumByTimeBucket(
-      intakes,
-      range,
-      (i) => i.date,
-      (i) => {
-        const goal = Number(goalCalories);
-        if (!Number.isFinite(goal) || goal <= 0) return 0;
-        const burned = Number(i?.burnedCalories) || 0;
-        const trained = Boolean(i?.trainedThatDay);
-        return trained ? goal + burned : goal;
-      },
-    );
-
-    const goalByTs = new Map(goalTotals.map((p) => [p.ts, p.value]));
-
-    const closenessPoints = totals.map((p) => {
-      const adjustedGoal = Number(goalByTs.get(p.ts) ?? 0);
-      const calories = Number(p.value ?? 0);
-
-      if (!Number.isFinite(adjustedGoal) || adjustedGoal <= 0) {
-        return { ts: p.ts, value: 0 };
-      }
-
-      const pct = 100 - (Math.abs(calories - adjustedGoal) / adjustedGoal) * 100;
-      return { ts: p.ts, value: clamp(pct, 0, 200) };
-    });
-
-    const pctChange = percentChangeSeries(closenessPoints);
-    const adjusted =
-      isBulking === false
-        ? // Cutting: improvements should read as "positive" when the user stays under goal.
-          // Flip the sign so the line direction matches the user's intent.
-          pctChange.map((p) => ({ ...p, value: -Number(p.value ?? 0) }))
-        : pctChange;
-
-    // Reverse the graph line direction (invert Y) as requested.
-    return adjusted.map((p) => ({ ...p, value: -Number(p.value ?? 0) }));
-  }, [intakes, range, goalCalories, isBulking]);
-
-  const latest = points?.length ? points[points.length - 1] : null;
-  const latestPct = latest ? Number(latest.value ?? 0) : 0;
-  const latestBase = latest ? Number(latest.base ?? 0) : 0;
-
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <div className="flex items-center justify-between gap-4">
-          <h2 className="card-title">Progress</h2>
-          <div className="flex items-center gap-3">
-            <span className="badge badge-ghost">
-              {latestPct >= 0 ? "+" : ""}
-              {latestPct.toFixed(1)}% (last)
-            </span>
-            <TimeRangeToggle value={range} onChange={setRange} />
-          </div>
-        </div>
-
-        <div className="mt-4 w-full overflow-hidden rounded-xl border border-base-300 bg-base-100 p-2">
-          {points.length < 2 ? (
-            <div className="flex h-65 items-center justify-center text-sm opacity-70">
-              Add at least 2 daily intakes to see % change.
-            </div>
-          ) : (
-            <PercentChangeAreaChart
-              points={points}
-              granularity={range}
-              height={260}
-              positiveColor="#60a5fa"
-            />
-          )}
-        </div>
-
-        <div className="mt-2 text-xs opacity-70">
-          Showing percentage change in goal-accuracy (closeness %) per {range} bucket.
-          {isBulking === null ? (
-            <> Trend is not adjusted (missing current/goal weight). </>
-          ) : (
-            <> Trend is adjusted for your goal ({isBulking ? "bulking" : "cutting"}). </>
-          )}
-          Latest bucket closeness: {Math.round(latestBase)}%.
-        </div>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Weight/components/WeightStartCtaCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Weight/components/WeightStartCtaCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,27 +1,0 @@
-import React from "react";
-
-export default function WeightStartCtaCard({ error, onStart, isSubmitting }) {
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body items-center text-center">
-        <h1 className="text-4xl font-bold">You are not tracking weight</h1>
-        <p className="opacity-80 max-w-xl">
-          Start tracking to save your weight profile, calculate your target pace,
-          and keep daily calorie intake history.
-        </p>
-
-        {error ? <p className="text-error text-sm mt-2">{error}</p> : null}
-
-        <button
-          type="button"
-          className="btn btn-lg mt-6 w-full max-w-md bg-green-400! text-black! hover:bg-green-500!"
-          onClick={onStart}
-          disabled={isSubmitting}
-        >
-          {isSubmitting ? "Starting…" : "Start Tracking Weight"}
-        </button>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Weight/components/WeightStartForm.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Weight/components/WeightStartForm.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,181 +1,0 @@
-import React from "react";
-
-function formatNumber(value) {
-  if (value === null || value === undefined || value === "") return "—";
-  const num = Number(value);
-  if (Number.isNaN(num)) return String(value);
-  return Number.isInteger(num) ? String(num) : num.toFixed(2);
-}
-
-export default function WeightStartForm({
-  form,
-  setForm,
-  onSubmit,
-  onCancel,
-  error,
-  isSubmitting,
-  autoCalculateTargets,
-  setAutoCalculateTargets,
-  estimatedGoalTimeWeeks,
-  estimatedGoalCalories,
-}) {
-  return (
-    <form onSubmit={onSubmit} className="card bg-base-200 border border-base-300">
-      <div className="card-body items-center text-center">
-        <h1 className="text-3xl font-bold">Start tracking weight</h1>
-        <p className="opacity-80 max-w-2xl">
-          Fill in your current body metrics and the target you want to reach.
-          Trekr will estimate the time and goal calories in the form, and you can
-          override the calculation manually if you want to plan your own target.
-        </p>
-
-        {error ? <p className="text-error text-sm mt-2">{error}</p> : null}
-
-        <div className="mt-4 grid w-full grid-cols-1 gap-4 md:grid-cols-3">
-          <div>
-            <label className="label">Current weight (kg)</label>
-            <input
-              type="number"
-              className="input input-bordered w-full"
-              value={form.weight}
-              onChange={(e) => setForm((p) => ({ ...p, weight: e.target.value }))}
-              min={1}
-              step="0.1"
-              required
-            />
-          </div>
-
-          <div>
-            <label className="label">Height (cm)</label>
-            <input
-              type="number"
-              className="input input-bordered w-full"
-              value={form.height}
-              onChange={(e) => setForm((p) => ({ ...p, height: e.target.value }))}
-              min={1}
-              step="0.1"
-              required
-            />
-          </div>
-
-          <div>
-            <label className="label">Goal weight (kg)</label>
-            <input
-              type="number"
-              className="input input-bordered w-full"
-              value={form.goalWeight}
-              onChange={(e) =>
-                setForm((p) => ({ ...p, goalWeight: e.target.value }))
-              }
-              min={1}
-              step="0.1"
-              required
-            />
-          </div>
-        </div>
-
-        <div className="mt-4 w-full rounded-2xl border border-base-300 bg-base-100 p-4 text-left">
-          <label className="label cursor-pointer justify-start gap-3">
-            <input
-              type="checkbox"
-              className="checkbox"
-              checked={autoCalculateTargets}
-              onChange={(e) => {
-                const next = e.target.checked;
-                setAutoCalculateTargets(next);
-                if (!next) {
-                  if (form.goalTimeWeeks === "" && estimatedGoalTimeWeeks !== null) {
-                    setForm((p) => ({
-                      ...p,
-                      goalTimeWeeks: String(estimatedGoalTimeWeeks),
-                    }));
-                  }
-                  if (form.goalCalories === "" && estimatedGoalCalories !== null) {
-                    setForm((p) => ({
-                      ...p,
-                      goalCalories: String(estimatedGoalCalories),
-                    }));
-                  }
-                }
-              }}
-            />
-            <span className="label-text">Auto-calculate goal time and calories</span>
-          </label>
-          <p className="text-xs opacity-70 mt-1">
-            Trekr calculates the recommended time locally and only saves your
-            weight profile plus the calorie target.
-          </p>
-
-          <div className="mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2">
-            <div className="rounded-xl border border-base-300 p-3">
-              <div className="text-xs uppercase opacity-60">Suggested time</div>
-              <div className="text-xl font-semibold">
-                {formatNumber(estimatedGoalTimeWeeks)} weeks
-              </div>
-            </div>
-            <div className="rounded-xl border border-base-300 p-3">
-              <div className="text-xs uppercase opacity-60">Suggested calories</div>
-              <div className="text-xl font-semibold">
-                {formatNumber(estimatedGoalCalories)} kcal
-              </div>
-            </div>
-          </div>
-        </div>
-
-        <div className="mt-4 grid w-full grid-cols-1 gap-4 md:grid-cols-2">
-          <div>
-            <label className="label">Goal time (weeks)</label>
-            <input
-              type="number"
-              className="input input-bordered w-full"
-              value={form.goalTimeWeeks}
-              onChange={(e) =>
-                setForm((p) => ({ ...p, goalTimeWeeks: e.target.value }))
-              }
-              min={0}
-              step="0.1"
-              disabled={autoCalculateTargets}
-              placeholder={autoCalculateTargets ? "Calculated automatically" : "12.5"}
-              required={!autoCalculateTargets}
-            />
-          </div>
-
-          <div>
-            <label className="label">Goal calories (kcal)</label>
-            <input
-              type="number"
-              className="input input-bordered w-full"
-              value={form.goalCalories}
-              onChange={(e) =>
-                setForm((p) => ({ ...p, goalCalories: e.target.value }))
-              }
-              min={0}
-              step="0.1"
-              disabled={autoCalculateTargets}
-              placeholder={autoCalculateTargets ? "Calculated automatically" : "2200"}
-              required={!autoCalculateTargets}
-            />
-          </div>
-        </div>
-
-        <div className="mt-6 flex w-full flex-col items-center gap-3 sm:flex-row sm:justify-center">
-          <button
-            className="btn btn-lg w-full sm:w-auto bg-green-400! text-black! hover:bg-green-500!"
-            type="submit"
-            disabled={isSubmitting}
-          >
-            {isSubmitting ? "Starting…" : "Start Tracking"}
-          </button>
-          <button
-            type="button"
-            className="btn btn-ghost btn-lg w-full sm:w-auto"
-            onClick={onCancel}
-          >
-            Cancel
-          </button>
-        </div>
-      </div>
-    </form>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Weight/components/WeightSummaryCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Weight/components/WeightSummaryCard.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,63 +1,0 @@
-import React, { useMemo } from "react";
-import { MdEdit } from "react-icons/md";
-
-function statValue(value, suffix = "") {
-  if (value === null || value === undefined || value === "") return "—";
-  const num = Number(value);
-  if (Number.isNaN(num)) return String(value);
-  const formatted = Number.isInteger(num) ? String(num) : num.toFixed(2);
-  return `${formatted}${suffix}`;
-}
-
-export default function WeightSummaryCard({ profile, onEdit, todayTrainingInfo }) {
-  const todayCalories = useMemo(() => {
-    if (!profile?.goalCalories || !todayTrainingInfo) return null;
-    const goal = Number(profile.goalCalories);
-    const burned = Number(todayTrainingInfo.totalBurnedCalories) || 0;
-    if (!Number.isFinite(goal)) return null;
-    return goal + burned;
-  }, [profile?.goalCalories, todayTrainingInfo]);
-
-  const stats = [
-    { label: "Current weight", value: profile?.weight, suffix: " kg" },
-    { label: "Goal weight", value: profile?.goalWeight, suffix: " kg" },
-    { label: "Goal calories", value: profile?.goalCalories, suffix: " kcal" },
-    todayTrainingInfo?.trainedToday ? 
-      { label: "Today's calories", value: todayCalories, suffix: " kcal", subtitle: `(+${statValue(todayTrainingInfo.totalBurnedCalories)} burned)` } 
-      : null,
-  ].filter(Boolean);
-
-  return (
-    <div className="card bg-base-200 border border-base-300">
-      <div className="card-body">
-        <div className="flex items-center justify-between gap-4">
-          <div>
-            <h2 className="text-lg font-semibold">Profile summary</h2>
-            <p className="opacity-80">
-              Your current target and calorie plan at a glance.
-            </p>
-          </div>
-          <button
-            type="button"
-            className="btn btn-sm btn-ghost text-blue-400 hover:text-blue-300"
-            title="Edit profile"
-            onClick={onEdit}
-          >
-            <MdEdit className="size-5" />
-          </button>
-        </div>
-
-        <div className="mt-4 grid grid-cols-1 gap-3 sm:grid-cols-3 lg:grid-cols-4">
-          {stats.map((stat) => (
-            <div key={stat.label} className="stat bg-base-100 rounded-box border border-base-300">
-              <div className="stat-title text-xs">{stat.label}</div>
-              <div className="stat-value text-lg">{statValue(stat.value, stat.suffix)}</div>
-              {stat.subtitle && <div className="stat-desc text-xs">{stat.subtitle}</div>}
-            </div>
-          ))}
-        </div>
-      </div>
-    </div>
-  );
-}
-
Index: frontend/src/pages/Dashboard/pages/Weight/components/WeightTrackingHeader.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Weight/components/WeightTrackingHeader.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,23 +1,0 @@
-import React from "react";
-
-export default function WeightTrackingHeader({ onAddIntake, isTodayLogged }) {
-  return (
-    <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
-      <div>
-        <h1 className="text-2xl font-bold">Weight</h1>
-        <p className="opacity-80">
-          Track your daily calorie intakes and keep an eye on your target.
-        </p>
-      </div>
-      <button
-        type="button"
-        className="btn bg-green-400! text-black! hover:bg-green-500! border-0"
-        onClick={onAddIntake}
-        disabled={isTodayLogged}
-      >
-        {isTodayLogged ? "Today's intake already logged" : "+ Add today's intake"}
-      </button>
-    </div>
-  );
-}
-
Index: frontend/src/pages/LandingPage/LandingPage.jsx
===================================================================
--- frontend/src/pages/LandingPage/LandingPage.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,25 +1,0 @@
-import React from "react";
-import NavbarLanding from "./components/NavbarLanding";
-import Hero from "./components/Hero";
-import Footer from "./components/Footer";
-import { HowItWorks } from "./components/HowItWorks";
-import { Who } from "./components/Who";
-import { Faq } from "./components/Faq";
-import Features from "./components/Features";
-import Benefits from "./components/Benefits";
-const LandingPage = () => {
-  return (
-    <div data-theme="forest" className="min-h-screen w-full overflow-x-hidden">
-      <NavbarLanding />
-      <Hero />
-      <HowItWorks />
-      <Who />
-      <Features />
-      <Benefits />
-      <Faq />
-      <Footer />
-    </div>
-  );
-};
-
-export default LandingPage;
Index: frontend/src/pages/LandingPage/components/Benefits.jsx
===================================================================
--- frontend/src/pages/LandingPage/components/Benefits.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,83 +1,0 @@
-import React from "react";
-
-export const Benefits = () => {
-  const benefits = [
-    {
-      number: "1",
-      title: "Unified tracking",
-      description:
-        "Stop jumping between 5+ different apps. Everything you need is in one place.",
-    },
-    {
-      number: "2",
-      title: "Real-time insights",
-      description:
-        "See your progress at a glance with clear dashboards and intuitive charts.",
-    },
-    {
-      number: "3",
-      title: "Goal-focused",
-      description:
-        "Set targets, log consistently, and watch trends emerge over time.",
-    },
-    {
-      number: "4",
-      title: "Built for habit stacking",
-      description:
-        "Track related areas and discover how fitness, finances, and discipline connect.",
-    },
-    {
-      number: "5",
-      title: "Data security",
-      description:
-        "Your personal metrics are encrypted and private. Only you control access.",
-    },
-    {
-      number: "6",
-      title: "Mobile-friendly",
-      description:
-        "Fully responsive design works seamlessly on phone, tablet, and desktop.",
-    },
-  ];
-
-  return (
-    <section id="benefits" className="px-[5%] py-16 md:py-24 lg:py-28">
-      <div className="mx-auto w-full max-w-6xl">
-        <div className="text-center mb-16 md:mb-20">
-          <p className="font-semibold text-sm md:text-base mb-3 md:mb-4">
-            Why Trekr
-          </p>
-          <h2 className="font-bold mb-6 text-3xl sm:text-4xl md:text-5xl lg:text-6xl leading-tight">
-            Designed for serious progress
-          </h2>
-          <p className="max-w-2xl mx-auto text-base md:text-lg opacity-80">
-            We built Trekr for people who don't settle for half measures. If
-            consistency matters to you, Trekr makes it easier to stay on track.
-          </p>
-        </div>
-
-        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 md:gap-10">
-          {benefits.map((benefit, index) => (
-            <div key={index} className="flex gap-4 md:gap-6">
-              <div className="shrink-0">
-                <div className="flex items-center justify-center h-12 w-12 md:h-16 md:w-16 rounded-full bg-primary text-white font-bold text-lg md:text-xl">
-                  {benefit.number}
-                </div>
-              </div>
-              <div className="flex-1">
-                <h3 className="text-lg md:text-xl font-bold mb-2">
-                  {benefit.title}
-                </h3>
-                <p className="opacity-80 text-sm md:text-base">
-                  {benefit.description}
-                </p>
-              </div>
-            </div>
-          ))}
-        </div>
-      </div>
-    </section>
-  );
-};
-
-export default Benefits;
Index: frontend/src/pages/LandingPage/components/Faq.defaults.js
===================================================================
--- frontend/src/pages/LandingPage/components/Faq.defaults.js	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,40 +1,0 @@
-export const FaqDefaults = {
-  heading: "Frequently asked questions",
-  description:
-    "Quick answers on how Trekr helps you track self-improvement across multiple areas — in one place.",
-  questions: [
-    {
-      title: "What can I track in Trekr?",
-      answer:
-        "Workouts (type and duration), weight & nutrition (goal, calories), finances & budgeting (income and expenses), investing (portfolio and returns), and discipline (daily tasks you can check off).",
-    },
-    {
-      title: "Do I need multiple apps to do all this?",
-      answer:
-        "No — Trekr is designed to unify the most important self-improvement categories so you can get a clear overview without switching between tools.",
-    },
-    {
-      title: "How do goals and progress tracking work?",
-      answer:
-        "You set a goal (for example: target weight or monthly budget), then log daily/weekly data. Trekr helps you see where you are vs. the goal and how you're trending over time.",
-    },
-    {
-      title: "Where is my data stored?",
-      answer:
-        "Your entries are stored in a database and linked to your user profile so you can track progress consistently over time.",
-    },
-    {
-      title: "Is Trekr a mobile app?",
-      answer:
-        "Right now Trekr is a web app. The goal is a fast, simple experience on both mobile and desktop in the browser.",
-    },
-  ],
-  footerHeading: "Still have questions?",
-  footerDescription: "Send us a message and we’ll help you get started.",
-  button: {
-    title: "Contact",
-    variant: "secondary",
-  },
-};
-
-
Index: frontend/src/pages/LandingPage/components/Faq.jsx
===================================================================
--- frontend/src/pages/LandingPage/components/Faq.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,63 +1,0 @@
-import {
-  Button,
-  Accordion,
-  AccordionContent,
-  AccordionItem,
-  AccordionTrigger,
-} from "@relume_io/relume-ui";
-
-import { FaqDefaults } from "./Faq.defaults";
-
-export const Faq = (props) => {
-  const {
-    heading,
-    description,
-    questions,
-    footerHeading,
-    footerDescription,
-    button,
-  } = {
-    ...FaqDefaults,
-    ...props,
-  };
-  return (
-    <section
-      id="relume"
-      className="px-[5%] py-16 md:py-24 lg:py-28 flex items-center justify-center"
-    >
-      <div className="mx-auto w-full max-w-2xl">
-        <div className="rb-12 mb-12 text-center md:mb-18 lg:mb-20">
-          <h2 className="rb-5 mb-5 font-bold text-4xl sm:text-5xl md:mb-6 md:text-6xl lg:text-7xl leading-tight">
-            {heading}
-          </h2>
-          <p className="text-sm sm:text-base md:text-lg opacity-80">
-            {description}
-          </p>
-        </div>
-        <Accordion type="multiple">
-          {questions.map((question, index) => (
-            <AccordionItem key={index} value={`item-${index}`}>
-              <AccordionTrigger className="md:py-5 md:text-md">
-                {question.title}
-              </AccordionTrigger>
-              <AccordionContent className="md:pb-6">
-                {question.answer}
-              </AccordionContent>
-            </AccordionItem>
-          ))}
-        </Accordion>
-        <div className="mx-auto mt-12 max-w-md text-center md:mt-18 lg:mt-20">
-          <h4 className="mb-3 text-2xl font-bold md:mb-4 md:text-3xl md:leading-[1.3] lg:text-4xl">
-            {footerHeading}
-          </h4>
-          <p className="text-sm sm:text-base md:text-lg opacity-80">
-            {footerDescription}
-          </p>
-          <div className="mt-6 md:mt-8">
-            <Button {...button}>{button.title}</Button>
-          </div>
-        </div>
-      </div>
-    </section>
-  );
-};
Index: frontend/src/pages/LandingPage/components/Features.jsx
===================================================================
--- frontend/src/pages/LandingPage/components/Features.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,83 +1,0 @@
-import React from "react";
-
-export const Features = () => {
-  const features = [
-    {
-      icon: "🏋️",
-      title: "Fitness tracking",
-      description:
-        "Log workouts, stay consistent, and see your training trend over time.",
-    },
-    {
-      icon: "⚖️",
-      title: "Weight & nutrition",
-      description:
-        "Track daily weigh-ins and calories so you always know what’s working.",
-    },
-    {
-      icon: "💰",
-      title: "Budgeting",
-      description:
-        "Record income and expenses to stay on top of your money without spreadsheets.",
-    },
-    {
-      icon: "📈",
-      title: "Investments",
-      description:
-        "Monitor assets and returns to keep a clear view of your portfolio.",
-    },
-    {
-      icon: "✅",
-      title: "Daily discipline",
-      description:
-        "Turn intentions into habits with simple daily tasks and check-ins.",
-    },
-    {
-      icon: "📊",
-      title: "Insights",
-      description:
-        "See patterns across categories so you can make better decisions faster.",
-    },
-  ];
-
-  return (
-    <section
-      id="features"
-      className="px-[5%] py-16 md:py-24 lg:py-28 bg-base-200"
-    >
-      <div className="mx-auto w-full max-w-6xl">
-        <div className="text-center mb-16 md:mb-20">
-          <p className="font-semibold text-sm md:text-base mb-3 md:mb-4">
-            What you can track
-          </p>
-          <h2 className="font-bold mb-6 text-3xl sm:text-4xl md:text-5xl lg:text-6xl leading-tight">
-            Everything in one dashboard
-          </h2>
-          <p className="max-w-2xl mx-auto text-base md:text-lg opacity-80">
-            Trekr brings your health, habits, and money together, so you don’t
-            lose momentum switching tools.
-          </p>
-        </div>
-
-        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 md:gap-8">
-          {features.map((feature, index) => (
-            <div
-              key={index}
-              className="card bg-base-100 border border-base-300 hover:shadow-md transition-shadow"
-            >
-              <div className="card-body p-6 md:p-8">
-                <div className="text-4xl md:text-5xl mb-4">{feature.icon}</div>
-                <h3 className="text-xl md:text-2xl font-bold mb-3">
-                  {feature.title}
-                </h3>
-                <p className="opacity-80">{feature.description}</p>
-              </div>
-            </div>
-          ))}
-        </div>
-      </div>
-    </section>
-  );
-};
-
-export default Features;
Index: frontend/src/pages/LandingPage/components/Footer.jsx
===================================================================
--- frontend/src/pages/LandingPage/components/Footer.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,53 +1,0 @@
-import React from "react";
-import logo from "../../../assets/logo.png";
-
-const Footer = () => {
-  return (
-    <footer className="footer sm:footer-horizontal bg-neutral text-neutral-content p-8 sm:p-10">
-      <aside>
-        <img src={logo} alt="Trekr" className="h-10 w-auto" />
-        <p>Track self-improvement progress — in one place.</p>
-      </aside>
-      <nav>
-        <h6 className="footer-title">Social</h6>
-        <div className="grid grid-flow-col gap-4">
-          <a>
-            <svg
-              xmlns="http://www.w3.org/2000/svg"
-              width="24"
-              height="24"
-              viewBox="0 0 24 24"
-              className="fill-current"
-            >
-              <path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"></path>
-            </svg>
-          </a>
-          <a>
-            <svg
-              xmlns="http://www.w3.org/2000/svg"
-              width="24"
-              height="24"
-              viewBox="0 0 24 24"
-              className="fill-current"
-            >
-              <path d="M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z"></path>
-            </svg>
-          </a>
-          <a>
-            <svg
-              xmlns="http://www.w3.org/2000/svg"
-              width="24"
-              height="24"
-              viewBox="0 0 24 24"
-              className="fill-current"
-            >
-              <path d="M9 8h-3v4h3v12h5v-12h3.642l.358-4h-4v-1.667c0-.955.192-1.333 1.115-1.333h2.885v-5h-3.808c-3.596 0-5.192 1.583-5.192 4.615v3.385z"></path>
-            </svg>
-          </a>
-        </div>
-      </nav>
-    </footer>
-  );
-};
-
-export default Footer;
Index: frontend/src/pages/LandingPage/components/Hero.jsx
===================================================================
--- frontend/src/pages/LandingPage/components/Hero.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,50 +1,0 @@
-import React, { useEffect, useState } from "react";
-import { Link } from "react-router-dom";
-
-const Hero = () => {
-  const [isAuthed, setIsAuthed] = useState(() =>
-    Boolean(localStorage.getItem("authToken")),
-  );
-
-  useEffect(() => {
-    const onStorage = (e) => {
-      if (e.key === "authToken") {
-        setIsAuthed(Boolean(e.newValue));
-      }
-    };
-    window.addEventListener("storage", onStorage);
-    return () => window.removeEventListener("storage", onStorage);
-  }, []);
-
-  return (
-    <div
-      className="hero min-h-[calc(100vh-4rem)] bg-cover bg-center"
-      style={{
-        backgroundImage:
-          "url(https://images.unsplash.com/photo-1551288049-bebda4e38f71?auto=format&fit=crop&w=1920&q=80)",
-      }}
-    >
-      <div className="hero-overlay"></div>
-      <div className="hero-content text-neutral-content text-center px-4 py-16 sm:py-24">
-        <div className="w-full max-w-2xl">
-          <h1 className="mb-5 font-bold text-3xl sm:text-4xl md:text-5xl lg:text-6xl leading-tight">
-            Trekr — track progress, every day
-          </h1>
-          <p className="mb-6 text-sm sm:text-base md:text-lg opacity-90">
-            One self-improvement hub: workouts, weight & nutrition, finances &
-            budgeting, investing, and daily discipline tasks. Set goals, log
-            consistently, and see your progress in one place.
-          </p>
-          <Link
-            className="btn btn-primary !text-white btn-sm sm:btn-md md:btn-lg"
-            to={isAuthed ? "/dashboard" : "/register"}
-          >
-            {isAuthed ? "Go to dashboard" : "Get started"}
-          </Link>
-        </div>
-      </div>
-    </div>
-  );
-};
-
-export default Hero;
Index: frontend/src/pages/LandingPage/components/HowItWorks.defaults.js
===================================================================
--- frontend/src/pages/LandingPage/components/HowItWorks.defaults.js	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,22 +1,0 @@
-import { RxChevronRight } from "react-icons/rx";
-
-export const HowItWorksDefaults = {
-  tagline: "How it works",
-  heading: "Log it. Track it. Improve it.",
-  description:
-    "Log what matters to your goals — workouts, weight/calories, budgets, investments, and daily tasks. Trekr gives you a clear view of trends over time so you can stay consistent and keep moving forward.",
-  buttons: [
-    { title: "Start free", variant: "secondary" },
-    {
-      title: "See a quick overview",
-      variant: "link",
-      size: "link",
-      iconRight: <RxChevronRight />,
-    },
-  ],
-  image: {
-    src: "https://images.unsplash.com/photo-1522202176988-66273c2fd55f?auto=format&fit=crop&w=1600&q=80",
-    alt: "Progress and goals overview on a laptop",
-  },
-};
-
Index: frontend/src/pages/LandingPage/components/HowItWorks.defaults.jsx
===================================================================
--- frontend/src/pages/LandingPage/components/HowItWorks.defaults.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,23 +1,0 @@
-import { RxChevronRight } from "react-icons/rx";
-
-export const HowItWorksDefaults = {
-  tagline: "How it works",
-  heading: "Log it. Track it. Improve it.",
-  description:
-    "Log what matters to your goals — workouts, weight/calories, budgets, investments, and daily tasks. Trekr gives you a clear view of trends over time so you can stay consistent and keep moving forward.",
-  buttons: [
-    { title: "Start free", variant: "secondary" },
-    {
-      title: "See a quick overview",
-      variant: "link",
-      size: "link",
-      iconRight: <RxChevronRight />,
-    },
-  ],
-  image: {
-    src: "https://images.unsplash.com/photo-1522202176988-66273c2fd55f?auto=format&fit=crop&w=1600&q=80",
-    alt: "Progress and goals overview on a laptop",
-  },
-};
-
-
Index: frontend/src/pages/LandingPage/components/HowItWorks.jsx
===================================================================
--- frontend/src/pages/LandingPage/components/HowItWorks.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,42 +1,0 @@
-import { Button } from "@relume_io/relume-ui";
-import { HowItWorksDefaults } from "./HowItWorks.defaults.jsx";
-
-export const HowItWorks = (props) => {
-  const { tagline, heading, description, buttons, image } = {
-    ...HowItWorksDefaults,
-    ...props,
-  };
-  return (
-    <section id="relume" className="px-[5%] py-16 md:py-24 lg:py-28">
-      <div className="mx-auto w-full max-w-6xl">
-        <div className="grid grid-cols-1 gap-y-12 md:grid-cols-2 md:items-center md:gap-x-12 lg:gap-x-20">
-          <div className="text-center md:text-left">
-            <p className="mb-3 font-semibold md:mb-4">{tagline}</p>
-            <h1 className="rb-5 mb-5 font-bold text-4xl sm:text-5xl md:mb-6 md:text-6xl lg:text-7xl leading-tight">
-              {heading}
-            </h1>
-            <p className="text-sm sm:text-base md:text-lg opacity-80">
-              {description}
-            </p>
-            <div className="mt-6 flex flex-wrap items-center gap-4 md:mt-8">
-              {buttons.map((button, index) => (
-                <Button key={index} {...button}>
-                  {button.title}
-                </Button>
-              ))}
-            </div>
-          </div>
-          <div>
-            <img
-              src={image.src}
-              className="w-full rounded-2xl object-cover"
-              alt={image.alt}
-            />
-          </div>
-        </div>
-      </div>
-    </section>
-  );
-};
-
-
Index: frontend/src/pages/LandingPage/components/NavbarLanding.jsx
===================================================================
--- frontend/src/pages/LandingPage/components/NavbarLanding.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,68 +1,0 @@
-import React, { useEffect, useState } from "react";
-import { Link, useNavigate } from "react-router-dom";
-import logo from "../../../assets/logo.png";
-
-const NavbarLanding = () => {
-  const navigate = useNavigate();
-  const [isAuthed, setIsAuthed] = useState(() =>
-    Boolean(localStorage.getItem("authToken")),
-  );
-
-  useEffect(() => {
-    const onStorage = (e) => {
-      if (e.key === "authToken") {
-        setIsAuthed(Boolean(e.newValue));
-      }
-    };
-    window.addEventListener("storage", onStorage);
-    return () => window.removeEventListener("storage", onStorage);
-  }, []);
-
-  const onLogout = () => {
-    localStorage.removeItem("authToken");
-    localStorage.removeItem("authUser");
-    setIsAuthed(false);
-    navigate("/", { replace: true });
-  };
-
-  return (
-    <div className="navbar bg-primary text-primary-content shadow-sm px-4 sm:px-6">
-      <div className="navbar-start flex-1 min-w-0">
-        <Link
-          className="btn btn-ghost text-primary-content"
-          aria-label="Trekr home"
-          to="/"
-        >
-          <img src={logo} alt="Trekr" className="h-12 w-auto rounded-2xl" />
-        </Link>
-      </div>
-      <div className="navbar-end flex-none">
-        {isAuthed ? (
-          <div className="flex flex-wrap items-center justify-end gap-2 sm:gap-3">
-            <Link
-              className="btn btn-sm sm:btn-md btn-outline border-primary-content text-primary-content"
-              to="/dashboard"
-            >
-              Dashboard
-            </Link>
-            <button
-              className="btn btn-sm sm:btn-md btn-outline border-primary-content text-primary-content"
-              onClick={onLogout}
-            >
-              Logout
-            </button>
-          </div>
-        ) : (
-          <Link
-            className="btn btn-sm sm:btn-md btn-tertiary text-blue-200! px-6 sm:px-8"
-            to="/login"
-          >
-            Start Tracking
-          </Link>
-        )}
-      </div>
-    </div>
-  );
-};
-
-export default NavbarLanding;
Index: frontend/src/pages/LandingPage/components/Who.defaults.jsx
===================================================================
--- frontend/src/pages/LandingPage/components/Who.defaults.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,25 +1,0 @@
-import { RxChevronRight } from "react-icons/rx";
-
-const WhoDefaults = {
-  tagline: "Who it's for",
-  heading: "Anyone working on themselves",
-  description:
-    "Whether you're training regularly, trying to manage weight and nutrition, organizing your budget, tracking investments, or building discipline — Trekr brings your key habits and metrics together in one place.",
-  buttons: [
-    { title: "Create an account", variant: "secondary" },
-    {
-      title: "Learn more",
-      variant: "link",
-      size: "link",
-      iconRight: <RxChevronRight />,
-    },
-  ],
-  image: {
-    src: "https://images.unsplash.com/photo-1554284126-aa88f22d8b74?auto=format&fit=crop&w=1600&q=80",
-    alt: "Planning habits and routine",
-  },
-};
-
-export { WhoDefaults };
-
-
Index: frontend/src/pages/LandingPage/components/Who.jsx
===================================================================
--- frontend/src/pages/LandingPage/components/Who.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,41 +1,0 @@
-import { Button } from "@relume_io/relume-ui";
-import { WhoDefaults } from "./Who.defaults.jsx";
-
-export const Who = (props) => {
-  const { tagline, heading, description, buttons, image } = {
-    ...WhoDefaults,
-    ...props,
-  };
-  return (
-    <section id="relume" className="px-[5%] py-16 md:py-24 lg:py-28">
-      <div className="mx-auto w-full max-w-6xl">
-        <div className="grid grid-cols-1 gap-y-12 md:grid-cols-2 md:items-center md:gap-x-12 lg:gap-x-20">
-          <div className="order-2 md:order-1">
-            <img
-              src={image.src}
-              className="w-full rounded-2xl object-cover"
-              alt={image.alt}
-            />
-          </div>
-          <div className="order-1 lg:order-2 text-center md:text-left">
-            <p className="mb-3 font-semibold md:mb-4">{tagline}</p>
-            <h2 className="rb-5 mb-5 font-bold text-4xl sm:text-5xl md:mb-6 md:text-6xl lg:text-7xl leading-tight">
-              {heading}
-            </h2>
-            <p className="text-sm sm:text-base md:text-lg opacity-80">
-              {description}
-            </p>
-            <div className="mt-6 flex flex-wrap gap-4 md:mt-8">
-              {buttons.map((button, index) => (
-                <Button key={index} {...button}>
-                  {button.title}
-                </Button>
-              ))}
-            </div>
-          </div>
-        </div>
-      </div>
-    </section>
-  );
-};
-
Index: frontend/src/pages/Login/Login.jsx
===================================================================
--- frontend/src/pages/Login/Login.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,99 +1,0 @@
-import React, { useEffect, useState } from "react";
-import { Link, useNavigate } from "react-router-dom";
-
-import api from "../../api/axios";
-
-const Login = () => {
-  const navigate = useNavigate();
-  const [usernameOrEmail, setUsernameOrEmail] = useState("");
-  const [password, setPassword] = useState("");
-  const [error, setError] = useState("");
-  const [isSubmitting, setIsSubmitting] = useState(false);
-
-  useEffect(() => {
-    const token = localStorage.getItem("authToken");
-    if (token) navigate("/dashboard", { replace: true });
-  }, [navigate]);
-
-  const onSubmit = async (e) => {
-    e.preventDefault();
-    setError("");
-    setIsSubmitting(true);
-    try {
-      const res = await api.post("/auth/login", {
-        usernameOrEmail,
-        password,
-      });
-      localStorage.setItem("authToken", res.data.token);
-      localStorage.setItem(
-        "authUser",
-        JSON.stringify({
-          userId: res.data.userId,
-          username: res.data.username,
-          email: res.data.email,
-        }),
-      );
-      navigate("/dashboard");
-    } catch (err) {
-      const message =
-        err?.response?.data?.message ||
-        err?.response?.data?.errors?.usernameOrEmail ||
-        "Login failed";
-      setError(message);
-    } finally {
-      setIsSubmitting(false);
-    }
-  };
-
-  return (
-    <div className="min-h-screen flex items-center justify-center p-4">
-      <form
-        onSubmit={onSubmit}
-        className="fieldset bg-base-200 border-base-300 rounded-box w-xs border p-4"
-      >
-        <legend className="fieldset-legend">Login</legend>
-
-        <label className="label">Username or Email</label>
-        <input
-          type="text"
-          className="input"
-          placeholder="Username or Email"
-          value={usernameOrEmail}
-          onChange={(e) => setUsernameOrEmail(e.target.value)}
-          autoComplete="username"
-          required
-        />
-
-        <label className="label">Password</label>
-        <input
-          type="password"
-          className="input"
-          placeholder="Password"
-          value={password}
-          onChange={(e) => setPassword(e.target.value)}
-          autoComplete="current-password"
-          required
-        />
-
-        {error ? <p className="text-error mt-2 text-sm">{error}</p> : null}
-
-        <button
-          className="btn btn-neutral mt-4"
-          type="submit"
-          disabled={isSubmitting}
-        >
-          {isSubmitting ? "Logging in..." : "Login"}
-        </button>
-
-        <p className="mt-3 text-sm">
-          Don&apos;t have an account?{" "}
-          <Link className="link link-primary" to="/register">
-            Register
-          </Link>
-        </p>
-      </form>
-    </div>
-  );
-};
-
-export default Login;
Index: frontend/src/pages/Register/Register.jsx
===================================================================
--- frontend/src/pages/Register/Register.jsx	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,134 +1,0 @@
-import React, { useEffect, useState } from "react";
-import { Link, useNavigate } from "react-router-dom";
-
-import api from "../../api/axios";
-
-const Register = () => {
-  const navigate = useNavigate();
-  const [email, setEmail] = useState("");
-  const [username, setUsername] = useState("");
-  const [password, setPassword] = useState("");
-  const [error, setError] = useState("");
-  const [isSubmitting, setIsSubmitting] = useState(false);
-
-  useEffect(() => {
-    const token = localStorage.getItem("authToken");
-    if (token) navigate("/dashboard", { replace: true });
-  }, [navigate]);
-
-  const onSubmit = async (e) => {
-    e.preventDefault();
-    setError("");
-    setIsSubmitting(true);
-
-    const normalizedEmail = email.trim().toLowerCase();
-    const normalizedUsername = username.trim();
-    const normalizedPassword = password;
-
-    if (normalizedUsername.length < 3 || normalizedUsername.length > 50) {
-      setError("Username must be between 3 and 50 characters");
-      setIsSubmitting(false);
-      return;
-    }
-
-    if (normalizedPassword.length < 6) {
-      setError("Password must be at least 6 characters");
-      setIsSubmitting(false);
-      return;
-    }
-
-    try {
-      const res = await api.post("/auth/register", {
-        email: normalizedEmail,
-        username: normalizedUsername,
-        password: normalizedPassword,
-      });
-      localStorage.setItem("authToken", res.data.token);
-      localStorage.setItem(
-        "authUser",
-        JSON.stringify({
-          userId: res.data.userId,
-          username: res.data.username,
-          email: res.data.email,
-        }),
-      );
-      navigate("/dashboard");
-    } catch (err) {
-      const fieldErrors = err?.response?.data?.errors ?? {};
-      const firstFieldError = Object.values(fieldErrors)[0];
-      const message =
-        firstFieldError ||
-        err?.response?.data?.message ||
-        "Registration failed";
-      setError(message);
-    } finally {
-      setIsSubmitting(false);
-    }
-  };
-
-  return (
-    <div className="min-h-screen flex items-center justify-center p-4">
-      <form
-        onSubmit={onSubmit}
-        className="fieldset bg-base-200 border-base-300 rounded-box w-xs border p-4"
-      >
-        <legend className="fieldset-legend">Register</legend>
-
-        <label className="label">Email</label>
-        <input
-          type="email"
-          className="input"
-          placeholder="Email"
-          value={email}
-          onChange={(e) => setEmail(e.target.value)}
-          autoComplete="email"
-          required
-        />
-
-        <label className="label">Username</label>
-        <input
-          type="text"
-          className="input"
-          placeholder="Username"
-          value={username}
-          onChange={(e) => setUsername(e.target.value)}
-          autoComplete="username"
-          minLength={3}
-          maxLength={50}
-          required
-        />
-
-        <label className="label">Password</label>
-        <input
-          type="password"
-          className="input"
-          placeholder="Password"
-          value={password}
-          onChange={(e) => setPassword(e.target.value)}
-          autoComplete="new-password"
-          minLength={6}
-          required
-        />
-
-        {error ? <p className="text-error mt-2 text-sm">{error}</p> : null}
-
-        <button
-          className="btn btn-neutral mt-4"
-          type="submit"
-          disabled={isSubmitting}
-        >
-          {isSubmitting ? "Creating account..." : "Register"}
-        </button>
-
-        <p className="mt-3 text-sm">
-          Already have an account?{" "}
-          <Link className="link link-primary" to="/login">
-            Login
-          </Link>
-        </p>
-      </form>
-    </div>
-  );
-};
-
-export default Register;
Index: frontend/src/utils/authSession.js
===================================================================
--- frontend/src/utils/authSession.js	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,37 +1,0 @@
-export const AUTH_TOKEN_KEY = "authToken";
-export const AUTH_USER_KEY = "authUser";
-
-function decodeJwtPayload(token) {
-  try {
-    const parts = token.split(".");
-    if (parts.length < 2) return null;
-    const base64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
-    const normalized = base64.padEnd(Math.ceil(base64.length / 4) * 4, "=");
-    const json = atob(normalized);
-    return JSON.parse(json);
-  } catch {
-    return null;
-  }
-}
-
-export function isTokenExpired(token) {
-  if (!token) return true;
-  const payload = decodeJwtPayload(token);
-  if (!payload || typeof payload.exp !== "number") return true;
-  return payload.exp * 1000 <= Date.now();
-}
-
-export function getAuthToken() {
-  return localStorage.getItem(AUTH_TOKEN_KEY);
-}
-
-export function clearAuthSession() {
-  localStorage.removeItem(AUTH_TOKEN_KEY);
-  localStorage.removeItem(AUTH_USER_KEY);
-}
-
-export function logoutAndRedirect(path = "/dashboard") {
-  clearAuthSession();
-  window.location.assign(path);
-}
-
Index: frontend/src/utils/timeSeries.js
===================================================================
--- frontend/src/utils/timeSeries.js	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,116 +1,0 @@
-// Utilities for bucketing time-series data and computing percentage changes.
-
-function startOfDay(d) {
-  return new Date(d.getFullYear(), d.getMonth(), d.getDate());
-}
-
-function startOfMonth(d) {
-  return new Date(d.getFullYear(), d.getMonth(), 1);
-}
-
-function startOfYear(d) {
-  return new Date(d.getFullYear(), 0, 1);
-}
-
-// ISO week start (Monday)
-function startOfISOWeek(d) {
-  const date = startOfDay(d);
-  const day = date.getDay(); // 0..6 (Sun..Sat)
-  const diff = (day === 0 ? -6 : 1) - day;
-  date.setDate(date.getDate() + diff);
-  return startOfDay(date);
-}
-
-function bucketKey(date, granularity) {
-  const d = new Date(date);
-  if (Number.isNaN(d.getTime())) return null;
-
-  let s;
-  switch (granularity) {
-    case "daily":
-      s = startOfDay(d);
-      break;
-    case "weekly":
-      s = startOfISOWeek(d);
-      break;
-    case "monthly":
-      s = startOfMonth(d);
-      break;
-    case "yearly":
-      s = startOfYear(d);
-      break;
-    default:
-      s = startOfDay(d);
-  }
-
-  return s.getTime();
-}
-
-export function sumByTimeBucket(items, granularity, getDate, getValue) {
-  const map = new Map();
-
-  for (const it of items ?? []) {
-    const rawDate = getDate(it);
-    const k = bucketKey(rawDate, granularity);
-    if (k == null) continue;
-
-    const v = Number(getValue(it) ?? 0);
-    if (!Number.isFinite(v)) continue;
-
-    map.set(k, (map.get(k) ?? 0) + v);
-  }
-
-  const points = Array.from(map.entries())
-    .sort((a, b) => a[0] - b[0])
-    .map(([ts, value]) => ({ ts, value }));
-
-  return points;
-}
-
-export function percentChangeSeries(points) {
-  // Output: [{ ts, value: pctChange, base: sumValue }]
-  const out = [];
-  let prev = null;
-
-  for (const p of points ?? []) {
-    const curr = Number(p.value ?? 0);
-    let pct = 0;
-
-    if (prev == null) {
-      pct = 0;
-    } else if (prev === 0) {
-      // Avoid exploding infinity when previous is 0.
-      // Define: if curr is also 0 -> 0%, else -> 100%.
-      pct = curr === 0 ? 0 : 100;
-    } else {
-      pct = ((curr - prev) / prev) * 100;
-    }
-
-    out.push({ ts: p.ts, value: pct, base: curr });
-    prev = curr;
-  }
-
-  return out;
-}
-
-export function formatBucketLabel(ts, granularity) {
-  const d = new Date(ts);
-  if (Number.isNaN(d.getTime())) return "—";
-
-  const optsDay = { month: "short", day: "2-digit" };
-  const optsMonth = { year: "numeric", month: "short" };
-
-  switch (granularity) {
-    case "daily":
-      return d.toLocaleDateString(undefined, optsDay);
-    case "weekly":
-      return `Wk of ${d.toLocaleDateString(undefined, optsDay)}`;
-    case "monthly":
-      return d.toLocaleDateString(undefined, optsMonth);
-    case "yearly":
-      return String(d.getFullYear());
-    default:
-      return d.toLocaleDateString();
-  }
-}
-
Index: frontend/tailwind.config.js
===================================================================
--- frontend/tailwind.config.js	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,15 +1,0 @@
-import relumePreset from "@relume_io/relume-tailwind";
-
-/** @type {import('tailwindcss').Config} */
-export default {
-  content: [
-    "./index.html",
-    "./src/**/*.{js,ts,jsx,tsx}",
-    "./node_modules/@relume_io/relume-ui/dist/**/*.{js,ts,jsx,tsx}",
-  ],
-  presets: [relumePreset],
-  theme: {
-    extend: {},
-  },
-  plugins: [],
-};
Index: frontend/vite.config.js
===================================================================
--- frontend/vite.config.js	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ frontend/vite.config.js	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -1,26 +1,7 @@
 import { defineConfig } from 'vite'
 import react from '@vitejs/plugin-react'
-import tailwindcss from '@tailwindcss/vite';
 
 // https://vite.dev/config/
 export default defineConfig({
-  plugins: [react(), tailwindcss()],
-  server: {
-    proxy: {
-      // Dev-only Yahoo Finance proxy to avoid browser CORS.
-      // Frontend can call `/yahoo/...` and `/yahoo2/...` as same-origin.
-      '/yahoo': {
-        target: 'https://query1.finance.yahoo.com',
-        changeOrigin: true,
-        secure: true,
-        rewrite: (path) => path.replace(/^\/yahoo/, ''),
-      },
-      '/yahoo2': {
-        target: 'https://query2.finance.yahoo.com',
-        changeOrigin: true,
-        secure: true,
-        rewrite: (path) => path.replace(/^\/yahoo2/, ''),
-      },
-    },
-  },
+  plugins: [react()],
 })
