Polish sticky headers, Custom View, docs page and dialogs

- Status tables: the whole header (column names + filters) sticks as one
  block, tucked 1px under the group header, so no gap can open between
  the rows; offsets use fractional heights
- Phones/tablets: the filter panel sticks under the group header too, and
  is opaque and compact (three filters per row on phones)
- Custom View: fix the group header being pushed over the column header
  (it lives inside the view's own scroll box); the column header now pins
  to the top of that box on desktop, and the header strip sticks on phones
- All Devices: group title is "All Devices (N)" instead of "Missing
  Software", matching the page title count
- Documentation fits the window on desktop: only the article list and the
  article scroll; placeholder no longer says "from the left"
- Dialogs sit above the terminal dock so it can't cover their last rows;
  page bottom padding follows the dock's measured height
This commit is contained in:
Johan Sandoval committed 2026-10-06 16:58:05 +00:00
1 parent a85c22b2b9
commit d24be4a2d6
4 files changed
+73 -25

No files matched your search

+49 -13
View File
@@ -10,25 +10,45 @@
* Sticky headers
*
* A status group's header ("Not Started (37)") sticks under the top nav while you scroll
* through that group, then hands over to the next group's header. On desktop the column
* header and filter rows stick beneath it. layout.js sets --nav-h (top nav height) and,
* per table, --sticky-top (nav + group header) and --thead-r1 (header row height).
* through that group, then hands over to the next group's header. Beneath it the table's
* header (column names + filters on desktop, the filter panel on phones) sticks as one
* block, so the rows inside it can never drift apart. layout.js sets --nav-h and, per
* table, --sticky-top (nav + group header).
* ------------------------------------------------------------------------------------- */
.group-header { position: sticky; top: var(--nav-h, 60px); z-index: 30; }
.master-table:not(#table-custom) thead { position: sticky; top: var(--sticky-top, 112px); z-index: 20; }
.master-table:not(#table-custom) thead tr.filter-row th {
/* the original header tint, but opaque so rows don't show through */
background: linear-gradient(rgba(0,0,0,0.2), rgba(0,0,0,0.2)), var(--bg-card);
}
@media (min-width: 1101px) {
/* An overflowing wrapper would capture the sticky rows; these tables never need to
/* An overflowing wrapper would capture the sticky header; these tables never need to
scroll sideways at desktop widths (they're fixed-layout, 100% wide) */
#masterList .table-wrapper, #software .table-wrapper, .stack-box.table-wrapper { overflow: visible !important; }
.master-table:not(#table-custom) thead th {
position: sticky; top: var(--sticky-top, 112px); z-index: 20;
}
.master-table:not(#table-custom) thead tr.filter-row th {
top: calc(var(--sticky-top, 112px) + var(--thead-r1, 38px) - 2px); z-index: 19; /* -2px: no seam from collapsed borders */
/* the original header tint, but opaque so rows don't show through */
background: linear-gradient(rgba(0,0,0,0.2), rgba(0,0,0,0.2)), var(--bg-card);
}
/* Custom View scrolls inside its own box (it can be wider than the page), so its
group header stays put and its column header sticks to the top of that box */
#wrapper-custom .group-header { position: static; }
#scroll-custom thead th { position: sticky; top: 0; z-index: 20; }
}
/* ---------------------------------------------------------------------------------------
* Bottom terminal dock: keep page content and dialogs clear of it.
* layout.js sets --dock-h to the dock's current height (bar only, or bar + terminal).
* ------------------------------------------------------------------------------------- */
body { padding-bottom: var(--dock-h, 40px) !important; }
/* Dialogs sit above the dock (below the top nav), so it can't cover their bottom rows */
.modal-overlay { z-index: 1950 !important; }
#modal { z-index: 1960 !important; }
#syncModal { z-index: 1970 !important; }
#confirmModal, #promptModal { z-index: 1980 !important; }
/* Documentation fits the window on desktop: only the article list and the article scroll */
@media (min-width: 901px) {
#docs > div { height: calc(100vh - var(--nav-h, 60px) - 50px - var(--dock-h, 40px)) !important; }
}
/* ---------------------------------------------------------------------------------------
@@ -56,7 +76,9 @@
/* Filters: a wrapping panel of labeled controls */
table.master-table thead tr.filter-row {
display: flex; flex-wrap: wrap; gap: 8px 10px; padding: 10px 12px;
background: rgba(0,0,0,0.15); border-bottom: 1px solid var(--border-color);
/* opaque: the panel sticks over the cards while scrolling */
background: linear-gradient(rgba(0,0,0,0.15), rgba(0,0,0,0.15)), var(--bg-card);
border-bottom: 1px solid var(--border-color); box-shadow: 0 4px 8px rgba(0,0,0,0.3);
}
table.master-table thead tr.filter-row th {
display: block; flex: 1 1 150px; min-width: 0; width: auto !important;
@@ -69,6 +91,11 @@
font-size: 0.78em; font-weight: 600; color: var(--text-muted);
}
/* Custom View: cards don't need the sideways-scrolling box, so it scrolls with the
page like the other tables and its header strip sticks under the group header */
#wrapper-custom, #scroll-custom { overflow: visible !important; max-height: none !important; }
#table-custom thead { position: sticky; top: var(--sticky-top, 112px); z-index: 20; }
/* Custom View keeps its header (sort / filter / remove buttons) as a strip of chips */
#table-custom thead tr.card-label-row {
display: flex; flex-wrap: wrap; gap: 6px; padding: 10px 12px;
@@ -134,6 +161,15 @@
@media (min-width: 1101px) {
.card-filter-toggle { display: none; }
}
@media (max-width: 600px) {
/* Compact filter panel on phones: three per row, shorter controls */
table.master-table thead tr.filter-row { gap: 6px 8px; padding: 8px 10px; }
table.master-table thead tr.filter-row th { flex: 1 1 96px; }
table.master-table thead tr.filter-row th::before { font-size: 0.7em; margin-bottom: 2px; }
table.master-table thead tr.filter-row input[type="text"],
table.master-table thead tr.filter-row .select-box { height: 32px; padding: 3px 6px; }
table.master-table thead tr.filter-row .select-box { font-size: 13px; }
}
@media (max-width: 420px) {
table.master-table tbody td { padding-left: 7.8em; }
table.master-table tbody td::before { width: 7.2em; }