diff --git a/.github/workflows/tauri-release.yml b/.github/workflows/tauri-release.yml
index f1eb86c..1ccea35 100644
--- a/.github/workflows/tauri-release.yml
+++ b/.github/workflows/tauri-release.yml
@@ -30,30 +30,14 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        platform: [windows, macos, linux]
+        platform: [windows]
         include:
           - platform: windows
             os: windows-latest
-          - platform: macos
-            os: macos-latest
-          - platform: linux
-            os: ubuntu-latest
     steps:
       - name: Checkout
         uses: actions/checkout@v4
 
-      - name: Install Linux system deps
-        if: matrix.platform == 'linux'
-        run: |
-          sudo apt-get update
-          sudo apt-get install -y \
-            pkg-config \
-            libglib2.0-dev \
-            libgtk-3-dev \
-            librsvg2-dev \
-            libayatana-appindicator3-dev \
-            libwebkit2gtk-4.1-dev || sudo apt-get install -y libwebkit2gtk-4.0-dev
-
       - name: Install Rust
         uses: dtolnay/rust-toolchain@stable
 
diff --git a/.gitignore b/.gitignore
index 62ebd70..703b4a4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,6 @@ package-lock.json
 pnpm-lock.yaml
 yarn.lock
 bun.lockb
+backend-plan.md
+frontend-plan.md
+PLAN.md
diff --git a/README.md b/README.md
index 4bb4ebd..119f483 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,12 @@ Build faster. Control everything. Work from one environment.
 
 ---
 
+## ⬇️ Download
+
+Download **maxc_v0.1.1**:
+
+[![Windows](https://img.shields.io/badge/Windows-MSI-0078D6?logo=windows&logoColor=white)](https://github.com/Pollux-Studio/maxc/releases/tag/v0.1.1)
+
 ## ✨ Overview
 
 **maxc** is an open source developer workspace that brings **terminals, browser automation, logs, and task orchestration into one unified environment**.
@@ -203,40 +209,40 @@ maxc uses a modular architecture designed for performance and extensibility.
 maxc/
 
 core/
-  workspace_manager
-  pane_manager
-  surface_manager
+  workspace_manager     # workspace lifecycle + state
+  pane_manager          # split panes + layout state
+  surface_manager       # tabs/surfaces + routing
 
 terminal/
-  conpty_engine
-  terminal_parser
-  terminal_renderer
+  conpty_engine         # Windows PTY integration
+  terminal_parser       # VT parsing + buffer model
+  terminal_renderer     # terminal render pipeline
 
 browser/
-  chromium_runtime
-  playwright_driver
-  dom_controller
-  automation_api
+  chromium_runtime      # embedded Chromium runtime
+  playwright_driver     # browser automation driver
+  dom_controller        # DOM interaction layer
+  automation_api        # browser RPC/commands
 
 automation/
-  rpc_server
-  command_dispatcher
-  socket_protocol
+  rpc_server            # JSON-RPC server
+  command_dispatcher    # RPC method routing
+  socket_protocol       # transport + protocol
 
 ui/
-  window_manager
-  layout_engine
-  sidebar
-  surface_tabs
+  window_manager        # top-level window system
+  layout_engine         # pane/surface layout
+  sidebar               # workspace + metadata sidebar
+  surface_tabs          # tab strip + surface switching
 
 notifications/
-  desktop_notifications
+  desktop_notifications # native notifications
 
 cli/
-  command_parser
+  command_parser        # CLI parsing + commands
 
 config/
-  configuration_loader
+  configuration_loader  # config files + defaults
 ```
 
 ## 🖥 Terminal Engine
@@ -402,45 +408,22 @@ maxc is built with modern systems technologies.
 * Clap CLI framework
 * Serde JSON RPC
 
-## 🗺 Development Roadmap
-
-### Phase 1
-
-Core workspace foundations
-
-* terminal + browser surface models
-* pane splitting
-* surface tabs
-
-### Phase 2
-
-Workspace manager
-
-* sidebar
-* workspace switching
-* CLI control
-
-### Phase 3
-
-Browser surfaces
-
-* embedded browser
-* DOM automation
+## 📦 v0.1.2 Roadmap
 
-### Phase 4
+Roadmap:
 
-Automation API
+* Update installer fix
+* Initial install backend not started fix
 
-* socket RPC server
-* command dispatcher
+Improvements:
 
-### Phase 5
+* Settings UI improved
+* App icon improved
 
-Notifications and metadata
+Added:
 
-* status indicators
-* progress tracking
-* sidebar logs
+* Logs page added
+* Shortcut customization added
 
 ## 📚 Documentation
 
@@ -461,7 +444,7 @@ Ways to contribute:
 
 maxc is released as **Free and Open Source Software (FOSS)**.
 
-License details will be added in the LICENSE file.
+License: [Apache-2.0](LICENSE).
 
 ## ❤️ Final Words
 
diff --git a/maxc-landing-page/.gitignore b/maxc-landing-page/.gitignore
new file mode 100644
index 0000000..c4ea510
--- /dev/null
+++ b/maxc-landing-page/.gitignore
@@ -0,0 +1,43 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.*
+.yarn/*
+!.yarn/patches
+!.yarn/plugins
+!.yarn/releases
+!.yarn/versions
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+.pnpm-debug.log*
+
+# env files (can opt-in for committing if needed)
+.env*
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
+
+.vercel
diff --git a/maxc-landing-page/README.md b/maxc-landing-page/README.md
new file mode 100644
index 0000000..e215bc4
--- /dev/null
+++ b/maxc-landing-page/README.md
@@ -0,0 +1,36 @@
+This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
+
+## Getting Started
+
+First, run the development server:
+
+```bash
+npm run dev
+# or
+yarn dev
+# or
+pnpm dev
+# or
+bun dev
+```
+
+Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+
+You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
+
+This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
+
+## Learn More
+
+To learn more about Next.js, take a look at the following resources:
+
+- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
+- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+
+You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
+
+## Deploy on Vercel
+
+The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
+
+Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
diff --git a/maxc-landing-page/app/docs/page.tsx b/maxc-landing-page/app/docs/page.tsx
new file mode 100644
index 0000000..a9398b7
--- /dev/null
+++ b/maxc-landing-page/app/docs/page.tsx
@@ -0,0 +1,107 @@
+import Link from "next/link";
+import { Navbar } from "@/components/landing/navbar";
+import { Footer } from "@/components/landing/footer";
+
+export default function DocsPage() {
+  return (
+    <main className="min-h-screen bg-[var(--background)] text-foreground">
+      <Navbar />
+
+      <section className="wrapper wrapper--ticks border-t border-nickel px-6 sm:px-10 py-14 sm:py-20">
+        <div className="flex flex-col gap-4">
+          <div className="flex flex-wrap items-center gap-3">
+            <h1 className="text-white text-3xl sm:text-4xl font-bold tracking-tight">Docs</h1>
+            <span className="text-[10px] uppercase tracking-widest text-black bg-white rounded-full px-2 py-1">
+              Stable
+            </span>
+          </div>
+          <p className="text-white/70 text-sm max-w-2xl">
+            Everything you need to run maxc locally, automate it with the CLI, and wire it into your agent workflows.
+          </p>
+        </div>
+      </section>
+
+      <section className="wrapper border-t border-nickel grid lg:grid-cols-2 divide-x divide-y divide-nickel">
+        <div className="p-6 sm:p-10 flex flex-col gap-4">
+          <h2 className="text-white text-xl font-semibold">Quick Start</h2>
+          <p className="text-white/50 text-sm leading-relaxed">
+            Install the desktop app, open a workspace, and attach terminals or browsers in seconds.
+          </p>
+          <div className="rounded-lg border border-[rgba(255,255,255,0.08)] bg-[#0f1117] p-4">
+            <div className="text-xs text-white/50 font-mono uppercase tracking-wide">Steps</div>
+            <ol className="mt-3 space-y-2 text-sm text-white/80">
+              <li>1. Download the installer for your OS.</li>
+              <li>2. Launch maxc and create a workspace.</li>
+              <li>3. Spawn a terminal or browser surface.</li>
+            </ol>
+          </div>
+        </div>
+
+        <div className="p-6 sm:p-10 flex flex-col gap-4 border-r-0">
+          <h2 className="text-white text-xl font-semibold">CLI</h2>
+          <p className="text-white/50 text-sm leading-relaxed">
+            Control every surface programmatically with one-line commands.
+          </p>
+          <div className="rounded-lg border border-[rgba(255,255,255,0.08)] bg-[#0f1117] p-4">
+            <pre className="text-xs font-mono text-white/80 leading-6">
+              <span className="text-white/50">$ </span>maxc terminal spawn
+              {"\n"}
+              <span className="text-white/50">$ </span>maxc browser open http://localhost:3000
+              {"\n"}
+              <span className="text-white/50">$ </span>maxc notify --title "Done" --level success
+            </pre>
+          </div>
+        </div>
+      </section>
+
+      <section className="wrapper border-t border-nickel grid lg:grid-cols-2 divide-x divide-y divide-nickel">
+        <div className="p-6 sm:p-10 flex flex-col gap-4">
+          <h2 className="text-white text-xl font-semibold">RPC</h2>
+          <p className="text-white/50 text-sm leading-relaxed">
+            Use JSON-RPC to drive workspaces and surfaces from any agent or script.
+          </p>
+          <div className="rounded-lg border border-[rgba(255,255,255,0.08)] bg-[#0f1117] p-4">
+            <pre className="text-xs font-mono text-white/80 leading-6">
+              {"{"}
+              {"\n"}  "id": "req-1",
+              {"\n"}  "method": "workspace.list",
+              {"\n"}  "params": {}
+              {"\n"}{"}"}
+            </pre>
+          </div>
+        </div>
+
+        <div className="p-6 sm:p-10 flex flex-col gap-4 border-r-0">
+          <h2 className="text-white text-xl font-semibold">Configuration</h2>
+          <p className="text-white/50 text-sm leading-relaxed">
+            Tune fonts, scrollback, and workspace defaults through the config file.
+          </p>
+          <div className="rounded-lg border border-[rgba(255,255,255,0.08)] bg-[#0f1117] p-4">
+            <pre className="text-xs font-mono text-white/80 leading-6">
+              font-family = "JetBrains Mono"
+              {"\n"}font-size = 14
+              {"\n"}scrollback-limit = 50000
+            </pre>
+          </div>
+        </div>
+      </section>
+
+      <section className="wrapper border-t border-nickel px-6 sm:px-10 py-12">
+        <div className="rounded-xl border border-[rgba(255,255,255,0.08)] bg-white/[0.02] p-6 flex flex-col gap-3">
+          <h2 className="text-white text-xl font-semibold">Downloads</h2>
+          <p className="text-white/50 text-sm">
+            Grab the latest stable installer from the downloads page.
+          </p>
+          <Link
+            href="/downloads"
+            className="inline-flex w-fit items-center gap-2 px-4 py-2 text-sm font-semibold rounded-lg bg-white text-black hover:opacity-85 transition-opacity"
+          >
+            Go to Downloads
+          </Link>
+        </div>
+      </section>
+
+      <Footer />
+    </main>
+  );
+}
diff --git a/maxc-landing-page/app/downloads/page.tsx b/maxc-landing-page/app/downloads/page.tsx
new file mode 100644
index 0000000..df47918
--- /dev/null
+++ b/maxc-landing-page/app/downloads/page.tsx
@@ -0,0 +1,182 @@
+import Image from "next/image";
+import { Navbar } from "@/components/landing/navbar";
+import { Footer } from "@/components/landing/footer";
+
+export const dynamic = "force-dynamic";
+
+type PlatformEntry = {
+  signature: string;
+  url: string;
+};
+
+type LatestJson = {
+  version: string;
+  notes: string;
+  pub_date: string;
+  platforms: Record<string, PlatformEntry>;
+};
+
+type Asset = {
+  name: string;
+  url: string;
+  signature: string;
+  platformKey: string;
+};
+
+const latestJsonUrl =
+  "https://github.com/Pollux-Studio/maxc/releases/download/stable/latest.json";
+
+const getFileName = (url: string) => {
+  const parts = url.split("/");
+  return parts[parts.length - 1] || url;
+};
+
+const formatDate = (value: string) => {
+  const date = new Date(value);
+  if (Number.isNaN(date.getTime())) return value;
+  return date.toLocaleString("en-US", { dateStyle: "medium", timeStyle: "short" });
+};
+
+const dedupeByUrl = (assets: Asset[]) => {
+  const map = new Map<string, Asset>();
+  for (const asset of assets) {
+    if (!map.has(asset.url)) {
+      map.set(asset.url, asset);
+    }
+  }
+  return Array.from(map.values());
+};
+
+const getPlatformLabel = (platformKey: string) =>
+  platformKey.replace(/-/g, " ").replace(/_/g, " ").trim();
+
+function WindowsLogo({ className }: { className?: string }) {
+  return (
+    <svg
+      viewBox="0 0 24 24"
+      aria-hidden="true"
+      className={className}
+      fill="currentColor"
+    >
+      <rect x="2" y="3" width="9" height="8" rx="1" />
+      <rect x="13" y="3" width="9" height="8" rx="1" />
+      <rect x="2" y="13" width="9" height="8" rx="1" />
+      <rect x="13" y="13" width="9" height="8" rx="1" />
+    </svg>
+  );
+}
+
+function AssetRow({ asset }: { asset: Asset }) {
+  return (
+    <div className="rounded-lg border border-[rgba(255,255,255,0.08)] bg-white/[0.02] px-4 py-3">
+      <div className="flex items-start justify-between gap-4">
+        <div>
+          <div className="text-sm text-white/85 font-mono break-all">{asset.name}</div>
+          <div className="text-[10px] text-white/40 mt-1">{getPlatformLabel(asset.platformKey)}</div>
+        </div>
+        <a
+          href={asset.url}
+          className="text-xs font-semibold text-black bg-white rounded-md px-3 py-1.5 whitespace-nowrap hover:opacity-85 transition-opacity"
+        >
+          Download
+        </a>
+      </div>
+    </div>
+  );
+}
+
+export default async function DownloadsPage() {
+  const response = await fetch(latestJsonUrl, { cache: "no-store" });
+  const latest = (await response.json()) as LatestJson;
+
+  const assets = dedupeByUrl(
+    Object.entries(latest.platforms).map(([platformKey, entry]) => ({
+      name: getFileName(entry.url),
+      url: entry.url,
+      signature: entry.signature,
+      platformKey,
+    }))
+  );
+
+  const windowsAssets = assets.filter((asset) => asset.platformKey.startsWith("windows"));
+  const macAssets = assets.filter((asset) => asset.platformKey.startsWith("darwin"));
+  const linuxAssets = assets.filter((asset) => asset.platformKey.startsWith("linux"));
+
+  return (
+    <main className="min-h-screen bg-[var(--background)] text-foreground">
+      <Navbar />
+
+      <section className="wrapper wrapper--ticks border-t border-nickel px-6 sm:px-10 py-14 sm:py-20">
+        <div className="flex flex-col gap-4">
+          <div className="flex flex-wrap items-center gap-3">
+            <h1 className="text-white text-3xl sm:text-4xl font-bold tracking-tight">Downloads</h1>
+            <span className="text-[10px] uppercase tracking-widest text-black bg-white rounded-full px-2 py-1">
+              Latest
+            </span>
+          </div>
+          <div className="text-white/70 text-sm">
+            maxc stable &middot; version {latest.version} &middot; published {formatDate(latest.pub_date)}
+          </div>
+          <div className="text-white/50 text-sm">{latest.notes}</div>
+        </div>
+      </section>
+
+      <section className="wrapper wrapper--ticks border-t border-nickel px-6 sm:px-10 py-10">
+        <div className="grid gap-6 lg:grid-cols-3">
+          <div className="rounded-xl border border-[rgba(255,255,255,0.08)] bg-white/[0.02] p-5">
+            <div className="flex items-center gap-2">
+              <WindowsLogo className="h-5 w-5 text-white/70" />
+              <div className="text-white font-semibold text-lg">Windows</div>
+            </div>
+            <div className="text-white/40 text-xs mt-1">x64</div>
+            <div className="mt-5 space-y-3">
+              {windowsAssets.map((asset) => (
+                <AssetRow key={asset.url} asset={asset} />
+              ))}
+            </div>
+          </div>
+
+          <div className="rounded-xl border border-[rgba(255,255,255,0.08)] bg-white/[0.02] p-5">
+            <div className="flex items-center gap-2">
+              <Image
+                src="/apple-logo-svgrepo-com.svg"
+                alt="Apple"
+                width={20}
+                height={20}
+                className="h-5 w-5 object-contain invert opacity-70"
+              />
+              <div className="text-white font-semibold text-lg">macOS</div>
+            </div>
+            <div className="text-white/40 text-xs mt-1">Apple Silicon</div>
+            <div className="mt-5 space-y-3">
+              {macAssets.map((asset) => (
+                <AssetRow key={asset.url} asset={asset} />
+              ))}
+            </div>
+          </div>
+
+          <div className="rounded-xl border border-[rgba(255,255,255,0.08)] bg-white/[0.02] p-5">
+            <div className="flex items-center gap-2">
+              <Image
+                src="/linux-svgrepo-com.svg"
+                alt="Linux"
+                width={20}
+                height={20}
+                className="h-5 w-5 object-contain grayscale invert opacity-70"
+              />
+              <div className="text-white font-semibold text-lg">Linux</div>
+            </div>
+            <div className="text-white/40 text-xs mt-1">AppImage, DEB, RPM</div>
+            <div className="mt-5 space-y-3">
+              {linuxAssets.map((asset) => (
+                <AssetRow key={asset.url} asset={asset} />
+              ))}
+            </div>
+          </div>
+        </div>
+      </section>
+
+      <Footer />
+    </main>
+  );
+}
diff --git a/maxc-landing-page/app/examples/page.tsx b/maxc-landing-page/app/examples/page.tsx
new file mode 100644
index 0000000..ef02867
--- /dev/null
+++ b/maxc-landing-page/app/examples/page.tsx
@@ -0,0 +1,45 @@
+import { Navbar } from "@/components/landing/navbar";
+import { Footer } from "@/components/landing/footer";
+
+const examples = [
+  {
+    title: "Automated test runner",
+    desc: "Spawn a terminal, run test suites, and notify agents on completion.",
+  },
+  {
+    title: "Browser regression sweep",
+    desc: "Open Chromium, execute scripted flows, and capture screenshots.",
+  },
+  {
+    title: "Agent-driven build pipeline",
+    desc: "Coordinate multiple AI agents to compile, lint, and deploy.",
+  },
+];
+
+export default function ExamplesPage() {
+  return (
+    <main className="min-h-screen bg-[var(--background)] text-foreground">
+      <Navbar />
+
+      <section className="wrapper wrapper--ticks border-t border-nickel px-6 sm:px-10 py-14 sm:py-20">
+        <div className="flex flex-col gap-4">
+          <h1 className="text-white text-3xl sm:text-4xl font-bold tracking-tight">Examples</h1>
+          <p className="text-white/60 text-sm max-w-2xl">
+            Practical workflows that show how maxc automates terminals, browsers, and AI agents.
+          </p>
+        </div>
+      </section>
+
+      <section className="wrapper border-t border-nickel grid lg:grid-cols-3 divide-x divide-y divide-nickel">
+        {examples.map((example, index) => (
+          <div key={example.title} className={`p-6 sm:p-10 ${index === examples.length - 1 ? "lg:border-r-0" : ""}`}>
+            <h2 className="text-white text-lg font-semibold">{example.title}</h2>
+            <p className="mt-3 text-white/50 text-sm leading-relaxed">{example.desc}</p>
+          </div>
+        ))}
+      </section>
+
+      <Footer />
+    </main>
+  );
+}
diff --git a/maxc-landing-page/app/favicon.ico b/maxc-landing-page/app/favicon.ico
new file mode 100644
index 0000000..718d6fe
Binary files /dev/null and b/maxc-landing-page/app/favicon.ico differ
diff --git a/maxc-landing-page/app/github/page.tsx b/maxc-landing-page/app/github/page.tsx
new file mode 100644
index 0000000..07a48fb
--- /dev/null
+++ b/maxc-landing-page/app/github/page.tsx
@@ -0,0 +1,29 @@
+import { Navbar } from "@/components/landing/navbar";
+import { Footer } from "@/components/landing/footer";
+
+export default function GitHubPage() {
+  return (
+    <main className="min-h-screen bg-[var(--background)] text-foreground">
+      <Navbar />
+
+      <section className="wrapper wrapper--ticks border-t border-nickel px-6 sm:px-10 py-14 sm:py-20">
+        <div className="flex flex-col gap-4">
+          <h1 className="text-white text-3xl sm:text-4xl font-bold tracking-tight">GitHub</h1>
+          <p className="text-white/60 text-sm max-w-2xl">
+            Explore the maxc source code, releases, and contribution guides on GitHub.
+          </p>
+          <a
+            href="https://github.com/Pollux-Studio/maxc"
+            className="inline-flex w-fit items-center gap-2 px-4 py-2 text-sm font-semibold rounded-lg bg-white text-black hover:opacity-85 transition-opacity"
+            target="_blank"
+            rel="noreferrer"
+          >
+            Visit GitHub
+          </a>
+        </div>
+      </section>
+
+      <Footer />
+    </main>
+  );
+}
diff --git a/maxc-landing-page/app/globals.css b/maxc-landing-page/app/globals.css
new file mode 100644
index 0000000..4c90598
--- /dev/null
+++ b/maxc-landing-page/app/globals.css
@@ -0,0 +1,196 @@
+@import "tailwindcss";
+@import "tw-animate-css";
+@import "shadcn/tailwind.css";
+
+@custom-variant dark (&:is(.dark *));
+
+:root {
+  --muted: oklch(0.97 0 0);
+  --card: oklch(1 0 0);
+  --border: oklch(0.922 0 0);
+  --accent: oklch(0.97 0 0);
+  --accent-strong: #ffffff;
+  --accent-foreground: oklch(0.205 0 0);
+  --background: oklch(1 0 0);
+  --foreground: oklch(0.145 0 0);
+  --card-foreground: oklch(0.145 0 0);
+  --popover: oklch(1 0 0);
+  --popover-foreground: oklch(0.145 0 0);
+  --primary: oklch(0.205 0 0);
+  --primary-foreground: oklch(0.985 0 0);
+  --secondary: oklch(0.97 0 0);
+  --secondary-foreground: oklch(0.205 0 0);
+  --muted-foreground: oklch(0.556 0 0);
+  --destructive: oklch(0.577 0.245 27.325);
+  --input: oklch(0.922 0 0);
+  --ring: oklch(0.708 0 0);
+  --chart-1: oklch(0.809 0.105 251.813);
+  --chart-2: oklch(0.623 0.214 259.815);
+  --chart-3: oklch(0.546 0.245 262.881);
+  --chart-4: oklch(0.488 0.243 264.376);
+  --chart-5: oklch(0.424 0.199 265.638);
+  --radius: 0.625rem;
+  --sidebar: oklch(0.985 0 0);
+  --sidebar-foreground: oklch(0.145 0 0);
+  --sidebar-primary: oklch(0.205 0 0);
+  --sidebar-primary-foreground: oklch(0.985 0 0);
+  --sidebar-accent: oklch(0.97 0 0);
+  --sidebar-accent-foreground: oklch(0.205 0 0);
+  --sidebar-border: oklch(0.922 0 0);
+  --sidebar-ring: oklch(0.708 0 0);
+
+  --color-nickel: rgba(255, 255, 255, 0.08);
+  --color-slate-bg: #0f1117;
+  --color-grey: rgba(255, 255, 255, 0.45);
+  --color-stroke: rgba(255, 255, 255, 0.08);
+}
+
+@theme inline {
+  --color-background: var(--background);
+  --color-foreground: var(--foreground);
+  --font-sans: var(--font-sans);
+  --font-mono: var(--font-jetbrains);
+  --color-sidebar-ring: var(--sidebar-ring);
+  --color-sidebar-border: var(--sidebar-border);
+  --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
+  --color-sidebar-accent: var(--sidebar-accent);
+  --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
+  --color-sidebar-primary: var(--sidebar-primary);
+  --color-sidebar-foreground: var(--sidebar-foreground);
+  --color-sidebar: var(--sidebar);
+  --color-chart-5: var(--chart-5);
+  --color-chart-4: var(--chart-4);
+  --color-chart-3: var(--chart-3);
+  --color-chart-2: var(--chart-2);
+  --color-chart-1: var(--chart-1);
+  --color-ring: var(--ring);
+  --color-input: var(--input);
+  --color-border: var(--border);
+  --color-destructive: var(--destructive);
+  --color-accent-foreground: var(--accent-foreground);
+  --color-accent: var(--accent);
+  --color-muted-foreground: var(--muted-foreground);
+  --color-muted: var(--muted);
+  --color-secondary-foreground: var(--secondary-foreground);
+  --color-secondary: var(--secondary);
+  --color-primary-foreground: var(--primary-foreground);
+  --color-primary: var(--primary);
+  --color-popover-foreground: var(--popover-foreground);
+  --color-popover: var(--popover);
+  --color-card-foreground: var(--card-foreground);
+  --color-card: var(--card);
+  --radius-sm: calc(var(--radius) * 0.6);
+  --radius-md: calc(var(--radius) * 0.8);
+  --radius-lg: var(--radius);
+  --radius-xl: calc(var(--radius) * 1.4);
+  --radius-2xl: calc(var(--radius) * 1.8);
+  --radius-3xl: calc(var(--radius) * 2.2);
+  --radius-4xl: calc(var(--radius) * 2.6);
+}
+
+body {
+  font-family: var(--font-space), system-ui, sans-serif;
+}
+
+::selection {
+  background: rgba(255, 255, 255, 0.2);
+}
+
+/* Scrollbar */
+* {
+  scrollbar-width: thin;
+  scrollbar-color: rgba(255, 255, 255, 0.2) rgba(8, 6, 13, 0.2);
+}
+
+*::-webkit-scrollbar {
+  width: 10px;
+  height: 10px;
+}
+
+*::-webkit-scrollbar-track {
+  background: #0b0d12;
+}
+
+*::-webkit-scrollbar-thumb {
+  background: rgba(255, 255, 255, 0.18);
+  border-radius: 999px;
+  border: 2px solid #0b0d12;
+}
+
+*::-webkit-scrollbar-thumb:hover {
+  background: rgba(255, 255, 255, 0.3);
+}
+
+/* ---- Vite-style wrapper ---- */
+.wrapper {
+  max-width: 1280px;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+.wrapper--ticks {
+  border-left: 1px solid var(--color-nickel);
+  border-right: 1px solid var(--color-nickel);
+}
+
+.border-nickel {
+  border-color: var(--color-nickel);
+}
+
+.divide-nickel > :not([hidden]) ~ :not([hidden]) {
+  border-color: var(--color-nickel);
+}
+
+.text-grey {
+  color: var(--color-grey);
+}
+
+.bg-slate-custom {
+  background-color: var(--color-slate-bg);
+}
+
+.dark {
+  --background: #08060d;
+  --foreground: oklch(0.985 0 0);
+  --card: #0f1117;
+  --card-foreground: oklch(0.985 0 0);
+  --popover: #0f1117;
+  --popover-foreground: oklch(0.985 0 0);
+  --primary: #08060d;
+  --primary-foreground: oklch(0.985 0 0);
+  --secondary: oklch(0.269 0 0);
+  --secondary-foreground: oklch(0.985 0 0);
+  --muted: oklch(0.269 0 0);
+  --muted-foreground: oklch(0.708 0 0);
+  --accent: oklch(0.269 0 0);
+  --accent-foreground: oklch(0.985 0 0);
+  --destructive: oklch(0.704 0.191 22.216);
+  --border: var(--color-nickel);
+  --input: oklch(1 0 0 / 15%);
+  --ring: oklch(0.556 0 0);
+  --chart-1: oklch(0.809 0.105 251.813);
+  --chart-2: oklch(0.623 0.214 259.815);
+  --chart-3: oklch(0.546 0.245 262.881);
+  --chart-4: oklch(0.488 0.243 264.376);
+  --chart-5: oklch(0.424 0.199 265.638);
+  --sidebar: #0f1117;
+  --sidebar-foreground: oklch(0.985 0 0);
+  --sidebar-primary: oklch(0.488 0.243 264.376);
+  --sidebar-primary-foreground: oklch(0.985 0 0);
+  --sidebar-accent: oklch(0.269 0 0);
+  --sidebar-accent-foreground: oklch(0.985 0 0);
+  --sidebar-border: var(--color-nickel);
+  --sidebar-ring: oklch(0.556 0 0);
+}
+
+@layer base {
+  * {
+    @apply border-border outline-ring/50;
+  }
+  body {
+    @apply bg-background text-foreground;
+  }
+  html {
+    @apply font-sans;
+  }
+}
diff --git a/maxc-landing-page/app/layout.tsx b/maxc-landing-page/app/layout.tsx
new file mode 100644
index 0000000..efaf2f2
--- /dev/null
+++ b/maxc-landing-page/app/layout.tsx
@@ -0,0 +1,92 @@
+import type { Metadata } from "next";
+import { JetBrains_Mono, Space_Grotesk, Geist } from "next/font/google";
+import { Analytics } from "@vercel/analytics/next";
+import "./globals.css";
+import { cn } from "@/lib/utils";
+
+const geist = Geist({subsets:['latin'],variable:'--font-sans'});
+
+const spaceGrotesk = Space_Grotesk({
+  variable: "--font-space",
+  subsets: ["latin"],
+});
+
+const jetbrainsMono = JetBrains_Mono({
+  variable: "--font-jetbrains",
+  subsets: ["latin"],
+});
+
+export const metadata: Metadata = {
+  metadataBase: new URL("https://maxc.polluxstudio.in"),
+  title: "maxc - Workspace for AI Coding Agents",
+  description:
+    "maxc is a programmable workspace for AI coding agents. Run terminals, automate browsers, and orchestrate AI agents from one developer environment.",
+  keywords: [
+    "AI coding agents",
+    "developer automation tools",
+    "terminal workspace",
+    "browser automation tools",
+    "AI development environment",
+    "agent orchestration",
+    "developer productivity tools",
+  ],
+  openGraph: {
+    title: "maxc - Control Center for AI Coding Agents",
+    description:
+      "Run terminals, control browsers, and orchestrate AI agents from one programmable workspace.",
+    url: "https://maxc.polluxstudio.in",
+    siteName: "maxc",
+    images: [
+      {
+        url: "https://maxc.polluxstudio.in/og-image.png",
+        width: 1200,
+        height: 630,
+        alt: "maxc - Control Center for AI Coding Agents",
+      },
+    ],
+    type: "website",
+  },
+  twitter: {
+    card: "summary_large_image",
+    title: "maxc - AI Coding Agent Workspace",
+    description: "Run terminals, browsers, and AI agents in one programmable workspace.",
+    images: ["https://maxc.polluxstudio.in/og-image.png"],
+  },
+  icons: {
+    icon: "/maxc_logo_full_white_single.svg",
+  },
+};
+
+export default function RootLayout({
+  children,
+}: Readonly<{
+  children: React.ReactNode;
+}>) {
+  const structuredData = {
+    "@context": "https://schema.org",
+    "@type": "SoftwareApplication",
+    name: "maxc",
+    applicationCategory: "DeveloperApplication",
+    description:
+      "maxc is a programmable workspace for AI coding agents that allows developers to run terminals, automate browsers, and orchestrate agent workflows.",
+    operatingSystem: ["Windows", "macOS", "Linux"],
+    url: "https://maxc.polluxstudio.in",
+  };
+
+  return (
+    <html lang="en" className={cn("dark font-sans", geist.variable)}>
+      <head>
+        <script
+          type="application/ld+json"
+          dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
+        />
+      </head>
+      <body
+        className={`${spaceGrotesk.variable} ${jetbrainsMono.variable} antialiased`}
+      >
+        {children}
+        <Analytics />
+      </body>
+    </html>
+  );
+}
diff --git a/maxc-landing-page/app/page.tsx b/maxc-landing-page/app/page.tsx
new file mode 100644
index 0000000..2a6f1eb
--- /dev/null
+++ b/maxc-landing-page/app/page.tsx
@@ -0,0 +1,27 @@
+import { Navbar } from "@/components/landing/navbar";
+import { Hero } from "@/components/landing/hero";
+import { Trust } from "@/components/landing/trust";
+import { Features } from "@/components/landing/features";
+import { Product } from "@/components/landing/product";
+import { Architecture } from "@/components/landing/architecture";
+import { CliShowcase } from "@/components/landing/cli-showcase";
+import { OpenSource } from "@/components/landing/open-source";
+import { CTA } from "@/components/landing/cta";
+import { Footer } from "@/components/landing/footer";
+
+export default function Home() {
+  return (
+    <main className="min-h-screen bg-[var(--background)] text-foreground">
+      <Navbar />
+      <Hero />
+      <Trust />
+      <Features />
+      <Product />
+      <Architecture />
+      <CliShowcase />
+      <OpenSource />
+      <CTA />
+      <Footer />
+    </main>
+  );
+}
diff --git a/maxc-landing-page/app/sitemap.ts b/maxc-landing-page/app/sitemap.ts
new file mode 100644
index 0000000..1b40311
--- /dev/null
+++ b/maxc-landing-page/app/sitemap.ts
@@ -0,0 +1,24 @@
+import type { MetadataRoute } from "next";
+
+export default function sitemap(): MetadataRoute.Sitemap {
+  const baseUrl = "https://maxc.polluxstudio.in";
+
+  return [
+    {
+      url: baseUrl,
+      lastModified: new Date(),
+    },
+    {
+      url: `${baseUrl}/docs`,
+      lastModified: new Date(),
+    },
+    {
+      url: `${baseUrl}/downloads`,
+      lastModified: new Date(),
+    },
+    {
+      url: `${baseUrl}/github`,
+      lastModified: new Date(),
+    },
+  ];
+}
diff --git a/maxc-landing-page/components.json b/maxc-landing-page/components.json
new file mode 100644
index 0000000..02e61e0
--- /dev/null
+++ b/maxc-landing-page/components.json
@@ -0,0 +1,25 @@
+{
+  "$schema": "https://ui.shadcn.com/schema.json",
+  "style": "radix-nova",
+  "rsc": true,
+  "tsx": true,
+  "tailwind": {
+    "config": "",
+    "css": "app/globals.css",
+    "baseColor": "neutral",
+    "cssVariables": true,
+    "prefix": ""
+  },
+  "iconLibrary": "lucide",
+  "rtl": false,
+  "aliases": {
+    "components": "@/components",
+    "utils": "@/lib/utils",
+    "ui": "@/components/ui",
+    "lib": "@/lib",
+    "hooks": "@/hooks"
+  },
+  "menuColor": "default",
+  "menuAccent": "subtle",
+  "registries": {}
+}
diff --git a/maxc-landing-page/components/landing/architecture.tsx b/maxc-landing-page/components/landing/architecture.tsx
new file mode 100644
index 0000000..cae1b10
--- /dev/null
+++ b/maxc-landing-page/components/landing/architecture.tsx
@@ -0,0 +1,58 @@
+export function Architecture() {
+  return (
+    <section
+      id="architecture"
+      className="wrapper wrapper--ticks border-t border-nickel grid lg:grid-cols-2 divide-x divide-y divide-nickel"
+    >
+      <div className="p-5 sm:p-10 flex flex-col gap-3">
+        <h2 className="text-white text-xl font-semibold">A programmable developer environment</h2>
+        <p className="sm:max-w-[28rem] text-white/50 text-pretty text-sm leading-relaxed">
+          The Rust backend processes every command through an event-sourced pipeline. All state is recoverable, all actions are replayable.
+        </p>
+        <p className="sm:max-w-[28rem] text-white/50 text-pretty text-sm leading-relaxed">
+          Agents connect via CLI commands, JSON-RPC socket, or environment hooks. No SDK required.
+        </p>
+      </div>
+
+      <div className="flex flex-col gap-3 justify-center border-r-0 p-5 sm:p-10">
+        <div className="font-mono text-sm space-y-2">
+          {[
+            { label: "Frontend UI", sub: "Tauri + React + xterm.js", color: "text-blue-400" },
+            { label: "RPC Client", sub: "JSON-RPC over named pipe", color: "text-cyan-400" },
+            { label: "maxc Backend", sub: "Rust automation server", color: "text-white/70" },
+          ].map((layer, i, arr) => (
+            <div key={layer.label}>
+              <div className="rounded-md border border-[rgba(255,255,255,0.08)] bg-white/[0.02] px-4 py-3 text-center">
+                <div className={`text-xs font-semibold ${layer.color}`}>{layer.label}</div>
+                <div className="text-[10px] text-white/30 mt-0.5">{layer.sub}</div>
+              </div>
+              {i < arr.length - 1 && (
+                <div className="flex justify-center py-1">
+                  <div className="w-px h-4 bg-white/10" />
+                </div>
+              )}
+            </div>
+          ))}
+
+          <div className="flex justify-center py-1">
+            <div className="w-px h-4 bg-white/10" />
+          </div>
+
+          <div className="grid grid-cols-2 gap-2">
+            {[
+              { label: "Terminal", sub: "ConPTY / PTY" },
+              { label: "Browser", sub: "Chromium CDP" },
+              { label: "Agent", sub: "Worker + Task" },
+              { label: "Events", sub: "Append-only log" },
+            ].map((rt) => (
+              <div key={rt.label} className="rounded-md border border-[rgba(255,255,255,0.08)] bg-white/[0.02] px-3 py-2 text-center">
+                <div className="text-[10px] font-semibold text-white/60">{rt.label}</div>
+                <div className="text-[9px] text-white/25 mt-0.5">{rt.sub}</div>
+              </div>
+            ))}
+          </div>
+        </div>
+      </div>
+    </section>
+  );
+}
diff --git a/maxc-landing-page/components/landing/cli-showcase.tsx b/maxc-landing-page/components/landing/cli-showcase.tsx
new file mode 100644
index 0000000..3619cd9
--- /dev/null
+++ b/maxc-landing-page/components/landing/cli-showcase.tsx
@@ -0,0 +1,45 @@
+const commands = [
+  { cmd: "maxc terminal spawn", desc: "Create a new terminal session" },
+  { cmd: 'maxc terminal input "npm run dev"', desc: "Send input to a terminal" },
+  { cmd: "maxc browser open http://localhost:3000", desc: "Open a browser and navigate" },
+  { cmd: 'maxc run "npm test"', desc: "One command to spawn + run" },
+  { cmd: 'maxc notify --title "Done" --level success', desc: "Send a notification" },
+];
+
+export function CliShowcase() {
+  return (
+    <section
+      id="cli"
+      className="wrapper wrapper--ticks border-t border-nickel grid lg:grid-cols-2 divide-x divide-y divide-nickel"
+    >
+      <div className="p-5 sm:p-10 flex flex-col gap-3">
+        <h5 className="text-white font-semibold">Control everything from the command line</h5>
+        <p className="sm:max-w-[28rem] text-white/50 text-pretty text-sm leading-relaxed">
+          Any AI agent that can run shell commands can control maxc. No SDK, no adapters, no configuration.
+        </p>
+        <p className="sm:max-w-[28rem] text-white/50 text-pretty text-sm leading-relaxed">
+          Works with Claude Code, OpenAI Codex, Cursor, OpenCode, or custom Python agents.
+        </p>
+      </div>
+
+      <div className="flex flex-col gap-3 justify-center border-r-0 p-5 sm:p-10">
+        <div className="rounded-lg overflow-hidden border border-[rgba(255,255,255,0.08)] bg-[#0a0c10]">
+          <div className="flex items-center gap-2 border-b border-[rgba(255,255,255,0.08)] px-4 py-2.5 bg-[#0d0f14]">
+            <span className="text-xs text-grey font-mono">terminal</span>
+          </div>
+          <div className="p-4 font-mono text-xs space-y-3">
+            {commands.map((c) => (
+              <div key={c.cmd}>
+                <div className="flex items-start gap-2">
+                  <span className="text-white/60 select-none shrink-0">$</span>
+                  <span className="text-white/80">{c.cmd}</span>
+                </div>
+                <div className="text-white/20 ml-4 mt-0.5 text-[10px]"># {c.desc}</div>
+              </div>
+            ))}
+          </div>
+        </div>
+      </div>
+    </section>
+  );
+}
diff --git a/maxc-landing-page/components/landing/cta.tsx b/maxc-landing-page/components/landing/cta.tsx
new file mode 100644
index 0000000..abdfedb
--- /dev/null
+++ b/maxc-landing-page/components/landing/cta.tsx
@@ -0,0 +1,22 @@
+import Link from "next/link";
+
+export function CTA() {
+  return (
+    <section className="wrapper wrapper--ticks border-t border-nickel px-5 sm:px-10 py-20 sm:py-32 flex flex-col justify-center items-center text-center">
+      <h3 className="text-white max-w-2xl text-balance text-3xl sm:text-4xl font-bold tracking-tight">
+        Start building with maxc today
+      </h3>
+      <p className="mt-4 text-white/50 max-w-md text-pretty">
+        Bring terminals, browsers, and AI agents into one workspace.
+      </p>
+      <div className="flex flex-wrap items-center justify-center gap-4 mt-10">
+        <Link href="/downloads" className="inline-flex items-center gap-2 px-6 py-2.5 text-sm font-semibold rounded-lg bg-white text-black hover:opacity-85 transition-opacity">
+          Download
+        </Link>
+        <Link href="/docs" className="inline-flex items-center gap-2 px-6 py-2.5 text-sm font-semibold rounded-lg border border-[rgba(255,255,255,0.08)] text-white hover:bg-white/[0.04] transition-colors">
+          Documentation
+        </Link>
+      </div>
+    </section>
+  );
+}
diff --git a/maxc-landing-page/components/landing/features.tsx b/maxc-landing-page/components/landing/features.tsx
new file mode 100644
index 0000000..fda58fd
--- /dev/null
+++ b/maxc-landing-page/components/landing/features.tsx
@@ -0,0 +1,46 @@
+import { Terminal, Globe2, Bot, LayoutGrid, Zap, Code2 } from "lucide-react";
+import type { LucideIcon } from "lucide-react";
+
+type Feature = { icon: LucideIcon; title: string; description: string };
+
+const features: Feature[] = [
+  { icon: Terminal, title: "Instant Terminal Sessions", description: "On demand terminal spawning with full PTY support and split pane multiplexing." },
+  { icon: Globe2, title: "Browser Automation", description: "Control real Chromium browsers. Navigate, click, type, screenshot — all via API." },
+  { icon: Bot, title: "AI Agent Workers", description: "Attach any AI coding agent to terminals and browsers. Start tasks, observe, cancel." },
+  { icon: Code2, title: "JSON RPC API", description: "52 methods. Automate every action using CLI, socket, or environment hooks." },
+];
+
+export function Features() {
+  return (
+    <>
+      <section
+        id="features"
+        className="wrapper wrapper--ticks border-t border-nickel px-5 sm:px-10 py-14 sm:py-28 flex flex-col justify-center gap-3 text-center items-center"
+      >
+        <h2 className="text-white max-w-2xl text-balance text-center text-3xl sm:text-4xl font-bold tracking-tight">
+          Run terminals and browsers in one workspace
+        </h2>
+        <p className="max-w-md text-white/70 text-balance sm:text-pretty">
+          Terminals, browsers, and agents in one programmable surface.
+        </p>
+      </section>
+
+      <section className="wrapper wrapper--ticks border-t border-nickel grid lg:grid-cols-2 divide-x divide-y divide-nickel">
+        {features.map((f, i) => (
+          <div
+            key={f.title}
+            className={`p-5 sm:p-10 flex flex-col gap-3 ${i % 2 === 1 ? "border-r-0" : ""} ${i >= features.length - 2 ? "lg:border-b-0" : ""}`}
+          >
+            <div className="flex items-center gap-3">
+              <f.icon className="size-5 text-white/70" />
+              <h5 className="text-white font-semibold">{f.title}</h5>
+            </div>
+            <p className="sm:max-w-[28rem] text-white/50 text-pretty text-sm leading-relaxed">
+              {f.description}
+            </p>
+          </div>
+        ))}
+      </section>
+    </>
+  );
+}
diff --git a/maxc-landing-page/components/landing/footer.tsx b/maxc-landing-page/components/landing/footer.tsx
new file mode 100644
index 0000000..cb882d8
--- /dev/null
+++ b/maxc-landing-page/components/landing/footer.tsx
@@ -0,0 +1,77 @@
+import Image from "next/image";
+import Link from "next/link";
+
+const columns = [
+  {
+    title: "Product",
+    links: [
+      { label: "Documentation", href: "/docs" },
+    ],
+  },
+  // {
+  //   title: "Resources",
+  //   links: [
+  //     { label: "API Reference", href: "#" },
+  //     { label: "Changelog", href: "#" },
+  //   ],
+  // },
+  {
+    title: "Social",
+    links: [
+      { label: "GitHub", href: "https://github.com/Pollux-Studio/maxc" },
+      { label: "LinkedIn", href: "https://www.linkedin.com" },
+    ],
+  },
+];
+
+export function Footer() {
+  return (
+    <footer className="wrapper wrapper--ticks border-t border-nickel">
+      <div className="px-8 sm:px-10 py-12 sm:py-16">
+        <div className="grid gap-10 sm:grid-cols-2 lg:grid-cols-4">
+          <div>
+            <div className="flex items-center">
+              <Image src="/maxc_logo_white.svg" alt="maxc" width={140} height={28} className="h-7 w-auto" />
+            </div>
+            <p className="mt-2 text-xs text-white/30 leading-relaxed max-w-[200px]">
+              The control center for AI coding agents. Open source, Rust powered.
+            </p>
+          </div>
+          {columns.map((col) => (
+            <div key={col.title}>
+              <div className="text-xs font-semibold text-white/50 uppercase tracking-wider mb-4">{col.title}</div>
+              <ul className="space-y-2.5">
+                {col.links.map((link) => {
+                  const isInternal = link.href.startsWith("/");
+                  return (
+                    <li key={link.label}>
+                      {isInternal ? (
+                        <Link href={link.href} className="text-sm text-white/30 hover:text-white/60 transition-colors">
+                          {link.label}
+                        </Link>
+                      ) : (
+                        <a
+                          href={link.href}
+                          className="text-sm text-white/30 hover:text-white/60 transition-colors"
+                          target="_blank"
+                          rel="noreferrer"
+                        >
+                          {link.label}
+                        </a>
+                      )}
+                    </li>
+                  );
+                })}
+              </ul>
+            </div>
+          ))}
+        </div>
+
+        <div className="mt-12 pt-6 border-t border-[rgba(255,255,255,0.05)] flex flex-col sm:flex-row items-center justify-between gap-4">
+          <span className="text-xs text-white/20">&copy; 2026 maxc. All rights reserved.</span>
+          <span className="text-xs text-white/20">Built with Rust, Tauri, and React.</span>
+        </div>
+      </div>
+    </footer>
+  );
+}
diff --git a/maxc-landing-page/components/landing/hero.tsx b/maxc-landing-page/components/landing/hero.tsx
new file mode 100644
index 0000000..1266628
--- /dev/null
+++ b/maxc-landing-page/components/landing/hero.tsx
@@ -0,0 +1,49 @@
+import { MockWorkspace } from "@/components/landing/mock-workspace";
+
+export function Hero() {
+  return (
+    <section
+      id="home"
+      className="wrapper wrapper--ticks border-t border-nickel grid md:grid-cols-2 w-full md:divide-x divide-nickel"
+    >
+      {/* Left: text + CTA */}
+      <div className="flex flex-col p-8 sm:p-10 justify-between gap-10 items-center md:items-start">
+        <div className="flex flex-col gap-5 items-center md:items-start text-center md:text-left">
+          <span className="text-grey text-xs font-mono uppercase tracking-wide">
+            Open Source &middot; Built with Rust
+          </span>
+
+          <h1 className="text-white text-pretty max-w-[25rem] text-4xl sm:text-5xl font-bold tracking-tight leading-[1.1]">
+            The Control Center for AI Coding Agents
+          </h1>
+
+          <p className="text-white/70 md:text-lg max-w-[27rem] text-pretty">
+            Run terminals, browsers, and AI agents in one programmable workspace.
+          </p>
+          <p className="text-white/50 text-sm max-w-[30rem] text-pretty">
+            maxc is a programmable workspace designed for AI coding agents. Developers can run terminal sessions,
+            automate browsers, and orchestrate AI agents inside a unified development environment. With a JSON-RPC
+            automation interface and real runtime execution, maxc enables powerful automation workflows for modern
+            software teams.
+          </p>
+
+          <div className="flex items-center gap-4 mt-6">
+            <a href="/downloads" className="inline-flex items-center gap-2 px-6 py-2.5 text-sm font-semibold rounded-lg bg-white text-black hover:opacity-85 transition-opacity">
+              Download now
+            </a>
+          </div>
+        </div>
+
+      </div>
+
+      {/* Right: product UI */}
+      <div className="flex flex-col sm:min-h-[32rem] overflow-hidden">
+        <div className="relative px-8 sm:px-10 py-10 h-full flex flex-col justify-center overflow-hidden">
+          <div className="origin-center scale-[1.12] translate-x-6 md:translate-x-10">
+            <MockWorkspace heightClass="h-[340px]" />
+          </div>
+        </div>
+      </div>
+    </section>
+  );
+}
diff --git a/maxc-landing-page/components/landing/mock-workspace.tsx b/maxc-landing-page/components/landing/mock-workspace.tsx
new file mode 100644
index 0000000..0c8d371
--- /dev/null
+++ b/maxc-landing-page/components/landing/mock-workspace.tsx
@@ -0,0 +1,69 @@
+import { Terminal, Globe2, Bot } from "lucide-react";
+
+type MockWorkspaceProps = {
+  heightClass?: string;
+};
+
+export function MockWorkspace({ heightClass = "h-[280px]" }: MockWorkspaceProps) {
+  return (
+    <div className="rounded-lg overflow-hidden border border-[rgba(255,255,255,0.08)] bg-[#0a0c10]">
+      <div className="flex items-center justify-between border-b border-[rgba(255,255,255,0.08)] px-4 py-2.5 bg-[#0d0f14]">
+        <span className="text-[10px] text-white/60 font-mono">maxc workspace &mdash; dev</span>
+        <div className="flex items-center gap-3 text-white/60 text-xs font-mono select-none">
+          <span className="leading-none">_</span>
+          <span className="leading-none">□</span>
+          <span className="leading-none">×</span>
+        </div>
+      </div>
+
+      <div className={`flex ${heightClass}`}>
+        <div className="w-28 border-r border-[rgba(255,255,255,0.06)] bg-[#0c0e13] p-3 space-y-1.5">
+          <div className="rounded bg-white/10 px-2 py-1.5 text-[10px] text-white/70 font-medium">dev</div>
+          <div className="rounded px-2 py-1.5 text-[10px] text-white/30">server</div>
+          <div className="rounded px-2 py-1.5 text-[10px] text-white/30">tests</div>
+        </div>
+
+        <div className="flex-1 flex">
+          <div className="flex-1 flex flex-col border-r border-[rgba(255,255,255,0.06)]">
+            <div className="border-b border-[rgba(255,255,255,0.06)] px-3 py-1.5 flex items-center gap-1.5">
+              <Terminal className="size-3 text-white/60" />
+              <span className="text-[10px] text-white/40 font-mono">Terminal 1</span>
+            </div>
+            <div className="flex-1 p-3 font-mono text-[10px] text-white/40 leading-5 space-y-0.5">
+              <div><span className="text-white/60">$</span> npm run dev</div>
+              <div className="text-white/20">ready on 0.0.0.0:3000</div>
+              <div className="text-white/20">compiled in 1.2s</div>
+              <div className="text-blue-400/60">GET /api/health 200 12ms</div>
+            </div>
+          </div>
+
+          <div className="flex-1 flex flex-col">
+            <div className="flex-1 border-b border-[rgba(255,255,255,0.06)] flex flex-col">
+              <div className="border-b border-[rgba(255,255,255,0.06)] px-3 py-1.5 flex items-center gap-1.5">
+                <Globe2 className="size-3 text-blue-400" />
+                <span className="text-[10px] text-white/40 font-mono">Browser</span>
+              </div>
+              <div className="flex-1 flex items-center justify-center">
+                <div className="w-20 h-14 rounded bg-white/[0.02] border border-[rgba(255,255,255,0.05)] flex items-center justify-center">
+                  <span className="text-[8px] text-white/20">localhost:3000</span>
+                </div>
+              </div>
+            </div>
+
+            <div className="h-24 flex flex-col">
+              <div className="border-b border-[rgba(255,255,255,0.06)] px-3 py-1.5 flex items-center gap-1.5">
+                <Bot className="size-3 text-purple-400" />
+                <span className="text-[10px] text-white/40 font-mono">Agent</span>
+                <span className="ml-auto text-[8px] text-white/70 bg-white/10 rounded px-1.5 py-0.5">Running</span>
+              </div>
+              <div className="flex-1 p-3 font-mono text-[10px] text-white/30 leading-4">
+                <div>Running tests...</div>
+                <div className="text-white/50">12/14 passed</div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+}
diff --git a/maxc-landing-page/components/landing/navbar.tsx b/maxc-landing-page/components/landing/navbar.tsx
new file mode 100644
index 0000000..2bc5e2e
--- /dev/null
+++ b/maxc-landing-page/components/landing/navbar.tsx
@@ -0,0 +1,50 @@
+import Image from "next/image";
+import Link from "next/link";
+import { Star } from "lucide-react";
+
+const navLinks = [
+  { label: "Home", href: "/#home", type: "hash" },
+  { label: "Features", href: "/#features", type: "hash" },
+  { label: "Product", href: "/#product", type: "hash" },
+  { label: "Open Source", href: "/#opensource", type: "hash" },
+  { label: "Docs", href: "/docs", type: "route" },
+];
+
+export function Navbar() {
+  return (
+    <div className="sticky top-0 z-50 w-full bg-[var(--background)] border-b border-nickel">
+      <header className="wrapper px-6 py-5 flex items-center justify-between">
+        <div className="flex gap-10 items-center">
+          <Link href="/" className="flex items-center">
+            <Image src="/maxc_logo_white.svg" alt="maxc" width={160} height={40} className="h-10 w-auto" priority />
+          </Link>
+          <nav className="hidden lg:flex items-center gap-1">
+            {navLinks.map((link) => (
+              <Link
+                key={link.label}
+                href={link.href}
+                className="px-3 py-2 text-sm font-medium text-white hover:opacity-70 transition-opacity"
+              >
+                {link.label}
+              </Link>
+            ))}
+          </nav>
+        </div>
+        <div className="flex items-center gap-4">
+          <a
+            href="https://github.com/Pollux-Studio/maxc"
+            className="flex items-center gap-2 rounded-full border border-[rgba(255,255,255,0.12)] bg-white/[0.02] px-3 py-1.5 text-xs text-white/80 hover:text-white hover:bg-white/[0.04] transition-colors"
+            aria-label="Star on GitHub"
+            target="_blank"
+            rel="noreferrer"
+          >
+            <Star className="size-3" />
+            <span className="font-semibold">Star</span>
+            <span className="text-white/40">GitHub</span>
+          </a>
+        </div>
+      </header>
+      <div className="wrapper relative h-0 border-l border-r border-nickel" />
+    </div>
+  );
+}
diff --git a/maxc-landing-page/components/landing/open-source.tsx b/maxc-landing-page/components/landing/open-source.tsx
new file mode 100644
index 0000000..4c72cc2
--- /dev/null
+++ b/maxc-landing-page/components/landing/open-source.tsx
@@ -0,0 +1,39 @@
+import { Code2, Globe2, Bot, Monitor } from "lucide-react";
+
+const highlights = [
+  { icon: Code2, label: "Rust backend", desc: "High-performance event-sourced server" },
+  { icon: Globe2, label: "52 RPC methods", desc: "Full automation surface via JSON-RPC" },
+  { icon: Monitor, label: "Tauri desktop", desc: "Native window with React + xterm.js" },
+  { icon: Bot, label: "Agent agnostic", desc: "Claude, Codex, Cursor, any agent" },
+];
+
+export function OpenSource() {
+  return (
+    <>
+      <section
+        id="opensource"
+        className="wrapper wrapper--ticks border-t border-nickel px-5 sm:px-10 py-14 sm:py-28 flex flex-col justify-center gap-3 text-center items-center"
+      >
+        <h2 className="text-white max-w-2xl text-balance text-center text-3xl sm:text-4xl font-bold tracking-tight">
+          Open source AI agent workspace
+        </h2>
+        <p className="max-w-md text-white/70 text-balance sm:text-pretty">
+          Inspect every line, contribute, or fork. maxc is built for extensibility.
+        </p>
+      </section>
+
+      <section className="wrapper wrapper--ticks border-t border-nickel grid sm:grid-cols-2 lg:grid-cols-4 divide-x divide-y divide-nickel">
+        {highlights.map((h, i) => (
+          <div
+            key={h.label}
+            className={`p-5 sm:p-8 flex flex-col gap-2 ${i === highlights.length - 1 ? "border-r-0" : ""}`}
+          >
+            <h.icon className="size-5 text-white/70 mb-1" />
+            <div className="text-sm font-semibold text-white">{h.label}</div>
+            <div className="text-xs text-white/40 leading-relaxed">{h.desc}</div>
+          </div>
+        ))}
+      </section>
+    </>
+  );
+}
diff --git a/maxc-landing-page/components/landing/product.tsx b/maxc-landing-page/components/landing/product.tsx
new file mode 100644
index 0000000..b1a4254
--- /dev/null
+++ b/maxc-landing-page/components/landing/product.tsx
@@ -0,0 +1,33 @@
+import { MockWorkspace } from "@/components/landing/mock-workspace";
+
+export function Product() {
+  return (
+    <>
+      <section
+        id="product"
+        className="wrapper wrapper--ticks border-t border-nickel px-5 sm:px-10 py-14 sm:py-28 flex flex-col justify-center gap-3 text-center items-center"
+      >
+        <h2 className="text-white max-w-2xl text-balance text-center text-3xl sm:text-4xl font-bold tracking-tight">
+          Automate development workflows with AI agents
+        </h2>
+      </section>
+
+      <section className="wrapper border-t border-nickel grid lg:grid-cols-2 divide-x divide-y divide-nickel">
+        <div className="p-5 sm:p-10 flex flex-col gap-3 border-l border-nickel">
+          <h5 className="text-white font-semibold">Workspace Layouts</h5>
+          <p className="sm:max-w-[28rem] text-white/50 text-pretty text-sm leading-relaxed">
+            Split panes, surface tabs, and resizable layouts. Organize terminals, browsers, and agent panels side by side.
+          </p>
+          <p className="sm:max-w-[28rem] text-white/50 text-pretty text-sm leading-relaxed">
+            Every layout persists across restarts via the durable event store.
+          </p>
+        </div>
+        <div className="flex flex-col gap-3 justify-between border-r-0">
+          <div className="p-5 sm:p-10 border-r border-nickel">
+            <MockWorkspace />
+          </div>
+        </div>
+      </section>
+    </>
+  );
+}
diff --git a/maxc-landing-page/components/landing/trust.tsx b/maxc-landing-page/components/landing/trust.tsx
new file mode 100644
index 0000000..db9422e
--- /dev/null
+++ b/maxc-landing-page/components/landing/trust.tsx
@@ -0,0 +1,28 @@
+const badges = [
+  "Open Source",
+  "Rust Powered",
+  "Agent Ready",
+  "JSON RPC API",
+  "Event Sourced",
+  "Cross Platform",
+];
+
+export function Trust() {
+  return (
+    <section className="wrapper wrapper--ticks border-t border-nickel px-8 sm:px-10 py-6 sm:py-8 flex flex-col justify-center gap-5">
+      <h6 className="text-center md:text-start text-white text-sm font-semibold">
+        Built for developers building autonomous software systems
+      </h6>
+      <div className="flex flex-wrap items-center justify-center md:justify-start gap-3">
+        {badges.map((label) => (
+          <span
+            key={label}
+            className="rounded-md border border-[rgba(255,255,255,0.08)] bg-white/[0.02] px-3 py-1.5 text-xs text-grey font-mono"
+          >
+            {label}
+          </span>
+        ))}
+      </div>
+    </section>
+  );
+}
diff --git a/maxc-landing-page/components/ui/badge.tsx b/maxc-landing-page/components/ui/badge.tsx
new file mode 100644
index 0000000..cacff11
--- /dev/null
+++ b/maxc-landing-page/components/ui/badge.tsx
@@ -0,0 +1,49 @@
+import * as React from "react"
+import { cva, type VariantProps } from "class-variance-authority"
+import { Slot } from "radix-ui"
+
+import { cn } from "@/lib/utils"
+
+const badgeVariants = cva(
+  "group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",
+  {
+    variants: {
+      variant: {
+        default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
+        secondary:
+          "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
+        destructive:
+          "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",
+        outline:
+          "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
+        ghost:
+          "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
+        link: "text-primary underline-offset-4 hover:underline",
+      },
+    },
+    defaultVariants: {
+      variant: "default",
+    },
+  }
+)
+
+function Badge({
+  className,
+  variant = "default",
+  asChild = false,
+  ...props
+}: React.ComponentProps<"span"> &
+  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
+  const Comp = asChild ? Slot.Root : "span"
+
+  return (
+    <Comp
+      data-slot="badge"
+      data-variant={variant}
+      className={cn(badgeVariants({ variant }), className)}
+      {...props}
+    />
+  )
+}
+
+export { Badge, badgeVariants }
diff --git a/maxc-landing-page/components/ui/button.tsx b/maxc-landing-page/components/ui/button.tsx
new file mode 100644
index 0000000..c88ffd6
--- /dev/null
+++ b/maxc-landing-page/components/ui/button.tsx
@@ -0,0 +1,67 @@
+import * as React from "react"
+import { cva, type VariantProps } from "class-variance-authority"
+import { Slot } from "radix-ui"
+
+import { cn } from "@/lib/utils"
+
+const buttonVariants = cva(
+  "group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
+  {
+    variants: {
+      variant: {
+        default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
+        outline:
+          "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
+        secondary:
+          "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
+        ghost:
+          "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
+        destructive:
+          "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
+        link: "text-primary underline-offset-4 hover:underline",
+      },
+      size: {
+        default:
+          "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
+        xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
+        sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
+        lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
+        icon: "size-8",
+        "icon-xs":
+          "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
+        "icon-sm":
+          "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
+        "icon-lg": "size-9",
+      },
+    },
+    defaultVariants: {
+      variant: "default",
+      size: "default",
+    },
+  }
+)
+
+function Button({
+  className,
+  variant = "default",
+  size = "default",
+  asChild = false,
+  ...props
+}: React.ComponentProps<"button"> &
+  VariantProps<typeof buttonVariants> & {
+    asChild?: boolean
+  }) {
+  const Comp = asChild ? Slot.Root : "button"
+
+  return (
+    <Comp
+      data-slot="button"
+      data-variant={variant}
+      data-size={size}
+      className={cn(buttonVariants({ variant, size, className }))}
+      {...props}
+    />
+  )
+}
+
+export { Button, buttonVariants }
diff --git a/maxc-landing-page/components/ui/card.tsx b/maxc-landing-page/components/ui/card.tsx
new file mode 100644
index 0000000..9bd5a25
--- /dev/null
+++ b/maxc-landing-page/components/ui/card.tsx
@@ -0,0 +1,103 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+function Card({
+  className,
+  size = "default",
+  ...props
+}: React.ComponentProps<"div"> & { size?: "default" | "sm" }) {
+  return (
+    <div
+      data-slot="card"
+      data-size={size}
+      className={cn(
+        "group/card flex flex-col gap-4 overflow-hidden rounded-xl bg-card py-4 text-sm text-card-foreground ring-1 ring-foreground/10 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
+        className
+      )}
+      {...props}
+    />
+  )
+}
+
+function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
+  return (
+    <div
+      data-slot="card-header"
+      className={cn(
+        "group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3",
+        className
+      )}
+      {...props}
+    />
+  )
+}
+
+function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
+  return (
+    <div
+      data-slot="card-title"
+      className={cn(
+        "text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
+        className
+      )}
+      {...props}
+    />
+  )
+}
+
+function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
+  return (
+    <div
+      data-slot="card-description"
+      className={cn("text-sm text-muted-foreground", className)}
+      {...props}
+    />
+  )
+}
+
+function CardAction({ className, ...props }: React.ComponentProps<"div">) {
+  return (
+    <div
+      data-slot="card-action"
+      className={cn(
+        "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
+        className
+      )}
+      {...props}
+    />
+  )
+}
+
+function CardContent({ className, ...props }: React.ComponentProps<"div">) {
+  return (
+    <div
+      data-slot="card-content"
+      className={cn("px-4 group-data-[size=sm]/card:px-3", className)}
+      {...props}
+    />
+  )
+}
+
+function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
+  return (
+    <div
+      data-slot="card-footer"
+      className={cn(
+        "flex items-center rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/card:p-3",
+        className
+      )}
+      {...props}
+    />
+  )
+}
+
+export {
+  Card,
+  CardHeader,
+  CardFooter,
+  CardTitle,
+  CardAction,
+  CardDescription,
+  CardContent,
+}
diff --git a/maxc-landing-page/components/ui/separator.tsx b/maxc-landing-page/components/ui/separator.tsx
new file mode 100644
index 0000000..d457090
--- /dev/null
+++ b/maxc-landing-page/components/ui/separator.tsx
@@ -0,0 +1,28 @@
+"use client"
+
+import * as React from "react"
+import { Separator as SeparatorPrimitive } from "radix-ui"
+
+import { cn } from "@/lib/utils"
+
+function Separator({
+  className,
+  orientation = "horizontal",
+  decorative = true,
+  ...props
+}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
+  return (
+    <SeparatorPrimitive.Root
+      data-slot="separator"
+      decorative={decorative}
+      orientation={orientation}
+      className={cn(
+        "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
+        className
+      )}
+      {...props}
+    />
+  )
+}
+
+export { Separator }
diff --git a/maxc-landing-page/eslint.config.mjs b/maxc-landing-page/eslint.config.mjs
new file mode 100644
index 0000000..05e726d
--- /dev/null
+++ b/maxc-landing-page/eslint.config.mjs
@@ -0,0 +1,18 @@
+import { defineConfig, globalIgnores } from "eslint/config";
+import nextVitals from "eslint-config-next/core-web-vitals";
+import nextTs from "eslint-config-next/typescript";
+
+const eslintConfig = defineConfig([
+  ...nextVitals,
+  ...nextTs,
+  // Override default ignores of eslint-config-next.
+  globalIgnores([
+    // Default ignores of eslint-config-next:
+    ".next/**",
+    "out/**",
+    "build/**",
+    "next-env.d.ts",
+  ]),
+]);
+
+export default eslintConfig;
diff --git a/maxc-landing-page/lib/utils.ts b/maxc-landing-page/lib/utils.ts
new file mode 100644
index 0000000..bd0c391
--- /dev/null
+++ b/maxc-landing-page/lib/utils.ts
@@ -0,0 +1,6 @@
+import { clsx, type ClassValue } from "clsx"
+import { twMerge } from "tailwind-merge"
+
+export function cn(...inputs: ClassValue[]) {
+  return twMerge(clsx(inputs))
+}
diff --git a/maxc-landing-page/next.config.ts b/maxc-landing-page/next.config.ts
new file mode 100644
index 0000000..e9ffa30
--- /dev/null
+++ b/maxc-landing-page/next.config.ts
@@ -0,0 +1,7 @@
+import type { NextConfig } from "next";
+
+const nextConfig: NextConfig = {
+  /* config options here */
+};
+
+export default nextConfig;
diff --git a/maxc-landing-page/package.json b/maxc-landing-page/package.json
new file mode 100644
index 0000000..1b53571
--- /dev/null
+++ b/maxc-landing-page/package.json
@@ -0,0 +1,35 @@
+{
+  "name": "maxc-landing-page",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "dev": "next dev",
+    "build": "next build",
+    "start": "next start",
+    "lint": "eslint"
+  },
+  "dependencies": {
+    "@vercel/analytics": "^2.0.1",
+    "class-variance-authority": "^0.7.1",
+    "clsx": "^2.1.1",
+    "framer-motion": "^12.36.0",
+    "lucide-react": "^0.577.0",
+    "next": "16.1.6",
+    "radix-ui": "^1.4.3",
+    "react": "19.2.3",
+    "react-dom": "19.2.3",
+    "shadcn": "^4.0.8",
+    "tailwind-merge": "^3.5.0",
+    "tw-animate-css": "^1.4.0"
+  },
+  "devDependencies": {
+    "@tailwindcss/postcss": "^4",
+    "@types/node": "^20",
+    "@types/react": "^19",
+    "@types/react-dom": "^19",
+    "eslint": "^9",
+    "eslint-config-next": "16.1.6",
+    "tailwindcss": "^4",
+    "typescript": "^5"
+  }
+}
diff --git a/maxc-landing-page/postcss.config.mjs b/maxc-landing-page/postcss.config.mjs
new file mode 100644
index 0000000..61e3684
--- /dev/null
+++ b/maxc-landing-page/postcss.config.mjs
@@ -0,0 +1,7 @@
+const config = {
+  plugins: {
+    "@tailwindcss/postcss": {},
+  },
+};
+
+export default config;
diff --git a/maxc-landing-page/public/apple-logo-svgrepo-com.svg b/maxc-landing-page/public/apple-logo-svgrepo-com.svg
new file mode 100644
index 0000000..51ded04
--- /dev/null
+++ b/maxc-landing-page/public/apple-logo-svgrepo-com.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
+<svg fill="#000000" width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
+<path d="M18.71 19.5C17.88 20.74 17 21.95 15.66 21.97C14.32 22 13.89 21.18 12.37 21.18C10.84 21.18 10.37 21.95 9.09997 22C7.78997 22.05 6.79997 20.68 5.95997 19.47C4.24997 17 2.93997 12.45 4.69997 9.39C5.56997 7.87 7.12997 6.91 8.81997 6.88C10.1 6.86 11.32 7.75 12.11 7.75C12.89 7.75 14.37 6.68 15.92 6.84C16.57 6.87 18.39 7.1 19.56 8.82C19.47 8.88 17.39 10.1 17.41 12.63C17.44 15.65 20.06 16.66 20.09 16.67C20.06 16.74 19.67 18.11 18.71 19.5ZM13 3.5C13.73 2.67 14.94 2.04 15.94 2C16.07 3.17 15.6 4.35 14.9 5.19C14.21 6.04 13.07 6.7 11.95 6.61C11.8 5.46 12.36 4.26 13 3.5Z"/>
+</svg>
\ No newline at end of file
diff --git a/maxc-landing-page/public/file.svg b/maxc-landing-page/public/file.svg
new file mode 100644
index 0000000..004145c
--- /dev/null
+++ b/maxc-landing-page/public/file.svg
@@ -0,0 +1 @@
+<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
\ No newline at end of file
diff --git a/maxc-landing-page/public/globe.svg b/maxc-landing-page/public/globe.svg
new file mode 100644
index 0000000..567f17b
--- /dev/null
+++ b/maxc-landing-page/public/globe.svg
@@ -0,0 +1 @@
+<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
\ No newline at end of file
diff --git a/maxc-landing-page/public/linux-svgrepo-com.svg b/maxc-landing-page/public/linux-svgrepo-com.svg
new file mode 100644
index 0000000..bd05879
--- /dev/null
+++ b/maxc-landing-page/public/linux-svgrepo-com.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
+<svg width="800px" height="800px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="none"><path fill="#000000" d="M8.294 1c-.09 0-.184.005-.28.012-2.465.194-1.811 2.804-1.85 3.674-.043.637-.174 1.14-.612 1.762-.516.613-1.24 1.604-1.584 2.637-.162.485-.24.982-.167 1.452a.247.247 0 00-.064.079c-.152.156-.263.35-.387.49-.116.115-.283.155-.465.232-.183.08-.384.157-.504.397a.78.78 0 00-.077.351c0 .116.016.234.032.313.034.233.068.425.023.566-.145.396-.163.668-.062.865.102.195.313.275.549.351.472.117 1.114.079 1.618.35.54.272 1.088.39 1.526.274.307-.067.566-.27.705-.552.342-.001.717-.157 1.318-.194.408-.034.918.155 1.503.116.015.078.037.116.067.194l.001.002c.229.454.65.66 1.1.625.45-.035.928-.313 1.316-.762.368-.446.982-.632 1.387-.877.203-.116.367-.273.379-.497.013-.234-.117-.473-.417-.803v-.056l-.002-.002c-.099-.117-.145-.312-.197-.54-.05-.234-.106-.459-.287-.61h-.001c-.035-.032-.072-.04-.11-.08a.208.208 0 00-.11-.037c.25-.745.153-1.487-.102-2.154-.31-.823-.854-1.54-1.269-2.032-.464-.587-.919-1.142-.91-1.965.016-1.255.138-3.578-2.067-3.581zm.309 1.986h.007c.125 0 .231.036.34.116a.89.89 0 01.256.31c.062.152.093.268.097.423 0-.012.004-.023.004-.035v.061a.05.05 0 01-.003-.012l-.002-.014c-.001.142-.03.282-.087.412a.556.556 0 01-.125.195.415.415 0 00-.051-.024c-.06-.027-.115-.038-.166-.078a.765.765 0 00-.128-.038c.03-.035.085-.078.107-.116a.69.69 0 00.051-.234V3.94a.706.706 0 00-.035-.233c-.027-.079-.06-.117-.107-.195-.05-.038-.098-.077-.156-.077h-.01c-.054 0-.102.018-.152.077a.467.467 0 00-.12.195.688.688 0 00-.052.234v.01c0 .053.004.105.011.156-.112-.039-.255-.078-.354-.117a.954.954 0 01-.01-.117V3.86a1.034 1.034 0 01.087-.448.63.63 0 01.251-.31.575.575 0 01.347-.117zm-1.728.035h.02c.084 0 .158.028.234.078a.806.806 0 01.2.272c.053.116.082.233.09.389v.002a.856.856 0 01-.002.155v.047l-.048.014c-.089.032-.16.079-.23.117a.633.633 0 00.002-.156V3.93c-.007-.078-.023-.117-.047-.194a.358.358 0 00-.097-.156.145.145 0 00-.107-.037h-.012c-.042.003-.076.023-.109.077a.322.322 0 00-.07.157.55.55 0 00-.013.193v.008c.007.08.021.117.047.195a.363.363 0 00.096.157c.006.005.012.01.02.014-.04.033-.068.04-.102.079a.177.177 0 01-.077.04 1.53 1.53 0 01-.16-.235 1.034 1.034 0 01-.09-.389c-.01-.132.005-.264.046-.39a.834.834 0 01.165-.312c.075-.077.152-.116.244-.116zm.799.995c.194 0 .428.038.71.233.17.116.304.157.613.273h.002c.149.079.236.155.279.232v-.076a.333.333 0 01.009.274c-.072.18-.301.375-.62.491v.001c-.156.08-.292.195-.452.272-.161.078-.343.17-.59.155a.664.664 0 01-.262-.039 2.077 2.077 0 01-.188-.115c-.113-.079-.211-.194-.357-.271v-.003h-.003c-.233-.144-.359-.299-.4-.414-.04-.157-.003-.275.113-.35.13-.08.221-.159.282-.197.06-.043.083-.059.102-.076h.001v-.002c.099-.117.255-.274.49-.35.08-.021.171-.038.272-.038h-.001zm1.633 1.25c.21.826.698 2.026 1.012 2.609.167.311.5.967.643 1.764.091-.003.193.01.3.037.376-.975-.319-2.022-.636-2.314-.128-.116-.135-.195-.071-.195.344.312.796.917.96 1.608.075.312.093.644.012.974.039.017.079.035.12.04.601.311.824.547.717.896v-.025c-.035-.002-.07 0-.105 0h-.01c.089-.272-.106-.481-.62-.714-.534-.233-.96-.196-1.033.271-.005.025-.008.039-.01.079-.04.013-.082.03-.123.037-.25.157-.386.39-.462.693-.076.31-.1.674-.12 1.09v.002c-.011.195-.099.489-.186.787-.875.626-2.088.897-3.12.195a1.543 1.543 0 00-.234-.31.846.846 0 00-.16-.195.963.963 0 00.27-.04.359.359 0 00.184-.194c.063-.156 0-.407-.201-.678-.201-.273-.543-.58-1.043-.888-.368-.233-.575-.507-.671-.814-.096-.312-.083-.633-.009-.96.143-.624.51-1.23.743-1.611.063-.038.022.078-.238.568-.23.438-.665 1.456-.07 2.248.022-.578.15-1.146.377-1.678.329-.745 1.016-2.044 1.07-3.073.029.021.127.08.17.118.126.078.22.194.343.271a.694.694 0 00.511.196l.065.003c.24 0 .425-.078.581-.156.17-.078.304-.195.432-.233h.003c.272-.08.487-.235.609-.409zm1.275 5.225c.021.35.2.726.514.803.343.078.837-.194 1.045-.446l.123-.006c.184-.004.337.006.494.156l.002.002c.121.116.178.31.228.511.05.233.09.455.239.622.283.307.376.528.37.665l.003-.004v.01l-.002-.007c-.009.153-.108.231-.29.347-.368.234-1.02.416-1.434.916-.36.43-.8.665-1.188.695-.387.03-.721-.117-.918-.524l-.003-.002c-.122-.233-.07-.597.033-.985.103-.39.25-.784.27-1.107.022-.417.044-.779.114-1.058.07-.271.18-.465.374-.574l.026-.013v-.001zm-6.308.028h.006a.53.53 0 01.091.009c.22.032.412.194.597.438l.53.97.003.003c.141.31.44.62.693.955.253.348.45.66.425.915v.004c-.033.434-.28.67-.656.755-.376.079-.887 0-1.397-.27-.565-.314-1.235-.274-1.667-.352-.215-.039-.355-.117-.421-.233-.064-.117-.066-.352.071-.718v-.002l.002-.002c.068-.195.017-.439-.016-.652-.032-.234-.049-.414.025-.549.093-.194.23-.233.402-.31.172-.08.374-.118.534-.275h.001c.15-.157.26-.351.39-.49.11-.117.222-.196.387-.196zM8.45 5.226c-.254.117-.551.312-.868.312-.316 0-.566-.155-.747-.272-.09-.078-.163-.156-.217-.195-.096-.078-.084-.194-.044-.194.064.01.076.078.117.117.056.038.125.116.21.194.17.116.396.272.68.272.283 0 .615-.156.816-.272.114-.078.26-.194.378-.272.09-.08.087-.156.163-.156.074.01.02.078-.086.194-.13.098-.264.189-.403.273zm-.631-.923V4.29c-.004-.012.007-.024.017-.03.043-.024.105-.015.151.003.037 0 .094.04.088.079-.004.029-.05.038-.079.038-.032 0-.054-.025-.082-.04-.03-.01-.085-.004-.095-.037zm-.322 0c-.011.034-.066.028-.097.038-.027.015-.05.04-.081.04-.03 0-.076-.012-.08-.04-.005-.038.052-.077.088-.077.047-.018.107-.028.151-.003.011.005.021.017.018.029v.012h.001z"/></svg>
\ No newline at end of file
diff --git a/maxc-landing-page/public/maxc_logo_dark.svg b/maxc-landing-page/public/maxc_logo_dark.svg
new file mode 100644
index 0000000..cd53269
--- /dev/null
+++ b/maxc-landing-page/public/maxc_logo_dark.svg
@@ -0,0 +1,4 @@
+<svg width="915" height="498" viewBox="0 0 915 498" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M183 311.25V219.706H137.25V311.25H91.5V219.706H45.75V311.25H0V173.934H228.75V311.25H183ZM457.5 311.25V357.022H320.25V311.25H274.5V173.934H320.25V128.162H457.5V173.934H503.25V311.25H457.5ZM320.25 219.706H411.75V173.934H320.25V219.706ZM457.5 219.706H411.75V265.478H320.25V311.25H457.5V219.706ZM869.25 173.934H823.5V128.162H869.25V173.934ZM823.5 219.706H777.75V173.934H823.5V219.706ZM777.75 219.706V265.478H732V219.706H777.75ZM777.75 311.25V265.478H823.5V311.25H777.75ZM823.5 357.022V311.25H869.25V357.022H823.5Z" fill="#1E1E1E"/>
+<path d="M620.623 289.997L579.213 331.425L537.804 289.997L579.213 248.569L537.804 207.141L579.213 165.712L620.623 207.141L662.028 165.712L703.438 207.141L662.028 248.569L703.438 289.997L662.028 331.425L620.623 289.997Z" fill="#1E1E1E"/>
+</svg>
diff --git a/maxc-landing-page/public/maxc_logo_full_dark_single.svg b/maxc-landing-page/public/maxc_logo_full_dark_single.svg
new file mode 100644
index 0000000..4a0823c
--- /dev/null
+++ b/maxc-landing-page/public/maxc_logo_full_dark_single.svg
@@ -0,0 +1,5 @@
+<svg width="1080" height="1080" viewBox="0 0 1080 1080" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect x="0.5" y="0.5" width="1079" height="1079" rx="99.5" fill="white"/>
+<rect x="0.5" y="0.5" width="1079" height="1079" rx="99.5" stroke="white"/>
+<path d="M637 641V703.5H449.5V641H387V453.5H449.5V391H637V453.5H699.5V641H637ZM449.5 516H574.5V453.5H449.5V516ZM637 516H574.5V578.5H449.5V641H637V516Z" fill="#1E1E1E"/>
+</svg>
diff --git a/maxc-landing-page/public/maxc_logo_full_white_single.svg b/maxc-landing-page/public/maxc_logo_full_white_single.svg
new file mode 100644
index 0000000..b9a75ec
--- /dev/null
+++ b/maxc-landing-page/public/maxc_logo_full_white_single.svg
@@ -0,0 +1,5 @@
+<svg width="1080" height="1080" viewBox="0 0 1080 1080" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect x="0.5" y="0.5" width="1079" height="1079" rx="99.5" fill="#1E1E1E"/>
+<rect x="0.5" y="0.5" width="1079" height="1079" rx="99.5" stroke="white"/>
+<path d="M637 641V703.5H449.5V641H387V453.5H449.5V391H637V453.5H699.5V641H637ZM449.5 516H574.5V453.5H449.5V516ZM637 516H574.5V578.5H449.5V641H637V516Z" fill="white"/>
+</svg>
diff --git a/maxc-landing-page/public/maxc_logo_white.svg b/maxc-landing-page/public/maxc_logo_white.svg
new file mode 100644
index 0000000..45a0bc3
--- /dev/null
+++ b/maxc-landing-page/public/maxc_logo_white.svg
@@ -0,0 +1,4 @@
+<svg width="250" height="136" viewBox="0 0 250 136" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M50 85V60H37.5V85H25V60H12.5V85H0V47.5H62.5V85H50ZM125 85V97.5H87.5V85H75V47.5H87.5V35H125V47.5H137.5V85H125ZM87.5 60H112.5V47.5H87.5V60ZM125 60H112.5V72.5H87.5V85H125V60ZM237.5 47.5H225V35H237.5V47.5ZM225 60H212.5V47.5H225V60ZM212.5 60V72.5H200V60H212.5ZM212.5 85V72.5H225V85H212.5ZM225 97.5V85H237.5V97.5H225Z" fill="white"/>
+<path d="M169.569 79.196L158.255 90.5097L146.941 79.196L158.255 67.8822L146.941 56.5685L158.255 45.2548L169.569 56.5685L180.882 45.2548L192.196 56.5685L180.882 67.8822L192.196 79.196L180.882 90.5097L169.569 79.196Z" fill="white"/>
+</svg>
diff --git a/maxc-landing-page/public/next.svg b/maxc-landing-page/public/next.svg
new file mode 100644
index 0000000..5174b28
--- /dev/null
+++ b/maxc-landing-page/public/next.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
\ No newline at end of file
diff --git a/maxc-landing-page/public/robots.txt b/maxc-landing-page/public/robots.txt
new file mode 100644
index 0000000..4d48990
--- /dev/null
+++ b/maxc-landing-page/public/robots.txt
@@ -0,0 +1,4 @@
+User-agent: *
+Allow: /
+
+Sitemap: https://maxc.polluxstudio.in/sitemap.xml
diff --git a/maxc-landing-page/public/vercel.svg b/maxc-landing-page/public/vercel.svg
new file mode 100644
index 0000000..7705396
--- /dev/null
+++ b/maxc-landing-page/public/vercel.svg
@@ -0,0 +1 @@
+<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
\ No newline at end of file
diff --git a/maxc-landing-page/public/window.svg b/maxc-landing-page/public/window.svg
new file mode 100644
index 0000000..b2b2a44
--- /dev/null
+++ b/maxc-landing-page/public/window.svg
@@ -0,0 +1 @@
+<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
\ No newline at end of file
diff --git a/maxc-landing-page/tsconfig.json b/maxc-landing-page/tsconfig.json
new file mode 100644
index 0000000..3a13f90
--- /dev/null
+++ b/maxc-landing-page/tsconfig.json
@@ -0,0 +1,34 @@
+{
+  "compilerOptions": {
+    "target": "ES2017",
+    "lib": ["dom", "dom.iterable", "esnext"],
+    "allowJs": true,
+    "skipLibCheck": true,
+    "strict": true,
+    "noEmit": true,
+    "esModuleInterop": true,
+    "module": "esnext",
+    "moduleResolution": "bundler",
+    "resolveJsonModule": true,
+    "isolatedModules": true,
+    "jsx": "react-jsx",
+    "incremental": true,
+    "plugins": [
+      {
+        "name": "next"
+      }
+    ],
+    "paths": {
+      "@/*": ["./*"]
+    }
+  },
+  "include": [
+    "next-env.d.ts",
+    "**/*.ts",
+    "**/*.tsx",
+    ".next/types/**/*.ts",
+    ".next/dev/types/**/*.ts",
+    "**/*.mts"
+  ],
+  "exclude": ["node_modules"]
+}
diff --git a/maxc_desktop/src-tauri/icons/128x128.png b/maxc_desktop/src-tauri/icons/128x128.png
index 6061a3e..e572a48 100644
Binary files a/maxc_desktop/src-tauri/icons/128x128.png and b/maxc_desktop/src-tauri/icons/128x128.png differ
diff --git a/maxc_desktop/src-tauri/icons/128x128@2x.png b/maxc_desktop/src-tauri/icons/128x128@2x.png
index 02522f2..affd62c 100644
Binary files a/maxc_desktop/src-tauri/icons/128x128@2x.png and b/maxc_desktop/src-tauri/icons/128x128@2x.png differ
diff --git a/maxc_desktop/src-tauri/icons/32x32.png b/maxc_desktop/src-tauri/icons/32x32.png
index dbe6064..6a77b34 100644
Binary files a/maxc_desktop/src-tauri/icons/32x32.png and b/maxc_desktop/src-tauri/icons/32x32.png differ
diff --git a/maxc_desktop/src-tauri/icons/64x64.png b/maxc_desktop/src-tauri/icons/64x64.png
index ee8ca56..06ac15c 100644
Binary files a/maxc_desktop/src-tauri/icons/64x64.png and b/maxc_desktop/src-tauri/icons/64x64.png differ
diff --git a/maxc_desktop/src-tauri/icons/Square107x107Logo.png b/maxc_desktop/src-tauri/icons/Square107x107Logo.png
index 04b896b..f49c977 100644
Binary files a/maxc_desktop/src-tauri/icons/Square107x107Logo.png and b/maxc_desktop/src-tauri/icons/Square107x107Logo.png differ
diff --git a/maxc_desktop/src-tauri/icons/Square142x142Logo.png b/maxc_desktop/src-tauri/icons/Square142x142Logo.png
index 5218115..f4ca777 100644
Binary files a/maxc_desktop/src-tauri/icons/Square142x142Logo.png and b/maxc_desktop/src-tauri/icons/Square142x142Logo.png differ
diff --git a/maxc_desktop/src-tauri/icons/Square150x150Logo.png b/maxc_desktop/src-tauri/icons/Square150x150Logo.png
index 7fe268b..a9be390 100644
Binary files a/maxc_desktop/src-tauri/icons/Square150x150Logo.png and b/maxc_desktop/src-tauri/icons/Square150x150Logo.png differ
diff --git a/maxc_desktop/src-tauri/icons/Square284x284Logo.png b/maxc_desktop/src-tauri/icons/Square284x284Logo.png
index d9a4738..3189931 100644
Binary files a/maxc_desktop/src-tauri/icons/Square284x284Logo.png and b/maxc_desktop/src-tauri/icons/Square284x284Logo.png differ
diff --git a/maxc_desktop/src-tauri/icons/Square30x30Logo.png b/maxc_desktop/src-tauri/icons/Square30x30Logo.png
index 6d04ccd..4778b28 100644
Binary files a/maxc_desktop/src-tauri/icons/Square30x30Logo.png and b/maxc_desktop/src-tauri/icons/Square30x30Logo.png differ
diff --git a/maxc_desktop/src-tauri/icons/Square310x310Logo.png b/maxc_desktop/src-tauri/icons/Square310x310Logo.png
index 57fc8dc..cf0bf64 100644
Binary files a/maxc_desktop/src-tauri/icons/Square310x310Logo.png and b/maxc_desktop/src-tauri/icons/Square310x310Logo.png differ
diff --git a/maxc_desktop/src-tauri/icons/Square44x44Logo.png b/maxc_desktop/src-tauri/icons/Square44x44Logo.png
index a6624b1..ae83744 100644
Binary files a/maxc_desktop/src-tauri/icons/Square44x44Logo.png and b/maxc_desktop/src-tauri/icons/Square44x44Logo.png differ
diff --git a/maxc_desktop/src-tauri/icons/Square71x71Logo.png b/maxc_desktop/src-tauri/icons/Square71x71Logo.png
index 9b8114d..7fc6fab 100644
Binary files a/maxc_desktop/src-tauri/icons/Square71x71Logo.png and b/maxc_desktop/src-tauri/icons/Square71x71Logo.png differ
diff --git a/maxc_desktop/src-tauri/icons/Square89x89Logo.png b/maxc_desktop/src-tauri/icons/Square89x89Logo.png
index 098c959..d0d9b3c 100644
Binary files a/maxc_desktop/src-tauri/icons/Square89x89Logo.png and b/maxc_desktop/src-tauri/icons/Square89x89Logo.png differ
diff --git a/maxc_desktop/src-tauri/icons/StoreLogo.png b/maxc_desktop/src-tauri/icons/StoreLogo.png
index 5b99242..9c92165 100644
Binary files a/maxc_desktop/src-tauri/icons/StoreLogo.png and b/maxc_desktop/src-tauri/icons/StoreLogo.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png b/maxc_desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png
index db90a65..62c7740 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png and b/maxc_desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png b/maxc_desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png
index 1859d09..6a0091a 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png and b/maxc_desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png b/maxc_desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png
index bb5c1a1..a13c9db 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png and b/maxc_desktop/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png b/maxc_desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png
index acb8307..c0b7c74 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png and b/maxc_desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png b/maxc_desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png
index 229ab37..f6aa3a3 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png and b/maxc_desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png b/maxc_desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png
index da6a97e..6c4db50 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png and b/maxc_desktop/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png b/maxc_desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png
index 1825044..3b7040b 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png and b/maxc_desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png b/maxc_desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png
index e94c20b..2fcd9b6 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png and b/maxc_desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png b/maxc_desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png
index 74d318a..7edee03 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png and b/maxc_desktop/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png b/maxc_desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png
index 4410a09..a44a382 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png and b/maxc_desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png b/maxc_desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png
index e2c69c2..3080049 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png and b/maxc_desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png b/maxc_desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png
index 8f83704..8564d05 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png and b/maxc_desktop/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png b/maxc_desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png
index e5e3f0d..eeacbaa 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png and b/maxc_desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png b/maxc_desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png
index bc66a02..d8b2b33 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png and b/maxc_desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/maxc_desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png b/maxc_desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png
index 3496176..0f88f66 100644
Binary files a/maxc_desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png and b/maxc_desktop/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/maxc_desktop/src-tauri/icons/icon.icns b/maxc_desktop/src-tauri/icons/icon.icns
index 58b5de2..cd69e2d 100644
Binary files a/maxc_desktop/src-tauri/icons/icon.icns and b/maxc_desktop/src-tauri/icons/icon.icns differ
diff --git a/maxc_desktop/src-tauri/icons/icon.ico b/maxc_desktop/src-tauri/icons/icon.ico
index 0a1aa64..f9cbc13 100644
Binary files a/maxc_desktop/src-tauri/icons/icon.ico and b/maxc_desktop/src-tauri/icons/icon.ico differ
diff --git a/maxc_desktop/src-tauri/icons/icon.png b/maxc_desktop/src-tauri/icons/icon.png
index 3171898..1e6e364 100644
Binary files a/maxc_desktop/src-tauri/icons/icon.png and b/maxc_desktop/src-tauri/icons/icon.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@1x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@1x.png
index bb90734..19c78e8 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@1x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@1x.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@2x-1.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@2x-1.png
index 56f37ec..5f8efb6 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@2x-1.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@2x-1.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@2x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@2x.png
index 56f37ec..5f8efb6 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@2x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@2x.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@3x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@3x.png
index 637f43c..2c55293 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@3x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-20x20@3x.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@1x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@1x.png
index a30e841..1bf9f0f 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@1x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@1x.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@2x-1.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@2x-1.png
index 7104d80..3d444bf 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@2x-1.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@2x-1.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@2x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@2x.png
index 7104d80..3d444bf 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@2x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@2x.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@3x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@3x.png
index 9e20913..138bd33 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@3x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-29x29@3x.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@1x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@1x.png
index 56f37ec..5f8efb6 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@1x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@1x.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@2x-1.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@2x-1.png
index 9901aed..6cc980f 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@2x-1.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@2x-1.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@2x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@2x.png
index 9901aed..6cc980f 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@2x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@2x.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@3x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@3x.png
index 4198d76..9999c67 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@3x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-40x40@3x.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-512@2x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-512@2x.png
index 7b5b70f..a66a9d4 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-512@2x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-512@2x.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-60x60@2x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-60x60@2x.png
index 4198d76..9999c67 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-60x60@2x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-60x60@2x.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-60x60@3x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-60x60@3x.png
index 8ffd068..55197bb 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-60x60@3x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-60x60@3x.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-76x76@1x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-76x76@1x.png
index f8302e4..5f49dec 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-76x76@1x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-76x76@1x.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-76x76@2x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-76x76@2x.png
index d12831d..2bb8482 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-76x76@2x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-76x76@2x.png differ
diff --git a/maxc_desktop/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png b/maxc_desktop/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png
index 58125b4..296f156 100644
Binary files a/maxc_desktop/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png and b/maxc_desktop/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png differ
diff --git a/maxc_desktop/src-tauri/src/lib.rs b/maxc_desktop/src-tauri/src/lib.rs
index b1a91e1..139af8e 100644
--- a/maxc_desktop/src-tauri/src/lib.rs
+++ b/maxc_desktop/src-tauri/src/lib.rs
@@ -1,10 +1,10 @@
-use std::path::Path;
+use std::path::{Path, PathBuf};
 use std::sync::{Arc, OnceLock};
 use std::time::{SystemTime, UNIX_EPOCH};
 
 use maxc_automation::RpcServer;
 use maxc_core::BackendConfig;
-use tauri::State;
+use tauri::{Manager, State};
 use tauri_plugin_updater::UpdaterExt;
 use url::Url;
 
@@ -15,8 +15,17 @@ struct RpcState {
 
 static RPC_STATE: OnceLock<RpcState> = OnceLock::new();
 
-fn init_server() -> RpcState {
-    let config = BackendConfig::from_env().unwrap_or_else(|_| BackendConfig::default());
+fn init_server(data_dir: Option<PathBuf>) -> RpcState {
+    let mut config = BackendConfig::from_env().unwrap_or_else(|_| BackendConfig::default());
+
+    // Resolve event_dir to an absolute path under the app data directory.
+    // On Windows this is %APPDATA%/com.polluxstudio.maxc-desktop/
+    // This ensures the event store is always writable regardless of CWD.
+    if let Some(dir) = data_dir {
+        let events_dir = dir.join("events");
+        config.event_dir = events_dir.to_string_lossy().to_string();
+    }
+
     let server = RpcServer::new(config).expect("failed to start backend automation server");
     RpcState {
         server: Arc::new(server),
@@ -140,20 +149,29 @@ async fn update_download_and_install(app: tauri::AppHandle, channel: String) ->
             .download_and_install(|_, _| {}, || {})
             .await
             .map_err(|e| e.to_string())?;
+
+        // Restart the app after successful update install
+        app.restart();
     }
     Ok(())
 }
 
 #[cfg_attr(mobile, tauri::mobile_entry_point)]
 pub fn run() {
-    let state = RPC_STATE.get_or_init(init_server).clone();
-
     tauri::Builder::default()
-        .manage(state)
         .plugin(tauri_plugin_opener::init())
         .plugin(tauri_plugin_dialog::init())
         .plugin(tauri_plugin_notification::init())
         .plugin(tauri_plugin_updater::Builder::new().build())
+        .setup(|app| {
+            // Resolve the app data directory for reliable event store path.
+            let data_dir = app.path().app_data_dir().ok();
+            let state = RPC_STATE
+                .get_or_init(|| init_server(data_dir))
+                .clone();
+            app.manage(state);
+            Ok(())
+        })
         .invoke_handler(tauri::generate_handler![
             rpc_call,
             get_git_branch,
diff --git a/maxc_desktop/src-tauri/tauri.conf.json b/maxc_desktop/src-tauri/tauri.conf.json
index ff5e732..d5ceb33 100644
--- a/maxc_desktop/src-tauri/tauri.conf.json
+++ b/maxc_desktop/src-tauri/tauri.conf.json
@@ -15,9 +15,13 @@
         "title": "maxc",
         "width": 1280,
         "height": 832,
+        "minWidth": 1100,
+        "minHeight": 720,
         "decorations": false,
         "center": true,
         "maximized": true,
+        "resizable": true,
+        "maximizable": true,
         "fullscreen": false
       }
     ],
@@ -25,17 +29,22 @@
       "csp": null
     }
   },
-  "bundle": {
-    "active": true,
-    "targets": "all",
-    "createUpdaterArtifacts": true,
-    "icon": [
-      "icons/32x32.png",
-      "icons/128x128.png",
-      "icons/128x128@2x.png",
-      "icons/icon.icns",
-      "icons/icon.ico"
-    ]
+  "bundle": {
+    "active": true,
+    "targets": "all",
+    "createUpdaterArtifacts": true,
+    "icon": [
+      "icons/32x32.png",
+      "icons/128x128.png",
+      "icons/128x128@2x.png",
+      "icons/icon.icns",
+      "icons/icon.ico"
+    ],
+    "windows": {
+      "nsis": {
+        "installMode": "currentUser"
+      }
+    }
   },
   "plugins": {
     "updater": {
diff --git a/maxc_desktop/src/App.css b/maxc_desktop/src/App.css
index 2ee91bf..2dcabd9 100644
--- a/maxc_desktop/src/App.css
+++ b/maxc_desktop/src/App.css
@@ -38,6 +38,9 @@
     --sidebar-accent-foreground: oklch(0.205 0 0);
     --sidebar-border: oklch(0.922 0 0);
     --sidebar-ring: oklch(0.708 0 0);
+    --scrollbar-thumb: oklch(0.62 0 0 / 0.35);
+    --scrollbar-thumb-hover: oklch(0.52 0 0 / 0.5);
+    --scrollbar-track: transparent;
 }
 
 .dark {
@@ -72,6 +75,9 @@
     --sidebar-accent-foreground: oklch(0.985 0 0);
     --sidebar-border: oklch(1 0 0 / 10%);
     --sidebar-ring: oklch(0.556 0 0);
+    --scrollbar-thumb: oklch(0.8 0 0 / 0.25);
+    --scrollbar-thumb-hover: oklch(0.9 0 0 / 0.4);
+    --scrollbar-track: transparent;
 }
 
 @theme inline {
@@ -152,3 +158,28 @@
   width: 0;
   height: 0;
 }
+
+.settings-scroll {
+  scrollbar-width: thin;
+  scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
+}
+
+.settings-scroll::-webkit-scrollbar {
+  width: 8px;
+  height: 8px;
+}
+
+.settings-scroll::-webkit-scrollbar-thumb {
+  background: var(--scrollbar-thumb);
+  border-radius: 999px;
+  border: 2px solid transparent;
+  background-clip: content-box;
+}
+
+.settings-scroll::-webkit-scrollbar-thumb:hover {
+  background: var(--scrollbar-thumb-hover);
+}
+
+.settings-scroll::-webkit-scrollbar-track {
+  background: var(--scrollbar-track);
+}
diff --git a/maxc_desktop/src/App.tsx b/maxc_desktop/src/App.tsx
index d500274..02967c8 100644
--- a/maxc_desktop/src/App.tsx
+++ b/maxc_desktop/src/App.tsx
@@ -10,15 +10,15 @@ import {
 import { getVersion } from "@tauri-apps/api/app";
 import {
   Bell,
-  ChevronDown,
   ChevronRight,
-  Check,
   FolderOpen,
   GitBranch,
   Keyboard,
+  Loader2,
   Minus,
   Moon,
   Plus,
+  ScrollText,
   Settings,
   Square,
   Sun,
@@ -29,33 +29,21 @@ import {
 import logoDark from "./assets/maxc_logo_dark.svg";
 import logoWhite from "./assets/maxc_logo_white.svg";
 import { Button } from "@/components/ui/button";
+import {
+  Dialog,
+  DialogContent,
+  DialogDescription,
+  DialogHeader,
+  DialogTitle,
+} from "@/components/ui/dialog";
 import { type XtermHandle } from "@/components/XtermTerminal";
 import { PaneContainer, type PaneNode, type BrowserState } from "@/components/PaneContainer";
 import { type SurfaceState } from "@/components/SurfaceTabBar";
 import { NotificationPanel, type NotificationItem } from "@/components/NotificationPanel";
+import { SettingsDialog } from "@/components/SettingsDialog";
 import { cn } from "@/lib/utils";
 import "./App.css";
 
-// ---------------------------------------------------------------------------
-// RPC helper
-// ---------------------------------------------------------------------------
-
-async function rpc<T = any>(method: string, params: Record<string, unknown>): Promise<T> {
-  const request = {
-    id: crypto.randomUUID(),
-    method,
-    params,
-  };
-  const raw = await invoke<string>("rpc_call", { request: JSON.stringify(request) });
-  const parsed = JSON.parse(raw);
-  if (parsed.error) {
-    const code = parsed.error.code || "ERROR";
-    const message = parsed.error.message || "Unknown error";
-    throw new Error(code + ": " + message);
-  }
-  return parsed.result as T;
-}
-
 // ---------------------------------------------------------------------------
 // Types
 // ---------------------------------------------------------------------------
@@ -84,14 +72,146 @@ type Readiness = {
 };
 
 type EnvEntry = { key: string; value: string };
-type UpdateInfo = {
-  available: boolean;
-  version?: string;
-  current_version?: string;
-  date_ms?: number | null;
-  body?: string | null;
+
+type ShortcutDef = {
+  id: string;
+  label: string;
+  defaultKeys: string;
+};
+
+type ShortcutBinding = ShortcutDef & { keys: string };
+
+type ParsedShortcut = ShortcutBinding & {
+  binding: {
+    key: string;
+    ctrl: boolean;
+    shift: boolean;
+    alt: boolean;
+  } | null;
+};
+
+const LOG_FILTERS = [
+  { id: "all", label: "All" },
+  { id: "system", label: "system.*" },
+  { id: "session", label: "session.*" },
+  { id: "workspace", label: "workspace.*" },
+  { id: "pane", label: "pane.*" },
+  { id: "surface", label: "surface.*" },
+  { id: "terminal", label: "terminal.*" },
+  { id: "browser", label: "browser.*" },
+  { id: "agent", label: "agent.*" },
+  { id: "notification", label: "notification.*" },
+  { id: "other", label: "Other" },
+];
+
+type BackendLogEntry = {
+  timestamp_ms: number;
+  level: "trace" | "debug" | "info" | "warn" | "error";
+  component: string;
+  event: string;
+  correlation_id: string;
+  command_id?: string | null;
+  connection_id?: string | null;
+  workspace_id?: string | null;
+  surface_id?: string | null;
+  method?: string | null;
+  duration_ms?: number | null;
+  status?: string | null;
+  fields?: Record<string, unknown>;
 };
 
+const DEFAULT_SHORTCUTS: ShortcutDef[] = [
+  { id: "new-window", label: "New window", defaultKeys: "Ctrl+Shift+N" },
+  { id: "new-workspace", label: "New workspace", defaultKeys: "Ctrl+N" },
+  { id: "new-terminal", label: "New terminal", defaultKeys: "Ctrl+T" },
+  { id: "new-browser", label: "New browser", defaultKeys: "Ctrl+B" },
+  { id: "split-right", label: "Split pane right", defaultKeys: "Ctrl+D" },
+  { id: "split-down", label: "Split pane down", defaultKeys: "Ctrl+Shift+D" },
+  { id: "toggle-shortcuts", label: "Toggle shortcuts", defaultKeys: "Ctrl+/" },
+];
+
+const MODIFIER_ALIASES = new Map<string, "ctrl" | "shift" | "alt">([
+  ["ctrl", "ctrl"],
+  ["control", "ctrl"],
+  ["cmd", "ctrl"],
+  ["command", "ctrl"],
+  ["meta", "ctrl"],
+  ["shift", "shift"],
+  ["alt", "alt"],
+  ["option", "alt"],
+]);
+
+function normalizeKeyToken(token: string) {
+  return token.length === 1 ? token.toLowerCase() : token.toLowerCase();
+}
+
+function parseShortcutKeys(raw: string) {
+  const trimmed = raw.trim();
+  if (!trimmed) return null;
+  const parts = trimmed.split("+").map((p) => p.trim()).filter(Boolean);
+  if (parts.length === 0) return null;
+  let ctrl = false;
+  let shift = false;
+  let alt = false;
+  const keyPart = parts[parts.length - 1];
+  for (const part of parts.slice(0, -1)) {
+    const mod = MODIFIER_ALIASES.get(part.toLowerCase());
+    if (mod === "ctrl") ctrl = true;
+    if (mod === "shift") shift = true;
+    if (mod === "alt") alt = true;
+  }
+  if (MODIFIER_ALIASES.has(keyPart.toLowerCase())) return null;
+  return {
+    key: normalizeKeyToken(keyPart),
+    ctrl,
+    shift,
+    alt,
+  };
+}
+
+function matchesShortcutEvent(e: KeyboardEvent, binding: { key: string; ctrl: boolean; shift: boolean; alt: boolean }) {
+  const key = normalizeKeyToken(e.key);
+  if (key !== binding.key) return false;
+  const hasCtrl = e.ctrlKey || e.metaKey;
+  if (binding.ctrl !== hasCtrl) return false;
+  if (binding.shift !== e.shiftKey) return false;
+  if (binding.alt !== e.altKey) return false;
+  return true;
+}
+
+function getMethodFamily(method?: string | null) {
+  if (!method) return "other";
+  const normalized = method.toLowerCase();
+  const idx = normalized.indexOf(".");
+  if (idx <= 0) return "other";
+  return normalized.slice(0, idx);
+}
+
+function extractLogMethod(entry: BackendLogEntry) {
+  if (entry.method) return entry.method;
+  const fieldMethod = entry.fields?.method;
+  return typeof fieldMethod === "string" ? fieldMethod : null;
+}
+
+function shortcutsFromStorage(): Record<string, string> | null {
+  if (typeof window === "undefined") return null;
+  try {
+    const raw = window.localStorage.getItem("maxc-shortcuts");
+    if (!raw) return null;
+    const parsed = JSON.parse(raw);
+    return typeof parsed === "object" && parsed !== null ? parsed : null;
+  } catch {
+    return null;
+  }
+}
+
+function buildShortcutMap(overrides?: Record<string, string> | null) {
+  const map: Record<string, string> = {};
+  for (const def of DEFAULT_SHORTCUTS) {
+    map[def.id] = overrides?.[def.id] ?? def.defaultKeys;
+  }
+  return map;
+}
 // ---------------------------------------------------------------------------
 // Title Bar
 // ---------------------------------------------------------------------------
@@ -106,6 +226,7 @@ function TitleBar({ theme }: { theme: "dark" | "light" }) {
   }, []);
 
   const handleMin = () => appWindow?.minimize().catch(console.error);
+  const handleMax = () => appWindow?.toggleMaximize().catch(console.error);
   const handleClose = () => appWindow?.close().catch(console.error);
 
   return (
@@ -114,7 +235,7 @@ function TitleBar({ theme }: { theme: "dark" | "light" }) {
         <img
           src={theme === "light" ? logoDark : logoWhite}
           alt="maxc"
-          className="h-5 w-auto select-none"
+          className="h-6 w-auto select-none"
           draggable={false}
         />
       </div>
@@ -131,10 +252,9 @@ function TitleBar({ theme }: { theme: "dark" | "light" }) {
         <Button
           variant="ghost"
           size="icon-sm"
-          disabled
-          className="no-drag text-muted-foreground/40"
-          aria-label="Maximize (disabled)"
-          title="Maximize disabled"
+          onClick={(e) => { e.stopPropagation(); handleMax(); }}
+          className="no-drag"
+          aria-label="Toggle maximize"
         >
           <Square className="size-3.5" />
         </Button>
@@ -170,51 +290,54 @@ function App() {
   const [surfaces, setSurfaces] = useState<SurfaceState[]>([]);
   const [browserStates, setBrowserStates] = useState<Map<string, BrowserState>>(new Map());
 
-  // -- drawer state --
-  const [drawerOpen, setDrawerOpen] = useState(false);
-  const [wsName, setWsName] = useState("");
-  const [wsFolder, setWsFolder] = useState("");
-  const [wsEnvVars, setWsEnvVars] = useState<EnvEntry[]>([]);
-  const [wsCreating, setWsCreating] = useState(false);
-  const [wsError, setWsError] = useState("");
-  const [editDrawerOpen, setEditDrawerOpen] = useState(false);
-  const [editWorkspaceId, setEditWorkspaceId] = useState("");
-  const [editEnvVars, setEditEnvVars] = useState<EnvEntry[]>([]);
-  const [editSaving, setEditSaving] = useState(false);
-  const [editError, setEditError] = useState("");
+  // -- settings dialog state --
+  const [settingsOpen, setSettingsOpen] = useState(false);
+  const [settingsDefaultTab, setSettingsDefaultTab] = useState("workspace");
+  const [settingsEditWorkspace, setSettingsEditWorkspace] = useState<Workspace | null>(null);
 
   // -- workspace metadata --
   const [gitBranches, setGitBranches] = useState<Record<string, string>>({});
   const [notificationItems, setNotificationItems] = useState<NotificationItem[]>([]);
   const [notificationPanelOpen, setNotificationPanelOpen] = useState(false);
   const [toastItems, setToastItems] = useState<NotificationItem[]>([]);
-  const [settingsOpen, setSettingsOpen] = useState(false);
   const [theme, setTheme] = useState<"dark" | "light">(() => {
     if (typeof window === "undefined") return "dark";
     const stored = window.localStorage.getItem("maxc-theme");
     return stored === "light" ? "light" : "dark";
   });
   const [appVersion, setAppVersion] = useState("");
-  const [updateChannel, setUpdateChannel] = useState<"stable" | "beta">(() => {
-    if (typeof window === "undefined") return "stable";
-    const stored = window.localStorage.getItem("maxc-update-channel");
-    return stored === "beta" ? "beta" : "stable";
-  });
-  const [updateStatus, setUpdateStatus] = useState<
-    "idle" | "checking" | "available" | "uptodate" | "downloading" | "ready" | "error"
-  >("idle");
-  const [updateError, setUpdateError] = useState("");
-  const [updateInfo, setUpdateInfo] = useState<UpdateInfo | null>(null);
-  const [updateProgress, setUpdateProgress] = useState<{ downloaded: number; total?: number }>({
-    downloaded: 0,
-    total: undefined,
-  });
-  const [envCopied, setEnvCopied] = useState(false);
 
   // -- shortcut help --
   const [showShortcuts, setShowShortcuts] = useState(false);
   const [renamingWorkspaceId, setRenamingWorkspaceId] = useState("");
   const [renameValue, setRenameValue] = useState("");
+  const [shortcutMap, setShortcutMap] = useState<Record<string, string>>(() =>
+    buildShortcutMap(shortcutsFromStorage()),
+  );
+  const [logsOpen, setLogsOpen] = useState(false);
+  const [rpcLogs, setRpcLogs] = useState<BackendLogEntry[]>([]);
+  const [rpcLogsLoading, setRpcLogsLoading] = useState(false);
+  const [rpcLogsError, setRpcLogsError] = useState("");
+  const [diagnosticsToken, setDiagnosticsToken] = useState<string | null>(null);
+  const [logFilter, setLogFilter] = useState("all");
+  const [logLevelFilter, setLogLevelFilter] = useState("all");
+  const [logSearch, setLogSearch] = useState("");
+
+  // -- create workspace drawer state --
+  const [drawerOpen, setDrawerOpen] = useState(false);
+  const [wsName, setWsName] = useState("");
+  const [wsFolder, setWsFolder] = useState("");
+  const [wsEnvVars, setWsEnvVars] = useState<EnvEntry[]>([]);
+  const [wsCreating, setWsCreating] = useState(false);
+  const [wsError, setWsError] = useState("");
+  const [rpcRateLimit, setRpcRateLimit] = useState<number | "unlimited">(() => {
+    if (typeof window === "undefined") return 30;
+    const stored = window.localStorage.getItem("maxc-rpc-rate-limit");
+    if (!stored) return 30;
+    if (stored === "unlimited") return "unlimited";
+    const parsed = Number(stored);
+    return Number.isFinite(parsed) && parsed > 0 ? parsed : 30;
+  });
 
   // -- refs --
   const surfacesRef = useRef<SurfaceState[]>([]);
@@ -229,6 +352,15 @@ function App() {
   const inputBufferRef = useRef<Map<string, string>>(new Map());
   const inputTimerRef = useRef<Map<string, number>>(new Map());
   const inputInFlightRef = useRef<Set<string>>(new Set());
+  const rateLimiterRef = useRef<{
+    limit: number | null;
+    timestamps: number[];
+    queue: Promise<void>;
+  }>({
+    limit: rpcRateLimit === "unlimited" ? null : rpcRateLimit,
+    timestamps: [],
+    queue: Promise.resolve(),
+  });
 
   const selectedWorkspace = useMemo(
     () => workspaces.find((w) => w.workspace_id === selectedWorkspaceId) ?? workspaces[0] ?? null,
@@ -253,10 +385,69 @@ function App() {
   }, []);
 
   useEffect(() => {
-    window.localStorage.setItem("maxc-update-channel", updateChannel);
-  }, [updateChannel]);
+    if (typeof window === "undefined") return;
+    window.localStorage.setItem(
+      "maxc-rpc-rate-limit",
+      rpcRateLimit === "unlimited" ? "unlimited" : String(rpcRateLimit),
+    );
+    rateLimiterRef.current.limit = rpcRateLimit === "unlimited" ? null : rpcRateLimit;
+  }, [rpcRateLimit]);
+
+  useEffect(() => {
+    if (typeof window === "undefined") return;
+    window.localStorage.setItem("maxc-shortcuts", JSON.stringify(shortcutMap));
+  }, [shortcutMap]);
 
   const readyForActions = Boolean(token) && (readiness?.ready ?? false) && selectedWorkspace !== null;
+  const shortcutList = useMemo<ShortcutBinding[]>(
+    () =>
+      DEFAULT_SHORTCUTS.map((def) => ({
+        ...def,
+        keys: shortcutMap[def.id] ?? def.defaultKeys,
+      })),
+    [shortcutMap],
+  );
+  const parsedShortcuts = useMemo<ParsedShortcut[]>(
+    () =>
+      shortcutList.map((entry) => ({
+        ...entry,
+        binding: parseShortcutKeys(entry.keys),
+      })),
+    [shortcutList],
+  );
+  const filteredRpcLogs = useMemo(() => {
+    let next = rpcLogs;
+    if (logFilter !== "all") {
+      if (logFilter === "other") {
+        next = next.filter((entry) => {
+          const family = getMethodFamily(extractLogMethod(entry));
+          return !LOG_FILTERS.some((filter) => filter.id === family && filter.id !== "other");
+        });
+      } else {
+        next = next.filter((entry) => {
+          const family = getMethodFamily(extractLogMethod(entry));
+          return family === logFilter;
+        });
+      }
+    }
+    if (logLevelFilter !== "all") {
+      next = next.filter((entry) => entry.level === logLevelFilter);
+    }
+    const query = logSearch.trim().toLowerCase();
+    if (query) {
+      next = next.filter((entry) => {
+        const method = extractLogMethod(entry) ?? "";
+        const event = entry.event ?? "";
+        const component = entry.component ?? "";
+        return (
+          method.toLowerCase().includes(query)
+          || event.toLowerCase().includes(query)
+          || component.toLowerCase().includes(query)
+        );
+      });
+    }
+    return next;
+  }, [logFilter, logLevelFilter, logSearch, rpcLogs]);
 
   const unreadNotifications = useMemo(
     () => notificationItems.filter((n) => !n.read),
@@ -292,6 +483,50 @@ function App() {
     return `https://${trimmed}`;
   }
 
+  const acquireRateLimitSlot = useCallback(async () => {
+    const state = rateLimiterRef.current;
+    const limit = state.limit;
+    if (!limit || limit <= 0) return;
+    const windowMs = 1000;
+    const now = Date.now();
+    state.timestamps = state.timestamps.filter((ts) => now - ts < windowMs);
+    if (state.timestamps.length < limit) {
+      state.timestamps.push(now);
+      return;
+    }
+    const waitMs = Math.max(0, windowMs - (now - state.timestamps[0]));
+    await new Promise((resolve) => setTimeout(resolve, waitMs));
+    return acquireRateLimitSlot();
+  }, []);
+
+  const scheduleRpcSlot = useCallback(() => {
+    const state = rateLimiterRef.current;
+    if (!state.limit || state.limit <= 0) return Promise.resolve();
+    const next = state.queue.then(() => acquireRateLimitSlot());
+    state.queue = next.catch(() => {});
+    return next;
+  }, [acquireRateLimitSlot]);
+
+  const rpc = useCallback(
+    async <T,>(method: string, params: Record<string, unknown>): Promise<T> => {
+      await scheduleRpcSlot();
+      const request = {
+        id: crypto.randomUUID(),
+        method,
+        params,
+      };
+      const raw = await invoke<string>("rpc_call", { request: JSON.stringify(request) });
+      const parsed = JSON.parse(raw);
+      if (parsed.error) {
+        const code = parsed.error.code || "ERROR";
+        const message = parsed.error.message || "Unknown error";
+        throw new Error(code + ": " + message);
+      }
+      return parsed.result as T;
+    },
+    [scheduleRpcSlot],
+  );
+
   // -- workspace metadata enrichment --
   const workspaceMetas: WorkspaceMeta[] = useMemo(() => {
     return workspaces.map((ws) => {
@@ -552,13 +787,6 @@ function App() {
       const ctrl = e.ctrlKey || e.metaKey;
       const targetSurface = focusedSurface?.surfaceId;
 
-      // Ctrl+Shift+N -> new window
-      if (ctrl && e.shiftKey && e.key.toLowerCase() === "n") {
-        e.preventDefault();
-        invoke("create_window").catch(console.error);
-        return;
-      }
-
       // Ctrl + / Ctrl = -> increase font size
       if (ctrl && (e.key === "+" || e.key === "=")) {
         e.preventDefault();
@@ -573,23 +801,38 @@ function App() {
         return;
       }
 
-      // Ctrl+N -> new workspace drawer
-      if (ctrl && e.key === "n") { e.preventDefault(); openDrawer(); return; }
-
-      // Ctrl+T -> new terminal surface in focused pane
-      if (ctrl && e.key === "t") { e.preventDefault(); handleCreateSurface(focusedPaneId, "terminal"); return; }
-
-      // Ctrl+B -> new browser surface in focused pane
-      if (ctrl && e.key === "b") { e.preventDefault(); handleCreateSurface(focusedPaneId, "browser"); return; }
-
-      // Ctrl+D -> split pane right
-      if (ctrl && !e.shiftKey && e.key === "d") { e.preventDefault(); handleSplitPane(focusedPaneId, "vertical"); return; }
-
-      // Ctrl+Shift+D -> split pane down
-      if (ctrl && e.shiftKey && e.key === "D") { e.preventDefault(); handleSplitPane(focusedPaneId, "horizontal"); return; }
-
-      // Ctrl+? -> toggle shortcuts panel
-      if (ctrl && e.key === "/") { e.preventDefault(); setShowShortcuts((v) => !v); return; }
+      const matchedShortcut = parsedShortcuts.find(
+        (shortcut) => shortcut.binding && matchesShortcutEvent(e, shortcut.binding),
+      );
+      if (matchedShortcut) {
+        e.preventDefault();
+        switch (matchedShortcut.id) {
+          case "new-window":
+            invoke("create_window").catch(console.error);
+            break;
+          case "new-workspace":
+            openDrawer();
+            break;
+          case "new-terminal":
+            handleCreateSurface(focusedPaneId, "terminal");
+            break;
+          case "new-browser":
+            handleCreateSurface(focusedPaneId, "browser");
+            break;
+          case "split-right":
+            handleSplitPane(focusedPaneId, "vertical");
+            break;
+          case "split-down":
+            handleSplitPane(focusedPaneId, "horizontal");
+            break;
+          case "toggle-shortcuts":
+            setShowShortcuts((v) => !v);
+            break;
+          default:
+            break;
+        }
+        return;
+      }
 
       // Alt+1-9 -> switch workspace
       if (e.altKey && e.key >= "1" && e.key <= "9") {
@@ -601,130 +844,202 @@ function App() {
         return;
       }
 
-      // Escape -> close drawer/shortcuts
+      // Escape -> close panels
       if (e.key === "Escape") {
-        if (drawerOpen) closeDrawer();
-        if (editDrawerOpen) closeEditDrawer();
         if (showShortcuts) setShowShortcuts(false);
         if (notificationPanelOpen) setNotificationPanelOpen(false);
+        if (logsOpen) setLogsOpen(false);
+        if (drawerOpen) setDrawerOpen(false);
         if (settingsOpen) setSettingsOpen(false);
       }
     };
     window.addEventListener("keydown", handler);
     return () => window.removeEventListener("keydown", handler);
-  }, [focusedSurface?.surfaceId, focusedPaneId, workspaces, selectedWorkspaceId, drawerOpen, editDrawerOpen, showShortcuts, notificationPanelOpen, settingsOpen]);
+  }, [
+    focusedSurface?.surfaceId,
+    focusedPaneId,
+    workspaces,
+    selectedWorkspaceId,
+    showShortcuts,
+    notificationPanelOpen,
+    logsOpen,
+    drawerOpen,
+    settingsOpen,
+    parsedShortcuts,
+  ]);
 
   // ---------------------------------------------------------------------------
-  // Drawer actions
+  // Settings dialog helpers
   // ---------------------------------------------------------------------------
   function openDrawer() {
-    setWsName(""); setWsFolder(""); setWsEnvVars([]); setWsError("");
+    setSettingsEditWorkspace(null);
+    setSettingsDefaultTab("workspace");
+    setSettingsOpen(false);
     setDrawerOpen(true);
+    setWsName("");
+    setWsFolder("");
+    setWsEnvVars([]);
+    setWsError("");
   }
+  function openEditDrawer(ws: Workspace) {
+    setSettingsEditWorkspace(ws);
+    setSettingsDefaultTab("workspace");
+    setDrawerOpen(false);
+    setSettingsOpen(true);
+  }
+  function openSettings(tab = "updates") {
+    setSettingsEditWorkspace(null);
+    setSettingsDefaultTab(tab);
+    setDrawerOpen(false);
+    setSettingsOpen(true);
+  }
+
   function closeDrawer() {
-    setDrawerOpen(false); setWsCreating(false); setWsError("");
+    setDrawerOpen(false);
   }
+
   async function pickFolder() {
     try {
       const selected = await open({ directory: true, multiple: false, title: "Select workspace folder" });
       if (selected && typeof selected === "string") setWsFolder(selected);
-    } catch { /* cancelled */ }
+    } catch {
+      // cancelled
+    }
   }
-  function addEnvEntry() { setWsEnvVars((p) => [...p, { key: "", value: "" }]); }
-  function updateEnvEntry(i: number, field: "key" | "value", val: string) {
-    setWsEnvVars((p) => p.map((e, idx) => (idx === i ? { ...e, [field]: val } : e)));
+
+  function addEnvEntry() {
+    setWsEnvVars((prev) => [...prev, { key: "", value: "" }]);
   }
-  function removeEnvEntry(i: number) { setWsEnvVars((p) => p.filter((_, idx) => idx !== i)); }
 
-  function addEditEnvEntry() { setEditEnvVars((p) => [...p, { key: "", value: "" }]); }
-  function updateEditEnvEntry(i: number, field: "key" | "value", val: string) {
-    setEditEnvVars((p) => p.map((e, idx) => (idx === i ? { ...e, [field]: val } : e)));
+  function updateEnvEntry(i: number, field: "key" | "value", value: string) {
+    setWsEnvVars((prev) =>
+      prev.map((entry, idx) => (idx === i ? { ...entry, [field]: value } : entry)),
+    );
   }
-  function removeEditEnvEntry(i: number) {
-    setEditEnvVars((p) => p.filter((_, idx) => idx !== i));
+
+  function removeEnvEntry(i: number) {
+    setWsEnvVars((prev) => prev.filter((_, idx) => idx !== i));
   }
 
   async function createWorkspace() {
-    if (!token) { setWsError("No session token"); return; }
     const name = wsName.trim();
-    if (!name) { setWsError("Workspace name is required"); return; }
-
+    if (!name) {
+      setWsError("Workspace name is required");
+      return;
+    }
     const envObj: Record<string, string> = {};
-    for (const e of wsEnvVars) { const k = e.key.trim(); if (k) envObj[k] = e.value; }
-
-    setWsCreating(true); setWsError("");
+    for (const entry of wsEnvVars) {
+      const key = entry.key.trim();
+      if (key) envObj[key] = entry.value;
+    }
+    setWsCreating(true);
+    setWsError("");
     try {
-      const result = await rpc<Workspace>("workspace.create", {
-        command_id: "ui-ws-create-" + crypto.randomUUID(),
-        name, folder: wsFolder, env_vars: envObj,
-        auth: { token },
-      });
-      const newWs: Workspace = {
-        workspace_id: result.workspace_id, name: result.name,
-        folder: result.folder, env_vars: result.env_vars, created_at_ms: result.created_at_ms,
-      };
-      setWorkspaces((w) => [...w, newWs]);
-      setSelectedWorkspaceId(newWs.workspace_id);
-      setBackendStatus("Workspace created");
-      closeDrawer();
-    } catch (error) {
-      setWsError((error as Error).message);
-    } finally { setWsCreating(false); }
+      await handleDialogCreateWorkspace(name, wsFolder, envObj);
+      setWsName("");
+      setWsFolder("");
+      setWsEnvVars([]);
+      setDrawerOpen(false);
+    } catch (err) {
+      setWsError((err as Error).message || "Failed to create workspace");
+    } finally {
+      setWsCreating(false);
+    }
   }
 
-  function openEditDrawer(ws: Workspace) {
-    setEditWorkspaceId(ws.workspace_id);
-    const editable = Object.entries(ws.env_vars || {})
-      .filter(([key]) => !key.startsWith("MAXC_"))
-      .map(([key, value]) => ({ key, value }));
-    setEditEnvVars(editable);
-    setEditError("");
-    setEditDrawerOpen(true);
+  function handleShortcutChange(id: string, keys: string) {
+    setShortcutMap((prev) => ({
+      ...prev,
+      [id]: keys,
+    }));
   }
 
-  function closeEditDrawer() {
-    setEditDrawerOpen(false);
-    setEditSaving(false);
-    setEditError("");
+  function resetShortcuts() {
+    setShortcutMap(buildShortcutMap());
   }
 
-  async function saveWorkspaceEnv() {
-    if (!token || !editWorkspaceId) return;
-    const ws = workspaces.find((w) => w.workspace_id === editWorkspaceId);
-    if (!ws) return;
-
-    const envObj: Record<string, string> = {};
-    for (const e of editEnvVars) {
-      const k = e.key.trim();
-      if (k) envObj[k] = e.value;
+  function handleRpcRateLimitChange(value: string) {
+    if (value === "unlimited") {
+      setRpcRateLimit("unlimited");
+      return;
     }
-    // Preserve MAXC_* and other system-provided values
-    for (const [key, value] of Object.entries(ws.env_vars || {})) {
-      if (key.startsWith("MAXC_") && !(key in envObj)) {
-        envObj[key] = value;
-      }
+    const parsed = Number(value);
+    if (Number.isFinite(parsed) && parsed > 0) {
+      setRpcRateLimit(parsed);
     }
+  }
 
-    setEditSaving(true);
-    setEditError("");
+  const loadRpcLogs = useCallback(async () => {
+    if (!token && !diagnosticsToken) return;
+    setRpcLogsLoading(true);
+    setRpcLogsError("");
     try {
-      await rpc("workspace.update", {
-        command_id: "ui-ws-env-update-" + crypto.randomUUID(),
-        workspace_id: ws.workspace_id,
-        env_vars: envObj,
-        auth: { token },
+      const authToken = diagnosticsToken ?? token;
+      const result = await rpc<{ logs: BackendLogEntry[] }>("system.logs", {
+        auth: { token: authToken },
       });
-      setWorkspaces((prev) =>
-        prev.map((w) =>
-          w.workspace_id === ws.workspace_id ? { ...w, env_vars: envObj } : w,
-        ),
-      );
-      closeEditDrawer();
+      const logs = Array.isArray(result.logs) ? result.logs : [];
+      const sorted = logs.slice().sort((a, b) => b.timestamp_ms - a.timestamp_ms);
+      setRpcLogs(sorted);
     } catch (err) {
-      setEditError((err as Error).message);
+      const message = err instanceof Error ? err.message : String(err);
+      if (!diagnosticsToken && /unauthorized/i.test(message)) {
+        try {
+          const diagSession = await rpc<{ token: string }>("session.create", {
+            command_id: "ui-session-diagnostics-" + crypto.randomUUID(),
+            scopes: ["diagnostics"],
+          });
+          setDiagnosticsToken(diagSession.token);
+          const retry = await rpc<{ logs: BackendLogEntry[] }>("system.logs", {
+            auth: { token: diagSession.token },
+          });
+          const logs = Array.isArray(retry.logs) ? retry.logs : [];
+          const sorted = logs.slice().sort((a, b) => b.timestamp_ms - a.timestamp_ms);
+          setRpcLogs(sorted);
+          setRpcLogsError("");
+        } catch (diagErr) {
+          setRpcLogsError(diagErr instanceof Error ? diagErr.message : String(diagErr));
+        }
+      } else {
+        setRpcLogsError(message);
+      }
     } finally {
-      setEditSaving(false);
+      setRpcLogsLoading(false);
     }
+  }, [rpc, token, diagnosticsToken]);
+
+  useEffect(() => {
+    if (!logsOpen) return;
+    loadRpcLogs();
+  }, [logsOpen, loadRpcLogs]);
+
+  async function handleDialogCreateWorkspace(name: string, folder: string, envVars: Record<string, string>) {
+    if (!token) throw new Error("No session token");
+    const result = await rpc<Workspace>("workspace.create", {
+      command_id: "ui-ws-create-" + crypto.randomUUID(),
+      name, folder, env_vars: envVars,
+      auth: { token },
+    });
+    const newWs: Workspace = {
+      workspace_id: result.workspace_id, name: result.name,
+      folder: result.folder, env_vars: result.env_vars, created_at_ms: result.created_at_ms,
+    };
+    setWorkspaces((w) => [...w, newWs]);
+    setSelectedWorkspaceId(newWs.workspace_id);
+    setBackendStatus("Workspace created");
+  }
+
+  async function handleDialogSaveWorkspaceEnv(workspaceId: string, envVars: Record<string, string>) {
+    if (!token) throw new Error("No session token");
+    await rpc("workspace.update", {
+      command_id: "ui-ws-env-update-" + crypto.randomUUID(),
+      workspace_id: workspaceId,
+      env_vars: envVars,
+      auth: { token },
+    });
+    setWorkspaces((prev) =>
+      prev.map((w) => w.workspace_id === workspaceId ? { ...w, env_vars: envVars } : w),
+    );
   }
 
   // ---------------------------------------------------------------------------
@@ -1734,7 +2049,15 @@ function App() {
             <Button
               size="icon-xs"
               variant="ghost"
-              onClick={() => setSettingsOpen(true)}
+              onClick={() => setLogsOpen(true)}
+              title="RPC Logs"
+            >
+              <ScrollText className="size-3" />
+            </Button>
+            <Button
+              size="icon-xs"
+              variant="ghost"
+              onClick={() => openSettings("updates")}
               title="Settings"
             >
               <Settings className="size-3" />
@@ -1780,6 +2103,7 @@ function App() {
         focusedPaneId={focusedPaneId}
         token={token}
         paneCount={paneCount}
+        canCreateSurface={readyForActions}
         onFocusPane={setFocusedPaneId}
         onSplitPane={handleSplitPane}
         onClosePane={handleClosePane}
@@ -1827,131 +2151,258 @@ function App() {
   }
 
   // ---------------------------------------------------------------------------
-  // New Workspace Drawer
+  // Keyboard shortcuts overlay
   // ---------------------------------------------------------------------------
-  function renderDrawer() {
+  function renderShortcutsPanel() {
+    return (
+      <Dialog open={showShortcuts} onOpenChange={setShowShortcuts}>
+        <DialogContent className="sm:max-w-sm">
+          <DialogHeader>
+            <DialogTitle className="flex items-center gap-2">
+              <Keyboard className="size-4" />
+              Keyboard Shortcuts
+            </DialogTitle>
+            <DialogDescription>
+              Customize shortcuts in Settings → Shortcuts.
+            </DialogDescription>
+          </DialogHeader>
+          <div className="space-y-2">
+            {shortcutList.map((s) => (
+              <div key={s.id} className="flex items-center justify-between text-xs">
+                <span className="text-muted-foreground">{s.label}</span>
+                <kbd className="rounded bg-muted px-2 py-0.5 text-[11px] font-mono">
+                  {s.keys}
+                </kbd>
+              </div>
+            ))}
+            <div className="flex items-center justify-between text-xs">
+              <span className="text-muted-foreground">Switch workspace</span>
+              <kbd className="rounded bg-muted px-2 py-0.5 text-[11px] font-mono">Alt+1-9</kbd>
+            </div>
+            <div className="flex items-center justify-between text-xs">
+              <span className="text-muted-foreground">Close panel / drawer</span>
+              <kbd className="rounded bg-muted px-2 py-0.5 text-[11px] font-mono">Escape</kbd>
+            </div>
+          </div>
+        </DialogContent>
+      </Dialog>
+    );
+  }
+
+  function renderNotificationToasts() {
+    if (toastItems.length === 0) return null;
+    return (
+      <div className="fixed right-4 top-12 z-50 flex w-[280px] flex-col gap-2">
+        {toastItems.map((n) => (
+          <div
+            key={n.notification_id}
+            className={cn(
+              "rounded-lg border px-3 py-2 text-xs shadow-lg backdrop-blur",
+              n.level === "success"
+                ? "border-emerald-500/20 bg-emerald-500/10 text-emerald-100"
+                : n.level === "warning"
+                  ? "border-amber-500/20 bg-amber-500/10 text-amber-100"
+                  : n.level === "error"
+                    ? "border-rose-500/20 bg-rose-500/10 text-rose-100"
+                    : "border-blue-500/20 bg-blue-500/10 text-blue-100",
+            )}
+          >
+            <div className="font-semibold">{n.title}</div>
+            {n.body && <div className="mt-1 text-[11px] text-white/70">{n.body}</div>}
+          </div>
+        ))}
+      </div>
+    );
+  }
+
+  function renderRpcLogsDrawer() {
     return (
       <>
         <div
           className={cn(
             "fixed inset-0 z-40 bg-black/40 transition-opacity duration-200",
-            drawerOpen ? "opacity-100" : "pointer-events-none opacity-0",
+            logsOpen ? "opacity-100" : "pointer-events-none opacity-0",
           )}
-          onClick={closeDrawer}
+          onClick={() => setLogsOpen(false)}
         />
         <div
           className={cn(
-            "fixed right-0 top-0 z-50 flex h-full w-[380px] flex-col border-l bg-card shadow-xl transition-transform duration-200 ease-out",
-            drawerOpen ? "translate-x-0" : "translate-x-full",
+            "fixed right-0 top-0 z-50 flex h-full w-[420px] flex-col border-l bg-card shadow-xl transition-transform duration-200 ease-out",
+            logsOpen ? "translate-x-0" : "translate-x-full",
           )}
         >
           <div className="flex items-center justify-between border-b px-5 py-4">
-            <h2 className="text-sm font-semibold">New Workspace</h2>
-            <Button variant="ghost" size="icon-sm" onClick={closeDrawer}><X className="size-4" /></Button>
-          </div>
-          <div className="flex-1 overflow-auto px-5 py-4 space-y-5">
-            {/* workspace id */}
-            <div className="space-y-1.5">
-              <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">Workspace ID</label>
-              <div className="rounded-md border bg-muted px-3 py-2 text-xs text-muted-foreground">Auto-generated on creation</div>
+            <div className="space-y-0.5">
+              <h2 className="text-sm font-semibold">RPC Logs</h2>
+              <div className="text-[11px] text-muted-foreground">
+                {filteredRpcLogs.length} of {rpcLogs.length} entries
+              </div>
             </div>
-            {/* name */}
-            <div className="space-y-1.5">
-              <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">Name <span className="text-destructive">*</span></label>
-              <input type="text" value={wsName} onChange={(e) => setWsName(e.target.value)} placeholder="e.g. my-project"
-                className="w-full rounded-md border bg-background px-3 py-2 text-xs outline-none transition focus:border-primary/50 focus:ring-1 focus:ring-primary/30"
-                autoFocus
-              />
+            <div className="flex items-center gap-2">
+              <Button
+                variant="outline"
+                size="sm"
+                className="h-7 px-2 text-[11px]"
+                onClick={loadRpcLogs}
+                disabled={rpcLogsLoading}
+              >
+                {rpcLogsLoading ? (
+                  <span className="inline-flex items-center gap-1.5">
+                    <Loader2 className="size-3 animate-spin" />
+                    Refreshing
+                  </span>
+                ) : (
+                  "Refresh"
+                )}
+              </Button>
+              <Button variant="ghost" size="icon-sm" onClick={() => setLogsOpen(false)}>
+                <X className="size-4" />
+              </Button>
             </div>
-            {/* folder */}
-            <div className="space-y-1.5">
-              <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">Working Directory</label>
-              <div className="flex gap-2">
-                <div className="flex-1 truncate rounded-md border bg-background px-3 py-2 text-xs text-muted-foreground">
-                  {wsFolder || "No folder selected"}
-                </div>
-                <Button variant="outline" size="sm" onClick={pickFolder} className="h-[34px] px-2.5 shrink-0">
-                  <FolderOpen className="size-3.5" /><span>Browse</span>
-                </Button>
+          </div>
+          <div className="settings-scroll flex-1 overflow-auto px-5 py-4 space-y-3 text-xs">
+            {rpcLogsError && (
+              <div className="rounded-md border border-rose-500/40 bg-rose-500/10 px-3 py-2 text-[11px] text-rose-200">
+                {rpcLogsError}
               </div>
+            )}
+            <input
+              type="text"
+              value={logSearch}
+              onChange={(e) => setLogSearch(e.target.value)}
+              placeholder="Search by method, event, or component"
+              className="h-7 w-full rounded-md border bg-muted px-2 text-[10px] outline-none focus:ring-1 focus:ring-ring"
+            />
+            <div className="flex flex-wrap gap-2">
+              {LOG_FILTERS.map((filter) => (
+                <Button
+                  key={filter.id}
+                  variant={logFilter === filter.id ? "default" : "outline"}
+                  size="sm"
+                  className="h-7 px-2 text-[10px]"
+                  onClick={() => setLogFilter(filter.id)}
+                >
+                  {filter.label}
+                </Button>
+              ))}
             </div>
-            {/* env vars */}
-            <div className="space-y-2">
-              <div className="flex items-center justify-between">
-                <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">Environment Variables</label>
-                <Button variant="ghost" size="icon-xs" onClick={addEnvEntry}><Plus className="size-3.5" /></Button>
+            <div className="flex flex-wrap gap-2">
+              {["all", "error", "warn", "info", "debug", "trace"].map((level) => (
+                <Button
+                  key={level}
+                  variant={logLevelFilter === level ? "default" : "outline"}
+                  size="sm"
+                  className="h-7 px-2 text-[10px] uppercase"
+                  onClick={() => setLogLevelFilter(level)}
+                >
+                  {level}
+                </Button>
+              ))}
+            </div>
+            {filteredRpcLogs.length === 0 && !rpcLogsLoading ? (
+              <div className="rounded-md border border-dashed px-3 py-4 text-center text-[11px] text-muted-foreground">
+                No results for {LOG_FILTERS.find((filter) => filter.id === logFilter)?.label ?? "selected"}.
               </div>
-              <p className="text-[11px] text-muted-foreground">Variables available to agent workers in this workspace.</p>
-              {wsEnvVars.length === 0 && (
-                <div className="rounded-md border border-dashed px-3 py-3 text-center text-[11px] text-muted-foreground">
-                  No environment variables. Click + to add.
-                </div>
-              )}
-              <div className="space-y-2">
-                {wsEnvVars.map((entry, i) => (
-                  <div key={i} className="flex items-center gap-1.5">
-                    <input type="text" value={entry.key} onChange={(e) => updateEnvEntry(i, "key", e.target.value)} placeholder="KEY"
-                      className="w-[120px] shrink-0 rounded-md border bg-background px-2 py-1.5 text-xs outline-none transition focus:border-primary/50 focus:ring-1 focus:ring-primary/30" />
-                    <span className="text-[11px] text-muted-foreground">=</span>
-                    <input type="text" value={entry.value} onChange={(e) => updateEnvEntry(i, "value", e.target.value)} placeholder="value"
-                      className="flex-1 rounded-md border bg-background px-2 py-1.5 text-xs outline-none transition focus:border-primary/50 focus:ring-1 focus:ring-primary/30" />
-                    <Button variant="ghost" size="icon-xs" onClick={() => removeEnvEntry(i)}>
-                      <Trash2 className="size-3 text-muted-foreground hover:text-destructive" />
-                    </Button>
+            ) : (
+              filteredRpcLogs.map((entry) => (
+                <div
+                  key={`${entry.timestamp_ms}-${entry.correlation_id}-${entry.method ?? entry.event}`}
+                  className="rounded-md border bg-muted/30 px-3 py-2 space-y-1"
+                >
+                  <div className="flex items-center justify-between">
+                    <span className="font-mono text-[11px] text-foreground">
+                      {extractLogMethod(entry) ?? entry.event}
+                    </span>
+                    <span
+                      className={cn(
+                        "text-[10px] font-medium",
+                        entry.status && entry.status.toLowerCase() === "ok"
+                          ? "text-emerald-500"
+                          : entry.level === "error"
+                            ? "text-rose-500"
+                            : "text-muted-foreground",
+                      )}
+                    >
+                      {(entry.status ?? entry.level ?? "info").toString().toUpperCase()}
+                    </span>
                   </div>
-                ))}
-              </div>
-            </div>
-          </div>
-          <div className="border-t px-5 py-4 space-y-2">
-            {wsError && <div className="rounded-md bg-destructive/10 px-3 py-2 text-xs text-destructive">{wsError}</div>}
-            <div className="flex gap-2">
-              <Button variant="outline" size="sm" onClick={closeDrawer} className="flex-1 h-9" disabled={wsCreating}>Cancel</Button>
-              <Button variant="default" size="sm" onClick={createWorkspace} className="flex-1 h-9" disabled={wsCreating || !wsName.trim()}>
-                {wsCreating ? "Creating..." : "Create Workspace"}
-              </Button>
-            </div>
+                  <div className="flex items-center justify-between text-[10px] text-muted-foreground">
+                    <span>{new Date(entry.timestamp_ms).toLocaleTimeString()}</span>
+                    <span>{entry.duration_ms ?? "—"} ms</span>
+                  </div>
+                  <div className="text-[10px] text-muted-foreground">
+                    {entry.component} · {entry.event}
+                  </div>
+                </div>
+              ))
+            )}
           </div>
         </div>
       </>
     );
   }
 
-  function renderEditDrawer() {
-    const ws = workspaces.find((w) => w.workspace_id === editWorkspaceId);
+  function renderDrawer() {
     return (
       <>
         <div
           className={cn(
             "fixed inset-0 z-40 bg-black/40 transition-opacity duration-200",
-            editDrawerOpen ? "opacity-100" : "pointer-events-none opacity-0",
+            drawerOpen ? "opacity-100" : "pointer-events-none opacity-0",
           )}
-          onClick={closeEditDrawer}
+          onClick={closeDrawer}
         />
         <div
           className={cn(
             "fixed right-0 top-0 z-50 flex h-full w-[380px] flex-col border-l bg-card shadow-xl transition-transform duration-200 ease-out",
-            editDrawerOpen ? "translate-x-0" : "translate-x-full",
+            drawerOpen ? "translate-x-0" : "translate-x-full",
           )}
         >
           <div className="flex items-center justify-between border-b px-5 py-4">
-            <div className="space-y-0.5">
-              <h2 className="text-sm font-semibold">Workspace Settings</h2>
-              <div className="text-[11px] text-muted-foreground truncate">
-                {ws?.name || "Workspace"}
-              </div>
-            </div>
-            <Button variant="ghost" size="icon-sm" onClick={closeEditDrawer}>
+            <h2 className="text-sm font-semibold">New Workspace</h2>
+            <Button variant="ghost" size="icon-sm" onClick={closeDrawer}>
               <X className="size-4" />
             </Button>
           </div>
-          <div className="flex-1 overflow-auto px-5 py-4 space-y-5 text-xs">
+          <div className="flex-1 overflow-auto px-5 py-4 space-y-5">
             <div className="space-y-1.5">
               <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
-                Working Directory
+                Workspace ID
               </label>
               <div className="rounded-md border bg-muted px-3 py-2 text-xs text-muted-foreground">
-                {ws?.folder || "No folder set"}
+                Auto-generated on creation
+              </div>
+            </div>
+            <div className="space-y-1.5">
+              <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
+                Name <span className="text-destructive">*</span>
+              </label>
+              <input
+                type="text"
+                value={wsName}
+                onChange={(e) => setWsName(e.target.value)}
+                placeholder="e.g. my-project"
+                className="w-full rounded-md border bg-background px-3 py-2 text-xs outline-none transition focus:border-primary/50 focus:ring-1 focus:ring-primary/30"
+                autoFocus
+              />
+            </div>
+            <div className="space-y-1.5">
+              <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
+                Working Directory
+              </label>
+              <div className="flex gap-2">
+                <div className="flex-1 truncate rounded-md border bg-background px-3 py-2 text-xs text-muted-foreground">
+                  {wsFolder || "No folder selected"}
+                </div>
+                <Button
+                  variant="outline"
+                  size="sm"
+                  onClick={pickFolder}
+                  className="h-[34px] px-2.5 shrink-0"
+                >
+                  <FolderOpen className="size-3.5" />
+                  <span>Browse</span>
+                </Button>
               </div>
             </div>
             <div className="space-y-2">
@@ -1959,22 +2410,25 @@ function App() {
                 <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
                   Environment Variables
                 </label>
-                <Button variant="ghost" size="icon-xs" onClick={addEditEnvEntry}>
+                <Button variant="ghost" size="icon-xs" onClick={addEnvEntry}>
                   <Plus className="size-3.5" />
                 </Button>
               </div>
-              {editEnvVars.length === 0 && (
+              <p className="text-[11px] text-muted-foreground">
+                Variables available to agent workers in this workspace.
+              </p>
+              {wsEnvVars.length === 0 && (
                 <div className="rounded-md border border-dashed px-3 py-3 text-center text-[11px] text-muted-foreground">
                   No environment variables. Click + to add.
                 </div>
               )}
               <div className="space-y-2">
-                {editEnvVars.map((entry, i) => (
+                {wsEnvVars.map((entry, i) => (
                   <div key={i} className="flex items-center gap-1.5">
                     <input
                       type="text"
                       value={entry.key}
-                      onChange={(e) => updateEditEnvEntry(i, "key", e.target.value)}
+                      onChange={(e) => updateEnvEntry(i, "key", e.target.value)}
                       placeholder="KEY"
                       className="w-[120px] shrink-0 rounded-md border bg-background px-2 py-1.5 text-xs outline-none transition focus:border-primary/50 focus:ring-1 focus:ring-primary/30"
                     />
@@ -1982,53 +2436,42 @@ function App() {
                     <input
                       type="text"
                       value={entry.value}
-                      onChange={(e) => updateEditEnvEntry(i, "value", e.target.value)}
+                      onChange={(e) => updateEnvEntry(i, "value", e.target.value)}
                       placeholder="value"
                       className="flex-1 rounded-md border bg-background px-2 py-1.5 text-xs outline-none transition focus:border-primary/50 focus:ring-1 focus:ring-primary/30"
                     />
-                    <Button variant="ghost" size="icon-xs" onClick={() => removeEditEnvEntry(i)}>
+                    <Button variant="ghost" size="icon-xs" onClick={() => removeEnvEntry(i)}>
                       <Trash2 className="size-3 text-muted-foreground hover:text-destructive" />
                     </Button>
                   </div>
                 ))}
               </div>
             </div>
-            <div className="space-y-2">
-              <div className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
-                MAXC Environment (read-only)
-              </div>
-              <div className="rounded-md border bg-muted px-3 py-2 text-[11px] text-muted-foreground whitespace-pre-wrap break-words">
-                {Object.entries(ws?.env_vars ?? {})
-                  .filter(([key]) => key.startsWith("MAXC_"))
-                  .map(([key, value]) => `${key}=${value}`)
-                  .join("\n") || "Not available yet."}
-              </div>
-            </div>
           </div>
           <div className="border-t px-5 py-4 space-y-2">
-            {editError && (
+            {wsError && (
               <div className="rounded-md bg-destructive/10 px-3 py-2 text-xs text-destructive">
-                {editError}
+                {wsError}
               </div>
             )}
             <div className="flex gap-2">
               <Button
                 variant="outline"
                 size="sm"
-                onClick={closeEditDrawer}
+                onClick={closeDrawer}
                 className="flex-1 h-9"
-                disabled={editSaving}
+                disabled={wsCreating}
               >
                 Cancel
               </Button>
               <Button
                 variant="default"
                 size="sm"
-                onClick={saveWorkspaceEnv}
+                onClick={createWorkspace}
                 className="flex-1 h-9"
-                disabled={editSaving}
+                disabled={wsCreating || !wsName.trim()}
               >
-                {editSaving ? "Saving..." : "Save"}
+                {wsCreating ? "Creating..." : "Create Workspace"}
               </Button>
             </div>
           </div>
@@ -2037,288 +2480,6 @@ function App() {
     );
   }
 
-  // ---------------------------------------------------------------------------
-  // Keyboard shortcuts overlay
-  // ---------------------------------------------------------------------------
-  function renderShortcutsPanel() {
-    if (!showShortcuts) return null;
-    const shortcuts = [
-      { keys: "Ctrl+Shift+N", desc: "New window" },
-      { keys: "Ctrl+N", desc: "New workspace" },
-      { keys: "Ctrl+T", desc: "New terminal" },
-      { keys: "Ctrl+B", desc: "New browser" },
-      { keys: "Ctrl+D", desc: "Split pane right" },
-      { keys: "Ctrl+Shift+D", desc: "Split pane down" },
-      { keys: "Alt+1-9", desc: "Switch workspace" },
-      { keys: "Ctrl+/", desc: "Toggle shortcuts" },
-      { keys: "Escape", desc: "Close panel / drawer" },
-    ];
-    return (
-      <>
-        <div className="fixed inset-0 z-40 bg-black/30" onClick={() => setShowShortcuts(false)} />
-        <div className="fixed left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2 w-[320px] rounded-xl border bg-card p-5 shadow-2xl">
-          <div className="flex items-center justify-between mb-4">
-            <h3 className="text-sm font-semibold flex items-center gap-2"><Keyboard className="size-4" /> Keyboard Shortcuts</h3>
-            <Button variant="ghost" size="icon-xs" onClick={() => setShowShortcuts(false)}><X className="size-3.5" /></Button>
-          </div>
-          <div className="space-y-2">
-            {shortcuts.map((s) => (
-              <div key={s.keys} className="flex items-center justify-between text-xs">
-                <span className="text-muted-foreground">{s.desc}</span>
-                <kbd className="rounded bg-muted px-2 py-0.5 text-[11px] font-mono">{s.keys}</kbd>
-              </div>
-            ))}
-          </div>
-        </div>
-      </>
-    );
-  }
-
-  function renderNotificationToasts() {
-    if (toastItems.length === 0) return null;
-    return (
-      <div className="fixed right-4 top-12 z-50 flex w-[280px] flex-col gap-2">
-        {toastItems.map((n) => (
-          <div
-            key={n.notification_id}
-            className={cn(
-              "rounded-lg border px-3 py-2 text-xs shadow-lg backdrop-blur",
-              n.level === "success"
-                ? "border-emerald-500/20 bg-emerald-500/10 text-emerald-100"
-                : n.level === "warning"
-                  ? "border-amber-500/20 bg-amber-500/10 text-amber-100"
-                  : n.level === "error"
-                    ? "border-rose-500/20 bg-rose-500/10 text-rose-100"
-                    : "border-blue-500/20 bg-blue-500/10 text-blue-100",
-            )}
-          >
-            <div className="font-semibold">{n.title}</div>
-            {n.body && <div className="mt-1 text-[11px] text-white/70">{n.body}</div>}
-          </div>
-        ))}
-      </div>
-    );
-  }
-
-  function renderSettingsPanel() {
-    const envLines = [
-      `MAXC_SOCKET_PATH=${socketPath}`,
-      token ? `MAXC_TOKEN=${token}` : "MAXC_TOKEN=",
-      selectedWorkspaceId ? `MAXC_WORKSPACE_ID=${selectedWorkspaceId}` : "MAXC_WORKSPACE_ID=",
-      focusedPaneId ? `MAXC_PANE_ID=${focusedPaneId}` : "MAXC_PANE_ID=",
-      focusedSurface?.surfaceId
-        ? `MAXC_SURFACE_ID=${focusedSurface.surfaceId}`
-        : "MAXC_SURFACE_ID=",
-    ];
-    const envBlock = envLines.join("\n");
-    const isUpdateDownloading = updateStatus === "downloading";
-
-    async function copyEnvBlock() {
-      try {
-        await navigator.clipboard.writeText(envBlock);
-        setEnvCopied(true);
-        window.setTimeout(() => setEnvCopied(false), 2000);
-      } catch {
-        setBackendStatus("Failed to copy env");
-      }
-    }
-
-    async function checkForUpdates() {
-      setUpdateStatus("checking");
-      setUpdateError("");
-      setUpdateInfo(null);
-      try {
-        const result = await invoke<UpdateInfo>("update_check", { channel: updateChannel });
-        if (!result.available) {
-          setUpdateStatus("uptodate");
-          return;
-        }
-        setUpdateInfo(result);
-        setUpdateStatus("available");
-      } catch (err) {
-        const message = err instanceof Error ? err.message : String(err);
-        if (/404|not found|no release/i.test(message)) {
-          setUpdateStatus("uptodate");
-          setUpdateError("");
-          return;
-        }
-        setUpdateStatus("error");
-        setUpdateError(message || "Update check failed");
-      }
-    }
-
-    async function downloadAndInstallUpdate() {
-      setUpdateStatus("downloading");
-      setUpdateError("");
-      setUpdateProgress({ downloaded: 0, total: undefined });
-      try {
-        await invoke("update_download_and_install", { channel: updateChannel });
-        setUpdateStatus("ready");
-      } catch (err) {
-        setUpdateStatus("error");
-        setUpdateError((err as Error).message || "Update download failed");
-      }
-    }
-
-    return (
-      <>
-        <div
-          className={cn(
-            "fixed inset-0 z-40 bg-black/40 transition-opacity duration-200",
-            settingsOpen ? "opacity-100" : "pointer-events-none opacity-0",
-          )}
-          onClick={() => setSettingsOpen(false)}
-        />
-        <div
-          className={cn(
-            "fixed right-0 top-0 z-50 flex h-full w-[380px] flex-col border-l bg-card shadow-xl transition-transform duration-200 ease-out",
-            settingsOpen ? "translate-x-0" : "translate-x-full",
-          )}
-        >
-          <div className="flex items-center justify-between border-b px-5 py-4">
-            <h2 className="text-sm font-semibold">Settings</h2>
-            <Button variant="ghost" size="icon-sm" onClick={() => setSettingsOpen(false)}>
-              <X className="size-4" />
-            </Button>
-          </div>
-          <div className="flex-1 overflow-auto overflow-x-hidden px-5 py-4 space-y-5 text-xs">
-            <div className="space-y-2">
-              <div className="flex items-center justify-between">
-                <span className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
-                  Updates
-                </span>
-                <div className="text-[10px] text-muted-foreground">
-                  {appVersion ? `v${appVersion}` : "v—"}
-                </div>
-              </div>
-              <div className="flex items-center gap-2">
-                <label className="text-[10px] text-muted-foreground">Channel</label>
-                <div className="relative">
-                  <select
-                    className="h-7 appearance-none rounded-md border border-border/70 bg-background px-2 pr-6 text-[11px] text-foreground shadow-sm outline-none transition focus:border-primary/60 focus:ring-1 focus:ring-primary/30"
-                    value={updateChannel}
-                    onChange={(e) => setUpdateChannel(e.target.value as "stable" | "beta")}
-                  >
-                    <option value="stable">Stable</option>
-                    <option value="beta">Beta</option>
-                  </select>
-                  <ChevronDown className="pointer-events-none absolute right-1.5 top-1/2 size-3 -translate-y-1/2 text-muted-foreground" />
-                </div>
-                <Button
-                  variant="outline"
-                  size="sm"
-                  className="h-7 px-2"
-                  onClick={checkForUpdates}
-                  disabled={updateStatus === "checking" || isUpdateDownloading}
-                >
-                  {updateStatus === "checking" ? "Checking..." : "Check"}
-                </Button>
-              </div>
-              {updateStatus === "available" && updateInfo && (
-                <div className="rounded-md border bg-muted px-3 py-2">
-                  <div className="text-[11px] text-foreground">
-                    Update available: v{updateInfo.version ?? "new"}
-                  </div>
-                  {updateInfo.date_ms ? (
-                    <div className="text-[10px] text-muted-foreground">
-                      {new Date(updateInfo.date_ms).toLocaleString()}
-                    </div>
-                  ) : null}
-                  {updateInfo.body && (
-                    <div className="mt-2 text-[10px] text-muted-foreground whitespace-pre-wrap">
-                      {updateInfo.body}
-                    </div>
-                  )}
-                  <div className="mt-2">
-                    <Button
-                      variant="default"
-                      size="sm"
-                      className="h-7 px-2"
-                      onClick={downloadAndInstallUpdate}
-                      disabled={isUpdateDownloading}
-                    >
-                      {isUpdateDownloading ? "Downloading..." : "Download & Install"}
-                    </Button>
-                  </div>
-                </div>
-              )}
-              {updateStatus === "downloading" && (
-                <div className="text-[10px] text-muted-foreground">
-                  Downloading update…{" "}
-                  {updateProgress.total
-                    ? `${Math.round((updateProgress.downloaded / updateProgress.total) * 100)}%`
-                    : ""}
-                </div>
-              )}
-              {updateStatus === "ready" && (
-                <div className="text-[10px] text-muted-foreground">
-                  Update installed. Restarting…
-                </div>
-              )}
-              {updateStatus === "uptodate" && (
-                <div className="text-[10px] text-muted-foreground">You are up to date.</div>
-              )}
-              {updateStatus === "error" && (
-                <div className="text-[10px] text-destructive">
-                  {updateError || "Updater not configured."}
-                </div>
-              )}
-            </div>
-
-            <div className="flex items-center gap-3 text-[10px] text-muted-foreground/80">
-              <div className="h-px flex-1 bg-border/70" />
-              <span className="uppercase tracking-[0.2em]">Agent</span>
-              <div className="h-px flex-1 bg-border/70" />
-            </div>
-
-            <div className="space-y-2">
-              <div className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
-                Agent Connection
-              </div>
-              <p className="text-muted-foreground">
-                Use these environment variables to let an external agent access all maxc
-                commands. Agents launched inside a maxc terminal inherit these values
-                automatically.
-              </p>
-            </div>
-
-            <div className="space-y-2">
-              <div className="flex items-center justify-between">
-                <span className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
-                  MAXC Environment
-                </span>
-                <Button variant="outline" size="sm" className="h-7 px-2" onClick={copyEnvBlock}>
-                  {envCopied ? (
-                    <span className="inline-flex items-center gap-1">
-                      <Check className="size-3.5" />
-                      Copied
-                    </span>
-                  ) : (
-                    "Copy"
-                  )}
-                </Button>
-              </div>
-              <pre className="whitespace-pre-wrap break-words rounded-md border bg-muted px-3 py-2 text-[11px] text-muted-foreground">
-                {envBlock}
-              </pre>
-            </div>
-
-            <div className="space-y-2">
-              <div className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
-                Example CLI Usage
-              </div>
-              <pre className="whitespace-pre-wrap break-words rounded-md border bg-muted px-3 py-2 text-[11px] text-muted-foreground">
-{`maxc terminal spawn --workspace-id ${selectedWorkspaceId || "ws-1"} --surface-id ${focusedSurface?.surfaceId || "sf-1"}
-maxc terminal input --workspace-id ${selectedWorkspaceId || "ws-1"} --surface-id ${focusedSurface?.surfaceId || "sf-1"} --terminal-session-id ts-1 --input "npm test\\n"
-maxc notify --title "Task complete" --body "All tests passed" --level success`}
-              </pre>
-            </div>
-          </div>
-        </div>
-      </>
-    );
-  }
-
   // ---------------------------------------------------------------------------
   // Layout
   // ---------------------------------------------------------------------------
@@ -2331,11 +2492,33 @@ maxc notify --title "Task complete" --body "All tests passed" --level success`}
           <div className="flex-1 min-h-0">{renderContent()}</div>
         </main>
       </div>
+      <SettingsDialog
+        open={settingsOpen && !drawerOpen}
+        onOpenChange={(open) => {
+          if (drawerOpen) return;
+          setSettingsOpen(open);
+          if (!open) setSettingsEditWorkspace(null);
+        }}
+        defaultTab={settingsDefaultTab}
+        token={token}
+        editWorkspace={settingsEditWorkspace}
+        appVersion={appVersion}
+        socketPath={socketPath}
+        selectedWorkspaceId={selectedWorkspaceId}
+        focusedPaneId={focusedPaneId}
+        focusedSurfaceId={focusedSurface?.surfaceId ?? ""}
+        shortcuts={shortcutList}
+        onShortcutChange={handleShortcutChange}
+        onResetShortcuts={resetShortcuts}
+        rpcRateLimit={rpcRateLimit}
+        onRpcRateLimitChange={handleRpcRateLimitChange}
+        onSaveWorkspaceEnv={handleDialogSaveWorkspaceEnv}
+        onStatusMessage={setBackendStatus}
+      />
+      {renderRpcLogsDrawer()}
       {renderDrawer()}
-      {renderEditDrawer()}
       {renderShortcutsPanel()}
       {renderNotificationToasts()}
-      {renderSettingsPanel()}
       <NotificationPanel
         open={notificationPanelOpen}
         notifications={notificationItems}
diff --git a/maxc_desktop/src/assets/maxc_logo_full_dark_single.svg b/maxc_desktop/src/assets/maxc_logo_full_dark_single.svg
index 4a0823c..59e134e 100644
--- a/maxc_desktop/src/assets/maxc_logo_full_dark_single.svg
+++ b/maxc_desktop/src/assets/maxc_logo_full_dark_single.svg
@@ -1,5 +1,12 @@
 <svg width="1080" height="1080" viewBox="0 0 1080 1080" fill="none" xmlns="http://www.w3.org/2000/svg">
-<rect x="0.5" y="0.5" width="1079" height="1079" rx="99.5" fill="white"/>
+<g clip-path="url(#clip0_38_92)">
+<rect width="1080" height="1080" rx="100" fill="white"/>
+<path d="M727 713V838H352V713H227V338H352V213H727V338H852V713H727ZM352 463H602V338H352V463ZM727 463H602V588H352V713H727V463Z" fill="#1E1E1E"/>
+</g>
 <rect x="0.5" y="0.5" width="1079" height="1079" rx="99.5" stroke="white"/>
-<path d="M637 641V703.5H449.5V641H387V453.5H449.5V391H637V453.5H699.5V641H637ZM449.5 516H574.5V453.5H449.5V516ZM637 516H574.5V578.5H449.5V641H637V516Z" fill="#1E1E1E"/>
+<defs>
+<clipPath id="clip0_38_92">
+<rect width="1080" height="1080" rx="100" fill="white"/>
+</clipPath>
+</defs>
 </svg>
diff --git a/maxc_desktop/src/assets/maxc_logo_full_white_single.svg b/maxc_desktop/src/assets/maxc_logo_full_white_single.svg
new file mode 100644
index 0000000..6c1d139
--- /dev/null
+++ b/maxc_desktop/src/assets/maxc_logo_full_white_single.svg
@@ -0,0 +1,11 @@
+<svg width="1080" height="1080" viewBox="0 0 1080 1080" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_38_87)">
+<rect width="1080" height="1080" rx="100" fill="#1E1E1E"/>
+<path d="M727 713V838H352V713H227V338H352V213H727V338H852V713H727ZM352 463H602V338H352V463ZM727 463H602V588H352V713H727V463Z" fill="white"/>
+</g>
+<defs>
+<clipPath id="clip0_38_87">
+<rect width="1080" height="1080" rx="100" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/maxc_desktop/src/components/PaneContainer.tsx b/maxc_desktop/src/components/PaneContainer.tsx
index a7d33c6..7ddfc3e 100644
--- a/maxc_desktop/src/components/PaneContainer.tsx
+++ b/maxc_desktop/src/components/PaneContainer.tsx
@@ -9,6 +9,14 @@ import {
   Terminal as TerminalIcon,
 } from "lucide-react";
 import { Shimmer } from "@/components/ai-elements/shimmer";
+import {
+  ContextMenu,
+  ContextMenuContent,
+  ContextMenuItem,
+  ContextMenuLabel,
+  ContextMenuSeparator,
+  ContextMenuTrigger,
+} from "@/components/ui/context-menu";
 import { SurfaceTabBar, type SurfaceState } from "./SurfaceTabBar";
 import { XtermTerminal, type XtermHandle } from "./XtermTerminal";
 import { BrowserView } from "./BrowserView";
@@ -66,6 +74,7 @@ export type PaneContainerProps = {
   onBrowserScreenshot: (surfaceId: string) => void;
   browserStates: Map<string, BrowserState>;
   workspaceFolder?: string;
+  canCreateSurface?: boolean;
 };
 
 // ---------------------------------------------------------------------------
@@ -131,145 +140,172 @@ export function PaneContainer(props: PaneContainerProps) {
   );
 
   return (
-    <div
-      className={cn(
-        "flex h-full w-full flex-col min-h-0 min-w-0",
-        isFocused && "ring-1 ring-primary/30 ring-inset",
-      )}
-      onClick={() => props.onFocusPane(node.paneId)}
-    >
-      <SurfaceTabBar
-        surfaces={node.surfaces}
-        activeSurfaceId={node.activeSurfaceId}
-        paneId={node.paneId}
-        onFocusSurface={props.onFocusSurface}
-        onCloseSurface={props.onCloseSurface}
-        onCreateSurface={props.onCreateSurface}
-        onSplitPane={props.onSplitPane}
-        onClosePane={props.onClosePane}
-        canClosePane={props.paneCount > 1}
-      />
-      <div className="flex-1 min-h-0 bg-background">
-        {activeSurface?.panelType === "terminal" &&
-        activeSurface.terminalSessionId ? (
-          <XtermTerminal
-            key={activeSurface.surfaceId}
-            ref={(handle) =>
-              props.registerXtermHandle(activeSurface.surfaceId, handle)
-            }
-            focused={isFocused}
-            onData={(data) =>
-              props.onTerminalData(activeSurface.surfaceId, data)
-            }
-            onResize={(cols, rows) =>
-              props.onTerminalResize(activeSurface.surfaceId, cols, rows)
-            }
+    <ContextMenu modal={false}>
+      <ContextMenuTrigger asChild>
+        <div
+          className={cn(
+            "flex h-full w-full flex-col min-h-0 min-w-0",
+            isFocused && "ring-1 ring-primary/30 ring-inset",
+          )}
+          onClick={() => props.onFocusPane(node.paneId)}
+          onContextMenu={() => props.onFocusPane(node.paneId)}
+        >
+          <SurfaceTabBar
+            surfaces={node.surfaces}
+            activeSurfaceId={node.activeSurfaceId}
+            paneId={node.paneId}
+            onFocusSurface={props.onFocusSurface}
+            onCloseSurface={props.onCloseSurface}
+            onCreateSurface={props.onCreateSurface}
+            onSplitPane={props.onSplitPane}
+            onClosePane={props.onClosePane}
+            canClosePane={props.paneCount > 1}
           />
-        ) : activeSurface?.panelType === "browser" &&
-          activeSurface.browserSessionId ? (
-          (() => {
-            const bs = props.browserStates.get(activeSurface.surfaceId);
-            return (
-              <BrowserView
-                surfaceId={activeSurface.surfaceId}
-                browserSessionId={activeSurface.browserSessionId}
-                workspaceId={activeSurface.workspaceId}
-                tabId={bs?.tabId ?? null}
+          <div className="flex-1 min-h-0 bg-background">
+            {activeSurface?.panelType === "terminal" &&
+            activeSurface.terminalSessionId ? (
+              <XtermTerminal
+                key={activeSurface.surfaceId}
+                ref={(handle) =>
+                  props.registerXtermHandle(activeSurface.surfaceId, handle)
+                }
                 focused={isFocused}
-                onNavigate={props.onBrowserNavigate}
-                onReload={props.onBrowserReload}
-                onBack={props.onBrowserBack}
-                onForward={props.onBrowserForward}
-                onScreenshot={props.onBrowserScreenshot}
-                currentUrl={bs?.currentUrl ?? ""}
-                screenshotData={bs?.screenshotData ?? null}
-                screenshotLoading={bs?.screenshotLoading ?? false}
-                sessionLoading={bs?.sessionLoading ?? false}
+                onData={(data) =>
+                  props.onTerminalData(activeSurface.surfaceId, data)
+                }
+                onResize={(cols, rows) =>
+                  props.onTerminalResize(activeSurface.surfaceId, cols, rows)
+                }
               />
-            );
-          })()
-        ) : activeSurface?.panelType === "browser" ? (
-          (() => {
-            const bs = props.browserStates.get(activeSurface.surfaceId);
-            return (
+            ) : activeSurface?.panelType === "browser" &&
+              activeSurface.browserSessionId ? (
+              (() => {
+                const bs = props.browserStates.get(activeSurface.surfaceId);
+                return (
+                  <BrowserView
+                    surfaceId={activeSurface.surfaceId}
+                    browserSessionId={activeSurface.browserSessionId}
+                    workspaceId={activeSurface.workspaceId}
+                    tabId={bs?.tabId ?? null}
+                    focused={isFocused}
+                    onNavigate={props.onBrowserNavigate}
+                    onReload={props.onBrowserReload}
+                    onBack={props.onBrowserBack}
+                    onForward={props.onBrowserForward}
+                    onScreenshot={props.onBrowserScreenshot}
+                    currentUrl={bs?.currentUrl ?? ""}
+                    screenshotData={bs?.screenshotData ?? null}
+                    screenshotLoading={bs?.screenshotLoading ?? false}
+                    sessionLoading={bs?.sessionLoading ?? false}
+                  />
+                );
+              })()
+            ) : activeSurface?.panelType === "browser" ? (
+              (() => {
+                const bs = props.browserStates.get(activeSurface.surfaceId);
+                return (
+                  <div className="flex h-full items-center justify-center">
+                    <div className="flex flex-col items-center gap-3 rounded-lg border border-dashed border-border/60 bg-card/60 px-6 py-5 text-center">
+                      <div className="flex size-9 items-center justify-center rounded-md bg-muted text-muted-foreground">
+                        <Globe2 className="size-4" />
+                      </div>
+                      <div className="space-y-1">
+                        <div className="text-[12px] font-medium text-foreground">Browser session</div>
+                        <div className="text-[10px] text-muted-foreground">
+                          {bs?.sessionLoading ? "Launching renderer…" : "Attach a live browser to this surface."}
+                        </div>
+                      </div>
+                      {bs?.sessionLoading ? (
+                        <div className="w-full max-w-[200px] text-left">
+                          <Shimmer className="text-[11px] text-muted-foreground">
+                            Warming GPU context… routing automation…
+                          </Shimmer>
+                        </div>
+                      ) : (
+                        <button
+                          className="rounded-md border border-border/70 bg-muted/40 px-2.5 py-1 text-[11px] text-foreground/80 hover:bg-muted/70"
+                          onClick={() => props.onAttachBrowser(activeSurface.surfaceId)}
+                        >
+                          Start browser
+                        </button>
+                      )}
+                    </div>
+                  </div>
+                );
+              })()
+            ) : activeSurface?.panelType === "terminal" ? (
               <div className="flex h-full items-center justify-center">
                 <div className="flex flex-col items-center gap-3 rounded-lg border border-dashed border-border/60 bg-card/60 px-6 py-5 text-center">
                   <div className="flex size-9 items-center justify-center rounded-md bg-muted text-muted-foreground">
-                    <Globe2 className="size-4" />
+                    <TerminalIcon className="size-4" />
                   </div>
                   <div className="space-y-1">
-                    <div className="text-[12px] font-medium text-foreground">Browser session</div>
-                    <div className="text-[10px] text-muted-foreground">
-                      {bs?.sessionLoading ? "Launching renderer…" : "Attach a live browser to this surface."}
-                    </div>
+                    <div className="text-[12px] font-medium text-foreground">Terminal session</div>
+                    <div className="text-[10px] text-muted-foreground">Spawn a terminal in this workspace.</div>
                   </div>
-                  {bs?.sessionLoading ? (
-                    <div className="w-full max-w-[200px] text-left">
-                      <Shimmer className="text-[11px] text-muted-foreground">
-                        Warming GPU context… routing automation…
-                      </Shimmer>
-                    </div>
-                  ) : (
-                    <button
-                      className="rounded-md border border-border/70 bg-muted/40 px-2.5 py-1 text-[11px] text-foreground/80 hover:bg-muted/70"
-                      onClick={() => props.onAttachBrowser(activeSurface.surfaceId)}
-                    >
-                      Start browser
-                    </button>
-                  )}
+                  <button
+                    className="rounded-md border border-border/70 bg-muted/40 px-2.5 py-1 text-[11px] text-foreground/80 hover:bg-muted/70"
+                    onClick={() => props.onAttachTerminal(activeSurface.surfaceId)}
+                  >
+                    Start terminal
+                  </button>
                 </div>
               </div>
-            );
-          })()
-        ) : activeSurface?.panelType === "terminal" ? (
-          <div className="flex h-full items-center justify-center">
-            <div className="flex flex-col items-center gap-3 rounded-lg border border-dashed border-border/60 bg-card/60 px-6 py-5 text-center">
-              <div className="flex size-9 items-center justify-center rounded-md bg-muted text-muted-foreground">
-                <TerminalIcon className="size-4" />
-              </div>
-              <div className="space-y-1">
-                <div className="text-[12px] font-medium text-foreground">Terminal session</div>
-                <div className="text-[10px] text-muted-foreground">Spawn a terminal in this workspace.</div>
-              </div>
-              <button
-                className="rounded-md border border-border/70 bg-muted/40 px-2.5 py-1 text-[11px] text-foreground/80 hover:bg-muted/70"
-                onClick={() => props.onAttachTerminal(activeSurface.surfaceId)}
-              >
-                Start terminal
-              </button>
-            </div>
-          </div>
-        ) : activeSurface?.panelType === "agent" ? (
-          <AgentPanel
-            token={props.token}
-            workspaceId={activeSurface.workspaceId}
-            surfaceId={activeSurface.surfaceId}
-            workspaceFolder={props.workspaceFolder}
-          />
-        ) : activeSurface ? (
-          <div className="flex h-full items-center justify-center text-xs text-[#767676]">
-            {activeSurface.panelType === "browser"
-              ? "Browser session not ready"
-              : "Empty surface"}
-          </div>
-        ) : (
-          <div className="flex h-full items-center justify-center">
-            <div className="flex flex-col items-center gap-3 rounded-lg border border-dashed border-border/60 bg-card/60 px-6 py-5 text-center">
-              <div className="flex size-9 items-center justify-center rounded-md bg-muted text-muted-foreground">
-                <Bot className="size-4" />
-              </div>
-              <div className="space-y-1">
-                <div className="text-[12px] font-medium text-foreground">No surfaces yet</div>
-                <div className="text-[10px] text-muted-foreground">Create a terminal, browser, or agent tab.</div>
+            ) : activeSurface?.panelType === "agent" ? (
+              <AgentPanel
+                token={props.token}
+                workspaceId={activeSurface.workspaceId}
+                surfaceId={activeSurface.surfaceId}
+                workspaceFolder={props.workspaceFolder}
+              />
+            ) : activeSurface ? (
+              <div className="flex h-full items-center justify-center text-xs text-[#767676]">
+                {activeSurface.panelType === "browser"
+                  ? "Browser session not ready"
+                  : "Empty surface"}
               </div>
-              <div className="flex items-center gap-2 text-[10px] text-muted-foreground">
-                <kbd className="rounded border border-border bg-muted/40 px-1.5 py-0.5">Ctrl+T</kbd>
-                <kbd className="rounded border border-border bg-muted/40 px-1.5 py-0.5">Ctrl+B</kbd>
+            ) : (
+              <div className="flex h-full items-center justify-center">
+                <div className="flex flex-col items-center gap-3 rounded-lg border border-dashed border-border/60 bg-card/60 px-6 py-5 text-center">
+                  <div className="flex size-9 items-center justify-center rounded-md bg-muted text-muted-foreground">
+                    <Bot className="size-4" />
+                  </div>
+                  <div className="space-y-1">
+                    <div className="text-[12px] font-medium text-foreground">No surfaces yet</div>
+                    <div className="text-[10px] text-muted-foreground">Create a terminal, browser, or agent tab.</div>
+                  </div>
+                  <div className="flex items-center gap-2 text-[10px] text-muted-foreground">
+                    <kbd className="rounded border border-border bg-muted/40 px-1.5 py-0.5">Ctrl+T</kbd>
+                    <kbd className="rounded border border-border bg-muted/40 px-1.5 py-0.5">Ctrl+B</kbd>
+                  </div>
+                </div>
               </div>
-            </div>
+            )}
           </div>
-        )}
-      </div>
-    </div>
+        </div>
+      </ContextMenuTrigger>
+      <ContextMenuContent>
+        <ContextMenuLabel>New Surface</ContextMenuLabel>
+        <ContextMenuSeparator />
+        <ContextMenuItem
+          disabled={!props.canCreateSurface}
+          onSelect={() => props.onCreateSurface(node.paneId, "terminal")}
+        >
+          Create Terminal
+        </ContextMenuItem>
+        <ContextMenuItem
+          disabled={!props.canCreateSurface}
+          onSelect={() => props.onCreateSurface(node.paneId, "browser")}
+        >
+          Create Browser
+        </ContextMenuItem>
+        <ContextMenuItem
+          disabled={!props.canCreateSurface}
+          onSelect={() => props.onCreateSurface(node.paneId, "agent")}
+        >
+          Create Agent
+        </ContextMenuItem>
+      </ContextMenuContent>
+    </ContextMenu>
   );
 }
diff --git a/maxc_desktop/src/components/SettingsDialog.tsx b/maxc_desktop/src/components/SettingsDialog.tsx
new file mode 100644
index 0000000..a7200da
--- /dev/null
+++ b/maxc_desktop/src/components/SettingsDialog.tsx
@@ -0,0 +1,758 @@
+import { useEffect, useState, type Dispatch, type SetStateAction } from "react";
+import { invoke } from "@tauri-apps/api/core";
+import {
+  Check,
+  ArrowUpDown,
+  Bot,
+  ChevronDown,
+  Download,
+  Info,
+  Keyboard,
+  Plus,
+  Trash2,
+} from "lucide-react";
+import logoWhite from "@/assets/maxc_logo_white.svg";
+import {
+  Dialog,
+  DialogContent,
+  DialogHeader,
+  DialogTitle,
+  DialogDescription,
+} from "@/components/ui/dialog";
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
+import { Button } from "@/components/ui/button";
+
+// ---------------------------------------------------------------------------
+// Types
+// ---------------------------------------------------------------------------
+
+type EnvEntry = { key: string; value: string };
+
+type Workspace = {
+  workspace_id: string;
+  name: string;
+  folder: string;
+  env_vars: Record<string, string>;
+  created_at_ms: number;
+};
+
+type UpdateInfo = {
+  available: boolean;
+  version?: string;
+  current_version?: string;
+  date_ms?: number | null;
+  body?: string | null;
+};
+
+type ShortcutItem = {
+  id: string;
+  label: string;
+  keys: string;
+  defaultKeys: string;
+};
+
+type RpcRateLimitValue = number | "unlimited";
+
+const RPC_ENDPOINT_GROUPS: { title: string; methods: string[] }[] = [
+  {
+    title: "Session",
+    methods: ["session.create", "session.refresh", "session.revoke"],
+  },
+  {
+    title: "System",
+    methods: ["system.health", "system.readiness", "system.diagnostics", "system.metrics", "system.logs"],
+  },
+  {
+    title: "Workspace",
+    methods: [
+      "workspace.create",
+      "workspace.list",
+      "workspace.update",
+      "workspace.delete",
+      "workspace.layout",
+    ],
+  },
+  {
+    title: "Pane",
+    methods: ["pane.create", "pane.split", "pane.list", "pane.close", "pane.resize"],
+  },
+  {
+    title: "Surface",
+    methods: ["surface.create", "surface.list", "surface.close", "surface.focus"],
+  },
+  {
+    title: "Terminal (PowerShell)",
+    methods: [
+      "terminal.spawn",
+      "terminal.input",
+      "terminal.resize",
+      "terminal.history",
+      "terminal.subscribe",
+      "terminal.kill",
+    ],
+  },
+  {
+    title: "Browser",
+    methods: [
+      "browser.create",
+      "browser.attach",
+      "browser.detach",
+      "browser.close",
+      "browser.tab.open",
+      "browser.tab.list",
+      "browser.tab.focus",
+      "browser.tab.close",
+      "browser.goto",
+      "browser.reload",
+      "browser.back",
+      "browser.forward",
+      "browser.click",
+      "browser.type",
+      "browser.key",
+      "browser.wait",
+      "browser.screenshot",
+      "browser.evaluate",
+      "browser.cookie.get",
+      "browser.cookie.set",
+      "browser.storage.get",
+      "browser.storage.set",
+      "browser.network.intercept",
+      "browser.upload",
+      "browser.download",
+      "browser.trace.start",
+      "browser.trace.stop",
+      "browser.raw.command",
+      "browser.history",
+      "browser.subscribe",
+    ],
+  },
+  {
+    title: "Agent",
+    methods: [
+      "agent.worker.create",
+      "agent.worker.list",
+      "agent.worker.get",
+      "agent.worker.close",
+      "agent.task.start",
+      "agent.task.list",
+      "agent.task.get",
+      "agent.task.cancel",
+      "agent.attach.terminal",
+      "agent.detach.terminal",
+      "agent.attach.browser",
+      "agent.detach.browser",
+    ],
+  },
+  {
+    title: "Notification",
+    methods: ["notification.send", "notification.list", "notification.clear"],
+  },
+];
+
+export type SettingsDialogProps = {
+  open: boolean;
+  onOpenChange: (open: boolean) => void;
+  /** Which tab to show on open */
+  defaultTab?: string;
+  /** Auth token */
+  token: string;
+  /** Current workspace being edited (null = settings mode) */
+  editWorkspace: Workspace | null;
+  /** App version string */
+  appVersion: string;
+  /** Named pipe path */
+  socketPath: string;
+  /** Current workspace/pane/surface IDs for env block */
+  selectedWorkspaceId: string;
+  focusedPaneId: string;
+  focusedSurfaceId: string;
+  /** Shortcuts */
+  shortcuts: ShortcutItem[];
+  onShortcutChange: (id: string, keys: string) => void;
+  onResetShortcuts: () => void;
+  /** Rate limit */
+  rpcRateLimit: RpcRateLimitValue;
+  onRpcRateLimitChange: (value: string) => void;
+  /** Callbacks */
+  onSaveWorkspaceEnv: (workspaceId: string, envVars: Record<string, string>) => Promise<void>;
+  onStatusMessage: (msg: string) => void;
+};
+
+// ---------------------------------------------------------------------------
+// Component
+// ---------------------------------------------------------------------------
+
+export function SettingsDialog({
+  open: isOpen,
+  onOpenChange,
+  defaultTab = "workspace",
+  token,
+  editWorkspace,
+  appVersion,
+  socketPath,
+  selectedWorkspaceId,
+  focusedPaneId,
+  focusedSurfaceId,
+  shortcuts,
+  onShortcutChange,
+  onResetShortcuts,
+  rpcRateLimit,
+  onRpcRateLimitChange,
+  onSaveWorkspaceEnv,
+  onStatusMessage,
+}: SettingsDialogProps) {
+  // -- Edit workspace state --
+  const [editEnvVars, setEditEnvVars] = useState<EnvEntry[]>(() => {
+    if (!editWorkspace) return [];
+    return Object.entries(editWorkspace.env_vars || {})
+      .filter(([k]) => !k.startsWith("MAXC_"))
+      .map(([key, value]) => ({ key, value }));
+  });
+  const [editSaving, setEditSaving] = useState(false);
+  const [editError, setEditError] = useState("");
+
+  // -- Update tab state --
+  const [updateChannel, setUpdateChannel] = useState<"stable" | "beta">(() => {
+    try { return (localStorage.getItem("maxc-update-channel") as "stable" | "beta") || "stable"; }
+    catch { return "stable"; }
+  });
+  const [updateStatus, setUpdateStatus] = useState<
+    "idle" | "checking" | "available" | "uptodate" | "downloading" | "ready" | "error"
+  >("idle");
+  const [updateError, setUpdateError] = useState("");
+  const [updateInfo, setUpdateInfo] = useState<UpdateInfo | null>(null);
+
+  // -- Agent tab state --
+  const [envCopied, setEnvCopied] = useState(false);
+  const [activeTab, setActiveTab] = useState(defaultTab);
+  const [captureShortcutId, setCaptureShortcutId] = useState<string | null>(null);
+
+  const isEditing = editWorkspace !== null;
+  const ws = editWorkspace;
+  const rateLimitValue = rpcRateLimit === "unlimited" ? "unlimited" : String(rpcRateLimit);
+  const showUnlimitedWarning = rpcRateLimit === "unlimited";
+  const isDownloading = updateStatus === "downloading";
+
+  useEffect(() => {
+    if (!isOpen) return;
+    const nextTab = !isEditing && defaultTab === "workspace" ? "updates" : defaultTab;
+    setActiveTab(nextTab);
+  }, [defaultTab, isEditing, isOpen]);
+
+  useEffect(() => {
+    if (!isOpen) return;
+    if (editWorkspace) {
+      setEditEnvVars(
+        Object.entries(editWorkspace.env_vars || {})
+          .filter(([k]) => !k.startsWith("MAXC_"))
+          .map(([key, value]) => ({ key, value })),
+      );
+    } else {
+      setEditEnvVars([]);
+    }
+    setEditError("");
+  }, [editWorkspace, isOpen]);
+
+  useEffect(() => {
+    if (!captureShortcutId) return;
+
+    function handleKeyCapture(event: KeyboardEvent) {
+      event.preventDefault();
+      event.stopPropagation();
+
+      const targetId = captureShortcutId;
+      if (!targetId) return;
+
+      if (event.key === "Escape") {
+        setCaptureShortcutId(null);
+        return;
+      }
+
+      if (event.key === "Backspace" || event.key === "Delete") {
+        onShortcutChange(targetId, "");
+        setCaptureShortcutId(null);
+        return;
+      }
+
+      const formatted = formatShortcut(event);
+      if (!formatted) return;
+      onShortcutChange(targetId, formatted);
+      setCaptureShortcutId(null);
+    }
+
+    window.addEventListener("keydown", handleKeyCapture, true);
+    return () => window.removeEventListener("keydown", handleKeyCapture, true);
+  }, [captureShortcutId, onShortcutChange]);
+
+  function formatShortcut(event: KeyboardEvent) {
+    const key = event.key;
+    if (key === "Control" || key === "Shift" || key === "Alt" || key === "Meta") return "";
+    const parts: string[] = [];
+    if (event.ctrlKey || event.metaKey) parts.push("Ctrl");
+    if (event.shiftKey) parts.push("Shift");
+    if (event.altKey) parts.push("Alt");
+    let mainKey = key;
+    if (mainKey === " ") mainKey = "Space";
+    if (mainKey.length === 1) mainKey = mainKey.toUpperCase();
+    parts.push(mainKey);
+    return parts.join("+");
+  }
+
+  // -- Handlers --
+
+  async function handleSaveEnv() {
+    if (!ws) return;
+    const envObj: Record<string, string> = {};
+    for (const e of editEnvVars) { const k = e.key.trim(); if (k) envObj[k] = e.value; }
+    for (const [key, value] of Object.entries(ws.env_vars || {})) {
+      if (key.startsWith("MAXC_") && !(key in envObj)) envObj[key] = value;
+    }
+    setEditSaving(true); setEditError("");
+    try {
+      await onSaveWorkspaceEnv(ws.workspace_id, envObj);
+      onOpenChange(false);
+    } catch (err) {
+      setEditError((err as Error).message);
+    } finally { setEditSaving(false); }
+  }
+
+  async function checkForUpdates() {
+    setUpdateStatus("checking"); setUpdateError(""); setUpdateInfo(null);
+    try {
+      const result = await invoke<UpdateInfo>("update_check", { channel: updateChannel });
+      if (!result.available) { setUpdateStatus("uptodate"); return; }
+      setUpdateInfo(result);
+      setUpdateStatus("available");
+    } catch (err) {
+      const msg = err instanceof Error ? err.message : String(err);
+      if (/404|not found|no release/i.test(msg)) { setUpdateStatus("uptodate"); return; }
+      setUpdateStatus("error"); setUpdateError(msg || "Update check failed");
+    }
+  }
+
+  async function downloadAndInstall() {
+    setUpdateStatus("downloading"); setUpdateError("");
+    try {
+      await invoke("update_download_and_install", { channel: updateChannel });
+      setUpdateStatus("ready");
+    } catch (err) {
+      setUpdateStatus("error"); setUpdateError((err as Error).message || "Update failed");
+    }
+  }
+
+  function handleChannelChange(ch: "stable" | "beta") {
+    setUpdateChannel(ch);
+    try { localStorage.setItem("maxc-update-channel", ch); } catch {}
+  }
+
+  const envLines = [
+    `MAXC_SOCKET_PATH=${socketPath}`,
+    token ? `MAXC_TOKEN=${token}` : "MAXC_TOKEN=",
+    selectedWorkspaceId ? `MAXC_WORKSPACE_ID=${selectedWorkspaceId}` : "MAXC_WORKSPACE_ID=",
+    focusedPaneId ? `MAXC_PANE_ID=${focusedPaneId}` : "MAXC_PANE_ID=",
+    focusedSurfaceId ? `MAXC_SURFACE_ID=${focusedSurfaceId}` : "MAXC_SURFACE_ID=",
+  ];
+  const envBlock = envLines.join("\n");
+
+  async function copyEnvBlock() {
+    try {
+      await navigator.clipboard.writeText(envBlock);
+      setEnvCopied(true);
+      setTimeout(() => setEnvCopied(false), 2000);
+    } catch { onStatusMessage("Failed to copy"); }
+  }
+
+  // -- Env var helpers (shared between create/edit) --
+  function envAdd(setter: Dispatch<SetStateAction<EnvEntry[]>>) {
+    setter((p) => [...p, { key: "", value: "" }]);
+  }
+  function envUpdate(setter: Dispatch<SetStateAction<EnvEntry[]>>, i: number, field: "key" | "value", val: string) {
+    setter((p) => p.map((e, idx) => (idx === i ? { ...e, [field]: val } : e)));
+  }
+  function envRemove(setter: Dispatch<SetStateAction<EnvEntry[]>>, i: number) {
+    setter((p) => p.filter((_, idx) => idx !== i));
+  }
+
+  function renderEnvEditor(entries: EnvEntry[], setter: Dispatch<SetStateAction<EnvEntry[]>>) {
+    return (
+      <div className="space-y-2">
+        <div className="flex items-center justify-between">
+          <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
+            Environment Variables
+          </label>
+          <Button variant="ghost" size="icon-xs" onClick={() => envAdd(setter)}>
+            <Plus className="size-3.5" />
+          </Button>
+        </div>
+        {entries.length === 0 ? (
+          <div className="text-[11px] text-muted-foreground/60 rounded-md border border-dashed px-3 py-2 text-center">
+            No variables. Click + to add.
+          </div>
+        ) : (
+          <div className="space-y-1.5">
+            {entries.map((entry, i) => (
+              <div key={i} className="flex items-center gap-1.5">
+                <input
+                  type="text"
+                  value={entry.key}
+                  onChange={(e) => envUpdate(setter, i, "key", e.target.value)}
+                  placeholder="KEY"
+                  className="flex-1 rounded-md border bg-muted px-2 py-1.5 text-[11px] font-mono outline-none focus:ring-1 focus:ring-ring"
+                />
+                <span className="text-muted-foreground text-[11px]">=</span>
+                <input
+                  type="text"
+                  value={entry.value}
+                  onChange={(e) => envUpdate(setter, i, "value", e.target.value)}
+                  placeholder="value"
+                  className="flex-1 rounded-md border bg-muted px-2 py-1.5 text-[11px] font-mono outline-none focus:ring-1 focus:ring-ring"
+                />
+                <Button variant="ghost" size="icon-xs" onClick={() => envRemove(setter, i)}>
+                  <Trash2 className="size-3 text-muted-foreground" />
+                </Button>
+              </div>
+            ))}
+          </div>
+        )}
+      </div>
+    );
+  }
+
+  return (
+    <Dialog open={isOpen} onOpenChange={onOpenChange}>
+      <DialogContent className="sm:max-w-lg h-[55vh] overflow-hidden flex flex-col" showCloseButton>
+        <DialogHeader>
+          <DialogTitle>{isEditing ? "Workspace Settings" : "Settings"}</DialogTitle>
+          <DialogDescription>
+            {isEditing
+              ? `Configure ${ws?.name || "workspace"}`
+              : "Manage workspaces, agent connection, and updates."}
+          </DialogDescription>
+        </DialogHeader>
+
+        <Tabs value={activeTab} onValueChange={setActiveTab} className="flex-1 min-h-0">
+          <TabsList variant="line" className="w-full justify-start">
+            {isEditing && (
+              <TabsTrigger value="workspace">
+                Workspace
+              </TabsTrigger>
+            )}
+            <TabsTrigger value="agent" className="gap-1.5">
+              <Bot className="size-3.5" />
+              Agent
+            </TabsTrigger>
+            <TabsTrigger value="shortcuts" className="gap-1.5">
+              <Keyboard className="size-3.5" />
+              Shortcuts
+            </TabsTrigger>
+            <TabsTrigger value="rate-limit" className="gap-1.5">
+              <ArrowUpDown className="size-3.5" />
+              Rate Limit
+            </TabsTrigger>
+            <TabsTrigger value="updates" className="gap-1.5">
+              <Download className="size-3.5" />
+              Updates
+            </TabsTrigger>
+            <TabsTrigger value="about" className="gap-1.5">
+              <Info className="size-3.5" />
+              About
+            </TabsTrigger>
+          </TabsList>
+
+          {/* ============ WORKSPACE TAB ============ */}
+          {isEditing && (
+            <TabsContent value="workspace" className="settings-scroll overflow-auto h-[55vh] pr-1 space-y-4 mt-3">
+              <div className="space-y-1.5">
+                <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
+                  Working Directory
+                </label>
+                <div className="rounded-md border bg-muted px-3 py-2 text-[11px] text-muted-foreground font-mono truncate">
+                  {ws?.folder || "No folder set"}
+                </div>
+              </div>
+
+              {renderEnvEditor(editEnvVars, setEditEnvVars)}
+
+              <div className="space-y-1.5">
+                <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
+                  MAXC Environment (read-only)
+                </label>
+                <pre className="rounded-md border bg-muted px-3 py-2 text-[10px] font-mono text-muted-foreground whitespace-pre-wrap break-words">
+                  {Object.entries(ws?.env_vars ?? {})
+                    .filter(([k]) => k.startsWith("MAXC_"))
+                    .map(([k, v]) => `${k}=${v}`)
+                    .join("\n") || "Not available yet."}
+                </pre>
+              </div>
+
+              {editError && (
+                <div className="text-[11px] text-destructive bg-destructive/10 rounded-md px-3 py-2">{editError}</div>
+              )}
+              <div className="flex gap-2 pt-1">
+                <Button variant="outline" size="sm" onClick={() => onOpenChange(false)} disabled={editSaving}>
+                  Cancel
+                </Button>
+                <Button size="sm" onClick={handleSaveEnv} disabled={editSaving}>
+                  {editSaving ? "Saving..." : "Save"}
+                </Button>
+              </div>
+            </TabsContent>
+          )}
+
+          {/* ============ AGENT TAB ============ */}
+          <TabsContent value="agent" className="settings-scroll overflow-auto h-[55vh] pr-1 space-y-4 mt-3">
+            <div className="space-y-1.5">
+              <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
+                Agent Connection
+              </label>
+              <p className="text-[11px] text-muted-foreground leading-relaxed">
+                Use these environment variables to let an external agent access all maxc commands.
+                Agents launched inside a maxc terminal inherit these values automatically.
+              </p>
+            </div>
+
+            <div className="space-y-1.5">
+              <div className="flex items-center justify-between">
+                <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
+                  MAXC Environment
+                </label>
+                <Button variant="outline" size="sm" onClick={copyEnvBlock} className="h-6 text-[10px] gap-1.5">
+                  {envCopied ? <><Check className="size-3" /> Copied</> : "Copy"}
+                </Button>
+              </div>
+              <pre className="rounded-md border bg-muted px-3 py-2 text-[10px] font-mono text-muted-foreground whitespace-pre-wrap break-words">
+                {envBlock}
+              </pre>
+            </div>
+
+          </TabsContent>
+
+          {/* ============ UPDATES TAB ============ */}
+          <TabsContent value="updates" className="settings-scroll overflow-auto h-[55vh] pr-1 space-y-4 mt-3">
+            <div className="space-y-1.5">
+              <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
+                Current Version
+              </label>
+              <div className="rounded-md border bg-muted px-3 py-2 text-[11px] font-mono">
+                {appVersion ? `v${appVersion}` : "Unknown"}
+              </div>
+            </div>
+
+            <div className="space-y-2">
+              <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
+                Update Channel
+              </label>
+              <div className="flex items-center gap-2">
+                <div className="relative">
+                  <select
+                    value={updateChannel}
+                    onChange={(e) => handleChannelChange(e.target.value as "stable" | "beta")}
+                    className="h-7 appearance-none rounded-md border bg-muted pl-2 pr-7 text-[11px] outline-none focus:ring-1 focus:ring-ring cursor-pointer"
+                  >
+                    <option value="stable">Stable</option>
+                    <option value="beta">Beta</option>
+                  </select>
+                  <ChevronDown className="pointer-events-none absolute right-1.5 top-1/2 -translate-y-1/2 size-3 text-muted-foreground" />
+                </div>
+                <Button
+                  variant="outline"
+                  size="sm"
+                  className="h-7 text-[11px]"
+                  onClick={checkForUpdates}
+                  disabled={updateStatus === "checking" || isDownloading}
+                >
+                  {updateStatus === "checking" ? "Checking..." : "Check for Updates"}
+                </Button>
+              </div>
+            </div>
+
+            {updateStatus === "available" && updateInfo && (
+              <div className="rounded-md border bg-muted px-3 py-3 space-y-2">
+                <div className="text-[11px] font-medium">
+                  Update available: v{updateInfo.version ?? "new"}
+                </div>
+                {updateInfo.date_ms && (
+                  <div className="text-[10px] text-muted-foreground">
+                    {new Date(updateInfo.date_ms).toLocaleString()}
+                  </div>
+                )}
+                {updateInfo.body && (
+                  <div className="text-[10px] text-muted-foreground whitespace-pre-wrap leading-relaxed">
+                    {updateInfo.body}
+                  </div>
+                )}
+                <Button size="sm" onClick={downloadAndInstall} disabled={isDownloading}>
+                  {isDownloading ? "Downloading..." : "Download & Install"}
+                </Button>
+              </div>
+            )}
+            {updateStatus === "downloading" && (
+              <div className="text-[11px] text-muted-foreground">Downloading update...</div>
+            )}
+            {updateStatus === "ready" && (
+              <div className="text-[11px] text-muted-foreground">Update installed. Restarting...</div>
+            )}
+            {updateStatus === "uptodate" && (
+              <div className="text-[11px] text-emerald-500">You are up to date.</div>
+            )}
+            {updateStatus === "error" && (
+              <div className="text-[11px] text-destructive">{updateError || "Update check failed."}</div>
+            )}
+          </TabsContent>
+
+          {/* ============ ABOUT TAB ============ */}
+          <TabsContent value="about" className="settings-scroll overflow-auto h-[55vh] pr-1 space-y-4 mt-3">
+            <div className="flex flex-col items-center gap-3 py-4">
+              <img
+                src={logoWhite}
+                alt="maxc"
+                className="h-12 w-auto select-none"
+                draggable={false}
+              />
+              <div className="text-[11px] text-muted-foreground font-mono">
+                {appVersion ? `Version ${appVersion}` : "Version unknown"}
+              </div>
+            </div>
+
+            <div className="space-y-2 text-[11px] text-muted-foreground leading-relaxed">
+              <p>
+                A programmable developer workspace for terminals, browsers, and AI agents.
+                Built with Rust, Tauri, and React.
+              </p>
+              <p>
+                maxc is agent-agnostic. Any AI coding agent that can run shell commands
+                can control terminals, browsers, and tasks through the CLI or JSON-RPC API.
+              </p>
+            </div>
+
+            <div className="grid grid-cols-2 gap-2 text-[10px]">
+              {[
+                { label: "Backend", value: "Rust + Event Sourcing" },
+                { label: "Frontend", value: "Tauri + React + xterm.js" },
+                { label: "RPC Methods", value: "52 methods" },
+                { label: "License", value: "Apache-2.0" },
+              ].map((item) => (
+                <div key={item.label} className="rounded-md border bg-muted px-3 py-2">
+                  <div className="text-muted-foreground">{item.label}</div>
+                  <div className="text-foreground font-medium mt-0.5">{item.value}</div>
+                </div>
+              ))}
+            </div>
+
+            <div className="flex gap-2 pt-1">
+              <Button variant="outline" size="sm" className="text-[11px]" asChild>
+                <a href="https://github.com/Pollux-Studio/maxc" target="_blank" rel="noopener noreferrer">
+                  GitHub
+                </a>
+              </Button>
+              <Button variant="outline" size="sm" className="text-[11px]" asChild>
+                <a href="https://maxc.polluxstudio.in/" target="_blank" rel="noopener noreferrer">
+                  Website
+                </a>
+              </Button>
+            </div>
+          </TabsContent>
+
+          {/* ============ SHORTCUTS TAB ============ */}
+          <TabsContent value="shortcuts" className="settings-scroll overflow-auto h-[55vh] pr-1 space-y-4 mt-3">
+            <div className="flex items-center justify-between">
+              <div>
+                <div className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
+                  Keyboard Shortcuts
+                </div>
+                <div className="text-[10px] text-muted-foreground mt-1">
+                  Use a format like <span className="font-mono">Ctrl+Shift+N</span>.
+                </div>
+              </div>
+              <Button variant="outline" size="sm" className="h-7 text-[11px]" onClick={onResetShortcuts}>
+                Reset
+              </Button>
+            </div>
+            <div className="space-y-2">
+              {shortcuts.map((shortcut) => (
+                <div key={shortcut.id} className="flex items-center gap-2">
+                  <div className="flex-1">
+                    <div className="text-[11px] font-medium text-foreground">{shortcut.label}</div>
+                    <div className="text-[10px] text-muted-foreground">
+                      Default: <span className="font-mono">{shortcut.defaultKeys}</span>
+                    </div>
+                  </div>
+                  <Button
+                    variant={captureShortcutId === shortcut.id ? "default" : "outline"}
+                    size="sm"
+                    className="h-7 px-2 text-[11px] font-mono"
+                    onClick={() =>
+                      setCaptureShortcutId((prev) => (prev === shortcut.id ? null : shortcut.id))
+                    }
+                  >
+                    {captureShortcutId === shortcut.id
+                      ? "Press keys..."
+                      : shortcut.keys || "Unassigned"}
+                  </Button>
+                </div>
+              ))}
+            </div>
+            <div className="rounded-md border bg-muted/50 px-3 py-2 text-[10px] text-muted-foreground">
+              Click a shortcut to capture keys. Press Escape to cancel, Backspace/Delete to clear.
+            </div>
+          </TabsContent>
+
+          {/* ============ RATE LIMIT TAB ============ */}
+          <TabsContent value="rate-limit" className="settings-scroll overflow-auto h-[55vh] pr-1 space-y-4 mt-3">
+            <div className="space-y-2">
+              <label className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
+                RPC Rate Limit
+              </label>
+              <div className="flex items-center gap-2">
+                <select
+                  value={rateLimitValue}
+                  onChange={(e) => onRpcRateLimitChange(e.target.value)}
+                  className="h-8 w-[160px] appearance-none rounded-md border bg-muted px-2 text-[11px] outline-none focus:ring-1 focus:ring-ring"
+                >
+                  <option value="5">5 req/s</option>
+                  <option value="10">10 req/s</option>
+                  <option value="20">20 req/s</option>
+                  <option value="30">30 req/s</option>
+                  <option value="60">60 req/s</option>
+                  <option value="120">120 req/s</option>
+                  <option value="unlimited">Unlimited</option>
+                </select>
+                <span className="text-[10px] text-muted-foreground">
+                  Applies to frontend JSON-RPC requests.
+                </span>
+              </div>
+              {showUnlimitedWarning && (
+                <div className="rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2 text-[10px] text-amber-200">
+                  Unlimited rate limit can increase system resource usage.
+                </div>
+              )}
+            </div>
+
+            <div className="space-y-3">
+              <div className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
+                RPC Endpoints
+              </div>
+              <div className="space-y-3">
+                {RPC_ENDPOINT_GROUPS.map((group) => (
+                  <div key={group.title} className="space-y-1">
+                    <div className="text-[11px] font-medium text-foreground">{group.title}</div>
+                    <div className="flex flex-wrap gap-1">
+                      {group.methods.map((method) => (
+                        <span
+                          key={method}
+                          className="rounded border bg-muted px-2 py-0.5 text-[10px] font-mono text-muted-foreground"
+                        >
+                          {method}
+                        </span>
+                      ))}
+                    </div>
+                  </div>
+                ))}
+              </div>
+            </div>
+          </TabsContent>
+        </Tabs>
+      </DialogContent>
+    </Dialog>
+  );
+}
diff --git a/maxc_desktop/src/components/ui/context-menu.tsx b/maxc_desktop/src/components/ui/context-menu.tsx
new file mode 100644
index 0000000..f0fe0fa
--- /dev/null
+++ b/maxc_desktop/src/components/ui/context-menu.tsx
@@ -0,0 +1,261 @@
+import * as React from "react"
+import { ContextMenu as ContextMenuPrimitive } from "radix-ui"
+
+import { cn } from "@/lib/utils"
+import { ChevronRightIcon, CheckIcon } from "lucide-react"
+
+function ContextMenu({
+  ...props
+}: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {
+  return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />
+}
+
+function ContextMenuTrigger({
+  className,
+  ...props
+}: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {
+  return (
+    <ContextMenuPrimitive.Trigger
+      data-slot="context-menu-trigger"
+      className={cn("select-none", className)}
+      {...props}
+    />
+  )
+}
+
+function ContextMenuGroup({
+  ...props
+}: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {
+  return (
+    <ContextMenuPrimitive.Group data-slot="context-menu-group" {...props} />
+  )
+}
+
+function ContextMenuPortal({
+  ...props
+}: React.ComponentProps<typeof ContextMenuPrimitive.Portal>) {
+  return (
+    <ContextMenuPrimitive.Portal data-slot="context-menu-portal" {...props} />
+  )
+}
+
+function ContextMenuSub({
+  ...props
+}: React.ComponentProps<typeof ContextMenuPrimitive.Sub>) {
+  return <ContextMenuPrimitive.Sub data-slot="context-menu-sub" {...props} />
+}
+
+function ContextMenuRadioGroup({
+  ...props
+}: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>) {
+  return (
+    <ContextMenuPrimitive.RadioGroup
+      data-slot="context-menu-radio-group"
+      {...props}
+    />
+  )
+}
+
+function ContextMenuContent({
+  className,
+  ...props
+}: React.ComponentProps<typeof ContextMenuPrimitive.Content> & {
+  side?: "top" | "right" | "bottom" | "left"
+}) {
+  return (
+    <ContextMenuPrimitive.Portal>
+      <ContextMenuPrimitive.Content
+        data-slot="context-menu-content"
+        className={cn("z-50 max-h-(--radix-context-menu-content-available-height) min-w-32 origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
+        {...props}
+      />
+    </ContextMenuPrimitive.Portal>
+  )
+}
+
+function ContextMenuItem({
+  className,
+  inset,
+  variant = "default",
+  ...props
+}: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {
+  inset?: boolean
+  variant?: "default" | "destructive"
+}) {
+  return (
+    <ContextMenuPrimitive.Item
+      data-slot="context-menu-item"
+      data-inset={inset}
+      data-variant={variant}
+      className={cn(
+        "group/context-menu-item relative flex min-h-7 cursor-default items-center gap-2 rounded-md px-2 py-1 text-xs/relaxed outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7.5 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5 data-[variant=destructive]:*:[svg]:text-destructive",
+        className
+      )}
+      {...props}
+    />
+  )
+}
+
+function ContextMenuSubTrigger({
+  className,
+  inset,
+  children,
+  ...props
+}: React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & {
+  inset?: boolean
+}) {
+  return (
+    <ContextMenuPrimitive.SubTrigger
+      data-slot="context-menu-sub-trigger"
+      data-inset={inset}
+      className={cn(
+        "flex min-h-7 cursor-default items-center gap-2 rounded-md px-2 py-1 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7.5 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
+        className
+      )}
+      {...props}
+    >
+      {children}
+      <ChevronRightIcon className="ml-auto" />
+    </ContextMenuPrimitive.SubTrigger>
+  )
+}
+
+function ContextMenuSubContent({
+  className,
+  ...props
+}: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>) {
+  return (
+    <ContextMenuPrimitive.SubContent
+      data-slot="context-menu-sub-content"
+      className={cn("z-50 min-w-32 origin-(--radix-context-menu-content-transform-origin) overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
+      {...props}
+    />
+  )
+}
+
+function ContextMenuCheckboxItem({
+  className,
+  children,
+  checked,
+  inset,
+  ...props
+}: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem> & {
+  inset?: boolean
+}) {
+  return (
+    <ContextMenuPrimitive.CheckboxItem
+      data-slot="context-menu-checkbox-item"
+      data-inset={inset}
+      className={cn(
+        "relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 pr-8 pl-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7.5 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
+        className
+      )}
+      checked={checked}
+      {...props}
+    >
+      <span className="pointer-events-none absolute right-2 flex items-center justify-center">
+        <ContextMenuPrimitive.ItemIndicator>
+          <CheckIcon
+          />
+        </ContextMenuPrimitive.ItemIndicator>
+      </span>
+      {children}
+    </ContextMenuPrimitive.CheckboxItem>
+  )
+}
+
+function ContextMenuRadioItem({
+  className,
+  children,
+  inset,
+  ...props
+}: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem> & {
+  inset?: boolean
+}) {
+  return (
+    <ContextMenuPrimitive.RadioItem
+      data-slot="context-menu-radio-item"
+      data-inset={inset}
+      className={cn(
+        "relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 pr-8 pl-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7.5 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
+        className
+      )}
+      {...props}
+    >
+      <span className="pointer-events-none absolute right-2 flex items-center justify-center">
+        <ContextMenuPrimitive.ItemIndicator>
+          <CheckIcon
+          />
+        </ContextMenuPrimitive.ItemIndicator>
+      </span>
+      {children}
+    </ContextMenuPrimitive.RadioItem>
+  )
+}
+
+function ContextMenuLabel({
+  className,
+  inset,
+  ...props
+}: React.ComponentProps<typeof ContextMenuPrimitive.Label> & {
+  inset?: boolean
+}) {
+  return (
+    <ContextMenuPrimitive.Label
+      data-slot="context-menu-label"
+      data-inset={inset}
+      className={cn(
+        "px-2 py-1.5 text-xs text-muted-foreground data-inset:pl-7.5",
+        className
+      )}
+      {...props}
+    />
+  )
+}
+
+function ContextMenuSeparator({
+  className,
+  ...props
+}: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {
+  return (
+    <ContextMenuPrimitive.Separator
+      data-slot="context-menu-separator"
+      className={cn("-mx-1 my-1 h-px bg-border/50", className)}
+      {...props}
+    />
+  )
+}
+
+function ContextMenuShortcut({
+  className,
+  ...props
+}: React.ComponentProps<"span">) {
+  return (
+    <span
+      data-slot="context-menu-shortcut"
+      className={cn(
+        "ml-auto text-[0.625rem] tracking-widest text-muted-foreground group-focus/context-menu-item:text-accent-foreground",
+        className
+      )}
+      {...props}
+    />
+  )
+}
+
+export {
+  ContextMenu,
+  ContextMenuTrigger,
+  ContextMenuContent,
+  ContextMenuItem,
+  ContextMenuCheckboxItem,
+  ContextMenuRadioItem,
+  ContextMenuLabel,
+  ContextMenuSeparator,
+  ContextMenuShortcut,
+  ContextMenuGroup,
+  ContextMenuPortal,
+  ContextMenuSub,
+  ContextMenuSubContent,
+  ContextMenuSubTrigger,
+  ContextMenuRadioGroup,
+}
diff --git a/maxc_desktop/src/components/ui/dialog.tsx b/maxc_desktop/src/components/ui/dialog.tsx
new file mode 100644
index 0000000..c9060de
--- /dev/null
+++ b/maxc_desktop/src/components/ui/dialog.tsx
@@ -0,0 +1,163 @@
+import * as React from "react"
+import { Dialog as DialogPrimitive } from "radix-ui"
+
+import { cn } from "@/lib/utils"
+import { Button } from "@/components/ui/button"
+import { XIcon } from "lucide-react"
+
+function Dialog({
+  ...props
+}: React.ComponentProps<typeof DialogPrimitive.Root>) {
+  return <DialogPrimitive.Root data-slot="dialog" {...props} />
+}
+
+function DialogTrigger({
+  ...props
+}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
+  return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
+}
+
+function DialogPortal({
+  ...props
+}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
+  return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
+}
+
+function DialogClose({
+  ...props
+}: React.ComponentProps<typeof DialogPrimitive.Close>) {
+  return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
+}
+
+function DialogOverlay({
+  className,
+  ...props
+}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
+  return (
+    <DialogPrimitive.Overlay
+      data-slot="dialog-overlay"
+      className={cn(
+        "fixed inset-0 isolate z-50 bg-black/80 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
+        className
+      )}
+      {...props}
+    />
+  )
+}
+
+function DialogContent({
+  className,
+  children,
+  showCloseButton = true,
+  ...props
+}: React.ComponentProps<typeof DialogPrimitive.Content> & {
+  showCloseButton?: boolean
+}) {
+  return (
+    <DialogPortal>
+      <DialogOverlay />
+      <DialogPrimitive.Content
+        data-slot="dialog-content"
+        className={cn(
+          "fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-background p-4 text-xs/relaxed ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
+          className
+        )}
+        {...props}
+      >
+        {children}
+        {showCloseButton && (
+          <DialogPrimitive.Close data-slot="dialog-close" asChild>
+            <Button
+              variant="ghost"
+              className="absolute top-2 right-2"
+              size="icon-sm"
+            >
+              <XIcon
+              />
+              <span className="sr-only">Close</span>
+            </Button>
+          </DialogPrimitive.Close>
+        )}
+      </DialogPrimitive.Content>
+    </DialogPortal>
+  )
+}
+
+function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
+  return (
+    <div
+      data-slot="dialog-header"
+      className={cn("flex flex-col gap-1", className)}
+      {...props}
+    />
+  )
+}
+
+function DialogFooter({
+  className,
+  showCloseButton = false,
+  children,
+  ...props
+}: React.ComponentProps<"div"> & {
+  showCloseButton?: boolean
+}) {
+  return (
+    <div
+      data-slot="dialog-footer"
+      className={cn(
+        "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
+        className
+      )}
+      {...props}
+    >
+      {children}
+      {showCloseButton && (
+        <DialogPrimitive.Close asChild>
+          <Button variant="outline">Close</Button>
+        </DialogPrimitive.Close>
+      )}
+    </div>
+  )
+}
+
+function DialogTitle({
+  className,
+  ...props
+}: React.ComponentProps<typeof DialogPrimitive.Title>) {
+  return (
+    <DialogPrimitive.Title
+      data-slot="dialog-title"
+      className={cn("text-sm font-medium", className)}
+      {...props}
+    />
+  )
+}
+
+function DialogDescription({
+  className,
+  ...props
+}: React.ComponentProps<typeof DialogPrimitive.Description>) {
+  return (
+    <DialogPrimitive.Description
+      data-slot="dialog-description"
+      className={cn(
+        "text-xs/relaxed text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
+        className
+      )}
+      {...props}
+    />
+  )
+}
+
+export {
+  Dialog,
+  DialogClose,
+  DialogContent,
+  DialogDescription,
+  DialogFooter,
+  DialogHeader,
+  DialogOverlay,
+  DialogPortal,
+  DialogTitle,
+  DialogTrigger,
+}
diff --git a/maxc_desktop/src/components/ui/tabs.tsx b/maxc_desktop/src/components/ui/tabs.tsx
new file mode 100644
index 0000000..6c41388
--- /dev/null
+++ b/maxc_desktop/src/components/ui/tabs.tsx
@@ -0,0 +1,88 @@
+import * as React from "react"
+import { cva, type VariantProps } from "class-variance-authority"
+import { Tabs as TabsPrimitive } from "radix-ui"
+
+import { cn } from "@/lib/utils"
+
+function Tabs({
+  className,
+  orientation = "horizontal",
+  ...props
+}: React.ComponentProps<typeof TabsPrimitive.Root>) {
+  return (
+    <TabsPrimitive.Root
+      data-slot="tabs"
+      data-orientation={orientation}
+      className={cn(
+        "group/tabs flex gap-2 data-horizontal:flex-col",
+        className
+      )}
+      {...props}
+    />
+  )
+}
+
+const tabsListVariants = cva(
+  "group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none",
+  {
+    variants: {
+      variant: {
+        default: "bg-muted",
+        line: "gap-1 bg-transparent",
+      },
+    },
+    defaultVariants: {
+      variant: "default",
+    },
+  }
+)
+
+function TabsList({
+  className,
+  variant = "default",
+  ...props
+}: React.ComponentProps<typeof TabsPrimitive.List> &
+  VariantProps<typeof tabsListVariants>) {
+  return (
+    <TabsPrimitive.List
+      data-slot="tabs-list"
+      data-variant={variant}
+      className={cn(tabsListVariants({ variant }), className)}
+      {...props}
+    />
+  )
+}
+
+function TabsTrigger({
+  className,
+  ...props
+}: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
+  return (
+    <TabsPrimitive.Trigger
+      data-slot="tabs-trigger"
+      className={cn(
+        "relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-xs font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start group-data-vertical/tabs:py-[calc(--spacing(1.25))] hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
+        "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent",
+        "data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground",
+        "after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
+        className
+      )}
+      {...props}
+    />
+  )
+}
+
+function TabsContent({
+  className,
+  ...props
+}: React.ComponentProps<typeof TabsPrimitive.Content>) {
+  return (
+    <TabsPrimitive.Content
+      data-slot="tabs-content"
+      className={cn("flex-1 text-xs/relaxed outline-none", className)}
+      {...props}
+    />
+  )
+}
+
+export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }
diff --git a/maxc_logo/maxc_logo_full_dark_single.svg b/maxc_logo/maxc_logo_full_dark_single.svg
index 4a0823c..59e134e 100644
--- a/maxc_logo/maxc_logo_full_dark_single.svg
+++ b/maxc_logo/maxc_logo_full_dark_single.svg
@@ -1,5 +1,12 @@
 <svg width="1080" height="1080" viewBox="0 0 1080 1080" fill="none" xmlns="http://www.w3.org/2000/svg">
-<rect x="0.5" y="0.5" width="1079" height="1079" rx="99.5" fill="white"/>
+<g clip-path="url(#clip0_38_92)">
+<rect width="1080" height="1080" rx="100" fill="white"/>
+<path d="M727 713V838H352V713H227V338H352V213H727V338H852V713H727ZM352 463H602V338H352V463ZM727 463H602V588H352V713H727V463Z" fill="#1E1E1E"/>
+</g>
 <rect x="0.5" y="0.5" width="1079" height="1079" rx="99.5" stroke="white"/>
-<path d="M637 641V703.5H449.5V641H387V453.5H449.5V391H637V453.5H699.5V641H637ZM449.5 516H574.5V453.5H449.5V516ZM637 516H574.5V578.5H449.5V641H637V516Z" fill="#1E1E1E"/>
+<defs>
+<clipPath id="clip0_38_92">
+<rect width="1080" height="1080" rx="100" fill="white"/>
+</clipPath>
+</defs>
 </svg>
diff --git a/maxc_logo/maxc_logo_full_white_single.svg b/maxc_logo/maxc_logo_full_white_single.svg
index b9a75ec..6c1d139 100644
--- a/maxc_logo/maxc_logo_full_white_single.svg
+++ b/maxc_logo/maxc_logo_full_white_single.svg
@@ -1,5 +1,11 @@
 <svg width="1080" height="1080" viewBox="0 0 1080 1080" fill="none" xmlns="http://www.w3.org/2000/svg">
-<rect x="0.5" y="0.5" width="1079" height="1079" rx="99.5" fill="#1E1E1E"/>
-<rect x="0.5" y="0.5" width="1079" height="1079" rx="99.5" stroke="white"/>
-<path d="M637 641V703.5H449.5V641H387V453.5H449.5V391H637V453.5H699.5V641H637ZM449.5 516H574.5V453.5H449.5V516ZM637 516H574.5V578.5H449.5V641H637V516Z" fill="white"/>
+<g clip-path="url(#clip0_38_87)">
+<rect width="1080" height="1080" rx="100" fill="#1E1E1E"/>
+<path d="M727 713V838H352V713H227V338H352V213H727V338H852V713H727ZM352 463H602V338H352V463ZM727 463H602V588H352V713H727V463Z" fill="white"/>
+</g>
+<defs>
+<clipPath id="clip0_38_87">
+<rect width="1080" height="1080" rx="100" fill="white"/>
+</clipPath>
+</defs>
 </svg>
