mobile: clamp grid items + table cells to viewport width

User reported the page rendering at ~3x viewport width on Android
Chrome with overflow-x:hidden clipping off most of the content.
Root cause: CSS grid items default to min-width:min-content, and the
indicator table inside the indicators panel has white-space:nowrap
cells. A long Symbol/Label value forces the table wider than its
panel; the panel propagates that minimum width up the grid; the grid
expands the .app-main; .app-main pushes the page wider than the
viewport. overflow-x:hidden then just chops the right portion off.

Fix has three parts:

1. .app and .app-main get min-width:0 and max-width:100vw so the
   shell can't be wider than the viewport regardless of descendants.
2. Every direct child of .app-main (each panel) gets min-width:0
   on mobile so individual panels can shrink past their min-content.
3. table.dense drops white-space:nowrap on text cells at ≤480px —
   long symbols wrap to two lines instead of forcing the table wide.
   Numeric cells keep nowrap (negative percentages reading as
   "−12\n.34%" would be unreadable).

Also adds an overflow-x:auto fallback on .panel-body pre/code so
any code block in AI output scrolls within the panel instead of
blowing the page out.
This commit is contained in:
Giorgio Gilestro 2026-05-28 19:02:30 +02:00
parent 5ceee96135
commit 8ec4ea1c72
2 changed files with 41 additions and 2 deletions

View file

@ -26,6 +26,13 @@ a:hover { text-decoration: underline; }
grid-template-columns: 1fr; grid-template-columns: 1fr;
grid-template-rows: auto 1fr auto; grid-template-rows: auto 1fr auto;
min-height: 100vh; 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 { .app-header {
@ -367,8 +374,17 @@ body.drawer-open .drawer-backdrop { opacity: 1; }
/* Body-level layout: tighten main padding too saves another 16px /* Body-level layout: tighten main padding too saves another 16px
of horizontal real estate which the indicator table and chat of horizontal real estate which the indicator table and chat
bubbles all benefit from. */ bubbles all benefit from. Also force min-width:0 on the grid
.app-main { padding: 10px 8px; gap: 10px; } 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, /* Markets bar: the desktop grid uses minmax(220px, 1fr) per market,
which at 4+ markets blows out to 880px+ and forces page-wide which at 4+ markets blows out to 880px+ and forces page-wide

View file

@ -95,6 +95,14 @@ table.dense tr:hover td { background: color-mix(in srgb, var(--accent) 5%, trans
/* --- Mobile (≤480px) -------------------------------------------------- */ /* --- Mobile (≤480px) -------------------------------------------------- */
@media (max-width: 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 { .panel-header {
padding: 8px 10px; padding: 8px 10px;
gap: 8px; 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 /* Scroll panels lose some vertical room on small screens so the
stacked layout doesn't push log/news off the fold. */ stacked layout doesn't push log/news off the fold. */
.panel-body--scroll { max-height: 60vh; } .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; }
} }