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