diff --git a/.github/workflows/mobile-layout-regression.yml b/.github/workflows/mobile-layout-regression.yml
new file mode 100644
--- /dev/null
+++ b/.github/workflows/mobile-layout-regression.yml
@@ -0,0 +1,52 @@
+name: Mobile layout regression
+
+on:
+  pull_request:
+    paths:
+      - "frontend/apps/artcraft/app/src/pages/PageApps/AppsIndexPage.tsx"
+      - "frontend/apps/artcraft/app/src/pages/MainApp.tsx"
+      - "frontend/apps/artcraft/app/src/components/signaled/TopBar/TopBar.tsx"
+      - "frontend/apps/artcraft/app/src/styles/**"
+      - "frontend/apps/artcraft/app/index.html"
+      - "frontend/apps/artcraft/playwright.mobile.config.ts"
+      - "frontend/apps/artcraft/e2e/mobile-layout.spec.ts"
+      - "frontend/package.json"
+      - "frontend/package-lock.json"
+      - ".github/workflows/mobile-layout-regression.yml"
+  push:
+    branches:
+      - fix/2466-mobile-layout
+  workflow_dispatch:
+
+permissions:
+  contents: read
+
+jobs:
+  mobile-layout:
+    name: Mobile layout smoke test
+    runs-on: ubuntu-latest
+    timeout-minutes: 20
+    steps:
+      - name: Check out source
+        uses: actions/checkout@v4
+
+      - name: Set up Node.js
+        uses: actions/setup-node@v4
+        with:
+          node-version: 22
+          cache: npm
+          cache-dependency-path: frontend/package-lock.json
+
+      - name: Install frontend workspace dependencies
+        working-directory: frontend
+        run: npm ci
+
+      - name: Install Playwright Chromium
+        working-directory: frontend
+        run: npx playwright install --with-deps chromium
+
+      - name: Run mobile layout smoke test
+        working-directory: frontend/apps/artcraft
+        env:
+          CI: "true"
+        run: npx playwright test e2e/mobile-layout.spec.ts --config=playwright.mobile.config.ts
diff --git a/frontend/apps/artcraft/app/src/components/signaled/TopBar/TopBar.tsx b/frontend/apps/artcraft/app/src/components/signaled/TopBar/TopBar.tsx
--- a/frontend/apps/artcraft/app/src/components/signaled/TopBar/TopBar.tsx
+++ b/frontend/apps/artcraft/app/src/components/signaled/TopBar/TopBar.tsx
@@ -546,7 +546,7 @@ export const TopBar = ({ pageName }: Props) => {
                     {sumTotalCredits.toLocaleString()}
                   </span>
                 }
-                buttonClassName="h-8 px-3 ps-2.5 bg-transparent hover:bg-white/10 border border-white/15 hover:border-white/30 shadow-none text-white/80 rounded-[3px] gap-1.5"
+                buttonClassName="h-8 px-3 ps-2.5 max-[359px]:px-1 max-[359px]:ps-1 bg-transparent hover:bg-white/10 border border-white/15 hover:border-white/30 shadow-none text-white/80 rounded-[3px] gap-1.5"
                 panelClassName="mt-2 bg-[#101014] border border-white/15 text-white rounded-[3px]"
               >
                 {(close) => (
diff --git a/frontend/apps/artcraft/e2e/mobile-layout.spec.ts b/frontend/apps/artcraft/e2e/mobile-layout.spec.ts
new file mode 100644
--- /dev/null
+++ b/frontend/apps/artcraft/e2e/mobile-layout.spec.ts
@@ -0,0 +1,50 @@
+import { expect, test } from "@playwright/test";
+
+const MOBILE_WIDTHS = [320, 360, 375, 390, 414, 430];
+
+test("home page fits common mobile viewport widths without horizontal overflow", async ({ page }) => {
+  await page.goto("/");
+  await expect(page.getByRole("heading", { name: /What will you craft today\?/i })).toBeVisible();
+
+  for (const width of MOBILE_WIDTHS) {
+    await page.setViewportSize({ width, height: 844 });
+    const metrics = await page.evaluate(() => {
+      const viewportWidth = document.documentElement.clientWidth;
+      const elements = [...document.querySelectorAll<HTMLElement>("body *")];
+      const overflow = elements
+        .filter((element) => {
+          const style = getComputedStyle(element);
+          if (style.display === "none" || style.visibility === "hidden") return false;
+          const rect = element.getBoundingClientRect();
+          return rect.width > 0 && (rect.left < -1 || rect.right > viewportWidth + 1);
+        })
+        .slice(0, 12)
+        .map((element) => ({
+          tag: element.tagName.toLowerCase(),
+          className: typeof element.className === "string" ? element.className : "",
+          left: Math.round(element.getBoundingClientRect().left),
+          right: Math.round(element.getBoundingClientRect().right),
+          width: Math.round(element.getBoundingClientRect().width),
+        }));
+
+      const main = document.querySelector("main");
+      const rect = main?.getBoundingClientRect();
+
+      return {
+        viewportWidth,
+        documentScrollWidth: document.documentElement.scrollWidth,
+        bodyScrollWidth: document.body.scrollWidth,
+        main: rect
+          ? { left: Math.round(rect.left), right: Math.round(rect.right), width: Math.round(rect.width) }
+          : null,
+        overflow,
+      };
+    });
+
+    console.log("mobile layout metrics:", JSON.stringify(metrics));
+    expect(metrics.documentScrollWidth, JSON.stringify(metrics, null, 2)).toBeLessThanOrEqual(metrics.viewportWidth + 1);
+    expect(metrics.overflow, JSON.stringify(metrics, null, 2)).toEqual([]);
+    expect(metrics.main, "main content should render").not.toBeNull();
+    expect(metrics.main!.width, JSON.stringify(metrics, null, 2)).toBeGreaterThanOrEqual(metrics.viewportWidth - 2);
+  }
+});
diff --git a/frontend/apps/artcraft/playwright.mobile.config.ts b/frontend/apps/artcraft/playwright.mobile.config.ts
new file mode 100644
--- /dev/null
+++ b/frontend/apps/artcraft/playwright.mobile.config.ts
@@ -0,0 +1,18 @@
+import { defineConfig } from "@playwright/test";
+
+export default defineConfig({
+  testDir: "./e2e",
+  testMatch: "**/mobile-layout.spec.ts",
+  timeout: 30_000,
+  use: {
+    baseURL: "http://127.0.0.1:4173",
+    viewport: { width: 390, height: 844 },
+    trace: "retain-on-failure",
+  },
+  webServer: {
+    command: "npx vite --host 127.0.0.1 --port 4173 --strictPort",
+    url: "http://127.0.0.1:4173",
+    timeout: 120_000,
+    reuseExistingServer: !process.env.CI,
+  },
+});
