Commit eec36526d2
eec36526d2721d98ac0d9446ba4e2975d16b5d8b
parent: 9ef1f3a945
Verified · cmc ci/build: success
cmc <hello@cleberg.net> · 2026-08-26T22:33:56Z
web: Settings gets a labelled rail row; tidy the account cell
A 14px gear on the rail was unreadable, so Settings becomes a row pinned
above the account cell — outside the scrolling body, so it is always
reachable. Log out moves to the far edge, and the profile link's hover
underline no longer runs under the avatar square.
internal/httpd/account.go
+2 −1
| @@ -48,13 +48,14 @@ func (s *Server) accountForm(w http.ResponseWriter, r *http.Request, u store.Use |
| 48 | 48 | |
| 49 | 49 | s.render(w, "account.html", struct { |
| 50 | 50 | basePage |
| 51 | Tab string // marks the rail's Settings row as current |
| 51 | 52 | Keys []accountKey |
| 52 | 53 | PGP []accountPGP |
| 53 | 54 | Emails []store.Email |
| 54 | 55 | Host string |
| 55 | 56 | Notice string |
| 56 | 57 | Message string |
| 57 | | }{s.baseFor(u), keys, pgp, emails, s.cfg.SiteHost(), |
| 58 | }{s.baseFor(u), "account", keys, pgp, emails, s.cfg.SiteHost(), |
| 58 | 59 | r.URL.Query().Get("e"), r.URL.Query().Get("m")}) |
| 59 | 60 | } |
| 60 | 61 | |
internal/web/static/style.css
+10
| @@ -258,6 +258,12 @@ ul.raillist.wide .owner { font-size: var(--fs-0); } |
| 258 | 258 | padding: 0 0.35rem; |
| 259 | 259 | border-radius: var(--r-sm); |
| 260 | 260 | } |
| 261 | /* pinned above the account cell: always reachable, never scrolled away */ |
| 262 | .railpinned { |
| 263 | flex: none; |
| 264 | padding: var(--sp-2) 0; |
| 265 | border-top: 1px solid var(--shell-line); |
| 266 | } |
| 261 | 267 | .railfoot { |
| 262 | 268 | flex: none; |
| 263 | 269 | border-top: 1px solid var(--shell-line); |
| @@ -273,8 +279,11 @@ ul.raillist.wide .owner { font-size: var(--fs-0); } |
| 273 | 279 | } |
| 274 | 280 | .railfoot a { color: var(--shell-fg); } |
| 275 | 281 | a.railuser { display: inline-flex; align-items: center; gap: var(--sp-2); } |
| 282 | /* the square is a graphic, not text: the link's hover underline stops at it */ |
| 283 | a.railuser:hover .avatar { text-decoration: none; } |
| 276 | 284 | .railfoot .railsettings { color: var(--shell-muted); display: inline-flex; } |
| 277 | 285 | .railfoot .railsettings:hover { color: var(--shell-fg); } |
| 286 | .railfoot form { margin-left: auto; } |
| 278 | 287 | .railfoot .linklike { |
| 279 | 288 | background: none; border: 0; padding: 0; cursor: pointer; |
| 280 | 289 | color: var(--shell-muted); font: inherit; text-decoration: underline; |
| @@ -399,6 +408,7 @@ nav.tabs a i { |
| 399 | 408 | ul.raillist a[aria-current] { border-left: 0; border-bottom-color: var(--shell-mark); } |
| 400 | 409 | /* the rail is a horizontal strip here: keep the account cell compact */ |
| 401 | 410 | .railfoot { border-top: 0; padding: var(--sp-2); } |
| 411 | .railpinned { border-top: 0; padding: 0; } |
| 402 | 412 | .content { padding: var(--sp-4) var(--sp-4) var(--sp-5); } |
| 403 | 413 | .repohead { padding: var(--sp-3) var(--sp-4) 0; } |
| 404 | 414 | } |
internal/web/templates/layout.html
+3 −1
| @@ -39,9 +39,11 @@ |
| 39 | 39 | </div> |
| 40 | 40 | {{end}} |
| 41 | 41 | </div> |
| 42 | <ul class="raillist railpinned"> |
| 43 | {{if .Viewer}}<li><a {{if eq (str . "Tab") "account"}}aria-current="page" {{end}}href="/settings">Settings</a></li>{{end}} |
| 44 | </ul> |
| 42 | 45 | <div class="railfoot"> |
| 43 | 46 | {{if .Viewer}}<a class="railuser" href="/{{.Viewer}}"><span class="avatar">{{initial .Viewer}}</span>{{.Viewer}}</a> |
| 44 | | <a class="railsettings" href="/settings" title="Account settings" aria-label="Account settings"><svg class="icon" width="14" height="14" viewBox="0 0 16 16" aria-hidden="true" fill="currentColor"><path d="M8 4.754a3.246 3.246 0 1 0 0 6.492 3.246 3.246 0 0 0 0-6.492ZM6.254 8a1.746 1.746 0 1 1 3.492 0 1.746 1.746 0 0 1-3.492 0Z"/><path d="M9.796 1.343c-.527-1.79-3.065-1.79-3.592 0l-.094.319a.873.873 0 0 1-1.255.52l-.292-.16c-1.64-.892-3.433.902-2.54 2.541l.159.292a.873.873 0 0 1-.52 1.255l-.319.094c-1.79.527-1.79 3.065 0 3.592l.319.094a.873.873 0 0 1 .52 1.255l-.16.292c-.892 1.64.901 3.434 2.541 2.54l.292-.159a.873.873 0 0 1 1.255.52l.094.319c.527 1.79 3.065 1.79 3.592 0l.094-.319a.873.873 0 0 1 1.255-.52l.292.16c1.64.893 3.434-.902 2.54-2.541l-.159-.292a.873.873 0 0 1 .52-1.255l.319-.094c1.79-.527 1.79-3.065 0-3.592l-.319-.094a.873.873 0 0 1-.52-1.255l.16-.292c.893-1.64-.902-3.433-2.541-2.54l-.292.159a.873.873 0 0 1-1.255-.52l-.094-.319Zm-2.153.425c.18-.613 1.048-.613 1.229 0l.093.319a2.373 2.373 0 0 0 3.416 1.416l.292-.16c.561-.306 1.175.308.87.87l-.16.292a2.373 2.373 0 0 0 1.415 3.416l.319.093c.613.18.613 1.048 0 1.229l-.319.093a2.373 2.373 0 0 0-1.416 3.416l.16.292c.305.561-.309 1.175-.87.87l-.292-.16a2.373 2.373 0 0 0-3.416 1.415l-.093.319c-.181.613-1.049.613-1.229 0l-.093-.319a2.373 2.373 0 0 0-3.416-1.416l-.292.16c-.561.305-1.175-.309-.87-.87l.16-.292a2.373 2.373 0 0 0-1.415-3.416l-.32-.093c-.612-.181-.612-1.049 0-1.229l.32-.093a2.373 2.373 0 0 0 1.416-3.416l-.16-.292c-.306-.561.308-1.175.87-.87l.292.16a2.373 2.373 0 0 0 3.416-1.416l.093-.318Z"/></svg></a> |
| 45 | 47 | <form method="post" action="/logout"><button type="submit" class="linklike">Log out</button></form> |
| 46 | 48 | {{else}}<a href="/login">Sign in</a>{{end}} |
| 47 | 49 | </div> |