internal/web/static/style.css
1278 lines · 41654 bytes
1/* gitbay stylesheet — Harbor: black and white ground, two accents with
2 separate jobs. Blue is what you can do (links, buttons, focus); orange
3 is where you are and what wants you (active nav, counts, pending state,
4 unverified signatures). Orange is never a button, so the two never
5 compete. One file, light and dark via prefers-color-scheme. Tokens
6 first; components use tokens only. No external requests: Atkinson
7 Hyperlegible is served from this origin. */
8
9@font-face {
10 font-family: "Atkinson Hyperlegible Next";
11 font-style: normal;
12 font-weight: 400 700;
13 font-display: swap;
14 src: url(/static/fonts/atkinson-next-roman.woff2) format("woff2");
15}
16@font-face {
17 font-family: "Atkinson Hyperlegible Next";
18 font-style: italic;
19 font-weight: 400 700;
20 font-display: swap;
21 src: url(/static/fonts/atkinson-next-italic.woff2) format("woff2");
22}
23@font-face {
24 font-family: "Atkinson Hyperlegible Mono";
25 font-style: normal;
26 font-weight: 400 600;
27 font-display: swap;
28 src: url(/static/fonts/atkinson-mono-roman.woff2) format("woff2");
29}
30
31:root {
32 /* declare native light+dark support: correct form controls and
33 scrollbars per scheme, and opt out of browser auto-darkening */
34 color-scheme: light dark;
35
36 /* ground and ink */
37 --bg: #ffffff;
38 --fg: #0d0d0d;
39 --muted: #595959; /* 7.00:1 on white */
40 --faint: #eaeaea; /* hairlines, row separators */
41 --line: #d4d4d4; /* control borders, table edges */
42 --surface: #ffffff;
43 --hover: #f5f5f5;
44 --code-bg: #f5f5f5;
45
46 /* blue: what you can do */
47 --accent: #0000f0; /* links, focus — 9.30:1 on white */
48 --accent-fg: #ffffff;
49 --fill: #0000f0; /* button grounds; white on it is 9.30:1 */
50
51 /* orange: where you are, what wants you */
52 --mark: #e4572e; /* bars and underlines — non-text, 3.0 bar */
53 --warn: #c2410c; /* the same orange at text size — 5.18:1 */
54
55 /* semantic */
56 --ok: #0a7d3c;
57 --bad: #c62828;
58 --done: #6b21a8; /* merged */
59 --neutral: #595959;
60
61 /* the rail is black in both schemes: the one brand constant */
62 --shell-bg: #000000;
63 --shell-fg: #f2f2f2;
64 --shell-muted: #8f8f8f;
65 --shell-line: #1c1c1c;
66 --shell-hover: #141414;
67 --shell-mark: #ff6b3d; /* 7.42:1 on black, both schemes */
68
69 /* type */
70 --sans: "Atkinson Hyperlegible Next", -apple-system, BlinkMacSystemFont,
71 "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
72 --mono: "Atkinson Hyperlegible Mono", ui-monospace, "SF Mono",
73 SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
74 --fs-0: 0.78rem;
75 --fs-1: 0.85rem;
76 --fs-2: 0.92rem;
77 --fs-3: 1rem;
78 --fs-4: 1.2rem;
79 --fs-5: 1.6rem;
80
81 /* spacing */
82 --sp-1: 0.25rem;
83 --sp-2: 0.5rem;
84 --sp-3: 0.75rem;
85 --sp-4: 1rem;
86 --sp-5: 1.5rem;
87 --sp-6: 2.5rem;
88
89 --chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23595959' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
90
91 /* radii: 2px everywhere — chart plates, not pills */
92 --r-sm: 2px;
93 --r-md: 2px;
94 --r-lg: 2px;
95 --r-pill: 2px;
96}
97@media (prefers-color-scheme: dark) {
98 :root {
99 --bg: #0a0a0a;
100 --fg: #f2f2f2;
101 --muted: #a1a1a1; /* 7.66:1 on #0a0a0a */
102 --faint: #1c1c1c;
103 --line: #2e2e2e;
104 --surface: #0f0f0f;
105 --hover: #161616;
106 --code-bg: #050505;
107 --accent: #5b6bff; /* 4.71:1 — pure #0000f0 is 2.13:1 here */
108 --accent-fg: #ffffff;
109 --fill: #0000f0; /* fills stay pure; white on it clears 9:1 */
110 --mark: #ff6b3d;
111 --warn: #ff6b3d;
112 --ok: #3fce7a;
113 --bad: #ff6b6b;
114 --done: #c084fc;
115 --neutral: #a1a1a1;
116 --chev: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23a1a1a1' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
117 }
118}
119
120* { box-sizing: border-box; }
121html { font-size: 15px; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
122body {
123 margin: 0;
124 background: var(--bg);
125 color: var(--fg);
126 font: var(--fs-3)/1.6 var(--sans);
127 min-height: 100vh;
128}
129
130a { color: var(--accent); text-decoration: none; }
131a:hover { text-decoration: underline; }
132
133/* one authored focus ring, so keyboard position is never the browser's
134 guess. Blue, because focus is an interactive state. */
135:focus-visible {
136 outline: 2px solid var(--accent);
137 outline-offset: 2px;
138 border-radius: 1px;
139}
140
141/* visually hidden, still read aloud: for headings a sighted reader gets
142 from the layout but a screen reader would otherwise miss */
143.vh {
144 position: absolute;
145 width: 1px; height: 1px;
146 margin: -1px; padding: 0; border: 0;
147 clip-path: inset(50%);
148 overflow: hidden;
149 white-space: nowrap;
150}
151/* the rail runs ahead of the content in source order, so give keyboard
152 and screen-reader users a way past it */
153a.skip {
154 position: absolute;
155 left: var(--sp-3); top: -3rem;
156 z-index: 50;
157 background: var(--fill);
158 color: #ffffff;
159 padding: var(--sp-2) var(--sp-4);
160 font-weight: 600;
161}
162a.skip:focus { top: var(--sp-3); text-decoration: none; }
163
164h1 { font-size: var(--fs-5); font-weight: 700; line-height: 1.18;
165 margin: 0 0 var(--sp-3); letter-spacing: -0.025em; text-wrap: balance; }
166h2 { font-size: var(--fs-4); font-weight: 700; line-height: 1.3;
167 margin: var(--sp-5) 0 var(--sp-3); letter-spacing: -0.015em; }
168h3 { font-size: var(--fs-3); font-weight: 600; margin: var(--sp-5) 0 var(--sp-2); }
169
170code, pre, .code, td.mode, td.size {
171 font-family: var(--mono);
172 font-size: var(--fs-1);
173}
174
175/* ---- shell: black rail, content pane ---- */
176.shell { display: flex; align-items: stretch; min-height: 100vh; }
177
178.rail {
179 flex: none;
180 width: 13rem;
181 background: var(--shell-bg);
182 color: var(--shell-fg);
183 border-right: 1px solid var(--shell-line);
184 position: sticky;
185 top: 0;
186 height: 100vh;
187 display: flex;
188 flex-direction: column;
189}
190a.brand {
191 display: flex;
192 align-items: center;
193 gap: var(--sp-2);
194 padding: var(--sp-3) var(--sp-4);
195 color: var(--shell-fg);
196 font-weight: 700;
197 font-size: var(--fs-3);
198 letter-spacing: -0.02em;
199 border-bottom: 1px solid var(--shell-line);
200}
201a.brand:hover { text-decoration: none; color: #ffffff; }
202a.brand svg.mark { display: block; flex: none; }
203a.brand span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
204
205.railbody { flex: 1; overflow-y: auto; padding: var(--sp-3) 0; }
206ul.raillist { list-style: none; margin: 0; padding: 0; }
207ul.raillist a {
208 display: block;
209 padding: 0.28rem var(--sp-4);
210 color: var(--shell-fg);
211 font-size: var(--fs-2);
212 border-left: 3px solid transparent;
213 overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
214}
215ul.raillist a:hover { background: var(--shell-hover); text-decoration: none; }
216/* orange marks position — the rail's only accent */
217ul.raillist a[aria-current] {
218 border-left-color: var(--shell-mark);
219 background: var(--shell-hover);
220 font-weight: 600;
221}
222ul.raillist .owner { color: var(--shell-muted); }
223ul.raillist.wide a { white-space: normal; padding-top: var(--sp-1); padding-bottom: var(--sp-1); }
224ul.raillist.wide b { display: block; font-weight: 500; font-size: var(--fs-1); }
225ul.raillist.wide .owner { font-size: var(--fs-0); }
226
227.raillabel {
228 display: flex;
229 align-items: center;
230 gap: var(--sp-2);
231 margin: var(--sp-4) 0 var(--sp-1);
232 padding: 0 var(--sp-4);
233 font-family: var(--mono);
234 font-size: var(--fs-0);
235 font-weight: 500;
236 letter-spacing: 0.1em;
237 text-transform: uppercase;
238 color: var(--shell-muted);
239}
240.raillabel .count {
241 font-family: var(--sans);
242 font-size: var(--fs-0);
243 font-weight: 700;
244 letter-spacing: 0;
245 background: var(--shell-mark);
246 color: #000000;
247 padding: 0 0.35rem;
248 border-radius: var(--r-sm);
249}
250.railfoot {
251 flex: none;
252 border-top: 1px solid var(--shell-line);
253 padding: var(--sp-2) var(--sp-4);
254 display: flex;
255 align-items: center;
256 gap: var(--sp-3);
257 font-size: var(--fs-2);
258}
259.railfoot a { color: var(--shell-fg); }
260a.railuser { display: inline-flex; align-items: center; gap: var(--sp-2); }
261.railfoot .linklike {
262 background: none; border: 0; padding: 0; cursor: pointer;
263 color: var(--shell-muted); font: inherit; text-decoration: underline;
264}
265.railfoot .linklike:hover { color: var(--shell-fg); }
266.avatar {
267 width: 1.4rem; height: 1.4rem; flex: none;
268 display: inline-grid; place-items: center;
269 background: var(--fill);
270 color: #ffffff;
271 font-size: var(--fs-0);
272 font-weight: 700;
273 border-radius: var(--r-sm);
274}
275
276.pane { flex: 1; min-width: 0; display: flex; flex-direction: column; }
277.content {
278 flex: 1;
279 padding: var(--sp-5) var(--sp-5) var(--sp-6);
280 max-width: 78rem;
281 width: 100%;
282}
283
284/* ---- repo header: identity and tabs on every page, the rest once ---- */
285.repohead {
286 padding: var(--sp-4) var(--sp-5) 0;
287 border-bottom: 1px solid var(--line);
288}
289.repohead .identity { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
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 */
294.repotitle {
295 margin: 0;
296 font-size: var(--fs-4);
297 font-weight: 700;
298 letter-spacing: -0.02em;
299 line-height: 1.3;
300}
301.repotitle a { color: var(--fg); }
302.repotitle a.owner { color: var(--muted); font-weight: 400; }
303.repotitle a:hover { color: var(--accent); text-decoration: none; }
304.repotitle .sep { color: var(--muted); margin: 0 0.12em; font-weight: 400; }
305.repodesc { margin: var(--sp-2) 0 0; color: var(--muted); font-size: var(--fs-2); max-width: 62ch; }
306.repometa { margin: var(--sp-1) 0 0; color: var(--muted); font-size: var(--fs-1); }
307.repohead .topics { margin: var(--sp-2) 0 0; }
308
309button.btn {
310 font: inherit;
311 font-size: var(--fs-1);
312 font-weight: 600;
313 padding: 0.15rem 0.7rem;
314 border: 1px solid var(--line);
315 border-radius: var(--r-sm);
316 background: var(--bg);
317 color: var(--fg);
318 cursor: pointer;
319}
320button.btn:hover { border-color: var(--accent); color: var(--accent); }
321button.btn[aria-pressed="true"] { border-color: var(--accent); color: var(--accent); }
322form.inline { display: inline; }
323
324nav.tabs {
325 display: flex;
326 gap: var(--sp-1);
327 margin-top: var(--sp-4);
328 overflow-x: auto;
329 scrollbar-width: none;
330}
331nav.tabs::-webkit-scrollbar { display: none; }
332nav.tabs a {
333 display: inline-flex;
334 align-items: center;
335 gap: var(--sp-2);
336 padding: var(--sp-2) var(--sp-3) 0.6rem;
337 color: var(--muted);
338 font-size: var(--fs-2);
339 white-space: nowrap;
340 border-bottom: 2px solid transparent;
341 margin-bottom: -1px;
342}
343nav.tabs a:hover { color: var(--fg); text-decoration: none; }
344/* orange marks position here too */
345nav.tabs a[aria-current] {
346 color: var(--fg);
347 font-weight: 700;
348 border-bottom-color: var(--mark);
349}
350nav.tabs a i {
351 font-style: normal;
352 font-family: var(--mono);
353 font-size: var(--fs-0);
354 background: var(--hover);
355 border-radius: var(--r-sm);
356 padding: 0 0.35rem;
357}
358
359/* ---- mobile: the rail becomes a single strip, not a wall of links ---- */
360@media (max-width: 52rem) {
361 .shell { display: block; }
362 .rail {
363 width: auto;
364 height: auto;
365 position: static;
366 flex-direction: row;
367 align-items: center;
368 gap: var(--sp-2);
369 border-right: 0;
370 border-bottom: 1px solid var(--shell-line);
371 overflow-x: auto;
372 }
373 a.brand { border-bottom: 0; padding-right: var(--sp-2); }
374 .railbody { flex: 1; overflow: visible; padding: 0; display: flex; align-items: center; }
375 /* pinned repos and the review queue both live on the dashboard, so the
376 strip keeps only what has nowhere else to go */
377 .railgroup { display: none; }
378 ul.raillist { display: flex; }
379 ul.raillist a { border-left: 0; border-bottom: 2px solid transparent; padding: var(--sp-2) var(--sp-3); }
380 ul.raillist a[aria-current] { border-left: 0; border-bottom-color: var(--shell-mark); }
381 .railfoot { border-top: 0; padding-left: var(--sp-2); }
382 .content { padding: var(--sp-4) var(--sp-4) var(--sp-5); }
383 .repohead { padding: var(--sp-3) var(--sp-4) 0; }
384}
385
386/* tables */
387table { border-collapse: collapse; width: 100%; }
388td {
389 padding: var(--sp-2) var(--sp-4) var(--sp-2) 0;
390 border-bottom: 1px solid var(--faint);
391 vertical-align: top;
392 font-size: var(--fs-2);
393}
394td:last-child { padding-right: 0; }
395td.size, td.mode { color: var(--muted); white-space: nowrap; }
396
397/* path bar on tree and blob pages */
398.pathbar {
399 display: flex;
400 flex-wrap: wrap;
401 align-items: center;
402 gap: var(--sp-2) var(--sp-3);
403 margin: var(--sp-3) 0;
404 font-size: var(--fs-2);
405}
406.pathbar .spacer { flex: 1; }
407.refchip {
408 display: inline-flex;
409 align-items: center;
410 gap: 0.3rem;
411 background: var(--surface);
412 border: 1px solid var(--faint);
413 border-radius: var(--r-md);
414 padding: 0.1rem 0.55rem;
415 font-family: var(--mono);
416 font-size: var(--fs-1);
417 color: var(--fg);
418}
419.pathbar .crumbs strong { color: var(--fg); }
420details.refmenu { position: relative; }
421details.refmenu summary { cursor: pointer; list-style: none; }
422details.refmenu summary::-webkit-details-marker { display: none; }
423details.refmenu summary::after { content: " ▾"; color: var(--muted); }
424details.refmenu .refdrop {
425 position: absolute;
426 z-index: 10;
427 top: calc(100% + 4px);
428 left: 0;
429 min-width: 12rem;
430 max-height: 20rem;
431 overflow-y: auto;
432 background: var(--bg);
433 border: 1px solid var(--line);
434 border-radius: var(--r-md);
435 box-shadow: 0 4px 16px rgba(0,0,0,0.12);
436 padding: var(--sp-1) 0;
437}
438details.refmenu .refdrop a {
439 display: block;
440 padding: var(--sp-1) var(--sp-3);
441 color: var(--fg);
442 font-family: var(--mono);
443 font-size: var(--fs-1);
444}
445details.refmenu .refdrop a:hover { background: var(--hover); text-decoration: none; }
446details.refmenu .refdrop a.allrefs { color: var(--accent); font-family: var(--sans); border-top: 1px solid var(--faint); margin-top: var(--sp-1); }
447
448/* file and refs tables: bordered cards, rows inside */
449table.tree, table.refs {
450 background: var(--surface);
451 border: 1px solid var(--line);
452 border-radius: var(--r-lg);
453 border-collapse: separate;
454 border-spacing: 0;
455 overflow: hidden;
456 margin-bottom: var(--sp-4);
457}
458table.tree td, table.refs td {
459 padding: var(--sp-2) var(--sp-4);
460 border-bottom: 1px solid var(--faint);
461}
462table.tree tr:last-child td, table.refs tr:last-child td { border-bottom: none; }
463table.tree tr:hover td, table.refs tr:hover td { background: var(--hover); }
464table.tree tr.cols th {
465 text-align: left;
466 font-weight: 500;
467 font-size: var(--fs-1);
468 color: var(--muted);
469 padding: var(--sp-1) var(--sp-4);
470 border-bottom: 1px solid var(--line);
471 background: var(--bg);
472}
473table.tree tr.cols:hover th { background: var(--bg); }
474table.tree th.size { text-align: right; }
475table.tree td.name { width: 100%; }
476table.tree td.name a { color: var(--fg); }
477table.tree td.name a:hover { color: var(--accent); }
478table.tree td.size { text-align: right; }
479table.tree td.empty, table.refs td.empty, li.empty, ul.loglist li.empty { color: var(--muted); }
480
481/* refs page */
482table.refs td.name { width: 100%; }
483table.refs td.sha { color: var(--muted); }
484
485/* card header (README) */
486.cardhead {
487 font-family: var(--mono);
488 font-size: var(--fs-1);
489 color: var(--muted);
490 border-bottom: 1px solid var(--faint);
491 margin: calc(-1 * var(--sp-4)) calc(-1 * var(--sp-5)) var(--sp-4);
492 padding: var(--sp-2) var(--sp-5);
493 background: var(--bg);
494 border-radius: var(--r-lg) var(--r-lg) 0 0;
495}
496
497/* log */
498ul.loglist {
499 list-style: none;
500 margin: var(--sp-3) 0;
501 padding: 0;
502 background: var(--surface);
503 border: 1px solid var(--line);
504 border-radius: var(--r-lg);
505 overflow: hidden;
506}
507ul.loglist li {
508 display: flex;
509 align-items: baseline;
510 gap: var(--sp-3);
511 padding: var(--sp-2) var(--sp-4);
512 border-bottom: 1px solid var(--faint);
513}
514ul.loglist li:last-child { border-bottom: none; }
515ul.loglist li:hover { background: var(--hover); }
516ul.loglist .commitmain { flex: 1; min-width: 0; }
517ul.loglist p { margin: 0; }
518ul.loglist .subject a { color: var(--fg); font-weight: 550; }
519ul.loglist .subject a:hover { color: var(--accent); }
520ul.loglist .commitside {
521 display: flex;
522 align-items: baseline;
523 gap: var(--sp-2);
524 white-space: nowrap;
525}
526p.pager { margin-top: var(--sp-4); }
527
528/* commit page */
529.commithead p { margin: var(--sp-1) 0; }
530.commithead h2 { margin-bottom: var(--sp-1); }
531code.fullsha { color: var(--muted); overflow-wrap: anywhere; }
532.empty-note { color: var(--muted); }
533.crumbs { color: var(--muted); font-size: var(--fs-2); }
534.desc, td.desc { color: var(--muted); }
535.error {
536 color: var(--fg);
537 border: 1px solid var(--bad);
538 border-left-width: 3px;
539 border-radius: var(--r-sm);
540 padding: var(--sp-2) var(--sp-3);
541 margin-bottom: var(--sp-4);
542}
543.meta { color: var(--muted); font-size: var(--fs-1); }
544svg.icon { vertical-align: -0.125em; }
545.lede { font-size: var(--fs-3); margin: var(--sp-2) 0; }
546
547/* repo listings (explore, owner pages, dashboard): one row per repo */
548ul.repolist {
549 list-style: none;
550 margin: var(--sp-3) 0 var(--sp-5);
551 padding: 0;
552 background: var(--surface);
553 border: 1px solid var(--line);
554 border-radius: var(--r-lg);
555 overflow: hidden;
556}
557ul.repolist li { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--faint); }
558/* pinned repos: a compact wrap of name pills, no description or meta */
559ul.pinlist {
560 list-style: none;
561 margin: var(--sp-3) 0 var(--sp-5);
562 padding: 0;
563 display: flex;
564 flex-wrap: wrap;
565 gap: var(--sp-2);
566}
567ul.pinlist li {
568 background: var(--surface);
569 border: 1px solid var(--line);
570 border-radius: var(--r-md);
571 padding: var(--sp-1) var(--sp-3);
572}
573ul.pinlist li:hover { background: var(--hover); }
574ul.pinlist li a { color: var(--fg); }
575ul.pinlist li a:hover { color: var(--accent); text-decoration: none; }
576ul.pinlist .sep { color: var(--muted); margin: 0 0.15em; }
577ul.repolist li:last-child { border-bottom: none; }
578ul.repolist li:hover { background: var(--hover); }
579ul.repolist li.empty { color: var(--muted); }
580ul.repolist p { margin: 0; }
581ul.repolist .reponame { font-size: var(--fs-3); }
582ul.repolist .reponame a { color: var(--fg); }
583ul.repolist .reponame a strong { color: var(--accent); font-weight: 600; }
584ul.repolist .reponame .sep { color: var(--muted); margin: 0 0.1em; }
585ul.repolist .desc { margin-top: 0.1rem; }
586ul.repolist .topics { margin-top: var(--sp-1); }
587ul.repolist .meta { margin-top: var(--sp-1); }
588
589/* owner profile header */
590.profilehead {
591 border-bottom: 1px solid var(--faint);
592 padding-bottom: var(--sp-4);
593 margin-bottom: var(--sp-4);
594}
595.profilehead h1 { margin: var(--sp-4) 0 var(--sp-1); }
596.profilehead .lede { margin: 0 0 var(--sp-1); }
597.profilehead .meta { margin: var(--sp-1) 0 0; }
598h2 .count { color: var(--muted); font-weight: 400; font-size: var(--fs-2); }
599
600/* activity graph: 53 week columns x 7 day rows, accent-tinted levels */
601.actgraph-scroll { overflow-x: auto; padding-bottom: var(--sp-1); }
602.actgraph { display: flex; gap: 3px; width: max-content; }
603.actweek { display: flex; flex-direction: column; gap: 3px; }
604.actday {
605 width: 11px;
606 height: 11px;
607 border-radius: 2px;
608 background: var(--faint);
609}
610.actday.pad { background: transparent; }
611.actday.l1 { background: color-mix(in srgb, var(--accent) 25%, var(--bg)); }
612.actday.l2 { background: color-mix(in srgb, var(--accent) 50%, var(--bg)); }
613.actday.l3 { background: color-mix(in srgb, var(--accent) 75%, var(--bg)); }
614.actday.l4 { background: var(--accent); }
615
616/* heading row with actions on the right */
617.headrow {
618 display: flex;
619 align-items: baseline;
620 gap: var(--sp-4);
621 flex-wrap: wrap;
622}
623.headrow .spacer { flex: 1; }
624
625/* member and org chips on owner pages */
626a.memberchip {
627 display: inline-block;
628 border: 1px solid var(--line);
629 border-radius: var(--r-pill);
630 padding: 0.05rem 0.6rem;
631 color: var(--fg);
632 font-size: var(--fs-1);
633 margin: 0 0.15rem 0.15rem 0;
634}
635a.memberchip:hover { text-decoration: none; border-color: var(--accent); color: var(--accent); }
636a.memberchip .role { color: var(--muted); }
637
638/* landing page */
639.landing { max-width: 44rem; padding: var(--sp-6) 0; }
640.landing h1 { font-size: 1.8rem; margin-bottom: var(--sp-3); }
641.landing .lede { font-size: var(--fs-4); color: var(--muted); line-height: 1.7; margin: 0 0 var(--sp-4); }
642pre.quickstart {
643 background: var(--code-bg);
644 border: 1px solid var(--line);
645 border-radius: var(--r-md);
646 padding: var(--sp-3) var(--sp-4);
647 overflow-x: auto;
648 margin: 0 0 var(--sp-4);
649}
650.landing .explorelink { font-weight: 550; }
651
652/* index toolbar */
653p.toolbar { color: var(--muted); font-size: var(--fs-2); margin-top: var(--sp-4); }
654form.inline { display: inline; }
655button.linklike {
656 background: none;
657 border: none;
658 color: var(--accent);
659 padding: 0;
660 font: inherit;
661 font-size: var(--fs-2);
662 cursor: pointer;
663}
664button.linklike:hover { text-decoration: underline; filter: none; }
665
666/* cards: README, comments */
667.readme, .code {
668 background: var(--surface);
669 border: 1px solid var(--line);
670 border-radius: var(--r-lg);
671 padding: var(--sp-4) var(--sp-5);
672 margin-top: var(--sp-4);
673 overflow-x: auto;
674}
675/* Highlighting is class-based with a palette per scheme, so code blocks
676 follow the site's own colors. */
677.code { background: var(--code-bg); color: var(--fg); padding: var(--sp-3) var(--sp-4); border-color: var(--line); }
678.code pre { margin: 0; background: transparent !important; }
679@media (prefers-color-scheme: dark) {
680 .code { border-color: var(--line); }
681}
682
683/* rendered markdown / org / html */
684.rendered { max-width: 100%; overflow-wrap: anywhere; }
685.rendered pre {
686 background: var(--code-bg);
687 border: 1px solid var(--line);
688 padding: var(--sp-3) var(--sp-4);
689 border-radius: var(--r-md);
690 overflow-x: auto;
691}
692.rendered code {
693 background: var(--code-bg);
694 border: 1px solid var(--line);
695 padding: 0.05rem 0.3rem;
696 border-radius: var(--r-sm);
697}
698.rendered pre code { background: transparent; border: none; padding: 0; }
699.rendered blockquote {
700 border-left: 3px solid var(--line);
701 margin-left: 0;
702 padding-left: var(--sp-4);
703 color: var(--muted);
704}
705.rendered img { max-width: 100%; }
706.rendered h1, .rendered h2 { border-bottom: 1px solid var(--faint); padding-bottom: var(--sp-1); }
707.rendered table {
708 border-collapse: collapse;
709 margin: var(--sp-3) 0;
710 display: block;
711 max-width: 100%;
712 overflow-x: auto;
713}
714.rendered th, .rendered td {
715 border: 1px solid var(--line);
716 padding: var(--sp-1) var(--sp-3);
717 text-align: left;
718 overflow-wrap: normal; /* scroll the table, don't shatter words */
719}
720.rendered th { background: var(--surface); font-weight: 600; }
721.blobimage { text-align: center; }
722.blobimage img {
723 max-width: 100%;
724 border: 1px solid var(--faint);
725 border-radius: var(--r-md);
726 background: var(--surface);
727}
728
729pre.message {
730 background: var(--code-bg);
731 border: 1px solid var(--line);
732 padding: var(--sp-3) var(--sp-4);
733 border-radius: var(--r-md);
734 white-space: pre-wrap;
735 overflow-wrap: anywhere;
736}
737
738/* diffs */
739details.difffold summary {
740 cursor: pointer;
741 display: flex;
742 align-items: baseline;
743 gap: var(--sp-3);
744 margin: var(--sp-5) 0 var(--sp-2);
745 list-style: none;
746}
747details.difffold summary::-webkit-details-marker { display: none; }
748/* flex summaries lose the native disclosure marker; draw our own */
749details.difffold summary::before { content: "▸"; color: var(--muted); }
750details.difffold[open] summary::before { content: "▾"; }
751details.difffold summary h3 { display: inline; margin: 0; }
752details.difffold summary .add { color: var(--ok); }
753details.difffold summary .del { color: var(--bad); }
754pre.diff {
755 background: var(--code-bg);
756 border: 1px solid var(--line);
757 padding: var(--sp-3) var(--sp-4);
758 border-radius: var(--r-md);
759 overflow-x: auto;
760 line-height: 1.5;
761}
762pre.diff .add { color: var(--ok); }
763pre.diff .del { color: var(--bad); }
764pre.diff .hunk { color: var(--accent); }
765pre.diff .meta { color: var(--muted); }
766
767/* badges: signature and check states. Semantic colors stay distinct:
768 green verified/success, amber pending/stale, red bad/failure, muted
769 unsigned. */
770.badge, .chip {
771 --chip: var(--neutral);
772 display: inline-block;
773 padding: 0.05rem 0.55rem;
774 border-radius: var(--r-pill);
775 font-size: var(--fs-0);
776 font-weight: 500;
777 line-height: 1.5;
778 color: var(--chip);
779 border: 1px solid color-mix(in srgb, var(--chip) 35%, transparent);
780 background: color-mix(in srgb, var(--chip) 7%, transparent);
781 white-space: nowrap;
782 vertical-align: middle;
783}
784.chip-open { --chip: var(--ok); }
785.chip-closed { --chip: var(--bad); }
786.chip-merged, .chip-done { --chip: var(--done); }
787.chip-neutral, .chip-source_gone { --chip: var(--neutral); }
788.chip-stale { --chip: var(--warn); }
789.chip.label { font-weight: 500; }
790.chip.topic { --chip: var(--accent); }
791.repohead .topics { margin: 0 0 var(--sp-2); }
792.repohead .mirrorline { margin: 0 0 var(--sp-2); }
793.mirrorerr { color: var(--bad); }
794.badge-verified { --chip: var(--ok); }
795.badge-unsigned { --chip: var(--neutral); }
796.badge-signed_unknown_key { --chip: var(--warn); }
797.badge-signed_email_mismatch { --chip: var(--bad); }
798.badge-signed_key_expired { --chip: var(--warn); }
799.badge-signed_key_revoked { --chip: var(--bad); }
800.badge-bad_signature { --chip: var(--bad); }
801.badge.check-success { --chip: var(--ok); }
802.badge.check-pending { --chip: var(--warn); }
803.badge.check-failure, .badge.check-error { --chip: var(--bad); }
804.badge.check-running, .chip.check-running { --chip: var(--warn); }
805.chip.check-success { --chip: var(--ok); }
806.chip.check-pending { --chip: var(--warn); }
807.chip.check-failure { --chip: var(--bad); }
808pre.buildlog { max-height: 40rem; overflow: auto; }
809span.check-success { color: var(--ok); }
810span.check-pending { color: var(--warn); }
811span.check-failure, span.check-error { color: var(--bad); }
812
813/* issue and MR listings */
814.listhead {
815 display: flex;
816 align-items: baseline;
817 gap: var(--sp-4);
818 flex-wrap: wrap;
819}
820.listhead h2 { margin-bottom: var(--sp-2); }
821nav.filters { display: flex; gap: var(--sp-1); }
822nav.filters a {
823 color: var(--muted);
824 font-size: var(--fs-2);
825 padding: 0.05rem var(--sp-2);
826 border-radius: var(--r-pill);
827}
828nav.filters a:hover { color: var(--fg); background: var(--hover); text-decoration: none; }
829nav.filters a.active { color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
830
831ul.issuelist {
832 list-style: none;
833 margin: var(--sp-2) 0;
834 padding: 0;
835 background: var(--surface);
836 border: 1px solid var(--line);
837 border-radius: var(--r-lg);
838 overflow: hidden;
839}
840ul.issuelist li {
841 display: flex;
842 align-items: baseline;
843 gap: var(--sp-3);
844 padding: var(--sp-3) var(--sp-4);
845 border-bottom: 1px solid var(--faint);
846}
847ul.issuelist li:last-child { border-bottom: none; }
848ul.issuelist li:hover { background: var(--hover); }
849ul.issuelist li.empty { display: block; color: var(--muted); }
850ul.issuelist .issuemain { flex: 1; min-width: 0; }
851ul.issuelist p { margin: 0; }
852ul.issuelist .title a { color: var(--fg); font-weight: 550; }
853ul.issuelist .title a:hover { color: var(--accent); }
854
855/* releases */
856article.release {
857 background: var(--surface);
858 border: 1px solid var(--line);
859 border-radius: var(--r-lg);
860 padding: var(--sp-3) var(--sp-4);
861 margin: var(--sp-4) 0;
862}
863.releasehead { background: none; border: 0; padding: 0; }
864.releasehead h3 { margin: 0 0 var(--sp-1); }
865.releasehead .meta { margin: 0 0 var(--sp-2); }
866table.assets { margin-top: var(--sp-2); }
867table.assets td.size { color: var(--muted); white-space: nowrap; text-align: right; }
868table.assets td.name { width: 100%; font-family: var(--mono); font-size: var(--fs-1); }
869
870/* milestones */
871ul.milestonelist {
872 list-style: none;
873 margin: var(--sp-2) 0;
874 padding: 0;
875 border: 1px solid var(--line);
876 border-radius: var(--r-lg);
877 overflow: hidden;
878}
879ul.milestonelist li { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--faint); }
880ul.milestonelist li:last-child { border-bottom: none; }
881ul.milestonelist li.empty { color: var(--muted); }
882ul.milestonelist p { margin: 0; }
883ul.milestonelist .title { font-weight: 550; }
884.progress {
885 height: 6px;
886 background: var(--faint);
887 border-radius: var(--r-pill);
888 margin-top: var(--sp-2);
889 overflow: hidden;
890 max-width: 24rem;
891}
892.progress .bar { height: 100%; background: var(--ok); }
893.listhead .spacer { flex: 1; }
894
895/* issue / MR detail */
896h2.issuetitle { margin-bottom: var(--sp-1); font-size: var(--fs-5); }
897.issuenumber { color: var(--muted); font-weight: 400; }
898.issuemeta { color: var(--muted); font-size: var(--fs-2); margin-top: 0; }
899.review { font-size: var(--fs-2); }
900
901/* comment cards; discussion stays at a readable measure */
902article.comment, form.commentform {
903 max-width: 48rem;
904}
905article.comment {
906 border: 1px solid var(--faint);
907 border-radius: var(--r-lg);
908 margin: var(--sp-4) 0;
909}
910article.comment .commenthead {
911 background: var(--surface);
912 border-bottom: 1px solid var(--faint);
913 border-radius: var(--r-lg) var(--r-lg) 0 0;
914 padding: var(--sp-2) var(--sp-4);
915 font-size: var(--fs-2);
916}
917article.comment .commenthead .when { color: var(--muted); }
918article.comment .rendered { padding: 0 var(--sp-4); }
919article.comment .rendered > :first-child { margin-top: var(--sp-3); }
920article.comment .rendered > :last-child { margin-bottom: var(--sp-3); }
921form.commentform { margin: var(--sp-4) 0; }
922details.editbox { margin: var(--sp-2) 0; max-width: 48rem; }
923details.editbox summary { cursor: pointer; color: var(--muted); font-size: var(--fs-2); }
924details.editbox summary:hover { color: var(--accent); }
925details.editbox input[type="text"] { width: 100%; }
926.syscomment {
927 max-width: 48rem;
928 color: var(--muted);
929 font-size: var(--fs-2);
930 margin: var(--sp-3) 0;
931 padding-left: var(--sp-4);
932 border-left: 3px solid var(--faint);
933}
934.syscomment p { display: inline; margin: 0; }
935
936/* review threads under diff lines */
937.thread {
938 border: 1px solid var(--faint);
939 border-left: 3px solid var(--accent);
940 border-radius: var(--r-md);
941 padding: var(--sp-2) var(--sp-4);
942 margin: var(--sp-2) 0 var(--sp-2) var(--sp-6);
943}
944.thread.resolved { border-left-color: var(--ok); opacity: 0.75; }
945.thread.stale { border-left-color: var(--warn); }
946.thread p.commenthead { font-size: var(--fs-2); margin: var(--sp-2) 0 0; }
947.thread .when { color: var(--muted); }
948.thread .rendered p { margin: var(--sp-1) 0; }
949.thread .threadstate { color: var(--muted); font-size: var(--fs-1); margin: var(--sp-1) 0 0; }
950
951/* forms: every control shares one shell, so a select reads as a sibling
952 of the text inputs beside it rather than as an OS control dropped in */
953input, textarea, button, select { font: inherit; color: inherit; }
954input[type="text"], input[type="search"], input[type="email"],
955input[type="password"], input:not([type]), textarea, select {
956 background: var(--bg);
957 color: var(--fg);
958 border: 1px solid var(--line);
959 border-radius: var(--r-md);
960 padding: var(--sp-2) var(--sp-3);
961 line-height: 1.4;
962}
963textarea { width: 100%; resize: vertical; }
964textarea[name="content"] { font-family: var(--mono); font-size: var(--fs-1); }
965/* the native arrow cannot be restyled, so draw our own and match the
966 inputs exactly; --chev carries the stroke colour per scheme */
967select {
968 appearance: none;
969 padding-right: 1.9rem;
970 background-image: var(--chev);
971 background-repeat: no-repeat;
972 background-position: right 0.6rem center;
973 background-size: 0.62rem;
974 cursor: pointer;
975}
976input:hover, textarea:hover, select:hover { border-color: var(--muted); }
977/* the global :focus-visible ring covers these; only the border moves */
978input:focus, textarea:focus, select:focus { border-color: var(--accent); }
979input[type="radio"], input[type="checkbox"] { accent-color: var(--fill); }
980label:has(> input[type="radio"]), label:has(> input[type="checkbox"]),
981label:has(> select) { display: inline-flex; align-items: center; gap: var(--sp-2); }
982
983/* Shape carries the meaning on these two and nothing else does: a circle
984 takes one answer, a square takes any number. It survives colour being
985 removed — greyscale, high contrast, colour blindness — so the native
986 shapes stay and only the colour joins the system. Drawing them by hand
987 would align the corners at the cost of the one cue that always works. */
988input[type="radio"], input[type="checkbox"] { accent-color: var(--fill); }
989
990/* a segmented control for a small, mutually exclusive set: real radios
991 underneath, so arrow keys and screen readers behave as they always did */
992fieldset.segmented { border: 0; margin: 0 0 var(--sp-4); padding: 0; }
993fieldset.segmented legend {
994 padding: 0;
995 margin-bottom: var(--sp-2);
996 color: var(--muted);
997 font-size: var(--fs-2);
998}
999fieldset.segmented .options { display: inline-flex; }
1000fieldset.segmented label { gap: 0; }
1001fieldset.segmented input {
1002 position: absolute;
1003 width: 1px;
1004 height: 1px;
1005 opacity: 0;
1006 pointer-events: none;
1007}
1008fieldset.segmented span {
1009 display: block;
1010 padding: var(--sp-2) var(--sp-4);
1011 border: 1px solid var(--line);
1012 font-size: var(--fs-2);
1013 cursor: pointer;
1014}
1015fieldset.segmented label + label span { border-left: 0; }
1016fieldset.segmented label:first-child span { border-radius: var(--r-sm) 0 0 var(--r-sm); }
1017fieldset.segmented label:last-child span { border-radius: 0 var(--r-sm) var(--r-sm) 0; }
1018fieldset.segmented span:hover { border-color: var(--muted); }
1019fieldset.segmented input:checked + span {
1020 background: var(--fill);
1021 border-color: var(--fill);
1022 color: #ffffff;
1023 font-weight: 600;
1024}
1025fieldset.segmented input:focus-visible + span {
1026 outline: 2px solid var(--accent);
1027 outline-offset: 2px;
1028}
1029
1030/* remaining input states */
1031::placeholder { color: var(--muted); opacity: 1; }
1032::selection { background: var(--fill); color: #ffffff; }
1033/* :user-invalid, not :invalid — a required field is invalid the moment
1034 the page loads, and colouring it red before anyone has typed is a
1035 scolding, not a hint */
1036input:user-invalid, textarea:user-invalid {
1037 border-color: var(--bad);
1038}
1039.hint { display: block; color: var(--muted); font-size: var(--fs-1); margin-top: var(--sp-1); }
1040button {
1041 background: var(--fill);
1042 color: #ffffff;
1043 border: none;
1044 border-radius: var(--r-md);
1045 padding: var(--sp-2) var(--sp-4);
1046 font-weight: 600;
1047 cursor: pointer;
1048}
1049button:hover { filter: brightness(1.15); }
1050
1051/* 404 */
1052.notfound { text-align: center; padding: var(--sp-6) 0; }
1053.notfound .bigcode {
1054 font-family: var(--mono);
1055 font-size: 4rem;
1056 color: var(--faint);
1057 -webkit-text-stroke: 1px var(--line);
1058 margin: 0;
1059 line-height: 1;
1060}
1061.notfound h1 { margin-top: var(--sp-3); }
1062
1063/* footer */
1064footer {
1065 border-top: 1px solid var(--faint);
1066 padding: var(--sp-4) var(--sp-5) var(--sp-5);
1067 max-width: 78rem;
1068 width: 100%;
1069 color: var(--muted);
1070 font-size: var(--fs-1);
1071}
1072footer p { margin: 0; }
1073footer a { color: var(--muted); text-decoration: underline; }
1074footer a:hover { color: var(--accent); }
1075
1076/* search */
1077form.searchform {
1078 display: flex;
1079 gap: var(--sp-2);
1080 margin: var(--sp-3) 0 var(--sp-4);
1081}
1082form.searchform input[type="search"] { flex: 1; max-width: 32rem; }
1083form.searchform.compact { margin: 0; }
1084form.searchform.compact input[type="search"] {
1085 padding: var(--sp-1) var(--sp-3);
1086 font-size: var(--fs-2);
1087 min-width: 18rem;
1088}
1089ul.matchlist { list-style: none; margin: var(--sp-3) 0; padding: 0; }
1090ul.matchlist li { margin-bottom: var(--sp-3); }
1091ul.matchlist .matchpath { font-family: var(--mono); font-size: var(--fs-1); }
1092pre.matchline {
1093 background: var(--code-bg);
1094 border: 1px solid var(--faint);
1095 border-radius: var(--r-md);
1096 padding: var(--sp-1) var(--sp-3);
1097 margin: var(--sp-1) 0 0;
1098 overflow-x: auto;
1099}
1100pre.matchline mark {
1101 background: color-mix(in srgb, var(--warn) 25%, transparent);
1102 color: inherit;
1103 border-radius: 2px;
1104}
1105
1106/* wiki */
1107.wikilayout { display: flex; gap: var(--sp-5); align-items: flex-start; }
1108.wikipage { flex: 1; min-width: 0; }
1109.wikinav { flex: none; width: 13rem; padding-top: var(--sp-4); }
1110.wikinav ul { list-style: none; margin: var(--sp-1) 0 var(--sp-4); padding: 0; }
1111.wikinav li a { display: block; padding: 0.15rem 0; color: var(--fg); }
1112.wikinav li a:hover { color: var(--accent); text-decoration: none; }
1113.wikinav li a.active { color: var(--accent); font-weight: 550; }
1114@media (max-width: 40rem) {
1115 /* Column direction + the desktop align-items:flex-start lets .wikipage
1116 take its content's intrinsic width, overflowing the viewport (and
1117 triggering iOS font inflation). Stretch pins it to the container. */
1118 .wikilayout { flex-direction: column; align-items: stretch; }
1119 .wikinav { width: auto; padding-top: 0; }
1120}
1121
1122/* blame */
1123.blame {
1124 border: 1px solid var(--line);
1125 border-radius: var(--rad-2, 6px);
1126 overflow: hidden;
1127}
1128.blamehunk {
1129 display: flex;
1130 gap: var(--sp-3);
1131 border-top: 1px solid var(--line);
1132 align-items: flex-start;
1133}
1134.blamehunk:first-child { border-top: none; }
1135.blameinfo {
1136 flex: none;
1137 width: 17rem;
1138 padding: var(--sp-2) var(--sp-3);
1139 min-width: 0;
1140}
1141.blameinfo .subject {
1142 margin: 0;
1143 font-size: var(--fs-1);
1144 white-space: nowrap;
1145 overflow: hidden;
1146 text-overflow: ellipsis;
1147}
1148.blameinfo .meta { margin: 0; font-size: var(--fs-1); color: var(--muted); }
1149.blamecode {
1150 flex: 1;
1151 margin: 0;
1152 padding: var(--sp-2) var(--sp-3) var(--sp-2) 0;
1153 overflow-x: auto;
1154 border-left: 1px solid var(--line);
1155 align-self: stretch;
1156}
1157.lineno {
1158 display: inline-block;
1159 min-width: 3.5em;
1160 padding-right: 1em;
1161 text-align: right;
1162 color: var(--muted);
1163 user-select: none;
1164}
1165
1166/* mobile */
1167@media (max-width: 40rem) {
1168 .container { padding-left: var(--sp-4); padding-right: var(--sp-4); }
1169 main.container { padding-top: var(--sp-2); }
1170 .repogrid { grid-template-columns: 1fr; }
1171 .thread { margin-left: var(--sp-3); }
1172 table.tree td.mode, table.tree th.mode { display: none; }
1173 .readme, .code { padding: var(--sp-3); }
1174 .blamehunk { flex-direction: column; gap: 0; }
1175 .blameinfo { width: auto; }
1176 .blamecode { border-left: none; padding-left: var(--sp-3); width: 100%; }
1177 .cardhead {
1178 margin: calc(-1 * var(--sp-3)) calc(-1 * var(--sp-3)) var(--sp-3);
1179 padding: var(--sp-2) var(--sp-3);
1180 }
1181}
1182
1183/* tree listing: the last commit is what a file table is scanned for, so
1184 it leads. The file's own facts moved to the blob page. */
1185.tipbar {
1186 display: flex;
1187 align-items: center;
1188 gap: var(--sp-3);
1189 padding: var(--sp-2) var(--sp-4);
1190 background: var(--hover);
1191 border: 1px solid var(--line);
1192 border-bottom: 0;
1193 border-radius: var(--r-lg) var(--r-lg) 0 0;
1194 font-size: var(--fs-2);
1195}
1196.tipbar .who { font-weight: 600; }
1197.tipbar .subject { color: var(--fg); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1198.tipbar .subject:hover { color: var(--accent); }
1199.tipbar .spacer { flex: 1; }
1200.tipbar .age { color: var(--muted); white-space: nowrap; }
1201.tipbar + table.tree { border-radius: 0 0 var(--r-lg) var(--r-lg); }
1202table.tree th.lastcommit, table.tree td.lastcommit { width: 55%; }
1203table.tree td.lastcommit a { color: var(--muted); display: block; overflow: hidden;
1204 text-overflow: ellipsis; white-space: nowrap; }
1205table.tree td.lastcommit a:hover { color: var(--accent); }
1206table.tree th.age, table.tree td.age {
1207 text-align: right;
1208 white-space: nowrap;
1209 color: var(--muted);
1210 font-variant-numeric: tabular-nums;
1211}
1212table.tree td.name { width: 25%; white-space: nowrap; }
1213table.tree td.name.dir a { color: var(--accent); }
1214p.clone { margin: 0 0 var(--sp-3); }
1215p.filefacts { color: var(--muted); font-size: var(--fs-1); margin: 0 0 var(--sp-3); }
1216.pathbar .act { font-size: var(--fs-1); }
1217
1218/* merge request: a two-column split, so state has somewhere to live that
1219 is not a run-on sentence under the title */
1220.withaside {
1221 display: grid;
1222 grid-template-columns: minmax(0, 1fr) 15rem;
1223 gap: var(--sp-5);
1224 align-items: start;
1225}
1226.withaside .mainside { min-width: 0; }
1227@media (max-width: 62rem) { .withaside { grid-template-columns: 1fr; } }
1228
1229.aside { font-size: var(--fs-2); }
1230.aside .grp { border-top: 1px solid var(--line); padding: var(--sp-3) 0; }
1231.aside .grp:first-child { border-top: 0; padding-top: 0; }
1232.aside h2 {
1233 margin: 0 0 var(--sp-2);
1234 font-family: var(--mono);
1235 font-size: var(--fs-0);
1236 font-weight: 500;
1237 letter-spacing: 0.1em;
1238 text-transform: uppercase;
1239 color: var(--muted);
1240}
1241.aside .row { display: flex; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-1); flex-wrap: wrap; }
1242.aside .row:last-child { margin-bottom: 0; }
1243.aside .none { color: var(--muted); }
1244.aside .dot { width: 0.45rem; height: 0.45rem; flex: none; border-radius: 50%; background: var(--muted); }
1245.aside .dot.ok { background: var(--ok); }
1246.aside .dot.bad { background: var(--bad); }
1247.aside .dot.pend { background: var(--mark); }
1248
1249/* sub-navigation within an item; orange marks position as it does above */
1250nav.subtabs {
1251 display: flex;
1252 gap: var(--sp-4);
1253 border-bottom: 1px solid var(--line);
1254 margin: 0 0 var(--sp-4);
1255}
1256nav.subtabs a {
1257 display: inline-flex;
1258 align-items: center;
1259 gap: var(--sp-2);
1260 padding: 0 0 var(--sp-2);
1261 color: var(--muted);
1262 font-size: var(--fs-2);
1263 border-bottom: 2px solid transparent;
1264 margin-bottom: -1px;
1265}
1266nav.subtabs a:hover { color: var(--fg); text-decoration: none; }
1267nav.subtabs a[aria-current] { color: var(--fg); font-weight: 700; border-bottom-color: var(--mark); }
1268nav.subtabs a i {
1269 font-style: normal;
1270 font-family: var(--mono);
1271 font-size: var(--fs-0);
1272 background: var(--hover);
1273 border-radius: var(--r-sm);
1274 padding: 0 0.35rem;
1275}
1276p.diffstat { color: var(--muted); font-size: var(--fs-2); margin: 0 0 var(--sp-3); }
1277p.diffstat .add { color: var(--ok); }
1278p.diffstat .del { color: var(--bad); }