Files
felhom-controller/REPORT.md
T
admin 7f0b41c3e7 docs(report): v0.146.0 nav polish
Overwrites REPORT.md per convention. Records the two changes, the four design
decisions behind the accordion (real <button>, landing-pages-survive check,
server-side open state, grid-rows instead of max-height), and — importantly —
what could NOT be verified and why: the demo controller's password is
customer-owned since the claim flow, so the build-server credentials are stale
and a curl-login returns the Bejelentkezés page. The four red-proofed render
tests stand in for the server-side half; the visual leg needs Viktor's browser.

Also notes the fleet gap: v0.146.0 is live on the demo box but the golden still
bakes 0.143.0, deferred to the next session.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nn3VgQk9iwEGgyx6QJ2NvE
2026-07-18 21:04:06 +02:00

88 lines
5.7 KiB
Markdown

# REPORT — most recent implementation
## felhom-controller v0.146.0 — nav polish: styled scrollbars + collapsible sidebar groups — 2026-07-18
**Commits:** `24d23b8` (feature) + `fd93020` (render tests). **UI-only** — no behavioural, backup or
restore surface touched. **Deployed and live on demo guest 9201** (`0.146.0 Up (healthy)`).
**Green:** `go build ./... && go vet ./... && go test ./...` all pass. Design-v2 gates
`template_id_gate`, `emoji_gate`, `native_confirm_gate`, `offbox_rename_gate`, `mojibake_gate`,
`app_row_dedup_gate`**all PASS**.
### 1. Scrollbars (`style.css`)
The platform default is a light, chunky bar that reads as a bright stripe against the navy and
competes with the content it is scrolling. Now thin and hairline-coloured: `scrollbar-width: thin` +
`scrollbar-color` for Firefox **and** `::-webkit-scrollbar` (8px, thumb `--line`, hover `--text-3`,
`--radius`) for WebKit/Blink — both declared, because neither alone covers the browsers customers
actually use. The two surfaces that really scroll take their own panel background as the track
(`.sidebar``--bg-2`, `html``--bg-0`) so the gutter never shows through as a lighter channel.
Tokens only, no raw hexes, no inline styles.
### 2. Collapsible nav groups (`layout.html` + `style.css`, vanilla JS)
Tárhely, Biztonsági mentés and Megosztás are accordions with a chevron indicator; **exactly one open
at a time**, and clicking the open one closes it. Groups without sub-items (Vezérlőpult,
Alkalmazások, Rendszermonitor, Debug) are untouched plain links. Hungarian labels unchanged. No nav
restructuring beyond the accordion behaviour; no design-token changes.
Four decisions worth recording:
- **The header is a real `<button>`**, so keyboard and assistive-tech reachability come for free
rather than being simulated with `tabindex`/`role` on a div. `aria-expanded` + `aria-controls` +
a `:focus-visible` outline.
- **Nothing became unreachable when the header stopped being a link.** Every group's own landing
page is *also* its first sub-item (`/storage` → Meghajtók, `/backups` → Áttekintés, `/sharing`
Hálózati megosztás). This was checked before the conversion, not assumed — and it is now asserted
by a test, because if someone later drops one of those sub-links the destination becomes
unreachable **silently**, the header still looking clickable.
- **Progressive enhancement.** The group containing the active page is rendered open **server-side**
(`.is-open`), so the correct group is open before any JS executes and stays open if JS never runs.
The listener only handles clicks.
- **No layout jump.** The collapse animates `grid-template-rows: 0fr → 1fr` (with `min-height: 0` +
`overflow: hidden` on the sub-list) rather than `max-height`. That animates to the content's REAL
height, so there is no magic number to drift when a group gains or loses an item — the specific way
a `max-height` accordion rots. The toggle reserves its 3px active border as `transparent` so
becoming active adds no width shift. Transitions are .18s, and both the collapse and the chevron
rotation are disabled under `prefers-reduced-motion: reduce`.
### 3. Verification — and what could not be verified
**The screenshot leg was not done, and the reason is worth recording.** The demo controller's
password is **customer-owned** since the claim flow — Viktor set it as customer zero during the
2026-07-18 rehearsal — so the credentials on the build server are stale. A curl-login against the
live container returns HTTP 200 with `<title>Bejelentkezés — Felhom</title>` and sets no session
cookie, i.e. the login is refused. The visual leg needs Viktor's browser.
Rather than assert nothing, `internal/web/nav_accordion_test.go` pins the **server-side half**
the part a screenshot would confirm only for whichever page happened to be open — rendering through
the real shared layout via the same `loadTemplates()` path the server uses:
| Test | Property |
|---|---|
| `TestNavGroup_ActiveGroupRendersOpenServerSide` | all 7 sub-pages open their own group, with `aria-expanded=true` and an `.active` toggle, and **exactly one** group open — the count is asserted, not just the group we expected |
| `TestNavGroup_PageOutsideAnyGroupOpensNothing` | a top-level page (dashboard) forces nothing open |
| `TestNavGroup_EveryGroupLandingPageSurvivesAsASubItem` | each group's landing page still exists as a sub-link — the property the `<a>``<button>` conversion depended on |
| `TestNavGroup_HeaderIsARealButtonWithAControlsTarget` | the toggle is a real button and its `aria-controls` targets an element that exists |
**Red-proofed:** removing `{{if $storageOpen}} is-open{{end}}` from `layout.html` fails both the
open-group assertion and the exactly-one-open count on `storage` and `storage-network`, then passes
again when restored.
Independently, the deployed 0.146.0 container was confirmed to be **serving the new stylesheet**
(the `nav-group-toggle` / `scrollbar-width` rules are present in the CSS it returns), so the live
image really does carry this change.
### 4. Pre-existing, deliberately not bundled
`docker_run_volume_path_gate.py` still fails on `internal/appexport/estimate.go:179`. That is
ROADMAP **R-29**, unrelated to this change, verified to fail identically on the untouched tree — and
R-29 itself says not to bundle its fix into an unrelated feature commit.
### 5. Fleet note — the golden still bakes 0.143.0
v0.146.0 is live on the demo box, but the golden image was **not** rebuilt this session (deferred
rather than half-run — it is a nested-VM snapshot-revert procedure). So a freshly installed box
would land on 0.143.0 and self-update. Tracked on the felhom.eu ROADMAP pre-invite checklist, whose
target moved from 0.145.x to **0.146.0**.