fix(dashboard): contain Tiles grid to prevent horizontal scroll

m reported /dashboard horizontally scrolls because Tiles widen past
the viewport. Root cause: '1fr' grid columns have an implicit
'min-content' minimum, so any tile with a long unbreakable string
(dot-separated slug path like dev.youpc.kommentar.knowledge-tools, or
a long task summary in NextSignal) pushes its column beyond
viewport-fraction → grid overflows main → horizontal scroll.

Fix triangle (the canonical CSS-grid containment recipe):
1. grid-template-columns: minmax(0, 1fr) instead of 1fr — overrides
   the implicit min-content floor.
2. min-width: 0 on the tile <article> — lets the grid item shrink
   below its content's min-content width.
3. overflow-wrap: anywhere on .tile-path — long slug-paths wrap at
   any character instead of forcing the tile wider.

Also: overflow: hidden on .tile as a belt-and-braces guard; the
ellipsis on .tile-signal-text was already there (slice 2) so it
already handled long task summaries.

Applied across all three breakpoint rules (1-col base, 2-col 600px,
3-col 900px) so the grid containment holds at every width.
This commit is contained in:
mAi
2026-05-26 12:33:18 +02:00
parent 2925c43a1e
commit c4a4ba0687

View File

@@ -342,13 +342,22 @@ table.bulk .chip-add-btn:hover { background: var(--accent); color: var(--accent-
.dashboard .dash-tiles {
display: grid; gap: 12px; margin-top: 8px;
grid-template-columns: 1fr;
/* minmax(0, 1fr) overrides the implicit min-content minimum on 1fr —
without it, any tile with a long unbreakable string (slug-path or
a long task summary) widens its column and pushes the grid past
the viewport, causing horizontal scroll. */
grid-template-columns: minmax(0, 1fr);
min-width: 0;
}
.dashboard .tile {
border: 1px solid var(--border); border-radius: 6px; padding: 12px 14px;
background: var(--surface);
display: flex; flex-direction: column; gap: 6px;
min-height: 110px;
/* min-width: 0 lets the grid item shrink below its content's
min-content width — critical pairing with minmax(0, 1fr) above. */
min-width: 0;
overflow: hidden;
}
.dashboard .tile.tile-pinned { border-left: 3px solid var(--accent); }
.dashboard .tile.tile-stale { border-style: dashed; opacity: 0.85; }
@@ -365,6 +374,11 @@ table.bulk .chip-add-btn:hover { background: var(--accent); color: var(--accent-
.dashboard .tile .tile-path {
font-family: ui-monospace, SFMono-Regular, monospace;
font-size: 0.78em;
/* Long dot-separated slugs (dev.youpc.kommentar.knowledge-tools)
are unbreakable by default — let them wrap at any character so
they don't widen the tile. */
overflow-wrap: anywhere;
min-width: 0;
}
.dashboard .tile .tile-live {
font-size: 0.72em; padding: 1px 6px; border-radius: 999px;
@@ -567,12 +581,14 @@ table.bulk .chip-add-btn:hover { background: var(--accent); color: var(--accent-
.dashboard .card-stale { grid-column: span 2; }
}
/* Phase 5h — Tiles grid breakpoints (1/2/3 cols at 600/900/—). */
/* Phase 5h — Tiles grid breakpoints (1/2/3 cols at 600/900/—).
minmax(0, 1fr) on every breakpoint so long unbreakable strings
(slug-paths, task summaries) don't push columns past the viewport. */
@media (min-width: 600px) {
.dashboard .dash-tiles { grid-template-columns: 1fr 1fr; }
.dashboard .dash-tiles { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
@media (min-width: 900px) {
.dashboard .dash-tiles { grid-template-columns: 1fr 1fr 1fr; }
.dashboard .dash-tiles { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); }
}
/* Graph fit-to-screen toggle (Phase 3i): when ".fit" is on the canvas,