fix(panel): lay every page out in one column width
The page column was the 48rem reading measure, which the send log, the mail queue and the system log widened to 64rem for their tables. The navigation and the page are centred as a pair, so that difference did not only change the page's width: it moved the navigation column and the left edge of every card on the way between two pages. The column is now 64rem throughout and the measure lives inside it — a page's heading, cards, back link and version footer are held to 48rem and centred in the column, and the pages made of data opt out and take the column whole. Which pages those are is declared by the page (a "wide" block in its template, the same mechanism as the section index) rather than derived from the navigation entry: .Active cannot tell the send log from a single delivery's page, which is prose and now keeps the measure instead of inheriting the log's width. Two rules follow from centring the children rather than the cards. The heading takes its margins as longhands, since the shorthand re-zeroed the auto side margins and pinned it a measure's width left of the card under it; and the back link is a block, since auto margins centre a block and do nothing for an inline-block. The scrollbar's width is reserved on every page as well. Without it a short page and a long one are laid out in viewports differing by that width, which moved the same things again, in the same direction, for a second reason. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -215,6 +215,32 @@ func TestNavLeadsWithStatusAndPointsDomainsAtItsOwnPath(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Whether a page takes the whole column or the reading measure is declared by
|
||||
// the page's own "wide" block (see layout.html), which the layout stamps into
|
||||
// <main>'s class list. A page that loses the block does not fail to render — it
|
||||
// silently comes back at the measure, with its table squeezed into two thirds
|
||||
// of the column — so the set is asserted here, in both directions.
|
||||
func TestOnlyThePagesMadeOfDataDeclareThemselvesWide(t *testing.T) {
|
||||
tmpl, err := loadTemplates()
|
||||
if err != nil {
|
||||
t.Fatalf("loadTemplates: %v", err)
|
||||
}
|
||||
wide := map[string]bool{"deliveries": true, "mail_queue": true, "system_log": true}
|
||||
for name, page := range tmpl.pages {
|
||||
var buf bytes.Buffer
|
||||
if err := page.ExecuteTemplate(&buf, "wide", nil); err != nil {
|
||||
t.Fatalf("execute the wide block of %s: %v", name, err)
|
||||
}
|
||||
got := strings.TrimSpace(buf.String())
|
||||
switch {
|
||||
case wide[name] && got != "wide":
|
||||
t.Errorf("page %q no longer declares itself wide (%q); its data falls back to the reading measure", name, got)
|
||||
case !wide[name] && got != "":
|
||||
t.Errorf("page %q declares itself %q; only the pages that are tables of data or raw log lines take the whole column", name, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Since the panel root redirects to the status page, a link left pointing at
|
||||
// "/" silently lands on the wrong screen instead of failing — so no template may
|
||||
// contain one.
|
||||
|
||||
Reference in New Issue
Block a user