A CLI-first git forge. cli forge git self-hosted

https://gitbay.org

Commit 55d8573ae4

55d8573ae49fba7d7deec20f4327e7101598bcac

parent: da232bfde4

Verified · cmc ci/build: success ci/test: success

cmc <hello@cleberg.net> · 2026-09-19 05:28 UTC

web: the icon nav is a top bar at every width

The 48px row of glyphs that the shell used below 52rem is now the only
layout; the 3.5rem left column is gone, along with its --rail-w token.
The shell is a column flex so the footer still meets the bottom of a
short page. The landing picture is recaptured under the new shell.
internal/web/static/img/mr-dark.png

Binary file not shown.

internal/web/static/img/mr-light.png

Binary file not shown.

internal/web/static/style.css +19 −50
@@ -120,7 +120,6 @@
120120 --sp-7: 48px;
121121
122122 /* the rail: a column the width of one hit target, a row one tall */
123 --rail-w: 3.5rem;
124123 --rail-hit: 40px;
125124 --rail-strip-h: 48px;
126125 --rail-mark: 24px;
@@ -251,33 +250,28 @@ a.skip {
251250}
252251a.skip:focus { top: var(--sp-3); text-decoration: none; }
253252
254/* ---- rail: one glyph per destination, no labels ----
255 The column is the width of a hit target and nothing else. Every item is
256 a square link carrying an inline svg, its name in an aria-label and in a
257 visually hidden span, so the nav reads the same to a screen reader as
258 the old text list did. */
253/* ---- rail: one row of glyphs across the top, no labels ----
254 One strip the height of a hit target, at every width: fixed squares,
255 no wrapping and no scrolling. Every item is a square link carrying an
256 inline svg, its name in an aria-label and in a visually hidden span, so
257 the nav reads the same to a screen reader as the old text list did. */
259258.rail {
260 flex: none;
261 width: var(--rail-w);
259 height: var(--rail-strip-h);
262260 background: var(--shell-bg);
263261 color: var(--shell-fg);
264 border-right: 1px solid var(--shell-line);
265 position: sticky;
266 top: 0;
267 height: 100vh;
262 border-bottom: 1px solid var(--shell-line);
268263 display: flex;
269 flex-direction: column;
264 flex-direction: row;
270265 align-items: center;
271 gap: var(--sp-1);
272 padding: var(--sp-3) 0;
266 padding: 0 var(--sp-1);
273267}
274268a.brand {
275269 display: flex;
276270 align-items: center;
277271 justify-content: center;
278272 flex: none;
279 width: var(--rail-hit);
280 height: var(--rail-hit);
273 width: var(--rail-mark-box);
274 height: var(--rail-strip-h);
281275 color: var(--shell-fg);
282276}
283277a.brand:hover { text-decoration: none; }
@@ -288,13 +282,11 @@ ul.raillist {
288282 margin: 0;
289283 padding: 0;
290284 display: flex;
291 flex-direction: column;
292285 align-items: center;
293 gap: var(--sp-1);
294286 min-width: 0;
295287}
296288/* the spacer that holds settings, admin and the account cell at the far
297 end of the rail in either orientation */
289 end of the row */
298290.railgap { flex: 1; }
299291.railicon {
300292 position: relative;
@@ -303,19 +295,18 @@ ul.raillist {
303295 justify-content: center;
304296 flex: none;
305297 width: var(--rail-hit);
306 height: var(--rail-hit);
298 height: var(--rail-strip-h);
307299 padding: 0;
308300 border: 0;
309301 background: none;
310302 color: var(--shell-fg);
311 border-radius: var(--r-ctl);
312303 cursor: pointer;
313304}
314305.railicon:hover { background: var(--shell-hover); text-decoration: none; }
315/* orange marks position — the rail's only accent */
306/* orange marks position along the bottom edge — the rail's only accent */
316307.railicon[aria-current] {
317308 background: var(--shell-hover);
318 box-shadow: inset 3px 0 0 var(--shell-mark);
309 box-shadow: inset 0 -2px 0 var(--shell-mark);
319310}
320311.count {
321312 font-size: var(--fs-0);
@@ -339,9 +330,7 @@ ul.raillist {
339330.railfoot {
340331 flex: none;
341332 display: flex;
342 flex-direction: column;
343333 align-items: center;
344 gap: var(--sp-1);
345334 min-width: 0;
346335}
347336.railfoot a { color: var(--shell-fg); }
@@ -352,7 +341,7 @@ a.railuser {
352341 justify-content: center;
353342 flex: none;
354343 width: var(--rail-hit);
355 height: var(--rail-hit);
344 height: var(--rail-strip-h);
356345}
357346a.railuser:hover { text-decoration: none; }
358347a.railuser .avatar { width: var(--rail-mark); height: var(--rail-mark); }
@@ -368,8 +357,9 @@ a.railuser .avatar { width: var(--rail-mark); height: var(--rail-mark); }
368357 font-weight: 600;
369358}
370359
371/* ---- shell ---- */
372.shell { display: flex; align-items: stretch; min-height: 100vh; }
360/* ---- shell: the rail above, then the pane, which fills the rest of the
361 viewport so the footer sits at the bottom of a short page ---- */
362.shell { display: flex; flex-direction: column; min-height: 100vh; }
373363.pane { flex: 1; min-width: 0; display: flex; flex-direction: column; }
374364main.content {
375365 flex: 1;
@@ -1476,27 +1466,6 @@ svg.icon { vertical-align: -0.125em; }
14761466}
14771467
14781468@media (max-width: 52rem) {
1479 /* the rail becomes one row of the same glyphs: fixed squares, no
1480 wrapping and no scrolling. The squares narrow a step further below
1481 30rem, where eleven of them would not otherwise fit a phone. */
1482 .shell { display: block; }
1483 .rail {
1484 width: auto;
1485 height: var(--rail-strip-h);
1486 position: static;
1487 flex-direction: row;
1488 align-items: center;
1489 gap: 0;
1490 padding: 0 var(--sp-1);
1491 border-right: 0;
1492 border-bottom: 1px solid var(--shell-line);
1493 overflow: visible;
1494 }
1495 a.brand { width: var(--rail-mark-box); height: var(--rail-strip-h); }
1496 ul.raillist, .railfoot { flex-direction: row; gap: 0; }
1497 .railicon, a.railuser { height: var(--rail-strip-h); border-radius: 0; }
1498 /* the current item is marked along the bottom edge in a row */
1499 .railicon[aria-current] { box-shadow: inset 0 -2px 0 var(--shell-mark); }
15001469 main.content { padding: var(--sp-4) var(--sp-4) var(--sp-5); }
15011470 footer { padding: var(--sp-4); }
15021471 .repohead { padding: var(--sp-3) var(--sp-4) 0; }