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