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