Dashboard layout: R-906/R-907 fixed on main (controller d5f2e47, 423b6d3), R-909..R-911 filed, evidence from 9202, report
gates / gates (push) Successful in 4m29s

Register 131 -> 134 (R-909 Apps card header, fixed on main; R-910 retake the website's dashboard pictures
after tomorrow's release; R-911 storage-unavailable banner stays Hungarian on English pages).
Evidence: before (0.303.0) / after (0.304.0-layout.rc2) pictures and measurements on scratch 9202, red proofs,
fixture diff. 9202 is back on 0.303.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
This commit is contained in:
2026-10-08 14:47:14 +02:00
parent 4510dd7d05
commit 7585097f26
57 changed files with 410 additions and 5 deletions
@@ -0,0 +1,50 @@
# Dashboard layout fixes — evidence (2026-10-08)
Scratch guest **9202** on demo-hp, headless Chrome (`ghcr.io/puppeteer/puppeteer`, already on 9202 from an earlier
session, left there) run inside 9202, through traefik with the real host name. Script: `tools/shots.js`. The session
cookie came from a 0600 file, never printed, shredded on both sides at the end. English is shown with `?lang=en` (a
per-request override; the household setting was never changed — read `hu` before and after).
| Run | Controller on 9202 | Files |
|---|---|---|
| before | `0.303.0` (the fleet's) | `before/before-*.png`, `before/before-measure.txt` |
| after | `0.304.0-layout.rc2` = controller `423b6d3` (test tag, never a release) | `after/after-*.png`, `after/after-measure.txt` |
Per language (hu, en) and width (1440 × 900; 390 × 844 @2, phone): the Launcher, the Apps page (plus three card
pictures: an installed app with two tags = Paperless-ngx, not installed = Immich, built-in = FileBrowser) and the
Backups page (one of the pages that showed „+ 5 további figyelmeztetés").
## What was measured (from the `*-measure.txt` files)
| | before (0.303.0) | after (rc2) |
|---|---|---|
| Banner | `+ 5 további figyelmeztetés` / `+ 5 more warnings` only, on every page | the three real warnings (two „Adattároló nem elérhető", hub off), no overflow line |
| Launcher 390 px: page width | 425 (hu) / 395 (en) on a 390 screen | 390 / 390 |
| Share button right edge, 390 px | 424 (hu) / 395 (en) — past the edge | 217 / 192, own line |
| Apps 390 px: page width | 519 (hu) / 434 (en) | 390 / 390 |
| Apps: name text under a tag | 1 card (Paperless-ngx, en, 1440) | 0 of 61, all four runs |
| Apps: logo top minus name top | three values (-5, 9, 21 px) | one value (-3 px) |
| Apps: Paperless address | „↗" on a second line (card picture) | one line, full address in `title` |
**Honest notes on the measuring:**
- The first „after" run (rc1) showed the phone pages STILL wider than the screen (481 / 472 px). The cause was the
banner: once R-906 let the real warnings through, the banner's link ran past the screen, and it had no colour of its
own. Fixed in `423b6d3` (rc2); the rc1 run was discarded and is not in this folder.
- The address-line counter in the BEFORE run counted any step in the text's top edge as a new line; on rc1 it said
„2 lines" for an address that the picture shows on one line (a 1 px baseline step). It was loosened before the rc2
run. The before claim rests on the card picture (`before-apps-*-card-installed.png`), not on that number.
- 9202's English pages show „Adattároló nem elérhető" in Hungarian — filed as R-911.
## Tests
- `red-proofs.txt`: the three new tests run against 05e12921's `stacks.html`, `style.css` and `handlers.go` — every
check fails with its own line.
- `fixture-diff.txt`: the three re-captured parity fixtures, each = its predecessor with exactly the template change
applied (byte-for-byte, 3 of 3), visible text identical.
## 9202 put back
`/etc/felhom-controller-image` restored to `…:0.303.0` from a copy taken before; restarted; `felhom-controller 0.303.0
Up (healthy)`; the two test images removed from 9202 (`docker rmi`, 4 tags untagged); `/root/layout` removed. Apps as
found (Paperless-ngx running, PrivateBin stopped). demo-hp host: only `pct list`, `pct exec 9202`, `pct push 9202`.
9201, demo-felhom, Tester 1, Tester 2, the hub: not touched.
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

@@ -0,0 +1,56 @@
after-launcher-hu-1440: html lang hu, version 0.304.0-layout.rc2
after-launcher-hu-1440: layout width 1440 (screen 1440) scrollWidth 1440 — wider than the screen: false
after-launcher-hu-1440: banners ["alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/grimm","alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/metub","alert-banner-warning: Hub kapcsolat kikapcsolva — a központi monitoring nem aktív\nRendszermo"]
after-launcher-hu-1440: share button {"left":1207,"right":1408,"top":213,"text":"Indítópult megosztása"} past the screen edge: false
after-apps-hu-1440: html lang hu, version 0.304.0-layout.rc2
after-apps-hu-1440: layout width 1440 (screen 1440) scrollWidth 1440 — wider than the screen: false
after-apps-hu-1440: banners ["alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/grimm","alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/metub","alert-banner-warning: Hub kapcsolat kikapcsolva — a központi monitoring nem aktív\nRendszermo"]
after-apps-hu-1440: 61 cards; name text under a tag on 0 []; tag outside card on 0; logo top minus name top [-3]; address on more than one line on 0
after-apps-hu-1440: {"name":"FileBrowser","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-3,"addr":"","addrLines":0,"addrTitle":""}
after-apps-hu-1440: {"name":"Immich","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-3,"addr":"","addrLines":0,"addrTitle":""}
after-apps-hu-1440: {"name":"Paperless-ngx","tags":2,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-3,"addr":"paperless.enkisfelhom.hu ↗","addrLines":1,"addrTitle":"paperless.enkisfelhom.hu"}
after-backups-hu-1440: html lang hu, version 0.304.0-layout.rc2
after-backups-hu-1440: layout width 1440 (screen 1440) scrollWidth 1440 — wider than the screen: false
after-backups-hu-1440: banners ["alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/grimm","alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/metub","alert-banner-warning: Hub kapcsolat kikapcsolva — a központi monitoring nem aktív\nRendszermo"]
after-launcher-hu-390: html lang hu, version 0.304.0-layout.rc2
after-launcher-hu-390: layout width 390 (screen 390) scrollWidth 390 — wider than the screen: false
after-launcher-hu-390: banners ["alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/grimm","alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/metub","alert-banner-warning: Hub kapcsolat kikapcsolva — a központi monitoring nem aktív\nRendszermo"]
after-launcher-hu-390: share button {"left":16,"right":217,"top":470,"text":"Indítópult megosztása"} past the screen edge: false
after-apps-hu-390: html lang hu, version 0.304.0-layout.rc2
after-apps-hu-390: layout width 390 (screen 390) scrollWidth 390 — wider than the screen: false
after-apps-hu-390: banners ["alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/grimm","alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/metub","alert-banner-warning: Hub kapcsolat kikapcsolva — a központi monitoring nem aktív\nRendszermo"]
after-apps-hu-390: 61 cards; name text under a tag on 0 []; tag outside card on 0; logo top minus name top [-3]; address on more than one line on 0
after-apps-hu-390: {"name":"FileBrowser","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-3,"addr":"","addrLines":0,"addrTitle":""}
after-apps-hu-390: {"name":"Immich","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-3,"addr":"","addrLines":0,"addrTitle":""}
after-apps-hu-390: {"name":"Paperless-ngx","tags":2,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-3,"addr":"paperless.enkisfelhom.hu ↗","addrLines":1,"addrTitle":"paperless.enkisfelhom.hu"}
after-backups-hu-390: html lang hu, version 0.304.0-layout.rc2
after-backups-hu-390: layout width 390 (screen 390) scrollWidth 390 — wider than the screen: false
after-backups-hu-390: banners ["alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/grimm","alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/metub","alert-banner-warning: Hub kapcsolat kikapcsolva — a központi monitoring nem aktív\nRendszermo"]
after-launcher-en-1440: html lang en, version 0.304.0-layout.rc2
after-launcher-en-1440: layout width 1440 (screen 1440) scrollWidth 1440 — wider than the screen: false
after-launcher-en-1440: banners ["alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/grimm","alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/metub","alert-banner-warning: The hub connection is off — central monitoring is not running\nSystem m"]
after-launcher-en-1440: share button {"left":1232,"right":1408,"top":213,"text":"Share the launcher"} past the screen edge: false
after-apps-en-1440: html lang en, version 0.304.0-layout.rc2
after-apps-en-1440: layout width 1440 (screen 1440) scrollWidth 1440 — wider than the screen: false
after-apps-en-1440: banners ["alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/grimm","alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/metub","alert-banner-warning: The hub connection is off — central monitoring is not running\nSystem m"]
after-apps-en-1440: 61 cards; name text under a tag on 0 []; tag outside card on 0; logo top minus name top [-3]; address on more than one line on 0
after-apps-en-1440: {"name":"FileBrowser","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-3,"addr":"","addrLines":0,"addrTitle":""}
after-apps-en-1440: {"name":"Immich","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-3,"addr":"","addrLines":0,"addrTitle":""}
after-apps-en-1440: {"name":"Paperless-ngx","tags":2,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-3,"addr":"paperless.enkisfelhom.hu ↗","addrLines":1,"addrTitle":"paperless.enkisfelhom.hu"}
after-backups-en-1440: html lang en, version 0.304.0-layout.rc2
after-backups-en-1440: layout width 1440 (screen 1440) scrollWidth 1440 — wider than the screen: false
after-backups-en-1440: banners ["alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/grimm","alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/metub","alert-banner-warning: The hub connection is off — central monitoring is not running\nSystem m"]
after-launcher-en-390: html lang en, version 0.304.0-layout.rc2
after-launcher-en-390: layout width 390 (screen 390) scrollWidth 390 — wider than the screen: false
after-launcher-en-390: banners ["alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/grimm","alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/metub","alert-banner-warning: The hub connection is off — central monitoring is not running\nSystem m"]
after-launcher-en-390: share button {"left":16,"right":192,"top":470,"text":"Share the launcher"} past the screen edge: false
after-apps-en-390: html lang en, version 0.304.0-layout.rc2
after-apps-en-390: layout width 390 (screen 390) scrollWidth 390 — wider than the screen: false
after-apps-en-390: banners ["alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/grimm","alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/metub","alert-banner-warning: The hub connection is off — central monitoring is not running\nSystem m"]
after-apps-en-390: 61 cards; name text under a tag on 0 []; tag outside card on 0; logo top minus name top [-3]; address on more than one line on 0
after-apps-en-390: {"name":"FileBrowser","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-3,"addr":"","addrLines":0,"addrTitle":""}
after-apps-en-390: {"name":"Immich","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-3,"addr":"","addrLines":0,"addrTitle":""}
after-apps-en-390: {"name":"Paperless-ngx","tags":2,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-3,"addr":"paperless.enkisfelhom.hu ↗","addrLines":1,"addrTitle":"paperless.enkisfelhom.hu"}
after-backups-en-390: html lang en, version 0.304.0-layout.rc2
after-backups-en-390: layout width 390 (screen 390) scrollWidth 390 — wider than the screen: false
after-backups-en-390: banners ["alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/grimm","alert-banner-warning: Adattároló nem elérhető: /mnt/felhom-drives/scratch_hdd/userdata/metub","alert-banner-warning: The hub connection is off — central monitoring is not running\nSystem m"]
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

@@ -0,0 +1,56 @@
before-launcher-hu-1440: html lang hu, version 0.303.0
before-launcher-hu-1440: layout width 1440 (screen 1440) scrollWidth 1440 — wider than the screen: false
before-launcher-hu-1440: banners ["alert-banner-info: + 5 további figyelmeztetés\n→"]
before-launcher-hu-1440: share button {"left":1207,"right":1408,"top":99,"text":"Indítópult megosztása"} past the screen edge: false
before-apps-hu-1440: html lang hu, version 0.303.0
before-apps-hu-1440: layout width 1440 (screen 1440) scrollWidth 1440 — wider than the screen: false
before-apps-hu-1440: banners ["alert-banner-info: + 5 további figyelmeztetés\n→"]
before-apps-hu-1440: 61 cards; name text under a tag on 0 []; tag outside card on 0; logo top minus name top [-5,9,21]; address on more than one line on 2
before-apps-hu-1440: {"name":"FileBrowser","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-5,"addr":"","addrLines":0,"addrTitle":""}
before-apps-hu-1440: {"name":"Immich","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-5,"addr":"","addrLines":0,"addrTitle":""}
before-apps-hu-1440: {"name":"Paperless-ngx","tags":2,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":21,"addr":"paperless.enkisfelhom.hu ↗","addrLines":2,"addrTitle":""}
before-backups-hu-1440: html lang hu, version 0.303.0
before-backups-hu-1440: layout width 1440 (screen 1440) scrollWidth 1440 — wider than the screen: false
before-backups-hu-1440: banners ["alert-banner-info: + 5 további figyelmeztetés\n→"]
before-launcher-hu-390: html lang hu, version 0.303.0
before-launcher-hu-390: layout width 425 (screen 390) scrollWidth 425 — wider than the screen: true
before-launcher-hu-390: banners ["alert-banner-info: + 5 további figyelmeztetés\n→"]
before-launcher-hu-390: share button {"left":290,"right":424,"top":134,"text":"Indítópult megosztása"} past the screen edge: true
before-apps-hu-390: html lang hu, version 0.303.0
before-apps-hu-390: layout width 519 (screen 390) scrollWidth 519 — wider than the screen: true
before-apps-hu-390: banners ["alert-banner-info: + 5 további figyelmeztetés\n→"]
before-apps-hu-390: 61 cards; name text under a tag on 0 []; tag outside card on 0; logo top minus name top [-5,9,21]; address on more than one line on 2
before-apps-hu-390: {"name":"FileBrowser","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-5,"addr":"","addrLines":0,"addrTitle":""}
before-apps-hu-390: {"name":"Immich","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-5,"addr":"","addrLines":0,"addrTitle":""}
before-apps-hu-390: {"name":"Paperless-ngx","tags":2,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":21,"addr":"paperless.enkisfelhom.hu ↗","addrLines":2,"addrTitle":""}
before-backups-hu-390: html lang hu, version 0.303.0
before-backups-hu-390: layout width 390 (screen 390) scrollWidth 390 — wider than the screen: false
before-backups-hu-390: banners ["alert-banner-info: + 5 további figyelmeztetés\n→"]
before-launcher-en-1440: html lang en, version 0.303.0
before-launcher-en-1440: layout width 1440 (screen 1440) scrollWidth 1440 — wider than the screen: false
before-launcher-en-1440: banners ["alert-banner-info: + 5 more warnings\n→"]
before-launcher-en-1440: share button {"left":1232,"right":1408,"top":99,"text":"Share the launcher"} past the screen edge: false
before-apps-en-1440: html lang en, version 0.303.0
before-apps-en-1440: layout width 1440 (screen 1440) scrollWidth 1440 — wider than the screen: false
before-apps-en-1440: banners ["alert-banner-info: + 5 more warnings\n→"]
before-apps-en-1440: 61 cards; name text under a tag on 1 ["Paperless-ngx"]; tag outside card on 0; logo top minus name top [-5,9,21]; address on more than one line on 2
before-apps-en-1440: {"name":"FileBrowser","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-5,"addr":"","addrLines":0,"addrTitle":""}
before-apps-en-1440: {"name":"Immich","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-5,"addr":"","addrLines":0,"addrTitle":""}
before-apps-en-1440: {"name":"Paperless-ngx","tags":2,"nameUnderTag":true,"tagOutsideCard":false,"logoTopMinusNameTop":21,"addr":"paperless.enkisfelhom.hu ↗","addrLines":2,"addrTitle":""}
before-backups-en-1440: html lang en, version 0.303.0
before-backups-en-1440: layout width 1440 (screen 1440) scrollWidth 1440 — wider than the screen: false
before-backups-en-1440: banners ["alert-banner-info: + 5 more warnings\n→"]
before-launcher-en-390: html lang en, version 0.303.0
before-launcher-en-390: layout width 395 (screen 390) scrollWidth 395 — wider than the screen: true
before-launcher-en-390: banners ["alert-banner-info: + 5 more warnings\n→"]
before-launcher-en-390: share button {"left":284,"right":395,"top":134,"text":"Share the launcher"} past the screen edge: true
before-apps-en-390: html lang en, version 0.303.0
before-apps-en-390: layout width 434 (screen 390) scrollWidth 434 — wider than the screen: true
before-apps-en-390: banners ["alert-banner-info: + 5 more warnings\n→"]
before-apps-en-390: 61 cards; name text under a tag on 0 []; tag outside card on 0; logo top minus name top [-5,21,8]; address on more than one line on 1
before-apps-en-390: {"name":"FileBrowser","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-5,"addr":"","addrLines":0,"addrTitle":""}
before-apps-en-390: {"name":"Immich","tags":1,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":-5,"addr":"","addrLines":0,"addrTitle":""}
before-apps-en-390: {"name":"Paperless-ngx","tags":2,"nameUnderTag":false,"tagOutsideCard":false,"logoTopMinusNameTop":21,"addr":"paperless.enkisfelhom.hu ↗","addrLines":2,"addrTitle":""}
before-backups-en-390: html lang en, version 0.303.0
before-backups-en-390: layout width 390 (screen 390) scrollWidth 390 — wider than the screen: false
before-backups-en-390: banners ["alert-banner-info: + 5 more warnings\n→"]
@@ -0,0 +1,3 @@
stacks_full cards 8 | old + the template change == new: True | visible text identical: True | bytes 60494 -> 61264
stacks_unhealthy_stop cards 1 | old + the template change == new: True | visible text identical: True | bytes 43371 -> 43452
stacks_install_interrupted cards 1 | old + the template change == new: True | visible text identical: True | bytes 43324 -> 43405
@@ -0,0 +1,55 @@
# Red proof: the three new tests run against 05e12921's stacks.html, style.css and handlers.go (the tests from 423b6d3).
--- FAIL: TestStackCardHeaderLayout (0.08s)
dashboard_layout_test.go:54: hu card 0: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:54: hu card 1: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:54: hu card 2: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:54: hu card 3: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:54: hu card 4: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:54: hu card 5: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:54: hu card 6: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:54: hu card 7: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:72: hu: 0 addresses, want 2 (filebrowser, privatebin)
dashboard_layout_test.go:54: en card 0: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:54: en card 1: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:54: en card 2: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:54: en card 3: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:54: en card 4: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:54: en card 5: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:54: en card 6: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:54: en card 7: want the title row, then a .stack-tags row (title 13, tags -1)
dashboard_layout_test.go:72: en: 0 addresses, want 2 (filebrowser, privatebin)
dashboard_layout_test.go:82: .stack-detail-header must stack the title row over the tags, not spread them on one row:
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: .75rem;
dashboard_layout_test.go:85: .stack-title-row must align the logo to the top of the name:
display: flex;
align-items: center;
gap: .75rem;
flex: 1;
min-width: 0;
dashboard_layout_test.go:87: style.css has no top-level ".stack-title-text" rule
--- FAIL: TestR907_PageHeaderWrapsOnAPhone (0.06s)
dashboard_layout_test.go:113: the phone block must let .page-header wrap
dashboard_layout_test.go:116: the share button's text must stay whole when it drops to its own line
dashboard_layout_test.go:122: the phone block lacks \.alert-banner \{[^}]*flex-wrap: wrap
dashboard_layout_test.go:122: the phone block lacks \.alert-message \{[^}]*min-width: 0[^}]*overflow-wrap: anywhere
dashboard_layout_test.go:122: the phone block lacks \.alert-link \{[^}]*flex-basis: 100%
dashboard_layout_test.go:126: .alert-link must take the banner's colour, not the browser's link blue: margin-left: auto; white-space: nowrap;
--- FAIL: TestR906_OverflowCountsOnlyThisPagesBannerAlerts (0.08s)
r906_overflow_test.go:48: /launcher: an overflow line is shown, but this page shows no more than one banner alert
r906_overflow_test.go:51: /launcher: 0 warning banners, want 1 (the hub-off warning)
r906_overflow_test.go:48: /stacks: an overflow line is shown, but this page shows no more than one banner alert
r906_overflow_test.go:51: /stacks: 0 warning banners, want 1 (the hub-off warning)
r906_overflow_test.go:48: /backups: an overflow line is shown, but this page shows no more than one banner alert
r906_overflow_test.go:51: /backups: 0 warning banners, want 1 (the hub-off warning)
r906_overflow_test.go:48: /monitoring: an overflow line is shown, but this page shows no more than one banner alert
r906_overflow_test.go:51: /monitoring: 0 warning banners, want 1 (the hub-off warning)
r906_overflow_test.go:48: /launcher?lang=en: an overflow line is shown, but this page shows no more than one banner alert
r906_overflow_test.go:51: /launcher?lang=en: 0 warning banners, want 1 (the hub-off warning)
r906_overflow_test.go:48: /stacks?lang=en: an overflow line is shown, but this page shows no more than one banner alert
r906_overflow_test.go:51: /stacks?lang=en: 0 warning banners, want 1 (the hub-off warning)
FAIL
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/web 0.253s
FAIL
@@ -0,0 +1,93 @@
// Dashboard layout evidence (2026-10-08): scratch guest 9202, headless Chrome inside 9202, through traefik with the real
// host name. Session cookie from a 0600 file (never printed). Per page and width: a picture, plus MEASUREMENTS:
// sideways scroll, and on /stacks for each card whether the name box overlaps any tag box and the logo/name top offset.
const puppeteer = require('puppeteer');
const fs = require('fs');
const sleep = ms => new Promise(r => setTimeout(r, ms));
const HOST = 'felhom.enkisfelhom.hu', BASE = 'https://' + HOST;
const sess = fs.readFileSync('/out/session.txt', 'utf8').trim();
const TAG = process.env.TAG; // before | after
const out = [];
let LANG = 'hu';
function log(...a) { const l = a.join(' '); console.log(l); out.push(l); }
async function setLang(p, lang) {
await p.goto(BASE + '/launcher', {waitUntil: 'networkidle2'});
const btn = await p.$(`button.lang-globe-item[value="${lang}"]`);
if (!btn) throw new Error('no globe item ' + lang);
await p.evaluate(b => b.closest('form').submit(), btn);
await p.waitForNavigation({waitUntil: 'networkidle2'}).catch(() => {});
log('language now', await p.$eval('html', e => e.lang));
}
async function measure(p, name) {
const m = await p.evaluate(() => {
const r = {scrollW: document.documentElement.scrollWidth, innerW: window.innerWidth};
r.banner = Array.from(document.querySelectorAll('.alerts-container .alert-banner')).map(b => b.className.replace('alert-banner ', '') + ': ' + b.innerText.trim().slice(0, 70));
const btn = document.querySelector('.share-open-btn');
if (btn) { const b = btn.getBoundingClientRect(); r.share = {left: Math.round(b.left), right: Math.round(b.right), top: Math.round(b.top), text: btn.innerText.trim()}; }
r.cards = [];
for (const c of document.querySelectorAll('.stack-detail-card')) {
const h = c.querySelector('h3'), logo = c.querySelector('.stack-logo-lg');
if (!h || !logo) continue;
const rg = document.createRange(); rg.selectNodeContents(h);
const tr = rg.getBoundingClientRect(), lr = logo.getBoundingClientRect(), cr = c.getBoundingClientRect();
const tags = Array.from(c.querySelectorAll('.tag')).map(t => t.getBoundingClientRect());
const overlap = tags.some(t => !(t.right <= tr.left || t.left >= tr.right || t.bottom <= tr.top || t.top >= tr.bottom));
const outside = tags.some(t => t.right > cr.right + 0.5);
const addr = c.querySelector('.subdomain-link');
let addrLines = 0;
if (addr) { const ar = document.createRange(); ar.selectNodeContents(addr); { const rs = Array.from(ar.getClientRects()).filter(x => x.width > 0); const t0 = Math.min(...rs.map(x => x.top)); const h0 = Math.min(...rs.map(x => x.height)); addrLines = 1 + rs.filter(x => x.top > t0 + h0 * 0.6).length; } }
r.cards.push({name: h.innerText.trim(), tags: tags.length, nameUnderTag: overlap, tagOutsideCard: outside,
logoTopMinusNameTop: Math.round(lr.top - tr.top), addr: addr ? addr.innerText.trim().replace(/\s+/g, ' ') : '', addrLines,
addrTitle: addr ? addr.title : ''});
}
return r;
});
log(`${name}: layout width ${m.innerW} (screen ${process.env.W}) scrollWidth ${m.scrollW} — wider than the screen: ${m.innerW > +process.env.W || m.scrollW > +process.env.W}`);
log(`${name}: banners ${JSON.stringify(m.banner)}`);
if (m.share) log(`${name}: share button ${JSON.stringify(m.share)} past the screen edge: ${m.share.right > +process.env.W}`);
if (m.cards.length) {
const ov = m.cards.filter(c => c.nameUnderTag).map(c => c.name);
const offs = [...new Set(m.cards.map(c => c.logoTopMinusNameTop))];
log(`${name}: ${m.cards.length} cards; name text under a tag on ${ov.length} ${JSON.stringify(ov)}; tag outside card on ${m.cards.filter(c => c.tagOutsideCard).length}; logo top minus name top ${JSON.stringify(offs)}; address on more than one line on ${m.cards.filter(c => c.addrLines > 1).length}`);
for (const c of m.cards.filter(c => /paperless|filebrowser|immich/i.test(c.name))) log(`${name}: ${JSON.stringify(c)}`);
}
}
async function shot(p, name, path) {
await p.goto(BASE + path + (LANG === 'en' ? '?lang=en' : ''), {waitUntil: 'networkidle2'});
await sleep(1200);
log(`${TAG}-${name}: html lang ${await p.$eval('html', e => e.lang)}, version ${await p.evaluate(() => (document.body.innerText.match(/\b0\.\d+\.\d+\S*/) || ['?'])[0])}`);
await p.screenshot({path: `/out/${TAG}-${name}.png`});
await measure(p, `${TAG}-${name}`);
}
async function cards(p, name) { // the three cards the brief names, as one element picture each
for (const [key, re] of [['installed', /paperless/i], ['notinstalled', /immich/i], ['builtin', /filebrowser|f.jlkezel/i]]) {
const hs = await p.$$('.stack-detail-card');
for (const h of hs) {
const t = await h.$eval('h3', e => e.innerText).catch(() => '');
if (re.test(t)) { await h.screenshot({path: `/out/${TAG}-${name}-card-${key}.png`}); break; }
}
}
}
(async () => {
const b = await puppeteer.launch({args: ['--no-sandbox', '--ignore-certificate-errors', `--host-resolver-rules=MAP * ${process.env.TRAEFIK}`]});
const p = await b.newPage();
const [k, v] = sess.split('=');
await p.setCookie({name: k, value: v, domain: HOST, path: '/', secure: true, httpOnly: true});
for (const lang of ['hu', 'en']) {
process.env.W = '1440';
await p.setViewport({width: 1440, height: 900, deviceScaleFactor: 1});
LANG = lang;
await shot(p, `launcher-${lang}-1440`, '/launcher');
await shot(p, `apps-${lang}-1440`, '/stacks');
await cards(p, `apps-${lang}-1440`);
await shot(p, `backups-${lang}-1440`, '/backups');
process.env.W = '390';
await p.setViewport({width: 390, height: 844, deviceScaleFactor: 2, isMobile: true, hasTouch: true});
await shot(p, `launcher-${lang}-390`, '/launcher');
await shot(p, `apps-${lang}-390`, '/stacks');
await cards(p, `apps-${lang}-390`);
await shot(p, `backups-${lang}-390`, '/backups');
}
fs.writeFileSync(`/out/${TAG}-measure.txt`, out.join('\n') + '\n');
await b.close();
})().catch(e => { console.error(e); process.exit(1); });
File diff suppressed because one or more lines are too long