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