From 0d78b752c9673ede5a962f54c52198b810b54daf Mon Sep 17 00:00:00 2001
From: HsiangNianian <i@jyunko.cn>
Date: Wed, 14 Jan 2026 16:38:02 +0800
Subject: feat: enhance VersionsView with modded version support and filtering
 options

---
 ui/src/components/VersionsView.svelte | 268 +++++++++++++++++++++++++++++-----
 1 file changed, 231 insertions(+), 37 deletions(-)

(limited to 'ui/src/components/VersionsView.svelte')

diff --git a/ui/src/components/VersionsView.svelte b/ui/src/components/VersionsView.svelte
index 98261b8..1ea4878 100644
--- a/ui/src/components/VersionsView.svelte
+++ b/ui/src/components/VersionsView.svelte
@@ -1,55 +1,249 @@
 <script lang="ts">
+  import { invoke } from "@tauri-apps/api/core";
   import { gameState } from "../stores/game.svelte";
+  import ModLoaderSelector from "./ModLoaderSelector.svelte";
 
   let searchQuery = $state("");
   let normalizedQuery = $derived(
     searchQuery.trim().toLowerCase().replace(/。/g, ".")
   );
 
-  let filteredVersions = $derived(
-    gameState.versions.filter((v) =>
-      v.id.toLowerCase().includes(normalizedQuery)
-    )
-  );
+  // Filter by version type
+  let typeFilter = $state<"all" | "release" | "snapshot" | "modded">("all");
+
+  // Installed modded versions
+  let installedFabricVersions = $state<string[]>([]);
+  let isLoadingModded = $state(false);
+
+  // Load installed modded versions
+  async function loadInstalledModdedVersions() {
+    isLoadingModded = true;
+    try {
+      installedFabricVersions = await invoke<string[]>(
+        "list_installed_fabric_versions"
+      );
+    } catch (e) {
+      console.error("Failed to load installed fabric versions:", e);
+    } finally {
+      isLoadingModded = false;
+    }
+  }
+
+  // Load on mount
+  $effect(() => {
+    loadInstalledModdedVersions();
+  });
+
+  // Combined versions list (vanilla + modded)
+  let allVersions = $derived(() => {
+    const moddedVersions = installedFabricVersions.map((id) => ({
+      id,
+      type: "fabric",
+      url: "",
+      time: "",
+      releaseTime: new Date().toISOString(),
+    }));
+    return [...moddedVersions, ...gameState.versions];
+  });
+
+  let filteredVersions = $derived(() => {
+    let versions = allVersions();
+
+    // Apply type filter
+    if (typeFilter === "release") {
+      versions = versions.filter((v) => v.type === "release");
+    } else if (typeFilter === "snapshot") {
+      versions = versions.filter((v) => v.type === "snapshot");
+    } else if (typeFilter === "modded") {
+      versions = versions.filter(
+        (v) => v.type === "fabric" || v.type === "forge"
+      );
+    }
+
+    // Apply search filter
+    if (normalizedQuery.length > 0) {
+      versions = versions.filter((v) =>
+        v.id.toLowerCase().includes(normalizedQuery)
+      );
+    }
+
+    return versions;
+  });
+
+  function getVersionBadge(type: string) {
+    switch (type) {
+      case "release":
+        return { text: "Release", class: "bg-green-600" };
+      case "snapshot":
+        return { text: "Snapshot", class: "bg-yellow-600" };
+      case "fabric":
+        return { text: "Fabric", class: "bg-blue-600" };
+      case "forge":
+        return { text: "Forge", class: "bg-orange-600" };
+      default:
+        return { text: type, class: "bg-zinc-600" };
+    }
+  }
+
+  function handleModLoaderInstall(versionId: string) {
+    // Refresh the installed versions list
+    loadInstalledModdedVersions();
+    // Select the newly installed version
+    gameState.selectedVersion = versionId;
+  }
+
+  // Get the base Minecraft version from selected version (for mod loader selector)
+  let selectedBaseVersion = $derived(() => {
+    const selected = gameState.selectedVersion;
+    if (!selected) return "";
+
+    // If it's a modded version, extract the base version
+    if (selected.startsWith("fabric-loader-")) {
+      // Format: fabric-loader-X.X.X-1.20.4
+      const parts = selected.split("-");
+      return parts[parts.length - 1];
+    }
+    if (selected.includes("-forge-")) {
+      // Format: 1.20.4-forge-49.0.38
+      return selected.split("-forge-")[0];
+    }
+
+    // Check if it's a valid vanilla version
+    const version = gameState.versions.find((v) => v.id === selected);
+    return version ? selected : "";
+  });
 </script>
 
 <div class="p-8 h-full overflow-y-auto bg-zinc-900">
   <h2 class="text-3xl font-bold mb-6">Versions</h2>
 
-  <input
-    type="text"
-    placeholder="Search versions..."
-    class="w-full p-3 mb-4 bg-zinc-800 border border-zinc-700 rounded text-white focus:outline-none focus:border-green-500 transition-colors"
-    bind:value={searchQuery}
-  />
-
-  <div class="grid gap-2">
-    {#if gameState.versions.length === 0}
-      <div class="text-zinc-500">Loading versions...</div>
-    {:else if filteredVersions.length === 0 && normalizedQuery.length > 0}
-      <div class="text-zinc-500">No versions found matching "{searchQuery}"</div>
-    {:else}
-      {#each filteredVersions as version}
+  <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
+    <!-- Left: Version List -->
+    <div class="lg:col-span-2 space-y-4">
+      <!-- Search and Filters -->
+      <div class="flex gap-3">
+        <input
+          type="text"
+          placeholder="Search versions..."
+          class="flex-1 p-3 bg-zinc-800 border border-zinc-700 rounded text-white focus:outline-none focus:border-green-500 transition-colors"
+          bind:value={searchQuery}
+        />
+      </div>
+
+      <!-- Type Filter Tabs -->
+      <div class="flex gap-1 bg-zinc-800 rounded-lg p-1">
         <button
-          class="flex items-center justify-between p-4 bg-zinc-800 rounded hover:bg-zinc-700 transition text-left border border-zinc-700 {gameState.selectedVersion ===
-          version.id
-            ? 'border-green-500 bg-zinc-800/80 ring-1 ring-green-500'
-            : ''}"
-          onclick={() => (gameState.selectedVersion = version.id)}
+          class="flex-1 px-3 py-2 rounded-md text-sm font-medium transition-colors {typeFilter ===
+          'all'
+            ? 'bg-zinc-700 text-white'
+            : 'text-zinc-400 hover:text-white'}"
+          onclick={() => (typeFilter = "all")}
         >
-          <div>
-            <div class="font-bold font-mono text-lg">{version.id}</div>
-            <div class="text-xs text-zinc-400 capitalize">
-              {version.type} • {new Date(
-                version.releaseTime
-              ).toLocaleDateString()}
-            </div>
-          </div>
-          {#if gameState.selectedVersion === version.id}
-            <div class="text-green-500 font-bold text-sm">SELECTED</div>
-          {/if}
+          All
         </button>
-      {/each}
-    {/if}
+        <button
+          class="flex-1 px-3 py-2 rounded-md text-sm font-medium transition-colors {typeFilter ===
+          'release'
+            ? 'bg-green-600 text-white'
+            : 'text-zinc-400 hover:text-white'}"
+          onclick={() => (typeFilter = "release")}
+        >
+          Releases
+        </button>
+        <button
+          class="flex-1 px-3 py-2 rounded-md text-sm font-medium transition-colors {typeFilter ===
+          'snapshot'
+            ? 'bg-yellow-600 text-white'
+            : 'text-zinc-400 hover:text-white'}"
+          onclick={() => (typeFilter = "snapshot")}
+        >
+          Snapshots
+        </button>
+        <button
+          class="flex-1 px-3 py-2 rounded-md text-sm font-medium transition-colors {typeFilter ===
+          'modded'
+            ? 'bg-purple-600 text-white'
+            : 'text-zinc-400 hover:text-white'}"
+          onclick={() => (typeFilter = "modded")}
+        >
+          Modded
+        </button>
+      </div>
+
+      <!-- Version List -->
+      <div class="grid gap-2 max-h-[calc(100vh-320px)] overflow-y-auto pr-2">
+        {#if gameState.versions.length === 0}
+          <div class="text-zinc-500">Loading versions...</div>
+        {:else if filteredVersions().length === 0}
+          <div class="text-zinc-500">
+            {#if normalizedQuery.length > 0}
+              No versions found matching "{searchQuery}"
+            {:else}
+              No versions in this category
+            {/if}
+          </div>
+        {:else}
+          {#each filteredVersions() as version}
+            {@const badge = getVersionBadge(version.type)}
+            <button
+              class="flex items-center justify-between p-4 bg-zinc-800 rounded hover:bg-zinc-700 transition text-left border border-zinc-700 {gameState.selectedVersion ===
+              version.id
+                ? 'border-green-500 bg-zinc-800/80 ring-1 ring-green-500'
+                : ''}"
+              onclick={() => (gameState.selectedVersion = version.id)}
+            >
+              <div class="flex items-center gap-3">
+                <span
+                  class="px-2 py-0.5 rounded text-xs font-medium {badge.class}"
+                >
+                  {badge.text}
+                </span>
+                <div>
+                  <div class="font-bold font-mono">{version.id}</div>
+                  {#if version.releaseTime && version.type !== "fabric" && version.type !== "forge"}
+                    <div class="text-xs text-zinc-400">
+                      {new Date(version.releaseTime).toLocaleDateString()}
+                    </div>
+                  {/if}
+                </div>
+              </div>
+              {#if gameState.selectedVersion === version.id}
+                <div class="text-green-500 font-bold text-sm">SELECTED</div>
+              {/if}
+            </button>
+          {/each}
+        {/if}
+      </div>
+    </div>
+
+    <!-- Right: Mod Loader Panel -->
+    <div class="space-y-4">
+      <!-- Selected Version Info -->
+      {#if gameState.selectedVersion}
+        <div class="bg-zinc-800 rounded-lg p-4 border border-zinc-700">
+          <h3 class="text-sm font-semibold text-zinc-400 mb-2">Selected</h3>
+          <p class="font-mono text-lg text-green-400">
+            {gameState.selectedVersion}
+          </p>
+        </div>
+      {/if}
+
+      <!-- Mod Loader Selector -->
+      <ModLoaderSelector
+        selectedGameVersion={selectedBaseVersion()}
+        onInstall={handleModLoaderInstall}
+      />
+
+      <!-- Help Text -->
+      <div class="bg-zinc-800/50 rounded-lg p-4 border border-zinc-700/50">
+        <h4 class="text-sm font-semibold text-zinc-400 mb-2">💡 Tip</h4>
+        <p class="text-xs text-zinc-500">
+          Select a vanilla Minecraft version, then use the Mod Loader panel to
+          install Fabric or Forge. Installed modded versions will appear in the
+          list with colored badges.
+        </p>
+      </div>
+    </div>
   </div>
 </div>
+
-- 
cgit v1.2.3-70-g09d2


From eed52135e7d6ffbbbd64070cf567bcf08653c7d5 Mon Sep 17 00:00:00 2001
From: HsiangNianian <i@jyunko.cn>
Date: Wed, 14 Jan 2026 18:15:31 +0800
Subject: feat: Enhance UI components and add visual effects

- Updated Sidebar component styles for improved aesthetics and usability.
- Refactored VersionsView component with a new layout and enhanced version filtering.
- Improved DownloadMonitor and GameConsole components for better performance and visual consistency.
- Added new settings for GPU acceleration and visual effects in settings store.
- Introduced ParticleBackground component with customizable effects (Constellation and Saturn).
- Implemented ConstellationEffect and SaturnEffect classes for dynamic background animations.
---
 src-tauri/Cargo.toml                        |   1 +
 src-tauri/capabilities/default.json         |   3 +-
 src-tauri/src/core/config.rs                |   8 +
 src-tauri/src/main.rs                       |   1 +
 ui/package.json                             |   1 +
 ui/pnpm-lock.yaml                           |  10 +
 ui/src/App.svelte                           | 145 +++++++++++---
 ui/src/components/BottomBar.svelte          |  79 ++++----
 ui/src/components/HomeView.svelte           |  57 ++++--
 ui/src/components/ModLoaderSelector.svelte  | 214 ++++++++++-----------
 ui/src/components/ParticleBackground.svelte |  57 ++++++
 ui/src/components/SettingsView.svelte       | 282 ++++++++++++++++++++--------
 ui/src/components/Sidebar.svelte            |  76 ++++----
 ui/src/components/VersionsView.svelte       | 184 +++++++++---------
 ui/src/lib/DownloadMonitor.svelte           |   2 +-
 ui/src/lib/GameConsole.svelte               |   2 +-
 ui/src/lib/effects/ConstellationEffect.ts   | 163 ++++++++++++++++
 ui/src/lib/effects/SaturnEffect.ts          | 194 +++++++++++++++++++
 ui/src/stores/settings.svelte.ts            |   3 +
 ui/src/types/index.ts                       |   4 +
 20 files changed, 1080 insertions(+), 406 deletions(-)
 create mode 100644 ui/src/components/ParticleBackground.svelte
 create mode 100644 ui/src/lib/effects/ConstellationEffect.ts
 create mode 100644 ui/src/lib/effects/SaturnEffect.ts

(limited to 'ui/src/components/VersionsView.svelte')

diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
index d7319a7..1d4ccc5 100644
--- a/src-tauri/Cargo.toml
+++ b/src-tauri/Cargo.toml
@@ -23,6 +23,7 @@ sha1 = "0.10"
 hex = "0.4"
 zip = "2.2.2"
 serde_urlencoded = "0.7.1"
+tauri-plugin-dialog = "2.5.0"
 
 [build-dependencies]
 tauri-build = { version = "2.0", features = [] }
diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json
index 894b905..4d8b907 100644
--- a/src-tauri/capabilities/default.json
+++ b/src-tauri/capabilities/default.json
@@ -12,6 +12,7 @@
     "core:app:allow-version",
     "core:path:default",
     "core:window:default",
-    "shell:allow-open"
+    "shell:allow-open",
+    "dialog:default"
   ]
 }
diff --git a/src-tauri/src/core/config.rs b/src-tauri/src/core/config.rs
index d6d594f..27e0011 100644
--- a/src-tauri/src/core/config.rs
+++ b/src-tauri/src/core/config.rs
@@ -13,6 +13,10 @@ pub struct LauncherConfig {
     pub width: u32,
     pub height: u32,
     pub download_threads: u32, // concurrent download threads (1-128)
+    pub custom_background_path: Option<String>,
+    pub enable_gpu_acceleration: bool,
+    pub enable_visual_effects: bool,
+    pub active_effect: String,
 }
 
 impl Default for LauncherConfig {
@@ -24,6 +28,10 @@ impl Default for LauncherConfig {
             width: 854,
             height: 480,
             download_threads: 32,
+            custom_background_path: None,
+            enable_gpu_acceleration: false,
+            enable_visual_effects: true,
+            active_effect: "constellation".to_string(),
         }
     }
 }
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index ba16f7a..f7a391a 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -1004,6 +1004,7 @@ async fn install_forge(
 
 fn main() {
     tauri::Builder::default()
+        .plugin(tauri_plugin_dialog::init())
         .plugin(tauri_plugin_shell::init())
         .manage(core::auth::AccountState::new())
         .manage(MsRefreshTokenState::new())
diff --git a/ui/package.json b/ui/package.json
index 0806781..03cc405 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -29,6 +29,7 @@
   },
   "dependencies": {
     "@tauri-apps/api": "^2.9.1",
+    "@tauri-apps/plugin-dialog": "^2.5.0",
     "@tauri-apps/plugin-shell": "^2.3.4"
   }
 }
diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml
index d48c01e..23d4ee2 100644
--- a/ui/pnpm-lock.yaml
+++ b/ui/pnpm-lock.yaml
@@ -14,6 +14,9 @@ importers:
       '@tauri-apps/api':
         specifier: ^2.9.1
         version: 2.9.1
+      '@tauri-apps/plugin-dialog':
+        specifier: ^2.5.0
+        version: 2.5.0
       '@tauri-apps/plugin-shell':
         specifier: ^2.3.4
         version: 2.3.4
@@ -296,6 +299,9 @@ packages:
   '@tauri-apps/api@2.9.1':
     resolution: {integrity: sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw==}
 
+  '@tauri-apps/plugin-dialog@2.5.0':
+    resolution: {integrity: sha512-I0R0ygwRd9AN8Wj5GnzCogOlqu2+OWAtBd0zEC4+kQCI32fRowIyuhPCBoUv4h/lQt2bM39kHlxPHD5vDcFjiA==}
+
   '@tauri-apps/plugin-shell@2.3.4':
     resolution: {integrity: sha512-ktsRWf8wHLD17aZEyqE8c5x98eNAuTizR1FSX475zQ4TxaiJnhwksLygQz+AGwckJL5bfEP13nWrlTNQJUpKpA==}
 
@@ -808,6 +814,10 @@ snapshots:
 
   '@tauri-apps/api@2.9.1': {}
 
+  '@tauri-apps/plugin-dialog@2.5.0':
+    dependencies:
+      '@tauri-apps/api': 2.9.1
+
   '@tauri-apps/plugin-shell@2.3.4':
     dependencies:
       '@tauri-apps/api': 2.9.1
diff --git a/ui/src/App.svelte b/ui/src/App.svelte
index 3750f11..d93374e 100644
--- a/ui/src/App.svelte
+++ b/ui/src/App.svelte
@@ -1,6 +1,7 @@
 <script lang="ts">
   import { getVersion } from "@tauri-apps/api/app";
-  import { onMount } from "svelte";
+  import { onMount, onDestroy } from "svelte";
+  import { convertFileSrc } from "@tauri-apps/api/core";
   import DownloadMonitor from "./lib/DownloadMonitor.svelte";
   import GameConsole from "./lib/GameConsole.svelte";
   
@@ -12,6 +13,7 @@
   import BottomBar from "./components/BottomBar.svelte";
   import LoginModal from "./components/LoginModal.svelte";
   import StatusToast from "./components/StatusToast.svelte";
+  import ParticleBackground from "./components/ParticleBackground.svelte";
 
   // Stores
   import { uiState } from "./stores/ui.svelte";
@@ -19,46 +21,139 @@
   import { settingsState } from "./stores/settings.svelte";
   import { gameState } from "./stores/game.svelte";
 
+  let mouseX = $state(0);
+  let mouseY = $state(0);
+
+  function handleMouseMove(e: MouseEvent) {
+    mouseX = (e.clientX / window.innerWidth) * 2 - 1;
+    mouseY = (e.clientY / window.innerHeight) * 2 - 1;
+  }
+
   onMount(async () => {
     authState.checkAccount();
     settingsState.loadSettings();
     gameState.loadVersions();
     getVersion().then((v) => (uiState.appVersion = v));
+    window.addEventListener("mousemove", handleMouseMove);
+  });
+  
+  onDestroy(() => {
+    if (typeof window !== 'undefined')
+      window.removeEventListener("mousemove", handleMouseMove);
   });
 </script>
 
 <div
-  class="flex h-screen bg-zinc-900 text-white font-sans overflow-hidden select-none"
+  class="relative h-screen w-screen overflow-hidden text-white font-sans selection:bg-indigo-500/30"
 >
-  <Sidebar />
+  <!-- Modern Animated Background -->
+  <div class="absolute inset-0 z-0 bg-[#09090b] overflow-hidden">
+    {#if settingsState.settings.custom_background_path}
+      <img
+        src={convertFileSrc(settingsState.settings.custom_background_path)}
+        alt="Background"
+        class="absolute inset-0 w-full h-full object-cover transition-transform duration-[20s] ease-linear hover:scale-105"
+      />
+      <!-- Dimming Overlay for readability -->
+      <div class="absolute inset-0 bg-black/50 "></div>
+    {:else if settingsState.settings.enable_visual_effects}
+      <!-- Original Gradient -->
+      <div 
+        class="absolute inset-0 opacity-60 bg-gradient-to-br from-emerald-900 via-zinc-900 to-indigo-950"
+      ></div>
 
-  <!-- Main Content -->
-  <main class="flex-1 flex flex-col relative min-w-0">
-    <DownloadMonitor />
-    <!-- Top Bar (Window Controls Placeholder) -->
-    <div
-      class="h-8 w-full bg-zinc-900/50 absolute top-0 left-0 z-50 drag-region"
-      data-tauri-drag-region
-    >
-      <!-- Windows/macOS controls would go here or be handled by OS -->
-    </div>
-
-    <!-- Background / Poster area -->
-    <div class="flex-1 relative overflow-hidden group">
       {#if uiState.currentView === "home"}
-        <HomeView />
-      {:else if uiState.currentView === "versions"}
-        <VersionsView />
-      {:else if uiState.currentView === "settings"}
-        <SettingsView />
+        <ParticleBackground />
       {/if}
+
+      <div 
+        class="absolute inset-0 bg-gradient-to-t from-zinc-900 via-transparent to-black/50"
+      ></div>
+    {/if}
+    
+    <!-- Subtle Grid Overlay -->
+    <div class="absolute inset-0 z-0 opacity-10 pointer-events-none" 
+         style="background-image: linear-gradient(#ffffff 1px, transparent 1px), linear-gradient(90deg, #ffffff 1px, transparent 1px); background-size: 40px 40px; mask-image: radial-gradient(circle at 50% 50%, black 30%, transparent 70%);">
     </div>
+  </div>
+
+  <!-- Content Wrapper -->
+  <div class="relative z-10 flex h-full p-4 gap-4">
+    <!-- Floating Sidebar -->
+    <Sidebar />
+
+    <!-- Main Content Area - Transparent & Flat -->
+    <main class="flex-1 flex flex-col relative min-w-0 overflow-hidden transition-all duration-300">
+      
+      <!-- Window Drag Region -->
+      <div
+        class="h-8 w-full absolute top-0 left-0 z-50 drag-region"
+        data-tauri-drag-region
+      ></div>
 
-    <BottomBar />
-  </main>
+      <!-- App Content -->
+      <div class="flex-1 relative overflow-hidden flex flex-col">
+          <!-- Views Container -->
+          <div class="flex-1 relative overflow-hidden">
+             {#if uiState.currentView === "home"}
+               <HomeView mouseX={mouseX} mouseY={mouseY} />
+             {:else if uiState.currentView === "versions"}
+               <VersionsView />
+             {:else if uiState.currentView === "settings"}
+               <SettingsView />
+             {/if}
+          </div>
+          
+          <!-- Download Monitor Overlay -->
+          <div class="absolute bottom-20 left-4 right-4 pointer-events-none z-20">
+             <div class="pointer-events-auto">
+                 <DownloadMonitor />
+             </div>
+          </div>
+          
+          <!-- Bottom Bar -->
+          <BottomBar />
+      </div>
+    </main>
+  </div>
 
   <LoginModal />
   <StatusToast />
-
-  <GameConsole visible={uiState.showConsole} />
+  
+  {#if uiState.showConsole}
+     <!-- Assuming GameConsole handles its own display mode or overlay -->
+    <div class="fixed inset-0 z-[100] bg-black/80  flex items-center justify-center p-10">
+        <div class="w-full h-full bg-[#1e1e1e] rounded-xl overflow-hidden border border-white/10 shadow-2xl relative">
+            <button class="absolute top-4 right-4 text-white hover:text-red-400 z-10" onclick={() => uiState.toggleConsole()}>✕</button>
+            <GameConsole />
+        </div>
+    </div>
+  {/if}
 </div>
+
+<style>
+  :global(body) {
+    margin: 0;
+    padding: 0;
+    background: #000;
+  }
+  
+  /* Modern Scrollbar */
+  :global(*::-webkit-scrollbar) {
+    width: 6px;
+    height: 6px;
+  }
+  
+  :global(*::-webkit-scrollbar-track) {
+    background: transparent;
+  }
+  
+  :global(*::-webkit-scrollbar-thumb) {
+    background: rgba(255, 255, 255, 0.1);
+    border-radius: 999px;
+  }
+  
+  :global(*::-webkit-scrollbar-thumb:hover) {
+    background: rgba(255, 255, 255, 0.25);
+  }
+</style>
diff --git a/ui/src/components/BottomBar.svelte b/ui/src/components/BottomBar.svelte
index dcad9e8..dd218f3 100644
--- a/ui/src/components/BottomBar.svelte
+++ b/ui/src/components/BottomBar.svelte
@@ -5,18 +5,19 @@
 </script>
 
 <div
-  class="h-24 bg-zinc-900 border-t border-zinc-800 flex items-center px-8 justify-between z-20 shadow-2xl"
+  class="h-24 bg-gradient-to-t from-black/50 to-transparent border-t border-white/5 flex items-center px-8 justify-between z-20 backdrop-blur-md"
 >
-  <div class="flex items-center gap-4">
+  <!-- Account Area -->
+  <div class="flex items-center gap-6">
     <div
-      class="flex items-center gap-4 cursor-pointer hover:opacity-80 transition-opacity"
+      class="group flex items-center gap-4 cursor-pointer transition-all duration-300 hover:scale-105"
       onclick={() => authState.openLoginModal()}
       role="button"
       tabindex="0"
       onkeydown={(e) => e.key === "Enter" && authState.openLoginModal()}
     >
       <div
-        class="w-12 h-12 rounded bg-gradient-to-tr from-indigo-500 to-purple-500 shadow-lg flex items-center justify-center text-white font-bold text-xl overflow-hidden"
+        class="w-12 h-12 rounded-xl bg-gradient-to-tr from-indigo-500 to-purple-500 shadow-lg shadow-indigo-500/20 flex items-center justify-center text-white font-bold text-xl overflow-hidden ring-2 ring-transparent group-hover:ring-white/20 transition-all"
       >
         {#if authState.currentAccount}
           <img
@@ -25,63 +26,73 @@
             class="w-full h-full"
           />
         {:else}
-          ?
+          <span class="text-white/50 text-2xl">?</span>
         {/if}
       </div>
       <div>
-        <div class="font-bold text-white text-lg">
-          {authState.currentAccount ? authState.currentAccount.username : "Click to Login"}
+        <div class="font-bold text-white text-lg group-hover:text-indigo-300 transition-colors">
+          {authState.currentAccount ? authState.currentAccount.username : "Login"}
         </div>
-        <div class="text-xs text-zinc-400 flex items-center gap-1">
+        <div class="text-xs text-zinc-400 flex items-center gap-1.5">
           <span
-            class="w-1.5 h-1.5 rounded-full {authState.currentAccount
-              ? 'bg-green-500'
-              : 'bg-zinc-500'}"
+            class="w-2 h-2 rounded-full {authState.currentAccount
+              ? 'bg-emerald-500 shadow-[0_0_8px_rgba(16,185,129,0.5)]'
+              : 'bg-zinc-600'}"
           ></span>
-          {authState.currentAccount ? "Ready" : "Guest"}
+          {authState.currentAccount ? "Ready to play" : "Guest Mode"}
         </div>
       </div>
     </div>
+    
+    <div class="h-8 w-px bg-white/10"></div>
+    
     <!-- Console Toggle -->
     <button
-      class="ml-4 text-xs text-zinc-500 hover:text-zinc-300 transition"
+      class="text-xs font-mono text-zinc-500 hover:text-white transition-colors flex items-center gap-2"
       onclick={() => uiState.toggleConsole()}
     >
+      <span class="text-lg">_</span>
       {uiState.showConsole ? "Hide Logs" : "Show Logs"}
     </button>
   </div>
 
-  <div class="flex items-center gap-4">
+  <!-- Action Area -->
+  <div class="flex items-center gap-6">
     <div class="flex flex-col items-end mr-2">
       <label
         for="version-select"
-        class="text-xs text-zinc-500 mb-1 uppercase font-bold tracking-wider"
-        >Version</label
+        class="text-[10px] text-white/40 mb-1 uppercase font-bold tracking-wider"
+        >Selected Version</label
       >
-      <select
-        id="version-select"
-        bind:value={gameState.selectedVersion}
-        class="bg-zinc-950 text-zinc-200 border border-zinc-700 rounded px-4 py-2 hover:border-zinc-500 transition-colors cursor-pointer outline-none focus:ring-1 focus:ring-indigo-500 w-48"
-      >
-        {#if gameState.versions.length === 0}
-          <option>Loading...</option>
-        {:else}
-          {#each gameState.versions as version}
-            <option value={version.id}>{version.id} ({version.type})</option
-            >
-          {/each}
-        {/if}
-      </select>
+      <div class="relative group">
+        <select
+          id="version-select"
+          bind:value={gameState.selectedVersion}
+          class="appearance-none bg-black/40 text-white border border-white/10 rounded-xl pl-4 pr-10 py-2.5 hover:border-white/30 transition-all cursor-pointer outline-none focus:ring-2 focus:ring-indigo-500/50 w-56 text-sm font-mono backdrop-blur-sm shadow-inner"
+        >
+          {#if gameState.versions.length === 0}
+            <option>Loading...</option>
+          {:else}
+            {#each gameState.versions as version}
+              <option value={version.id}>{version.id} {version.type !== 'release' ? `(${version.type})` : ''}</option>
+            {/each}
+          {/if}
+        </select>
+        <div class="absolute right-3 top-1/2 -translate-y-1/2 text-white/20 pointer-events-none group-hover:text-white/50 transition-colors">▼</div>
+      </div>
     </div>
 
     <button
       onclick={() => gameState.startGame()}
-      class="bg-green-600 hover:bg-green-500 text-white font-bold h-14 px-12 rounded transition-all transform active:scale-95 shadow-[0_0_15px_rgba(22,163,74,0.4)] hover:shadow-[0_0_25px_rgba(22,163,74,0.6)] flex flex-col items-center justify-center uppercase tracking-wider text-lg"
+      class="bg-gradient-to-r from-emerald-600 to-green-600 hover:from-emerald-500 hover:to-green-500 text-white font-bold h-14 px-10 rounded-xl transition-all duration-300 transform hover:scale-105 active:scale-95 shadow-[0_0_20px_rgba(16,185,129,0.3)] hover:shadow-[0_0_40px_rgba(16,185,129,0.5)] flex flex-col items-center justify-center uppercase tracking-widest text-xl relative overflow-hidden group"
     >
-      Play
+      <div class="absolute inset-0 bg-white/20 translate-y-full group-hover:translate-y-0 transition-transform duration-300 skew-y-12"></div>
+      <span class="relative z-10 flex items-center gap-2">
+        PLAY
+      </span>
       <span
-        class="text-[10px] font-normal opacity-80 normal-case tracking-normal"
-        >Click to launch</span
+        class="relative z-10 text-[9px] font-normal opacity-70 normal-case tracking-wide -mt-1"
+        >Launch Game</span
       >
     </button>
   </div>
diff --git a/ui/src/components/HomeView.svelte b/ui/src/components/HomeView.svelte
index e876c14..036c03a 100644
--- a/ui/src/components/HomeView.svelte
+++ b/ui/src/components/HomeView.svelte
@@ -1,26 +1,47 @@
 <script lang="ts">
-  // No script needed currently, just static markup mostly
+  type Props = {
+    mouseX: number;
+    mouseY: number;
+  };
+  let { mouseX = 0, mouseY = 0 }: Props = $props();
 </script>
 
-<!-- Background Image - Using gradient fallback -->
-<div
-  class="absolute inset-0 z-0 opacity-60 bg-gradient-to-br from-emerald-900 via-zinc-900 to-indigo-950 transition-transform duration-[10s] ease-linear group-hover:scale-105"
-></div>
-<div
-  class="absolute inset-0 z-0 bg-gradient-to-t from-zinc-900 via-transparent to-black/50"
-></div>
+<div class="absolute inset-0 z-0 overflow-hidden">
+  <!-- Parallax Background Layers -->
+  
+  <div class="absolute inset-0 bg-gradient-to-t from-[#09090b] via-[#09090b]/40 to-transparent"></div>
+</div>
 
-<div class="absolute bottom-24 left-8 z-10 p-4">
-  <h1
-    class="text-6xl font-black mb-2 tracking-tight text-white drop-shadow-lg"
+<div class="relative z-10 h-full flex flex-col justify-end p-12 pb-24">
+  <!-- 3D Floating Hero Text -->
+  <div 
+    class="transition-transform duration-200 ease-out origin-bottom-left"
+    style:transform={`perspective(1000px) rotateX(${mouseY * -2}deg) rotateY(${mouseX * 2}deg)`}
   >
-    MINECRAFT
-  </h1>
-  <div class="flex items-center gap-2 text-zinc-300">
-    <span
-      class="bg-zinc-800 text-xs px-2 py-1 rounded border border-zinc-600"
-      >JAVA EDITION</span
+    <h1
+      class="text-8xl font-black tracking-tighter text-white drop-shadow-2xl mb-4"
+      style="text-shadow: 0 10px 30px rgba(0,0,0,0.5);"
     >
-    <span class="text-lg">Release 1.20.4</span>
+      MINECRAFT
+    </h1>
+    
+    <div class="flex items-center gap-4">
+      <div 
+        class="bg-white/10 backdrop-blur-md border border-white/10 px-4 py-1.5 rounded-full text-sm font-bold uppercase tracking-widest text-emerald-400 shadow-xl"
+      >
+        Java Edition
+      </div>
+      <div class="text-2xl font-light text-zinc-300">
+        Latest Release 1.21
+      </div>
+    </div>
+  </div>
+
+  <!-- Action Area -->
+  <div class="mt-8 flex gap-4">
+    <!-- Quick Play Button (Visual only here, logic is in BottomBar usually) -->
+    <div class="text-zinc-400 text-sm italic">
+      Ready to play. Select version below or hit Launch.
+    </div>
   </div>
 </div>
diff --git a/ui/src/components/ModLoaderSelector.svelte b/ui/src/components/ModLoaderSelector.svelte
index 06eb6ae..4a59916 100644
--- a/ui/src/components/ModLoaderSelector.svelte
+++ b/ui/src/components/ModLoaderSelector.svelte
@@ -112,134 +112,134 @@
   }
 </script>
 
-<div class="bg-zinc-800 rounded-lg p-4 border border-zinc-700">
-  <h3 class="text-sm font-semibold text-zinc-400 mb-3">Mod Loader</h3>
+<div class="space-y-4">
+  <div class="flex items-center justify-between">
+      <h3 class="text-xs font-bold uppercase tracking-widest text-white/40">Select Mod Loader</h3>
+  </div>
 
-  <!-- Loader Type Tabs -->
-  <div class="flex gap-1 mb-4 bg-zinc-900 rounded-lg p-1">
+  <!-- Loader Type Tabs - Segmented Control -->
+  <div class="flex p-1 bg-black/40 rounded-xl border border-white/5 backdrop-blur-sm">
     <button
-      class="flex-1 px-3 py-2 rounded-md text-sm font-medium transition-colors {selectedLoader ===
-      'vanilla'
-        ? 'bg-zinc-700 text-white'
-        : 'text-zinc-400 hover:text-white hover:bg-zinc-800'}"
+      class="flex-1 px-3 py-2 rounded-lg text-sm font-medium transition-all duration-200
+      {selectedLoader === 'vanilla'
+        ? 'bg-white/10 text-white shadow-lg border border-white/10'
+        : 'text-zinc-500 hover:text-white hover:bg-white/5'}"
       onclick={() => onLoaderChange("vanilla")}
     >
       Vanilla
     </button>
     <button
-      class="flex-1 px-3 py-2 rounded-md text-sm font-medium transition-colors {selectedLoader ===
-      'fabric'
-        ? 'bg-blue-600 text-white'
-        : 'text-zinc-400 hover:text-white hover:bg-zinc-800'}"
+      class="flex-1 px-3 py-2 rounded-lg text-sm font-medium transition-all duration-200
+      {selectedLoader === 'fabric'
+        ? 'bg-indigo-500/20 text-indigo-300 shadow-lg border border-indigo-500/20'
+        : 'text-zinc-500 hover:text-white hover:bg-white/5'}"
       onclick={() => onLoaderChange("fabric")}
     >
       Fabric
     </button>
     <button
-      class="flex-1 px-3 py-2 rounded-md text-sm font-medium transition-colors {selectedLoader ===
-      'forge'
-        ? 'bg-orange-600 text-white'
-        : 'text-zinc-400 hover:text-white hover:bg-zinc-800'}"
+      class="flex-1 px-3 py-2 rounded-lg text-sm font-medium transition-all duration-200
+      {selectedLoader === 'forge'
+        ? 'bg-orange-500/20 text-orange-300 shadow-lg border border-orange-500/20'
+        : 'text-zinc-500 hover:text-white hover:bg-white/5'}"
       onclick={() => onLoaderChange("forge")}
     >
       Forge
     </button>
   </div>
 
-  {#if selectedLoader === "vanilla"}
-    <p class="text-sm text-zinc-500">
-      Launch the selected Minecraft version without any mod loaders.
-    </p>
-  {:else if !selectedGameVersion}
-    <p class="text-sm text-zinc-500">
-      Select a Minecraft version first to see available {selectedLoader} versions.
-    </p>
-  {:else if isLoading}
-    <div class="flex items-center gap-2 text-sm text-zinc-400">
-      <svg
-        class="animate-spin h-4 w-4"
-        xmlns="http://www.w3.org/2000/svg"
-        fill="none"
-        viewBox="0 0 24 24"
-      >
-        <circle
-          class="opacity-25"
-          cx="12"
-          cy="12"
-          r="10"
-          stroke="currentColor"
-          stroke-width="4"
-        ></circle>
-        <path
-          class="opacity-75"
-          fill="currentColor"
-          d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
-        ></path>
-      </svg>
-      Loading {selectedLoader} versions...
-    </div>
-  {:else if error}
-    <p class="text-sm text-red-400">{error}</p>
-  {:else if selectedLoader === "fabric"}
-    <div class="space-y-3">
-      <div>
-        <label for="fabric-loader-select" class="block text-xs text-zinc-500 mb-1"
-          >Loader Version</label
-        >
-        <select
-          id="fabric-loader-select"
-          class="w-full bg-zinc-900 border border-zinc-700 rounded px-3 py-2 text-sm focus:outline-none focus:border-blue-500"
-          bind:value={selectedFabricLoader}
-        >
-          {#each fabricLoaders as loader}
-            <option value={loader.version}>
-              {loader.version}
-              {loader.stable ? "(stable)" : ""}
-            </option>
-          {/each}
-        </select>
-      </div>
-      <button
-        class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded font-medium text-sm transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
-        onclick={installModLoader}
-        disabled={isLoading || !selectedFabricLoader}
-      >
-        Install Fabric {selectedFabricLoader}
-      </button>
-    </div>
-  {:else if selectedLoader === "forge"}
-    <div class="space-y-3">
-      {#if forgeVersions.length === 0}
-        <p class="text-sm text-zinc-500">
-          No Forge versions available for Minecraft {selectedGameVersion}
-        </p>
-      {:else}
+  <!-- Content Area -->
+  <div class="min-h-[100px] flex flex-col justify-center">
+    {#if selectedLoader === "vanilla"}
+        <div class="text-center p-4 rounded-xl bg-white/5 border border-dashed border-white/10 text-white/40 text-sm">
+           No mod loader selected. <br> Pure vanilla experience.
+        </div>
+        
+    {:else if !selectedGameVersion}
+        <div class="text-center p-4 rounded-xl bg-red-500/10 border border-red-500/20 text-red-300 text-sm">
+           ⚠️ Please select a base Minecraft version first.
+        </div>
+        
+    {:else if isLoading}
+        <div class="flex flex-col items-center gap-2 text-sm text-white/50 py-4">
+            <div class="w-6 h-6 border-2 border-white/20 border-t-white rounded-full animate-spin"></div>
+            Loading {selectedLoader} versions...
+        </div>
+        
+    {:else if error}
+        <div class="p-4 bg-red-500/10 border border-red-500/20 rounded-xl text-red-300 text-sm break-words">
+            {error}
+        </div>
+        
+    {:else if selectedLoader === "fabric"}
+        <div class="space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300">
         <div>
-          <label for="forge-version-select" class="block text-xs text-zinc-500 mb-1"
-            >Forge Version</label
-          >
-          <select
-            id="forge-version-select"
-            class="w-full bg-zinc-900 border border-zinc-700 rounded px-3 py-2 text-sm focus:outline-none focus:border-orange-500"
-            bind:value={selectedForgeVersion}
-          >
-            {#each forgeVersions as version}
-              <option value={version.version}>
-                {version.version}
-                {version.recommended ? "⭐ recommended" : ""}
-                {version.latest ? "(latest)" : ""}
-              </option>
-            {/each}
-          </select>
+            <label for="fabric-loader-select" class="block text-xs text-white/40 mb-2 pl-1"
+            >Loader Version</label
+            >
+            <div class="relative">
+                <select
+                id="fabric-loader-select"
+                class="w-full appearance-none bg-black/40 border border-white/10 rounded-xl px-4 py-3 text-sm focus:outline-none focus:border-indigo-500/50 text-white transition-colors"
+                bind:value={selectedFabricLoader}
+                >
+                {#each fabricLoaders as loader}
+                    <option value={loader.version}>
+                    {loader.version} {loader.stable ? "(stable)" : ""}
+                    </option>
+                {/each}
+                </select>
+                <div class="absolute right-4 top-1/2 -translate-y-1/2 text-white/20 pointer-events-none">▼</div>
+            </div>
         </div>
+        
         <button
-          class="w-full bg-orange-600 hover:bg-orange-700 text-white py-2 px-4 rounded font-medium text-sm transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
-          onclick={installModLoader}
-          disabled={isLoading || !selectedForgeVersion}
+            class="w-full bg-indigo-600 hover:bg-indigo-500 text-white py-3 px-4 rounded-xl font-bold text-sm transition-all shadow-lg shadow-indigo-500/20 disabled:opacity-50 disabled:shadow-none hover:scale-[1.02] active:scale-[0.98]"
+            onclick={installModLoader}
+            disabled={isLoading || !selectedFabricLoader}
         >
-          Install Forge {selectedForgeVersion}
+            Install Fabric {selectedFabricLoader}
         </button>
-      {/if}
-    </div>
-  {/if}
+        </div>
+        
+    {:else if selectedLoader === "forge"}
+        <div class="space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300">
+        {#if forgeVersions.length === 0}
+            <div class="text-center p-4 text-sm text-white/40 italic">
+            No Forge versions available for {selectedGameVersion}
+            </div>
+        {:else}
+            <div>
+            <label for="forge-version-select" class="block text-xs text-white/40 mb-2 pl-1"
+                >Forge Version</label
+            >
+            <div class="relative">
+                <select
+                    id="forge-version-select"
+                    class="w-full appearance-none bg-black/40 border border-white/10 rounded-xl px-4 py-3 text-sm focus:outline-none focus:border-orange-500/50 text-white transition-colors"
+                    bind:value={selectedForgeVersion}
+                >
+                    {#each forgeVersions as version}
+                    <option value={version.version}>
+                        {version.version}
+                        {version.recommended ? "⭐ recommended" : ""}
+                        {version.latest ? "(latest)" : ""}
+                    </option>
+                    {/each}
+                </select>
+                <div class="absolute right-4 top-1/2 -translate-y-1/2 text-white/20 pointer-events-none">▼</div>
+            </div>
+            </div>
+            
+            <button
+            class="w-full bg-orange-600 hover:bg-orange-500 text-white py-3 px-4 rounded-xl font-bold text-sm transition-all shadow-lg shadow-orange-500/20 disabled:opacity-50 disabled:shadow-none hover:scale-[1.02] active:scale-[0.98]"
+            onclick={installModLoader}
+            disabled={isLoading || !selectedForgeVersion}
+            >
+            Install Forge {selectedForgeVersion}
+            </button>
+        {/if}
+        </div>
+    {/if}
+  </div>
 </div>
diff --git a/ui/src/components/ParticleBackground.svelte b/ui/src/components/ParticleBackground.svelte
new file mode 100644
index 0000000..080f1f2
--- /dev/null
+++ b/ui/src/components/ParticleBackground.svelte
@@ -0,0 +1,57 @@
+<script lang="ts">
+  import { onMount, onDestroy } from "svelte";
+  import { ConstellationEffect } from "../lib/effects/ConstellationEffect";
+  import { SaturnEffect } from "../lib/effects/SaturnEffect";
+  import { settingsState } from "../stores/settings.svelte";
+
+  let canvas: HTMLCanvasElement;
+  let activeEffect: any;
+
+  function loadEffect() {
+    if (activeEffect) {
+      activeEffect.destroy();
+    }
+    
+    if (!canvas) return;
+
+    if (settingsState.settings.active_effect === "saturn") {
+      activeEffect = new SaturnEffect(canvas);
+    } else {
+      activeEffect = new ConstellationEffect(canvas);
+    }
+    
+    // Ensure correct size immediately
+    activeEffect.resize(window.innerWidth, window.innerHeight);
+  }
+
+  $effect(() => {
+    const _ = settingsState.settings.active_effect;
+    if (canvas) {
+        loadEffect();
+    }
+  });
+
+  onMount(() => {
+    const resizeObserver = new ResizeObserver(() => {
+      if (canvas && activeEffect) {
+         activeEffect.resize(window.innerWidth, window.innerHeight);
+      }
+    });
+    
+    resizeObserver.observe(document.body);
+    
+    return () => {
+      resizeObserver.disconnect();
+      if (activeEffect) activeEffect.destroy();
+    };
+  });
+  
+  onDestroy(() => {
+    if (activeEffect) activeEffect.destroy();
+  });
+</script>
+
+<canvas
+  bind:this={canvas}
+  class="absolute inset-0 z-0 pointer-events-none"
+></canvas>
diff --git a/ui/src/components/SettingsView.svelte b/ui/src/components/SettingsView.svelte
index 801970b..4c92220 100644
--- a/ui/src/components/SettingsView.svelte
+++ b/ui/src/components/SettingsView.svelte
@@ -1,150 +1,274 @@
 <script lang="ts">
   import { settingsState } from "../stores/settings.svelte";
+  import { open } from "@tauri-apps/plugin-dialog";
+  import { convertFileSrc } from "@tauri-apps/api/core";
+
+  async function selectBackground() {
+    try {
+      const selected = await open({
+        multiple: false,
+        filters: [
+          {
+            name: "Images",
+            extensions: ["png", "jpg", "jpeg", "webp", "gif"],
+          },
+        ],
+      });
+
+      if (selected && typeof selected === "string") {
+        settingsState.settings.custom_background_path = selected;
+        settingsState.saveSettings();
+      }
+    } catch (e) {
+      console.error("Failed to select background:", e);
+    }
+  }
+
+  function clearBackground() {
+    settingsState.settings.custom_background_path = undefined;
+    settingsState.saveSettings();
+  }
 </script>
 
-<div class="p-8 bg-zinc-900 h-full overflow-y-auto">
-  <h2 class="text-3xl font-bold mb-8">Settings</h2>
+<div class="h-full flex flex-col p-6 overflow-hidden">
+  <div class="flex items-center justify-between mb-6">
+     <h2 class="text-3xl font-black bg-clip-text text-transparent bg-gradient-to-r from-white to-white/60">Settings</h2>
+  </div>
+
+  <div class="flex-1 overflow-y-auto pr-2 space-y-6 custom-scrollbar pb-10">
 
-  <div class="space-y-6 max-w-2xl">
-    <!-- Java Path -->
-    <div class="bg-zinc-800/50 p-6 rounded-lg border border-zinc-700">
-      <label
-        for="java-path"
-        class="block text-sm font-bold text-zinc-400 mb-2 uppercase tracking-wide"
-        >Java Executable Path</label
-      >
-      <div class="flex gap-2">
-        <input
-          id="java-path"
-          bind:value={settingsState.settings.java_path}
-          type="text"
-          class="bg-zinc-950 text-white flex-1 p-3 rounded border border-zinc-700 focus:border-indigo-500 outline-none font-mono text-sm"
-          placeholder="e.g. java, /usr/bin/java"
-        />
-        <button
-          onclick={() => settingsState.detectJava()}
-          disabled={settingsState.isDetectingJava}
-          class="bg-zinc-700 hover:bg-zinc-600 disabled:opacity-50 text-white px-4 py-2 rounded transition-colors whitespace-nowrap"
-        >
-          {settingsState.isDetectingJava ? "Detecting..." : "Auto Detect"}
-        </button>
+    <!-- Appearance / Background -->
+    <div class="bg-black/20 p-6 rounded-2xl border border-white/5 ">
+      <h3 class="text-xs font-bold uppercase tracking-widest text-white/40 mb-6 flex items-center gap-2">
+        Appearance
+      </h3>
+      
+      <div class="space-y-4">
+        <div>
+          <label class="block text-sm font-medium text-white/70 mb-3">Custom Background Image</label>
+          
+          <div class="flex items-center gap-6">
+            <!-- Preview -->
+            <div class="w-40 h-24 rounded-xl overflow-hidden bg-black/50 border border-white/10 relative group shadow-lg">
+              {#if settingsState.settings.custom_background_path}
+                <img 
+                  src={convertFileSrc(settingsState.settings.custom_background_path)} 
+                  alt="Background Preview" 
+                  class="w-full h-full object-cover"
+                />
+              {:else}
+                <div class="w-full h-full bg-gradient-to-br from-emerald-900 via-zinc-900 to-indigo-950 opacity-100"></div>
+                <div class="absolute inset-0 flex items-center justify-center text-[10px] text-white/50 bg-black/20 ">Default Gradient</div>
+              {/if}
+            </div>
+
+            <!-- Actions -->
+            <div class="flex flex-col gap-2">
+              <button
+                onclick={selectBackground}
+                class="bg-white/10 hover:bg-white/20 text-white px-4 py-2 rounded-lg text-sm transition-colors border border-white/5"
+              >
+                Select Image
+              </button>
+              
+              {#if settingsState.settings.custom_background_path}
+                <button
+                  onclick={clearBackground}
+                  class="text-red-400 hover:text-red-300 text-sm px-4 py-1 text-left transition-colors"
+                >
+                  Reset to Default
+                </button>
+              {/if}
+            </div>
+          </div>
+          <p class="text-xs text-white/30 mt-3">
+            Select an image from your computer to replace the default gradient background.
+            Supported formats: PNG, JPG, WEBP, GIF.
+          </p>
+        </div>
+
+        <!-- Visual Settings -->
+        <div class="pt-4 border-t border-white/5 space-y-4">
+             <div class="flex items-center justify-between">
+                <div>
+                   <h4 class="text-sm font-medium text-white/90" id="visual-effects-label">Visual Effects</h4>
+                   <p class="text-xs text-white/40 mt-1">Enable particle effects and animated gradients. (Default: On)</p>
+                </div>
+                <button 
+                    aria-labelledby="visual-effects-label"
+                    onclick={() => { settingsState.settings.enable_visual_effects = !settingsState.settings.enable_visual_effects; settingsState.saveSettings(); }}
+                    class="w-11 h-6 rounded-full transition-colors duration-200 ease-in-out relative focus:outline-none {settingsState.settings.enable_visual_effects ? 'bg-indigo-500' : 'bg-white/10'}"
+                >
+                    <div class="absolute top-1 left-1 bg-white w-4 h-4 rounded-full shadow-sm transition-transform duration-200 ease-in-out {settingsState.settings.enable_visual_effects ? 'translate-x-5' : 'translate-x-0'}"></div>
+                </button>
+             </div>
+
+             {#if settingsState.settings.enable_visual_effects}
+                 <div class="flex items-center justify-between pl-2 border-l-2 border-white/5 ml-1">
+                    <div>
+                       <h4 class="text-sm font-medium text-white/90" id="theme-effect-label">Theme Effect</h4>
+                       <p class="text-xs text-white/40 mt-1">Select the active visual theme.</p>
+                    </div>
+                    <select
+                        aria-labelledby="theme-effect-label"
+                        bind:value={settingsState.settings.active_effect}
+                        onchange={() => settingsState.saveSettings()}
+                        class="bg-black/40 text-white text-xs px-3 py-2 rounded-lg border border-white/10 outline-none focus:border-indigo-500/50 appearance-none cursor-pointer hover:bg-white/5 transition-colors"
+                    >
+                        <option value="saturn">Saturn (Saturn)</option>
+                        <option value="constellation">Network (Constellation)</option>
+                    </select>
+                 </div>
+             {/if}
+
+             <div class="flex items-center justify-between">
+                <div>
+                   <h4 class="text-sm font-medium text-white/90" id="gpu-acceleration-label">GPU Acceleration</h4>
+                   <p class="text-xs text-white/40 mt-1">Enable GPU acceleration for the interface. (Default: Off, Requires Restart)</p>
+                </div>
+                <button 
+                    aria-labelledby="gpu-acceleration-label"
+                    onclick={() => { settingsState.settings.enable_gpu_acceleration = !settingsState.settings.enable_gpu_acceleration; settingsState.saveSettings(); }}
+                    class="w-11 h-6 rounded-full transition-colors duration-200 ease-in-out relative focus:outline-none {settingsState.settings.enable_gpu_acceleration ? 'bg-indigo-500' : 'bg-white/10'}"
+                >
+                    <div class="absolute top-1 left-1 bg-white w-4 h-4 rounded-full shadow-sm transition-transform duration-200 ease-in-out {settingsState.settings.enable_gpu_acceleration ? 'translate-x-5' : 'translate-x-0'}"></div>
+                </button>
+             </div>
+        </div>
       </div>
+    </div>
+
+    <!-- Java Path -->
+    <div class="bg-black/20 p-6 rounded-2xl border border-white/5 ">
+      <h3 class="text-xs font-bold uppercase tracking-widest text-white/40 mb-6 flex items-center gap-2">
+        Java Environment
+      </h3>
+      <div class="space-y-4">
+        <div>
+             <label for="java-path" class="block text-sm font-medium text-white/70 mb-2">Java Executable Path</label>
+             <div class="flex gap-2">
+                <input
+                id="java-path"
+                bind:value={settingsState.settings.java_path}
+                type="text"
+                class="bg-black/40 text-white flex-1 px-4 py-3 rounded-xl border border-white/10 focus:border-indigo-500/50 outline-none font-mono text-xs transition-colors"
+                placeholder="e.g. java, /usr/bin/java"
+                />
+                <button
+                onclick={() => settingsState.detectJava()}
+                disabled={settingsState.isDetectingJava}
+                class="bg-white/10 hover:bg-white/20 disabled:opacity-50 text-white px-4 py-2 rounded-xl border border-white/5 transition-colors whitespace-nowrap text-sm font-medium"
+                >
+                {settingsState.isDetectingJava ? "Detecting..." : "Auto Detect"}
+                </button>
+            </div>
+        </div>
       
       {#if settingsState.javaInstallations.length > 0}
         <div class="mt-4 space-y-2">
-          <p class="text-xs text-zinc-400 uppercase font-bold">Detected Java Installations:</p>
+          <p class="text-[10px] text-white/30 uppercase font-bold tracking-wider">Detected Installations</p>
           {#each settingsState.javaInstallations as java}
             <button
               onclick={() => settingsState.selectJava(java.path)}
-              class="w-full text-left p-3 bg-zinc-950 rounded border transition-colors {settingsState.settings.java_path === java.path ? 'border-indigo-500 bg-indigo-950/30' : 'border-zinc-700 hover:border-zinc-500'}"
+              class="w-full text-left p-3 rounded-lg border transition-all duration-200 group
+              {settingsState.settings.java_path === java.path 
+                ? 'bg-indigo-500/20 border-indigo-500/30' 
+                : 'bg-black/20 border-white/5 hover:bg-white/5 hover:border-white/10'}"
             >
               <div class="flex justify-between items-center">
                 <div>
-                  <span class="text-white font-mono text-sm">{java.version}</span>
-                  <span class="text-zinc-500 text-xs ml-2">{java.is_64bit ? "64-bit" : "32-bit"}</span>
+                  <span class="text-white font-mono text-xs font-bold">{java.version}</span>
+                  <span class="text-white/40 text-[10px] ml-2">{java.is_64bit ? "64-bit" : "32-bit"}</span>
                 </div>
                 {#if settingsState.settings.java_path === java.path}
-                  <span class="text-indigo-400 text-xs">Selected</span>
+                  <span class="text-indigo-300 text-[10px] font-bold uppercase tracking-wider">Selected</span>
                 {/if}
               </div>
-              <div class="text-zinc-500 text-xs font-mono truncate mt-1">{java.path}</div>
+              <div class="text-white/30 text-[10px] font-mono truncate mt-1 group-hover:text-white/50">{java.path}</div>
             </button>
           {/each}
         </div>
       {/if}
-      
-      <p class="text-xs text-zinc-500 mt-2">
-        The command or path to the Java Runtime Environment. Click "Auto Detect" to find installed Java versions.
-      </p>
+      </div>
     </div>
 
     <!-- Memory -->
-    <div class="bg-zinc-800/50 p-6 rounded-lg border border-zinc-700">
-      <h3
-        class="block text-sm font-bold text-zinc-400 mb-4 uppercase tracking-wide"
-        >Memory Allocation (RAM)</h3>
-
+    <div class="bg-black/20 p-6 rounded-2xl border border-white/5 ">
+      <h3 class="text-xs font-bold uppercase tracking-widest text-white/40 mb-6 flex items-center gap-2">
+        Memory Allocation (RAM)
+      </h3>
       <div class="grid grid-cols-2 gap-6">
         <div>
-          <label for="min-memory" class="block text-xs text-zinc-500 mb-1"
-            >Minimum (MB)</label
-          >
+          <label for="min-memory" class="block text-sm font-medium text-white/70 mb-2">Minimum (MB)</label>
           <input
             id="min-memory"
             bind:value={settingsState.settings.min_memory}
             type="number"
-            class="bg-zinc-950 text-white w-full p-3 rounded border border-zinc-700 focus:border-indigo-500 outline-none"
+            class="bg-black/40 text-white w-full px-4 py-3 rounded-xl border border-white/10 focus:border-indigo-500/50 outline-none transition-colors"
           />
         </div>
         <div>
-          <label for="max-memory" class="block text-xs text-zinc-500 mb-1"
-            >Maximum (MB)</label
-          >
+          <label for="max-memory" class="block text-sm font-medium text-white/70 mb-2">Maximum (MB)</label>
           <input
             id="max-memory"
             bind:value={settingsState.settings.max_memory}
             type="number"
-            class="bg-zinc-950 text-white w-full p-3 rounded border border-zinc-700 focus:border-indigo-500 outline-none"
+            class="bg-black/40 text-white w-full px-4 py-3 rounded-xl border border-white/10 focus:border-indigo-500/50 outline-none transition-colors"
           />
         </div>
       </div>
     </div>
 
     <!-- Resolution -->
-    <div class="bg-zinc-800/50 p-6 rounded-lg border border-zinc-700">
-      <h3
-        class="block text-sm font-bold text-zinc-400 mb-4 uppercase tracking-wide"
-        >Game Window Size</h3>
+    <div class="bg-black/20 p-6 rounded-2xl border border-white/5 ">
+      <h3 class="text-xs font-bold uppercase tracking-widest text-white/40 mb-6 flex items-center gap-2">
+        Game Window Size
+      </h3>
       <div class="grid grid-cols-2 gap-6">
         <div>
-          <label for="window-width" class="block text-xs text-zinc-500 mb-1">Width</label>
+          <label for="window-width" class="block text-sm font-medium text-white/70 mb-2">Width</label>
           <input
             id="window-width"
             bind:value={settingsState.settings.width}
             type="number"
-            class="bg-zinc-950 text-white w-full p-3 rounded border border-zinc-700 focus:border-indigo-500 outline-none"
+            class="bg-black/40 text-white w-full px-4 py-3 rounded-xl border border-white/10 focus:border-indigo-500/50 outline-none transition-colors"
           />
         </div>
         <div>
-          <label for="window-height" class="block text-xs text-zinc-500 mb-1">Height</label>
+          <label for="window-height" class="block text-sm font-medium text-white/70 mb-2">Height</label>
           <input
             id="window-height"
             bind:value={settingsState.settings.height}
             type="number"
-            class="bg-zinc-950 text-white w-full p-3 rounded border border-zinc-700 focus:border-indigo-500 outline-none"
+            class="bg-black/40 text-white w-full px-4 py-3 rounded-xl border border-white/10 focus:border-indigo-500/50 outline-none transition-colors"
           />
         </div>
       </div>
     </div>
 
     <!-- Download Settings -->
-    <div class="bg-zinc-800/50 p-6 rounded-lg border border-zinc-700">
-      <h3
-        class="block text-sm font-bold text-zinc-400 mb-4 uppercase tracking-wide"
-        >Download Settings</h3>
-      <div>
-        <label for="download-threads" class="block text-xs text-zinc-500 mb-1"
-          >Concurrent Download Threads</label
-        >
-        <input
-          id="download-threads"
-          bind:value={settingsState.settings.download_threads}
-          type="number"
-          min="1"
-          max="128"
-          step="1"
-          class="bg-zinc-950 text-white w-full p-3 rounded border border-zinc-700 focus:border-indigo-500 outline-none"
-        />
-        <p class="text-xs text-zinc-500 mt-2">
-          Number of concurrent download threads (1-128). Higher values increase download speed but use more bandwidth and system resources. Default: 32
-        </p>
-      </div>
+    <div class="bg-black/20 p-6 rounded-2xl border border-white/5 ">
+        <h3 class="text-xs font-bold uppercase tracking-widest text-white/40 mb-6 flex items-center gap-2">
+            Network
+        </h3>
+        <div>
+            <label for="download-threads" class="block text-sm font-medium text-white/70 mb-2">Concurrent Download Threads</label>
+            <input
+              id="download-threads"
+              bind:value={settingsState.settings.download_threads}
+              type="number"
+              min="1"
+              max="128"
+              class="bg-black/40 text-white w-full px-4 py-3 rounded-xl border border-white/10 focus:border-indigo-500/50 outline-none transition-colors"
+            />
+            <p class="text-xs text-white/30 mt-2">Higher values usually mean faster downloads but use more CPU/Network.</p>
+        </div>
     </div>
 
-    <div class="pt-4">
+    <div class="pt-4 flex justify-end">
       <button
         onclick={() => settingsState.saveSettings()}
-        class="bg-indigo-600 hover:bg-indigo-500 text-white font-bold py-3 px-8 rounded shadow-lg transition-transform active:scale-95"
+        class="bg-gradient-to-r from-emerald-600 to-green-600 hover:from-emerald-500 hover:to-green-500 text-white font-bold py-3 px-8 rounded-xl shadow-lg shadow-emerald-500/20 transition-all hover:scale-105 active:scale-95"
       >
         Save Settings
       </button>
diff --git a/ui/src/components/Sidebar.svelte b/ui/src/components/Sidebar.svelte
index a4f4e35..7976f6a 100644
--- a/ui/src/components/Sidebar.svelte
+++ b/ui/src/components/Sidebar.svelte
@@ -3,64 +3,56 @@
 </script>
 
 <aside
-  class="w-20 lg:w-64 bg-zinc-950 flex flex-col items-center lg:items-start transition-all duration-300 border-r border-zinc-800 shrink-0"
+  class="w-20 lg:w-64 bg-black flex flex-col items-center lg:items-start transition-all duration-300 shrink-0 py-6"
 >
+  <!-- Logo Area -->
   <div
-    class="h-20 w-full flex items-center justify-center lg:justify-start lg:px-6 border-b border-zinc-800/50"
+    class="h-16 w-full flex items-center justify-center lg:justify-start lg:px-8 mb-6"
   >
-    <!-- Icon Logo (Visible on small) -->
+    <!-- Icon Logo (Small) -->
     <div
-      class="lg:hidden text-2xl font-black bg-clip-text text-transparent bg-gradient-to-tr from-indigo-400 to-purple-400"
+      class="lg:hidden text-3xl font-black bg-clip-text text-transparent bg-gradient-to-tr from-indigo-400 to-fuchsia-400 drop-shadow-lg"
     >
       D
     </div>
-    <!-- Full Logo (Visible on large) -->
+    <!-- Full Logo (Large) -->
     <div
-      class="hidden lg:block font-bold text-xl tracking-wider text-indigo-400"
+      class="hidden lg:block font-bold text-2xl tracking-wider text-white"
     >
-      DROP<span class="text-white">OUT</span>
+      <span class="bg-clip-text text-transparent bg-gradient-to-r from-indigo-400 to-fuchsia-400">DROP</span>OUT
     </div>
   </div>
 
-  <nav class="flex-1 w-full flex flex-col gap-2 p-3">
-    <button
-      class="group flex items-center lg:gap-4 justify-center lg:justify-start w-full px-0 lg:px-4 py-3 rounded-lg hover:bg-zinc-800 {uiState.currentView ===
-      'home'
-        ? 'bg-zinc-800/80 text-white'
-        : 'text-zinc-400'} transition-all relative"
-      onclick={() => uiState.setView("home")}
-    >
-      <span class="text-xl relative z-10">🏠</span>
-      <span
-        class="hidden lg:block font-medium relative z-10 transition-opacity"
-        >Home</span
+  <!-- Navigation -->
+  <nav class="flex-1 w-full flex flex-col gap-3 px-3">
+    <!-- Nav Item Helper -->
+    {#snippet navItem(view, icon, label)}
+      <button
+        class="group flex items-center lg:gap-4 justify-center lg:justify-start w-full px-0 lg:px-5 py-3.5 rounded-xl transition-all duration-200 relative overflow-hidden
+        {uiState.currentView === view
+          ? 'bg-gradient-to-r from-indigo-500/20 to-purple-500/20 text-white shadow-lg shadow-indigo-500/10 border border-white/10'
+          : 'text-zinc-400 hover:text-white hover:bg-white/5'}"
+        onclick={() => uiState.setView(view)}
       >
-    </button>
-    <button
-      class="group flex items-center lg:gap-4 justify-center lg:justify-start w-full px-0 lg:px-4 py-3 rounded-lg hover:bg-zinc-800 {uiState.currentView ===
-      'versions'
-        ? 'bg-zinc-800/80 text-white'
-        : 'text-zinc-400'} transition-all"
-      onclick={() => uiState.setView("versions")}
-    >
-      <span class="text-xl">📦</span>
-      <span class="hidden lg:block font-medium">Versions</span>
-    </button>
-    <button
-      class="group flex items-center lg:gap-4 justify-center lg:justify-start w-full px-0 lg:px-4 py-3 rounded-lg hover:bg-zinc-800 {uiState.currentView ===
-      'settings'
-        ? 'bg-zinc-800/80 text-white'
-        : 'text-zinc-400'} transition-all"
-      onclick={() => uiState.setView("settings")}
-    >
-      <span class="text-xl">⚙️</span>
-      <span class="hidden lg:block font-medium">Settings</span>
-    </button>
+        <span class="text-xl relative z-10 transition-transform group-hover:scale-110 duration-200">{icon}</span>
+        <span class="hidden lg:block font-medium relative z-10">{label}</span>
+        
+        <!-- Active Indicator Line -->
+        {#if uiState.currentView === view}
+          <div class="absolute left-0 top-1/2 -translate-y-1/2 w-1 h-8 bg-indigo-500 rounded-r-full lg:hidden"></div>
+        {/if}
+      </button>
+    {/snippet}
+
+    {@render navItem('home', '🏠', 'Home')}
+    {@render navItem('versions', '📦', 'Versions')}
+    {@render navItem('settings', '⚙️', 'Settings')}
   </nav>
 
+  <!-- Footer Info -->
   <div
-    class="p-4 w-full border-t border-zinc-800 flex justify-center lg:justify-start"
+    class="p-4 w-full flex justify-center lg:justify-start lg:px-8 opacity-50 hover:opacity-100 transition-opacity"
   >
-    <div class="text-xs text-zinc-600 font-mono">v{uiState.appVersion}</div>
+    <div class="text-xs font-mono tracking-widest text-zinc-500">v{uiState.appVersion}</div>
   </div>
 </aside>
diff --git a/ui/src/components/VersionsView.svelte b/ui/src/components/VersionsView.svelte
index 1ea4878..00ac281 100644
--- a/ui/src/components/VersionsView.svelte
+++ b/ui/src/components/VersionsView.svelte
@@ -73,15 +73,15 @@
   function getVersionBadge(type: string) {
     switch (type) {
       case "release":
-        return { text: "Release", class: "bg-green-600" };
+        return { text: "Release", class: "bg-emerald-500/20 text-emerald-300 border-emerald-500/30" };
       case "snapshot":
-        return { text: "Snapshot", class: "bg-yellow-600" };
+        return { text: "Snapshot", class: "bg-amber-500/20 text-amber-300 border-amber-500/30" };
       case "fabric":
-        return { text: "Fabric", class: "bg-blue-600" };
+        return { text: "Fabric", class: "bg-indigo-500/20 text-indigo-300 border-indigo-500/30" };
       case "forge":
-        return { text: "Forge", class: "bg-orange-600" };
+        return { text: "Forge", class: "bg-orange-500/20 text-orange-300 border-orange-500/30" };
       default:
-        return { text: type, class: "bg-zinc-600" };
+        return { text: type, class: "bg-zinc-500/20 text-zinc-300 border-zinc-500/30" };
     }
   }
 
@@ -114,101 +114,92 @@
   });
 </script>
 
-<div class="p-8 h-full overflow-y-auto bg-zinc-900">
-  <h2 class="text-3xl font-bold mb-6">Versions</h2>
+<div class="h-full flex flex-col p-6 overflow-hidden">
+  <div class="flex items-center justify-between mb-6">
+     <h2 class="text-3xl font-black bg-clip-text text-transparent bg-gradient-to-r from-white to-white/60">Version Manager</h2>
+     <div class="text-sm text-white/40">Select a version to play or modify</div>
+  </div>
 
-  <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
+  <div class="flex-1 grid grid-cols-1 lg:grid-cols-3 gap-6 overflow-hidden">
     <!-- Left: Version List -->
-    <div class="lg:col-span-2 space-y-4">
-      <!-- Search and Filters -->
+    <div class="lg:col-span-2 flex flex-col gap-4 overflow-hidden">
+      <!-- Search and Filters (Glass Bar) -->
       <div class="flex gap-3">
-        <input
-          type="text"
-          placeholder="Search versions..."
-          class="flex-1 p-3 bg-zinc-800 border border-zinc-700 rounded text-white focus:outline-none focus:border-green-500 transition-colors"
-          bind:value={searchQuery}
-        />
+        <div class="relative flex-1">
+            <span class="absolute left-3 top-1/2 -translate-y-1/2 text-white/30">🔍</span>
+            <input
+              type="text"
+              placeholder="Search versions..."
+              class="w-full pl-9 pr-4 py-3 bg-black/20 border border-white/10 rounded-xl text-white placeholder-white/30 focus:outline-none focus:border-indigo-500/50 focus:bg-black/40 transition-all backdrop-blur-sm"
+              bind:value={searchQuery}
+            />
+        </div>
       </div>
 
-      <!-- Type Filter Tabs -->
-      <div class="flex gap-1 bg-zinc-800 rounded-lg p-1">
-        <button
-          class="flex-1 px-3 py-2 rounded-md text-sm font-medium transition-colors {typeFilter ===
-          'all'
-            ? 'bg-zinc-700 text-white'
-            : 'text-zinc-400 hover:text-white'}"
-          onclick={() => (typeFilter = "all")}
-        >
-          All
-        </button>
-        <button
-          class="flex-1 px-3 py-2 rounded-md text-sm font-medium transition-colors {typeFilter ===
-          'release'
-            ? 'bg-green-600 text-white'
-            : 'text-zinc-400 hover:text-white'}"
-          onclick={() => (typeFilter = "release")}
-        >
-          Releases
-        </button>
-        <button
-          class="flex-1 px-3 py-2 rounded-md text-sm font-medium transition-colors {typeFilter ===
-          'snapshot'
-            ? 'bg-yellow-600 text-white'
-            : 'text-zinc-400 hover:text-white'}"
-          onclick={() => (typeFilter = "snapshot")}
-        >
-          Snapshots
-        </button>
-        <button
-          class="flex-1 px-3 py-2 rounded-md text-sm font-medium transition-colors {typeFilter ===
-          'modded'
-            ? 'bg-purple-600 text-white'
-            : 'text-zinc-400 hover:text-white'}"
-          onclick={() => (typeFilter = "modded")}
-        >
-          Modded
-        </button>
+      <!-- Type Filter Tabs (Glass Caps) -->
+      <div class="flex p-1 bg-black/20 rounded-xl border border-white/5">
+        {#each ['all', 'release', 'snapshot', 'modded'] as filter}
+            <button
+            class="flex-1 px-3 py-2 rounded-lg text-sm font-medium transition-all duration-200 capitalize
+            {typeFilter === filter
+                ? 'bg-white/10 text-white shadow-lg border border-white/10'
+                : 'text-white/40 hover:text-white hover:bg-white/5'}"
+            onclick={() => (typeFilter = filter as any)}
+            >
+            {filter}
+            </button>
+        {/each}
       </div>
 
-      <!-- Version List -->
-      <div class="grid gap-2 max-h-[calc(100vh-320px)] overflow-y-auto pr-2">
+      <!-- Version List SCROLL -->
+      <div class="flex-1 overflow-y-auto pr-2 space-y-2 custom-scrollbar">
         {#if gameState.versions.length === 0}
-          <div class="text-zinc-500">Loading versions...</div>
+          <div class="flex items-center justify-center h-40 text-white/30 italic animate-pulse">
+             Fetching manifest...
+          </div>
         {:else if filteredVersions().length === 0}
-          <div class="text-zinc-500">
-            {#if normalizedQuery.length > 0}
-              No versions found matching "{searchQuery}"
-            {:else}
-              No versions in this category
-            {/if}
+          <div class="flex flex-col items-center justify-center -40 text-white/30 gap-2">
+             <span class="text-2xl">👻</span>
+             <span>No matching versions found</span>
           </div>
         {:else}
           {#each filteredVersions() as version}
             {@const badge = getVersionBadge(version.type)}
+            {@const isSelected = gameState.selectedVersion === version.id}
             <button
-              class="flex items-center justify-between p-4 bg-zinc-800 rounded hover:bg-zinc-700 transition text-left border border-zinc-700 {gameState.selectedVersion ===
-              version.id
-                ? 'border-green-500 bg-zinc-800/80 ring-1 ring-green-500'
-                : ''}"
+              class="w-full group flex items-center justify-between p-4 rounded-xl text-left border transition-all duration-200 relative overflow-hidden
+              {isSelected
+                ? 'bg-indigo-600/20 border-indigo-500/50 shadow-[0_0_20px_rgba(99,102,241,0.2)]'
+                : 'bg-white/5 border-white/5 hover:bg-white/10 hover:border-white/10 hover:translate-x-1'}"
               onclick={() => (gameState.selectedVersion = version.id)}
             >
-              <div class="flex items-center gap-3">
+              <!-- Selection Glow -->
+              {#if isSelected}
+                 <div class="absolute inset-0 bg-gradient-to-r from-indigo-500/10 to-transparent pointer-events-none"></div>
+              {/if}
+
+              <div class="relative z-10 flex items-center gap-4">
                 <span
-                  class="px-2 py-0.5 rounded text-xs font-medium {badge.class}"
+                  class="px-2.5 py-0.5 rounded-full text-[10px] font-bold uppercase tracking-wide border {badge.class}"
                 >
                   {badge.text}
                 </span>
                 <div>
-                  <div class="font-bold font-mono">{version.id}</div>
+                  <div class="font-bold font-mono text-lg tracking-tight {isSelected ? 'text-white' : 'text-zinc-300 group-hover:text-white'}">
+                    {version.id}
+                  </div>
                   {#if version.releaseTime && version.type !== "fabric" && version.type !== "forge"}
-                    <div class="text-xs text-zinc-400">
+                    <div class="text-xs text-white/30">
                       {new Date(version.releaseTime).toLocaleDateString()}
                     </div>
                   {/if}
                 </div>
               </div>
-              {#if gameState.selectedVersion === version.id}
-                <div class="text-green-500 font-bold text-sm">SELECTED</div>
+              
+              {#if isSelected}
+                <div class="relative z-10 text-indigo-400">
+                   <span class="text-lg">Selected</span>
+                </div>
               {/if}
             </button>
           {/each}
@@ -217,32 +208,29 @@
     </div>
 
     <!-- Right: Mod Loader Panel -->
-    <div class="space-y-4">
-      <!-- Selected Version Info -->
-      {#if gameState.selectedVersion}
-        <div class="bg-zinc-800 rounded-lg p-4 border border-zinc-700">
-          <h3 class="text-sm font-semibold text-zinc-400 mb-2">Selected</h3>
-          <p class="font-mono text-lg text-green-400">
-            {gameState.selectedVersion}
-          </p>
-        </div>
-      {/if}
-
-      <!-- Mod Loader Selector -->
-      <ModLoaderSelector
-        selectedGameVersion={selectedBaseVersion()}
-        onInstall={handleModLoaderInstall}
-      />
-
-      <!-- Help Text -->
-      <div class="bg-zinc-800/50 rounded-lg p-4 border border-zinc-700/50">
-        <h4 class="text-sm font-semibold text-zinc-400 mb-2">💡 Tip</h4>
-        <p class="text-xs text-zinc-500">
-          Select a vanilla Minecraft version, then use the Mod Loader panel to
-          install Fabric or Forge. Installed modded versions will appear in the
-          list with colored badges.
-        </p>
+    <div class="flex flex-col gap-4">
+      <!-- Selected Version Info Card -->
+      <div class="bg-gradient-to-br from-white/10 to-white/5 p-6 rounded-2xl border border-white/10 backdrop-blur-md relative overflow-hidden group">
+          <div class="absolute top-0 right-0 p-8 bg-indigo-500/20 blur-[60px] rounded-full group-hover:bg-indigo-500/30 transition-colors"></div>
+          
+          <h3 class="text-xs font-bold uppercase tracking-widest text-white/40 mb-2 relative z-10">Current Selection</h3>
+          {#if gameState.selectedVersion}
+            <p class="font-mono text-3xl font-black text-transparent bg-clip-text bg-gradient-to-r from-white to-white/70 relative z-10 truncate">
+                {gameState.selectedVersion}
+            </p>
+          {:else}
+            <p class="text-white/20 italic relative z-10">None selected</p>
+          {/if}
       </div>
+
+      <!-- Mod Loader Selector Card -->
+      <div class="bg-black/20 p-4 rounded-2xl border border-white/5 backdrop-blur-sm flex-1 flex flex-col">
+          <ModLoaderSelector
+            selectedGameVersion={selectedBaseVersion()}
+            onInstall={handleModLoaderInstall}
+          />
+      </div>
+
     </div>
   </div>
 </div>
diff --git a/ui/src/lib/DownloadMonitor.svelte b/ui/src/lib/DownloadMonitor.svelte
index 52c935c..860952c 100644
--- a/ui/src/lib/DownloadMonitor.svelte
+++ b/ui/src/lib/DownloadMonitor.svelte
@@ -156,7 +156,7 @@
 
 {#if visible}
   <div
-    class="fixed bottom-28 right-8 z-50 w-80 bg-zinc-900/90 backdrop-blur-md border border-zinc-700 rounded-lg shadow-2xl p-4 animate-in slide-in-from-right-10 fade-in duration-300"
+    class="fixed bottom-28 right-8 z-50 w-80 bg-zinc-900/90  border border-zinc-700 rounded-lg shadow-2xl p-4 animate-in slide-in-from-right-10 fade-in duration-300"
   >
     <div class="flex items-center justify-between mb-2">
       <h3 class="text-white font-bold text-sm">Downloads</h3>
diff --git a/ui/src/lib/GameConsole.svelte b/ui/src/lib/GameConsole.svelte
index 281dc85..8d5e0ce 100644
--- a/ui/src/lib/GameConsole.svelte
+++ b/ui/src/lib/GameConsole.svelte
@@ -75,7 +75,7 @@
 </script>
 
 {#if visible}
-<div class="fixed bottom-0 left-0 right-0 h-64 bg-zinc-950/95 border-t border-zinc-700 backdrop-blur flex flex-col z-50 transition-transform duration-300 transform translate-y-0">
+<div class="fixed bottom-0 left-0 right-0 h-64 bg-zinc-950/95 border-t border-zinc-700  flex flex-col z-50 transition-transform duration-300 transform translate-y-0">
   <div class="flex items-center justify-between px-4 py-2 border-b border-zinc-800 bg-zinc-900/50">
     <div class="flex items-center gap-4">
       <span class="text-xs font-bold text-zinc-400 uppercase tracking-widest">Logs</span>
diff --git a/ui/src/lib/effects/ConstellationEffect.ts b/ui/src/lib/effects/ConstellationEffect.ts
new file mode 100644
index 0000000..2cc702e
--- /dev/null
+++ b/ui/src/lib/effects/ConstellationEffect.ts
@@ -0,0 +1,163 @@
+
+export class ConstellationEffect {
+  private canvas: HTMLCanvasElement;
+  private ctx: CanvasRenderingContext2D;
+  private width: number = 0;
+  private height: number = 0;
+  private particles: Particle[] = [];
+  private animationId: number = 0;
+  private mouseX: number = -1000;
+  private mouseY: number = -1000;
+
+  // Configuration
+  private readonly particleCount = 100;
+  private readonly connectionDistance = 150;
+  private readonly particleSpeed = 0.5;
+
+  constructor(canvas: HTMLCanvasElement) {
+    this.canvas = canvas;
+    this.ctx = canvas.getContext("2d", { alpha: true })!;
+    
+    // Bind methods
+    this.animate = this.animate.bind(this);
+    this.handleMouseMove = this.handleMouseMove.bind(this);
+
+    // Initial setup
+    this.resize(window.innerWidth, window.innerHeight);
+    this.initParticles();
+    
+    // Mouse interaction
+    window.addEventListener("mousemove", this.handleMouseMove);
+
+    // Start animation
+    this.animate();
+  }
+
+  resize(width: number, height: number) {
+    const dpr = window.devicePixelRatio || 1;
+    this.width = width;
+    this.height = height;
+
+    this.canvas.width = width * dpr;
+    this.canvas.height = height * dpr;
+    this.canvas.style.width = `${width}px`;
+    this.canvas.style.height = `${height}px`;
+
+    this.ctx.scale(dpr, dpr);
+    
+    // Re-initialize if screen size changes significantly to maintain density
+    if (this.particles.length === 0) {
+        this.initParticles();
+    }
+  }
+
+  private initParticles() {
+    this.particles = [];
+    // Adjust density based on screen area
+    const area = this.width * this.height;
+    const density = Math.floor(area / 15000); // 1 particle per 15000px²
+    const count = Math.min(Math.max(density, 50), 200); // Clamp between 50 and 200
+
+    for (let i = 0; i < count; i++) {
+      this.particles.push(new Particle(this.width, this.height, this.particleSpeed));
+    }
+  }
+
+  private handleMouseMove(e: MouseEvent) {
+    const rect = this.canvas.getBoundingClientRect();
+    this.mouseX = e.clientX - rect.left;
+    this.mouseY = e.clientY - rect.top;
+  }
+
+  animate() {
+    this.ctx.clearRect(0, 0, this.width, this.height);
+    
+    // Update and draw particles
+    this.particles.forEach(p => {
+      p.update(this.width, this.height);
+      p.draw(this.ctx);
+    });
+
+    // Draw lines
+    this.drawConnections();
+
+    this.animationId = requestAnimationFrame(this.animate);
+  }
+
+  private drawConnections() {
+    this.ctx.lineWidth = 1;
+    
+    for (let i = 0; i < this.particles.length; i++) {
+        const p1 = this.particles[i];
+        
+        // Connect to mouse if close
+        const distMouse = Math.hypot(p1.x - this.mouseX, p1.y - this.mouseY);
+        if (distMouse < this.connectionDistance + 50) {
+            const alpha = 1 - (distMouse / (this.connectionDistance + 50));
+            this.ctx.strokeStyle = `rgba(255, 255, 255, ${alpha * 0.4})`; // Brighter near mouse
+            this.ctx.beginPath();
+            this.ctx.moveTo(p1.x, p1.y);
+            this.ctx.lineTo(this.mouseX, this.mouseY);
+            this.ctx.stroke();
+            
+            // Gently attract to mouse
+            if (distMouse > 10) {
+                p1.x += (this.mouseX - p1.x) * 0.005;
+                p1.y += (this.mouseY - p1.y) * 0.005;
+            }
+        }
+
+        // Connect to other particles
+        for (let j = i + 1; j < this.particles.length; j++) {
+            const p2 = this.particles[j];
+            const dist = Math.hypot(p1.x - p2.x, p1.y - p2.y);
+
+            if (dist < this.connectionDistance) {
+                const alpha = 1 - (dist / this.connectionDistance);
+                this.ctx.strokeStyle = `rgba(255, 255, 255, ${alpha * 0.15})`;
+                this.ctx.beginPath();
+                this.ctx.moveTo(p1.x, p1.y);
+                this.ctx.lineTo(p2.x, p2.y);
+                this.ctx.stroke();
+            }
+        }
+    }
+  }
+
+  destroy() {
+    cancelAnimationFrame(this.animationId);
+    window.removeEventListener("mousemove", this.handleMouseMove);
+  }
+}
+
+class Particle {
+    x: number;
+    y: number;
+    vx: number;
+    vy: number;
+    size: number;
+
+    constructor(w: number, h: number, speed: number) {
+        this.x = Math.random() * w;
+        this.y = Math.random() * h;
+        this.vx = (Math.random() - 0.5) * speed;
+        this.vy = (Math.random() - 0.5) * speed;
+        this.size = Math.random() * 2 + 1;
+    }
+
+    update(w: number, h: number) {
+        this.x += this.vx;
+        this.y += this.vy;
+
+        // Bounce off walls
+        if (this.x < 0 || this.x > w) this.vx *= -1;
+        if (this.y < 0 || this.y > h) this.vy *= -1;
+    }
+
+    draw(ctx: CanvasRenderingContext2D) {
+        ctx.fillStyle = "rgba(255, 255, 255, 0.4)";
+        ctx.beginPath();
+        ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
+        ctx.fill();
+    }
+}
diff --git a/ui/src/lib/effects/SaturnEffect.ts b/ui/src/lib/effects/SaturnEffect.ts
new file mode 100644
index 0000000..8a1c11f
--- /dev/null
+++ b/ui/src/lib/effects/SaturnEffect.ts
@@ -0,0 +1,194 @@
+// Optimized Saturn Effect for low-end hardware
+// Uses TypedArrays for memory efficiency and reduced particle density
+
+export class SaturnEffect {
+  private canvas: HTMLCanvasElement;
+  private ctx: CanvasRenderingContext2D;
+  private width: number = 0;
+  private height: number = 0;
+  
+  // Data-oriented design for performance
+  // xyz: Float32Array where [i*3, i*3+1, i*3+2] corresponds to x, y, z
+  private xyz: Float32Array | null = null;
+  // types: Uint8Array where 0 = planet, 1 = ring
+  private types: Uint8Array | null = null;
+  private count: number = 0;
+
+  private animationId: number = 0;
+  private angle: number = 0;
+  private scaleFactor: number = 1;
+
+  constructor(canvas: HTMLCanvasElement) {
+    this.canvas = canvas;
+    this.ctx = canvas.getContext('2d', { 
+      alpha: true,
+      desynchronized: false // default is usually fine, 'desynchronized' can help latency but might flicker
+    })!;
+    
+    // Initial resize will set up everything
+    this.resize(window.innerWidth, window.innerHeight);
+    this.initParticles();
+    
+    this.animate = this.animate.bind(this);
+    this.animate();
+  }
+
+  resize(width: number, height: number) {
+    const dpr = window.devicePixelRatio || 1;
+    this.width = width;
+    this.height = height;
+    
+    this.canvas.width = width * dpr;
+    this.canvas.height = height * dpr;
+    this.canvas.style.width = `${width}px`;
+    this.canvas.style.height = `${height}px`;
+    
+    this.ctx.scale(dpr, dpr);
+
+    // Dynamic scaling based on screen size
+    const minDim = Math.min(width, height);
+    this.scaleFactor = minDim * 0.45; 
+  }
+
+  initParticles() {
+    // Significantly reduced particle count for CPU optimization
+    // Planet: 1800 -> 1000
+    // Rings: 5000 -> 2500
+    // Total approx 3500 vs 6800 previously (approx 50% reduction)
+    const planetCount = 1000;
+    const ringCount = 2500;
+    this.count = planetCount + ringCount;
+
+    // Use TypedArrays for better memory locality
+    this.xyz = new Float32Array(this.count * 3);
+    this.types = new Uint8Array(this.count);
+
+    let idx = 0;
+
+    // 1. Planet
+    for (let i = 0; i < planetCount; i++) {
+        const theta = Math.random() * Math.PI * 2;
+        const phi = Math.acos((Math.random() * 2) - 1);
+        const r = 1.0; 
+
+        // x, y, z
+        this.xyz[idx * 3]     = r * Math.sin(phi) * Math.cos(theta);
+        this.xyz[idx * 3 + 1] = r * Math.sin(phi) * Math.sin(theta);
+        this.xyz[idx * 3 + 2] = r * Math.cos(phi);
+        
+        this.types[idx] = 0; // 0 for planet
+        idx++;
+    }
+
+    // 2. Rings
+    const ringInner = 1.4; 
+    const ringOuter = 2.3;
+    
+    for (let i = 0; i < ringCount; i++) {
+        const angle = Math.random() * Math.PI * 2;
+        const dist = Math.sqrt(Math.random() * (ringOuter*ringOuter - ringInner*ringInner) + ringInner*ringInner);
+        
+        // x, y, z
+        this.xyz[idx * 3]     = dist * Math.cos(angle);
+        this.xyz[idx * 3 + 1] = (Math.random() - 0.5) * 0.05; 
+        this.xyz[idx * 3 + 2] = dist * Math.sin(angle);
+
+        this.types[idx] = 1; // 1 for ring
+        idx++;
+    }
+  }
+
+  animate() {
+    this.ctx.clearRect(0, 0, this.width, this.height);
+    
+    // Normal blending
+    this.ctx.globalCompositeOperation = 'source-over';
+    
+    // Slower rotation (from 0.0015 to 0.0005)
+    this.angle += 0.0005;
+
+    const cx = this.width * 0.6; 
+    const cy = this.height * 0.5;
+    
+    // Pre-calculate rotation matrices
+    const rotationY = this.angle;
+    const rotationX = 0.4; 
+    const rotationZ = 0.15;
+
+    const sinY = Math.sin(rotationY);
+    const cosY = Math.cos(rotationY);
+    const sinX = Math.sin(rotationX);
+    const cosX = Math.cos(rotationX);
+    const sinZ = Math.sin(rotationZ);
+    const cosZ = Math.cos(rotationZ);
+
+    const fov = 1500; 
+    const scaleFactor = this.scaleFactor;
+
+    if (!this.xyz || !this.types) return;
+
+    for (let i = 0; i < this.count; i++) {
+        const x = this.xyz[i * 3];
+        const y = this.xyz[i * 3 + 1];
+        const z = this.xyz[i * 3 + 2];
+
+        // Apply Scale
+        const px = x * scaleFactor;
+        const py = y * scaleFactor;
+        const pz = z * scaleFactor;
+
+        // 1. Rotate Y
+        const x1 = px * cosY - pz * sinY;
+        const z1 = pz * cosY + px * sinY;
+        // y1 = py
+
+        // 2. Rotate X
+        const y2 = py * cosX - z1 * sinX;
+        const z2 = z1 * cosX + py * sinX;
+        // x2 = x1
+
+        // 3. Rotate Z
+        const x3 = x1 * cosZ - y2 * sinZ;
+        const y3 = y2 * cosZ + x1 * sinZ;
+        const z3 = z2;
+
+        const scale = fov / (fov + z3);
+        
+        if (z3 > -fov) {
+            const x2d = cx + x3 * scale;
+            const y2d = cy + y3 * scale;
+
+            // Size calculation - slightly larger dots to compensate for lower count
+            // Previously Planet 2.0 -> 2.4, Ring 1.3 -> 1.5
+            const type = this.types[i];
+            const sizeBase = type === 0 ? 2.4 : 1.5;
+            const size = sizeBase * scale;
+
+            // Opacity
+            let alpha = (scale * scale * scale);
+            if (alpha > 1) alpha = 1;
+            if (alpha < 0.15) continue; // Skip very faint particles for performance
+
+            // Optimization: Planet color vs Ring color
+            if (type === 0) {
+               // Planet: Warn White
+               this.ctx.fillStyle = `rgba(255, 240, 220, ${alpha})`;
+            } else {
+               // Ring: Cool White
+               this.ctx.fillStyle = `rgba(220, 240, 255, ${alpha})`;
+            }
+            
+            // Render as squares (fillRect) instead of circles (arc)
+            // This is significantly faster for software rendering and reduces GPU usage.
+            this.ctx.fillRect(x2d, y2d, size, size);
+        }
+    }
+
+    this.animationId = requestAnimationFrame(this.animate);
+  }
+
+  destroy() {
+    cancelAnimationFrame(this.animationId);
+  }
+}
+
diff --git a/ui/src/stores/settings.svelte.ts b/ui/src/stores/settings.svelte.ts
index 397b9a6..c59bf3c 100644
--- a/ui/src/stores/settings.svelte.ts
+++ b/ui/src/stores/settings.svelte.ts
@@ -10,6 +10,9 @@ export class SettingsState {
     width: 854,
     height: 480,
     download_threads: 32,
+    enable_gpu_acceleration: false,
+    enable_visual_effects: true,
+    active_effect: "constellation",
   });
   javaInstallations = $state<JavaInstallation[]>([]);
   isDetectingJava = $state(false);
diff --git a/ui/src/types/index.ts b/ui/src/types/index.ts
index 933aab5..fa48075 100644
--- a/ui/src/types/index.ts
+++ b/ui/src/types/index.ts
@@ -30,6 +30,10 @@ export interface LauncherConfig {
   width: number;
   height: number;
   download_threads: number;
+  custom_background_path?: string;
+  enable_gpu_acceleration: boolean;
+  enable_visual_effects: boolean;
+  active_effect: string;
 }
 
 export interface JavaInstallation {
-- 
cgit v1.2.3-70-g09d2


From 74849ad2d18586736d9677dfd10af4875f4ef2ca Mon Sep 17 00:00:00 2001
From: HsiangNianian <i@jyunko.cn>
Date: Wed, 14 Jan 2026 18:40:01 +0800
Subject: feat: enhance dark mode support across UI components

- Updated BottomBar, HomeView, LoginModal, ModLoaderSelector, SettingsView, Sidebar, StatusToast, and VersionsView components for improved dark mode styling.
- Adjusted color schemes for various elements to ensure better visibility and aesthetics in dark mode.
- Added a theme property to settings to enforce dark mode as the default.
- Refactored version badges in VersionsView for better color differentiation.
- Enhanced button and input styles for consistency in both light and dark themes.
---
 assets/image.jpg                           | Bin 172906 -> 161028 bytes
 src-tauri/src/core/config.rs               |   2 +
 src-tauri/src/main.rs                      |   4 --
 src-tauri/tauri.conf.json                  |   4 +-
 ui/src/App.svelte                          |  39 +++++++++++++------
 ui/src/components/BottomBar.svelte         |  20 +++++-----
 ui/src/components/HomeView.svelte          |  10 ++---
 ui/src/components/LoginModal.svelte        |  30 +++++++--------
 ui/src/components/ModLoaderSelector.svelte |  40 +++++++++----------
 ui/src/components/SettingsView.svelte      |  60 ++++++++++++++++++++---------
 ui/src/components/Sidebar.svelte           |   8 ++--
 ui/src/components/StatusToast.svelte       |  10 ++---
 ui/src/components/VersionsView.svelte      |  48 +++++++++++------------
 ui/src/stores/settings.svelte.ts           |   6 +++
 ui/src/types/index.ts                      |   1 +
 15 files changed, 163 insertions(+), 119 deletions(-)

(limited to 'ui/src/components/VersionsView.svelte')

diff --git a/assets/image.jpg b/assets/image.jpg
index 28cffe1..ddda96f 100644
Binary files a/assets/image.jpg and b/assets/image.jpg differ
diff --git a/src-tauri/src/core/config.rs b/src-tauri/src/core/config.rs
index 27e0011..510b126 100644
--- a/src-tauri/src/core/config.rs
+++ b/src-tauri/src/core/config.rs
@@ -17,6 +17,7 @@ pub struct LauncherConfig {
     pub enable_gpu_acceleration: bool,
     pub enable_visual_effects: bool,
     pub active_effect: String,
+    pub theme: String,
 }
 
 impl Default for LauncherConfig {
@@ -32,6 +33,7 @@ impl Default for LauncherConfig {
             enable_gpu_acceleration: false,
             enable_visual_effects: true,
             active_effect: "constellation".to_string(),
+            theme: "dark".to_string(),
         }
     }
 }
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index f7a391a..8a955a5 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -854,8 +854,6 @@ async fn get_recommended_java(
     Ok(core::java::get_recommended_java(required_major_version))
 }
 
-// ==================== Fabric Loader Commands ====================
-
 /// Get Minecraft versions supported by Fabric
 #[tauri::command]
 async fn get_fabric_game_versions() -> Result<Vec<core::fabric::FabricGameVersion>, String> {
@@ -949,8 +947,6 @@ async fn is_fabric_installed(
     ))
 }
 
-// ==================== Forge Loader Commands ====================
-
 /// Get Minecraft versions supported by Forge
 #[tauri::command]
 async fn get_forge_game_versions() -> Result<Vec<String>, String> {
diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json
index 9145e1b..682acb0 100644
--- a/src-tauri/tauri.conf.json
+++ b/src-tauri/tauri.conf.json
@@ -14,8 +14,8 @@
                 "title": "Minecraft DropOut Launcher",
                 "width": 1024,
                 "height": 768,
-                "minWidth": 800,
-                "minHeight": 600,
+                "minWidth": 905,
+                "minHeight": 575,
                 "resizable": true
             }
         ],
diff --git a/ui/src/App.svelte b/ui/src/App.svelte
index d93374e..2160b85 100644
--- a/ui/src/App.svelte
+++ b/ui/src/App.svelte
@@ -31,12 +31,22 @@
 
   onMount(async () => {
     authState.checkAccount();
-    settingsState.loadSettings();
+    await settingsState.loadSettings();
     gameState.loadVersions();
     getVersion().then((v) => (uiState.appVersion = v));
     window.addEventListener("mousemove", handleMouseMove);
   });
   
+  $effect(() => {
+    if (settingsState.settings.theme === 'light') {
+        document.documentElement.classList.remove('dark');
+        document.documentElement.setAttribute('data-theme', 'light');
+    } else {
+        document.documentElement.classList.add('dark');
+        document.documentElement.setAttribute('data-theme', 'dark');
+    }
+  });
+
   onDestroy(() => {
     if (typeof window !== 'undefined')
       window.removeEventListener("mousemove", handleMouseMove);
@@ -44,10 +54,10 @@
 </script>
 
 <div
-  class="relative h-screen w-screen overflow-hidden text-white font-sans selection:bg-indigo-500/30"
+  class="relative h-screen w-screen overflow-hidden dark:text-white text-gray-900 font-sans selection:bg-indigo-500/30"
 >
   <!-- Modern Animated Background -->
-  <div class="absolute inset-0 z-0 bg-[#09090b] overflow-hidden">
+  <div class="absolute inset-0 z-0 bg-[#09090b] dark:bg-[#09090b] bg-gray-100 overflow-hidden">
     {#if settingsState.settings.custom_background_path}
       <img
         src={convertFileSrc(settingsState.settings.custom_background_path)}
@@ -57,28 +67,35 @@
       <!-- Dimming Overlay for readability -->
       <div class="absolute inset-0 bg-black/50 "></div>
     {:else if settingsState.settings.enable_visual_effects}
-      <!-- Original Gradient -->
-      <div 
-        class="absolute inset-0 opacity-60 bg-gradient-to-br from-emerald-900 via-zinc-900 to-indigo-950"
-      ></div>
+      <!-- Original Gradient (Dark Only / or Adjusted for Light) -->
+      {#if settingsState.settings.theme === 'dark'}
+          <div 
+            class="absolute inset-0 opacity-60 bg-gradient-to-br from-emerald-900 via-zinc-900 to-indigo-950"
+          ></div>
+      {:else}
+           <!-- Light Mode Gradient -->
+           <div 
+            class="absolute inset-0 opacity-100 bg-gradient-to-br from-emerald-100 via-gray-100 to-indigo-100"
+          ></div>
+      {/if}
 
       {#if uiState.currentView === "home"}
         <ParticleBackground />
       {/if}
 
       <div 
-        class="absolute inset-0 bg-gradient-to-t from-zinc-900 via-transparent to-black/50"
+        class="absolute inset-0 bg-gradient-to-t from-zinc-900 via-transparent to-black/50 dark:from-zinc-900 dark:to-black/50 from-gray-100 to-transparent"
       ></div>
     {/if}
     
     <!-- Subtle Grid Overlay -->
-    <div class="absolute inset-0 z-0 opacity-10 pointer-events-none" 
-         style="background-image: linear-gradient(#ffffff 1px, transparent 1px), linear-gradient(90deg, #ffffff 1px, transparent 1px); background-size: 40px 40px; mask-image: radial-gradient(circle at 50% 50%, black 30%, transparent 70%);">
+    <div class="absolute inset-0 z-0 opacity-10 dark:opacity-10 opacity-30 pointer-events-none" 
+         style="background-image: linear-gradient({settingsState.settings.theme === 'dark' ? '#ffffff' : '#000000'} 1px, transparent 1px), linear-gradient(90deg, {settingsState.settings.theme === 'dark' ? '#ffffff' : '#000000'} 1px, transparent 1px); background-size: 40px 40px; mask-image: radial-gradient(circle at 50% 50%, black 30%, transparent 70%);">
     </div>
   </div>
 
   <!-- Content Wrapper -->
-  <div class="relative z-10 flex h-full p-4 gap-4">
+  <div class="relative z-10 flex h-full p-4 gap-4 text-gray-900 dark:text-white">
     <!-- Floating Sidebar -->
     <Sidebar />
 
diff --git a/ui/src/components/BottomBar.svelte b/ui/src/components/BottomBar.svelte
index dd218f3..0178111 100644
--- a/ui/src/components/BottomBar.svelte
+++ b/ui/src/components/BottomBar.svelte
@@ -5,7 +5,7 @@
 </script>
 
 <div
-  class="h-24 bg-gradient-to-t from-black/50 to-transparent border-t border-white/5 flex items-center px-8 justify-between z-20 backdrop-blur-md"
+  class="h-24 bg-gradient-to-t from-black/50 to-transparent dark:from-black/50 dark:to-transparent from-white/90 to-transparent border-t dark:border-white/5 border-black/5 flex items-center px-8 justify-between z-20 backdrop-blur-md"
 >
   <!-- Account Area -->
   <div class="flex items-center gap-6">
@@ -17,7 +17,7 @@
       onkeydown={(e) => e.key === "Enter" && authState.openLoginModal()}
     >
       <div
-        class="w-12 h-12 rounded-xl bg-gradient-to-tr from-indigo-500 to-purple-500 shadow-lg shadow-indigo-500/20 flex items-center justify-center text-white font-bold text-xl overflow-hidden ring-2 ring-transparent group-hover:ring-white/20 transition-all"
+        class="w-12 h-12 rounded-xl bg-gradient-to-tr from-indigo-500 to-purple-500 shadow-lg shadow-indigo-500/20 flex items-center justify-center text-white font-bold text-xl overflow-hidden ring-2 ring-transparent dark:group-hover:ring-white/20 group-hover:ring-black/10 transition-all"
       >
         {#if authState.currentAccount}
           <img
@@ -30,25 +30,25 @@
         {/if}
       </div>
       <div>
-        <div class="font-bold text-white text-lg group-hover:text-indigo-300 transition-colors">
+        <div class="font-bold dark:text-white text-gray-900 text-lg group-hover:text-indigo-500 dark:group-hover:text-indigo-300 transition-colors">
           {authState.currentAccount ? authState.currentAccount.username : "Login"}
         </div>
-        <div class="text-xs text-zinc-400 flex items-center gap-1.5">
+        <div class="text-xs dark:text-zinc-400 text-gray-500 flex items-center gap-1.5">
           <span
             class="w-2 h-2 rounded-full {authState.currentAccount
               ? 'bg-emerald-500 shadow-[0_0_8px_rgba(16,185,129,0.5)]'
-              : 'bg-zinc-600'}"
+              : 'dark:bg-zinc-600 bg-gray-400'}"
           ></span>
           {authState.currentAccount ? "Ready to play" : "Guest Mode"}
         </div>
       </div>
     </div>
     
-    <div class="h-8 w-px bg-white/10"></div>
+    <div class="h-8 w-px dark:bg-white/10 bg-black/10"></div>
     
     <!-- Console Toggle -->
     <button
-      class="text-xs font-mono text-zinc-500 hover:text-white transition-colors flex items-center gap-2"
+      class="text-xs font-mono dark:text-zinc-500 text-gray-500 dark:hover:text-white hover:text-black transition-colors flex items-center gap-2"
       onclick={() => uiState.toggleConsole()}
     >
       <span class="text-lg">_</span>
@@ -61,14 +61,14 @@
     <div class="flex flex-col items-end mr-2">
       <label
         for="version-select"
-        class="text-[10px] text-white/40 mb-1 uppercase font-bold tracking-wider"
+        class="text-[10px] dark:text-white/40 text-black/40 mb-1 uppercase font-bold tracking-wider"
         >Selected Version</label
       >
       <div class="relative group">
         <select
           id="version-select"
           bind:value={gameState.selectedVersion}
-          class="appearance-none bg-black/40 text-white border border-white/10 rounded-xl pl-4 pr-10 py-2.5 hover:border-white/30 transition-all cursor-pointer outline-none focus:ring-2 focus:ring-indigo-500/50 w-56 text-sm font-mono backdrop-blur-sm shadow-inner"
+          class="appearance-none dark:bg-black/40 bg-white/60 dark:text-white text-gray-900 border dark:border-white/10 border-black/10 rounded-xl pl-4 pr-10 py-2.5 dark:hover:border-white/30 hover:border-black/30 transition-all cursor-pointer outline-none focus:ring-2 focus:ring-indigo-500/50 w-56 text-sm font-mono backdrop-blur-sm shadow-inner"
         >
           {#if gameState.versions.length === 0}
             <option>Loading...</option>
@@ -78,7 +78,7 @@
             {/each}
           {/if}
         </select>
-        <div class="absolute right-3 top-1/2 -translate-y-1/2 text-white/20 pointer-events-none group-hover:text-white/50 transition-colors">▼</div>
+        <div class="absolute right-3 top-1/2 -translate-y-1/2 dark:text-white/20 text-black/20 pointer-events-none dark:group-hover:text-white/50 group-hover:text-black/50 transition-colors">▼</div>
       </div>
     </div>
 
diff --git a/ui/src/components/HomeView.svelte b/ui/src/components/HomeView.svelte
index 036c03a..9cd8014 100644
--- a/ui/src/components/HomeView.svelte
+++ b/ui/src/components/HomeView.svelte
@@ -19,19 +19,19 @@
     style:transform={`perspective(1000px) rotateX(${mouseY * -2}deg) rotateY(${mouseX * 2}deg)`}
   >
     <h1
-      class="text-8xl font-black tracking-tighter text-white drop-shadow-2xl mb-4"
-      style="text-shadow: 0 10px 30px rgba(0,0,0,0.5);"
+      class="text-8xl font-black tracking-tighter dark:text-white text-gray-900 drop-shadow-2xl mb-4"
+      style:text-shadow="0 10px 30px rgba(0,0,0,0.5)"
     >
       MINECRAFT
     </h1>
     
     <div class="flex items-center gap-4">
       <div 
-        class="bg-white/10 backdrop-blur-md border border-white/10 px-4 py-1.5 rounded-full text-sm font-bold uppercase tracking-widest text-emerald-400 shadow-xl"
+        class="bg-white/10 dark:bg-white/10 bg-black/5 backdrop-blur-md border dark:border-white/10 border-black/10 px-4 py-1.5 rounded-full text-sm font-bold uppercase tracking-widest text-emerald-500 dark:text-emerald-400 shadow-xl"
       >
         Java Edition
       </div>
-      <div class="text-2xl font-light text-zinc-300">
+      <div class="text-2xl font-light dark:text-zinc-300 text-gray-600">
         Latest Release 1.21
       </div>
     </div>
@@ -40,7 +40,7 @@
   <!-- Action Area -->
   <div class="mt-8 flex gap-4">
     <!-- Quick Play Button (Visual only here, logic is in BottomBar usually) -->
-    <div class="text-zinc-400 text-sm italic">
+    <div class="dark:text-zinc-400 text-gray-500 text-sm italic">
       Ready to play. Select version below or hit Launch.
     </div>
   </div>
diff --git a/ui/src/components/LoginModal.svelte b/ui/src/components/LoginModal.svelte
index f1ac0d5..1886cd9 100644
--- a/ui/src/components/LoginModal.svelte
+++ b/ui/src/components/LoginModal.svelte
@@ -9,16 +9,16 @@
 
 {#if authState.isLoginModalOpen}
   <div
-    class="fixed inset-0 z-[60] flex items-center justify-center bg-black/80 backdrop-blur-sm p-4"
+    class="fixed inset-0 z-[60] flex items-center justify-center bg-white/80 dark:bg-black/80 backdrop-blur-sm p-4"
   >
     <div
-      class="bg-zinc-900 border border-zinc-700 rounded-xl shadow-2xl p-6 w-full max-w-md animate-in fade-in zoom-in-0 duration-200"
+      class="bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-700 rounded-xl shadow-2xl p-6 w-full max-w-md animate-in fade-in zoom-in-0 duration-200"
     >
       <div class="flex justify-between items-center mb-6">
-        <h2 class="text-2xl font-bold text-white">Login</h2>
+        <h2 class="text-2xl font-bold text-gray-900 dark:text-white">Login</h2>
         <button
           onclick={() => authState.closeLoginModal()}
-          class="text-zinc-500 hover:text-white transition group"
+          class="text-zinc-500 hover:text-black dark:hover:text-white transition group"
         >
           ✕
         </button>
@@ -28,7 +28,7 @@
         <div class="space-y-4">
           <button
             onclick={() => authState.startMicrosoftLogin()}
-            class="w-full flex items-center justify-center gap-3 bg-[#2F2F2F] hover:bg-[#3F3F3F] text-white p-4 rounded-lg font-bold border border-transparent hover:border-zinc-500 transition-all group"
+            class="w-full flex items-center justify-center gap-3 bg-gray-100 hover:bg-gray-200 dark:bg-[#2F2F2F] dark:hover:bg-[#3F3F3F] text-gray-900 dark:text-white p-4 rounded-lg font-bold border border-transparent hover:border-zinc-400 dark:hover:border-zinc-500 transition-all group"
           >
             <!-- Microsoft Logo SVG -->
             <svg
@@ -49,10 +49,10 @@
 
           <div class="relative py-2">
             <div class="absolute inset-0 flex items-center">
-              <div class="w-full border-t border-zinc-700"></div>
+              <div class="w-full border-t border-zinc-200 dark:border-zinc-700"></div>
             </div>
             <div class="relative flex justify-center text-xs uppercase">
-              <span class="bg-zinc-900 px-2 text-zinc-500">OR</span>
+              <span class="bg-white dark:bg-zinc-900 px-2 text-zinc-400 dark:text-zinc-500">OR</span>
             </div>
           </div>
 
@@ -61,12 +61,12 @@
               type="text"
               bind:value={authState.offlineUsername}
               placeholder="Offline Username"
-              class="w-full bg-zinc-950 border border-zinc-700 rounded p-3 text-white focus:border-indigo-500 outline-none"
+              class="w-full bg-gray-50 border-zinc-200 dark:bg-zinc-950 dark:border-zinc-700 rounded p-3 text-gray-900 dark:text-white focus:border-indigo-500 outline-none"
               onkeydown={(e) => e.key === "Enter" && authState.performOfflineLogin()}
             />
             <button
               onclick={() => authState.performOfflineLogin()}
-              class="w-full bg-zinc-800 hover:bg-zinc-700 text-zinc-300 p-3 rounded font-medium transition-colors"
+              class="w-full bg-gray-200 hover:bg-gray-300 dark:bg-zinc-800 dark:hover:bg-zinc-700 text-gray-700 dark:text-zinc-300 p-3 rounded font-medium transition-colors"
             >
               Offline Login
             </button>
@@ -80,18 +80,18 @@
             </div>
           {:else if authState.deviceCodeData}
             <div class="space-y-4">
-              <p class="text-sm text-zinc-400">1. Go to this URL:</p>
+              <p class="text-sm text-gray-500 dark:text-zinc-400">1. Go to this URL:</p>
               <button
                 onclick={() =>
                     authState.deviceCodeData && openLink(authState.deviceCodeData.verification_uri)}
-                class="text-indigo-400 hover:text-indigo-300 underline break-all font-mono text-sm"
+                class="text-indigo-600 dark:text-indigo-400 hover:text-indigo-500 dark:hover:text-indigo-300 underline break-all font-mono text-sm"
               >
                 {authState.deviceCodeData.verification_uri}
               </button>
 
-              <p class="text-sm text-zinc-400 mt-2">2. Enter this code:</p>
+              <p class="text-sm text-gray-500 dark:text-zinc-400 mt-2">2. Enter this code:</p>
               <div
-                class="bg-zinc-950 p-4 rounded border border-zinc-700 font-mono text-2xl tracking-widest text-center select-all cursor-pointer hover:border-indigo-500 transition-colors"
+                class="bg-gray-50 dark:bg-zinc-950 p-4 rounded border border-zinc-200 dark:border-zinc-700 font-mono text-2xl tracking-widest text-center select-all cursor-pointer hover:border-indigo-500 transition-colors dark:text-white text-gray-900"
                 role="button"
                 tabindex="0"
                 onkeydown={(e) => e.key === 'Enter' && navigator.clipboard.writeText(authState.deviceCodeData?.user_code || "")}
@@ -106,8 +106,8 @@
 
               <div class="pt-6 space-y-3">
                    <div class="flex flex-col items-center gap-3">
-                       <div class="animate-spin rounded-full h-6 w-6 border-2 border-zinc-600 border-t-indigo-500"></div>
-                       <span class="text-sm text-zinc-400 font-medium break-all text-center">{authState.msLoginStatus}</span>
+                       <div class="animate-spin rounded-full h-6 w-6 border-2 border-zinc-300 dark:border-zinc-600 border-t-indigo-500"></div>
+                       <span class="text-sm text-gray-600 dark:text-zinc-400 font-medium break-all text-center">{authState.msLoginStatus}</span>
                    </div>
                    <p class="text-xs text-zinc-600">This window will update automatically.</p>
               </div>
diff --git a/ui/src/components/ModLoaderSelector.svelte b/ui/src/components/ModLoaderSelector.svelte
index 4a59916..fd26382 100644
--- a/ui/src/components/ModLoaderSelector.svelte
+++ b/ui/src/components/ModLoaderSelector.svelte
@@ -114,16 +114,16 @@
 
 <div class="space-y-4">
   <div class="flex items-center justify-between">
-      <h3 class="text-xs font-bold uppercase tracking-widest text-white/40">Select Mod Loader</h3>
+      <h3 class="text-xs font-bold uppercase tracking-widest text-gray-500 dark:text-white/40">Select Mod Loader</h3>
   </div>
 
   <!-- Loader Type Tabs - Segmented Control -->
-  <div class="flex p-1 bg-black/40 rounded-xl border border-white/5 backdrop-blur-sm">
+  <div class="flex p-1 bg-white/60 dark:bg-black/40 rounded-xl border border-black/5 dark:border-white/5 backdrop-blur-sm">
     <button
       class="flex-1 px-3 py-2 rounded-lg text-sm font-medium transition-all duration-200
       {selectedLoader === 'vanilla'
-        ? 'bg-white/10 text-white shadow-lg border border-white/10'
-        : 'text-zinc-500 hover:text-white hover:bg-white/5'}"
+        ? 'bg-white shadow-lg border border-black/5 text-black dark:bg-white/10 dark:text-white dark:border-white/10'
+        : 'text-gray-500 dark:text-zinc-500 hover:text-black dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5'}"
       onclick={() => onLoaderChange("vanilla")}
     >
       Vanilla
@@ -131,8 +131,8 @@
     <button
       class="flex-1 px-3 py-2 rounded-lg text-sm font-medium transition-all duration-200
       {selectedLoader === 'fabric'
-        ? 'bg-indigo-500/20 text-indigo-300 shadow-lg border border-indigo-500/20'
-        : 'text-zinc-500 hover:text-white hover:bg-white/5'}"
+        ? 'bg-indigo-100 text-indigo-700 border border-indigo-200 dark:bg-indigo-500/20 dark:text-indigo-300 dark:shadow-lg dark:border-indigo-500/20'
+        : 'text-gray-500 dark:text-zinc-500 hover:text-black dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5'}"
       onclick={() => onLoaderChange("fabric")}
     >
       Fabric
@@ -140,8 +140,8 @@
     <button
       class="flex-1 px-3 py-2 rounded-lg text-sm font-medium transition-all duration-200
       {selectedLoader === 'forge'
-        ? 'bg-orange-500/20 text-orange-300 shadow-lg border border-orange-500/20'
-        : 'text-zinc-500 hover:text-white hover:bg-white/5'}"
+        ? 'bg-orange-100 text-orange-700 border border-orange-200 dark:bg-orange-500/20 dark:text-orange-300 dark:shadow-lg dark:border-orange-500/20'
+        : 'text-gray-500 dark:text-zinc-500 hover:text-black dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5'}"
       onclick={() => onLoaderChange("forge")}
     >
       Forge
@@ -151,36 +151,36 @@
   <!-- Content Area -->
   <div class="min-h-[100px] flex flex-col justify-center">
     {#if selectedLoader === "vanilla"}
-        <div class="text-center p-4 rounded-xl bg-white/5 border border-dashed border-white/10 text-white/40 text-sm">
+        <div class="text-center p-4 rounded-xl bg-white/40 dark:bg-white/5 border border-dashed border-black/5 dark:border-white/10 text-gray-500 dark:text-white/40 text-sm">
            No mod loader selected. <br> Pure vanilla experience.
         </div>
         
     {:else if !selectedGameVersion}
-        <div class="text-center p-4 rounded-xl bg-red-500/10 border border-red-500/20 text-red-300 text-sm">
+        <div class="text-center p-4 rounded-xl bg-red-50 border border-red-200 text-red-700 dark:bg-red-500/10 dark:border-red-500/20 dark:text-red-300 text-sm">
            ⚠️ Please select a base Minecraft version first.
         </div>
         
     {:else if isLoading}
-        <div class="flex flex-col items-center gap-2 text-sm text-white/50 py-4">
-            <div class="w-6 h-6 border-2 border-white/20 border-t-white rounded-full animate-spin"></div>
+        <div class="flex flex-col items-center gap-2 text-sm text-gray-500 dark:text-white/50 py-4">
+            <div class="w-6 h-6 border-2 border-gray-200 border-t-gray-500 dark:border-white/20 dark:border-t-white rounded-full animate-spin"></div>
             Loading {selectedLoader} versions...
         </div>
         
     {:else if error}
-        <div class="p-4 bg-red-500/10 border border-red-500/20 rounded-xl text-red-300 text-sm break-words">
+        <div class="p-4 bg-red-50 border border-red-200 text-red-700 dark:bg-red-500/10 dark:border-red-500/20 dark:text-red-300 rounded-xl text-sm break-words">
             {error}
         </div>
         
     {:else if selectedLoader === "fabric"}
         <div class="space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300">
         <div>
-            <label for="fabric-loader-select" class="block text-xs text-white/40 mb-2 pl-1"
+            <label for="fabric-loader-select" class="block text-xs text-gray-500 dark:text-white/40 mb-2 pl-1"
             >Loader Version</label
             >
             <div class="relative">
                 <select
                 id="fabric-loader-select"
-                class="w-full appearance-none bg-black/40 border border-white/10 rounded-xl px-4 py-3 text-sm focus:outline-none focus:border-indigo-500/50 text-white transition-colors"
+                class="w-full appearance-none bg-white/80 dark:bg-black/40 border border-black/10 dark:border-white/10 rounded-xl px-4 py-3 text-sm focus:outline-none focus:border-indigo-500/50 text-gray-900 dark:text-white transition-colors"
                 bind:value={selectedFabricLoader}
                 >
                 {#each fabricLoaders as loader}
@@ -189,7 +189,7 @@
                     </option>
                 {/each}
                 </select>
-                <div class="absolute right-4 top-1/2 -translate-y-1/2 text-white/20 pointer-events-none">▼</div>
+                <div class="absolute right-4 top-1/2 -translate-y-1/2 text-black/30 dark:text-white/20 pointer-events-none">▼</div>
             </div>
         </div>
         
@@ -205,18 +205,18 @@
     {:else if selectedLoader === "forge"}
         <div class="space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300">
         {#if forgeVersions.length === 0}
-            <div class="text-center p-4 text-sm text-white/40 italic">
+            <div class="text-center p-4 text-sm text-gray-500 dark:text-white/40 italic">
             No Forge versions available for {selectedGameVersion}
             </div>
         {:else}
             <div>
-            <label for="forge-version-select" class="block text-xs text-white/40 mb-2 pl-1"
+            <label for="forge-version-select" class="block text-xs text-gray-500 dark:text-white/40 mb-2 pl-1"
                 >Forge Version</label
             >
             <div class="relative">
                 <select
                     id="forge-version-select"
-                    class="w-full appearance-none bg-black/40 border border-white/10 rounded-xl px-4 py-3 text-sm focus:outline-none focus:border-orange-500/50 text-white transition-colors"
+                    class="w-full appearance-none bg-white/80 dark:bg-black/40 border border-black/10 dark:border-white/10 rounded-xl px-4 py-3 text-sm focus:outline-none focus:border-orange-500/50 text-gray-900 dark:text-white transition-colors"
                     bind:value={selectedForgeVersion}
                 >
                     {#each forgeVersions as version}
@@ -227,7 +227,7 @@
                     </option>
                     {/each}
                 </select>
-                <div class="absolute right-4 top-1/2 -translate-y-1/2 text-white/20 pointer-events-none">▼</div>
+                <div class="absolute right-4 top-1/2 -translate-y-1/2 text-black/30 dark:text-white/20 pointer-events-none">▼</div>
             </div>
             </div>
             
diff --git a/ui/src/components/SettingsView.svelte b/ui/src/components/SettingsView.svelte
index 4c92220..86bcce1 100644
--- a/ui/src/components/SettingsView.svelte
+++ b/ui/src/components/SettingsView.svelte
@@ -32,24 +32,24 @@
 
 <div class="h-full flex flex-col p-6 overflow-hidden">
   <div class="flex items-center justify-between mb-6">
-     <h2 class="text-3xl font-black bg-clip-text text-transparent bg-gradient-to-r from-white to-white/60">Settings</h2>
+     <h2 class="text-3xl font-black bg-clip-text text-transparent bg-gradient-to-r dark:from-white dark:to-white/60 from-gray-900 to-gray-600">Settings</h2>
   </div>
 
   <div class="flex-1 overflow-y-auto pr-2 space-y-6 custom-scrollbar pb-10">
 
     <!-- Appearance / Background -->
-    <div class="bg-black/20 p-6 rounded-2xl border border-white/5 ">
-      <h3 class="text-xs font-bold uppercase tracking-widest text-white/40 mb-6 flex items-center gap-2">
+    <div class="dark:bg-black/20 bg-white/60 p-6 rounded-2xl border dark:border-white/5 border-black/5 shadow-sm backdrop-blur-sm">
+      <h3 class="text-xs font-bold uppercase tracking-widest dark:text-white/40 text-black/40 mb-6 flex items-center gap-2">
         Appearance
       </h3>
       
       <div class="space-y-4">
         <div>
-          <label class="block text-sm font-medium text-white/70 mb-3">Custom Background Image</label>
+          <label class="block text-sm font-medium dark:text-white/70 text-black/70 mb-3">Custom Background Image</label>
           
           <div class="flex items-center gap-6">
             <!-- Preview -->
-            <div class="w-40 h-24 rounded-xl overflow-hidden bg-black/50 border border-white/10 relative group shadow-lg">
+            <div class="w-40 h-24 rounded-xl overflow-hidden dark:bg-black/50 bg-gray-200 border dark:border-white/10 border-black/10 relative group shadow-lg">
               {#if settingsState.settings.custom_background_path}
                 <img 
                   src={convertFileSrc(settingsState.settings.custom_background_path)} 
@@ -66,7 +66,7 @@
             <div class="flex flex-col gap-2">
               <button
                 onclick={selectBackground}
-                class="bg-white/10 hover:bg-white/20 text-white px-4 py-2 rounded-lg text-sm transition-colors border border-white/5"
+                class="dark:bg-white/10 dark:hover:bg-white/20 bg-black/5 hover:bg-black/10 dark:text-white text-black px-4 py-2 rounded-lg text-sm transition-colors border dark:border-white/5 border-black/5"
               >
                 Select Image
               </button>
@@ -81,39 +81,39 @@
               {/if}
             </div>
           </div>
-          <p class="text-xs text-white/30 mt-3">
+          <p class="text-xs dark:text-white/30 text-black/40 mt-3">
             Select an image from your computer to replace the default gradient background.
             Supported formats: PNG, JPG, WEBP, GIF.
           </p>
         </div>
 
         <!-- Visual Settings -->
-        <div class="pt-4 border-t border-white/5 space-y-4">
+        <div class="pt-4 border-t dark:border-white/5 border-black/5 space-y-4">
              <div class="flex items-center justify-between">
                 <div>
-                   <h4 class="text-sm font-medium text-white/90" id="visual-effects-label">Visual Effects</h4>
-                   <p class="text-xs text-white/40 mt-1">Enable particle effects and animated gradients. (Default: On)</p>
+                   <h4 class="text-sm font-medium dark:text-white/90 text-black/80" id="visual-effects-label">Visual Effects</h4>
+                   <p class="text-xs dark:text-white/40 text-black/50 mt-1">Enable particle effects and animated gradients. (Default: On)</p>
                 </div>
                 <button 
                     aria-labelledby="visual-effects-label"
                     onclick={() => { settingsState.settings.enable_visual_effects = !settingsState.settings.enable_visual_effects; settingsState.saveSettings(); }}
-                    class="w-11 h-6 rounded-full transition-colors duration-200 ease-in-out relative focus:outline-none {settingsState.settings.enable_visual_effects ? 'bg-indigo-500' : 'bg-white/10'}"
+                    class="w-11 h-6 rounded-full transition-colors duration-200 ease-in-out relative focus:outline-none {settingsState.settings.enable_visual_effects ? 'bg-indigo-500' : 'dark:bg-white/10 bg-black/10'}"
                 >
                     <div class="absolute top-1 left-1 bg-white w-4 h-4 rounded-full shadow-sm transition-transform duration-200 ease-in-out {settingsState.settings.enable_visual_effects ? 'translate-x-5' : 'translate-x-0'}"></div>
                 </button>
              </div>
 
              {#if settingsState.settings.enable_visual_effects}
-                 <div class="flex items-center justify-between pl-2 border-l-2 border-white/5 ml-1">
+                 <div class="flex items-center justify-between pl-2 border-l-2 dark:border-white/5 border-black/5 ml-1">
                     <div>
-                       <h4 class="text-sm font-medium text-white/90" id="theme-effect-label">Theme Effect</h4>
-                       <p class="text-xs text-white/40 mt-1">Select the active visual theme.</p>
+                       <h4 class="text-sm font-medium dark:text-white/90 text-black/80" id="theme-effect-label">Theme Effect</h4>
+                       <p class="text-xs dark:text-white/40 text-black/50 mt-1">Select the active visual theme.</p>
                     </div>
                     <select
                         aria-labelledby="theme-effect-label"
                         bind:value={settingsState.settings.active_effect}
                         onchange={() => settingsState.saveSettings()}
-                        class="bg-black/40 text-white text-xs px-3 py-2 rounded-lg border border-white/10 outline-none focus:border-indigo-500/50 appearance-none cursor-pointer hover:bg-white/5 transition-colors"
+                        class="dark:bg-black/40 bg-white dark:text-white text-black text-xs px-3 py-2 rounded-lg border dark:border-white/10 border-black/10 outline-none focus:border-indigo-500/50 appearance-none cursor-pointer hover:bg-black/5 dark:hover:bg-white/5 transition-colors"
                     >
                         <option value="saturn">Saturn (Saturn)</option>
                         <option value="constellation">Network (Constellation)</option>
@@ -123,23 +123,45 @@
 
              <div class="flex items-center justify-between">
                 <div>
-                   <h4 class="text-sm font-medium text-white/90" id="gpu-acceleration-label">GPU Acceleration</h4>
-                   <p class="text-xs text-white/40 mt-1">Enable GPU acceleration for the interface. (Default: Off, Requires Restart)</p>
+                   <h4 class="text-sm font-medium dark:text-white/90 text-black/80" id="gpu-acceleration-label">GPU Acceleration</h4>
+                   <p class="text-xs dark:text-white/40 text-black/50 mt-1">Enable GPU acceleration for the interface. (Default: Off, Requires Restart)</p>
                 </div>
                 <button 
                     aria-labelledby="gpu-acceleration-label"
                     onclick={() => { settingsState.settings.enable_gpu_acceleration = !settingsState.settings.enable_gpu_acceleration; settingsState.saveSettings(); }}
-                    class="w-11 h-6 rounded-full transition-colors duration-200 ease-in-out relative focus:outline-none {settingsState.settings.enable_gpu_acceleration ? 'bg-indigo-500' : 'bg-white/10'}"
+                    class="w-11 h-6 rounded-full transition-colors duration-200 ease-in-out relative focus:outline-none {settingsState.settings.enable_gpu_acceleration ? 'bg-indigo-500' : 'dark:bg-white/10 bg-black/10'}"
                 >
                     <div class="absolute top-1 left-1 bg-white w-4 h-4 rounded-full shadow-sm transition-transform duration-200 ease-in-out {settingsState.settings.enable_gpu_acceleration ? 'translate-x-5' : 'translate-x-0'}"></div>
                 </button>
              </div>
+             
+             <!-- Color Theme Switcher -->
+             <div class="flex items-center justify-between pt-4 border-t dark:border-white/5 border-black/5 opacity-50 cursor-not-allowed">
+                <div>
+                   <h4 class="text-sm font-medium dark:text-white/90 text-black/80" id="color-theme-label">Color Theme</h4>
+                   <p class="text-xs dark:text-white/40 text-black/50 mt-1">Interface color mode. (Locked to Dark)</p>
+                </div>
+                <div class="flex items-center bg-black/5 dark:bg-white/5 rounded-lg p-1 pointer-events-none">
+                    <button
+                        disabled
+                        class="px-3 py-1 rounded-md text-xs font-medium transition-all text-gray-500 dark:text-gray-600"
+                    >
+                        Light
+                    </button>
+                    <button
+                        disabled
+                        class="px-3 py-1 rounded-md text-xs font-medium transition-all bg-indigo-500 text-white shadow-sm"
+                    >
+                        Dark
+                    </button>
+                </div>
+             </div>
         </div>
       </div>
     </div>
 
     <!-- Java Path -->
-    <div class="bg-black/20 p-6 rounded-2xl border border-white/5 ">
+    <div class="dark:bg-black/20 bg-white/60 p-6 rounded-2xl border dark:border-white/5 border-black/5 shadow-sm backdrop-blur-sm">
       <h3 class="text-xs font-bold uppercase tracking-widest text-white/40 mb-6 flex items-center gap-2">
         Java Environment
       </h3>
diff --git a/ui/src/components/Sidebar.svelte b/ui/src/components/Sidebar.svelte
index 7976f6a..e6fbf43 100644
--- a/ui/src/components/Sidebar.svelte
+++ b/ui/src/components/Sidebar.svelte
@@ -3,7 +3,7 @@
 </script>
 
 <aside
-  class="w-20 lg:w-64 bg-black flex flex-col items-center lg:items-start transition-all duration-300 shrink-0 py-6"
+  class="w-20 lg:w-64 dark:bg-black bg-white/80 border-r dark:border-white/5 border-gray-200/50 flex flex-col items-center lg:items-start transition-all duration-300 shrink-0 py-6 backdrop-blur-md"
 >
   <!-- Logo Area -->
   <div
@@ -17,7 +17,7 @@
     </div>
     <!-- Full Logo (Large) -->
     <div
-      class="hidden lg:block font-bold text-2xl tracking-wider text-white"
+      class="hidden lg:block font-bold text-2xl tracking-wider dark:text-white text-gray-900"
     >
       <span class="bg-clip-text text-transparent bg-gradient-to-r from-indigo-400 to-fuchsia-400">DROP</span>OUT
     </div>
@@ -30,8 +30,8 @@
       <button
         class="group flex items-center lg:gap-4 justify-center lg:justify-start w-full px-0 lg:px-5 py-3.5 rounded-xl transition-all duration-200 relative overflow-hidden
         {uiState.currentView === view
-          ? 'bg-gradient-to-r from-indigo-500/20 to-purple-500/20 text-white shadow-lg shadow-indigo-500/10 border border-white/10'
-          : 'text-zinc-400 hover:text-white hover:bg-white/5'}"
+          ? 'bg-gradient-to-r from-indigo-500/20 to-purple-500/20 dark:text-white text-indigo-900 shadow-lg shadow-indigo-500/10 dark:border border-white/10'
+          : 'dark:text-zinc-400 text-gray-500 hover:text-black dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5'}"
         onclick={() => uiState.setView(view)}
       >
         <span class="text-xl relative z-10 transition-transform group-hover:scale-110 duration-200">{icon}</span>
diff --git a/ui/src/components/StatusToast.svelte b/ui/src/components/StatusToast.svelte
index 0d68778..4c981c7 100644
--- a/ui/src/components/StatusToast.svelte
+++ b/ui/src/components/StatusToast.svelte
@@ -5,19 +5,19 @@
 {#if uiState.status !== "Ready"}
   {#key uiState.status}
     <div
-      class="absolute top-12 right-12 bg-zinc-800/90 backdrop-blur border border-zinc-600 p-4 rounded-lg shadow-2xl max-w-sm animate-in fade-in slide-in-from-top-4 duration-300 z-50 group"
+      class="absolute top-12 right-12 bg-white/90 dark:bg-zinc-800/90 backdrop-blur border border-zinc-200 dark:border-zinc-600 p-4 rounded-lg shadow-2xl max-w-sm animate-in fade-in slide-in-from-top-4 duration-300 z-50 group"
     >
       <div class="flex justify-between items-start mb-1">
-        <div class="text-xs text-zinc-400 uppercase font-bold">Status</div>
+        <div class="text-xs text-zinc-500 dark:text-zinc-400 uppercase font-bold">Status</div>
         <button
           onclick={() => uiState.setStatus("Ready")}
-          class="text-zinc-500 hover:text-white transition -mt-1 -mr-1 p-1"
+          class="text-zinc-400 hover:text-black dark:text-zinc-500 dark:hover:text-white transition -mt-1 -mr-1 p-1"
         >
           ✕
         </button>
       </div>
-      <div class="font-mono text-sm whitespace-pre-wrap mb-2">{uiState.status}</div>
-      <div class="w-full bg-zinc-700/50 h-1 rounded-full overflow-hidden">
+      <div class="font-mono text-sm whitespace-pre-wrap mb-2 text-gray-900 dark:text-gray-100">{uiState.status}</div>
+      <div class="w-full bg-gray-200 dark:bg-zinc-700/50 h-1 rounded-full overflow-hidden">
         <div
           class="h-full bg-indigo-500 origin-left w-full progress-bar"
         ></div>
diff --git a/ui/src/components/VersionsView.svelte b/ui/src/components/VersionsView.svelte
index 00ac281..8f3a568 100644
--- a/ui/src/components/VersionsView.svelte
+++ b/ui/src/components/VersionsView.svelte
@@ -73,15 +73,15 @@
   function getVersionBadge(type: string) {
     switch (type) {
       case "release":
-        return { text: "Release", class: "bg-emerald-500/20 text-emerald-300 border-emerald-500/30" };
+        return { text: "Release", class: "bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-500/20 dark:text-emerald-300 dark:border-emerald-500/30" };
       case "snapshot":
-        return { text: "Snapshot", class: "bg-amber-500/20 text-amber-300 border-amber-500/30" };
+        return { text: "Snapshot", class: "bg-amber-100 text-amber-700 border-amber-200 dark:bg-amber-500/20 dark:text-amber-300 dark:border-amber-500/30" };
       case "fabric":
-        return { text: "Fabric", class: "bg-indigo-500/20 text-indigo-300 border-indigo-500/30" };
+        return { text: "Fabric", class: "bg-indigo-100 text-indigo-700 border-indigo-200 dark:bg-indigo-500/20 dark:text-indigo-300 dark:border-indigo-500/30" };
       case "forge":
-        return { text: "Forge", class: "bg-orange-500/20 text-orange-300 border-orange-500/30" };
+        return { text: "Forge", class: "bg-orange-100 text-orange-700 border-orange-200 dark:bg-orange-500/20 dark:text-orange-300 dark:border-orange-500/30" };
       default:
-        return { text: type, class: "bg-zinc-500/20 text-zinc-300 border-zinc-500/30" };
+        return { text: type, class: "bg-zinc-100 text-zinc-700 border-zinc-200 dark:bg-zinc-500/20 dark:text-zinc-300 dark:border-zinc-500/30" };
     }
   }
 
@@ -116,8 +116,8 @@
 
 <div class="h-full flex flex-col p-6 overflow-hidden">
   <div class="flex items-center justify-between mb-6">
-     <h2 class="text-3xl font-black bg-clip-text text-transparent bg-gradient-to-r from-white to-white/60">Version Manager</h2>
-     <div class="text-sm text-white/40">Select a version to play or modify</div>
+     <h2 class="text-3xl font-black bg-clip-text text-transparent bg-gradient-to-r from-gray-900 to-gray-600 dark:from-white dark:to-white/60">Version Manager</h2>
+     <div class="text-sm dark:text-white/40 text-black/50">Select a version to play or modify</div>
   </div>
 
   <div class="flex-1 grid grid-cols-1 lg:grid-cols-3 gap-6 overflow-hidden">
@@ -126,24 +126,24 @@
       <!-- Search and Filters (Glass Bar) -->
       <div class="flex gap-3">
         <div class="relative flex-1">
-            <span class="absolute left-3 top-1/2 -translate-y-1/2 text-white/30">🔍</span>
+            <span class="absolute left-3 top-1/2 -translate-y-1/2 dark:text-white/30 text-black/30">🔍</span>
             <input
               type="text"
               placeholder="Search versions..."
-              class="w-full pl-9 pr-4 py-3 bg-black/20 border border-white/10 rounded-xl text-white placeholder-white/30 focus:outline-none focus:border-indigo-500/50 focus:bg-black/40 transition-all backdrop-blur-sm"
+              class="w-full pl-9 pr-4 py-3 bg-white/60 dark:bg-black/20 border border-black/10 dark:border-white/10 rounded-xl dark:text-white text-gray-900 placeholder-black/30 dark:placeholder-white/30 focus:outline-none focus:border-indigo-500/50 dark:focus:bg-black/40 focus:bg-white/80 transition-all backdrop-blur-sm"
               bind:value={searchQuery}
             />
         </div>
       </div>
 
       <!-- Type Filter Tabs (Glass Caps) -->
-      <div class="flex p-1 bg-black/20 rounded-xl border border-white/5">
+      <div class="flex p-1 bg-white/60 dark:bg-black/20 rounded-xl border border-black/5 dark:border-white/5">
         {#each ['all', 'release', 'snapshot', 'modded'] as filter}
             <button
             class="flex-1 px-3 py-2 rounded-lg text-sm font-medium transition-all duration-200 capitalize
             {typeFilter === filter
-                ? 'bg-white/10 text-white shadow-lg border border-white/10'
-                : 'text-white/40 hover:text-white hover:bg-white/5'}"
+                ? 'bg-white shadow-sm border border-black/5 dark:bg-white/10 dark:text-white dark:shadow-lg dark:border-white/10 text-black'
+                : 'text-black/40 dark:text-white/40 hover:text-black dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5'}"
             onclick={() => (typeFilter = filter as any)}
             >
             {filter}
@@ -154,11 +154,11 @@
       <!-- Version List SCROLL -->
       <div class="flex-1 overflow-y-auto pr-2 space-y-2 custom-scrollbar">
         {#if gameState.versions.length === 0}
-          <div class="flex items-center justify-center h-40 text-white/30 italic animate-pulse">
+          <div class="flex items-center justify-center h-40 dark:text-white/30 text-black/30 italic animate-pulse">
              Fetching manifest...
           </div>
         {:else if filteredVersions().length === 0}
-          <div class="flex flex-col items-center justify-center -40 text-white/30 gap-2">
+          <div class="flex flex-col items-center justify-center -40 dark:text-white/30 text-black/30 gap-2">
              <span class="text-2xl">👻</span>
              <span>No matching versions found</span>
           </div>
@@ -169,8 +169,8 @@
             <button
               class="w-full group flex items-center justify-between p-4 rounded-xl text-left border transition-all duration-200 relative overflow-hidden
               {isSelected
-                ? 'bg-indigo-600/20 border-indigo-500/50 shadow-[0_0_20px_rgba(99,102,241,0.2)]'
-                : 'bg-white/5 border-white/5 hover:bg-white/10 hover:border-white/10 hover:translate-x-1'}"
+                ? 'bg-indigo-50 border-indigo-200 dark:bg-indigo-600/20 dark:border-indigo-500/50 shadow-[0_0_20px_rgba(99,102,241,0.2)]'
+                : 'bg-white/40 dark:bg-white/5 border-black/5 dark:border-white/5 hover:bg-white/60 dark:hover:bg-white/10 hover:border-black/10 dark:hover:border-white/10 hover:translate-x-1'}"
               onclick={() => (gameState.selectedVersion = version.id)}
             >
               <!-- Selection Glow -->
@@ -185,11 +185,11 @@
                   {badge.text}
                 </span>
                 <div>
-                  <div class="font-bold font-mono text-lg tracking-tight {isSelected ? 'text-white' : 'text-zinc-300 group-hover:text-white'}">
+                  <div class="font-bold font-mono text-lg tracking-tight {isSelected ? 'text-black dark:text-white' : 'text-gray-700 dark:text-zinc-300 group-hover:text-black dark:group-hover:text-white'}">
                     {version.id}
                   </div>
                   {#if version.releaseTime && version.type !== "fabric" && version.type !== "forge"}
-                    <div class="text-xs text-white/30">
+                    <div class="text-xs dark:text-white/30 text-black/30">
                       {new Date(version.releaseTime).toLocaleDateString()}
                     </div>
                   {/if}
@@ -197,7 +197,7 @@
               </div>
               
               {#if isSelected}
-                <div class="relative z-10 text-indigo-400">
+                <div class="relative z-10 text-indigo-500 dark:text-indigo-400">
                    <span class="text-lg">Selected</span>
                 </div>
               {/if}
@@ -210,21 +210,21 @@
     <!-- Right: Mod Loader Panel -->
     <div class="flex flex-col gap-4">
       <!-- Selected Version Info Card -->
-      <div class="bg-gradient-to-br from-white/10 to-white/5 p-6 rounded-2xl border border-white/10 backdrop-blur-md relative overflow-hidden group">
+      <div class="bg-gradient-to-br from-white/40 to-white/20 dark:from-white/10 dark:to-white/5 p-6 rounded-2xl border border-black/5 dark:border-white/10 backdrop-blur-md relative overflow-hidden group">
           <div class="absolute top-0 right-0 p-8 bg-indigo-500/20 blur-[60px] rounded-full group-hover:bg-indigo-500/30 transition-colors"></div>
           
-          <h3 class="text-xs font-bold uppercase tracking-widest text-white/40 mb-2 relative z-10">Current Selection</h3>
+          <h3 class="text-xs font-bold uppercase tracking-widest dark:text-white/40 text-black/40 mb-2 relative z-10">Current Selection</h3>
           {#if gameState.selectedVersion}
-            <p class="font-mono text-3xl font-black text-transparent bg-clip-text bg-gradient-to-r from-white to-white/70 relative z-10 truncate">
+            <p class="font-mono text-3xl font-black text-transparent bg-clip-text bg-gradient-to-r from-gray-900 to-gray-600 dark:from-white dark:to-white/70 relative z-10 truncate">
                 {gameState.selectedVersion}
             </p>
           {:else}
-            <p class="text-white/20 italic relative z-10">None selected</p>
+            <p class="dark:text-white/20 text-black/20 italic relative z-10">None selected</p>
           {/if}
       </div>
 
       <!-- Mod Loader Selector Card -->
-      <div class="bg-black/20 p-4 rounded-2xl border border-white/5 backdrop-blur-sm flex-1 flex flex-col">
+      <div class="bg-white/60 dark:bg-black/20 p-4 rounded-2xl border border-black/5 dark:border-white/5 backdrop-blur-sm flex-1 flex flex-col">
           <ModLoaderSelector
             selectedGameVersion={selectedBaseVersion()}
             onInstall={handleModLoaderInstall}
diff --git a/ui/src/stores/settings.svelte.ts b/ui/src/stores/settings.svelte.ts
index c59bf3c..b67cdc3 100644
--- a/ui/src/stores/settings.svelte.ts
+++ b/ui/src/stores/settings.svelte.ts
@@ -13,6 +13,7 @@ export class SettingsState {
     enable_gpu_acceleration: false,
     enable_visual_effects: true,
     active_effect: "constellation",
+    theme: "dark",
   });
   javaInstallations = $state<JavaInstallation[]>([]);
   isDetectingJava = $state(false);
@@ -21,6 +22,11 @@ export class SettingsState {
     try {
       const result = await invoke<LauncherConfig>("get_settings");
       this.settings = result;
+      // Force dark mode
+      if (this.settings.theme !== "dark") {
+          this.settings.theme = "dark";
+          this.saveSettings();
+      }
     } catch (e) {
       console.error("Failed to load settings:", e);
     }
diff --git a/ui/src/types/index.ts b/ui/src/types/index.ts
index fa48075..7e2cc67 100644
--- a/ui/src/types/index.ts
+++ b/ui/src/types/index.ts
@@ -34,6 +34,7 @@ export interface LauncherConfig {
   enable_gpu_acceleration: boolean;
   enable_visual_effects: boolean;
   active_effect: string;
+  theme: string;
 }
 
 export interface JavaInstallation {
-- 
cgit v1.2.3-70-g09d2


From 1b92b559a37166796d431ade745b31c4f73bc2ed Mon Sep 17 00:00:00 2001
From: "Begonia, HE" <163421589+BegoniaHe@users.noreply.github.com>
Date: Wed, 14 Jan 2026 22:20:41 +0100
Subject: fix(ui): correct styling bugs and code quality issues
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Fix missing h- prefix in VersionsView height class (-40 → h-40)
- Correct typo in SaturnEffect comment (Warn → Warm White)
- Remove double space in App.svelte class attribute
---
 ui/src/App.svelte                     | 2 +-
 ui/src/components/VersionsView.svelte | 2 +-
 ui/src/lib/effects/SaturnEffect.ts    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'ui/src/components/VersionsView.svelte')

diff --git a/ui/src/App.svelte b/ui/src/App.svelte
index 1c465b1..968f6c5 100644
--- a/ui/src/App.svelte
+++ b/ui/src/App.svelte
@@ -140,7 +140,7 @@
   
   {#if uiState.showConsole}
      <!-- Assuming GameConsole handles its own display mode or overlay -->
-    <div class="fixed inset-0 z-[100] bg-black/80  flex items-center justify-center p-10">
+    <div class="fixed inset-0 z-[100] bg-black/80 flex items-center justify-center p-10">
         <div class="w-full h-full bg-[#1e1e1e] rounded-xl overflow-hidden border border-white/10 shadow-2xl relative">
             <button class="absolute top-4 right-4 text-white hover:text-red-400 z-10" onclick={() => uiState.toggleConsole()}>✕</button>
             <GameConsole />
diff --git a/ui/src/components/VersionsView.svelte b/ui/src/components/VersionsView.svelte
index 8f3a568..99cc296 100644
--- a/ui/src/components/VersionsView.svelte
+++ b/ui/src/components/VersionsView.svelte
@@ -158,7 +158,7 @@
              Fetching manifest...
           </div>
         {:else if filteredVersions().length === 0}
-          <div class="flex flex-col items-center justify-center -40 dark:text-white/30 text-black/30 gap-2">
+          <div class="flex flex-col items-center justify-center h-40 dark:text-white/30 text-black/30 gap-2">
              <span class="text-2xl">👻</span>
              <span>No matching versions found</span>
           </div>
diff --git a/ui/src/lib/effects/SaturnEffect.ts b/ui/src/lib/effects/SaturnEffect.ts
index 8a1c11f..a370936 100644
--- a/ui/src/lib/effects/SaturnEffect.ts
+++ b/ui/src/lib/effects/SaturnEffect.ts
@@ -171,7 +171,7 @@ export class SaturnEffect {
 
             // Optimization: Planet color vs Ring color
             if (type === 0) {
-               // Planet: Warn White
+               // Planet: Warm White
                this.ctx.fillStyle = `rgba(255, 240, 220, ${alpha})`;
             } else {
                // Ring: Cool White
-- 
cgit v1.2.3-70-g09d2

