internal/web/static/style.css
1437 lines · 47877 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/* repo facts: the counts a visitor sizes a project up with */
798.facts { margin: 0 0 var(--sp-4); }
799.facts .counts {
800 display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4);
801 margin: 0 0 var(--sp-3); font-size: var(--fs-2);
802}
803.facts .counts a { color: var(--fg); text-decoration: none; }
804.facts .counts a:hover { color: var(--accent); text-decoration: underline; }
805.facts .counts .fact { color: var(--muted); }
806.facts .counts strong { font-weight: 600; }
807
808.langbar {
809 display: flex; height: 0.5rem; margin: 0 0 var(--sp-2);
810 border-radius: var(--r-sm); overflow: hidden; background: var(--faint);
811}
812.langbar .lang { display: block; min-width: 2px; }
813.langs {
814 display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4);
815 margin: 0 0 var(--sp-3); font-size: var(--fs-1);
816}
817.langs .lang-name { display: inline-flex; align-items: center; gap: var(--sp-1); }
818.langs .muted { color: var(--muted); }
819.langs .dot { width: 0.6rem; height: 0.6rem; border-radius: 50%; display: inline-block; }
820/* named where it reads as the language's own color, neutral otherwise */
821.lang { background: var(--neutral); }
822.lang-go { background: #00add8; }
823.lang-rust { background: #dea584; }
824.lang-c, .lang-c- { background: #555555; }
825.lang-python { background: #3572a5; }
826.lang-javascript { background: #f1e05a; }
827.lang-typescript { background: #3178c6; }
828.lang-shell { background: #89e051; }
829.lang-ruby { background: #701516; }
830.lang-java { background: #b07219; }
831.lang-swift { background: #f05138; }
832.lang-html { background: #e34c26; }
833.lang-css { background: #563d7c; }
834.lang-org { background: #77aa99; }
835.lang-markdown { background: #083fa1; }
836.lang-emacs-lisp { background: #c065db; }
837.lang-nix { background: #7e7eff; }
838.lang-sql { background: #e38c00; }
839
840.contribs {
841 display: flex; flex-wrap: wrap; align-items: baseline;
842 gap: var(--sp-1) var(--sp-3); margin: 0; font-size: var(--fs-1);
843}
844.contribs .label { color: var(--muted); }
845
846/* diffs: one foldable section per file, a table so the line-number
847 gutters stay put while the code scrolls */
848details.difffold {
849 border: 1px solid var(--line);
850 border-radius: var(--r-md);
851 margin: 0 0 var(--sp-3);
852 background: var(--code-bg);
853}
854details.difffold summary {
855 cursor: pointer;
856 display: flex;
857 align-items: baseline;
858 gap: var(--sp-3);
859 padding: var(--sp-2) var(--sp-3);
860 list-style: none;
861 font-size: var(--fs-2);
862}
863details.difffold[open] summary { border-bottom: 1px solid var(--line); }
864details.difffold summary::-webkit-details-marker { display: none; }
865/* flex summaries lose the native disclosure marker; draw our own */
866details.difffold summary::before { content: "\25b8"; color: var(--muted); }
867details.difffold[open] summary::before { content: "\25be"; }
868details.difffold summary:hover { background: var(--fill-subtle); }
869summary .fpath { font-family: var(--mono); overflow-wrap: anywhere; }
870summary .fpath .was { color: var(--muted); }
871summary .fstat { margin-left: auto; font-family: var(--mono); white-space: nowrap; }
872details.difffold .add { color: var(--ok); }
873details.difffold .del { color: var(--bad); }
874details.difffold > .none { padding: var(--sp-3); margin: 0; }
875details.difffold .tablewrap { border-radius: 0 0 var(--r-md) var(--r-md); }
876
877table.difftable {
878 border-collapse: collapse;
879 width: 100%;
880 font-family: var(--mono);
881 font-size: var(--fs-1);
882 line-height: 1.5;
883}
884table.difftable td {
885 border: 0;
886 padding: 0;
887 vertical-align: top;
888 font-size: inherit;
889}
890table.difftable td.ln {
891 width: 1%;
892 min-width: 2.5rem;
893 padding: 0 var(--sp-2);
894 text-align: right;
895 color: var(--muted);
896 user-select: none;
897 border-right: 1px solid var(--line);
898 white-space: nowrap;
899}
900table.difftable td.code {
901 padding: 0 var(--sp-3);
902 white-space: pre-wrap;
903 overflow-wrap: anywhere;
904}
905/* the marker is decoration, so it lives in CSS and stays out of a copied
906 selection */
907table.difftable tr.add td.code::before { content: "+"; color: var(--ok); }
908table.difftable tr.del td.code::before { content: "\2212"; color: var(--bad); }
909table.difftable tr.ctx td.code::before { content: " "; }
910table.difftable tr.add { background: var(--diff-add); }
911table.difftable tr.del { background: var(--diff-del); }
912table.difftable tr.hunk td, table.difftable tr.dmeta td {
913 color: var(--muted);
914 padding: var(--sp-1) var(--sp-3);
915 background: var(--fill-subtle);
916 border-top: 1px solid var(--line);
917 border-bottom: 1px solid var(--line);
918}
919table.difftable tr.hunk td.code { color: var(--accent); }
920table.difftable tr.threadrow td { padding: var(--sp-2) var(--sp-3); background: var(--bg); }
921
922/* badges: signature and check states. Semantic colors stay distinct:
923 green verified/success, amber pending/stale, red bad/failure, muted
924 unsigned. */
925.badge, .chip {
926 --chip: var(--neutral);
927 display: inline-block;
928 padding: 0.05rem 0.55rem;
929 border-radius: var(--r-pill);
930 font-size: var(--fs-0);
931 font-weight: 500;
932 line-height: 1.5;
933 color: var(--chip);
934 border: 1px solid color-mix(in srgb, var(--chip) 35%, transparent);
935 background: color-mix(in srgb, var(--chip) 7%, transparent);
936 white-space: nowrap;
937 vertical-align: middle;
938}
939.chip-open { --chip: var(--ok); }
940.chip-closed { --chip: var(--bad); }
941.chip-merged, .chip-done { --chip: var(--done); }
942.chip-neutral, .chip-source_gone { --chip: var(--neutral); }
943.chip-stale { --chip: var(--warn); }
944.chip.label { font-weight: 500; }
945.chip.topic { --chip: var(--accent); }
946.repohead .topics { margin: 0 0 var(--sp-2); }
947.repohead .mirrorline { margin: 0 0 var(--sp-2); }
948.mirrorerr { color: var(--bad); }
949.badge-verified { --chip: var(--ok); }
950.badge-unsigned { --chip: var(--neutral); }
951.badge-signed_unknown_key { --chip: var(--warn); }
952.badge-signed_email_mismatch { --chip: var(--bad); }
953.badge-signed_key_expired { --chip: var(--warn); }
954.badge-signed_key_revoked { --chip: var(--bad); }
955.badge-bad_signature { --chip: var(--bad); }
956.badge.check-success { --chip: var(--ok); }
957.badge.check-pending { --chip: var(--warn); }
958.badge.check-failure, .badge.check-error { --chip: var(--bad); }
959.badge.check-running, .chip.check-running { --chip: var(--warn); }
960.chip.check-success { --chip: var(--ok); }
961.chip.check-pending { --chip: var(--warn); }
962.chip.check-failure { --chip: var(--bad); }
963pre.buildlog { max-height: 40rem; overflow: auto; }
964span.check-success { color: var(--ok); }
965span.check-pending { color: var(--warn); }
966span.check-failure, span.check-error { color: var(--bad); }
967
968/* issue and MR listings */
969.listhead {
970 display: flex;
971 align-items: baseline;
972 gap: var(--sp-4);
973 flex-wrap: wrap;
974}
975.listhead h2 { margin-bottom: var(--sp-2); }
976nav.filters { display: flex; gap: var(--sp-1); }
977nav.filters a {
978 color: var(--muted);
979 font-size: var(--fs-2);
980 padding: 0.05rem var(--sp-2);
981 border-radius: var(--r-pill);
982}
983nav.filters a:hover { color: var(--fg); background: var(--hover); text-decoration: none; }
984nav.filters a.active { color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
985
986ul.issuelist {
987 list-style: none;
988 margin: var(--sp-2) 0;
989 padding: 0;
990 background: var(--surface);
991 border: 1px solid var(--line);
992 border-radius: var(--r-lg);
993 overflow: hidden;
994}
995ul.issuelist li {
996 display: flex;
997 align-items: baseline;
998 gap: var(--sp-3);
999 padding: var(--sp-3) var(--sp-4);
1000 border-bottom: 1px solid var(--faint);
1001}
1002ul.issuelist li:last-child { border-bottom: none; }
1003ul.issuelist li:hover { background: var(--hover); }
1004ul.issuelist li.empty { display: block; color: var(--muted); }
1005ul.issuelist .issuemain { flex: 1; min-width: 0; }
1006ul.issuelist p { margin: 0; }
1007ul.issuelist .title a { color: var(--fg); font-weight: 550; }
1008ul.issuelist .title a:hover { color: var(--accent); }
1009
1010/* releases */
1011article.release {
1012 background: var(--surface);
1013 border: 1px solid var(--line);
1014 border-radius: var(--r-lg);
1015 padding: var(--sp-3) var(--sp-4);
1016 margin: var(--sp-4) 0;
1017}
1018.releasehead { background: none; border: 0; padding: 0; }
1019.releasehead h3 { margin: 0 0 var(--sp-1); }
1020.releasehead .meta { margin: 0 0 var(--sp-2); }
1021table.assets { margin-top: var(--sp-2); }
1022table.assets td.size { color: var(--muted); white-space: nowrap; text-align: right; }
1023table.assets td.name { width: 100%; font-family: var(--mono); font-size: var(--fs-1); }
1024
1025/* milestones */
1026ul.milestonelist {
1027 list-style: none;
1028 margin: var(--sp-2) 0;
1029 padding: 0;
1030 border: 1px solid var(--line);
1031 border-radius: var(--r-lg);
1032 overflow: hidden;
1033}
1034ul.milestonelist li { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--faint); }
1035ul.milestonelist li:last-child { border-bottom: none; }
1036ul.milestonelist li.empty { color: var(--muted); }
1037ul.milestonelist p { margin: 0; }
1038ul.milestonelist .title { font-weight: 550; }
1039.progress {
1040 height: 6px;
1041 background: var(--faint);
1042 border-radius: var(--r-pill);
1043 margin-top: var(--sp-2);
1044 overflow: hidden;
1045 max-width: 24rem;
1046}
1047.progress .bar { height: 100%; background: var(--ok); }
1048.listhead .spacer { flex: 1; }
1049
1050/* issue / MR detail */
1051h2.issuetitle { margin-bottom: var(--sp-1); font-size: var(--fs-5); }
1052.issuenumber { color: var(--muted); font-weight: 400; }
1053.issuemeta { color: var(--muted); font-size: var(--fs-2); margin-top: 0; }
1054.review { font-size: var(--fs-2); }
1055
1056/* comment cards; discussion stays at a readable measure */
1057article.comment, form.commentform {
1058 max-width: 48rem;
1059}
1060article.comment {
1061 border: 1px solid var(--faint);
1062 border-radius: var(--r-lg);
1063 margin: var(--sp-4) 0;
1064}
1065article.comment .commenthead {
1066 background: var(--surface);
1067 border-bottom: 1px solid var(--faint);
1068 border-radius: var(--r-lg) var(--r-lg) 0 0;
1069 padding: var(--sp-2) var(--sp-4);
1070 font-size: var(--fs-2);
1071}
1072article.comment .commenthead .when { color: var(--muted); }
1073article.comment .rendered { padding: 0 var(--sp-4); }
1074article.comment .rendered > :first-child { margin-top: var(--sp-3); }
1075article.comment .rendered > :last-child { margin-bottom: var(--sp-3); }
1076form.commentform { margin: var(--sp-4) 0; }
1077details.editbox { margin: var(--sp-2) 0; max-width: 48rem; }
1078details.editbox summary { cursor: pointer; color: var(--muted); font-size: var(--fs-2); }
1079details.editbox summary:hover { color: var(--accent); }
1080details.editbox input[type="text"] { width: 100%; }
1081.syscomment {
1082 max-width: 48rem;
1083 color: var(--muted);
1084 font-size: var(--fs-2);
1085 margin: var(--sp-3) 0;
1086 padding-left: var(--sp-4);
1087 border-left: 3px solid var(--faint);
1088}
1089.syscomment p { display: inline; margin: 0; }
1090
1091/* review threads under diff lines */
1092.thread {
1093 border: 1px solid var(--faint);
1094 border-left: 3px solid var(--accent);
1095 border-radius: var(--r-md);
1096 padding: var(--sp-2) var(--sp-4);
1097 margin: var(--sp-2) 0 var(--sp-2) var(--sp-6);
1098}
1099.thread.resolved { border-left-color: var(--ok); opacity: 0.75; }
1100.thread.stale { border-left-color: var(--warn); }
1101.thread p.commenthead { font-size: var(--fs-2); margin: var(--sp-2) 0 0; }
1102.thread .when { color: var(--muted); }
1103.thread .rendered p { margin: var(--sp-1) 0; }
1104.thread .threadstate { color: var(--muted); font-size: var(--fs-1); margin: var(--sp-1) 0 0; }
1105
1106/* forms: every control shares one shell, so a select reads as a sibling
1107 of the text inputs beside it rather than as an OS control dropped in */
1108input, textarea, button, select { font: inherit; color: inherit; }
1109input[type="text"], input[type="search"], input[type="email"],
1110input[type="password"], input:not([type]), textarea, select {
1111 background: var(--bg);
1112 color: var(--fg);
1113 border: 1px solid var(--line);
1114 border-radius: var(--r-md);
1115 padding: var(--sp-2) var(--sp-3);
1116 line-height: 1.4;
1117}
1118textarea { width: 100%; resize: vertical; }
1119textarea[name="content"] { font-family: var(--mono); font-size: var(--fs-1); }
1120/* the native arrow cannot be restyled, so draw our own and match the
1121 inputs exactly; --chev carries the stroke colour per scheme */
1122select {
1123 appearance: none;
1124 padding-right: 1.9rem;
1125 background-image: var(--chev);
1126 background-repeat: no-repeat;
1127 background-position: right 0.6rem center;
1128 background-size: 0.62rem;
1129 cursor: pointer;
1130}
1131input:hover, textarea:hover, select:hover { border-color: var(--muted); }
1132/* the global :focus-visible ring covers these; only the border moves */
1133input:focus, textarea:focus, select:focus { border-color: var(--accent); }
1134input[type="radio"], input[type="checkbox"] { accent-color: var(--fill); }
1135label:has(> input[type="radio"]), label:has(> input[type="checkbox"]),
1136label:has(> select) { display: inline-flex; align-items: center; gap: var(--sp-2); }
1137
1138/* Shape carries the meaning on these two and nothing else does: a circle
1139 takes one answer, a square takes any number. It survives colour being
1140 removed — greyscale, high contrast, colour blindness — so the native
1141 shapes stay and only the colour joins the system. Drawing them by hand
1142 would align the corners at the cost of the one cue that always works. */
1143input[type="radio"], input[type="checkbox"] { accent-color: var(--fill); }
1144
1145/* a segmented control for a small, mutually exclusive set: real radios
1146 underneath, so arrow keys and screen readers behave as they always did */
1147fieldset.segmented { border: 0; margin: 0 0 var(--sp-4); padding: 0; }
1148fieldset.segmented legend {
1149 padding: 0;
1150 margin-bottom: var(--sp-2);
1151 color: var(--muted);
1152 font-size: var(--fs-2);
1153}
1154fieldset.segmented .options { display: inline-flex; }
1155fieldset.segmented label { gap: 0; }
1156fieldset.segmented input {
1157 position: absolute;
1158 width: 1px;
1159 height: 1px;
1160 opacity: 0;
1161 pointer-events: none;
1162}
1163fieldset.segmented span {
1164 display: block;
1165 padding: var(--sp-2) var(--sp-4);
1166 border: 1px solid var(--line);
1167 font-size: var(--fs-2);
1168 cursor: pointer;
1169}
1170fieldset.segmented label + label span { border-left: 0; }
1171fieldset.segmented label:first-child span { border-radius: var(--r-sm) 0 0 var(--r-sm); }
1172fieldset.segmented label:last-child span { border-radius: 0 var(--r-sm) var(--r-sm) 0; }
1173fieldset.segmented span:hover { border-color: var(--muted); }
1174fieldset.segmented input:checked + span {
1175 background: var(--fill);
1176 border-color: var(--fill);
1177 color: #ffffff;
1178 font-weight: 600;
1179}
1180fieldset.segmented input:focus-visible + span {
1181 outline: 2px solid var(--accent);
1182 outline-offset: 2px;
1183}
1184
1185/* remaining input states */
1186::placeholder { color: var(--muted); opacity: 1; }
1187::selection { background: var(--fill); color: #ffffff; }
1188/* :user-invalid, not :invalid — a required field is invalid the moment
1189 the page loads, and colouring it red before anyone has typed is a
1190 scolding, not a hint */
1191input:user-invalid, textarea:user-invalid {
1192 border-color: var(--bad);
1193}
1194.hint { display: block; color: var(--muted); font-size: var(--fs-1); margin-top: var(--sp-1); }
1195button {
1196 background: var(--fill);
1197 color: #ffffff;
1198 border: none;
1199 border-radius: var(--r-md);
1200 padding: var(--sp-2) var(--sp-4);
1201 font-weight: 600;
1202 cursor: pointer;
1203}
1204button:hover { filter: brightness(1.15); }
1205
1206/* 404 */
1207.notfound { text-align: center; padding: var(--sp-6) 0; }
1208.notfound .bigcode {
1209 font-family: var(--mono);
1210 font-size: 4rem;
1211 color: var(--faint);
1212 -webkit-text-stroke: 1px var(--line);
1213 margin: 0;
1214 line-height: 1;
1215}
1216.notfound h1 { margin-top: var(--sp-3); }
1217
1218/* footer */
1219footer {
1220 border-top: 1px solid var(--faint);
1221 padding: var(--sp-4) var(--sp-5) var(--sp-5);
1222 width: 100%;
1223 color: var(--muted);
1224 font-size: var(--fs-1);
1225}
1226footer p { margin: 0; }
1227footer a { color: var(--muted); text-decoration: underline; }
1228footer a:hover { color: var(--accent); }
1229
1230/* search */
1231form.searchform {
1232 display: flex;
1233 gap: var(--sp-2);
1234 margin: var(--sp-3) 0 var(--sp-4);
1235}
1236form.searchform input[type="search"] { flex: 1; max-width: 32rem; }
1237form.searchform.compact { margin: 0; }
1238form.searchform.compact input[type="search"] {
1239 padding: var(--sp-1) var(--sp-3);
1240 font-size: var(--fs-2);
1241 min-width: 18rem;
1242}
1243ul.matchlist { list-style: none; margin: var(--sp-3) 0; padding: 0; }
1244ul.matchlist li { margin-bottom: var(--sp-3); }
1245ul.matchlist .matchpath { font-family: var(--mono); font-size: var(--fs-1); }
1246pre.matchline {
1247 background: var(--code-bg);
1248 border: 1px solid var(--faint);
1249 border-radius: var(--r-md);
1250 padding: var(--sp-1) var(--sp-3);
1251 margin: var(--sp-1) 0 0;
1252 overflow-x: auto;
1253}
1254pre.matchline mark {
1255 background: color-mix(in srgb, var(--warn) 25%, transparent);
1256 color: inherit;
1257 border-radius: 2px;
1258}
1259
1260/* wiki */
1261.wikilayout { display: flex; gap: var(--sp-5); align-items: flex-start; }
1262.wikipage { flex: 1; min-width: 0; }
1263.wikinav { flex: none; width: 13rem; padding-top: var(--sp-4); }
1264.wikinav ul { list-style: none; margin: var(--sp-1) 0 var(--sp-4); padding: 0; }
1265.wikinav li a { display: block; padding: 0.15rem 0; color: var(--fg); }
1266.wikinav li a:hover { color: var(--accent); text-decoration: none; }
1267.wikinav li a.active { color: var(--accent); font-weight: 550; }
1268@media (max-width: 40rem) {
1269 /* Column direction + the desktop align-items:flex-start lets .wikipage
1270 take its content's intrinsic width, overflowing the viewport (and
1271 triggering iOS font inflation). Stretch pins it to the container. */
1272 .wikilayout { flex-direction: column; align-items: stretch; }
1273 .wikinav { width: auto; padding-top: 0; }
1274}
1275
1276/* blame */
1277.blame {
1278 border: 1px solid var(--line);
1279 border-radius: var(--rad-2, 6px);
1280 overflow: hidden;
1281}
1282.blamehunk {
1283 display: flex;
1284 gap: var(--sp-3);
1285 border-top: 1px solid var(--line);
1286 align-items: flex-start;
1287}
1288.blamehunk:first-child { border-top: none; }
1289.blameinfo {
1290 flex: none;
1291 width: 17rem;
1292 padding: var(--sp-2) var(--sp-3);
1293 min-width: 0;
1294}
1295.blameinfo .subject {
1296 margin: 0;
1297 font-size: var(--fs-1);
1298 white-space: nowrap;
1299 overflow: hidden;
1300 text-overflow: ellipsis;
1301}
1302.blameinfo .meta { margin: 0; font-size: var(--fs-1); color: var(--muted); }
1303.blamecode {
1304 flex: 1;
1305 margin: 0;
1306 padding: var(--sp-2) var(--sp-3) var(--sp-2) 0;
1307 overflow-x: auto;
1308 border-left: 1px solid var(--line);
1309 align-self: stretch;
1310}
1311.lineno {
1312 display: inline-block;
1313 min-width: 3.5em;
1314 padding-right: 1em;
1315 text-align: right;
1316 color: var(--muted);
1317 user-select: none;
1318}
1319
1320/* mobile */
1321@media (max-width: 40rem) {
1322 .container { padding-left: var(--sp-4); padding-right: var(--sp-4); }
1323 main.container { padding-top: var(--sp-2); }
1324 .repogrid { grid-template-columns: 1fr; }
1325 .thread { margin-left: var(--sp-3); }
1326 /* the commit subject is the widest thing in the listing and the one
1327 column a phone can do without: the tipbar above already names the
1328 latest commit. */
1329 table.tree td.lastcommit, table.tree th.lastcommit { display: none; }
1330 table.tree td.mode, table.tree th.mode { display: none; }
1331 .clone, .pathbar { overflow-wrap: anywhere; }
1332 .readme, .code { padding: var(--sp-3); }
1333 .blamehunk { flex-direction: column; gap: 0; }
1334 .blameinfo { width: auto; }
1335 .blamecode { border-left: none; padding-left: var(--sp-3); width: 100%; }
1336 .cardhead {
1337 margin: calc(-1 * var(--sp-3)) calc(-1 * var(--sp-3)) var(--sp-3);
1338 padding: var(--sp-2) var(--sp-3);
1339 }
1340}
1341
1342/* tree listing: the last commit is what a file table is scanned for, so
1343 it leads. The file's own facts moved to the blob page. */
1344.tipbar {
1345 display: flex;
1346 align-items: center;
1347 gap: var(--sp-3);
1348 padding: var(--sp-2) var(--sp-4);
1349 background: var(--hover);
1350 border: 1px solid var(--line);
1351 border-bottom: 0;
1352 border-radius: var(--r-lg) var(--r-lg) 0 0;
1353 font-size: var(--fs-2);
1354}
1355.tipbar .who { font-weight: 600; }
1356.tipbar .subject { color: var(--fg); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1357.tipbar .subject:hover { color: var(--accent); }
1358.tipbar .spacer { flex: 1; }
1359.tipbar .age { color: var(--muted); white-space: nowrap; }
1360.tipbar + table.tree { border-radius: 0 0 var(--r-lg) var(--r-lg); }
1361table.tree th.lastcommit, table.tree td.lastcommit { width: 55%; }
1362table.tree td.lastcommit a { color: var(--muted); display: block; overflow: hidden;
1363 text-overflow: ellipsis; white-space: nowrap; }
1364table.tree td.lastcommit a:hover { color: var(--accent); }
1365table.tree th.age, table.tree td.age {
1366 text-align: right;
1367 white-space: nowrap;
1368 color: var(--muted);
1369 font-variant-numeric: tabular-nums;
1370}
1371table.tree td.name { width: 25%; white-space: nowrap; }
1372table.tree td.name.dir a { color: var(--accent); }
1373p.clone { margin: 0 0 var(--sp-3); }
1374p.filefacts { color: var(--muted); font-size: var(--fs-1); margin: 0 0 var(--sp-3); }
1375.pathbar .act { font-size: var(--fs-1); }
1376
1377/* merge request: a two-column split, so state has somewhere to live that
1378 is not a run-on sentence under the title */
1379.withaside {
1380 display: grid;
1381 grid-template-columns: minmax(0, 1fr) 15rem;
1382 gap: var(--sp-5);
1383 align-items: start;
1384}
1385.withaside .mainside { min-width: 0; }
1386@media (max-width: 62rem) { .withaside { grid-template-columns: 1fr; } }
1387
1388.aside { font-size: var(--fs-2); }
1389.aside .grp { border-top: 1px solid var(--line); padding: var(--sp-3) 0; }
1390.aside .grp:first-child { border-top: 0; padding-top: 0; }
1391.aside h2 {
1392 margin: 0 0 var(--sp-2);
1393 font-family: var(--mono);
1394 font-size: var(--fs-0);
1395 font-weight: 500;
1396 letter-spacing: 0.1em;
1397 text-transform: uppercase;
1398 color: var(--muted);
1399}
1400.aside .row { display: flex; align-items: center; gap: var(--sp-2); margin: 0 0 var(--sp-1); flex-wrap: wrap; }
1401.aside .row:last-child { margin-bottom: 0; }
1402.aside .none { color: var(--muted); }
1403.aside .dot { width: 0.45rem; height: 0.45rem; flex: none; border-radius: 50%; background: var(--muted); }
1404.aside .dot.ok { background: var(--ok); }
1405.aside .dot.bad { background: var(--bad); }
1406.aside .dot.pend { background: var(--mark); }
1407
1408/* sub-navigation within an item; orange marks position as it does above */
1409nav.subtabs {
1410 display: flex;
1411 gap: var(--sp-4);
1412 border-bottom: 1px solid var(--line);
1413 margin: 0 0 var(--sp-4);
1414}
1415nav.subtabs a {
1416 display: inline-flex;
1417 align-items: center;
1418 gap: var(--sp-2);
1419 padding: 0 0 var(--sp-2);
1420 color: var(--muted);
1421 font-size: var(--fs-2);
1422 border-bottom: 2px solid transparent;
1423 margin-bottom: -1px;
1424}
1425nav.subtabs a:hover { color: var(--fg); text-decoration: none; }
1426nav.subtabs a[aria-current] { color: var(--fg); font-weight: 700; border-bottom-color: var(--mark); }
1427nav.subtabs a i {
1428 font-style: normal;
1429 font-family: var(--mono);
1430 font-size: var(--fs-0);
1431 background: var(--hover);
1432 border-radius: var(--r-sm);
1433 padding: 0 0.35rem;
1434}
1435p.diffstat { color: var(--muted); font-size: var(--fs-2); margin: 0 0 var(--sp-3); }
1436p.diffstat .add { color: var(--ok); }
1437p.diffstat .del { color: var(--bad); }