Skip to main content

max / goingson

Bound the list views so virtual scrolling actually runs The three tab groups are display: block, so the flex: 1 on #tasks-view, #events-view, and #emails-view applied against a block parent and did nothing. Their list containers sat at auto height, scrollTop stayed 0, and VirtualScroller computed a visible range covering every row. Bound each group to a flex column while its list subview is the visible one, leaving the page-scroll subviews alone, and pin the chrome that is now a flex sibling of a flexing list. The board keeps its full height on purpose: it has no inner scroller, and shrinking it would slide it under the pagination bar. Also pins .pill-nav, which the contacts fix left able to squash.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-07-28 18:19 UTC
Signed with PGP, not checked
Commit: 474bfb77ba98eb4f14de5c2d893ca7011fbef64c
Parent: 4678f52
1 file changed, +47 insertions, -14 deletions
@@ -5239,6 +5239,28 @@
5239 5239 padding-bottom: var(--gap-page);
5240 5240 }
5241 5241
5242 + /* A tab group is a plain block by default, which leaves every descendant's
5243 + `flex: 1` inert and hands the scrolling to .main-content. The list-holding
5244 + subviews need bounding instead, and only those, so each rule turns its group
5245 + into a flex column solely while its list subview is the visible one; the
5246 + page-scroll subviews (Projects, Problems, Day, Week, Month, Timer) keep the
5247 + behaviour they ship with. Without this, #task-list-container and friends sit
5248 + at auto height and VirtualScroller renders every row. */
5249 + #work-view:has(> #tasks-view:not(.hidden)),
5250 + #time-view:has(> #events-view:not(.hidden)),
5251 + #messages-view:has(> #emails-view:not(.hidden)),
5252 + #messages-view:has(> #contacts-view:not(.hidden)) {
5253 + display: flex;
5254 + flex-direction: column;
5255 + flex: 1;
5256 + min-height: 0;
5257 + }
5258 +
5259 + /* The pill row is chrome, not content: it sizes to itself in every group. */
5260 + .tab-group > .pill-nav {
5261 + flex-shrink: 0;
5262 + }
5263 +
5242 5264 /* Task view fills available height */
5243 5265 #tasks-view {
5244 5266 display: flex;
@@ -5249,7 +5271,17 @@
5249 5271
5250 5272 #tasks-view .page-header,
5251 5273 #tasks-view .bulk-actions-bar,
5252 - #tasks-view .filter-bar {
5274 + #tasks-view .mobile-sort-bar,
5275 + #tasks-view .filter-bar,
5276 + #task-pagination {
5277 + flex-shrink: 0;
5278 + }
5279 +
5280 + /* Board mode has no inner scroller: the columns carry their own max-height and
5281 + the board is free to run past the viewport, as it does today. Shrinking it
5282 + instead would slide it under the pagination bar, since the subview does not
5283 + clip. */
5284 + #task-kanban-board {
5253 5285 flex-shrink: 0;
5254 5286 }
5255 5287
@@ -5261,7 +5293,16 @@
5261 5293 min-height: 0;
5262 5294 }
5263 5295
5264 - #events-view .page-header {
5296 + #events-view .page-header,
5297 + #events-view .filter-bar,
5298 + #events-view .bulk-actions-bar {
5299 + flex-shrink: 0;
5300 + }
5301 +
5302 + /* Only the Upcoming table flexes. The Recurring and Past sections bound
5303 + themselves with a max-height further down, so they keep their own size. */
5304 + .events-list > .past-events-section,
5305 + .events-list > .events-section-heading {
5265 5306 flex-shrink: 0;
5266 5307 }
5267 5308
@@ -5324,22 +5365,14 @@
5324 5365 }
5325 5366
5326 5367 #emails-view .page-header,
5327 - #emails-view .bulk-actions-bar {
5368 + #emails-view .email-filter-row,
5369 + #emails-view .bulk-actions-bar,
5370 + #email-pagination {
5328 5371 flex-shrink: 0;
5329 5372 }
5330 5373
5331 5374 /* Contacts view fills available height, so the card grid scrolls under a
5332 - fixed filter row instead of scrolling the page. The tab group is a plain
5333 - block by default, which would leave every descendant's `flex: 1` inert; it
5334 - only becomes a flex column while Contacts is the visible subview, so the
5335 - Emails subview keeps the page-scroll behaviour it ships with today. */
5336 - #messages-view:has(> #contacts-view:not(.hidden)) {
5337 - display: flex;
5338 - flex-direction: column;
5339 - flex: 1;
5340 - min-height: 0;
5341 - }
5342 -
5375 + fixed filter row instead of scrolling the page. */
5343 5376 #contacts-view {
5344 5377 display: flex;
5345 5378 flex-direction: column;