diff --git a/apps/desktop/src/routes/(window-chrome)/new-main/index.tsx b/apps/desktop/src/routes/(window-chrome)/new-main/index.tsx
index 4f2860cb89..89b80c5cb2 100644
--- a/apps/desktop/src/routes/(window-chrome)/new-main/index.tsx
+++ b/apps/desktop/src/routes/(window-chrome)/new-main/index.tsx
@@ -1597,36 +1597,42 @@ function createUpdateReadyToast() {
createTauriEventListener(events.updateReady, (update) => {
toast.custom(
(t) => (
-
+ // The main window is only 330px wide, so the toast must fit inside it
+ // (never exceed the viewport) and stack its actions below the message
+ // rather than racing them on one line — otherwise the card overflows
+ // the window edge and gets clipped.
+
{update.installed
? `Cap ${update.version} has been installed — restart to apply`
: `Cap ${update.version} is ready to install`}
-
{
- toast.dismiss(t.id);
- const install = update.installed
- ? Promise.resolve(null)
- : commands.updatesDownloadAndInstall();
- // On Windows the NSIS installer restarts Cap itself, so the
- // relaunch call is unreachable there; that matches update.tsx.
- install
- .then(() => relaunch())
- .catch((e) => console.error("Failed to install update:", e));
- }}
- >
- {update.installed ? "Restart now" : "Install and restart"}
-
-
toast.dismiss(t.id)}
- >
- Dismiss
-
+
+ {
+ toast.dismiss(t.id);
+ const install = update.installed
+ ? Promise.resolve(null)
+ : commands.updatesDownloadAndInstall();
+ // On Windows the NSIS installer restarts Cap itself, so the
+ // relaunch call is unreachable there; that matches update.tsx.
+ install
+ .then(() => relaunch())
+ .catch((e) => console.error("Failed to install update:", e));
+ }}
+ >
+ {update.installed ? "Restart now" : "Install and restart"}
+
+ toast.dismiss(t.id)}
+ >
+ Dismiss
+
+
),
{