From f463ff64de4893c3e25316151a6d0ed0948c86cf Mon Sep 17 00:00:00 2001 From: root Date: Sun, 10 May 2026 07:14:50 +0000 Subject: [PATCH] fix(web): global layout fixes for overlap, clipping, responsive reflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds web/src/layout-fixes.css imported once from main.tsx — surgical overrides applied with !important so they win against the existing 3000+ line index.css without rewriting it. Issues fixed: 1. Modals/popovers/dropdowns clipped by .dashboard-main { overflow: hidden } → now overflow: visible. Stacking context guard for [role=dialog]. 2. Right panel (308px fixed) covers main content on laptop/tablet → 260px below 1280px, hidden below 1024px. 3. Tables extending off-screen → .dashboard-content table wrapped with display:block + overflow-x:auto so they scroll inside their column. Also exposes .scroll-x utility. 4. Header search/indices push each other off-screen → flex-wrap on .trading-header, search shrinks to 240–360px range, indices wrap with smaller column gap on narrow. 5. Long unbreakable strings (commit SHAs, URLs) escaping containers → overflow-wrap: anywhere + word-break: break-word + pre-wrap on
.
6. Sidebar 76px doesn't collapse on mobile
   → 56px below 768px with reduced content padding.

Bumps @bytelyst/devops to ^0.1.3 (responsive panel) in backend + web.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---
 backend/package.json     |   2 +-
 web/package.json         |   2 +-
 web/src/layout-fixes.css | 149 +++++++++++++++++++++++++++++++++++++++
 web/src/main.tsx         |   1 +
 4 files changed, 152 insertions(+), 2 deletions(-)
 create mode 100644 web/src/layout-fixes.css

diff --git a/backend/package.json b/backend/package.json
index 7a74f77..72eda2c 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -77,7 +77,7 @@
     "socket.io": "^4.8.3",
     "winston": "^3.19.0",
     "@bytelyst/telemetry-client": "*",
-    "@bytelyst/devops": "^0.1.2"
+    "@bytelyst/devops": "^0.1.3"
   },
   "devDependencies": {
     "@types/node": "^25.0.3",
diff --git a/web/package.json b/web/package.json
index 8a090ec..97f72c4 100644
--- a/web/package.json
+++ b/web/package.json
@@ -42,7 +42,7 @@
     "react-router-dom": "^7.14.2",
     "recharts": "^3.6.0",
     "socket.io-client": "^4.8.3",
-    "@bytelyst/devops": "^0.1.2"
+    "@bytelyst/devops": "^0.1.3"
   },
   "devDependencies": {
     "@eslint/js": "^9.39.4",
diff --git a/web/src/layout-fixes.css b/web/src/layout-fixes.css
new file mode 100644
index 0000000..865d00a
--- /dev/null
+++ b/web/src/layout-fixes.css
@@ -0,0 +1,149 @@
+/* ============================================================================
+ * Layout fixes — global overrides for known overflow / responsiveness issues.
+ *
+ * Applied as a separate file so individual fixes are easy to review and revert.
+ * Imported once from main.tsx after the main index.css.
+ * ============================================================================ */
+
+/* --------------------------------------------------------------------------
+ * 1. Don't clip popovers / modals / dropdowns to the main area.
+ *    Allow horizontal clipping (prevents accidental page-wide scroll) but
+ *    keep vertical visible so absolute-positioned UI escapes the row.
+ * -------------------------------------------------------------------------- */
+.dashboard-main {
+  overflow: visible !important;
+}
+
+.dashboard-content-row {
+  overflow: visible !important;
+}
+
+.dashboard-content {
+  /* Vertical scroll stays. Horizontal overflow becomes a child concern,
+     not a layout-level concern, so wide tables can scroll inside their
+     own container instead of being silently clipped. */
+  overflow-x: clip;
+}
+
+/* --------------------------------------------------------------------------
+ * 2. Collapse the right panel on narrower viewports.
+ *    308px is too greedy below ~1280px and steals critical content width.
+ *    Below 1024px it's hidden entirely (mobile/tablet view).
+ * -------------------------------------------------------------------------- */
+@media (max-width: 1279px) {
+  .dashboard-right-panel,
+  .right-panel {
+    width: 260px;
+    min-width: 260px;
+    max-width: 260px;
+  }
+}
+
+@media (max-width: 1023px) {
+  .dashboard-right-panel,
+  .right-panel {
+    display: none !important;
+  }
+}
+
+/* --------------------------------------------------------------------------
+ * 3. Tables and large grids must scroll within their own container.
+ *    Any table that's a direct child of dashboard-content should never
+ *    push the layout horizontally — wrap consumers can opt-in via
+ *    .scroll-x to the same behavior.
+ * -------------------------------------------------------------------------- */
+.dashboard-content table:not(.no-scroll-fix),
+.scroll-x {
+  display: block;
+  max-width: 100%;
+  overflow-x: auto;
+}
+
+/* Preserve table semantics inside the scroll container */
+.dashboard-content table:not(.no-scroll-fix) > thead,
+.dashboard-content table:not(.no-scroll-fix) > tbody,
+.dashboard-content table:not(.no-scroll-fix) > tfoot {
+  display: table-row-group;
+}
+
+.dashboard-content table:not(.no-scroll-fix) > thead {
+  display: table-header-group;
+}
+
+/* --------------------------------------------------------------------------
+ * 4. Header should reflow on narrow viewports.
+ *    The fixed 300px search and three indices push each other off-screen
+ *    on laptop widths (~1366px) once the right panel is also showing.
+ * -------------------------------------------------------------------------- */
+.trading-header {
+  flex-wrap: wrap;
+  row-gap: 8px;
+  min-height: 56px;
+  height: auto !important;
+}
+
+.trading-header-search {
+  flex: 1 1 240px;
+  min-width: 0;
+  max-width: 360px;
+}
+
+.trading-header-indices {
+  flex-wrap: wrap;
+  row-gap: 6px;
+  column-gap: 20px !important;
+}
+
+@media (max-width: 760px) {
+  .trading-header-indices {
+    column-gap: 14px !important;
+  }
+  .trading-header-indices > div > div:first-child {
+    font-size: 10px;
+  }
+}
+
+/* --------------------------------------------------------------------------
+ * 5. Sidebar collapse on narrow viewports.
+ *    The fixed 76px sidebar plus margin-left compounds with content
+ *    overflow on small windows. Below 768px we collapse it to 56px.
+ * -------------------------------------------------------------------------- */
+@media (max-width: 767px) {
+  :root {
+    --trading-shell-sidebar-width: 56px;
+  }
+  .trading-sidebar {
+    width: 56px;
+  }
+  .dashboard-content {
+    padding: 16px 16px 24px !important;
+  }
+}
+
+/* --------------------------------------------------------------------------
+ * 6. Container guard — content never exceeds its column.
+ *    Long unbreakable strings (commit SHAs, URLs) that escape boxes are a
+ *    common source of "elements pushed off-screen". This forces wrap.
+ * -------------------------------------------------------------------------- */
+.dashboard-content,
+.dashboard-content code,
+.dashboard-content pre,
+.dashboard-content .ux-surface {
+  overflow-wrap: anywhere;
+  word-break: break-word;
+}
+
+.dashboard-content pre {
+  white-space: pre-wrap;
+}
+
+/* --------------------------------------------------------------------------
+ * 7. Modal / dialog z-index baseline.
+ *    Anything inside .dashboard-content-row that was clipped by the
+ *    overflow:hidden fix in (1) now needs a stacking context guard.
+ * -------------------------------------------------------------------------- */
+[role="dialog"],
+.modal,
+[data-radix-popper-content-wrapper] {
+  z-index: 100;
+}
diff --git a/web/src/main.tsx b/web/src/main.tsx
index 3610c97..94c2ea5 100644
--- a/web/src/main.tsx
+++ b/web/src/main.tsx
@@ -3,6 +3,7 @@ import { createRoot } from 'react-dom/client'
 import { Agentation } from 'agentation'
 import './index.css'
 import './App.css'
+import './layout-fixes.css'
 import App from './App.tsx'
 import { AuthProvider } from './components/AuthContext';
 import { ProductAccessibilityGate } from './components/ProductAccessibilityGate';