Commit 8eda4ca189
8eda4ca189404ac7f920ebefd5f1bf3c415eac69
parent: 1790a024c2
Verified · cmc ci/build: success
cmc <hello@cleberg.net> · 2026-08-26T01:59:10Z
web: keep the repo header identical across a repo's tabs
The header sits above the tab bar, so anything rendered on some tabs and
not others moves the navigation between clicks of that same navigation.
Describing the repo only on its home tab dropped the tabs 58px between
Code and Issues.
Description, topics, website and mirrors now render on every repo page,
and the title is the same size whether it is the h1 of the repo home or
the p that stands in elsewhere — the element still differs so each page
keeps its own h1, but the geometry does not. Tab bar sits at a fixed
offset on code, issues, merge requests and blob pages alike.
e2e/design_test.go
+9
| @@ -139,6 +139,15 @@ func TestReadmeRelativeLinks(t *testing.T) { |
| 139 | 139 | t.Errorf("explore row missing %q", want) |
| 140 | 140 | } |
| 141 | 141 | } |
| 142 | // The repo header renders the same on every tab of the repo. It sits |
| 143 | // above the tab bar, so anything that appears on one tab and not |
| 144 | // another moves the navigation between clicks of that navigation. |
| 145 | for _, page := range []string{"", "/issues", "/mrs", "/releases"} { |
| 146 | _, body := inst.get(t, "/alice/site"+page) |
| 147 | if !strings.Contains(body, `href="/explore?q=web"`) { |
| 148 | t.Errorf("repo header topics missing on /alice/site%s", page) |
| 149 | } |
| 150 | } |
| 142 | 151 | } |
| 143 | 152 | |
| 144 | 153 | func TestWebInteractions(t *testing.T) { |
internal/web/static/style.css
+3 −1
| @@ -288,6 +288,9 @@ a.railuser { display: inline-flex; align-items: center; gap: var(--sp-2); } |
| 288 | 288 | } |
| 289 | 289 | .repohead .identity { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; } |
| 290 | 290 | .repohead .identity .grow { flex: 1; } |
| 291 | /* h1 on the repo home, p elsewhere so each page keeps its own h1 — but |
| 292 | identical in size, because the tabs sit below this and navigation must |
| 293 | not move when you use it */ |
| 291 | 294 | .repotitle { |
| 292 | 295 | margin: 0; |
| 293 | 296 | font-size: var(--fs-4); |
| @@ -295,7 +298,6 @@ a.railuser { display: inline-flex; align-items: center; gap: var(--sp-2); } |
| 295 | 298 | letter-spacing: -0.02em; |
| 296 | 299 | line-height: 1.3; |
| 297 | 300 | } |
| 298 | | h1.repotitle { font-size: var(--fs-5); } |
| 299 | 301 | .repotitle a { color: var(--fg); } |
| 300 | 302 | .repotitle a.owner { color: var(--muted); font-weight: 400; } |
| 301 | 303 | .repotitle a:hover { color: var(--accent); text-decoration: none; } |
internal/web/templates/layout.html
−2
| @@ -57,13 +57,11 @@ |
| 57 | 57 | <span class="grow"></span> |
| 58 | 58 | {{if $.Viewer}}<form method="post" action="/{{.OwnerName}}/{{.Name}}/pin" class="inline"><button type="submit" class="btn" aria-pressed="{{if field $ "Pinned"}}true{{else}}false{{end}}">{{if field $ "Pinned"}}★ Pinned{{else}}☆ Pin{{end}}</button></form>{{end}} |
| 59 | 59 | </div> |
| 60 | | {{if field $ "RepoHome"}} |
| 61 | 60 | {{with field $ "Desc"}}<p class="repodesc">{{.}}</p>{{end}} |
| 62 | 61 | {{with field $ "Topics"}}<p class="topics">{{range .}}<a class="chip topic" href="/explore?q={{.}}">{{.}}</a> {{end}}</p>{{end}} |
| 63 | 62 | {{with $.Repo.Settings.Website}}<p class="repometa"><a href="{{.}}" rel="nofollow">{{.}}</a></p>{{end}} |
| 64 | 63 | {{range field $ "Mirrors"}}<p class="repometa">{{if eq .Direction "push"}}Mirrors to{{else}}Mirrors from{{end}} <a href="{{.URL}}" rel="nofollow">{{.Target}}</a>{{if .Error}} · <span class="bad">sync error: {{.Error}}</span>{{else if .Synced}} · synced {{.Synced}}{{end}}</p> |
| 65 | 64 | {{end}} |
| 66 | | {{end}} |
| 67 | 65 | <nav class="tabs" aria-label="Repository"> |
| 68 | 66 | {{$top := topTab (str $ "Tab")}} |
| 69 | 67 | <a {{if eq $top "code"}}aria-current="page" {{end}}href="/{{.OwnerName}}/{{.Name}}">Code</a> |