ui: give tables a real header, drop the column grid, quiet the row rules

Three things the file browser made obvious.

The header was not a surface.  Mantine gives thead no background at all, so
the header painted whatever was behind the table -- which is exactly what an
unstriped body row paints.  Against a striped body it read as one more stripe,
and bold type was the only thing distinguishing it.  It now carries `--head`,
the token that already means "recessed surface", with a full-strength 2px rule
under it: the header/body division is the one line in a table that carries
meaning, so it is the one allowed to be loud.

Column borders are gone.  A line around every cell is a lot of ink to repeat
what the column headings already say, and it was half of why the header
disappeared -- a bordered header cell looks like a cell in a grid.

Row rules were `--border`, the same weight as the outline around the table, so
a long table read as a stack of boxes.  They now use `--table-line`, a new
token per theme sitting between the surface and `--border`.  The table outline
is not a row rule and keeps `--border`; Mantine draws both from
`--table-border-color`, so that had to be restated.

In the file browser an icon and a filename are inline siblings in one cell.  An
inline SVG sits on the text baseline, so a 24px glyph beside 13px text hung
above it -- the icon looked centred in the row and the name looked like it was
resting on the icon's floor.  `vertical-align: middle` centres it, and the
margin is a gap that was never there at all: the folder icon touched the first
letter of its own name.

Cypress now loads App.css, as the app does.  Without it a spec covering the
file browser rows measures a component the app never renders.

One jest test and eleven browser tests, each checked red against a planted
regression.  Two notes for the next person:

  - `html .mantine-Table-table` is specificity, not decoration.  Mantine
    declares --table-border-color on its own hashed class, which ties with
    `.mantine-Table-table` and wins on source order.
  - the "quieter than the outline" test measures both lines against `--panel`.
    Nothing paints <html> under a mounted component, so measuring against the
    root background compares them to black, which ranks the *paler* line as the
    louder one -- the assertion passed backwards until it was pointed at the
    surface the rules actually sit on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Roland 2026-08-01 16:46:50 -06:00 • committed by lrnselfreliance
parent bd77ac090e
commit ee657d950f
7 changed files with 274 additions and 5 deletions

View file

@ -1183,6 +1183,51 @@ html[data-theme="night"] .wrolpi-status-failed {
/* ----------------------------------------------------------------- Tables */
/*
* The header is a surface, not just bold text.
*
* Mantine gives `thead` no background at all, so the header showed whatever was
* behind the table -- which is exactly what the unstriped body rows show. Bold
* type was the only thing separating the two, and against a striped body the
* header read as one more stripe. `--head` is the token for a recessed surface
* and is distinct from both the panel and the stripe in all four themes.
*/
.mantine-Table-thead .mantine-Table-th {
background: var(--head);
}
/*
* A full-strength rule under the header, because that is the one division in a
* table that carries meaning: everything above it names, everything below it is
* data. The rules between body rows are `--table-line` and much fainter -- see
* the note there. Applied to the last header row so a grouped header does not
* get a hard rule through the middle of itself.
*/
.mantine-Table-thead .mantine-Table-tr:last-child .mantine-Table-th {
border-bottom: 2px solid var(--border);
}
/*
* Row rules are quieter than any other border in the interface. They only have
* to let the eye track across a row; at `--border` strength, with a rule under
* every row, a long table turns into a stack of boxes.
*
* `html` for specificity, not decoration: Mantine declares this variable on its
* own hashed class, which ties with `.mantine-Table-table` and wins on source
* order because its stylesheet is imported after this one.
*/
html .mantine-Table-table {
--table-border-color: var(--table-line);
}
/*
* The outline around the whole table is not a row rule and keeps full strength;
* Mantine draws both from the same variable, so it has to be restated.
*/
html .mantine-Table-table[data-with-table-border] {
border-color: var(--border);
}
/* A sortable header: a real button, so the column is reachable by keyboard. */
.wrolpi-th-sort {
display: inline-flex;