From 707054b70f3701c2c3ef7ecb99748cea65212481 Mon Sep 17 00:00:00 2001
From: AnrokX <192667251+AnrokX@users.noreply.github.com>
Date: Thu, 12 Mar 2026 12:18:51 -0600
Subject: [PATCH 01/16] fix: remove max-width cap on dashboard so it fills
ultrawide screens
The dashboard-wrapper had max-width: 1800px with margin: 0 auto,
causing large gaps on both sides of ultrawide displays.
---
client/styles.css | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/client/styles.css b/client/styles.css
index 7ba0e134..1f4c9df4 100644
--- a/client/styles.css
+++ b/client/styles.css
@@ -14478,8 +14478,8 @@ body.dependency-onboarding-active #dependency-setup-modal {
/* Dashboard Layout */
.dashboard-wrapper {
- max-width: 1800px;
- margin: 0 auto;
+ max-width: none;
+ margin: 0;
padding: 0 var(--space-lg) var(--space-lg);
display: flex;
flex-direction: column;
From 9b812c0055d1e17c8da8fda804a148ac03e50c26 Mon Sep 17 00:00:00 2001
From: AnrokX <192667251+AnrokX@users.noreply.github.com>
Date: Thu, 12 Mar 2026 12:22:06 -0600
Subject: [PATCH 02/16] fix: make dashboard components adapt to viewport with
no scrolling
- Remove overflow-y: auto from left and right content columns
- Make bento sections and workspace grid flexible/shrinkable
- Right sidebar shrinks from 420px down to 200px on smaller screens
- Workspace cards use min() to shrink below 260px when needed
- Running services grid no longer scrolls independently
- Responsive breakpoints keep two-column layout longer
---
client/styles.css | 34 ++++++++++++++++++++++++++--------
1 file changed, 26 insertions(+), 8 deletions(-)
diff --git a/client/styles.css b/client/styles.css
index 1f4c9df4..0e21a6f2 100644
--- a/client/styles.css
+++ b/client/styles.css
@@ -14497,7 +14497,7 @@ body.dependency-onboarding-active #dependency-setup-modal {
.dashboard-main-content {
display: grid;
- grid-template-columns: minmax(0, 1fr) 420px;
+ grid-template-columns: minmax(0, 1fr) minmax(200px, 420px);
gap: var(--space-lg);
flex: 1;
min-height: 0;
@@ -14509,8 +14509,8 @@ body.dependency-onboarding-active #dependency-setup-modal {
flex-direction: column;
gap: var(--space-md);
height: 100%;
- overflow-y: auto;
- scrollbar-width: thin;
+ min-height: 0;
+ overflow: hidden;
}
.dashboard-content-right {
@@ -14518,8 +14518,8 @@ body.dependency-onboarding-active #dependency-setup-modal {
flex-direction: column;
gap: var(--space-md);
height: 100%;
- overflow-y: auto;
- scrollbar-width: thin;
+ min-height: 0;
+ overflow: hidden;
}
/* Create Workspace Banner */
@@ -14577,7 +14577,7 @@ body.dependency-onboarding-active #dependency-setup-modal {
/* Workspace Grid */
.bento-workspace-grid {
display: grid;
- grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
+ grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
gap: var(--space-md);
}
@@ -14678,8 +14678,8 @@ body.dependency-onboarding-active #dependency-setup-modal {
flex-direction: column;
gap: var(--space-sm);
flex: 1;
- overflow-y: auto;
- scrollbar-width: thin;
+ min-height: 0;
+ overflow: hidden;
}
.port-dashboard-card {
@@ -14741,8 +14741,26 @@ body.dependency-onboarding-active #dependency-setup-modal {
border: 1px solid var(--border-color);
}
+.dashboard-bento-section {
+ min-height: 0;
+ overflow: hidden;
+ flex: 1;
+}
+
+.dashboard-bento-section .bento-workspace-grid {
+ min-height: 0;
+ overflow: hidden;
+}
+
@media (max-width: 1200px) {
+ .dashboard-main-content {
+ grid-template-columns: minmax(0, 1fr) minmax(160px, 280px);
+ }
+}
+
+@media (max-width: 768px) {
.dashboard-main-content {
grid-template-columns: 1fr;
+ grid-template-rows: 1fr auto;
}
}
From 7bc21cae27cb1d72068f26cb8a2ead14acafaf76 Mon Sep 17 00:00:00 2001
From: AnrokX <192667251+AnrokX@users.noreply.github.com>
Date: Thu, 12 Mar 2026 12:31:12 -0600
Subject: [PATCH 03/16] fix: make dashboard components shrink to fit viewport
instead of clipping
Apply proper CSS flex/grid shrinking chain so all dashboard sections
resize proportionally to fit the screen:
- Use flex: 1 1 0% (not flex: 1) so flex-basis starts at 0
- Add min-height: 0 at every nesting level to allow shrinking
- Use grid-auto-rows: minmax(0, 1fr) so grid rows shrink
- Remove overflow: hidden from structural containers (only on leaf cards)
- Make bento sections, workspace grid, and port cards all shrinkable
---
client/styles.css | 34 ++++++++++++++++++++--------------
1 file changed, 20 insertions(+), 14 deletions(-)
diff --git a/client/styles.css b/client/styles.css
index 0e21a6f2..00b485db 100644
--- a/client/styles.css
+++ b/client/styles.css
@@ -14499,27 +14499,22 @@ body.dependency-onboarding-active #dependency-setup-modal {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(200px, 420px);
gap: var(--space-lg);
- flex: 1;
+ flex: 1 1 0%;
min-height: 0;
- overflow: hidden;
}
.dashboard-content-left {
display: flex;
flex-direction: column;
gap: var(--space-md);
- height: 100%;
min-height: 0;
- overflow: hidden;
}
.dashboard-content-right {
display: flex;
flex-direction: column;
gap: var(--space-md);
- height: 100%;
min-height: 0;
- overflow: hidden;
}
/* Create Workspace Banner */
@@ -14532,8 +14527,9 @@ body.dependency-onboarding-active #dependency-setup-modal {
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 14px 16px;
- flex-shrink: 0;
+ flex-shrink: 1;
align-self: flex-start;
+ min-height: 0;
}
.dashboard-create-title {
@@ -14566,6 +14562,8 @@ body.dependency-onboarding-active #dependency-setup-modal {
padding: var(--space-md);
box-shadow: var(--shadow-soft);
transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
+ min-height: 0;
+ overflow: hidden;
}
.dashboard-bento-card:hover {
@@ -14578,7 +14576,9 @@ body.dependency-onboarding-active #dependency-setup-modal {
.bento-workspace-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
+ grid-auto-rows: minmax(0, 1fr);
gap: var(--space-md);
+ min-height: 0;
}
/* Workspace Cards */
@@ -14589,6 +14589,7 @@ body.dependency-onboarding-active #dependency-setup-modal {
overflow: hidden;
display: flex;
flex-direction: column;
+ min-height: 0;
transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
}
@@ -14619,7 +14620,9 @@ body.dependency-onboarding-active #dependency-setup-modal {
.bento-workspace-card .workspace-card-body {
padding: 4px 14px 10px 14px;
- flex: 1;
+ flex: 1 1 0%;
+ min-height: 0;
+ overflow: hidden;
}
.bento-workspace-card .workspace-info h3 {
@@ -14669,7 +14672,7 @@ body.dependency-onboarding-active #dependency-setup-modal {
/* Running Services - bigger container */
.ports-dashboard-section {
- flex: 1;
+ flex: 1 1 0%;
min-height: 0;
}
@@ -14677,9 +14680,8 @@ body.dependency-onboarding-active #dependency-setup-modal {
display: flex;
flex-direction: column;
gap: var(--space-sm);
- flex: 1;
+ flex: 1 1 0%;
min-height: 0;
- overflow: hidden;
}
.port-dashboard-card {
@@ -14692,6 +14694,9 @@ body.dependency-onboarding-active #dependency-setup-modal {
border-left: 4px solid var(--border-color);
cursor: pointer;
transition: all 0.2s;
+ flex-shrink: 1;
+ min-height: 0;
+ overflow: hidden;
}
.port-dashboard-card:hover {
@@ -14742,14 +14747,15 @@ body.dependency-onboarding-active #dependency-setup-modal {
}
.dashboard-bento-section {
+ flex: 1 1 0%;
min-height: 0;
- overflow: hidden;
- flex: 1;
+ display: flex;
+ flex-direction: column;
}
.dashboard-bento-section .bento-workspace-grid {
+ flex: 1 1 0%;
min-height: 0;
- overflow: hidden;
}
@media (max-width: 1200px) {
From 884c7712bd21c6c69ddf8f00240c5abb561d00f1 Mon Sep 17 00:00:00 2001
From: AnrokX <192667251+AnrokX@users.noreply.github.com>
Date: Thu, 12 Mar 2026 12:36:25 -0600
Subject: [PATCH 04/16] fix: simplify dashboard responsive layout - zoom to
shrink on smaller screens
Revert the overcomplicated flex/grid shrinking approach. Instead:
- Restore original layout styles that work well at full size
- Use CSS zoom to scale down the entire dashboard on smaller screens
- 85% at <=1200px, 75% at <=900px, 60% at <=600px
- No clipping, no hidden content, everything just gets smaller
---
client/styles.css | 69 +++++++++++++++++++++--------------------------
1 file changed, 30 insertions(+), 39 deletions(-)
diff --git a/client/styles.css b/client/styles.css
index 00b485db..2bd4c7e8 100644
--- a/client/styles.css
+++ b/client/styles.css
@@ -14486,7 +14486,7 @@ body.dependency-onboarding-active #dependency-setup-modal {
color: #fff;
gap: var(--space-sm);
height: 100%;
- overflow: hidden;
+ overflow: auto;
}
.dashboard-header-modern {
@@ -14497,9 +14497,9 @@ body.dependency-onboarding-active #dependency-setup-modal {
.dashboard-main-content {
display: grid;
- grid-template-columns: minmax(0, 1fr) minmax(200px, 420px);
+ grid-template-columns: minmax(0, 1fr) 420px;
gap: var(--space-lg);
- flex: 1 1 0%;
+ flex: 1;
min-height: 0;
}
@@ -14507,14 +14507,18 @@ body.dependency-onboarding-active #dependency-setup-modal {
display: flex;
flex-direction: column;
gap: var(--space-md);
- min-height: 0;
+ height: 100%;
+ overflow-y: auto;
+ scrollbar-width: thin;
}
.dashboard-content-right {
display: flex;
flex-direction: column;
gap: var(--space-md);
- min-height: 0;
+ height: 100%;
+ overflow-y: auto;
+ scrollbar-width: thin;
}
/* Create Workspace Banner */
@@ -14527,9 +14531,8 @@ body.dependency-onboarding-active #dependency-setup-modal {
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 14px 16px;
- flex-shrink: 1;
+ flex-shrink: 0;
align-self: flex-start;
- min-height: 0;
}
.dashboard-create-title {
@@ -14562,8 +14565,6 @@ body.dependency-onboarding-active #dependency-setup-modal {
padding: var(--space-md);
box-shadow: var(--shadow-soft);
transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
- min-height: 0;
- overflow: hidden;
}
.dashboard-bento-card:hover {
@@ -14575,10 +14576,8 @@ body.dependency-onboarding-active #dependency-setup-modal {
/* Workspace Grid */
.bento-workspace-grid {
display: grid;
- grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
- grid-auto-rows: minmax(0, 1fr);
+ grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: var(--space-md);
- min-height: 0;
}
/* Workspace Cards */
@@ -14589,7 +14588,6 @@ body.dependency-onboarding-active #dependency-setup-modal {
overflow: hidden;
display: flex;
flex-direction: column;
- min-height: 0;
transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
}
@@ -14620,9 +14618,7 @@ body.dependency-onboarding-active #dependency-setup-modal {
.bento-workspace-card .workspace-card-body {
padding: 4px 14px 10px 14px;
- flex: 1 1 0%;
- min-height: 0;
- overflow: hidden;
+ flex: 1;
}
.bento-workspace-card .workspace-info h3 {
@@ -14672,7 +14668,7 @@ body.dependency-onboarding-active #dependency-setup-modal {
/* Running Services - bigger container */
.ports-dashboard-section {
- flex: 1 1 0%;
+ flex: 1;
min-height: 0;
}
@@ -14680,8 +14676,9 @@ body.dependency-onboarding-active #dependency-setup-modal {
display: flex;
flex-direction: column;
gap: var(--space-sm);
- flex: 1 1 0%;
- min-height: 0;
+ flex: 1;
+ overflow-y: auto;
+ scrollbar-width: thin;
}
.port-dashboard-card {
@@ -14694,9 +14691,6 @@ body.dependency-onboarding-active #dependency-setup-modal {
border-left: 4px solid var(--border-color);
cursor: pointer;
transition: all 0.2s;
- flex-shrink: 1;
- min-height: 0;
- overflow: hidden;
}
.port-dashboard-card:hover {
@@ -14746,27 +14740,24 @@ body.dependency-onboarding-active #dependency-setup-modal {
border: 1px solid var(--border-color);
}
-.dashboard-bento-section {
- flex: 1 1 0%;
- min-height: 0;
- display: flex;
- flex-direction: column;
-}
-
-.dashboard-bento-section .bento-workspace-grid {
- flex: 1 1 0%;
- min-height: 0;
-}
-
+/* Scale down dashboard on smaller screens */
@media (max-width: 1200px) {
.dashboard-main-content {
- grid-template-columns: minmax(0, 1fr) minmax(160px, 280px);
+ grid-template-columns: 1fr;
+ }
+ .dashboard-wrapper {
+ zoom: 0.85;
}
}
-@media (max-width: 768px) {
- .dashboard-main-content {
- grid-template-columns: 1fr;
- grid-template-rows: 1fr auto;
+@media (max-width: 900px) {
+ .dashboard-wrapper {
+ zoom: 0.75;
+ }
+}
+
+@media (max-width: 600px) {
+ .dashboard-wrapper {
+ zoom: 0.6;
}
}
From 745c4685fe4bd9303ae4a238cde34a3eac2d032d Mon Sep 17 00:00:00 2001
From: AnrokX <192667251+AnrokX@users.noreply.github.com>
Date: Thu, 12 Mar 2026 12:50:57 -0600
Subject: [PATCH 05/16] fix: improve dashboard modal responsiveness
---
client/styles.css | 86 +++++++++++++++++++++++++++++++----------------
1 file changed, 57 insertions(+), 29 deletions(-)
diff --git a/client/styles.css b/client/styles.css
index 2bd4c7e8..40a02580 100644
--- a/client/styles.css
+++ b/client/styles.css
@@ -7681,8 +7681,10 @@ body.dependency-onboarding-active #dependency-setup-modal {
bottom: 0;
background: var(--bg-primary);
z-index: 1000;
- padding: 2rem;
+ padding: clamp(0.75rem, 2vw, 2rem);
+ box-sizing: border-box;
overflow-y: auto;
+ overflow-x: hidden;
}
.dashboard-topbar {
@@ -14317,7 +14319,7 @@ body.dependency-onboarding-active #dependency-setup-modal {
.bento-grid {
display: grid;
- grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+ grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
gap: var(--space-md);
}
@@ -14478,15 +14480,16 @@ body.dependency-onboarding-active #dependency-setup-modal {
/* Dashboard Layout */
.dashboard-wrapper {
- max-width: none;
- margin: 0;
- padding: 0 var(--space-lg) var(--space-lg);
+ width: 100%;
+ max-width: 1520px;
+ margin: 0 auto;
+ padding: 0 0 var(--space-lg);
+ box-sizing: border-box;
display: flex;
flex-direction: column;
color: #fff;
- gap: var(--space-sm);
- height: 100%;
- overflow: auto;
+ gap: var(--space-md);
+ min-height: 100%;
}
.dashboard-header-modern {
@@ -14497,28 +14500,23 @@ body.dependency-onboarding-active #dependency-setup-modal {
.dashboard-main-content {
display: grid;
- grid-template-columns: minmax(0, 1fr) 420px;
+ grid-template-columns: minmax(0, 1fr) minmax(320px, 420px);
gap: var(--space-lg);
- flex: 1;
- min-height: 0;
+ align-items: start;
}
.dashboard-content-left {
display: flex;
flex-direction: column;
gap: var(--space-md);
- height: 100%;
- overflow-y: auto;
- scrollbar-width: thin;
+ min-width: 0;
}
.dashboard-content-right {
display: flex;
flex-direction: column;
gap: var(--space-md);
- height: 100%;
- overflow-y: auto;
- scrollbar-width: thin;
+ min-width: 0;
}
/* Create Workspace Banner */
@@ -14576,7 +14574,7 @@ body.dependency-onboarding-active #dependency-setup-modal {
/* Workspace Grid */
.bento-workspace-grid {
display: grid;
- grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
+ grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
gap: var(--space-md);
}
@@ -14676,9 +14674,6 @@ body.dependency-onboarding-active #dependency-setup-modal {
display: flex;
flex-direction: column;
gap: var(--space-sm);
- flex: 1;
- overflow-y: auto;
- scrollbar-width: thin;
}
.port-dashboard-card {
@@ -14740,24 +14735,57 @@ body.dependency-onboarding-active #dependency-setup-modal {
border: 1px solid var(--border-color);
}
-/* Scale down dashboard on smaller screens */
+/* Reflow dashboard on smaller screens instead of shrinking everything */
@media (max-width: 1200px) {
.dashboard-main-content {
- grid-template-columns: 1fr;
- }
- .dashboard-wrapper {
- zoom: 0.85;
+ grid-template-columns: minmax(0, 1fr);
}
}
@media (max-width: 900px) {
- .dashboard-wrapper {
- zoom: 0.75;
+ .dashboard-title-group {
+ align-items: flex-start;
+ }
+
+ .dashboard-title-group h1 {
+ font-size: 1.4rem;
+ }
+
+ .dashboard-topbar {
+ flex-wrap: wrap;
+ align-items: flex-start;
}
}
@media (max-width: 600px) {
.dashboard-wrapper {
- zoom: 0.6;
+ padding-bottom: var(--space-md);
+ }
+
+ .dashboard-title-group {
+ gap: var(--space-sm);
+ }
+
+ .dashboard-title-icon {
+ width: 40px;
+ height: 40px;
+ }
+
+ .dashboard-title-group h1 {
+ font-size: 1.25rem;
+ }
+
+ .dashboard-title-group p {
+ font-size: 0.9rem;
+ }
+
+ .bento-grid,
+ .bento-workspace-grid,
+ .workspace-grid {
+ grid-template-columns: minmax(0, 1fr);
+ }
+
+ .dashboard-wrapper {
+ gap: var(--space-sm);
}
}
From a0263fd4db876614496dff52ba5bc50b07087f04 Mon Sep 17 00:00:00 2001
From: AnrokX <192667251+AnrokX@users.noreply.github.com>
Date: Thu, 12 Mar 2026 13:21:29 -0600
Subject: [PATCH 06/16] fix: make dashboard adapt without overflow
---
client/dashboard.js | 177 +++++++++++++++++++++------
client/styles.css | 289 ++++++++++++++++++++++++++++++++++++++------
2 files changed, 393 insertions(+), 73 deletions(-)
diff --git a/client/dashboard.js b/client/dashboard.js
index 5f21d6c5..7258796f 100644
--- a/client/dashboard.js
+++ b/client/dashboard.js
@@ -9,6 +9,9 @@ class Dashboard {
this.quickLinks = null;
this._escHandler = null;
this._projectLaunchInFlight = false;
+ this._resizeHandler = null;
+ this._layoutMode = 'desktop';
+ this.compactTab = 'workspaces';
}
async show() {
@@ -64,6 +67,16 @@ class Dashboard {
document.removeEventListener('keydown', this._escHandler);
this._escHandler = null;
}
+
+ if (this._resizeHandler) {
+ window.removeEventListener('resize', this._resizeHandler);
+ this._resizeHandler = null;
+ }
+ }
+
+ getLayoutMode() {
+ if (typeof window === 'undefined') return 'desktop';
+ return window.innerWidth <= 1100 ? 'compact' : 'desktop';
}
render() {
@@ -112,11 +125,18 @@ class Dashboard {
const bTime = b.lastAccess ? new Date(b.lastAccess).getTime() : 0;
return bTime - aTime;
};
+ const escapeHtml = (value) => String(value ?? '')
+ .replace(/&/g, '&')
+ .replace(//g, '>');
const activeWorkspaces = this.workspaces.filter(ws => this.isWorkspaceActive(ws)).sort(sortByLastAccess);
const inactiveWorkspaces = this.workspaces.filter(ws => !this.isWorkspaceActive(ws)).sort(sortByLastAccess);
const canReturnToWorkspaces = !!(this.orchestrator.tabManager?.tabs?.size);
const visibility = this.orchestrator.getUiVisibilityConfig()?.dashboard || {};
const showProcessBanner = visibility.processBanner !== false;
+ const layoutMode = this.getLayoutMode();
+ const isCompactLayout = layoutMode === 'compact';
+ this._layoutMode = layoutMode;
// SVG Icons replacing Emojis
const svgIcon = (path, cls="dashboard-svg-icon") => ``;
@@ -254,18 +274,6 @@ class Dashboard {
` : '';
- const createSection = (visibility.createSection !== false) ? `
-
-
-
✨ Get Started
-
Set up a new workspace environment to begin building.
-
-
-
- ` : '';
-
const quickLinksSection = (visibility.quickLinks !== false) ? `
` : '';
- const activeSection = (visibility.workspacesActive !== false && activeWorkspaces.length > 0) ? `
-
-
Active Workspaces
-
- ${activeWorkspaces.map(ws => this.generateWorkspaceCard(ws, true)).join('')}
+ const workspaceCards = [];
+ if (visibility.createSection !== false) {
+ workspaceCards.push(this.generateCreateWorkspaceCard(), this.generateCreateProjectCard());
+ }
+ if (visibility.workspacesActive !== false) {
+ workspaceCards.push(...activeWorkspaces.map((ws) => this.generateWorkspaceCard(ws, true)));
+ }
+ if (visibility.workspacesAll !== false) {
+ workspaceCards.push(...inactiveWorkspaces.map((ws) => this.generateWorkspaceCard(ws, false)));
+ }
+
+ const workspaceMeta = [
+ visibility.workspacesActive !== false ? `${activeWorkspaces.length} active` : '',
+ visibility.workspacesAll !== false ? `${inactiveWorkspaces.length} more` : ''
+ ].filter(Boolean).join(' • ');
+
+ const workspaceSection = workspaceCards.length ? `
+
+
+ Workspaces
+ ${workspaceMeta ? `${escapeHtml(workspaceMeta)}` : ''}
+
+
+ ${workspaceCards.join('')}
` : '';
- const allSection = (visibility.workspacesAll !== false) ? `
-
-
All Workspaces
-
- ${inactiveWorkspaces.map(ws => this.generateWorkspaceCard(ws, false)).join('')}
+ const resourcesSection = [quickLinksSection, runningServicesSection].filter(Boolean).join('');
+
+ const compactTabs = [
+ workspaceSection ? { id: 'workspaces', label: 'Workspaces', content: workspaceSection } : null,
+ processSection ? { id: 'process', label: 'Process', content: processSection } : null,
+ resourcesSection ? { id: 'resources', label: 'Resources', content: resourcesSection } : null
+ ].filter(Boolean);
+
+ if (!compactTabs.some((tab) => tab.id === this.compactTab)) {
+ this.compactTab = compactTabs[0]?.id || 'workspaces';
+ }
+
+ const desktopTopSection = processSection && resourcesSection
+ ? `
+
+
+ ${processSection}
+
+
+ ${resourcesSection}
+
+
+ `
+ : (processSection || resourcesSection);
+
+ const desktopLayout = `
+ ${desktopTopSection}
+ ${workspaceSection}
+ `;
+
+ const compactLayout = `
+
+
+ ${compactTabs.map((tab) => `
+
+ `).join('')}
+
+
+ ${compactTabs.map((tab) => `
+
+ `).join('')}
- ` : '';
+ `;
return `
-
+
${canReturnToWorkspaces ? `
` : '
'}
${showProcessBanner ? `
` : '
'}
@@ -323,18 +400,7 @@ class Dashboard {
-
-
- ${createSection}
- ${processSection}
- ${activeSection}
- ${allSection}
-
-
- ${quickLinksSection}
- ${runningServicesSection}
-
-
+ ${isCompactLayout ? compactLayout : desktopLayout}
`;
}
@@ -3644,6 +3710,45 @@ class Dashboard {
});
});
+ document.querySelectorAll('.workspace-create-btn').forEach((btn) => {
+ btn.addEventListener('click', () => {
+ this.showCreateWorkspaceWizard();
+ });
+ });
+
+ document.querySelectorAll('.workspace-import-btn').forEach((btn) => {
+ btn.addEventListener('click', () => {
+ this.importWorkspaceFromFile();
+ });
+ });
+
+ document.querySelectorAll('.workspace-create-project-btn').forEach((btn) => {
+ btn.addEventListener('click', () => {
+ this.showCreateProjectWizard();
+ });
+ });
+
+ document.querySelectorAll('[data-dashboard-tab]').forEach((btn) => {
+ btn.addEventListener('click', () => {
+ const nextTab = String(btn.dataset.dashboardTab || '').trim();
+ if (!nextTab || nextTab === this.compactTab) return;
+ this.compactTab = nextTab;
+ this.render();
+ });
+ });
+
+ if (this._resizeHandler) {
+ window.removeEventListener('resize', this._resizeHandler);
+ }
+ this._resizeHandler = () => {
+ if (!this.isVisible) return;
+ const nextLayoutMode = this.getLayoutMode();
+ if (nextLayoutMode !== this._layoutMode) {
+ this.render();
+ }
+ };
+ window.addEventListener('resize', this._resizeHandler);
+
// ESC: return to tabbed workspaces if dashboard was opened from there
if (this._escHandler) {
document.removeEventListener('keydown', this._escHandler);
diff --git a/client/styles.css b/client/styles.css
index 40a02580..a93c904b 100644
--- a/client/styles.css
+++ b/client/styles.css
@@ -7681,10 +7681,9 @@ body.dependency-onboarding-active #dependency-setup-modal {
bottom: 0;
background: var(--bg-primary);
z-index: 1000;
- padding: clamp(0.75rem, 2vw, 2rem);
+ padding: 0;
box-sizing: border-box;
- overflow-y: auto;
- overflow-x: hidden;
+ overflow: hidden;
}
.dashboard-topbar {
@@ -14314,15 +14313,30 @@ body.dependency-onboarding-active #dependency-setup-modal {
color: var(--text-primary);
display: flex;
align-items: center;
+ justify-content: space-between;
gap: 8px;
+ flex-wrap: wrap;
+}
+
+.dashboard-section-meta {
+ font-size: 0.82rem;
+ font-weight: 500;
+ color: var(--text-primary);
+ opacity: 0.65;
}
.bento-grid {
display: grid;
- grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
+ grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
gap: var(--space-md);
}
+.dashboard-bento-section {
+ display: grid;
+ gap: var(--space-sm);
+ min-width: 0;
+}
+
.dashboard-bento-header {
display: flex;
align-items: center;
@@ -14481,44 +14495,58 @@ body.dependency-onboarding-active #dependency-setup-modal {
/* Dashboard Layout */
.dashboard-wrapper {
width: 100%;
- max-width: 1520px;
- margin: 0 auto;
- padding: 0 0 var(--space-lg);
+ margin: 0;
+ padding: clamp(0.75rem, 1.4vw, 1.5rem);
box-sizing: border-box;
- display: flex;
- flex-direction: column;
- color: #fff;
+ display: grid;
+ grid-template-rows: auto auto 1fr;
+ color: var(--text-primary);
gap: var(--space-md);
- min-height: 100%;
+ height: 100%;
+ min-height: 0;
+ overflow: hidden;
}
.dashboard-header-modern {
padding: var(--space-sm) 0 0 0;
margin-bottom: 0;
- flex-shrink: 0;
+ min-width: 0;
}
.dashboard-main-content {
display: grid;
- grid-template-columns: minmax(0, 1fr) minmax(320px, 420px);
- gap: var(--space-lg);
+ grid-template-columns: minmax(0, 1.45fr) minmax(24rem, 1.05fr);
+ gap: var(--space-md);
align-items: start;
+ min-height: 0;
}
.dashboard-content-left {
- display: flex;
- flex-direction: column;
+ display: grid;
gap: var(--space-md);
min-width: 0;
+ align-content: start;
+ min-height: 0;
}
.dashboard-content-right {
- display: flex;
- flex-direction: column;
+ display: grid;
+ gap: var(--space-md);
+ min-width: 0;
+ align-content: start;
+ min-height: 0;
+}
+
+.dashboard-resource-stack {
+ display: grid;
gap: var(--space-md);
min-width: 0;
}
+.dashboard-workspaces-grid {
+ grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
+}
+
/* Create Workspace Banner */
.dashboard-create-banner {
display: flex;
@@ -14563,6 +14591,8 @@ body.dependency-onboarding-active #dependency-setup-modal {
padding: var(--space-md);
box-shadow: var(--shadow-soft);
transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
+ min-width: 0;
+ min-height: 0;
}
.dashboard-bento-card:hover {
@@ -14574,7 +14604,7 @@ body.dependency-onboarding-active #dependency-setup-modal {
/* Workspace Grid */
.bento-workspace-grid {
display: grid;
- grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
+ grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
gap: var(--space-md);
}
@@ -14671,14 +14701,14 @@ body.dependency-onboarding-active #dependency-setup-modal {
}
.ports-dashboard-grid {
- display: flex;
- flex-direction: column;
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
gap: var(--space-sm);
}
.port-dashboard-card {
display: flex;
- align-items: center;
+ align-items: flex-start;
gap: var(--space-sm);
padding: 10px 12px;
background: var(--bg-tertiary);
@@ -14733,16 +14763,183 @@ body.dependency-onboarding-active #dependency-setup-modal {
border-radius: 6px;
color: var(--text-primary);
border: 1px solid var(--border-color);
+ margin-left: auto;
}
-/* Reflow dashboard on smaller screens instead of shrinking everything */
-@media (max-width: 1200px) {
- .dashboard-main-content {
- grid-template-columns: minmax(0, 1fr);
- }
+.dashboard-quick-links .quick-links-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(min(132px, 100%), 1fr));
+ gap: var(--space-sm);
}
-@media (max-width: 900px) {
+.dashboard-quick-links > .quick-links-grid {
+ display: block;
+}
+
+.dashboard-quick-links .quick-links-container {
+ gap: 0.65rem;
+}
+
+.dashboard-quick-links .quick-links-section {
+ display: grid;
+ gap: 0.45rem;
+}
+
+.dashboard-quick-links .quick-links-section h3 {
+ margin: 0;
+ font-size: 0.8rem;
+ color: var(--text-primary);
+ opacity: 0.7;
+}
+
+.dashboard-quick-links .quick-links-section .quick-links-grid {
+ grid-template-columns: repeat(auto-fit, minmax(min(132px, 100%), 1fr));
+ gap: 0.45rem;
+}
+
+.dashboard-quick-links .bento-quick-link {
+ width: 100%;
+ min-width: 0;
+ padding: 0.6rem 0.7rem !important;
+ font-size: 0.78rem;
+ gap: 0.45rem;
+}
+
+.dashboard-quick-links .quick-link-label {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.dashboard-compact-shell {
+ display: grid;
+ grid-template-rows: auto 1fr;
+ gap: var(--space-sm);
+ min-height: 0;
+}
+
+.dashboard-compact-tabs {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
+ gap: 8px;
+}
+
+.dashboard-compact-tab {
+ appearance: none;
+ border: 1px solid var(--border-color);
+ background: var(--bg-secondary);
+ color: var(--text-primary);
+ border-radius: 10px;
+ padding: 0.65rem 0.8rem;
+ font-size: 0.85rem;
+ font-weight: 600;
+ cursor: pointer;
+ transition: background 0.2s, border-color 0.2s, transform 0.2s;
+}
+
+.dashboard-compact-tab:hover {
+ border-color: var(--accent-primary);
+ background: var(--bg-hover);
+}
+
+.dashboard-compact-tab.is-active {
+ background: color-mix(in srgb, var(--accent-primary) 18%, var(--bg-secondary));
+ border-color: color-mix(in srgb, var(--accent-primary) 50%, var(--border-color));
+ color: var(--text-primary);
+}
+
+.dashboard-compact-panel-shell {
+ min-height: 0;
+}
+
+.dashboard-compact-panel {
+ display: none;
+ min-height: 0;
+}
+
+.dashboard-compact-panel.is-active {
+ display: grid;
+ gap: var(--space-md);
+}
+
+.dashboard-layout-compact .dashboard-bento-card {
+ padding: 12px;
+ border-radius: 12px;
+}
+
+.dashboard-layout-compact .dashboard-bento-header {
+ margin-bottom: 8px;
+ font-size: 0.98rem;
+}
+
+.dashboard-layout-compact .dashboard-bento-body {
+ font-size: 0.84rem;
+ margin-bottom: 8px;
+}
+
+.dashboard-layout-compact .dashboard-bento-actions {
+ gap: 5px;
+}
+
+.dashboard-layout-compact .bento-btn,
+.dashboard-layout-compact .bento-checkbox-label {
+ padding: 5px 8px;
+ font-size: 0.74rem;
+}
+
+.dashboard-layout-compact .bento-workspace-grid {
+ grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr));
+ gap: 10px;
+}
+
+.dashboard-layout-compact .bento-workspace-icon {
+ width: 34px;
+ height: 34px;
+ font-size: 17px;
+}
+
+.dashboard-layout-compact .bento-workspace-card .workspace-card-header {
+ padding: 10px 12px 2px;
+ gap: 10px;
+}
+
+.dashboard-layout-compact .bento-workspace-card .workspace-card-body {
+ padding: 2px 12px 8px;
+}
+
+.dashboard-layout-compact .bento-workspace-card .workspace-info h3 {
+ font-size: 0.92rem;
+}
+
+.dashboard-layout-compact .bento-workspace-card .workspace-type,
+.dashboard-layout-compact .bento-workspace-card .last-used {
+ font-size: 0.68rem;
+}
+
+.dashboard-layout-compact .bento-card-footer {
+ padding: 8px 12px;
+}
+
+.dashboard-layout-compact .workspace-card-footer .btn-primary,
+.dashboard-layout-compact .workspace-card-footer .btn-secondary,
+.dashboard-layout-compact .btn-cta-empty,
+.dashboard-layout-compact .bento-btn-primary {
+ padding: 0.4rem 0.55rem;
+ font-size: 0.72rem;
+}
+
+.dashboard-layout-compact .btn-icon,
+.dashboard-layout-compact .bento-action-group .btn-icon {
+ width: 26px;
+ height: 26px;
+ font-size: 12px;
+}
+
+@media (max-width: 1100px) {
+ .dashboard-wrapper {
+ gap: var(--space-sm);
+ }
+
.dashboard-title-group {
align-items: flex-start;
}
@@ -14758,10 +14955,6 @@ body.dependency-onboarding-active #dependency-setup-modal {
}
@media (max-width: 600px) {
- .dashboard-wrapper {
- padding-bottom: var(--space-md);
- }
-
.dashboard-title-group {
gap: var(--space-sm);
}
@@ -14779,13 +14972,35 @@ body.dependency-onboarding-active #dependency-setup-modal {
font-size: 0.9rem;
}
- .bento-grid,
- .bento-workspace-grid,
- .workspace-grid {
- grid-template-columns: minmax(0, 1fr);
+ .dashboard-compact-tabs {
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ }
+
+ .dashboard-layout-compact .bento-grid,
+ .dashboard-layout-compact .bento-workspace-grid,
+ .dashboard-layout-compact .ports-dashboard-grid,
+ .dashboard-layout-compact .quick-links-grid {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ }
+
+ .dashboard-layout-compact .port-dashboard-card {
+ padding: 9px 10px;
}
+}
+@media (max-width: 460px) {
.dashboard-wrapper {
- gap: var(--space-sm);
+ padding: 0.7rem;
+ }
+
+ .dashboard-compact-tabs {
+ grid-template-columns: minmax(0, 1fr);
+ }
+
+ .dashboard-layout-compact .bento-grid,
+ .dashboard-layout-compact .bento-workspace-grid,
+ .dashboard-layout-compact .ports-dashboard-grid,
+ .dashboard-layout-compact .quick-links-grid {
+ grid-template-columns: minmax(0, 1fr);
}
}
From b4a0c9bf78e0af9da29fc5127bbff4dfa17df466 Mon Sep 17 00:00:00 2001
From: AnrokX <192667251+AnrokX@users.noreply.github.com>
Date: Thu, 12 Mar 2026 13:27:46 -0600
Subject: [PATCH 07/16] fix: align dashboard workspace and resource columns
---
client/dashboard.js | 26 +++++++++--------
client/styles.css | 69 +++++++++++++++++++++++++++++++++++++++++----
2 files changed, 79 insertions(+), 16 deletions(-)
diff --git a/client/dashboard.js b/client/dashboard.js
index 7258796f..1659c89f 100644
--- a/client/dashboard.js
+++ b/client/dashboard.js
@@ -324,7 +324,8 @@ class Dashboard {
` : '';
- const resourcesSection = [quickLinksSection, runningServicesSection].filter(Boolean).join('');
+ const resourcesCards = [quickLinksSection, runningServicesSection].filter(Boolean);
+ const resourcesSection = resourcesCards.join('');
const compactTabs = [
workspaceSection ? { id: 'workspaces', label: 'Workspaces', content: workspaceSection } : null,
@@ -336,23 +337,26 @@ class Dashboard {
this.compactTab = compactTabs[0]?.id || 'workspaces';
}
- const desktopTopSection = processSection && resourcesSection
+ const desktopResourcesGrid = resourcesCards.length
+ ? `
+
+ ${resourcesCards.join('')}
+
+ `
+ : '';
+ const desktopResourceStack = [processSection, desktopResourcesGrid].filter(Boolean).join('');
+ const desktopLayout = (workspaceSection && desktopResourceStack)
? `
- ${processSection}
+ ${workspaceSection}
-
- ${resourcesSection}
+
+ ${desktopResourceStack}
`
- : (processSection || resourcesSection);
-
- const desktopLayout = `
- ${desktopTopSection}
- ${workspaceSection}
- `;
+ : (workspaceSection || desktopResourceStack);
const compactLayout = `
diff --git a/client/styles.css b/client/styles.css
index a93c904b..44fd825e 100644
--- a/client/styles.css
+++ b/client/styles.css
@@ -14515,7 +14515,7 @@ body.dependency-onboarding-active #dependency-setup-modal {
.dashboard-main-content {
display: grid;
- grid-template-columns: minmax(0, 1.45fr) minmax(24rem, 1.05fr);
+ grid-template-columns: minmax(0, 1.7fr) minmax(25rem, 1fr);
gap: var(--space-md);
align-items: start;
min-height: 0;
@@ -14539,12 +14539,20 @@ body.dependency-onboarding-active #dependency-setup-modal {
.dashboard-resource-stack {
display: grid;
- gap: var(--space-md);
+ gap: 0.8rem;
+ min-width: 0;
+}
+
+.dashboard-resource-cards {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
+ gap: 0.75rem;
min-width: 0;
+ align-items: start;
}
.dashboard-workspaces-grid {
- grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
+ grid-template-columns: repeat(auto-fit, minmax(min(185px, 100%), 1fr));
}
/* Create Workspace Banner */
@@ -14768,7 +14776,7 @@ body.dependency-onboarding-active #dependency-setup-modal {
.dashboard-quick-links .quick-links-grid {
display: grid;
- grid-template-columns: repeat(auto-fit, minmax(min(132px, 100%), 1fr));
+ grid-template-columns: repeat(auto-fit, minmax(min(124px, 100%), 1fr));
gap: var(--space-sm);
}
@@ -14793,7 +14801,7 @@ body.dependency-onboarding-active #dependency-setup-modal {
}
.dashboard-quick-links .quick-links-section .quick-links-grid {
- grid-template-columns: repeat(auto-fit, minmax(min(132px, 100%), 1fr));
+ grid-template-columns: repeat(auto-fit, minmax(min(124px, 100%), 1fr));
gap: 0.45rem;
}
@@ -14862,6 +14870,57 @@ body.dependency-onboarding-active #dependency-setup-modal {
gap: var(--space-md);
}
+.dashboard-layout-desktop .dashboard-content-right .dashboard-bento-section {
+ gap: 0.55rem;
+}
+
+.dashboard-layout-desktop .dashboard-content-right .dashboard-section-title {
+ font-size: 1rem;
+ margin-bottom: 0;
+}
+
+.dashboard-layout-desktop .dashboard-content-right .bento-grid {
+ grid-template-columns: repeat(auto-fit, minmax(min(170px, 100%), 1fr));
+ gap: 0.75rem;
+}
+
+.dashboard-layout-desktop .dashboard-content-right .dashboard-bento-card {
+ padding: 12px;
+ border-radius: 12px;
+}
+
+.dashboard-layout-desktop .dashboard-resource-cards .dashboard-bento-card {
+ height: 100%;
+}
+
+.dashboard-layout-desktop .dashboard-content-right .dashboard-bento-header {
+ margin-bottom: 8px;
+ font-size: 0.98rem;
+}
+
+.dashboard-layout-desktop .dashboard-content-right .dashboard-bento-body {
+ font-size: 0.84rem;
+ margin-bottom: 8px;
+}
+
+.dashboard-layout-desktop .dashboard-content-right .dashboard-bento-actions {
+ gap: 5px;
+}
+
+.dashboard-layout-desktop .dashboard-content-right .bento-btn,
+.dashboard-layout-desktop .dashboard-content-right .bento-checkbox-label {
+ padding: 5px 8px;
+ font-size: 0.74rem;
+}
+
+.dashboard-layout-desktop .dashboard-content-right .ports-dashboard-grid {
+ grid-template-columns: repeat(auto-fit, minmax(min(170px, 100%), 1fr));
+}
+
+.dashboard-layout-desktop .dashboard-content-right .port-dashboard-card {
+ padding: 9px 10px;
+}
+
.dashboard-layout-compact .dashboard-bento-card {
padding: 12px;
border-radius: 12px;
From 24a8ea52653cc737650e576f0bba2bf583dba04b Mon Sep 17 00:00:00 2001
From: AnrokX <192667251+AnrokX@users.noreply.github.com>
Date: Thu, 12 Mar 2026 13:31:48 -0600
Subject: [PATCH 08/16] fix: restore previous dashboard create visibility
---
client/dashboard.js | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/client/dashboard.js b/client/dashboard.js
index 1659c89f..b45b9947 100644
--- a/client/dashboard.js
+++ b/client/dashboard.js
@@ -274,6 +274,18 @@ class Dashboard {
` : '';
+ const createSection = (visibility.createSection !== false) ? `
+
+
+
✨ Get Started
+
Set up a new workspace environment to begin building.
+
+
+
+ ` : '';
+
const quickLinksSection = (visibility.quickLinks !== false) ? `