diff --git a/GEMINI.md b/GEMINI.md
new file mode 100644
index 0000000..39ebd3b
--- /dev/null
+++ b/GEMINI.md
@@ -0,0 +1,72 @@
+# GEMINI Project Context: SmurfHabits
+
+This document provides a comprehensive overview of the SmurfHabits project for AI-assisted development.
+
+## 1. Project Overview
+
+SmurfHabits is a mobile-first web application for habit tracking with a light gamification layer. The core user loop involves completing daily habits and quests to earn rewards, which are then used to build and develop a virtual village. This progression grants Experience Points (EXP) that are tracked on a global leaderboard.
+
+The project is a full-stack SPA (Single Page Application) built with Nuxt 3, using Vue 3 for the frontend and a Node.js backend powered by Nuxt Nitro. It uses SQLite as its database with Prisma ORM for data access.
+
+### Key Architectural Principles:
+- **Monorepo:** Frontend and backend coexist in a single codebase.
+- **Backend as Source of Truth:** All progression, time-based calculations, and rewards are handled by the server-side API to ensure consistency.
+- **Clear Separation of Concerns:** A strict distinction is maintained between UI (in `app/`), backend logic (in `server/`), and data persistence (in `prisma/`).
+
+## 2. Building and Running
+
+The project uses `npm` for dependency management and running scripts.
+
+### First-Time Setup
+1. **Install Node.js:** Ensure you are using a Node.js version in the 20.x LTS range.
+2. **Install Dependencies:**
+ ```bash
+ npm install
+ ```
+3. **Setup Database:** Create the initial database and apply migrations. The `.env` file is pre-configured to use a local SQLite file (`dev.db`).
+ ```bash
+ npx prisma migrate dev
+ ```
+
+### Development
+To run the development server with hot-reloading:
+```bash
+npm run dev
+```
+
+### Building for Production
+To build the application for production:
+```bash
+npm run build
+```
+
+## 3. Development Conventions
+
+Adhering to these conventions is critical for maintaining project stability.
+
+### Project Structure
+- `app/`: Contains all frontend UI code (pages, components, layouts).
+- `server/`: Contains all backend API code and utilities.
+- `prisma/`: Contains the database schema (`schema.prisma`) and migration files.
+- `public/`: Contains static assets.
+
+### Database and Prisma
+- The project is intentionally locked to **Prisma v6.x**. Do **NOT** upgrade to v7 or introduce Prisma adapters.
+- All changes to the database schema in `prisma/schema.prisma` **must** be followed by a migration command:
+ ```bash
+ npx prisma migrate dev
+ ```
+- The primary Prisma client instance is exported from `server/utils/prisma.ts`. Do not initialize the client elsewhere.
+
+### State Management
+- **Frontend:** Pinia is used for client-side state management.
+- **Backend:** The backend API is the authoritative source for all user progression, rewards, and time-sensitive data. The frontend should not implement its own logic for these calculations.
+
+### API Development
+- API routes are located in `server/api/`.
+- Group API endpoints by domain (e.g., `/api/habits`, `/api/village`).
+- All business logic should reside in the backend.
+
+### AI / Gemini Usage Rules
+- **DO NOT** allow the AI to change the Node.js version, upgrade Prisma, alter the Prisma configuration, or modify the core project structure.
+- **ALLOWED:** The AI can be used to add or modify Prisma schema models, generate new API endpoints, and implement business logic within the existing architectural framework.
diff --git a/app/app.vue b/app/app.vue
index 09f935b..732c82f 100644
--- a/app/app.vue
+++ b/app/app.vue
@@ -1,6 +1,14 @@
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/app/composables/useApi.ts b/app/composables/useApi.ts
new file mode 100644
index 0000000..ba468ff
--- /dev/null
+++ b/app/composables/useApi.ts
@@ -0,0 +1,18 @@
+// /composables/useApi.ts
+export const useApi = () => {
+ return $fetch.create({
+ baseURL: '/api',
+ credentials: 'include',
+ onRequest({ request, options }) {
+ // Log request
+ console.log('Fetching ', request, options);
+ },
+ onResponseError({ response }) {
+ if (response.status === 401) {
+ return; // Ignore 401 unauthorized errors, they are handled by the caller.
+ }
+ // Log all other errors
+ console.error('Fetch error ', response.status, response._data);
+ },
+ });
+};
diff --git a/app/composables/useAuth.ts b/app/composables/useAuth.ts
new file mode 100644
index 0000000..3a3c66a
--- /dev/null
+++ b/app/composables/useAuth.ts
@@ -0,0 +1,101 @@
+// /composables/useAuth.ts
+
+// Define User interface
+interface User {
+ id: string;
+ email: string;
+ nickname: string;
+}
+
+/**
+ * Composable for authentication management.
+ * All state is managed by Nuxt's useState to ensure it's shared and SSR-safe.
+ */
+export function useAuth() {
+ // --- State ---
+ // All state is defined here, inside the composable function.
+ // Nuxt's useState ensures this state is a singleton across the app.
+ const user = useState('user', () => null);
+ const loading = useState('auth_loading', () => false);
+ const initialized = useState('auth_initialized', () => false);
+
+ // --- Composables ---
+ const api = useApi();
+
+ // --- Computed Properties ---
+ const isAuthenticated = computed(() => !!user.value);
+
+ // --- Methods ---
+
+ /**
+ * Fetches the current user from the backend.
+ * Runs only once, guarded by the 'initialized' state.
+ */
+ const fetchMe = async () => {
+ if (initialized.value) {
+ return;
+ }
+
+ loading.value = true;
+ initialized.value = true;
+ try {
+ const fetchedUser = await api('/auth/me', { method: 'GET' });
+ user.value = fetchedUser;
+ } catch (error) {
+ user.value = null; // Silently handle 401s or other errors
+ } finally {
+ loading.value = false;
+ }
+ };
+
+ /**
+ * Logs the user in and fetches their data on success.
+ */
+ const login = async (email, password) => {
+ loading.value = true;
+ try {
+ await api('/auth/login', {
+ method: 'POST',
+ body: { email, password },
+ });
+
+ // We must re-fetch the user after logging in.
+ // Resetting 'initialized' allows fetchMe to run again.
+ initialized.value = false;
+ await fetchMe();
+
+ await navigateTo('/');
+ } catch (error) {
+ console.error('Login failed:', error);
+ throw error; // Re-throw to allow the UI to handle it
+ } finally {
+ loading.value = false;
+ }
+ };
+
+ /**
+ * Logs the user out.
+ */
+ const logout = async () => {
+ loading.value = true;
+ try {
+ await api('/auth/logout', { method: 'POST' });
+ } catch (error) {
+ console.error('Logout API call failed, proceeding with client-side logout:', error);
+ } finally {
+ user.value = null;
+ initialized.value = false; // Allow re-fetch on next app load/login
+ loading.value = false;
+ await navigateTo('/login');
+ }
+ };
+
+ return {
+ user,
+ loading,
+ isAuthenticated,
+ fetchMe,
+ login,
+ logout,
+ };
+}
\ No newline at end of file
diff --git a/app/layouts/default.vue b/app/layouts/default.vue
new file mode 100644
index 0000000..083272c
--- /dev/null
+++ b/app/layouts/default.vue
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
diff --git a/assets/ui-references/photo_2026-01-03_13-24-52.jpg b/assets/ui-references/photo_2026-01-03_13-24-52.jpg
new file mode 100644
index 0000000..b44a0a3
Binary files /dev/null and b/assets/ui-references/photo_2026-01-03_13-24-52.jpg differ
diff --git a/assets/ui-references/photo_2026-01-03_13-25-16.jpg b/assets/ui-references/photo_2026-01-03_13-25-16.jpg
new file mode 100644
index 0000000..a1f2ad4
Binary files /dev/null and b/assets/ui-references/photo_2026-01-03_13-25-16.jpg differ
diff --git a/assets/ui-references/photo_2026-01-03_13-25-21.jpg b/assets/ui-references/photo_2026-01-03_13-25-21.jpg
new file mode 100644
index 0000000..cba9fa6
Binary files /dev/null and b/assets/ui-references/photo_2026-01-03_13-25-21.jpg differ
diff --git a/assets/raw/smurf1.jpg b/assets/ui-references/smurf1.jpg
similarity index 100%
rename from assets/raw/smurf1.jpg
rename to assets/ui-references/smurf1.jpg
diff --git a/assets/raw/smurf2.jpg b/assets/ui-references/smurf2.jpg
similarity index 100%
rename from assets/raw/smurf2.jpg
rename to assets/ui-references/smurf2.jpg
diff --git a/assets/raw/smurf3.jpg b/assets/ui-references/smurf3.jpg
similarity index 100%
rename from assets/raw/smurf3.jpg
rename to assets/ui-references/smurf3.jpg
diff --git a/middleware/auth.global.ts b/middleware/auth.global.ts
new file mode 100644
index 0000000..ce21759
--- /dev/null
+++ b/middleware/auth.global.ts
@@ -0,0 +1,17 @@
+// /middleware/auth.ts
+export default defineNuxtRouteMiddleware((to) => {
+ // `app.vue` is responsible for the initial fetchUser call.
+ // This middleware just reads the state that's already present.
+ const { isAuthenticated } = useAuth();
+
+ // if the user is authenticated and tries to access /login, redirect to home
+ if (isAuthenticated.value && to.path === '/login') {
+ return navigateTo('/', { replace: true });
+ }
+
+ // if the user is not authenticated and tries to access any page other than public routes, redirect to /login
+ const publicRoutes = ['/login', '/register']; // Add any other public paths here
+ if (!isAuthenticated.value && !publicRoutes.includes(to.path)) {
+ return navigateTo('/login', { replace: true });
+ }
+});
\ No newline at end of file
diff --git a/pages/index.vue b/pages/index.vue
new file mode 100644
index 0000000..484e61c
--- /dev/null
+++ b/pages/index.vue
@@ -0,0 +1,12 @@
+
+
+