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