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