Pin list headers flush to the top of the scroll area

Sticky headers pinned at the content area's padding edge, leaving a strip
above them where scrolled-past rows showed through. Offset them by that
padding. In grouped lists, column headers now pin below the sticky group
heading instead of behind it.

Closes #5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-26 20:59:35 -05:00
parent ef1579c978
commit 1a23bd83a4

View File

@@ -774,9 +774,14 @@ input[type="checkbox"] {
color: var(--warn);
}
.content {
/* Named so sticky headers can cancel it: sticky elements pin at the scroll
container's padding edge, which would leave a strip above them where
scrolled-past rows still show. */
--content-pad-top: var(--space-5);
--group-header-h: 40px;
flex: 1;
overflow: auto;
padding: var(--space-5) var(--space-6);
padding: var(--content-pad-top) var(--space-6);
}
/* Empty / welcome state */
@@ -960,10 +965,18 @@ h4 {
* tag) since h3 is also used for .dialog-title, which must not be sticky. */
.group-header {
position: sticky;
top: 0;
top: calc(-1 * var(--content-pad-top, 0px));
z-index: 5;
margin: var(--space-4) 0 var(--space-2);
padding: var(--space-2) 0;
/* A fixed height, so a grouped table's column headers can pin just below
it (see `.group-header + table th`). */
height: var(--group-header-h);
box-sizing: border-box;
display: flex;
align-items: center;
gap: var(--space-2);
white-space: nowrap;
padding: 0;
background: var(--bg-app);
font-size: var(--fs-body);
font-weight: 700;
@@ -1569,7 +1582,7 @@ th {
letter-spacing: var(--tracking-label);
color: var(--muted);
position: sticky;
top: 0;
top: calc(-1 * var(--content-pad-top, 0px));
background: var(--bg-content);
border-bottom: 1px solid var(--border);
z-index: 1;
@@ -1579,6 +1592,10 @@ td {
border-bottom: 1px solid var(--border-soft);
vertical-align: middle;
}
/* Under a sticky group header, pin below it instead of behind it. */
.group-header + table th {
top: calc(var(--group-header-h) - var(--content-pad-top, 0px));
}
tbody tr {
transition: background 0.08s;
}
@@ -3291,7 +3308,8 @@ button.pull-action {
placement on Android). */
@media (max-width: 720px) {
.content {
padding: var(--space-4);
--content-pad-top: var(--space-4);
padding: var(--content-pad-top);
/* Clear the fixed bottom nav, or its last row of content is hidden
behind it — the safe-area inset is already baked into the nav's own
height, so it isn't added again here. */