Index: ithub/workflows/ci-cd.yml
===================================================================
--- .github/workflows/ci-cd.yml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,78 +1,0 @@
-name: CI
-
-on:
-  push:
-    branches: [master, dev]
-  pull_request:
-    branches: [master]
-
-env:
-  BACKEND_IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/trekr-backend
-  FRONTEND_IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/trekr-frontend
-
-jobs:
-  build:
-    name: Build
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Set up Docker Buildx
-        uses: docker/setup-buildx-action@v3
-
-      - name: Build backend image
-        uses: docker/build-push-action@v5
-        with:
-          context: ./backend
-          push: false
-          cache-from: type=gha,scope=backend
-          cache-to:   type=gha,scope=backend,mode=max
-
-      - name: Build frontend image
-        uses: docker/build-push-action@v5
-        with:
-          context: ./frontend
-          push: false
-          cache-from: type=gha,scope=frontend
-          cache-to:   type=gha,scope=frontend,mode=max
-
-  push:
-    name: Push to DockerHub
-    runs-on: ubuntu-latest
-    needs: build
-    if: github.ref == 'refs/heads/master' && github.event_name == 'push'
-    steps:
-      - uses: actions/checkout@v4
-
-      - name: Set up Docker Buildx
-        uses: docker/setup-buildx-action@v3
-
-      - name: Log in to DockerHub
-        uses: docker/login-action@v3
-        with:
-          username: ${{ secrets.DOCKERHUB_USERNAME }}
-          password: ${{ secrets.DOCKERHUB_TOKEN }}
-
-      - name: Build and push backend
-        uses: docker/build-push-action@v5
-        with:
-          context: ./backend
-          push: true
-          platforms: linux/amd64,linux/arm64
-          tags: |
-            ${{ env.BACKEND_IMAGE }}:latest
-            ${{ env.BACKEND_IMAGE }}:${{ github.sha }}
-          cache-from: type=gha,scope=backend
-          cache-to:   type=gha,scope=backend,mode=max
-
-      - name: Build and push frontend
-        uses: docker/build-push-action@v5
-        with:
-          context: ./frontend
-          push: true
-          platforms: linux/amd64,linux/arm64
-          tags: |
-            ${{ env.FRONTEND_IMAGE }}:latest
-            ${{ env.FRONTEND_IMAGE }}:${{ github.sha }}
-          cache-from: type=gha,scope=frontend
-          cache-to:   type=gha,scope=frontend,mode=max
Index: dea/.gitignore
===================================================================
--- .idea/.gitignore	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,10 +1,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Ignored default folder with query files
-/queries/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
-# Editor-based HTTP Client requests
-/httpRequests/
Index: dea/compiler.xml
===================================================================
--- .idea/compiler.xml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,22 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="CompilerConfiguration">
-    <annotationProcessing>
-      <profile default="true" name="Default" enabled="true" />
-      <profile name="Annotation profile for backend" enabled="true">
-        <sourceOutputDir name="target/generated-sources/annotations" />
-        <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
-        <outputRelativeToContentRoot value="true" />
-        <processorPath useClasspath="false">
-          <entry name="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.42/lombok-1.18.42.jar" />
-        </processorPath>
-        <module name="backend" />
-      </profile>
-    </annotationProcessing>
-  </component>
-  <component name="JavacSettings">
-    <option name="ADDITIONAL_OPTIONS_OVERRIDE">
-      <module name="backend" options="-parameters" />
-    </option>
-  </component>
-</project>
Index: dea/copilot.data.migration.ask2agent.xml
===================================================================
--- .idea/copilot.data.migration.ask2agent.xml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,6 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="Ask2AgentMigrationStateService">
-    <option name="migrationStatus" value="COMPLETED" />
-  </component>
-</project>
Index: dea/copilotDiffState.xml
===================================================================
--- .idea/copilotDiffState.xml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,44 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="CopilotDiffPersistence">
-    <option name="pendingDiffs">
-      <map>
-        <entry key="$PROJECT_DIR$/frontend/src/App.jsx">
-          <value>
-            <PendingDiffInfo>
-              <option name="filePath" value="$PROJECT_DIR$/frontend/src/App.jsx" />
-              <option name="originalContent" value="import { Navigate, Route, Routes } from &quot;react-router-dom&quot;;&#10;&#10;import LandingPage from &quot;./pages/LandingPage/LandingPage.jsx&quot;;&#10;import Login from &quot;./pages/Login/Login.jsx&quot;;&#10;import Register from &quot;./pages/Register/Register.jsx&quot;;&#10;import DashboardLayout from &quot;./pages/Dashboard/DashboardLayout.jsx&quot;;&#10;import ControlCenter from &quot;./pages/Dashboard/pages/ControlCenter/ControlCenter.jsx&quot;;&#10;import Training from &quot;./pages/Dashboard/pages/Training/Training.jsx&quot;;&#10;import TrainingTracking from &quot;./pages/Dashboard/pages/Training/TrainingTracking.jsx&quot;;&#10;import NewTrainingSession from &quot;./pages/Dashboard/pages/Training/NewTrainingSession.jsx&quot;;&#10;import Weight from &quot;./pages/Dashboard/pages/Weight/Weight.jsx&quot;;&#10;import WeightTracking from &quot;./pages/Dashboard/pages/Weight/WeightTracking.jsx&quot;;&#10;import NewWeightIntake from &quot;./pages/Dashboard/pages/Weight/NewWeightIntake.jsx&quot;;&#10;import Finance from &quot;./pages/Dashboard/pages/Finance/Finance.jsx&quot;;&#10;import FinanceTracking from &quot;./pages/Dashboard/pages/Finance/FinanceTracking.jsx&quot;;&#10;import NewIncome from &quot;./pages/Dashboard/pages/Finance/NewIncome.jsx&quot;;&#10;import Investing from &quot;./pages/Dashboard/pages/Investing/Investing.jsx&quot;;&#10;import InvestingTracking from &quot;./pages/Dashboard/pages/Investing/InvestingTracking.jsx&quot;;&#10;import NewInvestment from &quot;./pages/Dashboard/pages/Investing/NewInvestment.jsx&quot;;&#10;import Discipline from &quot;./pages/Dashboard/pages/Discipline/Discipline.jsx&quot;;&#10;import DisciplineTracking from &quot;./pages/Dashboard/pages/Discipline/DisciplineTracking.jsx&quot;;&#10;import CustomCategoryKanban from &quot;./pages/Dashboard/pages/CustomCategory/CustomCategoryKanban.jsx&quot;;&#10;&#10;function RequireAuth({ children }) {&#10;  const token = localStorage.getItem(&quot;authToken&quot;);&#10;  if (!token) return &lt;Navigate to=&quot;/login&quot; replace /&gt;;&#10;  return children;&#10;}&#10;&#10;function App() {&#10;  return (&#10;    &lt;div data-theme=&quot;forest&quot; className=&quot;min-h-screen w-full&quot;&gt;&#10;      &lt;Routes&gt;&#10;        &lt;Route path=&quot;/&quot; element={&lt;LandingPage /&gt;} /&gt;&#10;        &lt;Route path=&quot;/login&quot; element={&lt;Login /&gt;} /&gt;&#10;        &lt;Route path=&quot;/register&quot; element={&lt;Register /&gt;} /&gt;&#10;        &lt;Route&#10;          path=&quot;/dashboard&quot;&#10;          element={&#10;            &lt;RequireAuth&gt;&#10;              &lt;DashboardLayout /&gt;&#10;            &lt;/RequireAuth&gt;&#10;          }&#10;        &gt;&#10;          &lt;Route index element={&lt;Navigate to=&quot;control-center&quot; replace /&gt;} /&gt;&#10;          &lt;Route path=&quot;control-center&quot; element={&lt;ControlCenter /&gt;} /&gt;&#10;          &lt;Route path=&quot;training&quot; element={&lt;Training /&gt;} /&gt;&#10;          &lt;Route path=&quot;training/tracking&quot; element={&lt;TrainingTracking /&gt;} /&gt;&#10;          &lt;Route&#10;            path=&quot;training/sessions/new&quot;&#10;            element={&lt;NewTrainingSession /&gt;}&#10;          /&gt;&#10;          &lt;Route path=&quot;weight&quot; element={&lt;Weight /&gt;} /&gt;&#10;          &lt;Route path=&quot;weight/tracking&quot; element={&lt;WeightTracking /&gt;} /&gt;&#10;          &lt;Route path=&quot;weight/intakes/new&quot; element={&lt;NewWeightIntake /&gt;} /&gt;&#10;          &lt;Route path=&quot;finance&quot; element={&lt;Finance /&gt;} /&gt;&#10;           &lt;Route path=&quot;finance/tracking&quot; element={&lt;FinanceTracking /&gt;} /&gt;&#10;           &lt;Route path=&quot;finance/incomes/new&quot; element={&lt;NewIncome /&gt;} /&gt;&#10;          &lt;Route path=&quot;investing&quot; element={&lt;Investing /&gt;} /&gt;&#10;          &lt;Route path=&quot;investing/tracking&quot; element={&lt;InvestingTracking /&gt;} /&gt;&#10;          &lt;Route path=&quot;investing/assets/new&quot; element={&lt;NewInvestment /&gt;} /&gt;&#10;          &lt;Route path=&quot;discipline&quot; element={&lt;Discipline /&gt;} /&gt;&#10;           &lt;Route path=&quot;discipline/tracking&quot; element={&lt;DisciplineTracking /&gt;} /&gt;&#10;           &lt;Route path=&quot;custom/:customTrackingId&quot; element={&lt;CustomCategoryKanban /&gt;} /&gt;&#10;        &lt;/Route&gt;&#10;        &lt;Route path=&quot;*&quot; element={&lt;Navigate to=&quot;/&quot; replace /&gt;} /&gt;&#10;      &lt;/Routes&gt;&#10;    &lt;/div&gt;&#10;  );&#10;}&#10;&#10;export default App;&#10;" />
-              <option name="updatedContent" value="import { Navigate, Route, Routes } from &quot;react-router-dom&quot;;&#10;import { clearAuthSession, getAuthToken, isTokenExpired } from &quot;./utils/authSession&quot;;&#10;&#10;import LandingPage from &quot;./pages/LandingPage/LandingPage.jsx&quot;;&#10;import Login from &quot;./pages/Login/Login.jsx&quot;;&#10;import Register from &quot;./pages/Register/Register.jsx&quot;;&#10;import DashboardLayout from &quot;./pages/Dashboard/DashboardLayout.jsx&quot;;&#10;import ControlCenter from &quot;./pages/Dashboard/pages/ControlCenter/ControlCenter.jsx&quot;;&#10;import Training from &quot;./pages/Dashboard/pages/Training/Training.jsx&quot;;&#10;import TrainingTracking from &quot;./pages/Dashboard/pages/Training/TrainingTracking.jsx&quot;;&#10;import NewTrainingSession from &quot;./pages/Dashboard/pages/Training/NewTrainingSession.jsx&quot;;&#10;import Weight from &quot;./pages/Dashboard/pages/Weight/Weight.jsx&quot;;&#10;import WeightTracking from &quot;./pages/Dashboard/pages/Weight/WeightTracking.jsx&quot;;&#10;import NewWeightIntake from &quot;./pages/Dashboard/pages/Weight/NewWeightIntake.jsx&quot;;&#10;import Finance from &quot;./pages/Dashboard/pages/Finance/Finance.jsx&quot;;&#10;import FinanceTracking from &quot;./pages/Dashboard/pages/Finance/FinanceTracking.jsx&quot;;&#10;import NewIncome from &quot;./pages/Dashboard/pages/Finance/NewIncome.jsx&quot;;&#10;import Investing from &quot;./pages/Dashboard/pages/Investing/Investing.jsx&quot;;&#10;import InvestingTracking from &quot;./pages/Dashboard/pages/Investing/InvestingTracking.jsx&quot;;&#10;import NewInvestment from &quot;./pages/Dashboard/pages/Investing/NewInvestment.jsx&quot;;&#10;import Discipline from &quot;./pages/Dashboard/pages/Discipline/Discipline.jsx&quot;;&#10;import DisciplineTracking from &quot;./pages/Dashboard/pages/Discipline/DisciplineTracking.jsx&quot;;&#10;import CustomCategoryKanban from &quot;./pages/Dashboard/pages/CustomCategory/CustomCategoryKanban.jsx&quot;;&#10;&#10;function RequireAuth({ children }) {&#10;  const token = getAuthToken();&#10;  if (token &amp;&amp; isTokenExpired(token)) {&#10;    clearAuthSession();&#10;    return &lt;Navigate to=&quot;/login&quot; replace /&gt;;&#10;  }&#10;  if (!token) return &lt;Navigate to=&quot;/login&quot; replace /&gt;;&#10;  return children;&#10;}&#10;&#10;function App() {&#10;  return (&#10;    &lt;div data-theme=&quot;forest&quot; className=&quot;min-h-screen w-full&quot;&gt;&#10;      &lt;Routes&gt;&#10;        &lt;Route path=&quot;/&quot; element={&lt;LandingPage /&gt;} /&gt;&#10;        &lt;Route path=&quot;/login&quot; element={&lt;Login /&gt;} /&gt;&#10;        &lt;Route path=&quot;/register&quot; element={&lt;Register /&gt;} /&gt;&#10;        &lt;Route&#10;          path=&quot;/dashboard&quot;&#10;          element={&#10;            &lt;RequireAuth&gt;&#10;              &lt;DashboardLayout /&gt;&#10;            &lt;/RequireAuth&gt;&#10;          }&#10;        &gt;&#10;          &lt;Route index element={&lt;Navigate to=&quot;control-center&quot; replace /&gt;} /&gt;&#10;          &lt;Route path=&quot;control-center&quot; element={&lt;ControlCenter /&gt;} /&gt;&#10;          &lt;Route path=&quot;training&quot; element={&lt;Training /&gt;} /&gt;&#10;          &lt;Route path=&quot;training/tracking&quot; element={&lt;TrainingTracking /&gt;} /&gt;&#10;          &lt;Route&#10;            path=&quot;training/sessions/new&quot;&#10;            element={&lt;NewTrainingSession /&gt;}&#10;          /&gt;&#10;          &lt;Route path=&quot;weight&quot; element={&lt;Weight /&gt;} /&gt;&#10;          &lt;Route path=&quot;weight/tracking&quot; element={&lt;WeightTracking /&gt;} /&gt;&#10;          &lt;Route path=&quot;weight/intakes/new&quot; element={&lt;NewWeightIntake /&gt;} /&gt;&#10;          &lt;Route path=&quot;finance&quot; element={&lt;Finance /&gt;} /&gt;&#10;           &lt;Route path=&quot;finance/tracking&quot; element={&lt;FinanceTracking /&gt;} /&gt;&#10;           &lt;Route path=&quot;finance/incomes/new&quot; element={&lt;NewIncome /&gt;} /&gt;&#10;          &lt;Route path=&quot;investing&quot; element={&lt;Investing /&gt;} /&gt;&#10;          &lt;Route path=&quot;investing/tracking&quot; element={&lt;InvestingTracking /&gt;} /&gt;&#10;          &lt;Route path=&quot;investing/assets/new&quot; element={&lt;NewInvestment /&gt;} /&gt;&#10;          &lt;Route path=&quot;discipline&quot; element={&lt;Discipline /&gt;} /&gt;&#10;           &lt;Route path=&quot;discipline/tracking&quot; element={&lt;DisciplineTracking /&gt;} /&gt;&#10;           &lt;Route path=&quot;custom/:customTrackingId&quot; element={&lt;CustomCategoryKanban /&gt;} /&gt;&#10;        &lt;/Route&gt;&#10;        &lt;Route path=&quot;*&quot; element={&lt;Navigate to=&quot;/&quot; replace /&gt;} /&gt;&#10;      &lt;/Routes&gt;&#10;    &lt;/div&gt;&#10;  );&#10;}&#10;&#10;export default App;&#10;" />
-            </PendingDiffInfo>
-          </value>
-        </entry>
-        <entry key="$PROJECT_DIR$/frontend/src/api/axios.js">
-          <value>
-            <PendingDiffInfo>
-              <option name="filePath" value="$PROJECT_DIR$/frontend/src/api/axios.js" />
-              <option name="originalContent" value="import axios from &quot;axios&quot;;&#10;&#10;const api = axios.create({&#10;  baseURL: import.meta.env.VITE_API_BASE_URL ?? &quot;http://localhost:8080/api&quot;,&#10;});&#10;&#10;api.interceptors.request.use((config) =&gt; {&#10;  const token = localStorage.getItem(&quot;authToken&quot;);&#10;  if (token) {&#10;    config.headers = config.headers ?? {};&#10;    config.headers.Authorization = `Bearer ${token}`;&#10;  }&#10;  return config;&#10;});&#10;&#10;export default api;" />
-              <option name="updatedContent" value="import axios from &quot;axios&quot;;&#10;import { getAuthToken, isTokenExpired, logoutAndRedirect } from &quot;../utils/authSession&quot;;&#10;&#10;const api = axios.create({&#10;  baseURL: import.meta.env.VITE_API_BASE_URL ?? &quot;http://localhost:8080/api&quot;,&#10;});&#10;&#10;api.interceptors.request.use((config) =&gt; {&#10;  const token = getAuthToken();&#10;  if (token) {&#10;    if (isTokenExpired(token)) {&#10;      logoutAndRedirect(&quot;/dashboard&quot;);&#10;      return Promise.reject(new Error(&quot;Authentication session expired&quot;));&#10;    }&#10;    config.headers = config.headers ?? {};&#10;    config.headers.Authorization = `Bearer ${token}`;&#10;  }&#10;  return config;&#10;});&#10;&#10;api.interceptors.response.use(&#10;  (response) =&gt; response,&#10;  (error) =&gt; {&#10;    const status = error?.response?.status;&#10;    if (status === 401 || status === 403) {&#10;      logoutAndRedirect(&quot;/dashboard&quot;);&#10;    }&#10;    return Promise.reject(error);&#10;  },&#10;);&#10;&#10;export default api;" />
-            </PendingDiffInfo>
-          </value>
-        </entry>
-        <entry key="$PROJECT_DIR$/frontend/src/pages/Dashboard/DashboardLayout.jsx">
-          <value>
-            <PendingDiffInfo>
-              <option name="filePath" value="$PROJECT_DIR$/frontend/src/pages/Dashboard/DashboardLayout.jsx" />
-              <option name="originalContent" value="import React, { useMemo } from &quot;react&quot;;&#10;import { Outlet, useNavigate } from &quot;react-router-dom&quot;;&#10;&#10;import { SidebarInset, SidebarProvider } from &quot;@relume_io/relume-ui&quot;;&#10;&#10;import DashboardSidebar from &quot;./components/DashboardSidebar.jsx&quot;;&#10;import DashboardTopbar from &quot;./components/DashboardTopbar.jsx&quot;;&#10;&#10;const DashboardLayout = () =&gt; {&#10;  const navigate = useNavigate();&#10;&#10;  const user = useMemo(() =&gt; {&#10;    try {&#10;      const raw = localStorage.getItem(&quot;authUser&quot;);&#10;      return raw ? JSON.parse(raw) : null;&#10;    } catch {&#10;      return null;&#10;    }&#10;  }, []);&#10;&#10;  const username = user?.username ?? &quot;&quot;;&#10;&#10;  const onLogout = () =&gt; {&#10;    localStorage.removeItem(&quot;authToken&quot;);&#10;    localStorage.removeItem(&quot;authUser&quot;);&#10;    navigate(&quot;/&quot;, { replace: true });&#10;  };&#10;&#10;  return (&#10;    &lt;SidebarProvider&gt;&#10;      {/* App shell background */}&#10;      &lt;div className=&quot;pointer-events-none fixed inset-0 -z-10&quot;&gt;&#10;        &lt;div className=&quot;absolute inset-0 bg-base-300/10&quot; /&gt;&#10;        &lt;div className=&quot;absolute inset-0 bg-radial-[circle_at_20%_20%] from-green-400/10 via-transparent to-transparent&quot; /&gt;&#10;        &lt;div className=&quot;absolute inset-0 bg-radial-[circle_at_80%_30%] from-blue-400/10 via-transparent to-transparent&quot; /&gt;&#10;        &lt;div className=&quot;absolute inset-0 bg-linear-to-b from-black/10 via-transparent to-black/25&quot; /&gt;&#10;      &lt;/div&gt;&#10;&#10;      &lt;DashboardSidebar /&gt;&#10;&#10;      &lt;SidebarInset className=&quot;pt-16 lg:pt-0&quot;&gt;&#10;        &lt;DashboardTopbar username={username} onLogout={onLogout} /&gt;&#10;&#10;        &lt;div className=&quot;h-[calc(100vh-4rem)] overflow-auto&quot;&gt;&#10;          &lt;div className=&quot;mx-auto w-full max-w-7xl px-4 py-6 sm:px-6 sm:py-8 lg:px-8 lg:py-10&quot;&gt;&#10;            &lt;div className=&quot;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&quot;&gt;&#10;              &lt;div className=&quot;p-4 sm:p-6 lg:p-8&quot;&gt;&#10;                &lt;Outlet /&gt;&#10;              &lt;/div&gt;&#10;            &lt;/div&gt;&#10;          &lt;/div&gt;&#10;        &lt;/div&gt;&#10;      &lt;/SidebarInset&gt;&#10;    &lt;/SidebarProvider&gt;&#10;  );&#10;};&#10;&#10;export default DashboardLayout;&#10;" />
-              <option name="updatedContent" value="import React, { useMemo } from &quot;react&quot;;&#10;import { Outlet, useNavigate } from &quot;react-router-dom&quot;;&#10;&#10;import { SidebarInset, SidebarProvider } from &quot;@relume_io/relume-ui&quot;;&#10;&#10;import DashboardSidebar from &quot;./components/DashboardSidebar.jsx&quot;;&#10;import DashboardTopbar from &quot;./components/DashboardTopbar.jsx&quot;;&#10;import { clearAuthSession } from &quot;../../utils/authSession&quot;;&#10;&#10;const DashboardLayout = () =&gt; {&#10;  const navigate = useNavigate();&#10;&#10;  const user = useMemo(() =&gt; {&#10;    try {&#10;      const raw = localStorage.getItem(&quot;authUser&quot;);&#10;      return raw ? JSON.parse(raw) : null;&#10;    } catch {&#10;      return null;&#10;    }&#10;  }, []);&#10;&#10;  const username = user?.username ?? &quot;&quot;;&#10;&#10;  const onLogout = () =&gt; {&#10;    clearAuthSession();&#10;    navigate(&quot;/&quot;, { replace: true });&#10;  };&#10;&#10;  return (&#10;    &lt;SidebarProvider&gt;&#10;      {/* App shell background */}&#10;      &lt;div className=&quot;pointer-events-none fixed inset-0 -z-10&quot;&gt;&#10;        &lt;div className=&quot;absolute inset-0 bg-base-300/10&quot; /&gt;&#10;        &lt;div className=&quot;absolute inset-0 bg-radial-[circle_at_20%_20%] from-green-400/10 via-transparent to-transparent&quot; /&gt;&#10;        &lt;div className=&quot;absolute inset-0 bg-radial-[circle_at_80%_30%] from-blue-400/10 via-transparent to-transparent&quot; /&gt;&#10;        &lt;div className=&quot;absolute inset-0 bg-linear-to-b from-black/10 via-transparent to-black/25&quot; /&gt;&#10;      &lt;/div&gt;&#10;&#10;      &lt;DashboardSidebar /&gt;&#10;&#10;      &lt;SidebarInset className=&quot;pt-16 lg:pt-0&quot;&gt;&#10;        &lt;DashboardTopbar username={username} onLogout={onLogout} /&gt;&#10;&#10;        &lt;div className=&quot;h-[calc(100vh-4rem)] overflow-auto&quot;&gt;&#10;          &lt;div className=&quot;mx-auto w-full max-w-7xl px-4 py-6 sm:px-6 sm:py-8 lg:px-8 lg:py-10&quot;&gt;&#10;            &lt;div className=&quot;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&quot;&gt;&#10;              &lt;div className=&quot;p-4 sm:p-6 lg:p-8&quot;&gt;&#10;                &lt;Outlet /&gt;&#10;              &lt;/div&gt;&#10;            &lt;/div&gt;&#10;          &lt;/div&gt;&#10;        &lt;/div&gt;&#10;      &lt;/SidebarInset&gt;&#10;    &lt;/SidebarProvider&gt;&#10;  );&#10;};&#10;&#10;export default DashboardLayout;&#10;" />
-            </PendingDiffInfo>
-          </value>
-        </entry>
-        <entry key="$PROJECT_DIR$/frontend/src/utils/authSession.js">
-          <value>
-            <PendingDiffInfo>
-              <option name="filePath" value="$PROJECT_DIR$/frontend/src/utils/authSession.js" />
-              <option name="updatedContent" value="export const AUTH_TOKEN_KEY = &quot;authToken&quot;;&#10;export const AUTH_USER_KEY = &quot;authUser&quot;;&#10;&#10;function decodeJwtPayload(token) {&#10;  try {&#10;    const parts = token.split(&quot;.&quot;);&#10;    if (parts.length &lt; 2) return null;&#10;    const base64 = parts[1].replace(/-/g, &quot;+&quot;).replace(/_/g, &quot;/&quot;);&#10;    const normalized = base64.padEnd(Math.ceil(base64.length / 4) * 4, &quot;=&quot;);&#10;    const json = atob(normalized);&#10;    return JSON.parse(json);&#10;  } catch {&#10;    return null;&#10;  }&#10;}&#10;&#10;export function isTokenExpired(token) {&#10;  if (!token) return true;&#10;  const payload = decodeJwtPayload(token);&#10;  if (!payload || typeof payload.exp !== &quot;number&quot;) return true;&#10;  return payload.exp * 1000 &lt;= Date.now();&#10;}&#10;&#10;export function getAuthToken() {&#10;  return localStorage.getItem(AUTH_TOKEN_KEY);&#10;}&#10;&#10;export function clearAuthSession() {&#10;  localStorage.removeItem(AUTH_TOKEN_KEY);&#10;  localStorage.removeItem(AUTH_USER_KEY);&#10;}&#10;&#10;export function logoutAndRedirect(path = &quot;/dashboard&quot;) {&#10;  clearAuthSession();&#10;  window.location.assign(path);&#10;}&#10;" />
-            </PendingDiffInfo>
-          </value>
-        </entry>
-      </map>
-    </option>
-  </component>
-</project>
Index: dea/encodings.xml
===================================================================
--- .idea/encodings.xml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,6 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="Encoding">
-    <file url="file://$PROJECT_DIR$/backend/src/main/java" charset="UTF-8" />
-  </component>
-</project>
Index: dea/inspectionProfiles/Project_Default.xml
===================================================================
--- .idea/inspectionProfiles/Project_Default.xml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,7 +1,0 @@
-<component name="InspectionProjectProfileManager">
-  <profile version="1.0">
-    <option name="myName" value="Project Default" />
-    <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
-    <inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
-  </profile>
-</component>
Index: dea/jarRepositories.xml
===================================================================
--- .idea/jarRepositories.xml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,20 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="RemoteRepositoriesConfiguration">
-    <remote-repository>
-      <option name="id" value="central" />
-      <option name="name" value="Central Repository" />
-      <option name="url" value="https://repo.maven.apache.org/maven2" />
-    </remote-repository>
-    <remote-repository>
-      <option name="id" value="central" />
-      <option name="name" value="Maven Central repository" />
-      <option name="url" value="https://repo1.maven.org/maven2" />
-    </remote-repository>
-    <remote-repository>
-      <option name="id" value="jboss.community" />
-      <option name="name" value="JBoss Community repository" />
-      <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
-    </remote-repository>
-  </component>
-</project>
Index: dea/misc.xml
===================================================================
--- .idea/misc.xml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,14 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ExternalStorageConfigurationManager" enabled="true" />
-  <component name="MavenProjectsManager">
-    <option name="originalFiles">
-      <list>
-        <option value="$PROJECT_DIR$/backend/pom.xml" />
-      </list>
-    </option>
-  </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_22" default="true" project-jdk-name="22" project-jdk-type="JavaSDK">
-    <output url="file://$PROJECT_DIR$/out" />
-  </component>
-</project>
Index: dea/modules.xml
===================================================================
--- .idea/modules.xml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,8 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectModuleManager">
-    <modules>
-      <module fileurl="file://$PROJECT_DIR$/.idea/trekr.iml" filepath="$PROJECT_DIR$/.idea/trekr.iml" />
-    </modules>
-  </component>
-</project>
Index: dea/trekr.iml
===================================================================
--- .idea/trekr.iml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,9 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$" />
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>
Index: dea/vcs.xml
===================================================================
--- .idea/vcs.xml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,6 +1,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="VcsDirectoryMappings">
-    <mapping directory="" vcs="Git" />
-  </component>
-</project>
Index: scode/settings.json
===================================================================
--- .vscode/settings.json	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,4 +1,0 @@
-{
-    "java.compile.nullAnalysis.mode": "automatic",
-    "java.configuration.updateBuildConfiguration": "interactive"
-}
Index: ENTS.md
===================================================================
--- AGENTS.md	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,79 +1,0 @@
-# AGENTS.md — Agent onboarding for Trekr
-
-Checklist for an AI coding agent when working in this repo
-- [ ] Understand architecture: `frontend` (Vite + React) talking to `backend` (Spring Boot REST API).
-- [ ] Know how to run & iterate locally (frontend dev server + backend JVM with env vars/.env).
-- [ ] Token & auth contract: JWT format, Authorization: Bearer header, token stored by frontend at `localStorage:authToken`.
-- [ ] Data & DB locations: `db-scripts/` (migrations, triggers, views) and JPA entities under `backend/src/main/java/com/trekr/backend/entity`.
-
-Quick summary (one-liner)
-Trekr is a split repo: a Vite React frontend (calls `/api/*`) and a Spring Boot backend (Java 17, Spring Data JPA, Spring Security with JWT). Backend loads a `.env`/`env` file before boot and expects DB and JWT secrets via environment properties.
-
-Essential files & places to read first
-- `backend/src/main/java/com/trekr/backend/BackendApplication.java` — .env loader behavior and how system properties are set.
-- `backend/src/main/resources/application.properties` — key runtime properties (datasource, `jwt.secret`, JPA settings).
-- `backend/src/main/java/com/trekr/backend/config/SecurityConfig.java` — top-level security rules and CORS dev origins (`http://localhost:5173`).
-- `backend/src/main/java/com/trekr/backend/service/JwtService.java` — exact JWT payload (subject = userId, claims: `username`, `email`) and token validity.
-- `backend/src/main/java/com/trekr/backend/security/JwtAuthenticationFilter.java` — how the backend extracts and validates the Bearer token.
-- `backend/src/main/java/com/trekr/backend/config/LegacyPasswordEncoder.java` — password rules: supports BCrypt (new) and plaintext (legacy seeds).
-- `backend/src/main/java/com/trekr/backend/controller/*` and `.../service/*` — canonical pattern: controllers are thin HTTP layers delegating to services; DTOs under `dto/`.
-- `frontend/src/api/axios.js` and `frontend/src/utils/authSession.js` — axios interceptors, where tokens are read/written, dev API base (`import.meta.env.VITE_API_BASE_URL`).
-- `db-scripts/` — migrations (`migrations/`), triggers and views—use these as source of truth for DB shape/constraints.
-
-Run / build / dev commands
-- Backend (preferred for local dev):
-  - Start with a .env or `env` file in repo root or `backend/` (see `BackendApplication` search order). Example env keys used: `SPRING_DATASOURCE_URL`, `SPRING_DATASOURCE_USERNAME`, `SPRING_DATASOURCE_PASSWORD`, `JWT_SECRET`.
-  - Dev run (from repo root):
-
-    cd backend && ./mvnw spring-boot:run
-
-  - Package and run jar:
-
-    cd backend && ./mvnw package
-    java -jar target/backend-0.0.1-SNAPSHOT.jar
-
-  - Run tests / compile:
-
-    cd backend && ./mvnw test
-
-- Frontend (Vite + npm):
-
-  cd frontend && npm install
-  npm run dev           # runs at :5173 by default (frontend dev)
-  npm run build         # production bundle
-
-Key runtime contracts & examples
-- API prefix: frontend uses `VITE_API_BASE_URL` default `http://localhost:8080/api` and axios attaches `Authorization: Bearer <token>` header (see `frontend/src/api/axios.js`).
-- Login flow: POST `/api/auth/login` returns `AuthResponse` (see `backend/src/main/java/com/trekr/backend/dto/auth/AuthResponse.java` and `AuthController`).
-- JWT payload (verify when issuing tokens): subject = userId, claims `username` and `email` (see `JwtService.generateToken`).
-- Token storage: frontend keys: `authToken` and `authUser` in localStorage (see `authSession.js`).
-
-Project-specific conventions & notable patterns
-- Layering: `controller` -> `service` -> `repository` (Spring Data JPA). DTOs are collected in `dto/<domain>` and entities are in `entity/<domain>`.
-- Legacy seed convenience: `LegacyPasswordEncoder` accepts plain-text seeded passwords (non-bcrypt). When changing auth/seed data be careful to preserve compatibility.
-- .env handling: Backend intentionally loads `.env` or `env` from several locations before Spring starts and sets values as system properties (so Spring `${...}` placeholders resolve). Put development env variables in repo root `.env` or `backend/.env`.
-- Database: the repo contains SQL migrations and helpers in `db-scripts/` (migrations, triggers, views). Treat these as authoritative when changing JPA mappings and ensure migrations remain in sync.
-- CORS: dev origins are explicitly whitelisted in `SecurityConfig` for the Vite dev server. If adding a different frontend origin add it there.
-
-Integration & dependency notes
-- JDBC: production target is PostgreSQL (dependency present in `pom.xml`), but tests use H2 (test scope). The default `application.properties` disables automatic DDL by default — change `SPRING_JPA_HIBERNATE_DDL_AUTO` if you need schema auto-update.
-- JWT implementation uses `io.jsonwebtoken` (jjwt); signing key comes from `jwt.secret` (env `JWT_SECRET` or `JWT_CONFIG_SECRET`). The code pads a dev fallback to 32+ chars if secret is missing.
-- Dotenv: the backend sets system properties using `io.github.cdimascio.dotenv.Dotenv` before Spring starts — do not rely on Spring's property loading only for dev overrides that the app expects early.
-
-Debugging tips for agents
-- If a token-authenticated endpoint returns 401 in dev, check:
-  1) the frontend `authToken` is present and not expired (`authSession.isTokenExpired`).
-  2) backend logs (Spring Security DEBUG is enabled in `application.properties`).
-  3) CORS origins if calling from the browser dev server.
-- To reproduce DB-related bugs locally, prefer running Postgres (set `SPRING_DATASOURCE_URL`) or temporarily set `SPRING_JPA_HIBERNATE_DDL_AUTO=update` for quick iteration (but be cautious with managed DBs).
-
-Where to look for more context
-- `backend/HELP.md` — general pointers and links to Spring docs.
-- `db-scripts/` — migration and trigger logic (useful for understanding computed columns and constraints).
-- `frontend/src/pages/*` and `frontend/src/api/*` — real call sites showing which backend endpoints are used.
-
-If you need to make changes
-- Prefer small edits in the pattern used: update DTOs + services + controllers; update SQL migrations when the schema changes; update `frontend/src/api/axios.js` and `VITE_API_BASE_URL` if changing API paths.
-
-Done: create this file at repo root as `AGENTS.md` to guide future agents.
-
Index: README.md
===================================================================
--- README.md	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ README.md	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -1,3 +1,1 @@
-## trekr
-
 Trekr преставува веб апликација за следење на прогрес во сите свери на самоподобрување. Во базата на податоци ќе се чуваат информации за корисниците кои ги внесуваат константно при користење на апликацијата и кои се релеватни за нивниот прогрес во одредена бранша, како нивната промена во килажа, секојдневни типови и должини на тренинзи, нивните финанциски придобивки, инвестиции и месечен буџет и дневна листа на дисциплински задачи. Веб апликацијата ќе биде платформа за следење на секојдневен прогрес и ќе им дозволи на корисниците да ги следат и ажурираат своите цели...
Index: backend/.gitignore
===================================================================
--- backend/.gitignore	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
+++ backend/.gitignore	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -0,0 +1,33 @@
+HELP.md
+target/
+.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
Index: ckend/Dockerfile
===================================================================
--- backend/Dockerfile	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,11 +1,0 @@
-FROM maven:3.9-eclipse-temurin-21 AS build
-WORKDIR /app
-COPY pom.xml .
-RUN mvn dependency:go-offline -q
-COPY src ./src
-RUN mvn package -DskipTests -q
-
-FROM eclipse-temurin:21-jre
-WORKDIR /app
-COPY --from=build /app/target/backend-0.0.1-SNAPSHOT.jar app.jar
-ENTRYPOINT ["java", "-jar", "app.jar"]
Index: ckend/HELP.md
===================================================================
--- backend/HELP.md	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,39 +1,0 @@
-# Getting Started
-
-### Project Documentation
-
-* [Normalization (Phase P5)](docs/Normalization.txt)
-
-### Reference Documentation
-
-For further reference, please consider the following sections:
-
-* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html)
-* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/4.0.2/maven-plugin)
-* [Create an OCI image](https://docs.spring.io/spring-boot/4.0.2/maven-plugin/build-image.html)
-* [Spring Data JPA](https://docs.spring.io/spring-boot/4.0.2/reference/data/sql.html#data.sql.jpa-and-spring-data)
-* [Spring Security](https://docs.spring.io/spring-boot/4.0.2/reference/web/spring-security.html)
-* [Validation](https://docs.spring.io/spring-boot/4.0.2/reference/io/validation.html)
-* [Spring Web](https://docs.spring.io/spring-boot/4.0.2/reference/web/servlet.html)
-
-### Guides
-
-The following guides illustrate how to use some features concretely:
-
-* [Accessing Data with JPA](https://spring.io/guides/gs/accessing-data-jpa/)
-* [Securing a Web Application](https://spring.io/guides/gs/securing-web/)
-* [Spring Boot and OAuth2](https://spring.io/guides/tutorials/spring-boot-oauth2/)
-* [Authenticating a User with LDAP](https://spring.io/guides/gs/authenticating-ldap/)
-* [Validation](https://spring.io/guides/gs/validating-form-input/)
-* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
-* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
-* [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)
-
-### Maven Parent overrides
-
-Due to Maven's design, elements are inherited from the parent POM to the project POM.
-While most of the inheritance is fine, it also inherits unwanted elements like `<license>` and `<developers>` from the
-parent.
-To prevent this, the project POM contains empty overrides for these elements.
-If you manually switch to a different parent and actually want the inheritance, you need to remove those overrides.
-
Index: ckend/docs/SQL_Injection_Prevention.txt
===================================================================
--- backend/docs/SQL_Injection_Prevention.txt	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,350 +1,0 @@
-= SQL Injection Prevention Strategy =
-
-==概述 ==
-
-SQL Injection е критична безбедносна ранливост каде нападачот внесува злонамерен SQL код преку корисничкиот влез за манипулирање со базата на податоци. Овој документ опишува како е имплементирана заштитата во Trekr backend за спречување на овој вид напади.
-
-== 1. Безбедни пракси имплементирани во проектот ==
-
-=== 1.1 Параметризирани пропити преку JPA ===
-
-Целиот backend користи Spring Data JPA која автоматски генерира параметризирани пропити што спречуваат SQL injection.
-
-==== Безбедно: Derived Query Methods ====
-
-Кога користиме method names на Spring Data, те се автоматски преведуваат во параметризирани SQL пропити:
-
-{{{
-// UserRepository.java
-public interface UserRepository extends JpaRepository<User, Long> {
-    Optional<User> findByEmail(String email);
-    Optional<User> findByUsername(String username);
-}
-
-// Сэчно користи параметриран пропит во подложина (EQUIVALENT TO):
-// SELECT * FROM users WHERE email = ?
-// параметарот se праќа одвоено од SQL командата
-}}}
-
-==== Безбедно: @Query со @Param ====
-
-За комплексни пропити, користториве @Query со именувани параметри:
-
-{{{
-// TaskRepository.java
-@Modifying
-@Query("update Task t set t.finished = false where t.disciplineUser.userId = :userId")
-int resetFinishedForUser(@Param("userId") Long userId);
-
-// Параметарот :userId се врзува безбедно преку JDBC, не преку string concatenation
-}}}
-
-==== Безбедно: Collection параметри ====
-
-За множество вредности (IN клаузули), користи параметризиран пропит:
-
-{{{
-// TrainingSessionRepository.java
-@java.util.List<TrainingSession> findByTrainingUser_UserIdAndDateIn(
-    Long userId,
-    Collection<LocalDate> dates
-);
-
-// Сэчно: SELECT * FROM training_sessions WHERE training_user_id = ? AND date IN (?, ?, ?)
-// Сите параметри се врзени безбедно, не преку строг конкатенација
-}}}
-
-=== 1.2 Строга типизација на параметри ===
-
-Кога параметарите се типизирани (Long, BigDecimal, LocalDate), т.е. не strings, SQL injection е веќе невозможна:
-
-{{{
-// FinanceService.java - пример од createIncome
-BigDecimal amount = request.getAmount();  // BigDecimal, не String
-if (amount.compareTo(BigDecimal.ZERO) <= 0) {
-    throw new RuntimeException("Amount must be greater than 0");
-}
-
-Income income = new Income();
-income.setAmount(amount);  // Num values can't inject SQL
-incomeRepository.save(income);
-
-// Генерирана SQL: INSERT INTO incomes (amount) VALUES (?)
-// Параметарот amount се врзува како број, не како строк
-}}}
-
-=== 1.3 Основна валидација на влезот ===
-
-Така поради внесување и валидација на нивото на апликација пред db операции:
-
-{{{
-// CustomTrackingService.java
-public CustomTrackingCategoryDto createCustomTrackingCategory(
-        Long userId,
-        CreateCustomTrackingCategoryRequest request) {
-
-    String name = request.getName();
-
-    // Валидација: не null/empty
-    if (name == null || name.isBlank()) {
-        throw new RuntimeException("Name is required");
-    }
-
-    String trimmed = name.trim();
-
-    // Валидација: должина
-    if (trimmed.length() > 100) {
-        throw new RuntimeException("Name is too long");
-    }
-
-    // На крај, trimmed value се зачувува преку ORM
-    // Никогаш не се користи raw SQL string concatenation
-    CustomTrackingCategory category = new CustomTrackingCategory();
-    category.setName(trimmed);
-    customTrackingCategoryRepository.save(category);
-}
-}}}
-
-=== 1.4 Authorization checks за ownership ===
-
-Дополнително заштита: провера дека конкретен корисник има право да приступи на специфичната информација:
-
-{{{
-// CustomTrackingService.java
-@Transactional
-public void deleteCustomCategoryTask(Long userId, Long customTrackingId, Long taskId) {
-    Task task = taskRepository.findById(taskId)
-            .orElseThrow(() -> new RuntimeException("Task not found"));
-
-    // Провера: дали задачата припаѓа на корисникот
-    if (task.getCustomTrackingCategory() == null
-            || !customTrackingId.equals(task.getCustomTrackingCategory().getCustomTrackingId())
-            || task.getCustomTrackingCategory().getUser() == null
-            || !userId.equals(task.getCustomTrackingCategory().getUser().getUserId())) {
-        throw new RuntimeException("Task not found");  // Скриена информација
-    }
-
-    int deleted = taskRepository.deleteByTaskIdAndCustomTrackingCategory_CustomTrackingIdAndCustomTrackingCategory_User_UserId(
-            taskId, customTrackingId, userId);
-    if (deleted == 0) {
-        throw new RuntimeException("Task not found");
-    }
-}
-}}}
-
-== 2. НЕБЕЗБЕДНИ ПРАКСИ која НИКОГАШ не смеаат да бидат користени ==
-
-=== 2.1 String Concatenation со SQL ===
-
-❌ НЕБЕЗБЕДНО - НЕ КВАЧИ НИКОГАШ:
-
-{{{
-// ОПАСНО: SQL injection уязвимост
-String email = userInput;  // од форма или параметар
-String query = "SELECT * FROM users WHERE email = '" + email + "'";
-// Ако userInput = "admin' OR '1'='1", резултира:
-// SELECT * FROM users WHERE email = 'admin' OR '1'='1'
-// Сие врати сите корисници!
-}}}
-
-=== 2.2 Директни SQL пропити со методи како createNativeQuery без параметри ===
-
-❌ НЕБЕЗБЕДНО:
-
-{{{
-// ОПАСНО
-String userProvidedFilter = request.getFilter();
-TypedQuery<User> query = entityManager.createNativeQuery(
-    "SELECT * FROM users WHERE name = '" + userProvidedFilter + "'",
-    User.class
-);
-// Позволува SQL injection
-}}}
-
-✅ БЕЗБЕДНО:
-
-{{{
-// ПРАВИЛНО
-TypedQuery<User> query = entityManager.createNativeQuery(
-    "SELECT * FROM users WHERE name = ?1",
-    User.class
-);
-query.setParameter(1, userProvidedFilter);
-// Параметарот se врзува безбедно
-}}}
-
-=== 2.3 Динамички конструирање на JPQL пропити преку string concatenation ===
-
-❌ НЕБЕЗБЕДНО:
-
-{{{
-// ОПАСНО
-String sortBy = request.getSortBy();  // "name' OR 'x'='x"
-String jpql = "SELECT u FROM User u ORDER BY u." + sortBy;
-TypedQuery<User> query = entityManager.createQuery(jpql, User.class);
-// Позволува SQL injection преку ORDER BY clause
-}}}
-
-✅ БЕЗБЕДНО:
-
-{{{
-// ПРАВИЛНО: користи Specification или CriteriaBuilder за динамички пропити
-CriteriaBuilder cb = entityManager.getCriteriaBuilder();
-CriteriaQuery<User> cq = cb.createQuery(User.class);
-Root<User> root = cq.from(User.class);
-
-// Динамички sort параметар е безбедно обработен
-Order order = Sort.Direction.ASC.equals(direction)
-    ? cb.asc(root.get(sortField))
-    : cb.desc(root.get(sortField));
-
-cq.orderBy(order);
-TypedQuery<User> query = entityManager.createQuery(cq);
-}}}
-
-== 3. Best Practices за имплементација ==
-
-=== 3.1 Правило: Никогаш не користи user input директно во SQL ===
-
-* Сите user inputs мора да бидат параметри
-* Користи Spring Data JPA методи deriva или @Query со @Param
-* За комплексни пропити, користи CriteriaBuilder или Specification
-
-=== 3.2 Правило: Типизирај параметри секогаш ===
-
-❌ ЛОШО:
-{{{
-Long userId = Long.parseLong(request.getUserId());  // String -> Long конверзија
-String query = "SELECT * FROM users WHERE id = " + userId;  // Неопходно SQL injection ризик
-}}}
-
-✅ ДОБРО:
-{{{
-Long userId = Long.parseLong(request.getUserId());  // String -> Long конверзија
-userRepository.findById(userId);  // Параметар е Long, не String
-// Типизирани параметри не можат да содржат SQL код
-}}}
-
-=== 3.3 Правило: Валидирай влез пред користење ===
-
-* Должина на strings
-* Формат на emails (regex или validator)
-* Диапаз��н на числа
-* Null/empty проверки
-
-{{{
-// FinanceService.java - пример
-public void startOrUpdateTracking(Long userId, FinanceStartRequest request) {
-    BigDecimal spending = normalizePercent(request.getSpendingBudget());
-    // ... остали валидации ...
-
-    // Валидирај сума = 100
-    validateSumTo100(spending, saving, investing, donation, credit);
-
-    // Сека валидација е успешна пред зачување во DB
-    financeUserRepository.save(financeUser);
-}
-}}}
-
-=== 3.4 Правило: Користи ОРМ библиотеки (JPA/Hibernate) ===
-
-* ОРМ автоматски параметризира пропити
-* Избегнувај raw JDBC комнди без параметри
-* За специјални случаи, користи JPA Criteria API
-
-=== 3.5 Правило: Логирај и мониторирај пропокусни пропити ===
-
-{{{
-// application.properties
-spring.jpa.show-sql=true
-logging.level.org.hibernate.SQL=DEBUG
-logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
-
-// TRACE анализира пропити и видија каков параметри се врзуваат
-}}}
-
-== 4. Минимални правила за нови допринесувачи ==
-
-При собачување нов feature, следи:
-
-1. ✅ Користи Spring Data JPA методи (findBy*, save*, etc.)
-2. ✅ За custom пропити, користи @Query("#jpql") со @Param параметри
-3. ✅ Никогаш не користи string concatenation со SQL
-4. ✅ Валидирај user inputs пред DB операции
-5. ✅ Провери ownership/authorization пред delete/update операции
-6. ✅ Типизирај сите параметри (Long, BigDecimal, LocalDate, не String)
-
-== 5. Пример: Правилна имплементација новог endpoint-а ==
-
-Сценарио: Нов endpoint за ажурирање на трошок по категорија.
-
-{{{
-// FinanceController.java
-@PutMapping("/allocations/{categoryId}")
-public ResponseEntity<AllocationDto> updateAllocation(
-        @PathVariable Long categoryId,
-        @Valid @RequestBody UpdateAllocationRequest request) {
-
-    AllocationDto result = financeService.updateAllocation(userId, categoryId, request);
-    return ResponseEntity.ok(result);
-}
-
-// FinanceService.java
-@Transactional
-public AllocationDto updateAllocation(Long userId, Long categoryId, UpdateAllocationRequest request) {
-
-    // 1. Валидирај input
-    BigDecimal amount = request.getAmount();
-    if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
-        throw new RuntimeException("Amount must be greater than 0");
-    }
-
-    // 2. Преземи објект од DB (JPA - безбедно)
-    Allocation allocation = allocationRepository.findById(categoryId)
-            .orElseThrow(() -> new RuntimeException("Allocation not found"));
-
-    // 3. Провери ownership
-    if (!userId.equals(allocation.getUser().getUserId())) {
-        throw new RuntimeException("Allocation not found");
-    }
-
-    // 4. Ажурирај и зачувај (JPA - безбедно)
-    allocation.setAmount(amount);
-    Allocation saved = allocationRepository.save(allocation);
-
-    // 5. Врати DTO
-    return new AllocationDto(saved.getId(), saved.getAmount());
-}
-}}}
-
-== 6. Заднила и прилична функција ==
-
-Оваа заштита е имплементирана во:
-
-* UserRepository.java - findByEmail/Username
-* TaskRepository.java - findByDisciplineUser_UserId, resetFinishedForUser (@Query)
-* TrainingSessionRepository.java - findByTrainingUser_UserIdAndDateIn
-* CustomTrackingService.java - ownership checking + validation
-* FinanceService.java - input validation + JPA save
-* DisciplineService.java - ownership checks + validation
-
-== 7. Потребни алатки за QA ==
-
-При тестирање на нови endpoints, следи:
-
-1. SQL logging: вклучи DEBUG на Hibernate SQL во тест environment
-2. Penetration testing: алати како OWASP ZAP или SQLmap (за белите хакери)
-3. Code review: проверка дека нема string concatenation со SQL
-4. Static analysis: SonarQube или Checkmarx може да детектери потенцијални SQL injection ризици
-
-== Закончување ==
-
-Trekr backend е заштитен од SQL Injection напади преку:
-* Spring Data JPA параметризирани пропити
-* Типизирани параметри
-* Приоритетна валидација
-* Ownership & authorization checks
-* Никогаш нема string concatenation со SQL
-
-За сите нови features, следи ги best practices навултени во овој документ.
-
Index: ckend/gitignore
===================================================================
--- backend/gitignore	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,38 +1,0 @@
-HELP.md
-target/
-.mvn/wrapper/maven-wrapper.jar
-!**/src/main/**/target/
-!**/src/test/**/target/
-
-### STS ###
-.apt_generated
-.classpath
-.factorypath
-.project
-.settings
-.springBeans
-.sts4-cache
-
-### IntelliJ IDEA ###
-.idea
-*.iws
-*.iml
-*.ipr
-
-### NetBeans ###
-/nbproject/private/
-/nbbuild/
-/dist/
-/nbdist/
-/.nb-gradle/
-build/
-!**/src/main/**/build/
-!**/src/test/**/build/
-
-### VS Code ###
-.vscode/
-
-### Environment Variables ###
-.env
-.env.local
-.env.*.local
Index: backend/pom.xml
===================================================================
--- backend/pom.xml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ backend/pom.xml	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -32,9 +32,4 @@
     <dependencies>
         <dependency>
-            <groupId>io.github.cdimascio</groupId>
-            <artifactId>dotenv-java</artifactId>
-            <version>3.0.0</version>
-        </dependency>
-        <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-jpa</artifactId>
@@ -53,25 +48,4 @@
         </dependency>
 
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-databind</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>io.jsonwebtoken</groupId>
-            <artifactId>jjwt-api</artifactId>
-            <version>0.12.6</version>
-        </dependency>
-        <dependency>
-            <groupId>io.jsonwebtoken</groupId>
-            <artifactId>jjwt-impl</artifactId>
-            <version>0.12.6</version>
-            <scope>runtime</scope>
-        </dependency>
-        <dependency>
-            <groupId>io.jsonwebtoken</groupId>
-            <artifactId>jjwt-jackson</artifactId>
-            <version>0.12.6</version>
-            <scope>runtime</scope>
-        </dependency>
         <dependency>
             <groupId>org.postgresql</groupId>
@@ -102,10 +76,4 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-webmvc-test</artifactId>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>com.h2database</groupId>
-            <artifactId>h2</artifactId>
             <scope>test</scope>
         </dependency>
Index: backend/src/main/java/com/trekr/backend/BackendApplication.java
===================================================================
--- backend/src/main/java/com/trekr/backend/BackendApplication.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ backend/src/main/java/com/trekr/backend/BackendApplication.java	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -1,11 +1,6 @@
 package com.trekr.backend;
 
-import io.github.cdimascio.dotenv.Dotenv;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
 
 @SpringBootApplication
@@ -13,75 +8,5 @@
 
     public static void main(String[] args) {
-        // Load .env file BEFORE Spring Boot starts
-        // This ensures system properties are available for ${} placeholder resolution
-        Dotenv dotenv = loadEnvironmentVariables();
-
-        // Create SpringApplication instance
-        SpringApplication app = new SpringApplication(BackendApplication.class);
-
-        // Set system properties and default properties from .env file
-        if (dotenv != null) {
-            java.util.Map<String, Object> defaultProps = new java.util.HashMap<>();
-
-            dotenv.entries().forEach(entry -> {
-                String key = entry.getKey();
-                String value = entry.getValue();
-                if (value != null && !value.trim().isEmpty()) {
-                    // Set as system property (for ${} placeholders in application.properties)
-                    System.setProperty(key, value);
-                    // Collect for default properties
-                    defaultProps.put(key, value);
-                }
-            });
-
-            // Set all default properties at once
-            if (!defaultProps.isEmpty()) {
-                app.setDefaultProperties(defaultProps);
-            }
-        }
-
-        app.run(args);
-    }
-
-    private static Dotenv loadEnvironmentVariables() {
-        Dotenv dotenv = null;
-
-        // Prefer a standard ".env" file, but also support the existing "env" file.
-        // We search multiple locations so it works whether the app is launched from:
-        // - backend/ (common in IDE)
-        // - repo root (common when running a built JAR)
-        String[][] candidates = new String[][] {
-                { "./", ".env" },
-                { "./", "env" },
-                { "./backend", ".env" },
-                { "./backend", "env" },
-                { "../", ".env" },
-                { "../", "env" },
-                { "../backend", ".env" },
-                { "../backend", "env" },
-        };
-
-        for (String[] candidate : candidates) {
-            try {
-                Path envPath = Paths.get(candidate[0], candidate[1]).normalize();
-                if (!Files.isRegularFile(envPath)) {
-                    continue;
-                }
-
-                Dotenv loaded = Dotenv.configure()
-                        .directory(envPath.getParent().toString())
-                        .filename(envPath.getFileName().toString())
-                        .ignoreIfMissing()
-                        .load();
-                if (loaded != null) {
-                    dotenv = loaded;
-                    break;
-                }
-            } catch (Exception ignored) {
-                // keep searching
-            }
-        }
-
-        return dotenv;
+        SpringApplication.run(BackendApplication.class, args);
     }
 
Index: ckend/src/main/java/com/trekr/backend/config/AuthProperties.java
===================================================================
--- backend/src/main/java/com/trekr/backend/config/AuthProperties.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,15 +1,0 @@
-package com.trekr.backend.config;
-
-import lombok.Getter;
-import lombok.Setter;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-@Getter @Setter
-@ConfigurationProperties(prefix = "auth")
-public class AuthProperties {
-    private String secret;
-    private int accessTokenMaxAge;
-    private int refreshTokenMaxAge;
-}
Index: ckend/src/main/java/com/trekr/backend/config/JacksonConfig.java
===================================================================
--- backend/src/main/java/com/trekr/backend/config/JacksonConfig.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,18 +1,0 @@
-package com.trekr.backend.config;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import tools.jackson.databind.ObjectMapper;
-import tools.jackson.databind.cfg.DateTimeFeature;
-import tools.jackson.databind.json.JsonMapper;
-
-@Configuration
-public class JacksonConfig {
-
-    @Bean
-    public ObjectMapper objectMapper() {
-        return JsonMapper.builder()
-                .disable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS)
-                .build();
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/config/LegacyPasswordEncoder.java
===================================================================
--- backend/src/main/java/com/trekr/backend/config/LegacyPasswordEncoder.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,29 +1,0 @@
-package com.trekr.backend.config;
-
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.security.crypto.password.PasswordEncoder;
-
-/**
- * Supports both BCrypt (for new users) and plain text (for legacy seed data).
- * Use BCrypt for encoding; for matching, tries BCrypt first, then plain.
- */
-public class LegacyPasswordEncoder implements PasswordEncoder {
-
-    private final BCryptPasswordEncoder bcrypt = new BCryptPasswordEncoder();
-
-    @Override
-    public String encode(CharSequence rawPassword) {
-        return bcrypt.encode(rawPassword);
-    }
-
-    @Override
-    public boolean matches(CharSequence rawPassword, String encodedPassword) {
-        if (encodedPassword == null || encodedPassword.isEmpty()) {
-            return false;
-        }
-        if (encodedPassword.startsWith("$2a$") || encodedPassword.startsWith("$2b$")) {
-            return bcrypt.matches(rawPassword, encodedPassword);
-        }
-        return rawPassword.toString().equals(encodedPassword);
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/config/SecurityConfig.java
===================================================================
--- backend/src/main/java/com/trekr/backend/config/SecurityConfig.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,67 +1,0 @@
-package com.trekr.backend.config;
-
-import com.trekr.backend.security.JwtAuthenticationFilter;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.Customizer;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
-import org.springframework.security.config.http.SessionCreationPolicy;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.CorsConfigurationSource;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-
-import java.util.List;
-
-@Configuration
-@EnableWebSecurity
-public class SecurityConfig {
-
-    private final JwtAuthenticationFilter jwtAuthenticationFilter;
-
-    public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) {
-        this.jwtAuthenticationFilter = jwtAuthenticationFilter;
-    }
-
-    @Bean
-    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
-        http
-                .csrf(AbstractHttpConfigurer::disable)
-                .cors(Customizer.withDefaults())
-                .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
-                .httpBasic(AbstractHttpConfigurer::disable)
-                .formLogin(AbstractHttpConfigurer::disable)
-                .authorizeHttpRequests(auth -> auth
-                        .requestMatchers("/api/auth/**").permitAll()
-                        .anyRequest().authenticated());
-
-        http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
-        return http.build();
-    }
-
-    @Bean
-    public CorsConfigurationSource corsConfigurationSource() {
-        CorsConfiguration config = new CorsConfiguration();
-        config.setAllowedOrigins(List.of(
-                "http://localhost:5173",
-                "http://127.0.0.1:5173",
-                "http://localhost:3000",
-                "http://127.0.0.1:3000"));
-        config.setAllowedMethods(List.of("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
-        config.setAllowedHeaders(List.of("Authorization", "Content-Type", "Accept", "Origin", "X-Requested-With"));
-        config.setAllowCredentials(true);
-
-        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
-        source.registerCorsConfiguration("/**", config);
-        return source;
-    }
-
-    @Bean
-    public PasswordEncoder passwordEncoder() {
-        return new LegacyPasswordEncoder();
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/controller/AuthController.java
===================================================================
--- backend/src/main/java/com/trekr/backend/controller/AuthController.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,38 +1,0 @@
-package com.trekr.backend.controller;
-
-import com.trekr.backend.dto.auth.AuthResponse;
-import com.trekr.backend.dto.auth.LoginRequest;
-import com.trekr.backend.dto.auth.RegisterRequest;
-import com.trekr.backend.service.AuthService;
-import jakarta.validation.Valid;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-@RestController
-@RequestMapping("/api/auth")
-public class AuthController {
-
-    private final AuthService authService;
-
-    public AuthController(AuthService authService) {
-        this.authService = authService;
-    }
-
-    @PostMapping("/register")
-    public ResponseEntity<AuthResponse> register(@Valid @RequestBody RegisterRequest request) {
-        AuthResponse response = authService.register(request);
-        return ResponseEntity.status(HttpStatus.CREATED).body(response);
-    }
-
-    @PostMapping("/login")
-    public ResponseEntity<AuthResponse> login(@Valid @RequestBody LoginRequest request) {
-        AuthResponse response = authService.login(request);
-        return ResponseEntity.ok(response);
-    }
-
-    @GetMapping("/ping")
-    public ResponseEntity<Void> ping() {
-        return ResponseEntity.ok().build();
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/controller/CustomTrackingController.java
===================================================================
--- backend/src/main/java/com/trekr/backend/controller/CustomTrackingController.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,102 +1,0 @@
-package com.trekr.backend.controller;
-
-import com.trekr.backend.dto.discipline.CreateCustomTrackingCategoryRequest;
-import com.trekr.backend.dto.discipline.CreateTaskRequest;
-import com.trekr.backend.dto.discipline.CustomTrackingCategoriesResponse;
-import com.trekr.backend.dto.discipline.CustomTrackingCategoryDto;
-import com.trekr.backend.dto.discipline.TaskDto;
-import com.trekr.backend.dto.discipline.TasksResponse;
-import com.trekr.backend.dto.discipline.UpdateTaskFinishedRequest;
-import com.trekr.backend.dto.discipline.UpdateTaskRequest;
-import com.trekr.backend.dto.discipline.UpdateTaskStatusRequest;
-import com.trekr.backend.security.UserPrincipal;
-import com.trekr.backend.service.CustomTrackingService;
-import jakarta.validation.Valid;
-import org.springframework.http.HttpStatus;
-import org.springframework.security.core.Authentication;
-import org.springframework.web.bind.annotation.*;
-
-@RestController
-@RequestMapping("/api/discipline/custom-tracking-categories")
-public class CustomTrackingController {
-
-    private final CustomTrackingService customTrackingService;
-
-    public CustomTrackingController(CustomTrackingService customTrackingService) {
-        this.customTrackingService = customTrackingService;
-    }
-
-    @GetMapping
-    public CustomTrackingCategoriesResponse customTrackingCategories(Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return customTrackingService.getCustomTrackingCategories(principal.getUserId());
-    }
-
-    @PostMapping
-    @ResponseStatus(HttpStatus.CREATED)
-    public CustomTrackingCategoryDto createCustomTrackingCategory(
-            @Valid @RequestBody CreateCustomTrackingCategoryRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return customTrackingService.createCustomTrackingCategory(principal.getUserId(), request);
-    }
-
-    @GetMapping("/{customTrackingId}/tasks")
-    public TasksResponse tasks(
-            @PathVariable Long customTrackingId,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return customTrackingService.getCustomCategoryTasks(principal.getUserId(), customTrackingId);
-    }
-
-    @PostMapping("/{customTrackingId}/tasks")
-    @ResponseStatus(HttpStatus.CREATED)
-    public TaskDto createTask(
-            @PathVariable Long customTrackingId,
-            @Valid @RequestBody CreateTaskRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return customTrackingService.createCustomCategoryTask(principal.getUserId(), customTrackingId, request);
-    }
-
-    @PutMapping("/{customTrackingId}/tasks/{taskId}")
-    public TaskDto updateTask(
-            @PathVariable Long customTrackingId,
-            @PathVariable Long taskId,
-            @Valid @RequestBody UpdateTaskRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return customTrackingService.updateCustomCategoryTask(principal.getUserId(), customTrackingId, taskId, request);
-    }
-
-    @PatchMapping("/{customTrackingId}/tasks/{taskId}/finished")
-    public TaskDto updateTaskFinished(
-            @PathVariable Long customTrackingId,
-            @PathVariable Long taskId,
-            @Valid @RequestBody UpdateTaskFinishedRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return customTrackingService.updateCustomCategoryTaskFinished(principal.getUserId(), customTrackingId, taskId, request);
-    }
-
-    @PatchMapping("/{customTrackingId}/tasks/{taskId}/status")
-    public TaskDto updateTaskStatus(
-            @PathVariable Long customTrackingId,
-            @PathVariable Long taskId,
-            @RequestBody UpdateTaskStatusRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return customTrackingService.updateCustomCategoryTaskStatus(principal.getUserId(), customTrackingId, taskId, request);
-    }
-
-    @DeleteMapping("/{customTrackingId}/tasks/{taskId}")
-    @ResponseStatus(HttpStatus.NO_CONTENT)
-    public void deleteTask(
-            @PathVariable Long customTrackingId,
-            @PathVariable Long taskId,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        customTrackingService.deleteCustomCategoryTask(principal.getUserId(), customTrackingId, taskId);
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/controller/DisciplineController.java
===================================================================
--- backend/src/main/java/com/trekr/backend/controller/DisciplineController.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,122 +1,0 @@
-package com.trekr.backend.controller;
-
-import com.trekr.backend.dto.discipline.CreateTaskRequest;
-import com.trekr.backend.dto.discipline.ComputeDailyCompletionResponse;
-import com.trekr.backend.dto.discipline.DailyCompletionsResponse;
-import com.trekr.backend.dto.discipline.TaskDto;
-import com.trekr.backend.dto.discipline.TasksResponse;
-import com.trekr.backend.dto.discipline.TrackingStatusResponse;
-import com.trekr.backend.dto.discipline.UpdateTaskFinishedRequest;
-import com.trekr.backend.dto.discipline.UpdateTaskRequest;
-import com.trekr.backend.security.UserPrincipal;
-import com.trekr.backend.service.DisciplineService;
-import jakarta.validation.Valid;
-import org.springframework.http.HttpStatus;
-import org.springframework.security.core.Authentication;
-import org.springframework.web.bind.annotation.*;
-
-import java.time.LocalDate;
-
-@RestController
-@RequestMapping("/api/discipline")
-public class DisciplineController {
-
-    private final DisciplineService disciplineService;
-
-    public DisciplineController(DisciplineService disciplineService) {
-        this.disciplineService = disciplineService;
-    }
-
-    @GetMapping("/status")
-    public TrackingStatusResponse status(Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        boolean tracking = disciplineService.isTracking(principal.getUserId());
-        return new TrackingStatusResponse(tracking);
-    }
-
-    @PostMapping("/start")
-    @ResponseStatus(HttpStatus.CREATED)
-    public TrackingStatusResponse start(Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        disciplineService.startTracking(principal.getUserId());
-        return new TrackingStatusResponse(true);
-    }
-
-    @GetMapping("/tasks")
-    public TasksResponse tasks(
-            @RequestParam(defaultValue = "0") int page,
-            @RequestParam(defaultValue = "20") int size,
-            Authentication authentication) {
-        if (size < 1)
-            size = 20;
-        if (size > 200)
-            size = 200;
-        if (page < 0)
-            page = 0;
-
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return disciplineService.getTasks(principal.getUserId(), page, size);
-    }
-
-    @PostMapping("/tasks")
-    @ResponseStatus(HttpStatus.CREATED)
-    public TaskDto createTask(
-            @Valid @RequestBody CreateTaskRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return disciplineService.createTask(principal.getUserId(), request);
-    }
-
-    @PutMapping("/tasks/{taskId}")
-    public TaskDto updateTask(
-            @PathVariable Long taskId,
-            @Valid @RequestBody UpdateTaskRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return disciplineService.updateTask(principal.getUserId(), taskId, request);
-    }
-
-    @PatchMapping("/tasks/{taskId}/finished")
-    public TaskDto updateTaskFinished(
-            @PathVariable Long taskId,
-            @Valid @RequestBody UpdateTaskFinishedRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return disciplineService.updateTaskFinished(principal.getUserId(), taskId, request);
-    }
-
-    @DeleteMapping("/tasks/{taskId}")
-    @ResponseStatus(HttpStatus.NO_CONTENT)
-    public void deleteTask(
-            @PathVariable Long taskId,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        disciplineService.deleteTask(principal.getUserId(), taskId);
-    }
-
-    @PostMapping("/daily-completions/compute")
-    public ComputeDailyCompletionResponse computeDailyCompletion(
-            @RequestParam(required = false) LocalDate date,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        LocalDate target = (date != null) ? date : LocalDate.now();
-        return disciplineService.computeDailyCompletion(principal.getUserId(), target);
-    }
-
-    @GetMapping("/daily-completions")
-    public DailyCompletionsResponse dailyCompletions(
-            @RequestParam(defaultValue = "0") int page,
-            @RequestParam(defaultValue = "14") int size,
-            Authentication authentication) {
-        if (size < 1)
-            size = 14;
-        if (size > 365)
-            size = 365;
-        if (page < 0)
-            page = 0;
-
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return disciplineService.getDailyCompletions(principal.getUserId(), page, size);
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/controller/FinanceController.java
===================================================================
--- backend/src/main/java/com/trekr/backend/controller/FinanceController.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,72 +1,0 @@
-package com.trekr.backend.controller;
-
-import com.trekr.backend.dto.finance.CreateIncomeRequest;
-import com.trekr.backend.dto.finance.FinanceProfileResponse;
-import com.trekr.backend.dto.finance.FinanceStartRequest;
-import com.trekr.backend.dto.finance.IncomeDto;
-import com.trekr.backend.dto.finance.IncomesResponse;
-import com.trekr.backend.dto.finance.TrackingStatusResponse;
-import com.trekr.backend.security.UserPrincipal;
-import com.trekr.backend.service.FinanceService;
-import jakarta.validation.Valid;
-import org.springframework.http.HttpStatus;
-import org.springframework.security.core.Authentication;
-import org.springframework.web.bind.annotation.*;
-
-@RestController
-@RequestMapping("/api/finance")
-public class FinanceController {
-
-    private final FinanceService financeService;
-
-    public FinanceController(FinanceService financeService) {
-        this.financeService = financeService;
-    }
-
-    @GetMapping("/status")
-    public TrackingStatusResponse status(Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        boolean tracking = financeService.isTracking(principal.getUserId());
-        return new TrackingStatusResponse(tracking);
-    }
-
-    @PostMapping("/start")
-    @ResponseStatus(HttpStatus.CREATED)
-    public TrackingStatusResponse start(@Valid @RequestBody FinanceStartRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        financeService.startOrUpdateTracking(principal.getUserId(), request);
-        return new TrackingStatusResponse(true);
-    }
-
-    @GetMapping("/profile")
-    public FinanceProfileResponse profile(Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return financeService.getProfile(principal.getUserId());
-    }
-
-    @GetMapping("/incomes")
-    public IncomesResponse incomes(
-            @RequestParam(defaultValue = "0") int page,
-            @RequestParam(defaultValue = "5") int size,
-            Authentication authentication) {
-        if (size < 1)
-            size = 5;
-        if (size > 50)
-            size = 50;
-        if (page < 0)
-            page = 0;
-
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return financeService.getIncomes(principal.getUserId(), page, size);
-    }
-
-    @PostMapping("/incomes")
-    @ResponseStatus(HttpStatus.CREATED)
-    public IncomeDto createIncome(@Valid @RequestBody CreateIncomeRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return financeService.createIncome(principal.getUserId(), request);
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/controller/InvestingController.java
===================================================================
--- backend/src/main/java/com/trekr/backend/controller/InvestingController.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,74 +1,0 @@
-package com.trekr.backend.controller;
-
-import com.trekr.backend.dto.invest.AssetDto;
-import com.trekr.backend.dto.invest.CreateAssetRequest;
-import com.trekr.backend.dto.invest.InvestingAssetsResponse;
-import com.trekr.backend.dto.invest.TrackingStatusResponse;
-import com.trekr.backend.security.UserPrincipal;
-import com.trekr.backend.service.InvestingService;
-import jakarta.validation.Valid;
-import org.springframework.http.HttpStatus;
-import org.springframework.security.core.Authentication;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/api/investing")
-public class InvestingController {
-
-    private final InvestingService investingService;
-
-    public InvestingController(InvestingService investingService) {
-        this.investingService = investingService;
-    }
-
-    @GetMapping("/status")
-    public TrackingStatusResponse status(Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        boolean tracking = investingService.isTracking(principal.getUserId());
-        return new TrackingStatusResponse(tracking);
-    }
-
-    @PostMapping("/start")
-    @ResponseStatus(HttpStatus.CREATED)
-    public TrackingStatusResponse start(Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        investingService.startTracking(principal.getUserId());
-        return new TrackingStatusResponse(true);
-    }
-
-    @GetMapping("/assets")
-    public InvestingAssetsResponse assets(
-            @RequestParam(defaultValue = "0") int page,
-            @RequestParam(defaultValue = "5") int size,
-            Authentication authentication) {
-        if (size < 1)
-            size = 5;
-        if (size > 50)
-            size = 50;
-        if (page < 0)
-            page = 0;
-
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return investingService.getAssets(principal.getUserId(), page, size);
-    }
-
-    @PostMapping("/assets")
-    @ResponseStatus(HttpStatus.CREATED)
-    public AssetDto createAsset(
-            @Valid @RequestBody CreateAssetRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return investingService.createAsset(principal.getUserId(), request);
-    }
-
-    @DeleteMapping("/assets/{assetId}")
-    @ResponseStatus(HttpStatus.NO_CONTENT)
-    public void deleteAsset(
-            @PathVariable Long assetId,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        investingService.deleteAsset(principal.getUserId(), assetId);
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/controller/TrainingController.java
===================================================================
--- backend/src/main/java/com/trekr/backend/controller/TrainingController.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,80 +1,0 @@
-package com.trekr.backend.controller;
-
-import com.trekr.backend.dto.training.CreateTrainingSessionRequest;
-import com.trekr.backend.dto.training.TrainingSessionDto;
-import com.trekr.backend.dto.training.TrainingStartRequest;
-import com.trekr.backend.dto.training.TrainingSessionsResponse;
-import com.trekr.backend.dto.training.TrainingProfileResponse;
-import com.trekr.backend.dto.training.TrackingStatusResponse;
-import com.trekr.backend.dto.training.WorkoutTypeDto;
-import com.trekr.backend.security.UserPrincipal;
-import com.trekr.backend.service.TrainingService;
-import jakarta.validation.Valid;
-import org.springframework.http.HttpStatus;
-import org.springframework.security.core.Authentication;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/api/training")
-public class TrainingController {
-
-    private final TrainingService trainingService;
-
-    public TrainingController(TrainingService trainingService) {
-        this.trainingService = trainingService;
-    }
-
-    @GetMapping("/status")
-    public TrackingStatusResponse status(Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        boolean tracking = trainingService.isTracking(principal.getUserId());
-        return new TrackingStatusResponse(tracking);
-    }
-
-    @PostMapping("/start")
-    @ResponseStatus(HttpStatus.CREATED)
-    public TrackingStatusResponse start(@Valid @RequestBody TrainingStartRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        trainingService.startTracking(principal.getUserId(), request);
-        return new TrackingStatusResponse(true);
-    }
-
-    @GetMapping("/sessions")
-    public TrainingSessionsResponse sessions(
-            @RequestParam(defaultValue = "0") int page,
-            @RequestParam(defaultValue = "5") int size,
-            Authentication authentication) {
-        if (size < 1)
-            size = 5;
-        if (size > 50)
-            size = 50;
-        if (page < 0)
-            page = 0;
-
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return trainingService.getSessions(principal.getUserId(), page, size);
-    }
-
-    @GetMapping("/workout-types")
-    public List<WorkoutTypeDto> workoutTypes() {
-        return trainingService.getWorkoutTypes();
-    }
-
-    @GetMapping("/profile")
-    public TrainingProfileResponse profile(Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return trainingService.getProfile(principal.getUserId());
-    }
-
-    @PostMapping("/sessions")
-    @ResponseStatus(HttpStatus.CREATED)
-    public TrainingSessionDto createSession(
-            @Valid @RequestBody CreateTrainingSessionRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return trainingService.createSession(principal.getUserId(), request);
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/controller/WeightController.java
===================================================================
--- backend/src/main/java/com/trekr/backend/controller/WeightController.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,97 +1,0 @@
-package com.trekr.backend.controller;
-
-import com.trekr.backend.dto.weight.CreateDailyIntakeRequest;
-import com.trekr.backend.dto.weight.TrackingStatusResponse;
-import com.trekr.backend.dto.weight.WeightDailyIntakeDto;
-import com.trekr.backend.dto.weight.WeightDailyIntakesResponse;
-import com.trekr.backend.dto.weight.WeightProfileResponse;
-import com.trekr.backend.dto.weight.WeightStartRequest;
-import com.trekr.backend.dto.weight.TodayTrainingInfoDto;
-import com.trekr.backend.security.UserPrincipal;
-import com.trekr.backend.service.WeightService;
-import jakarta.validation.Valid;
-import org.springframework.http.HttpStatus;
-import org.springframework.security.core.Authentication;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseStatus;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-@RequestMapping("/api/weight")
-public class WeightController {
-
-    private final WeightService weightService;
-
-    public WeightController(WeightService weightService) {
-        this.weightService = weightService;
-    }
-
-    @GetMapping("/status")
-    public TrackingStatusResponse status(Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return new TrackingStatusResponse(weightService.isTracking(principal.getUserId()));
-    }
-
-    @PostMapping("/start")
-    @ResponseStatus(HttpStatus.CREATED)
-    public TrackingStatusResponse start(
-            @Valid @RequestBody WeightStartRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        weightService.startTracking(principal.getUserId(), request);
-        return new TrackingStatusResponse(true);
-    }
-
-    @GetMapping("/profile")
-    public WeightProfileResponse profile(Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return weightService.getProfile(principal.getUserId());
-    }
-
-    @GetMapping("/intakes")
-    public WeightDailyIntakesResponse intakes(
-            @RequestParam(defaultValue = "0") int page,
-            @RequestParam(defaultValue = "5") int size,
-            Authentication authentication) {
-        if (size < 1) {
-            size = 5;
-        }
-        if (size > 50) {
-            size = 50;
-        }
-        if (page < 0) {
-            page = 0;
-        }
-
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return weightService.getDailyIntakes(principal.getUserId(), page, size);
-    }
-
-    @PostMapping("/intakes")
-    @ResponseStatus(HttpStatus.CREATED)
-    public WeightDailyIntakeDto createDailyIntake(
-            @Valid @RequestBody CreateDailyIntakeRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return weightService.createDailyIntake(principal.getUserId(), request);
-    }
-
-    @PutMapping("/profile")
-    public WeightProfileResponse updateProfile(
-            @Valid @RequestBody WeightStartRequest request,
-            Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return weightService.updateProfile(principal.getUserId(), request);
-    }
-
-    @GetMapping("/today-training")
-    public TodayTrainingInfoDto getTodayTrainingInfo(Authentication authentication) {
-        UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
-        return weightService.getTodayTrainingInfo(principal.getUserId());
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/auth/AuthResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/auth/AuthResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,60 +1,0 @@
-package com.trekr.backend.dto.auth;
-
-public class AuthResponse {
-    private String token;
-    private String type = "Bearer";
-    private Long userId;
-    private String username;
-    private String email;
-
-    public AuthResponse() {
-    }
-
-    public AuthResponse(String token, String type, Long userId, String username, String email) {
-        this.token = token;
-        this.type = type;
-        this.userId = userId;
-        this.username = username;
-        this.email = email;
-    }
-
-    public String getToken() {
-        return token;
-    }
-
-    public void setToken(String token) {
-        this.token = token;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    public String getEmail() {
-        return email;
-    }
-
-    public void setEmail(String email) {
-        this.email = email;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/auth/LoginRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/auth/LoginRequest.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,31 +1,0 @@
-package com.trekr.backend.dto.auth;
-
-import jakarta.validation.constraints.NotBlank;
-
-public class LoginRequest {
-
-    @NotBlank(message = "Username or email is required")
-    private String usernameOrEmail;
-
-    @NotBlank(message = "Password is required")
-    private String password;
-
-    public LoginRequest() {
-    }
-
-    public String getUsernameOrEmail() {
-        return usernameOrEmail;
-    }
-
-    public void setUsernameOrEmail(String usernameOrEmail) {
-        this.usernameOrEmail = usernameOrEmail;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/auth/RegisterRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/auth/RegisterRequest.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,47 +1,0 @@
-package com.trekr.backend.dto.auth;
-
-import jakarta.validation.constraints.Email;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.Size;
-
-public class RegisterRequest {
-
-    @NotBlank(message = "Email is required")
-    @Email(message = "Email must be valid")
-    private String email;
-
-    @NotBlank(message = "Username is required")
-    @Size(min = 3, max = 50, message = "Username must be between 3 and 50 characters")
-    private String username;
-
-    @NotBlank(message = "Password is required")
-    @Size(min = 6, message = "Password must be at least 6 characters")
-    private String password;
-
-    public RegisterRequest() {
-    }
-
-    public String getEmail() {
-        return email;
-    }
-
-    public void setEmail(String email) {
-        this.email = email;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/discipline/ComputeDailyCompletionResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/discipline/ComputeDailyCompletionResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,5 +1,0 @@
-package com.trekr.backend.dto.discipline;
-
-public record ComputeDailyCompletionResponse(boolean created, DailyCompletionDto completion) {
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/discipline/CreateCustomTrackingCategoryRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/discipline/CreateCustomTrackingCategoryRequest.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,29 +1,0 @@
-
-package com.trekr.backend.dto.discipline;
-
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.Size;
-
-public class CreateCustomTrackingCategoryRequest {
-
-	@NotBlank(message = "Name is required")
-	@Size(max = 100, message = "Name must be at most 100 characters")
-	private String name;
-
-	public CreateCustomTrackingCategoryRequest() {
-	}
-
-	public CreateCustomTrackingCategoryRequest(String name) {
-		this.name = name;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-}
-
-
Index: ckend/src/main/java/com/trekr/backend/dto/discipline/CreateTaskRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/discipline/CreateTaskRequest.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,30 +1,0 @@
-package com.trekr.backend.dto.discipline;
-
-import jakarta.validation.constraints.NotBlank;
-
-import java.time.LocalDate;
-
-public class CreateTaskRequest {
-
-    @NotBlank
-    private String name;
-
-    private String description;
-    private LocalDate dueDate;
-    private String priority;
-
-    public CreateTaskRequest() {
-    }
-
-    public String getName() { return name; }
-    public void setName(String name) { this.name = name; }
-
-    public String getDescription() { return description; }
-    public void setDescription(String description) { this.description = description; }
-
-    public LocalDate getDueDate() { return dueDate; }
-    public void setDueDate(LocalDate dueDate) { this.dueDate = dueDate; }
-
-    public String getPriority() { return priority; }
-    public void setPriority(String priority) { this.priority = priority; }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/discipline/CustomTrackingCategoriesResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/discipline/CustomTrackingCategoriesResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,26 +1,0 @@
-
-package com.trekr.backend.dto.discipline;
-
-import java.util.List;
-
-public class CustomTrackingCategoriesResponse {
-
-	private List<CustomTrackingCategoryDto> items;
-
-	public CustomTrackingCategoriesResponse() {
-	}
-
-	public CustomTrackingCategoriesResponse(List<CustomTrackingCategoryDto> items) {
-		this.items = items;
-	}
-
-	public List<CustomTrackingCategoryDto> getItems() {
-		return items;
-	}
-
-	public void setItems(List<CustomTrackingCategoryDto> items) {
-		this.items = items;
-	}
-}
-
-
Index: ckend/src/main/java/com/trekr/backend/dto/discipline/CustomTrackingCategoryDto.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/discipline/CustomTrackingCategoryDto.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,34 +1,0 @@
-
-package com.trekr.backend.dto.discipline;
-
-public class CustomTrackingCategoryDto {
-
-	private Long customTrackingId;
-	private String name;
-
-	public CustomTrackingCategoryDto() {
-	}
-
-	public CustomTrackingCategoryDto(Long customTrackingId, String name) {
-		this.customTrackingId = customTrackingId;
-		this.name = name;
-	}
-
-	public Long getCustomTrackingId() {
-		return customTrackingId;
-	}
-
-	public void setCustomTrackingId(Long customTrackingId) {
-		this.customTrackingId = customTrackingId;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-}
-
-
Index: ckend/src/main/java/com/trekr/backend/dto/discipline/DailyCompletionDto.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/discipline/DailyCompletionDto.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package com.trekr.backend.dto.discipline;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-public record DailyCompletionDto(Long dailyCompletionId, LocalDate date, BigDecimal procent) {
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/discipline/DailyCompletionsResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/discipline/DailyCompletionsResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package com.trekr.backend.dto.discipline;
-
-import java.util.List;
-
-public record DailyCompletionsResponse(List<DailyCompletionDto> completions, boolean hasMore) {
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/discipline/TaskDto.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/discipline/TaskDto.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,16 +1,0 @@
-package com.trekr.backend.dto.discipline;
-
-import com.trekr.backend.entity.discipline.TaskStatus;
-
-import java.time.LocalDate;
-
-public record TaskDto(
-        Long taskId,
-        String name,
-        boolean isFinished,
-        TaskStatus status,
-        String description,
-        LocalDate dueDate,
-        String priority
-) {
-}
Index: ckend/src/main/java/com/trekr/backend/dto/discipline/TasksResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/discipline/TasksResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package com.trekr.backend.dto.discipline;
-
-import java.util.List;
-
-public record TasksResponse(List<TaskDto> tasks, boolean hasMore) {
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/discipline/TrackingStatusResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/discipline/TrackingStatusResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,5 +1,0 @@
-package com.trekr.backend.dto.discipline;
-
-public record TrackingStatusResponse(boolean tracking) {
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/discipline/UpdateTaskFinishedRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/discipline/UpdateTaskFinishedRequest.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,21 +1,0 @@
-package com.trekr.backend.dto.discipline;
-
-import jakarta.validation.constraints.NotNull;
-
-public class UpdateTaskFinishedRequest {
-
-    @NotNull
-    private Boolean isFinished;
-
-    public UpdateTaskFinishedRequest() {
-    }
-
-    public Boolean getIsFinished() {
-        return isFinished;
-    }
-
-    public void setIsFinished(Boolean isFinished) {
-        this.isFinished = isFinished;
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/discipline/UpdateTaskRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/discipline/UpdateTaskRequest.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,35 +1,0 @@
-package com.trekr.backend.dto.discipline;
-
-import com.trekr.backend.entity.discipline.TaskStatus;
-import jakarta.validation.constraints.NotBlank;
-
-import java.time.LocalDate;
-
-public class UpdateTaskRequest {
-
-    @NotBlank
-    private String name;
-
-    private String description;
-    private LocalDate dueDate;
-    private String priority;
-    private TaskStatus status;
-
-    public UpdateTaskRequest() {
-    }
-
-    public String getName() { return name; }
-    public void setName(String name) { this.name = name; }
-
-    public String getDescription() { return description; }
-    public void setDescription(String description) { this.description = description; }
-
-    public LocalDate getDueDate() { return dueDate; }
-    public void setDueDate(LocalDate dueDate) { this.dueDate = dueDate; }
-
-    public String getPriority() { return priority; }
-    public void setPriority(String priority) { this.priority = priority; }
-
-    public TaskStatus getStatus() { return status; }
-    public void setStatus(TaskStatus status) { this.status = status; }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/discipline/UpdateTaskStatusRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/discipline/UpdateTaskStatusRequest.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,19 +1,0 @@
-package com.trekr.backend.dto.discipline;
-
-import com.trekr.backend.entity.discipline.TaskStatus;
-
-public class UpdateTaskStatusRequest {
-    private TaskStatus status;
-
-    public UpdateTaskStatusRequest() {
-    }
-
-    public TaskStatus getStatus() {
-        return status;
-    }
-
-    public void setStatus(TaskStatus status) {
-        this.status = status;
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/finance/CreateIncomeRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/finance/CreateIncomeRequest.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,35 +1,0 @@
-package com.trekr.backend.dto.finance;
-
-import jakarta.validation.constraints.NotNull;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-public class CreateIncomeRequest {
-
-    @NotNull
-    private LocalDate date;
-
-    @NotNull
-    private BigDecimal amount;
-
-    public CreateIncomeRequest() {
-    }
-
-    public LocalDate getDate() {
-        return date;
-    }
-
-    public void setDate(LocalDate date) {
-        this.date = date;
-    }
-
-    public BigDecimal getAmount() {
-        return amount;
-    }
-
-    public void setAmount(BigDecimal amount) {
-        this.amount = amount;
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/finance/FinanceProfileResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/finance/FinanceProfileResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package com.trekr.backend.dto.finance;
-
-import java.math.BigDecimal;
-
-public record FinanceProfileResponse(
-        BigDecimal spendingBudget,
-        BigDecimal savingBudget,
-        BigDecimal investingBudget,
-        BigDecimal donationBudget,
-        BigDecimal credit) {
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/finance/FinanceStartRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/finance/FinanceStartRequest.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,67 +1,0 @@
-package com.trekr.backend.dto.finance;
-
-import jakarta.validation.constraints.NotNull;
-
-import java.math.BigDecimal;
-
-public class FinanceStartRequest {
-
-    @NotNull
-    private BigDecimal spendingBudget;
-
-    @NotNull
-    private BigDecimal savingBudget;
-
-    @NotNull
-    private BigDecimal investingBudget;
-
-    @NotNull
-    private BigDecimal donationBudget;
-
-    @NotNull
-    private BigDecimal credit;
-
-    public FinanceStartRequest() {
-    }
-
-    public BigDecimal getSpendingBudget() {
-        return spendingBudget;
-    }
-
-    public void setSpendingBudget(BigDecimal spendingBudget) {
-        this.spendingBudget = spendingBudget;
-    }
-
-    public BigDecimal getSavingBudget() {
-        return savingBudget;
-    }
-
-    public void setSavingBudget(BigDecimal savingBudget) {
-        this.savingBudget = savingBudget;
-    }
-
-    public BigDecimal getInvestingBudget() {
-        return investingBudget;
-    }
-
-    public void setInvestingBudget(BigDecimal investingBudget) {
-        this.investingBudget = investingBudget;
-    }
-
-    public BigDecimal getDonationBudget() {
-        return donationBudget;
-    }
-
-    public void setDonationBudget(BigDecimal donationBudget) {
-        this.donationBudget = donationBudget;
-    }
-
-    public BigDecimal getCredit() {
-        return credit;
-    }
-
-    public void setCredit(BigDecimal credit) {
-        this.credit = credit;
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/finance/IncomeDto.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/finance/IncomeDto.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,11 +1,0 @@
-package com.trekr.backend.dto.finance;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-public record IncomeDto(
-        Long incomeId,
-        LocalDate date,
-        BigDecimal amount) {
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/finance/IncomesResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/finance/IncomesResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,7 +1,0 @@
-package com.trekr.backend.dto.finance;
-
-import java.util.List;
-
-public record IncomesResponse(List<IncomeDto> incomes, boolean hasMore) {
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/finance/TrackingStatusResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/finance/TrackingStatusResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,5 +1,0 @@
-package com.trekr.backend.dto.finance;
-
-public record TrackingStatusResponse(boolean tracking) {
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/invest/AssetDto.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/invest/AssetDto.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,64 +1,0 @@
-package com.trekr.backend.dto.invest;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-public class AssetDto {
-
-    private Long assetId;
-    private String tickerSymbol;
-    private BigDecimal buyPrice;
-    private LocalDate buyDate;
-    private BigDecimal quantity;
-
-    public AssetDto() {
-    }
-
-    public AssetDto(Long assetId, String tickerSymbol, BigDecimal buyPrice, LocalDate buyDate, BigDecimal quantity) {
-        this.assetId = assetId;
-        this.tickerSymbol = tickerSymbol;
-        this.buyPrice = buyPrice;
-        this.buyDate = buyDate;
-        this.quantity = quantity;
-    }
-
-    public Long getAssetId() {
-        return assetId;
-    }
-
-    public void setAssetId(Long assetId) {
-        this.assetId = assetId;
-    }
-
-    public String getTickerSymbol() {
-        return tickerSymbol;
-    }
-
-    public void setTickerSymbol(String tickerSymbol) {
-        this.tickerSymbol = tickerSymbol;
-    }
-
-    public BigDecimal getBuyPrice() {
-        return buyPrice;
-    }
-
-    public void setBuyPrice(BigDecimal buyPrice) {
-        this.buyPrice = buyPrice;
-    }
-
-    public LocalDate getBuyDate() {
-        return buyDate;
-    }
-
-    public void setBuyDate(LocalDate buyDate) {
-        this.buyDate = buyDate;
-    }
-
-    public BigDecimal getQuantity() {
-        return quantity;
-    }
-
-    public void setQuantity(BigDecimal quantity) {
-        this.quantity = quantity;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/invest/CreateAssetRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/invest/CreateAssetRequest.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,60 +1,0 @@
-package com.trekr.backend.dto.invest;
-
-import jakarta.validation.constraints.DecimalMin;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.PastOrPresent;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-public class CreateAssetRequest {
-
-    @NotBlank
-    private String tickerSymbol;
-
-    @NotNull
-    @DecimalMin(value = "0", inclusive = false)
-    private BigDecimal quantity;
-
-    @DecimalMin(value = "0", inclusive = true)
-    private BigDecimal buyPrice;
-
-    @PastOrPresent
-    private LocalDate buyDate;
-
-    public CreateAssetRequest() {
-    }
-
-    public String getTickerSymbol() {
-        return tickerSymbol;
-    }
-
-    public void setTickerSymbol(String tickerSymbol) {
-        this.tickerSymbol = tickerSymbol;
-    }
-
-    public BigDecimal getQuantity() {
-        return quantity;
-    }
-
-    public void setQuantity(BigDecimal quantity) {
-        this.quantity = quantity;
-    }
-
-    public BigDecimal getBuyPrice() {
-        return buyPrice;
-    }
-
-    public void setBuyPrice(BigDecimal buyPrice) {
-        this.buyPrice = buyPrice;
-    }
-
-    public LocalDate getBuyDate() {
-        return buyDate;
-    }
-
-    public void setBuyDate(LocalDate buyDate) {
-        this.buyDate = buyDate;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/invest/InvestingAssetsResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/invest/InvestingAssetsResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,33 +1,0 @@
-package com.trekr.backend.dto.invest;
-
-import java.util.List;
-
-public class InvestingAssetsResponse {
-
-    private List<AssetDto> assets;
-    private boolean hasMore;
-
-    public InvestingAssetsResponse() {
-    }
-
-    public InvestingAssetsResponse(List<AssetDto> assets, boolean hasMore) {
-        this.assets = assets;
-        this.hasMore = hasMore;
-    }
-
-    public List<AssetDto> getAssets() {
-        return assets;
-    }
-
-    public void setAssets(List<AssetDto> assets) {
-        this.assets = assets;
-    }
-
-    public boolean isHasMore() {
-        return hasMore;
-    }
-
-    public void setHasMore(boolean hasMore) {
-        this.hasMore = hasMore;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/invest/TrackingStatusResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/invest/TrackingStatusResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,21 +1,0 @@
-package com.trekr.backend.dto.invest;
-
-public class TrackingStatusResponse {
-
-    private boolean tracking;
-
-    public TrackingStatusResponse() {
-    }
-
-    public TrackingStatusResponse(boolean tracking) {
-        this.tracking = tracking;
-    }
-
-    public boolean isTracking() {
-        return tracking;
-    }
-
-    public void setTracking(boolean tracking) {
-        this.tracking = tracking;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/training/CreateTrainingSessionRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/training/CreateTrainingSessionRequest.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,71 +1,0 @@
-package com.trekr.backend.dto.training;
-
-import jakarta.validation.constraints.DecimalMin;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.PastOrPresent;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-public class CreateTrainingSessionRequest {
-
-    @NotBlank
-    private String type;
-
-    @NotNull
-    @DecimalMin(value = "1", inclusive = true)
-    private BigDecimal durationMinutes;
-
-    @NotNull
-    private Boolean autoCalculateCalories;
-
-    @DecimalMin(value = "0", inclusive = true)
-    private BigDecimal calories;
-
-    @PastOrPresent
-    private LocalDate date;
-
-    public CreateTrainingSessionRequest() {
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public BigDecimal getDurationMinutes() {
-        return durationMinutes;
-    }
-
-    public void setDurationMinutes(BigDecimal durationMinutes) {
-        this.durationMinutes = durationMinutes;
-    }
-
-    public Boolean getAutoCalculateCalories() {
-        return autoCalculateCalories;
-    }
-
-    public void setAutoCalculateCalories(Boolean autoCalculateCalories) {
-        this.autoCalculateCalories = autoCalculateCalories;
-    }
-
-    public BigDecimal getCalories() {
-        return calories;
-    }
-
-    public void setCalories(BigDecimal calories) {
-        this.calories = calories;
-    }
-
-    public LocalDate getDate() {
-        return date;
-    }
-
-    public void setDate(LocalDate date) {
-        this.date = date;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/training/TrackingStatusResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/training/TrackingStatusResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,21 +1,0 @@
-package com.trekr.backend.dto.training;
-
-public class TrackingStatusResponse {
-
-    private boolean tracking;
-
-    public TrackingStatusResponse() {
-    }
-
-    public TrackingStatusResponse(boolean tracking) {
-        this.tracking = tracking;
-    }
-
-    public boolean isTracking() {
-        return tracking;
-    }
-
-    public void setTracking(boolean tracking) {
-        this.tracking = tracking;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/training/TrainingProfileResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/training/TrainingProfileResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,43 +1,0 @@
-package com.trekr.backend.dto.training;
-
-import java.math.BigDecimal;
-
-public class TrainingProfileResponse {
-
-    private String gender;
-    private Integer age;
-    private BigDecimal weight;
-
-    public TrainingProfileResponse() {
-    }
-
-    public TrainingProfileResponse(String gender, Integer age, BigDecimal weight) {
-        this.gender = gender;
-        this.age = age;
-        this.weight = weight;
-    }
-
-    public String getGender() {
-        return gender;
-    }
-
-    public void setGender(String gender) {
-        this.gender = gender;
-    }
-
-    public Integer getAge() {
-        return age;
-    }
-
-    public void setAge(Integer age) {
-        this.age = age;
-    }
-
-    public BigDecimal getWeight() {
-        return weight;
-    }
-
-    public void setWeight(BigDecimal weight) {
-        this.weight = weight;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/training/TrainingSessionDto.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/training/TrainingSessionDto.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,64 +1,0 @@
-package com.trekr.backend.dto.training;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-public class TrainingSessionDto {
-
-    private Long trainingId;
-    private LocalDate date;
-    private String type;
-    private BigDecimal duration;
-    private BigDecimal calories;
-
-    public TrainingSessionDto() {
-    }
-
-    public TrainingSessionDto(Long trainingId, LocalDate date, String type, BigDecimal duration, BigDecimal calories) {
-        this.trainingId = trainingId;
-        this.date = date;
-        this.type = type;
-        this.duration = duration;
-        this.calories = calories;
-    }
-
-    public Long getTrainingId() {
-        return trainingId;
-    }
-
-    public void setTrainingId(Long trainingId) {
-        this.trainingId = trainingId;
-    }
-
-    public LocalDate getDate() {
-        return date;
-    }
-
-    public void setDate(LocalDate date) {
-        this.date = date;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public BigDecimal getDuration() {
-        return duration;
-    }
-
-    public void setDuration(BigDecimal duration) {
-        this.duration = duration;
-    }
-
-    public BigDecimal getCalories() {
-        return calories;
-    }
-
-    public void setCalories(BigDecimal calories) {
-        this.calories = calories;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/training/TrainingSessionsResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/training/TrainingSessionsResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,33 +1,0 @@
-package com.trekr.backend.dto.training;
-
-import java.util.List;
-
-public class TrainingSessionsResponse {
-
-    private List<TrainingSessionDto> sessions;
-    private boolean hasMore;
-
-    public TrainingSessionsResponse() {
-    }
-
-    public TrainingSessionsResponse(List<TrainingSessionDto> sessions, boolean hasMore) {
-        this.sessions = sessions;
-        this.hasMore = hasMore;
-    }
-
-    public List<TrainingSessionDto> getSessions() {
-        return sessions;
-    }
-
-    public void setSessions(List<TrainingSessionDto> sessions) {
-        this.sessions = sessions;
-    }
-
-    public boolean isHasMore() {
-        return hasMore;
-    }
-
-    public void setHasMore(boolean hasMore) {
-        this.hasMore = hasMore;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/training/TrainingStartRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/training/TrainingStartRequest.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,50 +1,0 @@
-package com.trekr.backend.dto.training;
-
-import jakarta.validation.constraints.Max;
-import jakarta.validation.constraints.Min;
-import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
-
-import java.math.BigDecimal;
-
-public class TrainingStartRequest {
-
-    @NotBlank(message = "Gender is required")
-    private String gender;
-
-    @NotNull(message = "Age is required")
-    @Min(value = 1, message = "Age must be greater than 0")
-    @Max(value = 120, message = "Age must be realistic")
-    private Integer age;
-
-    @NotNull(message = "Weight is required")
-    @Min(value = 1, message = "Weight must be greater than 0")
-    private BigDecimal weight;
-
-    public TrainingStartRequest() {
-    }
-
-    public String getGender() {
-        return gender;
-    }
-
-    public void setGender(String gender) {
-        this.gender = gender;
-    }
-
-    public Integer getAge() {
-        return age;
-    }
-
-    public void setAge(Integer age) {
-        this.age = age;
-    }
-
-    public BigDecimal getWeight() {
-        return weight;
-    }
-
-    public void setWeight(BigDecimal weight) {
-        this.weight = weight;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/training/WorkoutTypeDto.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/training/WorkoutTypeDto.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,43 +1,0 @@
-package com.trekr.backend.dto.training;
-
-import java.math.BigDecimal;
-
-public class WorkoutTypeDto {
-
-    private String type;
-    private String label;
-    private BigDecimal met;
-
-    public WorkoutTypeDto() {
-    }
-
-    public WorkoutTypeDto(String type, String label, BigDecimal met) {
-        this.type = type;
-        this.label = label;
-        this.met = met;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public String getLabel() {
-        return label;
-    }
-
-    public void setLabel(String label) {
-        this.label = label;
-    }
-
-    public BigDecimal getMet() {
-        return met;
-    }
-
-    public void setMet(BigDecimal met) {
-        this.met = met;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/dto/weight/CreateDailyIntakeRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/weight/CreateDailyIntakeRequest.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,22 +1,0 @@
-package com.trekr.backend.dto.weight;
-
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.PositiveOrZero;
-
-import java.math.BigDecimal;
-
-public class CreateDailyIntakeRequest {
-
-    @NotNull(message = "Calories are required")
-    @PositiveOrZero(message = "Calories must be 0 or greater")
-    private BigDecimal calories;
-
-    public BigDecimal getCalories() {
-        return calories;
-    }
-
-    public void setCalories(BigDecimal calories) {
-        this.calories = calories;
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/weight/TodayTrainingInfoDto.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/weight/TodayTrainingInfoDto.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,34 +1,0 @@
-package com.trekr.backend.dto.weight;
-
-import java.math.BigDecimal;
-
-public class TodayTrainingInfoDto {
-
-    private boolean trainedToday;
-    private BigDecimal totalBurnedCalories;
-
-    public TodayTrainingInfoDto() {
-    }
-
-    public TodayTrainingInfoDto(boolean trainedToday, BigDecimal totalBurnedCalories) {
-        this.trainedToday = trainedToday;
-        this.totalBurnedCalories = totalBurnedCalories;
-    }
-
-    public boolean isTrainedToday() {
-        return trainedToday;
-    }
-
-    public void setTrainedToday(boolean trainedToday) {
-        this.trainedToday = trainedToday;
-    }
-
-    public BigDecimal getTotalBurnedCalories() {
-        return totalBurnedCalories;
-    }
-
-    public void setTotalBurnedCalories(BigDecimal totalBurnedCalories) {
-        this.totalBurnedCalories = totalBurnedCalories;
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/weight/TrackingStatusResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/weight/TrackingStatusResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,22 +1,0 @@
-package com.trekr.backend.dto.weight;
-
-public class TrackingStatusResponse {
-
-    private boolean tracking;
-
-    public TrackingStatusResponse() {
-    }
-
-    public TrackingStatusResponse(boolean tracking) {
-        this.tracking = tracking;
-    }
-
-    public boolean isTracking() {
-        return tracking;
-    }
-
-    public void setTracking(boolean tracking) {
-        this.tracking = tracking;
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/weight/WeightDailyIntakeDto.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/weight/WeightDailyIntakeDto.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,73 +1,0 @@
-package com.trekr.backend.dto.weight;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-public class WeightDailyIntakeDto {
-
-    private Long dailyIntakeId;
-    private LocalDate date;
-    private BigDecimal calories;
-    private boolean trainedThatDay;
-    private BigDecimal burnedCalories;
-
-    public WeightDailyIntakeDto() {
-    }
-
-    public WeightDailyIntakeDto(Long dailyIntakeId, LocalDate date, BigDecimal calories) {
-        this.dailyIntakeId = dailyIntakeId;
-        this.date = date;
-        this.calories = calories;
-        this.trainedThatDay = false;
-        this.burnedCalories = BigDecimal.ZERO;
-    }
-
-    public WeightDailyIntakeDto(Long dailyIntakeId, LocalDate date, BigDecimal calories, boolean trainedThatDay, BigDecimal burnedCalories) {
-        this.dailyIntakeId = dailyIntakeId;
-        this.date = date;
-        this.calories = calories;
-        this.trainedThatDay = trainedThatDay;
-        this.burnedCalories = burnedCalories;
-    }
-
-    public Long getDailyIntakeId() {
-        return dailyIntakeId;
-    }
-
-    public void setDailyIntakeId(Long dailyIntakeId) {
-        this.dailyIntakeId = dailyIntakeId;
-    }
-
-    public LocalDate getDate() {
-        return date;
-    }
-
-    public void setDate(LocalDate date) {
-        this.date = date;
-    }
-
-    public BigDecimal getCalories() {
-        return calories;
-    }
-
-    public void setCalories(BigDecimal calories) {
-        this.calories = calories;
-    }
-
-    public boolean isTrainedThatDay() {
-        return trainedThatDay;
-    }
-
-    public void setTrainedThatDay(boolean trainedThatDay) {
-        this.trainedThatDay = trainedThatDay;
-    }
-
-    public BigDecimal getBurnedCalories() {
-        return burnedCalories;
-    }
-
-    public void setBurnedCalories(BigDecimal burnedCalories) {
-        this.burnedCalories = burnedCalories;
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/weight/WeightDailyIntakesResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/weight/WeightDailyIntakesResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,44 +1,0 @@
-package com.trekr.backend.dto.weight;
-
-import java.util.List;
-
-public class WeightDailyIntakesResponse {
-
-    private List<WeightDailyIntakeDto> intakes;
-    private boolean hasMore;
-    private boolean hasTodayIntake;
-
-    public WeightDailyIntakesResponse() {
-    }
-
-    public WeightDailyIntakesResponse(List<WeightDailyIntakeDto> intakes, boolean hasMore, boolean hasTodayIntake) {
-        this.intakes = intakes;
-        this.hasMore = hasMore;
-        this.hasTodayIntake = hasTodayIntake;
-    }
-
-    public List<WeightDailyIntakeDto> getIntakes() {
-        return intakes;
-    }
-
-    public void setIntakes(List<WeightDailyIntakeDto> intakes) {
-        this.intakes = intakes;
-    }
-
-    public boolean isHasMore() {
-        return hasMore;
-    }
-
-    public void setHasMore(boolean hasMore) {
-        this.hasMore = hasMore;
-    }
-
-    public boolean isHasTodayIntake() {
-        return hasTodayIntake;
-    }
-
-    public void setHasTodayIntake(boolean hasTodayIntake) {
-        this.hasTodayIntake = hasTodayIntake;
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/weight/WeightProfileResponse.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/weight/WeightProfileResponse.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,56 +1,0 @@
-package com.trekr.backend.dto.weight;
-
-import java.math.BigDecimal;
-
-public class WeightProfileResponse {
-
-    private BigDecimal weight;
-    private BigDecimal height;
-    private BigDecimal goalWeight;
-    private BigDecimal goalCalories;
-
-    public WeightProfileResponse() {
-    }
-
-    public WeightProfileResponse(BigDecimal weight, BigDecimal height, BigDecimal goalWeight,
-            BigDecimal goalCalories) {
-        this.weight = weight;
-        this.height = height;
-        this.goalWeight = goalWeight;
-        this.goalCalories = goalCalories;
-    }
-
-    public BigDecimal getWeight() {
-        return weight;
-    }
-
-    public void setWeight(BigDecimal weight) {
-        this.weight = weight;
-    }
-
-    public BigDecimal getHeight() {
-        return height;
-    }
-
-    public void setHeight(BigDecimal height) {
-        this.height = height;
-    }
-
-    public BigDecimal getGoalWeight() {
-        return goalWeight;
-    }
-
-    public void setGoalWeight(BigDecimal goalWeight) {
-        this.goalWeight = goalWeight;
-    }
-
-
-    public BigDecimal getGoalCalories() {
-        return goalCalories;
-    }
-
-    public void setGoalCalories(BigDecimal goalCalories) {
-        this.goalCalories = goalCalories;
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/dto/weight/WeightStartRequest.java
===================================================================
--- backend/src/main/java/com/trekr/backend/dto/weight/WeightStartRequest.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,69 +1,0 @@
-package com.trekr.backend.dto.weight;
-
-import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Positive;
-import jakarta.validation.constraints.PositiveOrZero;
-
-import java.math.BigDecimal;
-
-public class WeightStartRequest {
-
-    @NotNull(message = "Current weight is required")
-    @Positive(message = "Current weight must be greater than 0")
-    private BigDecimal weight;
-
-    @NotNull(message = "Height is required")
-    @Positive(message = "Height must be greater than 0")
-    private BigDecimal height;
-
-    @NotNull(message = "Goal weight is required")
-    @Positive(message = "Goal weight must be greater than 0")
-    private BigDecimal goalWeight;
-
-    @PositiveOrZero(message = "Goal calories must be 0 or greater")
-    private BigDecimal goalCalories;
-
-    private Boolean autoCalculateTargets = Boolean.TRUE;
-
-    public BigDecimal getWeight() {
-        return weight;
-    }
-
-    public void setWeight(BigDecimal weight) {
-        this.weight = weight;
-    }
-
-    public BigDecimal getHeight() {
-        return height;
-    }
-
-    public void setHeight(BigDecimal height) {
-        this.height = height;
-    }
-
-    public BigDecimal getGoalWeight() {
-        return goalWeight;
-    }
-
-    public void setGoalWeight(BigDecimal goalWeight) {
-        this.goalWeight = goalWeight;
-    }
-
-
-    public BigDecimal getGoalCalories() {
-        return goalCalories;
-    }
-
-    public void setGoalCalories(BigDecimal goalCalories) {
-        this.goalCalories = goalCalories;
-    }
-
-    public Boolean getAutoCalculateTargets() {
-        return autoCalculateTargets;
-    }
-
-    public void setAutoCalculateTargets(Boolean autoCalculateTargets) {
-        this.autoCalculateTargets = autoCalculateTargets;
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/entity/User.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/User.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,64 +1,0 @@
-package com.trekr.backend.entity;
-
-import jakarta.persistence.*;
-
-@Entity
-@Table(name = "USERS", schema = "trekr")
-public class User {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "user_id")
-    private Long userId;
-
-    @Column(name = "email", nullable = false, unique = true)
-    private String email;
-
-    @Column(name = "username", nullable = false, unique = true)
-    private String username;
-
-    @Column(name = "password", nullable = false)
-    private String password;
-
-    public User() {
-    }
-
-    public User(Long userId, String email, String username, String password) {
-        this.userId = userId;
-        this.email = email;
-        this.username = username;
-        this.password = password;
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public String getEmail() {
-        return email;
-    }
-
-    public void setEmail(String email) {
-        this.email = email;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public void setUsername(String username) {
-        this.username = username;
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public void setPassword(String password) {
-        this.password = password;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/entity/discipline/CustomTrackingCategory.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/discipline/CustomTrackingCategory.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,56 +1,0 @@
-package com.trekr.backend.entity.discipline;
-
-import com.trekr.backend.entity.User;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
-
-@Entity
-@Table(name = "CUSTOM_TRACKING_CATEGORIES", schema = "trekr")
-public class CustomTrackingCategory {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "custom_tracking_id")
-    private Long customTrackingId;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "user_id")
-    private User user;
-
-    @Column(name = "name", nullable = false)
-    private String name;
-
-    public CustomTrackingCategory() {
-    }
-
-    public Long getCustomTrackingId() {
-        return customTrackingId;
-    }
-
-    public void setCustomTrackingId(Long customTrackingId) {
-        this.customTrackingId = customTrackingId;
-    }
-
-    public User getUser() {
-        return user;
-    }
-
-    public void setUser(User user) {
-        this.user = user;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/entity/discipline/DailyCompletion.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/discipline/DailyCompletion.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,70 +1,0 @@
-package com.trekr.backend.entity.discipline;
-
-import com.trekr.backend.entity.User;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-@Entity
-@Table(name = "DAILY_COMPLETION", schema = "trekr")
-public class DailyCompletion {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "daily_completion_id")
-    private Long dailyCompletionId;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "user_id")
-    private User user;
-
-    @Column(name = "date")
-    private LocalDate date;
-
-    @Column(name = "procent")
-    private BigDecimal procent;
-
-    public DailyCompletion() {
-    }
-
-    public Long getDailyCompletionId() {
-        return dailyCompletionId;
-    }
-
-    public void setDailyCompletionId(Long dailyCompletionId) {
-        this.dailyCompletionId = dailyCompletionId;
-    }
-
-    public User getUser() {
-        return user;
-    }
-
-    public void setUser(User user) {
-        this.user = user;
-    }
-
-    public LocalDate getDate() {
-        return date;
-    }
-
-    public void setDate(LocalDate date) {
-        this.date = date;
-    }
-
-    public BigDecimal getProcent() {
-        return procent;
-    }
-
-    public void setProcent(BigDecimal procent) {
-        this.procent = procent;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/entity/discipline/DisciplineUser.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/discipline/DisciplineUser.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,44 +1,0 @@
-package com.trekr.backend.entity.discipline;
-
-import com.trekr.backend.entity.User;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.MapsId;
-import jakarta.persistence.OneToOne;
-import jakarta.persistence.Table;
-
-@Entity
-@Table(name = "DISCIPLINE_USERS", schema = "trekr")
-public class DisciplineUser {
-
-    @Id
-    @Column(name = "user_id")
-    private Long userId;
-
-    @OneToOne(fetch = FetchType.LAZY, optional = false)
-    @MapsId
-    @JoinColumn(name = "user_id")
-    private User user;
-
-    public DisciplineUser() {
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public User getUser() {
-        return user;
-    }
-
-    public void setUser(User user) {
-        this.user = user;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/entity/discipline/Task.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/discipline/Task.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,83 +1,0 @@
-package com.trekr.backend.entity.discipline;
-
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.EnumType;
-import jakarta.persistence.Enumerated;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
-
-import java.time.LocalDate;
-
-@Entity
-@Table(name = "TASKS", schema = "trekr")
-public class Task {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "task_id")
-    private Long taskId;
-
-    @Column(name = "name", nullable = false)
-    private String name;
-
-    @Enumerated(EnumType.STRING)
-    @Column(name = "status", nullable = false)
-    private TaskStatus status = TaskStatus.NOT_STARTED;
-
-    @Column(name = "description")
-    private String description;
-
-    @Column(name = "due_date")
-    private LocalDate dueDate;
-
-    @Column(name = "priority")
-    private String priority;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "discipline_user_id")
-    private DisciplineUser disciplineUser;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "custom_tracking_id")
-    private CustomTrackingCategory customTrackingCategory;
-
-    public Task() {
-    }
-
-    public Long getTaskId() { return taskId; }
-    public void setTaskId(Long taskId) { this.taskId = taskId; }
-
-    public String getName() { return name; }
-    public void setName(String name) { this.name = name; }
-
-    public TaskStatus getStatus() { return status; }
-    public void setStatus(TaskStatus status) { this.status = status; }
-
-    public boolean isFinished() { return TaskStatus.FINISHED == status; }
-    public void setFinished(boolean finished) {
-        this.status = finished ? TaskStatus.FINISHED : TaskStatus.NOT_STARTED;
-    }
-
-    public String getDescription() { return description; }
-    public void setDescription(String description) { this.description = description; }
-
-    public LocalDate getDueDate() { return dueDate; }
-    public void setDueDate(LocalDate dueDate) { this.dueDate = dueDate; }
-
-    public String getPriority() { return priority; }
-    public void setPriority(String priority) { this.priority = priority; }
-
-    public DisciplineUser getDisciplineUser() { return disciplineUser; }
-    public void setDisciplineUser(DisciplineUser disciplineUser) { this.disciplineUser = disciplineUser; }
-
-    public CustomTrackingCategory getCustomTrackingCategory() { return customTrackingCategory; }
-    public void setCustomTrackingCategory(CustomTrackingCategory customTrackingCategory) {
-        this.customTrackingCategory = customTrackingCategory;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/entity/discipline/TaskDailyCompletion.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/discipline/TaskDailyCompletion.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,54 +1,0 @@
-package com.trekr.backend.entity.discipline;
-
-import jakarta.persistence.EmbeddedId;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.MapsId;
-import jakarta.persistence.Table;
-
-@Entity
-@Table(name = "TASK_DAILY_COMPLETION", schema = "trekr")
-public class TaskDailyCompletion {
-
-    @EmbeddedId
-    private TaskDailyCompletionId id;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @MapsId("taskId")
-    @JoinColumn(name = "task_id")
-    private Task task;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @MapsId("dailyCompletionId")
-    @JoinColumn(name = "daily_completion_id")
-    private DailyCompletion dailyCompletion;
-
-    public TaskDailyCompletion() {
-    }
-
-    public TaskDailyCompletionId getId() {
-        return id;
-    }
-
-    public void setId(TaskDailyCompletionId id) {
-        this.id = id;
-    }
-
-    public Task getTask() {
-        return task;
-    }
-
-    public void setTask(Task task) {
-        this.task = task;
-    }
-
-    public DailyCompletion getDailyCompletion() {
-        return dailyCompletion;
-    }
-
-    public void setDailyCompletion(DailyCompletion dailyCompletion) {
-        this.dailyCompletion = dailyCompletion;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/entity/discipline/TaskDailyCompletionId.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/discipline/TaskDailyCompletionId.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,56 +1,0 @@
-package com.trekr.backend.entity.discipline;
-
-import jakarta.persistence.Column;
-import jakarta.persistence.Embeddable;
-
-import java.io.Serializable;
-import java.util.Objects;
-
-@Embeddable
-public class TaskDailyCompletionId implements Serializable {
-
-    @Column(name = "task_id")
-    private Long taskId;
-
-    @Column(name = "daily_completion_id")
-    private Long dailyCompletionId;
-
-    public TaskDailyCompletionId() {
-    }
-
-    public TaskDailyCompletionId(Long taskId, Long dailyCompletionId) {
-        this.taskId = taskId;
-        this.dailyCompletionId = dailyCompletionId;
-    }
-
-    public Long getTaskId() {
-        return taskId;
-    }
-
-    public void setTaskId(Long taskId) {
-        this.taskId = taskId;
-    }
-
-    public Long getDailyCompletionId() {
-        return dailyCompletionId;
-    }
-
-    public void setDailyCompletionId(Long dailyCompletionId) {
-        this.dailyCompletionId = dailyCompletionId;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o)
-            return true;
-        if (o == null || getClass() != o.getClass())
-            return false;
-        TaskDailyCompletionId that = (TaskDailyCompletionId) o;
-        return Objects.equals(taskId, that.taskId) && Objects.equals(dailyCompletionId, that.dailyCompletionId);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(taskId, dailyCompletionId);
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/entity/discipline/TaskStatus.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/discipline/TaskStatus.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package com.trekr.backend.entity.discipline;
-
-public enum TaskStatus {
-    NOT_STARTED,
-    IN_PROGRESS,
-    FINISHED
-}
-
Index: ckend/src/main/java/com/trekr/backend/entity/finance/FinanceUser.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/finance/FinanceUser.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,101 +1,0 @@
-package com.trekr.backend.entity.finance;
-
-import com.trekr.backend.entity.User;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.MapsId;
-import jakarta.persistence.OneToOne;
-import jakarta.persistence.Table;
-
-import java.math.BigDecimal;
-
-@Entity
-@Table(name = "FINANCE_USERS", schema = "trekr")
-public class FinanceUser {
-
-    @Id
-    @Column(name = "user_id")
-    private Long userId;
-
-    @OneToOne(fetch = FetchType.LAZY, optional = false)
-    @MapsId
-    @JoinColumn(name = "user_id")
-    private User user;
-
-    @Column(name = "spending_budget")
-    private BigDecimal spendingBudget;
-
-    @Column(name = "saving_budget")
-    private BigDecimal savingBudget;
-
-    @Column(name = "investing_budget")
-    private BigDecimal investingBudget;
-
-    @Column(name = "donation_budget")
-    private BigDecimal donationBudget;
-
-    @Column(name = "credit")
-    private BigDecimal credit;
-
-    public FinanceUser() {
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public User getUser() {
-        return user;
-    }
-
-    public void setUser(User user) {
-        this.user = user;
-    }
-
-    public BigDecimal getSpendingBudget() {
-        return spendingBudget;
-    }
-
-    public void setSpendingBudget(BigDecimal spendingBudget) {
-        this.spendingBudget = spendingBudget;
-    }
-
-    public BigDecimal getSavingBudget() {
-        return savingBudget;
-    }
-
-    public void setSavingBudget(BigDecimal savingBudget) {
-        this.savingBudget = savingBudget;
-    }
-
-    public BigDecimal getInvestingBudget() {
-        return investingBudget;
-    }
-
-    public void setInvestingBudget(BigDecimal investingBudget) {
-        this.investingBudget = investingBudget;
-    }
-
-    public BigDecimal getDonationBudget() {
-        return donationBudget;
-    }
-
-    public void setDonationBudget(BigDecimal donationBudget) {
-        this.donationBudget = donationBudget;
-    }
-
-    public BigDecimal getCredit() {
-        return credit;
-    }
-
-    public void setCredit(BigDecimal credit) {
-        this.credit = credit;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/entity/finance/Income.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/finance/Income.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,69 +1,0 @@
-package com.trekr.backend.entity.finance;
-
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-@Entity
-@Table(name = "INCOMES", schema = "trekr")
-public class Income {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "income_id")
-    private Long incomeId;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "user_id")
-    private FinanceUser financeUser;
-
-    @Column(name = "date", nullable = false)
-    private LocalDate date;
-
-    @Column(name = "amount", nullable = false)
-    private BigDecimal amount;
-
-    public Income() {
-    }
-
-    public Long getIncomeId() {
-        return incomeId;
-    }
-
-    public void setIncomeId(Long incomeId) {
-        this.incomeId = incomeId;
-    }
-
-    public FinanceUser getFinanceUser() {
-        return financeUser;
-    }
-
-    public void setFinanceUser(FinanceUser financeUser) {
-        this.financeUser = financeUser;
-    }
-
-    public LocalDate getDate() {
-        return date;
-    }
-
-    public void setDate(LocalDate date) {
-        this.date = date;
-    }
-
-    public BigDecimal getAmount() {
-        return amount;
-    }
-
-    public void setAmount(BigDecimal amount) {
-        this.amount = amount;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/entity/invest/Asset.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/invest/Asset.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,91 +1,0 @@
-package com.trekr.backend.entity.invest;
-
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-@Entity
-@Table(name = "ASSETS", schema = "trekr")
-public class Asset {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "asset_id")
-    private Long assetId;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "user_id")
-    private InvestorUser investorUser;
-
-    @Column(name = "ticker_symbol", nullable = false)
-    private String tickerSymbol;
-
-    @Column(name = "buy_price")
-    private BigDecimal buyPrice;
-
-    @Column(name = "buy_date")
-    private LocalDate buyDate;
-
-    @Column(name = "quantity")
-    private BigDecimal quantity;
-
-    public Asset() {
-    }
-
-    public Long getAssetId() {
-        return assetId;
-    }
-
-    public void setAssetId(Long assetId) {
-        this.assetId = assetId;
-    }
-
-    public InvestorUser getInvestorUser() {
-        return investorUser;
-    }
-
-    public void setInvestorUser(InvestorUser investorUser) {
-        this.investorUser = investorUser;
-    }
-
-    public String getTickerSymbol() {
-        return tickerSymbol;
-    }
-
-    public void setTickerSymbol(String tickerSymbol) {
-        this.tickerSymbol = tickerSymbol;
-    }
-
-    public BigDecimal getBuyPrice() {
-        return buyPrice;
-    }
-
-    public void setBuyPrice(BigDecimal buyPrice) {
-        this.buyPrice = buyPrice;
-    }
-
-    public LocalDate getBuyDate() {
-        return buyDate;
-    }
-
-    public void setBuyDate(LocalDate buyDate) {
-        this.buyDate = buyDate;
-    }
-
-    public BigDecimal getQuantity() {
-        return quantity;
-    }
-
-    public void setQuantity(BigDecimal quantity) {
-        this.quantity = quantity;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/entity/invest/InvestorUser.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/invest/InvestorUser.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,42 +1,0 @@
-package com.trekr.backend.entity.invest;
-
-import com.trekr.backend.entity.User;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.MapsId;
-import jakarta.persistence.OneToOne;
-import jakarta.persistence.Table;
-
-@Entity
-@Table(name = "INVESTOR_USERS", schema = "trekr")
-public class InvestorUser {
-
-    @Id
-    private Long userId;
-
-    @OneToOne(fetch = FetchType.LAZY, optional = false)
-    @MapsId
-    @JoinColumn(name = "user_id")
-    private User user;
-
-    public InvestorUser() {
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public User getUser() {
-        return user;
-    }
-
-    public void setUser(User user) {
-        this.user = user;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/entity/training/TrainingSession.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/training/TrainingSession.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,92 +1,0 @@
-package com.trekr.backend.entity.training;
-
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-@Entity
-@Table(name = "TRAINING_SESSIONS", schema = "trekr")
-public class TrainingSession {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "training_id")
-    private Long trainingId;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "training_user_id")
-    private TrainingUser trainingUser;
-
-    @Column(name = "duration")
-    private BigDecimal duration;
-
-    @Column(name = "calories")
-    private BigDecimal calories;
-
-    @Column(name = "date")
-    private LocalDate date;
-
-    @Column(name = "type")
-    private String type;
-
-    public TrainingSession() {
-    }
-
-    public Long getTrainingId() {
-        return trainingId;
-    }
-
-    public void setTrainingId(Long trainingId) {
-        this.trainingId = trainingId;
-    }
-
-    public TrainingUser getTrainingUser() {
-        return trainingUser;
-    }
-
-    public void setTrainingUser(TrainingUser trainingUser) {
-        this.trainingUser = trainingUser;
-    }
-
-
-    public BigDecimal getDuration() {
-        return duration;
-    }
-
-    public void setDuration(BigDecimal duration) {
-        this.duration = duration;
-    }
-
-    public BigDecimal getCalories() {
-        return calories;
-    }
-
-    public void setCalories(BigDecimal calories) {
-        this.calories = calories;
-    }
-
-    public LocalDate getDate() {
-        return date;
-    }
-
-    public void setDate(LocalDate date) {
-        this.date = date;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/entity/training/TrainingUser.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/training/TrainingUser.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,79 +1,0 @@
-package com.trekr.backend.entity.training;
-
-import com.trekr.backend.entity.User;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.MapsId;
-import jakarta.persistence.OneToOne;
-import jakarta.persistence.Table;
-
-import java.math.BigDecimal;
-
-@Entity
-@Table(name = "TRAINING_USERS", schema = "trekr")
-public class TrainingUser {
-
-    @Id
-    @Column(name = "user_id")
-    private Long userId;
-
-    @OneToOne(fetch = FetchType.LAZY, optional = false)
-    @MapsId
-    @JoinColumn(name = "user_id")
-    private User user;
-
-    @Column(name = "gender")
-    private String gender;
-
-    @Column(name = "age")
-    private Integer age;
-
-    @Column(name = "weight")
-    private BigDecimal weight;
-
-    public TrainingUser() {
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public User getUser() {
-        return user;
-    }
-
-    public void setUser(User user) {
-        this.user = user;
-    }
-
-    public String getGender() {
-        return gender;
-    }
-
-    public void setGender(String gender) {
-        this.gender = gender;
-    }
-
-    public Integer getAge() {
-        return age;
-    }
-
-    public void setAge(Integer age) {
-        this.age = age;
-    }
-
-    public BigDecimal getWeight() {
-        return weight;
-    }
-
-    public void setWeight(BigDecimal weight) {
-        this.weight = weight;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/entity/weight/DailyIntake.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/weight/DailyIntake.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,69 +1,0 @@
-package com.trekr.backend.entity.weight;
-
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.GeneratedValue;
-import jakarta.persistence.GenerationType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.ManyToOne;
-import jakarta.persistence.Table;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-@Entity
-@Table(name = "DAILY_INTAKES", schema = "trekr")
-public class DailyIntake {
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "daily_intake_id")
-    private Long dailyIntakeId;
-
-    @ManyToOne(fetch = FetchType.LAZY)
-    @JoinColumn(name = "user_id")
-    private WeightUser weightUser;
-
-    @Column(name = "calories")
-    private BigDecimal calories;
-
-    @Column(name = "date")
-    private LocalDate date;
-
-    public DailyIntake() {
-    }
-
-    public Long getDailyIntakeId() {
-        return dailyIntakeId;
-    }
-
-    public void setDailyIntakeId(Long dailyIntakeId) {
-        this.dailyIntakeId = dailyIntakeId;
-    }
-
-    public WeightUser getWeightUser() {
-        return weightUser;
-    }
-
-    public void setWeightUser(WeightUser weightUser) {
-        this.weightUser = weightUser;
-    }
-
-    public BigDecimal getCalories() {
-        return calories;
-    }
-
-    public void setCalories(BigDecimal calories) {
-        this.calories = calories;
-    }
-
-    public LocalDate getDate() {
-        return date;
-    }
-
-    public void setDate(LocalDate date) {
-        this.date = date;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/entity/weight/WeightUser.java
===================================================================
--- backend/src/main/java/com/trekr/backend/entity/weight/WeightUser.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,91 +1,0 @@
-package com.trekr.backend.entity.weight;
-
-import com.trekr.backend.entity.User;
-import jakarta.persistence.Column;
-import jakarta.persistence.Entity;
-import jakarta.persistence.FetchType;
-import jakarta.persistence.Id;
-import jakarta.persistence.JoinColumn;
-import jakarta.persistence.MapsId;
-import jakarta.persistence.OneToOne;
-import jakarta.persistence.Table;
-
-import java.math.BigDecimal;
-
-@Entity
-@Table(name = "WEIGHT_USERS", schema = "trekr")
-public class WeightUser {
-
-    @Id
-    @Column(name = "user_id")
-    private Long userId;
-
-    @OneToOne(fetch = FetchType.LAZY, optional = false)
-    @MapsId
-    @JoinColumn(name = "user_id")
-    private User user;
-
-    @Column(name = "weight")
-    private BigDecimal weight;
-
-    @Column(name = "height")
-    private BigDecimal height;
-
-    @Column(name = "goal_weight")
-    private BigDecimal goalWeight;
-
-    @Column(name = "goal_calories")
-    private BigDecimal goalCalories;
-
-    public WeightUser() {
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public User getUser() {
-        return user;
-    }
-
-    public void setUser(User user) {
-        this.user = user;
-    }
-
-    public BigDecimal getWeight() {
-        return weight;
-    }
-
-    public void setWeight(BigDecimal weight) {
-        this.weight = weight;
-    }
-
-    public BigDecimal getHeight() {
-        return height;
-    }
-
-    public void setHeight(BigDecimal height) {
-        this.height = height;
-    }
-
-    public BigDecimal getGoalWeight() {
-        return goalWeight;
-    }
-
-    public void setGoalWeight(BigDecimal goalWeight) {
-        this.goalWeight = goalWeight;
-    }
-
-
-    public BigDecimal getGoalCalories() {
-        return goalCalories;
-    }
-
-    public void setGoalCalories(BigDecimal goalCalories) {
-        this.goalCalories = goalCalories;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/exception/GlobalExceptionHandler.java
===================================================================
--- backend/src/main/java/com/trekr/backend/exception/GlobalExceptionHandler.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,56 +1,0 @@
-package com.trekr.backend.exception;
-
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.validation.FieldError;
-import org.springframework.web.bind.MethodArgumentNotValidException;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.RestControllerAdvice;
-
-import java.time.LocalDateTime;
-import java.util.HashMap;
-import java.util.Map;
-
-@RestControllerAdvice
-public class GlobalExceptionHandler {
-    
-    @ExceptionHandler(MethodArgumentNotValidException.class)
-    public ResponseEntity<Map<String, Object>> handleValidationExceptions(
-            MethodArgumentNotValidException ex) {
-        Map<String, Object> errors = new HashMap<>();
-        Map<String, String> fieldErrors = new HashMap<>();
-        
-        ex.getBindingResult().getAllErrors().forEach((error) -> {
-            String fieldName = ((FieldError) error).getField();
-            String errorMessage = error.getDefaultMessage();
-            fieldErrors.put(fieldName, errorMessage);
-        });
-        
-        errors.put("timestamp", LocalDateTime.now());
-        errors.put("status", HttpStatus.BAD_REQUEST.value());
-        errors.put("message", "Validation failed");
-        errors.put("errors", fieldErrors);
-        
-        return ResponseEntity.badRequest().body(errors);
-    }
-    
-    @ExceptionHandler(RuntimeException.class)
-    public ResponseEntity<Map<String, Object>> handleRuntimeException(RuntimeException ex) {
-        Map<String, Object> error = new HashMap<>();
-        error.put("timestamp", LocalDateTime.now());
-        error.put("status", HttpStatus.BAD_REQUEST.value());
-        error.put("message", ex.getMessage());
-        
-        return ResponseEntity.badRequest().body(error);
-    }
-    
-    @ExceptionHandler(Exception.class)
-    public ResponseEntity<Map<String, Object>> handleGenericException(Exception ex) {
-        Map<String, Object> error = new HashMap<>();
-        error.put("timestamp", LocalDateTime.now());
-        error.put("status", HttpStatus.INTERNAL_SERVER_ERROR.value());
-        error.put("message", "An unexpected error occurred");
-        
-        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/repository/AssetRepository.java
===================================================================
--- backend/src/main/java/com/trekr/backend/repository/AssetRepository.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,14 +1,0 @@
-package com.trekr.backend.repository;
-
-import com.trekr.backend.entity.invest.Asset;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-@Repository
-public interface AssetRepository extends JpaRepository<Asset, Long> {
-    Page<Asset> findByInvestorUser_UserIdOrderByAssetIdDesc(Long userId, Pageable pageable);
-
-    int deleteByAssetIdAndInvestorUser_UserId(Long assetId, Long userId);
-}
Index: ckend/src/main/java/com/trekr/backend/repository/CustomTrackingCategoryRepository.java
===================================================================
--- backend/src/main/java/com/trekr/backend/repository/CustomTrackingCategoryRepository.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,16 +1,0 @@
-
-package com.trekr.backend.repository;
-
-import com.trekr.backend.entity.discipline.CustomTrackingCategory;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.List;
-
-public interface CustomTrackingCategoryRepository extends JpaRepository<CustomTrackingCategory, Long> {
-
-	List<CustomTrackingCategory> findByUser_UserIdOrderByCustomTrackingIdDesc(Long userId);
-
-	boolean existsByUser_UserIdAndNameIgnoreCase(Long userId, String name);
-}
-
-
Index: ckend/src/main/java/com/trekr/backend/repository/DailyCompletionRepository.java
===================================================================
--- backend/src/main/java/com/trekr/backend/repository/DailyCompletionRepository.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,17 +1,0 @@
-package com.trekr.backend.repository;
-
-import com.trekr.backend.entity.discipline.DailyCompletion;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.time.LocalDate;
-import java.util.Optional;
-
-public interface DailyCompletionRepository extends JpaRepository<DailyCompletion, Long> {
-
-    Optional<DailyCompletion> findByUser_UserIdAndDate(Long userId, LocalDate date);
-
-    Page<DailyCompletion> findByUser_UserIdOrderByDateDescDailyCompletionIdDesc(Long userId, Pageable pageable);
-}
-
Index: ckend/src/main/java/com/trekr/backend/repository/DailyIntakeRepository.java
===================================================================
--- backend/src/main/java/com/trekr/backend/repository/DailyIntakeRepository.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,17 +1,0 @@
-package com.trekr.backend.repository;
-
-import com.trekr.backend.entity.weight.DailyIntake;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-import java.time.LocalDate;
-
-@Repository
-public interface DailyIntakeRepository extends JpaRepository<DailyIntake, Long> {
-    Page<DailyIntake> findByWeightUser_UserIdOrderByDateDesc(Long userId, Pageable pageable);
-
-    boolean existsByWeightUser_UserIdAndDate(Long userId, LocalDate date);
-}
-
Index: ckend/src/main/java/com/trekr/backend/repository/DisciplineUserRepository.java
===================================================================
--- backend/src/main/java/com/trekr/backend/repository/DisciplineUserRepository.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package com.trekr.backend.repository;
-
-import com.trekr.backend.entity.discipline.DisciplineUser;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-public interface DisciplineUserRepository extends JpaRepository<DisciplineUser, Long> {
-}
-
Index: ckend/src/main/java/com/trekr/backend/repository/FinanceUserRepository.java
===================================================================
--- backend/src/main/java/com/trekr/backend/repository/FinanceUserRepository.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package com.trekr.backend.repository;
-
-import com.trekr.backend.entity.finance.FinanceUser;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-public interface FinanceUserRepository extends JpaRepository<FinanceUser, Long> {
-}
-
Index: ckend/src/main/java/com/trekr/backend/repository/IncomeRepository.java
===================================================================
--- backend/src/main/java/com/trekr/backend/repository/IncomeRepository.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package com.trekr.backend.repository;
-
-import com.trekr.backend.entity.finance.Income;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-public interface IncomeRepository extends JpaRepository<Income, Long> {
-
-    Page<Income> findByFinanceUser_UserIdOrderByDateDescIncomeIdDesc(Long userId, Pageable pageable);
-}
-
Index: ckend/src/main/java/com/trekr/backend/repository/InvestorUserRepository.java
===================================================================
--- backend/src/main/java/com/trekr/backend/repository/InvestorUserRepository.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package com.trekr.backend.repository;
-
-import com.trekr.backend.entity.invest.InvestorUser;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-@Repository
-public interface InvestorUserRepository extends JpaRepository<InvestorUser, Long> {
-}
Index: ckend/src/main/java/com/trekr/backend/repository/TaskDailyCompletionRepository.java
===================================================================
--- backend/src/main/java/com/trekr/backend/repository/TaskDailyCompletionRepository.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package com.trekr.backend.repository;
-
-import com.trekr.backend.entity.discipline.TaskDailyCompletion;
-import com.trekr.backend.entity.discipline.TaskDailyCompletionId;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-public interface TaskDailyCompletionRepository extends JpaRepository<TaskDailyCompletion, TaskDailyCompletionId> {
-}
-
Index: ckend/src/main/java/com/trekr/backend/repository/TaskRepository.java
===================================================================
--- backend/src/main/java/com/trekr/backend/repository/TaskRepository.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,35 +1,0 @@
-package com.trekr.backend.repository;
-
-import com.trekr.backend.entity.discipline.Task;
-import com.trekr.backend.entity.discipline.TaskStatus;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.Modifying;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-
-import java.util.List;
-
-public interface TaskRepository extends JpaRepository<Task, Long> {
-
-    Page<Task> findByDisciplineUser_UserIdOrderByTaskIdDesc(Long userId, Pageable pageable);
-
-    int deleteByTaskIdAndDisciplineUser_UserId(Long taskId, Long userId);
-
-    long countByDisciplineUser_UserId(Long userId);
-
-    long countByDisciplineUser_UserIdAndStatus(Long userId, TaskStatus status);
-
-    List<Task> findByDisciplineUser_UserIdAndStatus(Long userId, TaskStatus status);
-
-    List<Task> findByCustomTrackingCategory_CustomTrackingIdAndCustomTrackingCategory_User_UserIdOrderByTaskIdDesc(
-            Long customTrackingId, Long userId);
-
-    int deleteByTaskIdAndCustomTrackingCategory_CustomTrackingIdAndCustomTrackingCategory_User_UserId(
-            Long taskId, Long customTrackingId, Long userId);
-
-    @Modifying
-    @Query("update Task t set t.status = :status where t.disciplineUser.userId = :userId")
-    int resetStatusForUser(@Param("userId") Long userId, @Param("status") TaskStatus status);
-}
Index: ckend/src/main/java/com/trekr/backend/repository/TrainingSessionRepository.java
===================================================================
--- backend/src/main/java/com/trekr/backend/repository/TrainingSessionRepository.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,19 +1,0 @@
-package com.trekr.backend.repository;
-
-import com.trekr.backend.entity.training.TrainingSession;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-import java.time.LocalDate;
-import java.util.Collection;
-
-@Repository
-public interface TrainingSessionRepository extends JpaRepository<TrainingSession, Long> {
-    Page<TrainingSession> findByTrainingUser_UserIdOrderByDateDesc(Long userId, Pageable pageable);
-    java.util.List<TrainingSession> findByTrainingUser_UserIdAndDate(Long userId, java.time.LocalDate date);
-
-    @SuppressWarnings("unused")
-    java.util.List<TrainingSession> findByTrainingUser_UserIdAndDateIn(Long userId, Collection<LocalDate> dates);
-}
Index: ckend/src/main/java/com/trekr/backend/repository/TrainingUserRepository.java
===================================================================
--- backend/src/main/java/com/trekr/backend/repository/TrainingUserRepository.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,9 +1,0 @@
-package com.trekr.backend.repository;
-
-import com.trekr.backend.entity.training.TrainingUser;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-@Repository
-public interface TrainingUserRepository extends JpaRepository<TrainingUser, Long> {
-}
Index: ckend/src/main/java/com/trekr/backend/repository/UserRepository.java
===================================================================
--- backend/src/main/java/com/trekr/backend/repository/UserRepository.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,15 +1,0 @@
-package com.trekr.backend.repository;
-
-import com.trekr.backend.entity.User;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-import java.util.Optional;
-
-@Repository
-public interface UserRepository extends JpaRepository<User, Long> {
-    Optional<User> findByEmail(String email);
-    Optional<User> findByUsername(String username);
-    boolean existsByEmail(String email);
-    boolean existsByUsername(String username);
-}
Index: ckend/src/main/java/com/trekr/backend/repository/WeightUserRepository.java
===================================================================
--- backend/src/main/java/com/trekr/backend/repository/WeightUserRepository.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,10 +1,0 @@
-package com.trekr.backend.repository;
-
-import com.trekr.backend.entity.weight.WeightUser;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-
-@Repository
-public interface WeightUserRepository extends JpaRepository<WeightUser, Long> {
-}
-
Index: ckend/src/main/java/com/trekr/backend/resources/application.properties
===================================================================
--- backend/src/main/java/com/trekr/backend/resources/application.properties	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,4 +1,0 @@
-### NOTE
-### This file is intentionally NOT used by Spring Boot.
-### The active config is in: src/main/resources/application.properties
-
Index: ckend/src/main/java/com/trekr/backend/security/JwtAuthenticationFilter.java
===================================================================
--- backend/src/main/java/com/trekr/backend/security/JwtAuthenticationFilter.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,54 +1,0 @@
-package com.trekr.backend.security;
-
-import com.trekr.backend.service.JwtService;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import java.io.IOException;
-import java.util.List;
-
-@Component
-public class JwtAuthenticationFilter extends OncePerRequestFilter {
-
-    private final JwtService jwtService;
-
-    public JwtAuthenticationFilter(JwtService jwtService) {
-        this.jwtService = jwtService;
-    }
-
-    @Override
-    protected void doFilterInternal(
-            HttpServletRequest request,
-            HttpServletResponse response,
-            FilterChain filterChain) throws ServletException, IOException {
-
-        String authHeader = request.getHeader("Authorization");
-        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
-            filterChain.doFilter(request, response);
-            return;
-        }
-
-        String token = authHeader.substring("Bearer ".length()).trim();
-        if (token.isEmpty() || !jwtService.isTokenValid(token)) {
-            filterChain.doFilter(request, response);
-            return;
-        }
-
-        if (SecurityContextHolder.getContext().getAuthentication() == null) {
-            UserPrincipal principal = jwtService.parseUserPrincipal(token);
-            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(principal,
-                    null, List.of());
-            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
-            SecurityContextHolder.getContext().setAuthentication(authentication);
-        }
-
-        filterChain.doFilter(request, response);
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/security/UserPrincipal.java
===================================================================
--- backend/src/main/java/com/trekr/backend/security/UserPrincipal.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,33 +1,0 @@
-package com.trekr.backend.security;
-
-import java.io.Serializable;
-
-/**
- * Represents the currently logged-in user after we've validated their JWT.
- * Controllers can inject this or get it from SecurityContextHolder.
- */
-public class UserPrincipal implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    private final Long userId;
-    private final String username;
-    private final String email;
-
-    public UserPrincipal(Long userId, String username, String email) {
-        this.userId = userId;
-        this.username = username;
-        this.email = email;
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public String getUsername() {
-        return username;
-    }
-
-    public String getEmail() {
-        return email;
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/service/AuthService.java
===================================================================
--- backend/src/main/java/com/trekr/backend/service/AuthService.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,60 +1,0 @@
-package com.trekr.backend.service;
-
-import com.trekr.backend.dto.auth.AuthResponse;
-import com.trekr.backend.dto.auth.LoginRequest;
-import com.trekr.backend.dto.auth.RegisterRequest;
-import com.trekr.backend.entity.User;
-import com.trekr.backend.repository.UserRepository;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-@Service
-public class AuthService {
-
-    private final UserRepository userRepository;
-    private final PasswordEncoder passwordEncoder;
-    private final JwtService jwtService;
-
-    public AuthService(UserRepository userRepository, PasswordEncoder passwordEncoder, JwtService jwtService) {
-        this.userRepository = userRepository;
-        this.passwordEncoder = passwordEncoder;
-        this.jwtService = jwtService;
-    }
-
-    @Transactional
-    public AuthResponse register(RegisterRequest request) {
-        if (userRepository.existsByEmail(request.getEmail())) {
-            throw new RuntimeException("Email already exists");
-        }
-        if (userRepository.existsByUsername(request.getUsername())) {
-            throw new RuntimeException("Username already exists");
-        }
-
-        User user = new User();
-        user.setEmail(request.getEmail().trim().toLowerCase());
-        user.setUsername(request.getUsername().trim());
-        user.setPassword(passwordEncoder.encode(request.getPassword()));
-
-        user = userRepository.save(user);
-
-        String token = jwtService.generateToken(user.getUserId(), user.getUsername(), user.getEmail());
-        return new AuthResponse(token, "Bearer", user.getUserId(), user.getUsername(), user.getEmail());
-    }
-
-    @Transactional(readOnly = true)
-    public AuthResponse login(LoginRequest request) {
-        String usernameOrEmail = request.getUsernameOrEmail().trim();
-        String emailLookup = usernameOrEmail.contains("@") ? usernameOrEmail.toLowerCase() : usernameOrEmail;
-        User user = userRepository.findByUsername(usernameOrEmail)
-                .or(() -> userRepository.findByEmail(emailLookup))
-                .orElseThrow(() -> new RuntimeException("Invalid credentials"));
-
-        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
-            throw new RuntimeException("Invalid credentials");
-        }
-
-        String token = jwtService.generateToken(user.getUserId(), user.getUsername(), user.getEmail());
-        return new AuthResponse(token, "Bearer", user.getUserId(), user.getUsername(), user.getEmail());
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/service/CustomTrackingService.java
===================================================================
--- backend/src/main/java/com/trekr/backend/service/CustomTrackingService.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,218 +1,0 @@
-package com.trekr.backend.service;
-
-import com.trekr.backend.dto.discipline.CreateCustomTrackingCategoryRequest;
-import com.trekr.backend.dto.discipline.CreateTaskRequest;
-import com.trekr.backend.dto.discipline.CustomTrackingCategoriesResponse;
-import com.trekr.backend.dto.discipline.CustomTrackingCategoryDto;
-import com.trekr.backend.dto.discipline.TaskDto;
-import com.trekr.backend.dto.discipline.TasksResponse;
-import com.trekr.backend.dto.discipline.UpdateTaskFinishedRequest;
-import com.trekr.backend.dto.discipline.UpdateTaskStatusRequest;
-import com.trekr.backend.entity.discipline.TaskStatus;
-import com.trekr.backend.dto.discipline.UpdateTaskRequest;
-import com.trekr.backend.entity.User;
-import com.trekr.backend.entity.discipline.CustomTrackingCategory;
-import com.trekr.backend.entity.discipline.Task;
-import com.trekr.backend.repository.CustomTrackingCategoryRepository;
-import com.trekr.backend.repository.TaskRepository;
-import com.trekr.backend.repository.UserRepository;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.util.List;
-
-@Service
-public class CustomTrackingService {
-
-    private final CustomTrackingCategoryRepository customTrackingCategoryRepository;
-    private final TaskRepository taskRepository;
-    private final UserRepository userRepository;
-
-    public CustomTrackingService(
-            CustomTrackingCategoryRepository customTrackingCategoryRepository,
-            TaskRepository taskRepository,
-            UserRepository userRepository) {
-        this.customTrackingCategoryRepository = customTrackingCategoryRepository;
-        this.taskRepository = taskRepository;
-        this.userRepository = userRepository;
-    }
-
-    @Transactional(readOnly = true)
-    public CustomTrackingCategoriesResponse getCustomTrackingCategories(Long userId) {
-        List<CustomTrackingCategoryDto> items = customTrackingCategoryRepository
-                .findByUser_UserIdOrderByCustomTrackingIdDesc(userId)
-                .stream()
-                .map(c -> new CustomTrackingCategoryDto(c.getCustomTrackingId(), c.getName()))
-                .toList();
-
-        return new CustomTrackingCategoriesResponse(items);
-    }
-
-    @Transactional
-    public CustomTrackingCategoryDto createCustomTrackingCategory(Long userId, CreateCustomTrackingCategoryRequest request) {
-        String name = request.getName();
-        if (name == null || name.isBlank()) {
-            throw new RuntimeException("Name is required");
-        }
-        String trimmed = name.trim();
-        if (trimmed.length() > 100) {
-            throw new RuntimeException("Name is too long");
-        }
-
-        if (customTrackingCategoryRepository.existsByUser_UserIdAndNameIgnoreCase(userId, trimmed)) {
-            throw new RuntimeException("Custom category with that name already exists");
-        }
-
-        User user = userRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("User not found"));
-
-        CustomTrackingCategory category = new CustomTrackingCategory();
-        category.setUser(user);
-        category.setName(trimmed);
-        CustomTrackingCategory saved = customTrackingCategoryRepository.save(category);
-
-        return new CustomTrackingCategoryDto(saved.getCustomTrackingId(), saved.getName());
-    }
-
-    @Transactional(readOnly = true)
-    public TasksResponse getCustomCategoryTasks(Long userId, Long customTrackingId) {
-        requireOwnership(userId, customTrackingId);
-
-        List<TaskDto> tasks = taskRepository
-                .findByCustomTrackingCategory_CustomTrackingIdAndCustomTrackingCategory_User_UserIdOrderByTaskIdDesc(
-                        customTrackingId, userId)
-                .stream()
-                .map(t -> new TaskDto(t.getTaskId(), t.getName(), t.isFinished(), t.getStatus(), t.getDescription(), t.getDueDate(), t.getPriority()))
-                .toList();
-
-        return new TasksResponse(tasks, false);
-    }
-
-    @Transactional
-    public TaskDto createCustomCategoryTask(Long userId, Long customTrackingId, CreateTaskRequest request) {
-        CustomTrackingCategory category = requireOwnership(userId, customTrackingId);
-
-        String name = request.getName();
-        if (name == null || name.isBlank()) {
-            throw new RuntimeException("Task name is required");
-        }
-        if (name.length() > 200) {
-            throw new RuntimeException("Task name is too long");
-        }
-
-        Task task = new Task();
-        task.setName(name.trim());
-        task.setStatus(TaskStatus.NOT_STARTED);
-        task.setDescription(request.getDescription());
-        task.setDueDate(request.getDueDate());
-        task.setPriority(request.getPriority());
-        task.setDisciplineUser(null);
-        task.setCustomTrackingCategory(category);
-
-        Task saved = taskRepository.save(task);
-        return new TaskDto(saved.getTaskId(), saved.getName(), saved.isFinished(), saved.getStatus(), saved.getDescription(), saved.getDueDate(), saved.getPriority());
-    }
-
-    @Transactional
-    public TaskDto updateCustomCategoryTask(Long userId, Long customTrackingId, Long taskId, UpdateTaskRequest request) {
-        Task task = taskRepository.findById(taskId)
-                .orElseThrow(() -> new RuntimeException("Task not found"));
-
-        if (task.getCustomTrackingCategory() == null
-                || !customTrackingId.equals(task.getCustomTrackingCategory().getCustomTrackingId())
-                || task.getCustomTrackingCategory().getUser() == null
-                || !userId.equals(task.getCustomTrackingCategory().getUser().getUserId())) {
-            throw new RuntimeException("Task not found");
-        }
-
-        String name = request.getName();
-        if (name == null || name.isBlank()) {
-            throw new RuntimeException("Task name is required");
-        }
-
-        task.setName(name.trim());
-        task.setDescription(request.getDescription());
-        task.setDueDate(request.getDueDate());
-        task.setPriority(request.getPriority());
-        if (request.getStatus() != null) {
-            task.setStatus(request.getStatus());
-        }
-        Task saved = taskRepository.save(task);
-        return new TaskDto(saved.getTaskId(), saved.getName(), saved.isFinished(), saved.getStatus(), saved.getDescription(), saved.getDueDate(), saved.getPriority());
-    }
-
-    @Transactional
-    public TaskDto updateCustomCategoryTaskFinished(Long userId, Long customTrackingId, Long taskId,
-                                                    UpdateTaskFinishedRequest request) {
-        Task task = taskRepository.findById(taskId)
-                .orElseThrow(() -> new RuntimeException("Task not found"));
-
-        if (task.getCustomTrackingCategory() == null
-                || !customTrackingId.equals(task.getCustomTrackingCategory().getCustomTrackingId())
-                || task.getCustomTrackingCategory().getUser() == null
-                || !userId.equals(task.getCustomTrackingCategory().getUser().getUserId())) {
-            throw new RuntimeException("Task not found");
-        }
-
-        Boolean finished = request.getIsFinished();
-        if (finished == null) {
-            throw new RuntimeException("isFinished is required");
-        }
-
-        task.setFinished(finished);
-        Task saved = taskRepository.save(task);
-        return new TaskDto(saved.getTaskId(), saved.getName(), saved.isFinished(), saved.getStatus(), saved.getDescription(), saved.getDueDate(), saved.getPriority());
-    }
-
-    @Transactional
-    public TaskDto updateCustomCategoryTaskStatus(Long userId, Long customTrackingId, Long taskId,
-                                                  UpdateTaskStatusRequest request) {
-        Task task = taskRepository.findById(taskId)
-                .orElseThrow(() -> new RuntimeException("Task not found"));
-
-        if (task.getCustomTrackingCategory() == null
-                || !customTrackingId.equals(task.getCustomTrackingCategory().getCustomTrackingId())
-                || task.getCustomTrackingCategory().getUser() == null
-                || !userId.equals(task.getCustomTrackingCategory().getUser().getUserId())) {
-            throw new RuntimeException("Task not found");
-        }
-
-        if (request.getStatus() == null) {
-            throw new RuntimeException("status is required");
-        }
-
-        task.setStatus(request.getStatus());
-        Task saved = taskRepository.save(task);
-        return new TaskDto(saved.getTaskId(), saved.getName(), saved.isFinished(), saved.getStatus(), saved.getDescription(), saved.getDueDate(), saved.getPriority());
-    }
-
-    @Transactional
-    public void deleteCustomCategoryTask(Long userId, Long customTrackingId, Long taskId) {
-        if (taskId == null || customTrackingId == null) {
-            throw new RuntimeException("Task not found");
-        }
-
-        int deleted = taskRepository
-                .deleteByTaskIdAndCustomTrackingCategory_CustomTrackingIdAndCustomTrackingCategory_User_UserId(
-                        taskId, customTrackingId, userId);
-        if (deleted == 0) {
-            throw new RuntimeException("Task not found");
-        }
-    }
-
-    private CustomTrackingCategory requireOwnership(Long userId, Long customTrackingId) {
-        if (customTrackingId == null) {
-            throw new RuntimeException("Custom tracking category not found");
-        }
-
-        CustomTrackingCategory category = customTrackingCategoryRepository.findById(customTrackingId)
-                .orElseThrow(() -> new RuntimeException("Custom tracking category not found"));
-
-        if (category.getUser() == null || !userId.equals(category.getUser().getUserId())) {
-            throw new RuntimeException("Custom tracking category not found");
-        }
-
-        return category;
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/service/DisciplineService.java
===================================================================
--- backend/src/main/java/com/trekr/backend/service/DisciplineService.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,250 +1,0 @@
-package com.trekr.backend.service;
-
-import com.trekr.backend.dto.discipline.CreateTaskRequest;
-import com.trekr.backend.dto.discipline.DailyCompletionDto;
-import com.trekr.backend.dto.discipline.DailyCompletionsResponse;
-import com.trekr.backend.dto.discipline.TaskDto;
-import com.trekr.backend.dto.discipline.TasksResponse;
-import com.trekr.backend.dto.discipline.ComputeDailyCompletionResponse;
-import com.trekr.backend.dto.discipline.UpdateTaskFinishedRequest;
-import com.trekr.backend.dto.discipline.UpdateTaskRequest;
-import com.trekr.backend.entity.User;
-import com.trekr.backend.entity.discipline.DisciplineUser;
-import com.trekr.backend.entity.discipline.DailyCompletion;
-import com.trekr.backend.entity.discipline.Task;
-import com.trekr.backend.entity.discipline.TaskDailyCompletion;
-import com.trekr.backend.entity.discipline.TaskStatus;
-import com.trekr.backend.entity.discipline.TaskDailyCompletionId;
-import com.trekr.backend.repository.DailyCompletionRepository;
-import com.trekr.backend.repository.DisciplineUserRepository;
-import com.trekr.backend.repository.TaskRepository;
-import com.trekr.backend.repository.TaskDailyCompletionRepository;
-import com.trekr.backend.repository.UserRepository;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.time.LocalDate;
-import java.util.List;
-
-@Service
-public class DisciplineService {
-
-    private final DisciplineUserRepository disciplineUserRepository;
-    private final TaskRepository taskRepository;
-    private final DailyCompletionRepository dailyCompletionRepository;
-    private final TaskDailyCompletionRepository taskDailyCompletionRepository;
-    private final UserRepository userRepository;
-
-    public DisciplineService(
-            DisciplineUserRepository disciplineUserRepository,
-            TaskRepository taskRepository,
-            DailyCompletionRepository dailyCompletionRepository,
-            TaskDailyCompletionRepository taskDailyCompletionRepository,
-            UserRepository userRepository) {
-        this.disciplineUserRepository = disciplineUserRepository;
-        this.taskRepository = taskRepository;
-        this.dailyCompletionRepository = dailyCompletionRepository;
-        this.taskDailyCompletionRepository = taskDailyCompletionRepository;
-        this.userRepository = userRepository;
-    }
-
-
-    public boolean isTracking(Long userId) {
-        return disciplineUserRepository.existsById(userId);
-    }
-
-    @Transactional
-    public void startTracking(Long userId) {
-        if (disciplineUserRepository.existsById(userId)) {
-            return;
-        }
-
-        User user = userRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("User not found"));
-
-        DisciplineUser disciplineUser = new DisciplineUser();
-        disciplineUser.setUser(user);
-        disciplineUserRepository.save(disciplineUser);
-    }
-
-    @Transactional(readOnly = true)
-    public TasksResponse getTasks(Long userId, int page, int size) {
-        if (!disciplineUserRepository.existsById(userId)) {
-            return new TasksResponse(List.of(), false);
-        }
-
-        Page<Task> result = taskRepository.findByDisciplineUser_UserIdOrderByTaskIdDesc(
-                userId, PageRequest.of(page, size));
-
-        List<TaskDto> tasks = result.getContent().stream()
-                .map(t -> new TaskDto(t.getTaskId(), t.getName(), t.isFinished(), t.getStatus(), t.getDescription(), t.getDueDate(), t.getPriority()))
-                .toList();
-
-        return new TasksResponse(tasks, result.hasNext());
-    }
-
-    @Transactional
-    public TaskDto createTask(Long userId, CreateTaskRequest request) {
-        DisciplineUser disciplineUser = disciplineUserRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("Discipline tracking is not enabled for this user"));
-
-        String name = request.getName();
-        if (name == null || name.isBlank()) {
-            throw new RuntimeException("Task name is required");
-        }
-
-        if (name.length() > 200) {
-            throw new RuntimeException("Task name is too long");
-        }
-
-        Task task = new Task();
-        task.setName(name.trim());
-        task.setFinished(false);
-        task.setDisciplineUser(disciplineUser);
-
-        Task saved = taskRepository.save(task);
-        return new TaskDto(saved.getTaskId(), saved.getName(), saved.isFinished(), saved.getStatus(), saved.getDescription(), saved.getDueDate(), saved.getPriority());
-    }
-
-    @Transactional
-    public TaskDto updateTask(Long userId, Long taskId, UpdateTaskRequest request) {
-        Task task = taskRepository.findById(taskId)
-                .orElseThrow(() -> new RuntimeException("Task not found"));
-
-        if (task.getDisciplineUser() == null || !userId.equals(task.getDisciplineUser().getUserId())) {
-            throw new RuntimeException("Task not found");
-        }
-
-        String name = request.getName();
-        if (name == null || name.isBlank()) {
-            throw new RuntimeException("Task name is required");
-        }
-
-        task.setName(name.trim());
-        Task saved = taskRepository.save(task);
-        return new TaskDto(saved.getTaskId(), saved.getName(), saved.isFinished(), saved.getStatus(), saved.getDescription(), saved.getDueDate(), saved.getPriority());
-    }
-
-    @Transactional
-    public TaskDto updateTaskFinished(Long userId, Long taskId, UpdateTaskFinishedRequest request) {
-        Task task = taskRepository.findById(taskId)
-                .orElseThrow(() -> new RuntimeException("Task not found"));
-
-        if (task.getDisciplineUser() == null || !userId.equals(task.getDisciplineUser().getUserId())) {
-            throw new RuntimeException("Task not found");
-        }
-
-        Boolean finished = request.getIsFinished();
-        if (finished == null) {
-            throw new RuntimeException("isFinished is required");
-        }
-
-        task.setFinished(finished);
-        Task saved = taskRepository.save(task);
-        return new TaskDto(saved.getTaskId(), saved.getName(), saved.isFinished(), saved.getStatus(), saved.getDescription(), saved.getDueDate(), saved.getPriority());
-    }
-
-    @Transactional
-    public void deleteTask(Long userId, Long taskId) {
-        if (taskId == null) {
-            throw new RuntimeException("Task not found");
-        }
-
-        int deleted = taskRepository.deleteByTaskIdAndDisciplineUser_UserId(taskId, userId);
-        if (deleted == 0) {
-            throw new RuntimeException("Task not found");
-        }
-    }
-
-    /**
-     * Computes the daily completion percentage for the given date:
-     * finished_tasks / total_tasks * 100
-     * - Persisted once per user+date. If already computed, it is not re-computed.
-     * - After computing, all tasks for that user are reset to unfinished.
-     */
-    @Transactional
-    public ComputeDailyCompletionResponse computeDailyCompletion(Long userId, LocalDate date) {
-        if (!disciplineUserRepository.existsById(userId)) {
-            throw new RuntimeException("Discipline tracking is not enabled for this user");
-        }
-
-        if (date == null) {
-            throw new RuntimeException("Date is required");
-        }
-
-        if (date.isAfter(LocalDate.now())) {
-            throw new RuntimeException("Date cannot be in the future");
-        }
-
-        DailyCompletion existing = dailyCompletionRepository.findByUser_UserIdAndDate(userId, date).orElse(null);
-        if (existing != null) {
-            return new ComputeDailyCompletionResponse(false,
-                    new DailyCompletionDto(existing.getDailyCompletionId(), existing.getDate(), existing.getProcent()));
-        }
-
-        long total = taskRepository.countByDisciplineUser_UserId(userId);
-        long finished = taskRepository.countByDisciplineUser_UserIdAndStatus(userId, TaskStatus.FINISHED);
-
-        BigDecimal percent;
-        if (total <= 0) {
-            percent = BigDecimal.ZERO;
-        } else {
-            percent = BigDecimal.valueOf(finished)
-                    .multiply(new BigDecimal("100"))
-                    .divide(BigDecimal.valueOf(total), 2, RoundingMode.HALF_UP);
-        }
-
-        User user = userRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("User not found"));
-
-        DailyCompletion completion = new DailyCompletion();
-        completion.setUser(user);
-        completion.setDate(date);
-        completion.setProcent(percent);
-        DailyCompletion savedCompletion = dailyCompletionRepository.save(completion);
-
-        // Link all tasks that were finished at calculation time
-        // (not strictly required for now, but matches schema and enables future analytics)
-        if (finished > 0) {
-            List<TaskDailyCompletion> links = taskRepository.findByDisciplineUser_UserIdAndStatus(userId, TaskStatus.FINISHED)
-                    .stream()
-                    .map(t -> {
-                        TaskDailyCompletion link = new TaskDailyCompletion();
-                        link.setTask(t);
-                        link.setDailyCompletion(savedCompletion);
-                        link.setId(new TaskDailyCompletionId(t.getTaskId(), savedCompletion.getDailyCompletionId()));
-                        return link;
-                    })
-                    .toList();
-            taskDailyCompletionRepository.saveAll(links);
-        }
-
-        // Reset all tasks for next day
-        taskRepository.resetStatusForUser(userId, TaskStatus.NOT_STARTED);
-
-        DailyCompletionDto dto = new DailyCompletionDto(savedCompletion.getDailyCompletionId(),
-                savedCompletion.getDate(), savedCompletion.getProcent());
-        return new ComputeDailyCompletionResponse(true, dto);
-    }
-
-    @Transactional(readOnly = true)
-    public DailyCompletionsResponse getDailyCompletions(Long userId, int page, int size) {
-        if (!disciplineUserRepository.existsById(userId)) {
-            return new DailyCompletionsResponse(List.of(), false);
-        }
-
-        Page<DailyCompletion> result = dailyCompletionRepository
-                .findByUser_UserIdOrderByDateDescDailyCompletionIdDesc(userId, PageRequest.of(page, size));
-
-        List<DailyCompletionDto> items = result.getContent().stream()
-                .map(dc -> new DailyCompletionDto(dc.getDailyCompletionId(), dc.getDate(), dc.getProcent()))
-                .toList();
-
-        return new DailyCompletionsResponse(items, result.hasNext());
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/service/FinanceService.java
===================================================================
--- backend/src/main/java/com/trekr/backend/service/FinanceService.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,159 +1,0 @@
-package com.trekr.backend.service;
-
-import com.trekr.backend.dto.finance.CreateIncomeRequest;
-import com.trekr.backend.dto.finance.FinanceProfileResponse;
-import com.trekr.backend.dto.finance.FinanceStartRequest;
-import com.trekr.backend.dto.finance.IncomeDto;
-import com.trekr.backend.dto.finance.IncomesResponse;
-import com.trekr.backend.entity.User;
-import com.trekr.backend.entity.finance.FinanceUser;
-import com.trekr.backend.entity.finance.Income;
-import com.trekr.backend.repository.FinanceUserRepository;
-import com.trekr.backend.repository.IncomeRepository;
-import com.trekr.backend.repository.UserRepository;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.time.LocalDate;
-import java.util.List;
-
-@Service
-public class FinanceService {
-
-    private final FinanceUserRepository financeUserRepository;
-    private final IncomeRepository incomeRepository;
-    private final UserRepository userRepository;
-
-    public FinanceService(
-            FinanceUserRepository financeUserRepository,
-            IncomeRepository incomeRepository,
-            UserRepository userRepository) {
-        this.financeUserRepository = financeUserRepository;
-        this.incomeRepository = incomeRepository;
-        this.userRepository = userRepository;
-    }
-
-    public boolean isTracking(Long userId) {
-        return financeUserRepository.existsById(userId);
-    }
-
-    @Transactional
-    public void startOrUpdateTracking(Long userId, FinanceStartRequest request) {
-        FinanceUser financeUser = financeUserRepository.findById(userId).orElse(null);
-        if (financeUser == null) {
-            User user = userRepository.findById(userId)
-                    .orElseThrow(() -> new RuntimeException("User not found"));
-            financeUser = new FinanceUser();
-            financeUser.setUser(user);
-        }
-
-        BigDecimal spending = normalizePercent(request.getSpendingBudget());
-        BigDecimal saving = normalizePercent(request.getSavingBudget());
-        BigDecimal investing = normalizePercent(request.getInvestingBudget());
-        BigDecimal donation = normalizePercent(request.getDonationBudget());
-        BigDecimal credit = normalizePercent(request.getCredit());
-
-        validateSumTo100(spending, saving, investing, donation, credit);
-
-        financeUser.setSpendingBudget(spending);
-        financeUser.setSavingBudget(saving);
-        financeUser.setInvestingBudget(investing);
-        financeUser.setDonationBudget(donation);
-        financeUser.setCredit(credit);
-
-        financeUserRepository.save(financeUser);
-    }
-
-    @Transactional(readOnly = true)
-    public FinanceProfileResponse getProfile(Long userId) {
-        FinanceUser financeUser = financeUserRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("Finance tracking is not enabled for this user"));
-
-        return new FinanceProfileResponse(
-                financeUser.getSpendingBudget(),
-                financeUser.getSavingBudget(),
-                financeUser.getInvestingBudget(),
-                financeUser.getDonationBudget(),
-                financeUser.getCredit());
-    }
-
-    @Transactional(readOnly = true)
-    public IncomesResponse getIncomes(Long userId, int page, int size) {
-        if (!financeUserRepository.existsById(userId)) {
-            return new IncomesResponse(List.of(), false);
-        }
-
-        Page<Income> result = incomeRepository.findByFinanceUser_UserIdOrderByDateDescIncomeIdDesc(
-                userId, PageRequest.of(page, size));
-
-        List<IncomeDto> dtos = result.getContent().stream()
-                .map(i -> new IncomeDto(i.getIncomeId(), i.getDate(), i.getAmount()))
-                .toList();
-
-        return new IncomesResponse(dtos, result.hasNext());
-    }
-
-    @Transactional
-    public IncomeDto createIncome(Long userId, CreateIncomeRequest request) {
-        FinanceUser financeUser = financeUserRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("Finance tracking is not enabled for this user"));
-
-        LocalDate date = request.getDate();
-        if (date == null) {
-            throw new RuntimeException("Date is required");
-        }
-        if (date.isAfter(LocalDate.now().plusDays(1))) {
-            throw new RuntimeException("Date cannot be in the future");
-        }
-
-        BigDecimal amount = request.getAmount();
-        if (amount == null) {
-            throw new RuntimeException("Amount is required");
-        }
-        if (amount.compareTo(BigDecimal.ZERO) <= 0) {
-            throw new RuntimeException("Amount must be greater than 0");
-        }
-
-        Income income = new Income();
-        income.setFinanceUser(financeUser);
-        income.setDate(date);
-        income.setAmount(amount);
-
-        Income saved = incomeRepository.save(income);
-        return new IncomeDto(saved.getIncomeId(), saved.getDate(), saved.getAmount());
-    }
-
-    private static BigDecimal normalizePercent(BigDecimal value) {
-        if (value == null) {
-            return null;
-        }
-        return value.setScale(2, RoundingMode.HALF_UP);
-    }
-
-    private static void validateSumTo100(BigDecimal spending, BigDecimal saving, BigDecimal investing, BigDecimal donation,
-            BigDecimal credit) {
-        if (spending == null || saving == null || investing == null || donation == null || credit == null) {
-            throw new RuntimeException("All 5 percentage values are required");
-        }
-
-        List<BigDecimal> list = List.of(spending, saving, investing, donation, credit);
-
-        for (BigDecimal v : list) {
-            if (v.compareTo(BigDecimal.ZERO) < 0 || v.compareTo(new BigDecimal("100")) > 0) {
-                throw new RuntimeException("Percentages must be between 0 and 100");
-            }
-        }
-
-        BigDecimal sum = spending.add(saving).add(investing).add(donation).add(credit);
-        // allow tiny rounding errors (e.g. 33.33 * 3 + 0.01)
-        BigDecimal diff = sum.subtract(new BigDecimal("100")).abs();
-        if (diff.compareTo(new BigDecimal("0.01")) > 0) {
-            throw new RuntimeException("Percentages must sum to 100");
-        }
-    }
-}
-
Index: ckend/src/main/java/com/trekr/backend/service/InvestingService.java
===================================================================
--- backend/src/main/java/com/trekr/backend/service/InvestingService.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,136 +1,0 @@
-package com.trekr.backend.service;
-
-import com.trekr.backend.dto.invest.AssetDto;
-import com.trekr.backend.dto.invest.CreateAssetRequest;
-import com.trekr.backend.dto.invest.InvestingAssetsResponse;
-import com.trekr.backend.entity.User;
-import com.trekr.backend.entity.invest.Asset;
-import com.trekr.backend.entity.invest.InvestorUser;
-import com.trekr.backend.repository.AssetRepository;
-import com.trekr.backend.repository.InvestorUserRepository;
-import com.trekr.backend.repository.UserRepository;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.time.LocalDate;
-import java.util.List;
-import java.util.Locale;
-
-@Service
-public class InvestingService {
-
-    private final InvestorUserRepository investorUserRepository;
-    private final AssetRepository assetRepository;
-    private final UserRepository userRepository;
-
-    public InvestingService(
-            InvestorUserRepository investorUserRepository,
-            AssetRepository assetRepository,
-            UserRepository userRepository) {
-        this.investorUserRepository = investorUserRepository;
-        this.assetRepository = assetRepository;
-        this.userRepository = userRepository;
-    }
-
-    public boolean isTracking(Long userId) {
-        return investorUserRepository.existsById(userId);
-    }
-
-    @Transactional
-    public void startTracking(Long userId) {
-        if (investorUserRepository.existsById(userId)) {
-            return;
-        }
-
-        User user = userRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("User not found"));
-
-        InvestorUser investorUser = new InvestorUser();
-        investorUser.setUser(user);
-        investorUserRepository.save(investorUser);
-    }
-
-    @Transactional(readOnly = true)
-    public InvestingAssetsResponse getAssets(Long userId, int page, int size) {
-        if (!investorUserRepository.existsById(userId)) {
-            return new InvestingAssetsResponse(List.of(), false);
-        }
-
-        Page<Asset> result = assetRepository
-                .findByInvestorUser_UserIdOrderByAssetIdDesc(userId, PageRequest.of(page, size));
-
-        List<AssetDto> assets = result.getContent().stream()
-                .map(a -> new AssetDto(
-                        a.getAssetId(),
-                        a.getTickerSymbol(),
-                        a.getBuyPrice(),
-                        a.getBuyDate(),
-                        a.getQuantity()))
-                .toList();
-
-        return new InvestingAssetsResponse(assets, result.hasNext());
-    }
-
-    @Transactional
-    public AssetDto createAsset(Long userId, CreateAssetRequest request) {
-        InvestorUser investorUser = investorUserRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("Investing tracking is not enabled for this user"));
-
-        String ticker = normalizeTicker(request.getTickerSymbol());
-        if (ticker == null || ticker.isBlank()) {
-            throw new RuntimeException("Ticker symbol is required");
-        }
-
-        if (ticker.length() > 30) {
-            throw new RuntimeException("Ticker symbol is too long");
-        }
-
-        // Allow equities (AAPL), crypto pairs (BTC/USD), indices (^GSPC), FX pairs
-        // (EURUSD=X), etc.
-        if (!ticker.matches("^[A-Z0-9.^=\\-/]{1,30}$")) {
-            throw new RuntimeException("Ticker symbol contains invalid characters");
-        }
-
-        LocalDate buyDate = request.getBuyDate();
-        if (buyDate != null && buyDate.isAfter(LocalDate.now())) {
-            throw new RuntimeException("Buy date cannot be in the future");
-        }
-
-        Asset asset = new Asset();
-        asset.setInvestorUser(investorUser);
-        asset.setTickerSymbol(ticker);
-        asset.setQuantity(request.getQuantity());
-        asset.setBuyPrice(request.getBuyPrice());
-        asset.setBuyDate(buyDate);
-
-        Asset saved = assetRepository.save(asset);
-
-        return new AssetDto(
-                saved.getAssetId(),
-                saved.getTickerSymbol(),
-                saved.getBuyPrice(),
-                saved.getBuyDate(),
-                saved.getQuantity());
-    }
-
-    @Transactional
-    public void deleteAsset(Long userId, Long assetId) {
-        if (assetId == null) {
-            throw new RuntimeException("Asset not found");
-        }
-
-        int deleted = assetRepository.deleteByAssetIdAndInvestorUser_UserId(assetId, userId);
-        if (deleted == 0) {
-            throw new RuntimeException("Asset not found");
-        }
-    }
-
-    private static String normalizeTicker(String tickerSymbol) {
-        if (tickerSymbol == null) {
-            return null;
-        }
-        return tickerSymbol.trim().toUpperCase(Locale.ROOT);
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/service/JwtService.java
===================================================================
--- backend/src/main/java/com/trekr/backend/service/JwtService.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,64 +1,0 @@
-package com.trekr.backend.service;
-
-import com.trekr.backend.security.UserPrincipal;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.JwtException;
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.security.Keys;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-
-import javax.crypto.SecretKey;
-import java.nio.charset.StandardCharsets;
-import java.util.Date;
-
-@Service
-public class JwtService {
-
-    private final SecretKey signingKey;
-    private static final long TOKEN_VALIDITY_MS = 24 * 60 * 60 * 1000; // 24 hours
-
-    public JwtService(@Value("${jwt.secret}") String secret) {
-        String key = secret != null && !secret.isBlank() ? secret : "dev-fallback-secret-min-32-chars-required";
-        if (key.length() < 32) {
-            key = key + "0".repeat(Math.max(0, 32 - key.length()));
-        }
-        this.signingKey = Keys.hmacShaKeyFor(key.getBytes(StandardCharsets.UTF_8));
-    }
-
-    public String generateToken(Long userId, String username, String email) {
-        return Jwts.builder()
-                .subject(String.valueOf(userId))
-                .claim("username", username)
-                .claim("email", email)
-                .issuedAt(new Date())
-                .expiration(new Date(System.currentTimeMillis() + TOKEN_VALIDITY_MS))
-                .signWith(signingKey)
-                .compact();
-    }
-
-    public boolean isTokenValid(String token) {
-        try {
-            parseClaims(token);
-            return true;
-        } catch (JwtException | IllegalArgumentException ex) {
-            return false;
-        }
-    }
-
-    public UserPrincipal parseUserPrincipal(String token) {
-        Claims claims = parseClaims(token);
-        Long userId = Long.valueOf(claims.getSubject());
-        String username = (String) claims.get("username");
-        String email = (String) claims.get("email");
-        return new UserPrincipal(userId, username, email);
-    }
-
-    private Claims parseClaims(String token) {
-        return Jwts.parser()
-                .verifyWith(signingKey)
-                .build()
-                .parseSignedClaims(token)
-                .getPayload();
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/service/TrainingService.java
===================================================================
--- backend/src/main/java/com/trekr/backend/service/TrainingService.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,232 +1,0 @@
-package com.trekr.backend.service;
-
-import com.trekr.backend.dto.training.CreateTrainingSessionRequest;
-import com.trekr.backend.dto.training.TrainingSessionDto;
-import com.trekr.backend.dto.training.TrainingStartRequest;
-import com.trekr.backend.dto.training.TrainingSessionsResponse;
-import com.trekr.backend.dto.training.TrainingProfileResponse;
-import com.trekr.backend.dto.training.WorkoutTypeDto;
-import com.trekr.backend.entity.User;
-import com.trekr.backend.entity.training.TrainingSession;
-import com.trekr.backend.entity.training.TrainingUser;
-import com.trekr.backend.repository.TrainingSessionRepository;
-import com.trekr.backend.repository.TrainingUserRepository;
-import com.trekr.backend.repository.UserRepository;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.math.BigDecimal;
-import java.math.RoundingMode;
-import java.time.LocalDate;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-@Service
-public class TrainingService {
-
-    private static final Map<String, BigDecimal> MET_BY_TYPE = Map.ofEntries(
-            Map.entry("running", new BigDecimal("9.8")),
-            Map.entry("cycling", new BigDecimal("7.5")),
-            Map.entry("walking", new BigDecimal("3.5")),
-            Map.entry("strength", new BigDecimal("6.0")),
-            Map.entry("hiit", new BigDecimal("9.0")),
-            Map.entry("yoga", new BigDecimal("2.5")),
-            Map.entry("swimming", new BigDecimal("8.0")),
-            Map.entry("rowing", new BigDecimal("7.0")),
-            Map.entry("elliptical", new BigDecimal("5.0")),
-
-            // Added types (same calories formula; MET is the only extra input)
-            Map.entry("hiking", new BigDecimal("6.0")),
-            Map.entry("stair-climbing", new BigDecimal("8.8")),
-            Map.entry("jump-rope", new BigDecimal("12.3")),
-            Map.entry("boxing", new BigDecimal("7.8")),
-            Map.entry("basketball", new BigDecimal("8.0")),
-            Map.entry("soccer", new BigDecimal("10.0")),
-            Map.entry("tennis", new BigDecimal("7.3")),
-            Map.entry("dance", new BigDecimal("5.5")),
-            Map.entry("pilates", new BigDecimal("3.0")),
-            Map.entry("stretching", new BigDecimal("2.3")));
-
-    private static final List<String> WORKOUT_TYPE_ORDER = List.of(
-            "running",
-            "cycling",
-            "walking",
-            "strength",
-            "hiit",
-            "yoga",
-            "swimming",
-            "rowing",
-            "elliptical",
-            "hiking",
-            "stair-climbing",
-            "jump-rope",
-            "boxing",
-            "basketball",
-            "soccer",
-            "tennis",
-            "dance",
-            "pilates",
-            "stretching");
-
-    private final TrainingUserRepository trainingUserRepository;
-    private final TrainingSessionRepository trainingSessionRepository;
-    private final UserRepository userRepository;
-
-    public TrainingService(
-            TrainingUserRepository trainingUserRepository,
-            TrainingSessionRepository trainingSessionRepository,
-            UserRepository userRepository) {
-        this.trainingUserRepository = trainingUserRepository;
-        this.trainingSessionRepository = trainingSessionRepository;
-        this.userRepository = userRepository;
-    }
-
-    public boolean isTracking(Long userId) {
-        return trainingUserRepository.existsById(userId);
-    }
-
-    @Transactional
-    public void startTracking(Long userId, TrainingStartRequest request) {
-        if (trainingUserRepository.existsById(userId)) {
-            return;
-        }
-
-        User user = userRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("User not found"));
-
-        TrainingUser trainingUser = new TrainingUser();
-        trainingUser.setUser(user);
-        trainingUser.setGender(request.getGender());
-        trainingUser.setAge(request.getAge());
-        trainingUser.setWeight(request.getWeight());
-
-        trainingUserRepository.save(trainingUser);
-    }
-
-    @Transactional(readOnly = true)
-    public TrainingSessionsResponse getSessions(Long userId, int page, int size) {
-        if (!trainingUserRepository.existsById(userId)) {
-            return new TrainingSessionsResponse(List.of(), false);
-        }
-
-        Page<TrainingSession> result = trainingSessionRepository
-                .findByTrainingUser_UserIdOrderByDateDesc(userId, PageRequest.of(page, size));
-
-        List<TrainingSessionDto> sessions = result.getContent().stream()
-                .map(s -> new TrainingSessionDto(
-                        s.getTrainingId(),
-                        s.getDate(),
-                        s.getType(),
-                        s.getDuration(),
-                        s.getCalories()))
-                .toList();
-
-        return new TrainingSessionsResponse(sessions, result.hasNext());
-    }
-
-    public List<WorkoutTypeDto> getWorkoutTypes() {
-        return WORKOUT_TYPE_ORDER.stream()
-                .map(type -> new WorkoutTypeDto(type, labelForType(type), MET_BY_TYPE.get(type)))
-                .toList();
-    }
-
-    @Transactional(readOnly = true)
-    public TrainingProfileResponse getProfile(Long userId) {
-        TrainingUser trainingUser = trainingUserRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("Training tracking is not enabled for this user"));
-        return new TrainingProfileResponse(trainingUser.getGender(), trainingUser.getAge(), trainingUser.getWeight());
-    }
-
-    @Transactional
-    public TrainingSessionDto createSession(Long userId, CreateTrainingSessionRequest request) {
-        TrainingUser trainingUser = trainingUserRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("Training tracking is not enabled for this user"));
-
-        String type = normalizeType(request.getType());
-        BigDecimal met = MET_BY_TYPE.get(type);
-        if (met == null) {
-            throw new RuntimeException("Unsupported workout type");
-        }
-
-        BigDecimal durationMinutes = request.getDurationMinutes();
-        if (durationMinutes == null || durationMinutes.compareTo(BigDecimal.ONE) < 0) {
-            throw new RuntimeException("Duration must be at least 1 minute");
-        }
-
-        BigDecimal calories;
-        if (Boolean.TRUE.equals(request.getAutoCalculateCalories())) {
-            calories = calculateCalories(trainingUser, met, durationMinutes);
-        } else {
-            calories = request.getCalories();
-            if (calories == null) {
-                throw new RuntimeException("Calories are required when auto-calculation is disabled");
-            }
-            if (calories.compareTo(BigDecimal.ZERO) < 0) {
-                throw new RuntimeException("Calories must be 0 or greater");
-            }
-        }
-
-        TrainingSession session = new TrainingSession();
-        session.setTrainingUser(trainingUser);
-        session.setType(type);
-        session.setDuration(durationMinutes);
-        session.setCalories(calories);
-        // Allow client to supply a date (past or present). If not provided, use today.
-        java.time.LocalDate suppliedDate = request.getDate();
-        if (suppliedDate == null) {
-            suppliedDate = LocalDate.now();
-        }
-        if (suppliedDate.isAfter(LocalDate.now())) {
-            throw new RuntimeException("Date cannot be in the future");
-        }
-        session.setDate(suppliedDate);
-
-        TrainingSession saved = trainingSessionRepository.save(session);
-
-        return new TrainingSessionDto(
-                saved.getTrainingId(),
-                saved.getDate(),
-                saved.getType(),
-                saved.getDuration(),
-                saved.getCalories());
-    }
-
-    private static String normalizeType(String type) {
-        if (type == null) {
-            return null;
-        }
-        return type.trim().toLowerCase(Locale.ROOT);
-    }
-
-    private static String labelForType(String type) {
-        if (type == null || type.isBlank()) {
-            return "";
-        }
-        if ("hiit".equals(type)) {
-            return "HIIT";
-        }
-
-        String normalized = type.replace('_', '-');
-        return Arrays.stream(normalized.split("-"))
-                .filter(part -> !part.isBlank())
-                .map(part -> Character.toUpperCase(part.charAt(0)) + part.substring(1))
-                .collect(Collectors.joining(" "));
-    }
-
-    private static BigDecimal calculateCalories(TrainingUser trainingUser, BigDecimal met, BigDecimal durationMinutes) {
-        BigDecimal weightKg = trainingUser.getWeight();
-        if (weightKg == null) {
-            throw new RuntimeException("Weight is required to auto-calculate calories");
-        }
-
-        BigDecimal durationHours = durationMinutes.divide(new BigDecimal("60"), 10, RoundingMode.HALF_UP);
-        return met.multiply(weightKg)
-                .multiply(durationHours)
-                .setScale(2, RoundingMode.HALF_UP);
-    }
-}
Index: ckend/src/main/java/com/trekr/backend/service/WeightService.java
===================================================================
--- backend/src/main/java/com/trekr/backend/service/WeightService.java	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,228 +1,0 @@
-package com.trekr.backend.service;
-
-import com.trekr.backend.dto.weight.CreateDailyIntakeRequest;
-import com.trekr.backend.dto.weight.TodayTrainingInfoDto;
-import com.trekr.backend.dto.weight.WeightDailyIntakeDto;
-import com.trekr.backend.dto.weight.WeightDailyIntakesResponse;
-import com.trekr.backend.dto.weight.WeightProfileResponse;
-import com.trekr.backend.dto.weight.WeightStartRequest;
-import com.trekr.backend.entity.User;
-import com.trekr.backend.entity.weight.DailyIntake;
-import com.trekr.backend.entity.weight.WeightUser;
-import com.trekr.backend.repository.DailyIntakeRepository;
-import com.trekr.backend.repository.TrainingSessionRepository;
-import com.trekr.backend.repository.UserRepository;
-import com.trekr.backend.repository.WeightUserRepository;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-@Service
-public class WeightService {
-
-    private static final BigDecimal CALORIE_WEIGHT_FACTOR = new BigDecimal("10");
-    private static final BigDecimal CALORIE_HEIGHT_FACTOR = new BigDecimal("6.25");
-    private static final BigDecimal CALORIE_BASE = new BigDecimal("50");
-    private static final BigDecimal LOSS_CALORIE_DELTA = new BigDecimal("500");
-    private static final BigDecimal GAIN_CALORIE_DELTA = new BigDecimal("300");
-
-    private final WeightUserRepository weightUserRepository;
-    private final DailyIntakeRepository dailyIntakeRepository;
-    private final UserRepository userRepository;
-    private final TrainingSessionRepository trainingSessionRepository;
-
-    public WeightService(
-            WeightUserRepository weightUserRepository,
-            DailyIntakeRepository dailyIntakeRepository,
-            UserRepository userRepository,
-            TrainingSessionRepository trainingSessionRepository) {
-        this.weightUserRepository = weightUserRepository;
-        this.dailyIntakeRepository = dailyIntakeRepository;
-        this.userRepository = userRepository;
-        this.trainingSessionRepository = trainingSessionRepository;
-    }
-
-    public boolean isTracking(Long userId) {
-        return weightUserRepository.existsById(userId);
-    }
-
-    @Transactional
-    public void startTracking(Long userId, WeightStartRequest request) {
-        if (weightUserRepository.existsById(userId)) {
-            return;
-        }
-
-        User user = userRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("User not found"));
-
-        BigDecimal goalCalories = resolveGoalCalories(request, request.getWeight(), request.getHeight(), request.getGoalWeight());
-
-        WeightUser weightUser = new WeightUser();
-        weightUser.setUser(user);
-        weightUser.setWeight(request.getWeight());
-        weightUser.setHeight(request.getHeight());
-        weightUser.setGoalWeight(request.getGoalWeight());
-        weightUser.setGoalCalories(goalCalories);
-
-        weightUserRepository.save(weightUser);
-    }
-
-    @Transactional(readOnly = true)
-    public WeightProfileResponse getProfile(Long userId) {
-        WeightUser weightUser = weightUserRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("Weight tracking is not enabled for this user"));
-
-        return new WeightProfileResponse(
-                weightUser.getWeight(),
-                weightUser.getHeight(),
-                weightUser.getGoalWeight(),
-                weightUser.getGoalCalories());
-    }
-
-    @Transactional(readOnly = true)
-    public WeightDailyIntakesResponse getDailyIntakes(Long userId, int page, int size) {
-        if (!weightUserRepository.existsById(userId)) {
-            return new WeightDailyIntakesResponse(List.of(), false, false);
-        }
-
-        Page<DailyIntake> result = dailyIntakeRepository
-                .findByWeightUser_UserIdOrderByDateDesc(userId, PageRequest.of(page, size));
-
-        List<LocalDate> dates = result.getContent().stream()
-                .map(DailyIntake::getDate)
-                .distinct()
-                .toList();
-
-        Map<LocalDate, Integer> trainingCountsByDate = new HashMap<>();
-        Map<LocalDate, BigDecimal> burnedCaloriesByDate = new HashMap<>();
-        if (!dates.isEmpty()) {
-            trainingSessionRepository.findByTrainingUser_UserIdAndDateIn(userId, dates).forEach(session -> {
-                LocalDate sessionDate = session.getDate();
-                trainingCountsByDate.merge(sessionDate, 1, Integer::sum);
-                BigDecimal calories = session.getCalories() != null ? session.getCalories() : BigDecimal.ZERO;
-                burnedCaloriesByDate.merge(sessionDate, calories, BigDecimal::add);
-            });
-        }
-
-        List<WeightDailyIntakeDto> intakes = result.getContent().stream()
-                .map(d -> {
-                    boolean trainedThatDay = trainingCountsByDate.getOrDefault(d.getDate(), 0) > 0;
-                    BigDecimal burnedCalories = burnedCaloriesByDate.getOrDefault(d.getDate(), BigDecimal.ZERO)
-                            .setScale(2, java.math.RoundingMode.HALF_UP);
-
-                    return new WeightDailyIntakeDto(
-                            d.getDailyIntakeId(),
-                            d.getDate(),
-                            d.getCalories(),
-                            trainedThatDay,
-                            burnedCalories);
-                })
-                .toList();
-
-        boolean hasTodayIntake = dailyIntakeRepository.existsByWeightUser_UserIdAndDate(userId, LocalDate.now());
-        return new WeightDailyIntakesResponse(intakes, result.hasNext(), hasTodayIntake);
-    }
-
-    @Transactional
-    public WeightDailyIntakeDto createDailyIntake(Long userId, CreateDailyIntakeRequest request) {
-        WeightUser weightUser = weightUserRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("Weight tracking is not enabled for this user"));
-
-        LocalDate today = LocalDate.now();
-        if (dailyIntakeRepository.existsByWeightUser_UserIdAndDate(userId, today)) {
-            throw new RuntimeException("Today's intake has already been recorded");
-        }
-
-        DailyIntake intake = new DailyIntake();
-        intake.setWeightUser(weightUser);
-        intake.setCalories(request.getCalories());
-        intake.setDate(today);
-
-        DailyIntake saved = dailyIntakeRepository.save(intake);
-        
-        // Fetch today's training data
-        var trainingSessions = trainingSessionRepository.findByTrainingUser_UserIdAndDate(userId, today);
-        boolean trainedToday = !trainingSessions.isEmpty();
-        BigDecimal burnedCalories = trainingSessions.stream()
-                .map(ts -> ts.getCalories() != null ? ts.getCalories() : BigDecimal.ZERO)
-                .reduce(BigDecimal.ZERO, BigDecimal::add)
-                .setScale(2, java.math.RoundingMode.HALF_UP);
-        
-        return new WeightDailyIntakeDto(saved.getDailyIntakeId(), saved.getDate(), saved.getCalories(), trainedToday, burnedCalories);
-    }
-
-    public WeightProfileResponse updateProfile(Long userId, WeightStartRequest request) {
-        WeightUser weightUser = weightUserRepository.findById(userId)
-                .orElseThrow(() -> new RuntimeException("Weight tracking is not enabled for this user"));
-
-        BigDecimal goalCalories = resolveGoalCalories(request, request.getWeight(), request.getHeight(), request.getGoalWeight());
-
-        weightUser.setWeight(request.getWeight());
-        weightUser.setHeight(request.getHeight());
-        weightUser.setGoalWeight(request.getGoalWeight());
-        weightUser.setGoalCalories(goalCalories);
-
-        WeightUser updated = weightUserRepository.save(weightUser);
-        return new WeightProfileResponse(
-                updated.getWeight(),
-                updated.getHeight(),
-                updated.getGoalWeight(),
-                updated.getGoalCalories());
-    }
-
-    @Transactional(readOnly = true)
-    public TodayTrainingInfoDto getTodayTrainingInfo(Long userId) {
-        // Try to get training user, if doesn't exist just return zeros
-        var trainingUser = trainingSessionRepository.findByTrainingUser_UserIdAndDate(userId, LocalDate.now());
-
-        boolean trainedToday = !trainingUser.isEmpty();
-        BigDecimal totalBurnedCalories = trainingUser.stream()
-                .map(ts -> ts.getCalories() != null ? ts.getCalories() : BigDecimal.ZERO)
-                .reduce(BigDecimal.ZERO, BigDecimal::add)
-                .setScale(2, java.math.RoundingMode.HALF_UP);
-
-        return new TodayTrainingInfoDto(trainedToday, totalBurnedCalories);
-    }
-
-    private static BigDecimal resolveGoalCalories(
-            WeightStartRequest request,
-            BigDecimal currentWeight,
-            BigDecimal height,
-            BigDecimal goalWeight) {
-        if (!Boolean.FALSE.equals(request.getAutoCalculateTargets())) {
-            return calculateGoalCalories(currentWeight, height, goalWeight);
-        }
-
-        BigDecimal goalCalories = request.getGoalCalories();
-        if (goalCalories == null) {
-            throw new RuntimeException("Goal calories are required when auto-calculation is disabled");
-        }
-        if (goalCalories.compareTo(BigDecimal.ZERO) < 0) {
-            throw new RuntimeException("Goal calories must be 0 or greater");
-        }
-        return goalCalories.setScale(2, java.math.RoundingMode.HALF_UP);
-    }
-
-    private static BigDecimal calculateGoalCalories(BigDecimal currentWeight, BigDecimal height, BigDecimal goalWeight) {
-        BigDecimal maintenanceCalories = currentWeight.multiply(CALORIE_WEIGHT_FACTOR)
-                .add(height.multiply(CALORIE_HEIGHT_FACTOR))
-                .add(CALORIE_BASE)
-                .setScale(2, java.math.RoundingMode.HALF_UP);
-
-        int direction = goalWeight.compareTo(currentWeight);
-        if (direction < 0) {
-            return maintenanceCalories.subtract(LOSS_CALORIE_DELTA).max(BigDecimal.ZERO).setScale(2, java.math.RoundingMode.HALF_UP);
-        }
-        if (direction > 0) {
-            return maintenanceCalories.add(GAIN_CALORIE_DELTA).setScale(2, java.math.RoundingMode.HALF_UP);
-        }
-        return maintenanceCalories;
-    }
-}
Index: backend/src/main/resources/application.properties
===================================================================
--- backend/src/main/resources/application.properties	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ backend/src/main/resources/application.properties	(revision 72053b5fc3ff291757af1cdd64e8fdfcb9e9b17d)
@@ -1,54 +1,1 @@
-spring.application.name=trekr
-
-# ============================
-# JPA & Hibernate
-# ============================
-# NOTE: On some managed PostgreSQL providers the app user cannot read pg_catalog views
-# like pg_settings. Hibernate schema migration/metadata introspection can trigger that
-# access during startup (e.g., when ddl-auto=update).
-#
-# Default to no automatic DDL. Override locally if your DB user has sufficient rights:
-#   export SPRING_JPA_HIBERNATE_DDL_AUTO=update
-spring.jpa.hibernate.ddl-auto=${SPRING_JPA_HIBERNATE_DDL_AUTO:none}
-spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
-spring.jpa.show-sql=false
-spring.jpa.properties.hibernate.format_sql=true
-spring.jpa.properties.hibernate.default_schema=trekr
-spring.jpa.properties.hibernate.hbm2ddl.create_namespaces=true
-
-# Avoid JDBC metadata access on boot (further reduces pg_catalog permission requirements)
-spring.jpa.properties.hibernate.boot.allow_jdbc_metadata_access=false
-
-# ============================
-# PostgreSQL connection (loaded from backend/.env or backend/env)
-# ============================
-spring.datasource.driver-class-name=org.postgresql.Driver
-spring.datasource.url=${SPRING_DATASOURCE_URL}
-spring.datasource.username=${SPRING_DATASOURCE_USERNAME}
-spring.datasource.password=${SPRING_DATASOURCE_PASSWORD}
-
-# ============================
-# JWT Configuration (supports JWT_SECRET or JWT_CONFIG_SECRET)
-# ============================
-jwt.secret=${JWT_SECRET:${JWT_CONFIG_SECRET:dev-fallback-secret-min-32-chars-required}}
-
-# ============================
-# Logging
-# ============================
-logging.level.org.springframework.security=DEBUG
-
-# ============================
-# HikariCP
-# ============================
-spring.datasource.hikari.pool-name=trekrHikariPool
-# Remote PostgreSQL (especially via SSH tunnel) often has a small max_connections.
-# Use a slightly larger default so the app can serve more concurrent users without
-# overloading the database; override via env if your provider has tighter limits.
-spring.datasource.hikari.maximum-pool-size=${SPRING_DATASOURCE_HIKARI_MAX_POOL_SIZE:20}
-spring.datasource.hikari.minimum-idle=${SPRING_DATASOURCE_HIKARI_MIN_IDLE:5}
-spring.datasource.hikari.connection-timeout=30000
-spring.datasource.hikari.idle-timeout=600000
-spring.datasource.hikari.max-lifetime=1800000
-
-# Max multipart parts
-server.tomcat.max-part-count=50
+spring.application.name=backend
Index: ckend/src/test/resources/application.properties
===================================================================
--- backend/src/test/resources/application.properties	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,21 +1,0 @@
-# Test profile: use in-memory DB so tests don't require external Postgres
-
-spring.datasource.url=jdbc:h2:mem:trekr;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DATABASE_TO_LOWER=TRUE
-spring.datasource.driver-class-name=org.h2.Driver
-spring.datasource.username=sa
-spring.datasource.password=
-
-spring.jpa.hibernate.ddl-auto=create-drop
-spring.jpa.show-sql=false
-spring.jpa.properties.hibernate.format_sql=true
-spring.jpa.properties.hibernate.default_schema=trekr
-spring.jpa.properties.hibernate.hbm2ddl.create_namespaces=false
-
-# Ensure schema exists before Hibernate runs DDL
-spring.sql.init.mode=always
-
-# JWT secret for tests
-jwt.secret=test-secret-min-32-chars-000000000000
-
-# Keep noise down in tests
-logging.level.org.springframework.security=INFO
Index: ckend/src/test/resources/schema.sql
===================================================================
--- backend/src/test/resources/schema.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,2 +1,0 @@
-CREATE SCHEMA IF NOT EXISTS trekr;
-SET SCHEMA trekr;
Index: -scripts/ddl.sql
===================================================================
--- db-scripts/ddl.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,149 +1,0 @@
-DROP SCHEMA IF EXISTS trekr CASCADE;
-
-CREATE SCHEMA trekr;
-
-SET search_path TO trekr;
-DROP TABLE IF EXISTS TASK_DAILY_COMPLETION;
-DROP TABLE IF EXISTS DAILY_COMPLETION;
-DROP TABLE IF EXISTS TASKS;
-DROP TABLE IF EXISTS CUSTOM_TRACKING_CATEGORIES;
-DROP TABLE IF EXISTS ASSETS;
-DROP TABLE IF EXISTS INVESTOR_USERS;
-DROP TABLE IF EXISTS DAILY_INTAKES;
-DROP TABLE IF EXISTS WEIGHT_USERS;
-DROP TABLE IF EXISTS TRAINING_SESSIONS;
-DROP TABLE IF EXISTS TRAINING_USERS;
-DROP TABLE IF EXISTS INCOMES;
-DROP TABLE IF EXISTS FINANCE_USERS;
-DROP TABLE IF EXISTS DISCIPLINE_USERS;
-DROP TABLE IF EXISTS USERS;
-
-CREATE TABLE USERS (
-    user_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
-    email TEXT NOT NULL UNIQUE,
-    username TEXT NOT NULL UNIQUE,
-    password TEXT NOT NULL
-);
-
-CREATE TABLE FINANCE_USERS (
-    user_id BIGINT PRIMARY KEY
-        REFERENCES USERS(user_id) ON DELETE CASCADE,
-    spending_budget NUMERIC,
-    saving_budget NUMERIC,
-    investing_budget NUMERIC,
-    donation_budget NUMERIC,
-    credit NUMERIC
-);
-
-CREATE TABLE INCOMES (
-    income_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
-    user_id BIGINT
-        REFERENCES FINANCE_USERS(user_id) ON DELETE CASCADE,
-    date DATE NOT NULL,
-    amount NUMERIC NOT NULL
-);
-
-CREATE TABLE TRAINING_USERS (
-    user_id BIGINT PRIMARY KEY
-        REFERENCES USERS(user_id) ON DELETE CASCADE,
-    gender TEXT,
-    age INTEGER,
-    weight NUMERIC
-);
-
-CREATE TABLE WEIGHT_USERS (
-    user_id BIGINT PRIMARY KEY
-        REFERENCES USERS(user_id) ON DELETE CASCADE,
-    weight NUMERIC NOT NULL,
-    height NUMERIC NOT NULL,
-    goal_weight NUMERIC NOT NULL,
-    goal_calories NUMERIC NOT NULL
-);
-
-CREATE TABLE DAILY_INTAKES (
-    daily_intake_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
-    user_id BIGINT
-        REFERENCES WEIGHT_USERS(user_id) ON DELETE CASCADE,
-    calories NUMERIC NOT NULL,
-    date DATE NOT NULL,
-
-    CONSTRAINT daily_intakes_unique_user_date UNIQUE (user_id, date)
-);
-
-CREATE TABLE TRAINING_SESSIONS (
-    training_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
-    training_user_id BIGINT
-        REFERENCES TRAINING_USERS(user_id) ON DELETE CASCADE,
-    duration NUMERIC,
-    calories NUMERIC,
-    date DATE,
-    type TEXT
-);
-
-CREATE TABLE DISCIPLINE_USERS (
-    user_id BIGINT PRIMARY KEY
-        REFERENCES USERS(user_id) ON DELETE CASCADE
-);
-
-CREATE TABLE CUSTOM_TRACKING_CATEGORIES (
-    custom_tracking_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
-    user_id BIGINT
-        REFERENCES USERS(user_id) ON DELETE CASCADE,
-    name TEXT NOT NULL
-);
-
-CREATE TABLE TASKS (
-    task_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
-    name TEXT NOT NULL,
-    status VARCHAR(20) NOT NULL DEFAULT 'NOT_STARTED',
-    description TEXT,
-    due_date DATE,
-    priority VARCHAR(10),
-
-    discipline_user_id BIGINT
-        REFERENCES DISCIPLINE_USERS(user_id) ON DELETE CASCADE,
-
-    custom_tracking_id BIGINT
-        REFERENCES CUSTOM_TRACKING_CATEGORIES(custom_tracking_id)
-        ON DELETE CASCADE,
-
-    CONSTRAINT task_belongs_to_exactly_one_category
-        CHECK (
-            (discipline_user_id IS NOT NULL AND custom_tracking_id IS NULL)
-            OR
-            (discipline_user_id IS NULL AND custom_tracking_id IS NOT NULL)
-        )
-);
-
-CREATE TABLE DAILY_COMPLETION (
-    daily_completion_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
-    user_id BIGINT
-        REFERENCES USERS(user_id) ON DELETE CASCADE,
-    date DATE,
-    procent NUMERIC
-);
-
-CREATE TABLE TASK_DAILY_COMPLETION (
-    task_id BIGINT
-        REFERENCES TASKS(task_id) ON DELETE CASCADE,
-    daily_completion_id BIGINT
-        REFERENCES DAILY_COMPLETION(daily_completion_id) ON DELETE CASCADE,
-
-    CONSTRAINT task_daily_completion_pk
-        PRIMARY KEY (task_id, daily_completion_id)
-);
-
-CREATE TABLE INVESTOR_USERS (
-    user_id BIGINT PRIMARY KEY
-        REFERENCES USERS(user_id) ON DELETE CASCADE
-);
-
-CREATE TABLE ASSETS (
-    asset_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
-    user_id BIGINT
-        REFERENCES INVESTOR_USERS(user_id) ON DELETE CASCADE,
-    ticker_symbol TEXT NOT NULL,
-    buy_price NUMERIC,
-    buy_date DATE,
-    quantity NUMERIC
-);
Index: -scripts/dml.sql
===================================================================
--- db-scripts/dml.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,427 +1,0 @@
-SET search_path TO trekr;
-
-INSERT INTO USERS (user_id, email, username, password) VALUES
-(1, 'dimitar@example.com', 'dimitar_arsov', '1234'),
-(2, 'filip@example.com', 'filip_gavrilovski', '1234'),
-(3, 'marko@example.com', 'marko_markovski', '1234'),
-(4, 'andrej.shumanovski@gmail.com', 'andrej_shumanovski', '1234'),
-(5, 'angelovski.mario222@gmail.com', 'angelovski_mario', '1234'),
-(6, 'ana@example.com', 'ana_ilievska', '1234'),
-(7, 'petar@example.com', 'petar_stojanov', '1234'),
-(8, 'elena@example.com', 'elena_ristova', '1234'),
-(9, 'stefan@example.com', 'stefan_nikolov', '1234'),
-(10, 'ivana@example.com', 'ivana_karapandzova', '1234'),
-(11, 'nikola@example.com', 'nikola_ivanov', '1234'),
-(12, 'marija@example.com', 'marija_petrova', '1234'),
-(13, 'viktor@example.com', 'viktor_stojkov', '1234'),
-(14, 'katerina@example.com', 'katerina_ristevska', '1234'),
-(15, 'jovan@example.com', 'jovan_mitev', '1234'),
-(16, 'teodora@example.com', 'teodora_angelova', '1234'),
-(17, 'bojan@example.com', 'bojan_popov', '1234'),
-(18, 'sara@example.com', 'sara_karovska', '1234'),
-(19, 'aleksandar@example.com', 'aleksandar_dimitrov', '1234'),
-(20, 'milena@example.com', 'milena_stefanovska', '1234'),
-(21, 'goran@example.com', 'goran_iliev', '1234'),
-(22, 'kristina@example.com', 'kristina_georgieva', '1234'),
-(23, 'martin@example.com', 'martin_danev', '1234'),
-(24, 'ema@example.com', 'ema_spasovska', '1234'),
-(25, 'daniel@example.com', 'daniel_nikolov', '1234'),
-(26, 'irena@example.com', 'irena_jovanovska', '1234'),
-(27, 'stojan@example.com', 'stojan_tasev', '1234'),
-(28, 'vanja@example.com', 'vanja_trajkovska', '1234'),
-(29, 'petra@example.com', 'petra_kostova', '1234'),
-(30, 'vlado@example.com', 'vlado_ilievski', '1234');
-
-SELECT setval(
-	pg_get_serial_sequence('trekr.users', 'user_id'),
-	(SELECT COALESCE(MAX(user_id), 0) FROM trekr.users)
-);
-
-INSERT INTO FINANCE_USERS (user_id, spending_budget, saving_budget, investing_budget, donation_budget, credit) VALUES
-(1, 500, 200, 300, 50, 1000),
-(2, 600, 250, 200, 30, 500),
-(3, 400, 150, 250, 20, 0),
-(4, 1000, 500, 500, 100, 2000),
-(5, 700, 300, 200, 40, 800),
-(6, 450, 150, 150, 20, 200),
-(7, 900, 350, 250, 60, 1200),
-(8, 550, 200, 300, 25, 0),
-(9, 800, 300, 400, 50, 1500),
-(10, 650, 250, 200, 30, 400),
-(11, 750, 250, 200, 25, 600),
-(12, 520, 220, 180, 15, 300),
-(13, 900, 400, 350, 40, 1500),
-(14, 480, 180, 120, 10, 200),
-(15, 1100, 500, 450, 70, 2500),
-(16, 650, 250, 200, 20, 400),
-(17, 700, 260, 240, 25, 850),
-(18, 560, 210, 160, 15, 150),
-(19, 980, 420, 380, 55, 1800),
-(20, 600, 230, 220, 20, 500),
-(21, 430, 160, 120, 10, 0),
-(22, 820, 330, 260, 35, 1100),
-(23, 740, 290, 240, 30, 700),
-(24, 500, 200, 150, 15, 250),
-(25, 1200, 550, 500, 80, 3000);
-
-INSERT INTO INCOMES (income_id, user_id, date, amount) VALUES
-(1, 1, '2026-01-01', 2000),
-(2, 2, '2026-01-03', 1800),
-(3, 3, '2026-01-05', 2200),
-(4, 4, '2026-01-07', 5000),
-(5, 5, '2026-01-08', 3200),
-(6, 6, '2026-01-10', 1600),
-(7, 7, '2026-01-12', 4100),
-(8, 8, '2026-01-14', 2300),
-(9, 9, '2026-01-16', 3700),
-(10, 10, '2026-01-18', 1900),
-(11, 11, '2026-02-01', 2600),
-(12, 11, '2026-03-01', 2600),
-(13, 12, '2026-02-03', 2100),
-(14, 12, '2026-03-03', 2150),
-(15, 13, '2026-02-05', 3300),
-(16, 13, '2026-03-05', 3400),
-(17, 14, '2026-02-07', 1900),
-(18, 14, '2026-03-07', 1950),
-(19, 15, '2026-02-09', 5200),
-(20, 15, '2026-03-09', 5200),
-(21, 16, '2026-02-11', 2400),
-(22, 16, '2026-03-11', 2450),
-(23, 17, '2026-02-13', 2700),
-(24, 17, '2026-03-13', 2750),
-(25, 18, '2026-02-15', 2200),
-(26, 18, '2026-03-15', 2250),
-(27, 19, '2026-02-17', 4100),
-(28, 19, '2026-03-17', 4150),
-(29, 20, '2026-02-19', 2500),
-(30, 20, '2026-03-19', 2550),
-(31, 21, '2026-02-21', 1600),
-(32, 22, '2026-02-23', 2900),
-(33, 22, '2026-03-23', 2950),
-(34, 23, '2026-02-25', 2750),
-(35, 23, '2026-03-25', 2800),
-(36, 24, '2026-02-27', 2050),
-(37, 24, '2026-03-27', 2100),
-(38, 25, '2026-02-28', 6000),
-(39, 25, '2026-03-28', 6050);
-
-SELECT setval(
-	pg_get_serial_sequence('trekr.incomes', 'income_id'),
-	(SELECT COALESCE(MAX(income_id), 0) FROM trekr.incomes)
-);
-
-INSERT INTO TRAINING_USERS (user_id, gender, age, weight) VALUES
-(1, 'Male', 21, 73),
-(2, 'Male', 23, 80),
-(3, 'Male', 22, 78),
-(4, 'Female', 25, 65),
-(5, 'Male', 24, 86),
-(6, 'Female', 22, 58),
-(7, 'Male', 28, 92),
-(8, 'Female', 26, 70),
-(9, 'Male', 30, 83),
-(10, 'Female', 21, 62),
-(11, 'Male', 27, 82),
-(12, 'Female', 24, 61),
-(13, 'Male', 29, 90),
-(14, 'Female', 23, 57),
-(15, 'Male', 31, 88),
-(16, 'Female', 28, 66),
-(17, 'Male', 26, 76),
-(18, 'Female', 22, 55),
-(19, 'Male', 33, 94),
-(20, 'Female', 30, 69);
-
-INSERT INTO WEIGHT_USERS (user_id, weight, height, goal_weight, goal_calories) VALUES
-(1, 73, 181, 70, 2500),
-(2, 80, 185, 75, 2600),
-(3, 78, 180, 74, 2400),
-(4, 65, 170, 60, 2000),
-(5, 86, 188, 80, 2800),
-(6, 58, 165, 55, 1900),
-(7, 92, 190, 85, 3000),
-(8, 70, 172, 66, 2100),
-(9, 83, 179, 78, 2500),
-(10, 62, 168, 58, 2000),
-(11, 82, 183, 78, 2600),
-(12, 61, 169, 58, 2000),
-(13, 90, 191, 85, 2900),
-(14, 57, 164, 55, 1900),
-(15, 88, 186, 82, 2800),
-(16, 66, 172, 62, 2100),
-(17, 76, 179, 72, 2500),
-(18, 55, 162, 53, 1850),
-(19, 94, 193, 88, 3100),
-(20, 69, 173, 65, 2200);
-
-INSERT INTO DAILY_INTAKES (daily_intake_id, user_id, calories, date) VALUES
-(1, 1, 2400, '2026-02-01'),
-(2, 2, 2500, '2026-02-01'),
-(3, 3, 2300, '2026-02-01'),
-(4, 4, 2100, '2026-02-02'),
-(5, 5, 2750, '2026-02-02'),
-(6, 6, 1850, '2026-02-02'),
-(7, 7, 2950, '2026-02-03'),
-(8, 8, 2050, '2026-02-03'),
-(9, 9, 2450, '2026-02-03'),
-(10, 10, 1950, '2026-02-04'),
-(11, 11, 2550, '2026-02-05'),
-(12, 11, 2450, '2026-02-06'),
-(13, 12, 1980, '2026-02-05'),
-(14, 12, 2050, '2026-02-06'),
-(15, 13, 2850, '2026-02-06'),
-(16, 13, 2950, '2026-02-07'),
-(17, 14, 1850, '2026-02-06'),
-(18, 14, 1900, '2026-02-07'),
-(19, 15, 2700, '2026-02-07'),
-(20, 15, 2750, '2026-02-08'),
-(21, 16, 2150, '2026-02-07'),
-(22, 16, 2250, '2026-02-08'),
-(23, 17, 2400, '2026-02-08'),
-(24, 17, 2500, '2026-02-09'),
-(25, 18, 1800, '2026-02-08'),
-(26, 18, 1900, '2026-02-09'),
-(27, 19, 3000, '2026-02-09'),
-(28, 19, 3100, '2026-02-10'),
-(29, 20, 2200, '2026-02-09'),
-(30, 20, 2300, '2026-02-10');
-
-SELECT setval(
-	pg_get_serial_sequence('trekr.daily_intakes', 'daily_intake_id'),
-	(SELECT COALESCE(MAX(daily_intake_id), 0) FROM trekr.daily_intakes)
-);
-
-INSERT INTO TRAINING_SESSIONS (training_id, training_user_id, duration, calories, date, type) VALUES
-(1, 1, 60, 500, '2026-02-01', 'running'),
-(2, 2, 45, 400, '2026-02-01', 'cycling'),
-(3, 3, 30, 300, '2026-02-01', 'swimming'),
-(4, 4, 50, 420, '2026-02-02', 'hiit'),
-(5, 5, 40, 350, '2026-02-02', 'strength'),
-(6, 6, 35, 280, '2026-02-02', 'yoga'),
-(7, 7, 55, 520, '2026-02-03', 'running'),
-(8, 8, 45, 390, '2026-02-03', 'cycling'),
-(9, 9, 30, 260, '2026-02-03', 'rowing'),
-(10, 10, 60, 480, '2026-02-04', 'swimming'),
-(11, 11, 50, 430, '2026-02-05', 'strength'),
-(12, 12, 40, 310, '2026-02-05', 'yoga'),
-(13, 13, 60, 540, '2026-02-06', 'running'),
-(14, 14, 35, 260, '2026-02-06', 'pilates'),
-(15, 15, 45, 390, '2026-02-07', 'cycling'),
-(16, 16, 55, 460, '2026-02-07', 'hiit'),
-(17, 17, 30, 240, '2026-02-08', 'rowing'),
-(18, 18, 65, 520, '2026-02-08', 'swimming'),
-(19, 19, 50, 440, '2026-02-09', 'running'),
-(20, 20, 45, 370, '2026-02-09', 'strength'),
-(21, 11, 35, 300, '2026-02-12', 'cycling'),
-(22, 13, 30, 260, '2026-02-12', 'strength'),
-(23, 15, 70, 600, '2026-02-13', 'running'),
-(24, 17, 40, 320, '2026-02-13', 'strength');
-
-SELECT setval(
-	pg_get_serial_sequence('trekr.training_sessions', 'training_id'),
-	(SELECT COALESCE(MAX(training_id), 0) FROM trekr.training_sessions)
-);
-
-INSERT INTO DISCIPLINE_USERS (user_id) VALUES
-(1),
-(2),
-(3),
-(4),
-(5),
-(6),
-(7),
-(8),
-(9),
-(10),
-(11),
-(12),
-(13),
-(14),
-(15);
-
-INSERT INTO CUSTOM_TRACKING_CATEGORIES (custom_tracking_id, user_id, name) VALUES
-(1, 1, 'Project Trekr'),
-(2, 2, 'Language Learning'),
-(3, 3, 'Side Hustle'),
-(4, 5, 'Fitness Plan'),
-(5, 6, 'Exam Prep'),
-(6, 11, 'University'),
-(7, 12, 'Health'),
-(8, 13, 'Startup'),
-(9, 14, 'Cooking'),
-(10, 15, 'Reading List'),
-(11, 16, 'Work Sprint'),
-(12, 17, 'Finance Goals'),
-(13, 18, 'Language'),
-(14, 19, 'Gym Program'),
-(15, 20, 'Exam Prep');
-
-SELECT setval(
-	pg_get_serial_sequence('trekr.custom_tracking_categories', 'custom_tracking_id'),
-	(SELECT COALESCE(MAX(custom_tracking_id), 0) FROM trekr.custom_tracking_categories)
-);
-
-INSERT INTO TASKS (task_id, name, status, discipline_user_id, custom_tracking_id) VALUES
-(1, 'Morning Run', 'NOT_STARTED', 1, NULL),
-(2, 'Read Book', 'NOT_STARTED', 1, NULL),
-(3, 'Meditation', 'NOT_STARTED', 2, NULL),
-(4, 'Code Review', 'NOT_STARTED', NULL, 1),
-(5, 'Push Updates', 'NOT_STARTED', NULL, 1),
-(6, 'Plan Day', 'NOT_STARTED', 3, NULL),
-(7, 'No Sugar', 'NOT_STARTED', 3, NULL),
-(8, 'Stretch', 'NOT_STARTED', 3, NULL),
-(9, 'Drink Water', 'NOT_STARTED', 4, NULL),
-(10, 'Walk 8k Steps', 'NOT_STARTED', 4, NULL),
-(11, 'Journal', 'NOT_STARTED', 5, NULL),
-(12, 'Gym', 'NOT_STARTED', 5, NULL),
-(13, 'Duolingo', 'NOT_STARTED', NULL, 2),
-(14, 'Watch Lesson', 'NOT_STARTED', NULL, 2),
-(15, 'Practice Problems', 'NOT_STARTED', NULL, 5),
-(16, 'Stretch 10m', 'NOT_STARTED', 7, NULL),
-(17, 'No Soda', 'NOT_STARTED', 7, NULL),
-(18, 'Walk 30m', 'NOT_STARTED', 8, NULL),
-(19, 'Sleep 7h', 'NOT_STARTED', 8, NULL),
-(20, 'Read 20p', 'NOT_STARTED', 9, NULL),
-(21, 'Meditate', 'NOT_STARTED', 9, NULL),
-(22, 'No Sugar', 'NOT_STARTED', 9, NULL),
-(23, 'Drink Water', 'NOT_STARTED', 10, NULL),
-(24, 'Morning Run', 'NOT_STARTED', 11, NULL),
-(25, 'Plan Day', 'NOT_STARTED', 11, NULL),
-(26, 'Study 1h', 'NOT_STARTED', 11, NULL),
-(27, 'Yoga', 'NOT_STARTED', 12, NULL),
-(28, 'Cook Healthy', 'NOT_STARTED', 12, NULL),
-(29, 'Gym', 'NOT_STARTED', 13, NULL),
-(30, 'Protein Target', 'NOT_STARTED', 13, NULL),
-(31, 'Journal', 'NOT_STARTED', 14, NULL),
-(32, 'Early Bed', 'NOT_STARTED', 14, NULL),
-(33, 'Duolingo', 'NOT_STARTED', 15, NULL),
-(34, 'No Alcohol', 'NOT_STARTED', 15, NULL),
-(35, 'Walk 8k Steps', 'NOT_STARTED', 15, NULL),
-(36, 'Attend Lecture', 'NOT_STARTED', NULL, 6),
-(37, 'Solve Tasks', 'NOT_STARTED', NULL, 6),
-(38, 'Review', 'NOT_STARTED', NULL, 6),
-(39, 'Steps', 'NOT_STARTED', NULL, 7),
-(40, 'Water', 'NOT_STARTED', NULL, 7),
-(41, 'Pitch', 'NOT_STARTED', NULL, 8),
-(42, 'Build', 'NOT_STARTED', NULL, 8),
-(43, 'Ship', 'NOT_STARTED', NULL, 8),
-(44, 'Meal Prep', 'NOT_STARTED', NULL, 9),
-(45, 'Groceries', 'NOT_STARTED', NULL, 9),
-(46, 'Read Fiction', 'NOT_STARTED', NULL, 10),
-(47, 'Read Nonfiction', 'NOT_STARTED', NULL, 10),
-(48, 'Standup', 'NOT_STARTED', NULL, 11),
-(49, 'Tickets', 'NOT_STARTED', NULL, 11),
-(50, 'PR Review', 'NOT_STARTED', NULL, 11),
-(51, 'Track Expenses', 'NOT_STARTED', NULL, 12),
-(52, 'Invest', 'NOT_STARTED', NULL, 12),
-(53, 'Duolingo Session', 'NOT_STARTED', NULL, 13),
-(54, 'Podcast', 'NOT_STARTED', NULL, 13),
-(55, 'Squat', 'NOT_STARTED', NULL, 14),
-(56, 'Bench', 'NOT_STARTED', NULL, 14),
-(57, 'Deadlift', 'NOT_STARTED', NULL, 14),
-(58, 'Practice', 'NOT_STARTED', NULL, 15),
-(59, 'Mock', 'NOT_STARTED', NULL, 15),
-(60, 'Review Exam', 'NOT_STARTED', NULL, 15);
-
-SELECT setval(
-	pg_get_serial_sequence('trekr.tasks', 'task_id'),
-	(SELECT COALESCE(MAX(task_id), 0) FROM trekr.tasks)
-);
-
-INSERT INTO DAILY_COMPLETION (daily_completion_id, user_id, date, procent) VALUES
-(1, 1, '2026-02-01', 100),
-(2, 2, '2026-02-01', 50),
-(3, 3, '2026-02-01', 67),
-(4, 4, '2026-02-01', 50),
-(5, 5, '2026-02-02', 100),
-(6, 6, '2026-02-02', 0),
-(7, 7, '2026-02-03', 80),
-(8, 8, '2026-02-03', 60),
-(9, 9, '2026-02-03', 40),
-(10, 10, '2026-02-04', 90),
-(11, 11, '2026-02-05', 66),
-(12, 11, '2026-02-06', 33),
-(13, 12, '2026-02-05', 50),
-(14, 12, '2026-02-06', 100),
-(15, 13, '2026-02-06', 67),
-(16, 13, '2026-02-07', 34),
-(17, 14, '2026-02-06', 50),
-(18, 14, '2026-02-07', 50),
-(19, 15, '2026-02-07', 67),
-(20, 15, '2026-02-08', 33),
-(21, 16, '2026-02-07', 34),
-(22, 16, '2026-02-08', 67),
-(23, 17, '2026-02-08', 50),
-(24, 17, '2026-02-09', 50),
-(25, 18, '2026-02-08', 100),
-(26, 18, '2026-02-09', 50),
-(27, 19, '2026-02-09', 67),
-(28, 19, '2026-02-10', 34),
-(29, 20, '2026-02-09', 33),
-(30, 20, '2026-02-10', 66);
-
--- If DAILY_COMPLETION.daily_completion_id is an IDENTITY column, advance its sequence past dummy ids.
-SELECT setval(
-	pg_get_serial_sequence('trekr.daily_completion', 'daily_completion_id'),
-	(SELECT COALESCE(MAX(daily_completion_id), 0) FROM trekr.daily_completion)
-);
-
-INSERT INTO TASK_DAILY_COMPLETION (task_id, daily_completion_id) VALUES
-(1, 1),
-(2, 1),
-(3, 2),
-(6, 3),
-(7, 3),
-(9, 4),
-(11, 5),
-(12, 5),
-(13, 8),
-(14, 8),
-(15, 10),
-(24, 11),
-(25, 11),
-(27, 13),
-(28, 14),
-(41, 15),
-(42, 15),
-(44, 17),
-(45, 18),
-(33, 19),
-(34, 19),
-(51, 22),
-(52, 22),
-(39, 23),
-(40, 24),
-(53, 25),
-(54, 26),
-(55, 27),
-(56, 27),
-(57, 28),
-(58, 30);
-
-INSERT INTO INVESTOR_USERS (user_id) VALUES
-(1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12), (13), (14), (15);
-
-INSERT INTO ASSETS (asset_id, user_id, ticker_symbol, buy_price, buy_date, quantity) VALUES
-(1, 1, 'AAPL', 150, '2026-01-01', 1.5),
-(2, 1, 'TSLA', 700, '2026-01-10', 2),
-(3, 2, 'GOOGL', 2800, '2026-01-15', 1),
-(4, 3, 'MSFT', 320, '2026-01-20', 1),
-(5, 4, 'AMZN', 155, '2026-01-22', 1),
-(6, 5, 'NVDA', 610, '2026-01-25', 1),
-(7, 6, 'SPY', 480, '2026-01-28', 1),
-(8, 1, 'ETH', 2400, '2026-01-30', 1),
-(9, 7, 'KO', 58, '2026-02-02', 10),
-(10, 8, 'V', 245, '2026-02-03', 3),
-(11, 9, 'NFLX', 610, '2026-02-04', 1),
-(12, 10, 'DIS', 110, '2026-02-05', 4),
-(13, 11, 'AAPL', 155, '2026-02-06', 2),
-(14, 12, 'MSFT', 330, '2026-02-07', 1.2),
-(15, 13, 'TSLA', 720, '2026-02-08', 0.8),
-(16, 14, 'SPY', 485, '2026-02-09', 1.5),
-(17, 15, 'NVDA', 640, '2026-02-10', 0.9);
-
-SELECT setval(
-	pg_get_serial_sequence('trekr.assets', 'asset_id'),
-	(SELECT COALESCE(MAX(asset_id), 0) FROM trekr.assets)
-);
Index: -scripts/docker-init/01-init.sql
===================================================================
--- db-scripts/docker-init/01-init.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,5 +1,0 @@
--- Combined init: schema (DDL) then seed data (DML)
--- Postgres runs all *.sql files in /docker-entrypoint-initdb.d on first start.
-
-\i /docker-entrypoint-initdb.d/ddl.sql
-\i /docker-entrypoint-initdb.d/dml.sql
Index: -scripts/migrations/002_task_enhancements.sql
===================================================================
--- db-scripts/migrations/002_task_enhancements.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,17 +1,0 @@
--- Migration 002: Add description, due_date, priority, status to tasks
--- Replace is_finished boolean with status enum string
-
-SET search_path TO trekr;
-
-ALTER TABLE tasks ADD COLUMN IF NOT EXISTS description TEXT;
-ALTER TABLE tasks ADD COLUMN IF NOT EXISTS due_date DATE;
-ALTER TABLE tasks ADD COLUMN IF NOT EXISTS priority VARCHAR(10);
-ALTER TABLE tasks ADD COLUMN IF NOT EXISTS status VARCHAR(20);
-
--- Migrate existing data from is_finished to status
-UPDATE tasks SET status = CASE WHEN is_finished THEN 'FINISHED' ELSE 'NOT_STARTED' END WHERE status IS NULL;
-
-ALTER TABLE tasks ALTER COLUMN status SET NOT NULL;
-ALTER TABLE tasks ALTER COLUMN status SET DEFAULT 'NOT_STARTED';
-
-ALTER TABLE tasks DROP COLUMN IF EXISTS is_finished;
Index: -scripts/migrations/V001__expand_tasks_table.sql
===================================================================
--- db-scripts/migrations/V001__expand_tasks_table.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,44 +1,0 @@
--- Flyway Migration: Expand TASKS table with description, due_date, priority, and status enum
--- This migration adds new columns to support custom tracking tasks with enhanced details.
--- Daily discipline tasks will use NULL for these optional fields.
-
-SET search_path TO trekr;
-
--- Create ENUM type for task status
-CREATE TYPE task_status AS ENUM ('NOT_STARTED', 'IN_PROGRESS', 'FINISHED');
-
--- Add new columns to TASKS table
-ALTER TABLE trekr.tasks
-ADD COLUMN description TEXT,
-ADD COLUMN due_date DATE,
-ADD COLUMN priority VARCHAR(10) DEFAULT 'MEDIUM' CHECK (priority IN ('LOW', 'MEDIUM', 'HIGH')),
-ADD COLUMN status task_status DEFAULT 'NOT_STARTED';
-
--- For backwards compatibility, migrate is_finished to status
--- is_finished = true → status = FINISHED
--- is_finished = false → status = NOT_STARTED
-UPDATE trekr.tasks
-SET status = CASE
-    WHEN is_finished = true THEN 'FINISHED'::task_status
-    ELSE 'NOT_STARTED'::task_status
-END;
-
--- Drop the is_finished column (after migration)
-ALTER TABLE trekr.tasks
-DROP COLUMN is_finished;
-
--- Add index for filtering tasks by status and custom_tracking_id
-CREATE INDEX idx_tasks_custom_tracking_status
-ON trekr.tasks(custom_tracking_id, status)
-WHERE custom_tracking_id IS NOT NULL;
-
--- Add index for filtering by discipline_user_id and status (for daily completion computation)
-CREATE INDEX idx_tasks_discipline_status
-ON trekr.tasks(discipline_user_id, status)
-WHERE discipline_user_id IS NOT NULL;
-
--- Add index for due_date filtering (useful for reports)
-CREATE INDEX idx_tasks_due_date
-ON trekr.tasks(due_date)
-WHERE due_date IS NOT NULL;
-
Index: -scripts/p6-relational-algebra/p6_q1_annual_finance_budget_resilience_ra.txt
===================================================================
--- db-scripts/p6-relational-algebra/p6_q1_annual_finance_budget_resilience_ra.txt	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,42 +1,0 @@
-FB <- pi_{fu.user_id, u.username, u.email,
-          COALESCE(fu.spending_budget,0)->spending_budget,
-          COALESCE(fu.saving_budget,0)->saving_budget,
-          COALESCE(fu.investing_budget,0)->investing_budget,
-          COALESCE(fu.donation_budget,0)->donation_budget,
-          COALESCE(fu.credit,0)->credit}
-      (finance_users fu bowtie_{fu.user_id = u.user_id} users u)
-
-FBM <- FB x M
-IY <- sigma_{YEAR(i.date)=Y}(incomes i)
-MI0 <- FBM leftouterjoin_{FBM.user_id = i.user_id AND FBM.month_no = MONTH(i.date)} IY
-MI <- gamma_{user_id, month_no;
-             SUM(COALESCE(i.amount,0))->month_income}(MI0)
-
-MIR <- omega_{PARTITION BY user_id ORDER BY month_income DESC, month_no ASC;
-              DENSE_RANK()->best_month_rank,
-              DENSE_RANK(PARTITION BY user_id ORDER BY month_income ASC, month_no ASC)->worst_month_rank}(MI)
-
-AI <- gamma_{user_id;
-             SUM(month_income)->total_income,
-             AVG(month_income)->avg_monthly_income,
-             STDDEV_SAMP(month_income)->income_stddev,
-             MAX(month_income)->best_month_income,
-             MIN(month_income)->worst_month_income,
-             COUNT_IF(month_income>0)->active_income_months}(MI)
-
-BWM <- gamma_{user_id;
-              MAX_IF(month_no, best_month_rank=1)->best_month_no,
-              MAX_IF(month_no, worst_month_rank=1)->worst_month_no}(MIR)
-
-R0 <- FB bowtie_{FB.user_id=AI.user_id} AI bowtie_{FB.user_id=BWM.user_id} BWM
-R1 <- alpha_{(spending_budget+saving_budget+investing_budget+donation_budget)*12->planned_annual_budget,
-             total_income->actual_annual_income,
-             income_stddev/NULLIF(avg_monthly_income,0)->income_volatility_cv,
-             total_income-(spending_budget*12)->annual_free_cash_after_spending,
-             (spending_budget*12)/NULLIF(total_income,0)->spending_pressure_ratio,
-             credit/NULLIF(total_income,0)->leverage_ratio}(R0)
-R  <- omega_{ORDER BY annual_free_cash_after_spending DESC,
-                    spending_pressure_ratio ASC,
-                    user_id ASC;
-             DENSE_RANK()->finance_resilience_rank}(R1)
-
Index: -scripts/p6-relational-algebra/p6_q2_annual_training_consistency_workload_ra.txt
===================================================================
--- db-scripts/p6-relational-algebra/p6_q2_annual_training_consistency_workload_ra.txt	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,52 +1,0 @@
-TB <- pi_{tu.user_id, u.username, u.email, tu.gender, tu.age, tu.weight}
-      (training_users tu bowtie_{tu.user_id = u.user_id} users u)
-
-TBM <- TB x M
-TSY <- sigma_{YEAR(ts.date)=Y}(training_sessions ts)
-MS0 <- TBM leftouterjoin_{TBM.user_id = ts.training_user_id AND TBM.month_no = MONTH(ts.date)} TSY
-MS <- gamma_{user_id, month_no;
-             COUNT(ts.training_id)->sessions_count,
-             SUM(COALESCE(ts.duration,0))->total_duration_minutes,
-             SUM(COALESCE(ts.calories,0))->total_calories,
-             AVG(COALESCE(ts.duration,0))->avg_session_duration,
-             AVG(COALESCE(ts.calories,0))->avg_session_calories}(MS0)
-
-MR <- omega_{PARTITION BY user_id ORDER BY total_calories DESC, month_no ASC;
-             DENSE_RANK()->peak_calorie_month_rank,
-             DENSE_RANK(PARTITION BY user_id ORDER BY sessions_count DESC, month_no ASC)->peak_sessions_month_rank}(MS)
-
-AMS <- sigma_{sessions_count>0}(MS)
-AMS1 <- omega_{PARTITION BY user_id ORDER BY month_no;
-               ROW_NUMBER()->rn}(AMS)
-AMS2 <- alpha_{month_no - rn -> grp}(AMS1)
-LS0 <- gamma_{user_id, grp; COUNT(*)->streak_len}(AMS2)
-LS  <- gamma_{user_id; MAX(streak_len)->longest_active_month_streak}(LS0)
-
-AT <- gamma_{user_id;
-             SUM(sessions_count)->annual_sessions,
-             SUM(total_duration_minutes)->annual_duration_minutes,
-             SUM(total_calories)->annual_calories,
-             AVG(total_duration_minutes)->avg_monthly_duration,
-             AVG(total_calories)->avg_monthly_calories,
-             COUNT_IF(sessions_count>0)->active_months,
-             REGR_SLOPE(total_calories, month_no)->calories_trend_slope,
-             REGR_SLOPE(total_duration_minutes, month_no)->duration_trend_slope}(MS)
-
-PM <- gamma_{user_id;
-             MAX_IF(month_no, peak_calorie_month_rank=1)->peak_calorie_month_no,
-             MAX_IF(month_no, peak_sessions_month_rank=1)->peak_sessions_month_no}(MR)
-
-R0 <- TB bowtie_{TB.user_id=AT.user_id} AT
-         bowtie_{TB.user_id=PM.user_id} PM
-         leftouterjoin_{TB.user_id=LS.user_id} LS
-R1 <- alpha_{active_months/12.0->consistency_ratio,
-             COALESCE(longest_active_month_streak,0)->longest_active_month_streak_nz,
-             COALESCE(calories_trend_slope,0)->calories_trend_slope_nz,
-             COALESCE(duration_trend_slope,0)->duration_trend_slope_nz}(R0)
-R  <- omega_{ORDER BY annual_calories DESC,
-                    active_months DESC,
-                    longest_active_month_streak_nz DESC,
-                    user_id ASC;
-             DENSE_RANK()->training_annual_rank}(R1)
-
-
Index: -scripts/p6-relational-algebra/p6_q3_annual_discipline_adherence_streaks_ra.txt
===================================================================
--- db-scripts/p6-relational-algebra/p6_q3_annual_discipline_adherence_streaks_ra.txt	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,56 +1,0 @@
-DB <- pi_{du.user_id, u.username, u.email}
-      (discipline_users du bowtie_{du.user_id = u.user_id} users u)
-
-TC <- tasks t leftouterjoin_{t.custom_tracking_id = c.custom_tracking_id} custom_tracking_categories c
-TM0 <- alpha_{COALESCE(t.discipline_user_id, c.user_id)->owner_user_id}(TC)
-TM1 <- sigma_{t.discipline_user_id IS NOT NULL OR t.custom_tracking_id IS NOT NULL}(TM0)
-TM <- gamma_{owner_user_id;
-             COUNT(*)->total_tasks_defined,
-             COUNT_IF(t.custom_tracking_id IS NULL)->core_tasks,
-             COUNT_IF(t.custom_tracking_id IS NOT NULL)->custom_tasks,
-             COUNT_DISTINCT(COALESCE(t.custom_tracking_id,'core'))->task_category_span}(TM1)
-
-ADC0 <- sigma_{YEAR(dc.date)=Y}(daily_completion dc)
-ADC <- alpha_{COALESCE(dc.procent,0)->procent,
-              CASE(procent>=80,1,0)->strong_day}(ADC0)
-
-DCS <- gamma_{user_id;
-              COUNT(*)->tracked_days,
-              AVG(procent)->avg_completion_percent,
-              PERCENTILE_CONT_0_5(procent)->median_completion_percent,
-              COUNT_IF(procent=100)->perfect_days,
-              COUNT_IF(procent>=80)->strong_days,
-              STDDEV_SAMP(procent)->completion_variability}(ADC)
-
-SDS0 <- sigma_{strong_day=1}(ADC)
-SDS1 <- omega_{PARTITION BY user_id ORDER BY date; ROW_NUMBER()->rn}(SDS0)
-SDS2 <- alpha_{date - rn -> grp}(SDS1)
-LSS0 <- gamma_{user_id, grp; COUNT(*)->streak_len}(SDS2)
-LSS  <- gamma_{user_id; MAX(streak_len)->longest_strong_day_streak}(LSS0)
-
-ATE0 <- ADC0 leftouterjoin_{ADC0.daily_completion_id = tdc.daily_completion_id} task_daily_completion tdc
-ATE  <- gamma_{ADC0.user_id; COUNT(tdc.task_id)->completed_task_events}(ATE0)
-
-R0 <- DB
-      leftouterjoin_{DB.user_id = TM.owner_user_id} TM
-      leftouterjoin_{DB.user_id = DCS.user_id} DCS
-      leftouterjoin_{DB.user_id = ATE.user_id} ATE
-      leftouterjoin_{DB.user_id = LSS.user_id} LSS
-R1 <- alpha_{COALESCE(total_tasks_defined,0)->total_tasks_defined_nz,
-             COALESCE(core_tasks,0)->core_tasks_nz,
-             COALESCE(custom_tasks,0)->custom_tasks_nz,
-             COALESCE(task_category_span,0)->task_category_span_nz,
-             COALESCE(tracked_days,0)->tracked_days_nz,
-             COALESCE(avg_completion_percent,0)->avg_completion_percent_nz,
-             COALESCE(median_completion_percent,0)->median_completion_percent_nz,
-             COALESCE(perfect_days,0)->perfect_days_nz,
-             COALESCE(strong_days,0)->strong_days_nz,
-             COALESCE(completion_variability,0)->completion_variability_nz,
-             COALESCE(completed_task_events,0)->completed_task_events_nz,
-             COALESCE(longest_strong_day_streak,0)->longest_strong_day_streak_nz,
-             COALESCE(strong_days/NULLIF(tracked_days,0),0)->strong_day_ratio,
-             (COALESCE(avg_completion_percent,0)*0.45 +
-              COALESCE(longest_strong_day_streak,0)*2.00 +
-              COALESCE(completed_task_events,0)*0.35)->discipline_composite_score}(R0)
-R  <- omega_{ORDER BY discipline_composite_score DESC, user_id ASC;
-             DENSE_RANK()->discipline_annual_rank}(R1)
Index: -scripts/p6-relational-algebra/p6_q4_annual_investing_diversification_concentration_ra.txt
===================================================================
--- db-scripts/p6-relational-algebra/p6_q4_annual_investing_diversification_concentration_ra.txt	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,64 +1,0 @@
-
-IB <- pi_{iu.user_id, u.username, u.email}
-      (investor_users iu bowtie_{iu.user_id = u.user_id} users u)
-
-AAL <- pi_{a.user_id, a.ticker_symbol,
-           COALESCE(a.quantity,0)->quantity,
-           COALESCE(a.buy_price,0)->buy_price,
-           COALESCE(a.quantity,0)*COALESCE(a.buy_price,0)->invested_amount,
-           a.buy_date}
-       (sigma_{YEAR(a.buy_date)=Y}(assets a))
-
-TR <- gamma_{user_id, ticker_symbol;
-             SUM(quantity)->total_quantity,
-             SUM(invested_amount)->total_invested_amount,
-             COUNT(*)->lot_count,
-             MIN(buy_date)->first_buy_date,
-             MAX(buy_date)->last_buy_date}(AAL)
-
-PT <- gamma_{user_id;
-             SUM(total_invested_amount)->annual_total_invested,
-             SUM(lot_count)->annual_lot_count,
-             COUNT(*)->distinct_tickers}(TR)
-
-W0 <- TR bowtie_{TR.user_id = PT.user_id} PT
-W1 <- alpha_{total_invested_amount/NULLIF(annual_total_invested,0)->position_weight}(W0)
-W  <- omega_{PARTITION BY user_id ORDER BY total_invested_amount DESC, ticker_symbol ASC;
-             DENSE_RANK()->position_rank}(W1)
-
-C <- gamma_{user_id;
-            SUM(position_weight*position_weight)->hhi_concentration,
-            MAX(position_weight)->top_position_weight,
-            MAX_IF(ticker_symbol, position_rank=1)->top_ticker}(W)
-
-IBM <- IB x M
-AY  <- sigma_{YEAR(a.buy_date)=Y}(assets a)
-MI0 <- IBM leftouterjoin_{IBM.user_id=a.user_id AND IBM.month_no=MONTH(a.buy_date)} AY
-MI  <- gamma_{user_id, month_no;
-              SUM(COALESCE(a.quantity,0)*COALESCE(a.buy_price,0))->monthly_invested_amount}(MI0)
-MS  <- gamma_{user_id;
-              AVG(monthly_invested_amount)->avg_monthly_contribution,
-              STDDEV_SAMP(monthly_invested_amount)->contribution_stddev,
-              COUNT_IF(monthly_invested_amount>0)->active_investing_months}(MI)
-
-R0 <- IB
-      leftouterjoin_{IB.user_id=PT.user_id} PT
-      leftouterjoin_{IB.user_id=C.user_id} C
-      leftouterjoin_{IB.user_id=MS.user_id} MS
-R1 <- alpha_{COALESCE(annual_total_invested,0)->annual_total_invested_nz,
-             COALESCE(annual_lot_count,0)->annual_lot_count_nz,
-             COALESCE(distinct_tickers,0)->distinct_tickers_nz,
-             COALESCE(avg_monthly_contribution,0)->avg_monthly_contribution_nz,
-             COALESCE(active_investing_months,0)->active_investing_months_nz,
-             COALESCE(active_investing_months,0)/12.0->activity_ratio,
-             COALESCE(hhi_concentration,0)->hhi_concentration_nz,
-             1-COALESCE(hhi_concentration,1)->diversification_index,
-             COALESCE(top_position_weight,0)->top_position_weight_nz,
-             COALESCE(contribution_stddev/NULLIF(avg_monthly_contribution,0),0)->contribution_volatility_cv}(R0)
-R  <- omega_{ORDER BY diversification_index DESC,
-                    annual_total_invested_nz DESC,
-                    active_investing_months_nz DESC,
-                    user_id ASC;
-             DENSE_RANK()->investing_annual_rank}(R1)
-
-
Index: -scripts/p6_q1_annual_finance_budget_resilience.sql
===================================================================
--- db-scripts/p6_q1_annual_finance_budget_resilience.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,102 +1,0 @@
-SET search_path TO trekr;
-
--- P6 Q1 (Annual): Finance budget resilience and income stability leaderboard.
--- Change report_year in params CTE when needed.
-WITH params AS (
-    SELECT 2026::int AS report_year
-),
-months AS (
-    SELECT generate_series(1, 12) AS month_no
-),
-finance_base AS (
-    SELECT
-        fu.user_id,
-        u.username,
-        u.email,
-        COALESCE(fu.spending_budget, 0) AS spending_budget,
-        COALESCE(fu.saving_budget, 0) AS saving_budget,
-        COALESCE(fu.investing_budget, 0) AS investing_budget,
-        COALESCE(fu.donation_budget, 0) AS donation_budget,
-        COALESCE(fu.credit, 0) AS credit
-    FROM finance_users fu
-    JOIN users u ON u.user_id = fu.user_id
-),
-monthly_income AS (
-    SELECT
-        fb.user_id,
-        m.month_no,
-        COALESCE(SUM(i.amount), 0) AS month_income
-    FROM finance_base fb
-    CROSS JOIN months m
-    LEFT JOIN incomes i
-        ON i.user_id = fb.user_id
-       AND EXTRACT(YEAR FROM i.date)::int = (SELECT report_year FROM params)
-       AND EXTRACT(MONTH FROM i.date)::int = m.month_no
-    GROUP BY fb.user_id, m.month_no
-),
-monthly_income_ranked AS (
-    SELECT
-        mi.*,
-        DENSE_RANK() OVER (PARTITION BY mi.user_id ORDER BY mi.month_income DESC, mi.month_no ASC) AS best_month_rank,
-        DENSE_RANK() OVER (PARTITION BY mi.user_id ORDER BY mi.month_income ASC, mi.month_no ASC) AS worst_month_rank
-    FROM monthly_income mi
-),
-annual_income AS (
-    SELECT
-        user_id,
-        SUM(month_income) AS total_income,
-        AVG(month_income) AS avg_monthly_income,
-        STDDEV_SAMP(month_income) AS income_stddev,
-        MAX(month_income) AS best_month_income,
-        MIN(month_income) AS worst_month_income,
-        COUNT(*) FILTER (WHERE month_income > 0) AS active_income_months
-    FROM monthly_income
-    GROUP BY user_id
-),
-best_worst_months AS (
-    SELECT
-        user_id,
-        MAX(month_no) FILTER (WHERE best_month_rank = 1) AS best_month_no,
-        MAX(month_no) FILTER (WHERE worst_month_rank = 1) AS worst_month_no
-    FROM monthly_income_ranked
-    GROUP BY user_id
-)
-SELECT
-    fb.user_id,
-    fb.username,
-    fb.email,
-    (fb.spending_budget + fb.saving_budget + fb.investing_budget + fb.donation_budget) * 12 AS planned_annual_budget,
-    ai.total_income AS actual_annual_income,
-    ai.avg_monthly_income,
-    ai.active_income_months,
-    ai.best_month_income,
-    ai.worst_month_income,
-    bwm.best_month_no,
-    bwm.worst_month_no,
-    ROUND(
-        (ai.income_stddev / NULLIF(ai.avg_monthly_income, 0))::numeric,
-        4
-    ) AS income_volatility_cv,
-    ROUND(
-        (ai.total_income - (fb.spending_budget * 12))::numeric,
-        2
-    ) AS annual_free_cash_after_spending,
-    ROUND(
-        ((fb.spending_budget * 12) / NULLIF(ai.total_income, 0))::numeric,
-        4
-    ) AS spending_pressure_ratio,
-    ROUND(
-        (fb.credit / NULLIF(ai.total_income, 0))::numeric,
-        4
-    ) AS leverage_ratio,
-    DENSE_RANK() OVER (
-        ORDER BY
-            (ai.total_income - (fb.spending_budget * 12)) DESC,
-            ((fb.spending_budget * 12) / NULLIF(ai.total_income, 0)) ASC,
-            fb.user_id ASC
-    ) AS finance_resilience_rank
-FROM finance_base fb
-JOIN annual_income ai ON ai.user_id = fb.user_id
-JOIN best_worst_months bwm ON bwm.user_id = fb.user_id
-ORDER BY finance_resilience_rank, fb.user_id;
-
Index: -scripts/p6_q2_annual_training_consistency_workload.sql
===================================================================
--- db-scripts/p6_q2_annual_training_consistency_workload.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,116 +1,0 @@
-SET search_path TO trekr;
-
--- P6 Q2 (Annual): Training consistency, workload trend, and peak period analysis.
--- Change report_year in params CTE when needed.
-WITH params AS (
-    SELECT 2026::int AS report_year
-),
-months AS (
-    SELECT generate_series(1, 12) AS month_no
-),
-training_base AS (
-    SELECT
-        tu.user_id,
-        u.username,
-        u.email,
-        tu.gender,
-        tu.age,
-        tu.weight
-    FROM training_users tu
-    JOIN users u ON u.user_id = tu.user_id
-),
-monthly_sessions AS (
-    SELECT
-        tb.user_id,
-        m.month_no,
-        COALESCE(COUNT(ts.training_id), 0) AS sessions_count,
-        COALESCE(SUM(ts.duration), 0) AS total_duration_minutes,
-        COALESCE(SUM(ts.calories), 0) AS total_calories,
-        COALESCE(AVG(ts.duration), 0) AS avg_session_duration,
-        COALESCE(AVG(ts.calories), 0) AS avg_session_calories
-    FROM training_base tb
-    CROSS JOIN months m
-    LEFT JOIN training_sessions ts
-        ON ts.training_user_id = tb.user_id
-       AND EXTRACT(YEAR FROM ts.date)::int = (SELECT report_year FROM params)
-       AND EXTRACT(MONTH FROM ts.date)::int = m.month_no
-    GROUP BY tb.user_id, m.month_no
-),
-monthly_ranked AS (
-    SELECT
-        ms.*,
-        DENSE_RANK() OVER (PARTITION BY ms.user_id ORDER BY ms.total_calories DESC, ms.month_no ASC) AS peak_calorie_month_rank,
-        DENSE_RANK() OVER (PARTITION BY ms.user_id ORDER BY ms.sessions_count DESC, ms.month_no ASC) AS peak_sessions_month_rank
-    FROM monthly_sessions ms
-),
-active_month_streaks AS (
-    SELECT
-        user_id,
-        month_no,
-        month_no - ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY month_no) AS grp
-    FROM monthly_sessions
-    WHERE sessions_count > 0
-),
-longest_streak AS (
-    SELECT
-        user_id,
-        MAX(streak_len) AS longest_active_month_streak
-    FROM (
-        SELECT user_id, grp, COUNT(*) AS streak_len
-        FROM active_month_streaks
-        GROUP BY user_id, grp
-    ) s
-    GROUP BY user_id
-),
-annual_training AS (
-    SELECT
-        user_id,
-        SUM(sessions_count) AS annual_sessions,
-        SUM(total_duration_minutes) AS annual_duration_minutes,
-        SUM(total_calories) AS annual_calories,
-        AVG(total_duration_minutes) AS avg_monthly_duration,
-        AVG(total_calories) AS avg_monthly_calories,
-        COUNT(*) FILTER (WHERE sessions_count > 0) AS active_months,
-        REGR_SLOPE(total_calories::numeric, month_no::numeric) AS calories_trend_slope,
-        REGR_SLOPE(total_duration_minutes::numeric, month_no::numeric) AS duration_trend_slope
-    FROM monthly_sessions
-    GROUP BY user_id
-),
-peak_months AS (
-    SELECT
-        user_id,
-        MAX(month_no) FILTER (WHERE peak_calorie_month_rank = 1) AS peak_calorie_month_no,
-        MAX(month_no) FILTER (WHERE peak_sessions_month_rank = 1) AS peak_sessions_month_no
-    FROM monthly_ranked
-    GROUP BY user_id
-)
-SELECT
-    tb.user_id,
-    tb.username,
-    tb.email,
-    tb.gender,
-    tb.age,
-    tb.weight,
-    at.annual_sessions,
-    ROUND(at.annual_duration_minutes::numeric, 2) AS annual_duration_minutes,
-    ROUND(at.annual_calories::numeric, 2) AS annual_calories,
-    at.active_months,
-    ROUND((at.active_months / 12.0)::numeric, 4) AS consistency_ratio,
-    COALESCE(ls.longest_active_month_streak, 0) AS longest_active_month_streak,
-    pm.peak_calorie_month_no,
-    pm.peak_sessions_month_no,
-    ROUND(COALESCE(at.calories_trend_slope, 0)::numeric, 4) AS calories_trend_slope,
-    ROUND(COALESCE(at.duration_trend_slope, 0)::numeric, 4) AS duration_trend_slope,
-    DENSE_RANK() OVER (
-        ORDER BY
-            at.annual_calories DESC,
-            at.active_months DESC,
-            COALESCE(ls.longest_active_month_streak, 0) DESC,
-            tb.user_id ASC
-    ) AS training_annual_rank
-FROM training_base tb
-JOIN annual_training at ON at.user_id = tb.user_id
-JOIN peak_months pm ON pm.user_id = tb.user_id
-LEFT JOIN longest_streak ls ON ls.user_id = tb.user_id
-ORDER BY training_annual_rank, tb.user_id;
-
Index: -scripts/p6_q3_annual_discipline_adherence_streaks.sql
===================================================================
--- db-scripts/p6_q3_annual_discipline_adherence_streaks.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,124 +1,0 @@
-SET search_path TO trekr;
-
--- P6 Q3 (Annual): Discipline adherence, completion quality, and streak behavior.
--- Change report_year in params CTE when needed.
-WITH params AS (
-    SELECT 2026::int AS report_year
-),
-discipline_base AS (
-    SELECT
-        du.user_id,
-        u.username,
-        u.email
-    FROM discipline_users du
-    JOIN users u ON u.user_id = du.user_id
-),
-task_mix AS (
-    SELECT
-        COALESCE(t.discipline_user_id, c.user_id) AS user_id,
-        COUNT(*) AS total_tasks_defined,
-        COUNT(*) FILTER (WHERE t.custom_tracking_id IS NULL) AS core_tasks,
-        COUNT(*) FILTER (WHERE t.custom_tracking_id IS NOT NULL) AS custom_tasks,
-        COUNT(DISTINCT COALESCE(t.custom_tracking_id::text, 'core')) AS task_category_span
-    FROM tasks t
-    LEFT JOIN custom_tracking_categories c
-        ON c.custom_tracking_id = t.custom_tracking_id
-    WHERE t.discipline_user_id IS NOT NULL
-       OR t.custom_tracking_id IS NOT NULL
-    GROUP BY COALESCE(t.discipline_user_id, c.user_id)
-),
-annual_daily_completion AS (
-    SELECT
-        dc.user_id,
-        dc.date,
-        COALESCE(dc.procent, 0) AS procent,
-        CASE WHEN COALESCE(dc.procent, 0) >= 80 THEN 1 ELSE 0 END AS strong_day
-    FROM daily_completion dc
-    WHERE EXTRACT(YEAR FROM dc.date)::int = (SELECT report_year FROM params)
-),
-daily_completion_stats AS (
-    SELECT
-        adc.user_id,
-        COUNT(*) AS tracked_days,
-        AVG(adc.procent) AS avg_completion_percent,
-        PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY adc.procent) AS median_completion_percent,
-        COUNT(*) FILTER (WHERE adc.procent = 100) AS perfect_days,
-        COUNT(*) FILTER (WHERE adc.procent >= 80) AS strong_days,
-        STDDEV_SAMP(adc.procent) AS completion_variability
-    FROM annual_daily_completion adc
-    GROUP BY adc.user_id
-),
-strong_day_streaks AS (
-    SELECT
-        user_id,
-        date,
-        date - (ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY date))::int AS grp
-    FROM annual_daily_completion
-    WHERE strong_day = 1
-),
-longest_strong_streak AS (
-    SELECT
-        user_id,
-        MAX(streak_len) AS longest_strong_day_streak
-    FROM (
-        SELECT user_id, grp, COUNT(*) AS streak_len
-        FROM strong_day_streaks
-        GROUP BY user_id, grp
-    ) s
-    GROUP BY user_id
-),
-annual_task_execution AS (
-    SELECT
-        dc.user_id,
-        COUNT(tdc.task_id) AS completed_task_events
-    FROM daily_completion dc
-    LEFT JOIN task_daily_completion tdc
-        ON tdc.daily_completion_id = dc.daily_completion_id
-    WHERE EXTRACT(YEAR FROM dc.date)::int = (SELECT report_year FROM params)
-    GROUP BY dc.user_id
-)
-SELECT
-    db.user_id,
-    db.username,
-    db.email,
-    COALESCE(tm.total_tasks_defined, 0) AS total_tasks_defined,
-    COALESCE(tm.core_tasks, 0) AS core_tasks,
-    COALESCE(tm.custom_tasks, 0) AS custom_tasks,
-    COALESCE(tm.task_category_span, 0) AS task_category_span,
-    COALESCE(dcs.tracked_days, 0) AS tracked_days,
-    ROUND(COALESCE(dcs.avg_completion_percent, 0)::numeric, 2) AS avg_completion_percent,
-    ROUND(COALESCE(dcs.median_completion_percent, 0)::numeric, 2) AS median_completion_percent,
-    COALESCE(dcs.perfect_days, 0) AS perfect_days,
-    COALESCE(dcs.strong_days, 0) AS strong_days,
-    ROUND(COALESCE(dcs.completion_variability, 0)::numeric, 4) AS completion_variability,
-    COALESCE(ate.completed_task_events, 0) AS completed_task_events,
-    COALESCE(lss.longest_strong_day_streak, 0) AS longest_strong_day_streak,
-    ROUND(
-        COALESCE((COALESCE(dcs.strong_days, 0) / NULLIF(COALESCE(dcs.tracked_days, 0), 0)::numeric), 0),
-        4
-    ) AS strong_day_ratio,
-    ROUND(
-        (
-            COALESCE(dcs.avg_completion_percent, 0) * 0.45
-            + COALESCE(lss.longest_strong_day_streak, 0) * 2.00
-            + COALESCE(ate.completed_task_events, 0) * 0.35
-        )::numeric,
-        2
-    ) AS discipline_composite_score,
-    DENSE_RANK() OVER (
-        ORDER BY
-            (
-                COALESCE(dcs.avg_completion_percent, 0) * 0.45
-                + COALESCE(lss.longest_strong_day_streak, 0) * 2.00
-                + COALESCE(ate.completed_task_events, 0) * 0.35
-            ) DESC,
-            db.user_id ASC
-    ) AS discipline_annual_rank
-FROM discipline_base db
-LEFT JOIN task_mix tm ON tm.user_id = db.user_id
-LEFT JOIN daily_completion_stats dcs ON dcs.user_id = db.user_id
-LEFT JOIN annual_task_execution ate ON ate.user_id = db.user_id
-LEFT JOIN longest_strong_streak lss ON lss.user_id = db.user_id
-ORDER BY discipline_annual_rank, db.user_id;
-
-
Index: -scripts/p6_q4_annual_investing_diversification_concentration.sql
===================================================================
--- db-scripts/p6_q4_annual_investing_diversification_concentration.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,123 +1,0 @@
-SET search_path TO trekr;
-
--- P6 Q4 (Annual): Investing diversification, concentration risk, and contribution pacing.
--- Change report_year in params CTE when needed.
-WITH params AS (
-    SELECT 2026::int AS report_year
-),
-months AS (
-    SELECT generate_series(1, 12) AS month_no
-),
-investor_base AS (
-    SELECT
-        iu.user_id,
-        u.username,
-        u.email
-    FROM investor_users iu
-    JOIN users u ON u.user_id = iu.user_id
-),
-annual_asset_lots AS (
-    SELECT
-        a.user_id,
-        a.ticker_symbol,
-        COALESCE(a.quantity, 0) AS quantity,
-        COALESCE(a.buy_price, 0) AS buy_price,
-        COALESCE(a.quantity, 0) * COALESCE(a.buy_price, 0) AS invested_amount,
-        a.buy_date
-    FROM assets a
-    WHERE EXTRACT(YEAR FROM a.buy_date)::int = (SELECT report_year FROM params)
-),
-ticker_rollup AS (
-    SELECT
-        aal.user_id,
-        aal.ticker_symbol,
-        SUM(aal.quantity) AS total_quantity,
-        SUM(aal.invested_amount) AS total_invested_amount,
-        COUNT(*) AS lot_count,
-        MIN(aal.buy_date) AS first_buy_date,
-        MAX(aal.buy_date) AS last_buy_date
-    FROM annual_asset_lots aal
-    GROUP BY aal.user_id, aal.ticker_symbol
-),
-portfolio_totals AS (
-    SELECT
-        user_id,
-        SUM(total_invested_amount) AS annual_total_invested,
-        SUM(lot_count) AS annual_lot_count,
-        COUNT(*) AS distinct_tickers
-    FROM ticker_rollup
-    GROUP BY user_id
-),
-weights AS (
-    SELECT
-        tr.user_id,
-        tr.ticker_symbol,
-        tr.total_invested_amount,
-        pt.annual_total_invested,
-        (tr.total_invested_amount / NULLIF(pt.annual_total_invested, 0)) AS position_weight,
-        DENSE_RANK() OVER (
-            PARTITION BY tr.user_id
-            ORDER BY tr.total_invested_amount DESC, tr.ticker_symbol ASC
-        ) AS position_rank
-    FROM ticker_rollup tr
-    JOIN portfolio_totals pt ON pt.user_id = tr.user_id
-),
-concentration AS (
-    SELECT
-        user_id,
-        SUM(position_weight * position_weight) AS hhi_concentration,
-        MAX(position_weight) AS top_position_weight,
-        MAX(ticker_symbol) FILTER (WHERE position_rank = 1) AS top_ticker
-    FROM weights
-    GROUP BY user_id
-),
-monthly_investment AS (
-    SELECT
-        ib.user_id,
-        m.month_no,
-        COALESCE(SUM(a.quantity * a.buy_price), 0) AS monthly_invested_amount
-    FROM investor_base ib
-    CROSS JOIN months m
-    LEFT JOIN assets a
-        ON a.user_id = ib.user_id
-       AND EXTRACT(YEAR FROM a.buy_date)::int = (SELECT report_year FROM params)
-       AND EXTRACT(MONTH FROM a.buy_date)::int = m.month_no
-    GROUP BY ib.user_id, m.month_no
-),
-monthly_investment_stats AS (
-    SELECT
-        user_id,
-        AVG(monthly_invested_amount) AS avg_monthly_contribution,
-        STDDEV_SAMP(monthly_invested_amount) AS contribution_stddev,
-        COUNT(*) FILTER (WHERE monthly_invested_amount > 0) AS active_investing_months
-    FROM monthly_investment
-    GROUP BY user_id
-)
-SELECT
-    ib.user_id,
-    ib.username,
-    ib.email,
-    COALESCE(pt.annual_total_invested, 0) AS annual_total_invested,
-    COALESCE(pt.annual_lot_count, 0) AS annual_lot_count,
-    COALESCE(pt.distinct_tickers, 0) AS distinct_tickers,
-    ROUND(COALESCE(ms.avg_monthly_contribution, 0)::numeric, 2) AS avg_monthly_contribution,
-    COALESCE(ms.active_investing_months, 0) AS active_investing_months,
-    ROUND((COALESCE(ms.active_investing_months, 0) / 12.0)::numeric, 4) AS activity_ratio,
-    ROUND(COALESCE(c.hhi_concentration, 0)::numeric, 4) AS hhi_concentration,
-    ROUND((1 - COALESCE(c.hhi_concentration, 1))::numeric, 4) AS diversification_index,
-    ROUND(COALESCE(c.top_position_weight, 0)::numeric, 4) AS top_position_weight,
-    c.top_ticker,
-    ROUND((COALESCE(ms.contribution_stddev, 0) / NULLIF(ms.avg_monthly_contribution, 0))::numeric, 4) AS contribution_volatility_cv,
-    DENSE_RANK() OVER (
-        ORDER BY
-            (1 - COALESCE(c.hhi_concentration, 1)) DESC,
-            COALESCE(pt.annual_total_invested, 0) DESC,
-            COALESCE(ms.active_investing_months, 0) DESC,
-            ib.user_id ASC
-    ) AS investing_annual_rank
-FROM investor_base ib
-LEFT JOIN portfolio_totals pt ON pt.user_id = ib.user_id
-LEFT JOIN concentration c ON c.user_id = ib.user_id
-LEFT JOIN monthly_investment_stats ms ON ms.user_id = ib.user_id
-ORDER BY investing_annual_rank, ib.user_id;
-
Index: -scripts/triggers/compute_daily_completion.sql
===================================================================
--- db-scripts/triggers/compute_daily_completion.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,84 +1,0 @@
--- Compute daily completion for a single user and date entirely in the DB
--- Inserts a daily_completions row (if not exists), links finished tasks into task_daily_completions,
--- and resets tasks.finished = false for that user.
--- Usage: SELECT trekr.fn_compute_daily_completion(user_id := 123, day := DATE '2026-05-06');
-
-CREATE OR REPLACE FUNCTION trekr.fn_compute_daily_completion(user_id bigint, day date)
-RETURNS TABLE(created boolean, daily_completion_id bigint, procent numeric)
-LANGUAGE plpgsql
-AS $$
-DECLARE
-    total_count bigint;
-    finished_count bigint;
-    pct numeric;
-    dc_id bigint;
-    user_rec record;
-    finished_tasks RECORD;
-BEGIN
-    IF user_id IS NULL THEN
-        RAISE EXCEPTION 'user_id is required';
-    END IF;
-    IF day IS NULL THEN
-        RAISE EXCEPTION 'day is required';
-    END IF;
-    IF day > current_date THEN
-        RAISE EXCEPTION 'date cannot be in the future';
-    END IF;
-
-    -- ensure user tracking exists: rely on discipline_users table existence
-    IF NOT EXISTS (SELECT 1 FROM trekr.discipline_users du WHERE du.user_id = user_id) THEN
-        RAISE EXCEPTION 'Discipline tracking is not enabled for this user';
-    END IF;
-
-    -- if already computed for that user+date, return existing
-    SELECT dc.daily_completion_id, dc.procent INTO dc_id, pct
-    FROM trekr.daily_completions dc
-    WHERE dc.user_id = user_id AND dc.date = day
-    LIMIT 1;
-
-    IF dc_id IS NOT NULL THEN
-        RETURN QUERY SELECT false, dc_id, pct;
-        RETURN;
-    END IF;
-
-    SELECT COUNT(*) INTO total_count FROM trekr.tasks t WHERE t.discipline_user_id = (
-        SELECT du.discipline_user_id FROM trekr.discipline_users du WHERE du.user_id = user_id
-    );
-
-    SELECT COUNT(*) INTO finished_count FROM trekr.tasks t WHERE t.discipline_user_id = (
-        SELECT du.discipline_user_id FROM trekr.discipline_users du WHERE du.user_id = user_id
-    ) AND t.finished = true;
-
-    IF total_count <= 0 THEN
-        pct := 0;
-    ELSE
-        pct := round((finished_count::numeric * 100) / total_count::numeric, 2);
-    END IF;
-
-    -- insert daily completion
-    INSERT INTO trekr.daily_completions (user_id, date, procent)
-    VALUES (user_id, day, pct)
-    RETURNING daily_completion_id INTO dc_id;
-
-    -- link finished tasks
-    FOR finished_tasks IN
-        SELECT t.task_id FROM trekr.tasks t
-        WHERE t.discipline_user_id = (
-            SELECT du.discipline_user_id FROM trekr.discipline_users du WHERE du.user_id = user_id
-        ) AND t.finished = true
-    LOOP
-        INSERT INTO trekr.task_daily_completions (task_id, daily_completion_id)
-        VALUES (finished_tasks.task_id, dc_id)
-        ON CONFLICT DO NOTHING;
-    END LOOP;
-
-    -- reset all tasks for user
-    UPDATE trekr.tasks t SET finished = false
-    WHERE t.discipline_user_id = (
-        SELECT du.discipline_user_id FROM trekr.discipline_users du WHERE du.user_id = user_id
-    );
-
-    RETURN QUERY SELECT true, dc_id, pct;
-END;
-$$;
-
Index: -scripts/triggers/compute_daily_completion_all.sql
===================================================================
--- db-scripts/triggers/compute_daily_completion_all.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,31 +1,0 @@
--- Compute daily completion for all discipline users for a given date
--- Usage: SELECT trekr.fn_compute_daily_completion_for_all(day := DATE '2026-05-06');
-
-CREATE OR REPLACE FUNCTION trekr.fn_compute_daily_completion_for_all(day date)
-RETURNS void
-LANGUAGE plpgsql
-AS $$
-DECLARE
-    u RECORD;
-BEGIN
-    IF day IS NULL THEN
-        RAISE EXCEPTION 'day is required';
-    END IF;
-
-    FOR u IN SELECT user_id FROM trekr.discipline_users LOOP
-        BEGIN
-            PERFORM trekr.fn_compute_daily_completion(u.user_id, day);
-        EXCEPTION WHEN OTHERS THEN
-            -- log and continue (requires a logging table or use RAISE NOTICE)
-            RAISE NOTICE 'compute_daily_completion failed for user %: %', u.user_id, SQLERRM;
-        END;
-    END LOOP;
-END;
-$$;
-
--- Optionally create a pg_cron job to run nightly (requires pg_cron extension)
--- Example (commented):
--- CREATE EXTENSION IF NOT EXISTS pg_cron;
--- SELECT cron.schedule('compute_daily_completions_every_day', '59 23 * * *',
---     $$SELECT trekr.fn_compute_daily_completion_for_all(current_date - INTERVAL '1 day')$$);
-
Index: -scripts/triggers/finance_validate_trigger.sql
===================================================================
--- db-scripts/triggers/finance_validate_trigger.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,48 +1,0 @@
--- Validate finance percentages on insert/update
--- Ensures the five budget fields sum to ~100 (tolerance 0.01) and each is between 0 and 100
--- Schema: trekr
-
-CREATE OR REPLACE FUNCTION trekr.fn_validate_finance_percentages()
-RETURNS trigger
-LANGUAGE plpgsql
-AS $$
-DECLARE
-    s NUMERIC;
-    eps CONSTANT NUMERIC := 0.01; -- allow small rounding differences
-    vals NUMERIC[] := ARRAY[NEW.spending_budget, NEW.saving_budget, NEW.investing_budget, NEW.donation_budget, NEW.credit];
-    v NUMERIC;
-BEGIN
-    -- Null checks: all five values must be provided (business rule)
-    FOREACH v IN ARRAY vals LOOP
-        IF v IS NULL THEN
-            RAISE EXCEPTION 'All 5 finance percentage values are required';
-        END IF;
-        IF v < 0 OR v > 100 THEN
-            RAISE EXCEPTION 'Finance percentage values must be between 0 and 100';
-        END IF;
-    END LOOP;
-
-    s := (NEW.spending_budget + NEW.saving_budget + NEW.investing_budget + NEW.donation_budget + NEW.credit)::numeric;
-    IF abs(s - 100) > eps THEN
-        RAISE EXCEPTION 'Finance percentages must sum to 100 (got: %)', s;
-    END IF;
-
-    RETURN NEW;
-END;
-$$;
-
--- Trigger on finance_users table
-DO $$
-BEGIN
-    IF NOT EXISTS (
-        SELECT 1 FROM pg_trigger t
-        JOIN pg_class c ON t.tgrelid = c.oid
-        WHERE t.tgname = 'trg_validate_finance_percentages' AND c.relname = 'finance_users'
-    ) THEN
-        CREATE TRIGGER trg_validate_finance_percentages
-        BEFORE INSERT OR UPDATE ON trekr.finance_users
-        FOR EACH ROW
-        EXECUTE FUNCTION trekr.fn_validate_finance_percentages();
-    END IF;
-END$$;
-
Index: -scripts/triggers/uniqueness_and_training_checks.sql
===================================================================
--- db-scripts/triggers/uniqueness_and_training_checks.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,36 +1,0 @@
--- Add useful DB constraints and checks
-
--- Unique index: ensure a user has at most one daily intake per date
-DO $$
-BEGIN
-    IF NOT EXISTS (
-        SELECT 1 FROM pg_indexes WHERE schemaname = 'trekr' AND tablename = 'daily_intakes' AND indexname = 'uq_daily_intake_user_date'
-    ) THEN
-        CREATE UNIQUE INDEX uq_daily_intake_user_date ON trekr.daily_intakes (weight_user_id, date);
-    END IF;
-END$$;
-
--- Prevent inserting training sessions with future date
-CREATE OR REPLACE FUNCTION trekr.fn_check_training_date()
-RETURNS trigger LANGUAGE plpgsql AS $$
-BEGIN
-    IF NEW.date > current_date THEN
-        RAISE EXCEPTION 'Training session date cannot be in the future: %', NEW.date;
-    END IF;
-    RETURN NEW;
-END$$;
-
-DO $$
-BEGIN
-    IF NOT EXISTS (
-        SELECT 1 FROM pg_trigger t
-        JOIN pg_class c ON t.tgrelid = c.oid
-        WHERE t.tgname = 'trg_check_training_date' AND c.relname = 'training_sessions'
-    ) THEN
-        CREATE TRIGGER trg_check_training_date
-        BEFORE INSERT OR UPDATE ON trekr.training_sessions
-        FOR EACH ROW
-        EXECUTE FUNCTION trekr.fn_check_training_date();
-    END IF;
-END$$;
-
Index: -scripts/tunnel_scripta.sh
===================================================================
--- db-scripts/tunnel_scripta.sh	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,14 +1,0 @@
-#!/bin/bash
-echo "PRED DA JA STARTUVATE SKRIPTATA TREBA VO NEA DA GI STAVITE"
-echo "VASHETO KORISNICHKO IME I LOZINKA ZA TUNELOT."
-echo "PO STARTUVANJETO, BAZATA KJE BIDE DOSTAPNA NA PORTA LOCALHOST:9999"
-echo "AKO SAKATE DA SLUSHA NA DRUGA PORTA, SMENETE JA SKRIPTATA SOODVETNO"
-echo "AKO SAKATE DA STOPIRATE (CTRL+C)"
-
-
-sshpass -p '459499b8' ssh -v -2 -C -N -L 9999:localhost:5432 t_trekr@194.149.135.130
-
-echo "VRSKATA TREBA DA STOI OTVORENA SE DODEKA IMATE PRISTAP DO SERVEROT"
-echo "OVAA PORAKA KAZHUVA DEKA TUNELOT VEKJE SE ZATVORIL"
-echo "AKO TOA SE SLUCHILO SAMO OD SEBE, IMATE PROBLEM SO VOSPOSTAVUVANJE"
-echo "NA VRSKATA DO SERVEROT (BLOKADA) ILI VI SE POGRESHNI PARAMETRITE"
Index: -scripts/views/finance_allocations_view.sql
===================================================================
--- db-scripts/views/finance_allocations_view.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,18 +1,0 @@
--- View: calculate allocation amounts per finance category for the current month
-CREATE OR REPLACE VIEW trekr.vw_finance_allocations_current_month AS
-SELECT
-    f.user_id,
-    fm.total_earned_this_month,
-    f.spending_budget,
-    f.saving_budget,
-    f.investing_budget,
-    f.donation_budget,
-    f.credit,
-    ROUND((COALESCE(f.spending_budget,0) / 100.0) * fm.total_earned_this_month, 2) AS spending_amount,
-    ROUND((COALESCE(f.saving_budget,0) / 100.0) * fm.total_earned_this_month, 2) AS saving_amount,
-    ROUND((COALESCE(f.investing_budget,0) / 100.0) * fm.total_earned_this_month, 2) AS investing_amount,
-    ROUND((COALESCE(f.donation_budget,0) / 100.0) * fm.total_earned_this_month, 2) AS donation_amount,
-    ROUND((COALESCE(f.credit,0) / 100.0) * fm.total_earned_this_month, 2) AS credit_amount
-FROM trekr.finance_users f
-LEFT JOIN trekr.vw_finance_current_month fm ON fm.user_id = f.user_id;
-
Index: -scripts/views/finance_monthly_summary_view.sql
===================================================================
--- db-scripts/views/finance_monthly_summary_view.sql	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,22 +1,0 @@
--- View: monthly income summary per user
--- Shows total income per user per month and year
-CREATE OR REPLACE VIEW trekr.vw_finance_monthly_summary AS
-SELECT
-    i.finance_user_id AS user_id,
-    EXTRACT(YEAR FROM i.date)::int AS year,
-    EXTRACT(MONTH FROM i.date)::int AS month,
-    SUM(i.amount) AS total_income
-FROM trekr.incomes i
-GROUP BY i.finance_user_id, EXTRACT(YEAR FROM i.date), EXTRACT(MONTH FROM i.date);
-
--- View: current month total money earned for each user
-CREATE OR REPLACE VIEW trekr.vw_finance_current_month AS
-SELECT
-    f.user_id,
-    COALESCE(SUM(i.amount), 0) AS total_earned_this_month
-FROM trekr.finance_users f
-LEFT JOIN trekr.incomes i
-    ON i.finance_user_id = f.user_id
-    AND date_trunc('month', i.date) = date_trunc('month', current_date)
-GROUP BY f.user_id;
-
Index: cker-compose.yml
===================================================================
--- docker-compose.yml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,43 +1,0 @@
-services:
-  db:
-    image: postgres:16-alpine
-    environment:
-      POSTGRES_DB: trekr
-      POSTGRES_USER: trekr
-      POSTGRES_PASSWORD: trekr
-    volumes:
-      - db_data:/var/lib/postgresql/data
-      - ./db-scripts/ddl.sql:/docker-entrypoint-initdb.d/ddl.sql:ro
-      - ./db-scripts/dml.sql:/docker-entrypoint-initdb.d/dml.sql:ro
-      - ./db-scripts/docker-init/01-init.sql:/docker-entrypoint-initdb.d/01-init.sql:ro
-    healthcheck:
-      test: ["CMD-SHELL", "pg_isready -U trekr -d trekr"]
-      interval: 5s
-      timeout: 5s
-      retries: 10
-    ports:
-      - "5432:5432"
-
-  backend:
-    build: ./backend
-    environment:
-      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/trekr
-      SPRING_DATASOURCE_USERNAME: trekr
-      SPRING_DATASOURCE_PASSWORD: trekr
-      SPRING_JPA_HIBERNATE_DDL_AUTO: none
-      JWT_SECRET: ${JWT_SECRET:-change-me-in-production-min-32-chars}
-    depends_on:
-      db:
-        condition: service_healthy
-    ports:
-      - "8080:8080"
-
-  frontend:
-    build: ./frontend
-    ports:
-      - "3000:80"
-    depends_on:
-      - backend
-
-volumes:
-  db_data:
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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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: ontend/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()],
 })
Index: s/backend.yaml
===================================================================
--- k8s/backend.yaml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,63 +1,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  name: backend
-  namespace: trekr
-spec:
-  replicas: 1
-  selector:
-    matchLabels:
-      app: backend
-  template:
-    metadata:
-      labels:
-        app: backend
-    spec:
-      initContainers:
-        - name: wait-for-postgres
-          image: postgres:16-alpine
-          command: [sh, -c, until pg_isready -h postgres -p 5432 -U trekr; do sleep 2; done]
-      containers:
-        - name: backend
-          image: DOCKERHUB_USERNAME/trekr-backend:latest
-          envFrom:
-            - configMapRef:
-                name: backend-config
-          env:
-            - name: SPRING_DATASOURCE_PASSWORD
-              valueFrom:
-                secretKeyRef:
-                  name: trekr-secrets
-                  key: db-password
-            - name: JWT_SECRET
-              valueFrom:
-                secretKeyRef:
-                  name: trekr-secrets
-                  key: jwt-secret
-          ports:
-            - containerPort: 8080
-          readinessProbe:
-            httpGet:
-              path: /api/auth/ping
-              port: 8080
-            initialDelaySeconds: 20
-            periodSeconds: 10
-            failureThreshold: 6
-          livenessProbe:
-            httpGet:
-              path: /api/auth/ping
-              port: 8080
-            initialDelaySeconds: 60
-            periodSeconds: 15
----
-apiVersion: v1
-kind: Service
-metadata:
-  name: backend
-  namespace: trekr
-spec:
-  selector:
-    app: backend
-  ports:
-    - port: 8080
-      targetPort: 8080
Index: s/configmaps.yaml
===================================================================
--- k8s/configmaps.yaml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,9 +1,0 @@
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: backend-config
-  namespace: trekr
-data:
-  SPRING_DATASOURCE_URL: "jdbc:postgresql://postgres:5432/trekr"
-  SPRING_DATASOURCE_USERNAME: "trekr"
-  SPRING_JPA_HIBERNATE_DDL_AUTO: "none"
Index: s/deploy-local.sh
===================================================================
--- k8s/deploy-local.sh	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,64 +1,0 @@
-#!/bin/bash
-set -e
-
-# ── Config ────────────────────────────────────────────────────────────────────
-read -p "DockerHub username: " DOCKERHUB_USERNAME
-read -p "DB password (choose any): " DB_PASSWORD
-read -p "JWT secret (min 32 chars): " JWT_SECRET
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-
-echo ""
-echo "==> Switching to docker-desktop context..."
-kubectl config use-context docker-desktop
-
-echo "==> Applying namespace..."
-kubectl apply -f "$SCRIPT_DIR/namespace.yaml"
-
-echo "==> Creating secrets..."
-kubectl create secret generic trekr-secrets \
-  --namespace=trekr \
-  --from-literal=db-password="$DB_PASSWORD" \
-  --from-literal=jwt-secret="$JWT_SECRET" \
-  --save-config \
-  --dry-run=client -o yaml | kubectl apply -f -
-
-echo "==> Creating DB init ConfigMap from DDL..."
-kubectl create configmap trekr-db-init \
-  --namespace=trekr \
-  --from-file=01-ddl.sql="$SCRIPT_DIR/../db-scripts/ddl.sql" \
-  --save-config \
-  --dry-run=client -o yaml | kubectl apply -f -
-
-echo "==> Applying ConfigMaps..."
-kubectl apply -f "$SCRIPT_DIR/configmaps.yaml"
-
-echo "==> Applying Postgres StatefulSet..."
-kubectl apply -f "$SCRIPT_DIR/postgres.yaml"
-
-echo "==> Waiting for Postgres..."
-kubectl rollout status statefulset/postgres -n trekr --timeout=120s
-
-echo "==> Applying Backend Deployment..."
-sed "s|DOCKERHUB_USERNAME|$DOCKERHUB_USERNAME|g" "$SCRIPT_DIR/backend.yaml" | kubectl apply -f -
-
-echo "==> Applying Frontend Deployment..."
-sed "s|DOCKERHUB_USERNAME|$DOCKERHUB_USERNAME|g" "$SCRIPT_DIR/frontend.yaml" | kubectl apply -f -
-
-echo "==> Applying Ingress..."
-kubectl apply -f "$SCRIPT_DIR/ingress.yaml"
-
-echo "==> Waiting for backend rollout..."
-kubectl rollout status deployment/backend -n trekr --timeout=180s
-
-echo "==> Waiting for frontend rollout..."
-kubectl rollout status deployment/frontend -n trekr --timeout=60s
-
-echo ""
-echo "==> Adding trekr.local to /etc/hosts (needs sudo)..."
-if ! grep -q "trekr.local" /etc/hosts; then
-  echo "127.0.0.1 trekr.local" | sudo tee -a /etc/hosts
-fi
-
-echo ""
-echo "✅ Done! Open http://trekr.local in your browser."
Index: s/frontend.yaml
===================================================================
--- k8s/frontend.yaml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,38 +1,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  name: frontend
-  namespace: trekr
-spec:
-  replicas: 1
-  selector:
-    matchLabels:
-      app: frontend
-  template:
-    metadata:
-      labels:
-        app: frontend
-    spec:
-      containers:
-        - name: frontend
-          image: DOCKERHUB_USERNAME/trekr-frontend:latest
-          ports:
-            - containerPort: 80
-          readinessProbe:
-            httpGet:
-              path: /
-              port: 80
-            initialDelaySeconds: 5
-            periodSeconds: 5
----
-apiVersion: v1
-kind: Service
-metadata:
-  name: frontend
-  namespace: trekr
-spec:
-  selector:
-    app: frontend
-  ports:
-    - port: 80
-      targetPort: 80
Index: s/ingress.yaml
===================================================================
--- k8s/ingress.yaml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,20 +1,0 @@
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
-  name: trekr-ingress
-  namespace: trekr
-  annotations:
-    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
-spec:
-  ingressClassName: nginx
-  rules:
-    - host: trekr.local
-      http:
-        paths:
-          - path: /
-            pathType: Prefix
-            backend:
-              service:
-                name: frontend
-                port:
-                  number: 80
Index: s/namespace.yaml
===================================================================
--- k8s/namespace.yaml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,4 +1,0 @@
-apiVersion: v1
-kind: Namespace
-metadata:
-  name: trekr
Index: s/postgres.yaml
===================================================================
--- k8s/postgres.yaml	(revision 0427f599f15f08425a193b5b366fd15cc0a95f42)
+++ 	(revision )
@@ -1,72 +1,0 @@
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
-  name: postgres-pvc
-  namespace: trekr
-spec:
-  accessModes: [ReadWriteOnce]
-  resources:
-    requests:
-      storage: 2Gi
----
-apiVersion: apps/v1
-kind: StatefulSet
-metadata:
-  name: postgres
-  namespace: trekr
-spec:
-  serviceName: postgres
-  replicas: 1
-  selector:
-    matchLabels:
-      app: postgres
-  template:
-    metadata:
-      labels:
-        app: postgres
-    spec:
-      containers:
-        - name: postgres
-          image: postgres:16-alpine
-          env:
-            - name: POSTGRES_DB
-              value: trekr
-            - name: POSTGRES_USER
-              value: trekr
-            - name: POSTGRES_PASSWORD
-              valueFrom:
-                secretKeyRef:
-                  name: trekr-secrets
-                  key: db-password
-          ports:
-            - containerPort: 5432
-          volumeMounts:
-            - name: data
-              mountPath: /var/lib/postgresql/data
-            - name: init-sql
-              mountPath: /docker-entrypoint-initdb.d
-          readinessProbe:
-            exec:
-              command: [pg_isready, -U, trekr, -d, trekr]
-            initialDelaySeconds: 5
-            periodSeconds: 5
-            failureThreshold: 10
-      volumes:
-        - name: data
-          persistentVolumeClaim:
-            claimName: postgres-pvc
-        - name: init-sql
-          configMap:
-            name: trekr-db-init
----
-apiVersion: v1
-kind: Service
-metadata:
-  name: postgres
-  namespace: trekr
-spec:
-  selector:
-    app: postgres
-  ports:
-    - port: 5432
-      targetPort: 5432
