diff --git a/app/static/css/layout.css b/app/static/css/layout.css index 2d6fe80..1d2db25 100644 --- a/app/static/css/layout.css +++ b/app/static/css/layout.css @@ -26,6 +26,13 @@ a:hover { text-decoration: underline; } grid-template-columns: 1fr; grid-template-rows: auto 1fr auto; min-height: 100vh; + /* Grid items default to min-content min-width which can blow past + the viewport when a descendant table or flex row is wide. min-width:0 + lets the cell shrink below intrinsic min-content, and max-width:100vw + caps the whole shell against the viewport so we never need to rely on + overflow:hidden clipping. */ + min-width: 0; + max-width: 100vw; } .app-header { @@ -367,8 +374,17 @@ body.drawer-open .drawer-backdrop { opacity: 1; } /* Body-level layout: tighten main padding too — saves another 16px of horizontal real estate which the indicator table and chat - bubbles all benefit from. */ - .app-main { padding: 10px 8px; gap: 10px; } + bubbles all benefit from. Also force min-width:0 on the grid + container and every grid item, otherwise a wide table inside + a panel forces the whole grid (and the page) wider than the + viewport. This is the single most important mobile fix. */ + .app-main { + padding: 10px 8px; + gap: 10px; + min-width: 0; + max-width: 100vw; + } + .app-main > * { min-width: 0; } /* Markets bar: the desktop grid uses minmax(220px, 1fr) per market, which at 4+ markets blows out to 880px+ and forces page-wide diff --git a/app/static/css/panels.css b/app/static/css/panels.css index 4d2d9a3..7a704ae 100644 --- a/app/static/css/panels.css +++ b/app/static/css/panels.css @@ -95,6 +95,14 @@ table.dense tr:hover td { background: color-mix(in srgb, var(--accent) 5%, trans /* --- Mobile (≤480px) -------------------------------------------------- */ @media (max-width: 480px) { + /* Force panels and their bodies to honour the parent grid cell + width, even when descendants (tables, code blocks, long URLs) + have intrinsic widths that exceed the viewport. min-width:0 is + the magic that lets flex/grid items shrink past min-content; + max-width:100% caps the box itself. */ + .panel { min-width: 0; max-width: 100%; } + .panel-body { min-width: 0; max-width: 100%; } + .panel-header { padding: 8px 10px; gap: 8px; @@ -105,4 +113,19 @@ table.dense tr:hover td { background: color-mix(in srgb, var(--accent) 5%, trans /* Scroll panels lose some vertical room on small screens so the stacked layout doesn't push log/news off the fold. */ .panel-body--scroll { max-height: 60vh; } + + /* Tables: dropping white-space:nowrap lets long Symbol / Label cells + wrap to a second line instead of forcing the table wider than the + panel. Numeric cells stay nowrap since "−12.34%" wrapping would be + unreadable. */ + table.dense { table-layout: auto; } + table.dense th, table.dense td { white-space: normal; } + table.dense .num { white-space: nowrap; } + + /* Final safety net: if a descendant still insists on being wider + than the panel (e.g. a wide pre/code block in the AI output), + scroll it horizontally inside the panel rather than blowing the + whole page out. */ + .panel-body pre, + .panel-body code { max-width: 100%; overflow-x: auto; } }