main.css
Raw
1/* View Transitions */
2@view-transition {
3 navigation: auto;
4}
5
6.site-nav {
7 view-transition-name: site-nav;
8}
9.repo-header {
10 view-transition-name: repo-header;
11}
12.breadcrumb {
13 view-transition-name: breadcrumb;
14}
15
16/* ============================================================
17 @layer reset
18 ============================================================ */
19@layer reset {
20 *,
21 *::before,
22 *::after {
23 box-sizing: border-box;
24 margin: 0;
25 padding: 0;
26 }
27 html {
28 -webkit-text-size-adjust: 100%;
29 }
30 body {
31 min-height: 100dvh;
32 min-width: 500px;
33 }
34 img,
35 video {
36 max-width: 100%;
37 height: auto;
38 }
39 button,
40 input,
41 textarea,
42 select {
43 font: inherit;
44 }
45 a {
46 color: inherit;
47 }
48 ul,
49 ol {
50 list-style: none;
51 }
52 h1,
53 h2,
54 h3,
55 h4,
56 h5,
57 h6 {
58 font-weight: 600;
59 line-height: 1.2;
60 }
61 pre,
62 code {
63 font-family: var(--font-mono);
64 }
65}
66
67/* ============================================================
68 @layer tokens
69 ============================================================ */
70@layer tokens {
71 :root {
72 /* Colors — light */
73 --color-bg: #ffffff;
74 --color-bg-subtle: #f6f8fa;
75 --color-bg-inset: #eef0f2;
76 --color-border: #d0d7de;
77 --color-border-muted: #e4e7eb;
78 --color-text: #1f2328;
79 --color-text-muted: #656d76;
80 --color-link: #0969da;
81 --color-link-hover: #0550ae;
82
83 --color-accent: #fd7e14;
84 --color-accent-bg: #fff3cd;
85
86 --color-success: #1a7f37;
87 --color-success-bg: #dafbe1;
88 --color-danger: #cf222e;
89 --color-danger-bg: #ffebe9;
90 --color-warning: #9a6700;
91 --color-warning-bg: #fff8c5;
92 --color-merged: #8250df;
93 --color-merged-bg: #fbefff;
94
95 /* Typography */
96 --font-sans:
97 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
98 --font-mono:
99 ui-monospace, "Cascadia Code", "Source Code Pro", monospace;
100
101 --text-xs: 0.75rem;
102 --text-sm: 0.875rem;
103 --text-base: 1rem;
104 --text-lg: 1.125rem;
105 --text-xl: 1.25rem;
106 --text-2xl: 1.5rem;
107 --text-3xl: 1.875rem;
108
109 /* Spacing */
110 --space-1: 0.25rem;
111 --space-2: 0.5rem;
112 --space-3: 0.75rem;
113 --space-4: 1rem;
114 --space-5: 1.25rem;
115 --space-6: 1.5rem;
116 --space-8: 2rem;
117 --space-10: 2.5rem;
118 --space-12: 3rem;
119 --space-16: 4rem;
120
121 /* Border radius */
122 --radius-sm: 4px;
123 --radius-md: 6px;
124 --radius-lg: 8px;
125 --radius-full: 9999px;
126
127 /* Shadows */
128 --shadow-sm: 0 1px 0 rgba(27, 31, 36, 0.04);
129 --shadow-md: 0 3px 6px rgba(140, 149, 159, 0.15);
130 --shadow-lg: 0 8px 24px rgba(140, 149, 159, 0.2);
131 }
132
133 @media (prefers-color-scheme: dark) {
134 :root {
135 --color-bg: #0d1117;
136 --color-bg-subtle: #161b22;
137 --color-bg-inset: #1c2128;
138 --color-border: #30363d;
139 --color-border-muted: #21262d;
140 --color-text: #e6edf3;
141 --color-text-muted: #7d8590;
142 --color-link: #58a6ff;
143 --color-link-hover: #79c0ff;
144
145 --color-accent: #f0883e;
146 --color-accent-bg: #3d2f00;
147
148 --color-success: #3fb950;
149 --color-success-bg: #0d2b19;
150 --color-danger: #f85149;
151 --color-danger-bg: #2d1419;
152 --color-warning: #d29922;
153 --color-warning-bg: #2c2000;
154 --color-merged: #bc8cff;
155 --color-merged-bg: #1e0b3e;
156 }
157 }
158
159 /* Explicit theme overrides — applied via data-theme attribute set by cookie */
160 :root[data-theme="dark"] {
161 --color-bg: #0d1117;
162 --color-bg-subtle: #161b22;
163 --color-bg-inset: #1c2128;
164 --color-border: #30363d;
165 --color-border-muted: #21262d;
166 --color-text: #e6edf3;
167 --color-text-muted: #7d8590;
168 --color-link: #58a6ff;
169 --color-link-hover: #79c0ff;
170 --color-accent: #f0883e;
171 --color-accent-bg: #3d2f00;
172 --color-success: #3fb950;
173 --color-success-bg: #0d2b19;
174 --color-danger: #f85149;
175 --color-danger-bg: #2d1419;
176 --color-warning: #d29922;
177 --color-warning-bg: #2c2000;
178 --color-merged: #bc8cff;
179 --color-merged-bg: #1e0b3e;
180 }
181 :root[data-theme="light"] {
182 --color-bg: #ffffff;
183 --color-bg-subtle: #f6f8fa;
184 --color-bg-inset: #eef0f2;
185 --color-border: #d0d7de;
186 --color-border-muted: #e4e7eb;
187 --color-text: #1f2328;
188 --color-text-muted: #656d76;
189 --color-link: #0969da;
190 --color-link-hover: #0550ae;
191 --color-accent: #fd7e14;
192 --color-accent-bg: #fff3cd;
193 --color-success: #1a7f37;
194 --color-success-bg: #dafbe1;
195 --color-danger: #cf222e;
196 --color-danger-bg: #ffebe9;
197 --color-warning: #9a6700;
198 --color-warning-bg: #fff8c5;
199 --color-merged: #8250df;
200 --color-merged-bg: #fbefff;
201 }
202}
203
204/* ============================================================
205 @layer layout
206 ============================================================ */
207@layer layout {
208 body {
209 font-family: var(--font-sans);
210 font-size: var(--text-base);
211 color: var(--color-text);
212 background: var(--color-bg);
213 display: grid;
214 grid-template-rows: auto 1fr auto;
215 min-height: 100dvh;
216 }
217
218 .site-header {
219 background: var(--color-bg-subtle);
220 border-bottom: 1px solid var(--color-border);
221 position: sticky;
222 top: 0;
223 z-index: 100;
224 }
225
226 .site-nav {
227 max-width: 1200px;
228 margin: 0 auto;
229 padding: var(--space-3) var(--space-4);
230 display: flex;
231 align-items: center;
232 gap: var(--space-4);
233 }
234
235 .site-logo {
236 display: flex;
237 align-items: center;
238 gap: var(--space-2);
239 text-decoration: none;
240 font-weight: 700;
241 font-size: var(--text-lg);
242 color: var(--color-text);
243 }
244
245 .logo-icon {
246 width: 1.6em;
247 height: 1.6em;
248 display: block;
249 flex-shrink: 0;
250 }
251
252 .nav-links {
253 margin-left: auto;
254 display: flex;
255 align-items: center;
256 gap: var(--space-3);
257 }
258
259 .nav-user {
260 font-size: var(--text-sm);
261 color: var(--color-text-muted);
262 }
263
264 .site-main {
265 padding: var(--space-8) var(--space-4);
266 min-width: 0;
267 }
268
269 .site-footer {
270 text-align: center;
271 padding: var(--space-6) var(--space-4);
272 font-size: var(--text-sm);
273 color: var(--color-text-muted);
274 border-top: 1px solid var(--color-border);
275 }
276
277 .container {
278 max-width: 1000px;
279 margin: 0 auto;
280 overflow-x: clip;
281 }
282
283 .container-narrow {
284 max-width: 680px;
285 }
286
287 .inline-form {
288 display: inline;
289 }
290
291 /* --- Two-step delete confirmation --- */
292 .confirm-details {
293 position: relative;
294 display: inline-block;
295 }
296 .confirm-details > summary {
297 list-style: none;
298 }
299 .confirm-details > summary::-webkit-details-marker {
300 display: none;
301 }
302 .confirm-popup {
303 position: absolute;
304 right: 0;
305 top: calc(100% + var(--space-1));
306 background: var(--color-bg);
307 border: 1px solid var(--color-border);
308 border-radius: var(--radius-md);
309 padding: var(--space-3) var(--space-4);
310 display: flex;
311 align-items: center;
312 gap: var(--space-3);
313 white-space: nowrap;
314 z-index: 100;
315 font-size: var(--text-sm);
316 color: var(--color-text-muted);
317 }
318}
319
320/* ============================================================
321 @layer components
322 ============================================================ */
323@layer components {
324 /* --- Buttons --- */
325 .btn {
326 display: inline-flex;
327 align-items: center;
328 gap: var(--space-2);
329 padding: var(--space-2) var(--space-4);
330 border: 1px solid var(--color-border);
331 border-radius: var(--radius-md);
332 font-size: var(--text-sm);
333 font-weight: 500;
334 text-decoration: none;
335 cursor: pointer;
336 background: var(--color-bg-subtle);
337 color: var(--color-text);
338 transition:
339 background 0.1s,
340 border-color 0.1s;
341 white-space: nowrap;
342 }
343 .btn:hover {
344 background: var(--color-bg-inset);
345 border-color: var(--color-border);
346 }
347 .btn:disabled {
348 opacity: 0.5;
349 cursor: not-allowed;
350 }
351 .btn-primary {
352 background: var(--color-accent);
353 border-color: transparent;
354 color: #fff;
355 }
356 .btn-primary:hover {
357 background: color-mix(in srgb, var(--color-accent) 82%, #000);
358 }
359 .btn-secondary {
360 background: var(--color-bg-subtle);
361 border-color: var(--color-border);
362 }
363 .btn-ghost {
364 background: transparent;
365 border-color: transparent;
366 }
367 .btn-ghost:hover {
368 background: var(--color-bg-inset);
369 }
370 /* Keep ghost transparent even when combined with size variants */
371 .btn-ghost.btn-xs,
372 .btn-ghost.btn-sm {
373 background: transparent;
374 border-color: transparent;
375 }
376 .btn-ghost.btn-xs:hover,
377 .btn-ghost.btn-sm:hover {
378 background: var(--color-bg-inset);
379 }
380 .btn-sm {
381 padding: var(--space-1) var(--space-3);
382 font-size: var(--text-xs);
383 }
384 .btn-block {
385 width: 100%;
386 justify-content: center;
387 }
388
389 /* --- Forms --- */
390 .form-group {
391 display: flex;
392 flex-direction: column;
393 gap: var(--space-2);
394 margin-bottom: var(--space-4);
395 }
396 .form-group label {
397 font-size: var(--text-sm);
398 font-weight: 500;
399 color: var(--color-text);
400 }
401 .form-group input:not([type="file"]):not([type="checkbox"]),
402 .form-group textarea,
403 .form-group select {
404 padding: var(--space-2) var(--space-3);
405 border: 1px solid var(--color-border);
406 border-radius: var(--radius-md);
407 background: var(--color-bg);
408 color: var(--color-text);
409 font-size: var(--text-sm);
410 }
411 .form-group input:not([type="file"]):not([type="checkbox"]):focus,
412 .form-group textarea:focus {
413 outline: 2px solid var(--color-accent);
414 outline-offset: -1px;
415 border-color: var(--color-accent);
416 }
417 .form-group input[type="file"] {
418 font-size: var(--text-sm);
419 color: var(--color-text);
420 padding: 0;
421 border: none;
422 background: none;
423 }
424 .form-group textarea {
425 resize: vertical;
426 min-height: 120px;
427 }
428 .form-success {
429 background: var(--color-success-bg);
430 color: var(--color-success);
431 border: 1px solid var(--color-success);
432 border-radius: var(--radius-md);
433 padding: var(--space-3) var(--space-4);
434 font-size: var(--text-sm);
435 margin-bottom: var(--space-4);
436 }
437 .form-hint {
438 font-size: var(--text-sm);
439 color: var(--color-text-muted);
440 margin: 0;
441 }
442 .form-error {
443 background: var(--color-danger-bg);
444 color: var(--color-danger);
445 border: 1px solid var(--color-danger);
446 border-radius: var(--radius-md);
447 padding: var(--space-3) var(--space-4);
448 font-size: var(--text-sm);
449 margin-bottom: var(--space-4);
450 }
451 .form-actions {
452 display: flex;
453 gap: var(--space-3);
454 align-items: center;
455 flex-wrap: wrap;
456 }
457 .form-card {
458 background: var(--color-bg-subtle);
459 border: 1px solid var(--color-border);
460 border-radius: var(--radius-lg);
461 padding: var(--space-6);
462 margin-top: var(--space-4);
463 }
464 .checkbox-label {
465 display: flex;
466 align-items: center;
467 gap: var(--space-2);
468 cursor: pointer;
469 }
470
471 /* --- Page header --- */
472 .page-header {
473 display: flex;
474 align-items: center;
475 justify-content: space-between;
476 margin-bottom: var(--space-6);
477 gap: var(--space-4);
478 }
479 .page-title {
480 font-size: var(--text-2xl);
481 color: var(--color-text);
482 margin-bottom: var(--space-4);
483 }
484 .page-title a {
485 text-decoration: none;
486 color: var(--color-link);
487 }
488 .page-title a:hover {
489 text-decoration: underline;
490 }
491 .section-title {
492 font-size: var(--text-lg);
493 margin-bottom: var(--space-4);
494 padding-bottom: var(--space-2);
495 border-bottom: 1px solid var(--color-border);
496 }
497
498 /* --- Auth --- */
499 .auth-container {
500 max-width: 400px;
501 margin: var(--space-12) auto;
502 }
503 .auth-container .page-title {
504 margin-bottom: var(--space-6);
505 }
506 .auth-form {
507 margin-bottom: var(--space-4);
508 }
509 .auth-footer {
510 text-align: center;
511 font-size: var(--text-sm);
512 color: var(--color-text-muted);
513 margin-top: var(--space-4);
514 }
515 .passkey-btn {
516 display: none;
517 margin-top: var(--space-3);
518 }
519
520 /* --- Repo header --- */
521 .repo-header {
522 margin-bottom: var(--space-2);
523 }
524 .repo-title-row {
525 display: flex;
526 align-items: center;
527 gap: var(--space-3);
528 flex-wrap: wrap;
529 }
530 .repo-title-row .page-title {
531 margin-bottom: 0;
532 }
533 .repo-header-title {
534 display: flex;
535 align-items: center;
536 gap: var(--space-3);
537 flex-wrap: wrap;
538 }
539 .repo-description {
540 color: var(--color-text-muted);
541 margin-top: var(--space-2);
542 }
543 .repo-header-meta {
544 display: flex;
545 align-items: center;
546 gap: var(--space-4);
547 margin-bottom: var(--space-3);
548 font-size: var(--text-sm);
549 color: var(--color-text-muted);
550 }
551 .icon {
552 font-style: normal;
553 }
554
555 /* --- Branch selector --- */
556 .branch-selector {
557 display: inline-flex;
558 align-items: center;
559 gap: var(--space-2);
560 }
561 .branch-selector-icon {
562 color: var(--color-text-muted);
563 font-size: var(--text-sm);
564 user-select: none;
565 }
566 .branch-select {
567 padding: var(--space-1) var(--space-2);
568 padding-right: var(--space-5);
569 border: 1px solid var(--color-border);
570 border-radius: var(--radius-md);
571 background: var(--color-bg-subtle);
572 font-size: var(--text-sm);
573 font-family: var(--font-mono);
574 color: var(--color-text);
575 cursor: pointer;
576 appearance: auto;
577 max-width: 180px;
578 }
579 .branch-select:hover {
580 border-color: var(--color-text-muted);
581 }
582 .branch-select:focus {
583 outline: 2px solid var(--color-accent);
584 outline-offset: -1px;
585 }
586
587 /* toolbar row above file tree */
588 .tree-toolbar {
589 display: flex;
590 align-items: center;
591 justify-content: space-between;
592 margin-bottom: var(--space-3);
593 }
594
595 /* commits-header flex row */
596 .commits-header {
597 display: flex;
598 align-items: center;
599 gap: var(--space-4);
600 margin-bottom: var(--space-4);
601 flex-wrap: wrap;
602 }
603 .commits-header .section-title {
604 margin-bottom: 0;
605 }
606
607 /* --- Repo nav bar (tabs + private badge) --- */
608 .repo-nav-bar {
609 display: flex;
610 align-items: center;
611 justify-content: space-between;
612 border-bottom: 1px solid var(--color-border);
613 margin-bottom: var(--space-6);
614 gap: var(--space-4);
615 }
616
617 /* --- Repo tabs --- */
618 .repo-tabs {
619 display: flex;
620 gap: 0;
621 flex: 1;
622 overflow-x: auto;
623 overflow-y: hidden;
624 }
625 .repo-tab {
626 padding: var(--space-3) var(--space-4);
627 font-size: var(--text-sm);
628 text-decoration: none;
629 color: var(--color-text-muted);
630 border-bottom: 2px solid transparent;
631 margin-bottom: -1px;
632 transition: color 0.1s;
633 }
634 .repo-tab:hover {
635 color: var(--color-text);
636 }
637 .repo-tab.active {
638 color: var(--color-text);
639 font-weight: 600;
640 border-bottom-color: var(--color-accent);
641 }
642 /* Align active indicator with nav-bar border */
643 .repo-tab {
644 margin-bottom: -1px;
645 }
646
647 /* --- Repo list --- */
648 .repo-list {
649 display: flex;
650 flex-direction: column;
651 gap: var(--space-2);
652 }
653 .repo-card {
654 display: flex;
655 align-items: flex-start;
656 justify-content: space-between;
657 padding: var(--space-4) var(--space-5);
658 border: 1px solid var(--color-border);
659 border-radius: var(--radius-lg);
660 background: var(--color-bg);
661 gap: var(--space-4);
662 transition: border-color 0.15s;
663 }
664 .repo-card:hover {
665 border-color: var(--color-accent);
666 }
667 .repo-card-main {
668 flex: 1;
669 min-width: 0;
670 }
671 .repo-card-title {
672 display: flex;
673 align-items: center;
674 gap: var(--space-2);
675 flex-wrap: wrap;
676 margin-bottom: var(--space-1);
677 }
678 .repo-name {
679 font-size: var(--text-lg);
680 font-weight: 600;
681 color: var(--color-link);
682 text-decoration: none;
683 }
684 .repo-name:hover {
685 text-decoration: underline;
686 }
687 .repo-card-meta {
688 display: flex;
689 flex-direction: column;
690 align-items: flex-end;
691 gap: var(--space-1);
692 font-size: var(--text-xs);
693 color: var(--color-text-muted);
694 white-space: nowrap;
695 }
696 .repo-date {
697 color: var(--color-text-muted);
698 }
699
700 /* --- Badges --- */
701 .badge {
702 display: inline-flex;
703 align-items: center;
704 padding: 1px var(--space-2);
705 border-radius: var(--radius-full);
706 font-size: var(--text-xs);
707 font-weight: 500;
708 border: 1px solid;
709 }
710 .badge-private {
711 color: var(--color-warning);
712 border-color: var(--color-warning);
713 background: var(--color-warning-bg);
714 }
715 .issue-badge,
716 .patch-badge {
717 display: inline-flex;
718 align-items: center;
719 padding: var(--space-1) var(--space-3);
720 border-radius: var(--radius-full);
721 font-size: var(--text-xs);
722 font-weight: 500;
723 text-transform: capitalize;
724 }
725 .issue-badge.open,
726 .patch-badge.open {
727 background: var(--color-success-bg);
728 color: var(--color-success);
729 }
730 .issue-badge.closed,
731 .patch-badge.closed {
732 background: var(--color-danger-bg);
733 color: var(--color-danger);
734 }
735 .issue-badge.completed {
736 background: var(--color-merged-bg);
737 color: var(--color-merged);
738 }
739 .patch-badge.merged {
740 background: var(--color-merged-bg);
741 color: var(--color-merged);
742 }
743
744 /* --- Empty state --- */
745 .empty-state {
746 text-align: center;
747 padding: var(--space-16) var(--space-4);
748 color: var(--color-text-muted);
749 }
750 .empty-state p {
751 margin-bottom: var(--space-4);
752 font-size: var(--text-lg);
753 }
754
755 /* --- Breadcrumb --- */
756 .breadcrumb {
757 display: flex;
758 align-items: center;
759 flex-wrap: wrap;
760 gap: var(--space-1);
761 font-size: var(--text-sm);
762 margin-bottom: var(--space-4);
763 }
764 .breadcrumb a {
765 color: var(--color-link);
766 text-decoration: none;
767 }
768 .breadcrumb a:hover {
769 text-decoration: underline;
770 }
771 .breadcrumb-sep {
772 color: var(--color-text-muted);
773 }
774 .breadcrumb-current {
775 color: var(--color-text-muted);
776 }
777
778 /* --- File tree --- */
779 .file-tree {
780 width: 100%;
781 border: 1px solid var(--color-border);
782 border-radius: var(--radius-lg);
783 border-collapse: collapse;
784 overflow: hidden;
785 margin-bottom: var(--space-6);
786 }
787 .file-tree-row {
788 border-bottom: 1px solid var(--color-border-muted);
789 }
790 .file-tree-row:last-child {
791 border-bottom: none;
792 }
793 .file-tree-row:hover {
794 background: var(--color-bg-subtle);
795 }
796 .file-icon,
797 .file-name,
798 .file-size {
799 padding: var(--space-2) var(--space-3);
800 font-size: var(--text-sm);
801 vertical-align: middle;
802 }
803 .file-icon {
804 width: 36px;
805 padding-right: var(--space-1);
806 text-align: center;
807 line-height: 0;
808 }
809 .file-name {
810 width: 100%;
811 }
812 .file-name a {
813 color: var(--color-link);
814 text-decoration: none;
815 }
816 .file-name a:hover {
817 text-decoration: underline;
818 }
819 .file-name a.file-name-dir {
820 font-weight: 500;
821 }
822 .file-size {
823 text-align: right;
824 color: var(--color-text-muted);
825 font-size: var(--text-xs);
826 white-space: nowrap;
827 padding-right: var(--space-4);
828 }
829 .file-icon-dir {
830 color: var(--color-link);
831 }
832 .file-icon-file {
833 color: var(--color-text-muted);
834 }
835 .tree-icon {
836 display: inline-block;
837 vertical-align: text-bottom;
838 }
839 .file-tree-row-up .file-name a {
840 color: var(--color-text-muted);
841 }
842 .file-tree-row-up .file-name a:hover {
843 color: var(--color-link);
844 }
845
846 /* --- File blob --- */
847 .file-blob-header {
848 display: flex;
849 align-items: center;
850 justify-content: space-between;
851 padding: var(--space-3) var(--space-4);
852 background: var(--color-bg-subtle);
853 border: 1px solid var(--color-border);
854 border-radius: var(--radius-lg) var(--radius-lg) 0 0;
855 }
856 .file-blob-name {
857 font-size: var(--text-sm);
858 font-weight: 500;
859 }
860 .file-blob-body {
861 border: 1px solid var(--color-border);
862 border-top: none;
863 border-radius: 0 0 var(--radius-lg) var(--radius-lg);
864 overflow: auto;
865 }
866 /* Blob line-number table */
867 .blob-table {
868 min-width: 100%;
869 border-collapse: collapse;
870 font-family: var(--font-mono);
871 font-size: var(--text-sm);
872 line-height: 1.6;
873 background-color: var(--shiki-light-bg, #fff);
874 color: var(--shiki-light, inherit);
875 }
876 .blob-ln {
877 width: 1%;
878 min-width: 48px;
879 text-align: right;
880 padding: 0 var(--space-3);
881 color: var(--color-text-muted);
882 border-right: 1px solid var(--color-border-muted);
883 user-select: none;
884 white-space: nowrap;
885 vertical-align: top;
886 }
887 .blob-ln a {
888 color: inherit;
889 text-decoration: none;
890 }
891 .blob-ln a:hover {
892 color: var(--color-link);
893 }
894 .blob-code {
895 padding: 0 var(--space-4);
896 white-space: pre;
897 overflow: visible;
898 vertical-align: top;
899 }
900 .blob-table tr:target {
901 background: color-mix(in srgb, #ddf4ff 60%, transparent);
902 }
903 .blob-table tr:target .blob-ln {
904 background: color-mix(in srgb, #ddf4ff 80%, transparent);
905 }
906 .file-download-notice {
907 padding: var(--space-8);
908 text-align: center;
909 color: var(--color-text-muted);
910 }
911 .file-download-notice p {
912 margin-bottom: var(--space-4);
913 }
914 .file-media {
915 padding: var(--space-4);
916 display: flex;
917 justify-content: center;
918 background: var(--color-canvas-subtle);
919 }
920 .file-media-img {
921 max-width: 100%;
922 height: auto;
923 display: block;
924 }
925 .file-media-audio {
926 width: 100%;
927 max-width: 600px;
928 }
929 .file-media-video {
930 max-width: 100%;
931 max-height: 80vh;
932 }
933
934 /* --- Commit list --- */
935 .commit-list {
936 display: flex;
937 flex-direction: column;
938 }
939 .commit-item {
940 display: flex;
941 align-items: flex-start;
942 justify-content: space-between;
943 padding: var(--space-3) 0;
944 border-bottom: 1px solid var(--color-border-muted);
945 gap: var(--space-4);
946 flex-wrap: wrap;
947 }
948 .commit-item:last-child {
949 border-bottom: none;
950 }
951 .commit-main {
952 flex: 1;
953 min-width: 0;
954 }
955 .commit-subject {
956 color: var(--color-text);
957 text-decoration: none;
958 font-size: var(--text-sm);
959 font-weight: 500;
960 }
961 .commit-subject:hover {
962 color: var(--color-link);
963 }
964 .commit-meta {
965 display: flex;
966 align-items: center;
967 gap: var(--space-3);
968 font-size: var(--text-xs);
969 color: var(--color-text-muted);
970 white-space: nowrap;
971 }
972 .commit-hash {
973 font-family: var(--font-mono);
974 color: var(--color-link);
975 text-decoration: none;
976 background: var(--color-bg-inset);
977 padding: 1px var(--space-2);
978 border-radius: var(--radius-sm);
979 }
980 .commit-hash:hover {
981 text-decoration: underline;
982 }
983 .mono {
984 font-family: var(--font-mono);
985 }
986
987 /* --- Commit detail viewer --- */
988 .commit-page-top {
989 display: flex;
990 align-items: center;
991 justify-content: space-between;
992 margin-bottom: var(--space-4);
993 }
994 .commit-card {
995 border: 1px solid var(--color-border);
996 border-radius: var(--radius-lg);
997 margin-bottom: var(--space-4);
998 overflow: hidden;
999 }
1000 .commit-card-subject {
1001 font-size: var(--text-xl);
1002 font-weight: 600;
1003 padding: var(--space-5) var(--space-6);
1004 border-bottom: 1px solid var(--color-border);
1005 line-height: 1.3;
1006 }
1007 .commit-card-body {
1008 padding: var(--space-4) var(--space-6);
1009 font-family: inherit;
1010 font-size: var(--text-sm);
1011 color: var(--color-text-muted);
1012 border-bottom: 1px solid var(--color-border);
1013 overflow-x: auto;
1014 }
1015 .commit-card-meta {
1016 padding: var(--space-4) var(--space-6);
1017 display: flex;
1018 flex-direction: column;
1019 gap: var(--space-2);
1020 background: var(--color-bg-subtle);
1021 }
1022 .commit-card-meta-row {
1023 display: flex;
1024 align-items: baseline;
1025 gap: var(--space-3);
1026 font-size: var(--text-sm);
1027 flex-wrap: wrap;
1028 }
1029 .commit-meta-label {
1030 font-weight: 600;
1031 color: var(--color-text-muted);
1032 min-width: 5rem;
1033 font-size: var(--text-xs);
1034 text-transform: uppercase;
1035 letter-spacing: 0.04em;
1036 }
1037 .commit-sha-full {
1038 font-size: var(--text-xs);
1039 background: var(--color-bg-inset);
1040 padding: 2px var(--space-2);
1041 border-radius: var(--radius-sm);
1042 word-break: break-all;
1043 }
1044 .commit-stats-bar {
1045 font-size: var(--text-sm);
1046 color: var(--color-text-muted);
1047 margin-bottom: var(--space-4);
1048 }
1049
1050 /* --- Commit layout (sidebar + diffs) --- */
1051 .commit-layout {
1052 display: grid;
1053 grid-template-columns: 1fr;
1054 gap: var(--space-5);
1055 align-items: start;
1056 }
1057 .commit-diffs {
1058 min-width: 0;
1059 }
1060 @media (min-width: 900px) {
1061 .commit-layout {
1062 grid-template-columns: 220px 1fr;
1063 }
1064 .commit-layout:has(.file-nav-details:not([open])) {
1065 grid-template-columns: auto 1fr;
1066 }
1067 }
1068
1069 /* --- File nav sidebar --- */
1070 .commit-file-nav {
1071 position: sticky;
1072 top: calc(56px + var(--space-4));
1073 max-height: calc(100vh - 140px);
1074 overflow-y: auto;
1075 }
1076 .file-nav-details {
1077 border: 1px solid var(--color-border);
1078 border-radius: var(--radius-lg);
1079 background: var(--color-bg-subtle);
1080 overflow: hidden;
1081 }
1082 .file-nav-toggle {
1083 display: flex;
1084 align-items: center;
1085 gap: var(--space-2);
1086 padding: var(--space-3) var(--space-4);
1087 font-size: var(--text-sm);
1088 font-weight: 500;
1089 cursor: pointer;
1090 list-style: none;
1091 user-select: none;
1092 border-bottom: 1px solid var(--color-border);
1093 }
1094 .file-nav-toggle::-webkit-details-marker {
1095 display: none;
1096 }
1097 .file-nav-details:not([open]) .file-nav-toggle {
1098 border-bottom: none;
1099 }
1100 .file-nav-toggle-icon {
1101 font-size: 1em;
1102 transition: transform 0.15s;
1103 }
1104 .file-nav-details:not([open]) .file-nav-toggle-icon {
1105 transform: rotate(-90deg);
1106 }
1107 .file-nav-list {
1108 padding: var(--space-1) 0;
1109 list-style: none;
1110 }
1111 .file-nav-item {
1112 display: flex;
1113 align-items: center;
1114 gap: var(--space-2);
1115 padding: var(--space-1) var(--space-3);
1116 font-size: var(--text-xs);
1117 text-decoration: none;
1118 color: var(--color-text);
1119 border-radius: 0;
1120 overflow: hidden;
1121 }
1122 .file-nav-item:hover {
1123 background: var(--color-bg-inset);
1124 }
1125 .file-nav-status {
1126 flex-shrink: 0;
1127 width: 16px;
1128 height: 16px;
1129 display: inline-flex;
1130 align-items: center;
1131 justify-content: center;
1132 border-radius: var(--radius-sm);
1133 font-size: 9px;
1134 font-weight: 700;
1135 font-family: var(--font-mono);
1136 }
1137 .file-status-added {
1138 background: var(--color-success-bg);
1139 color: var(--color-success);
1140 }
1141 .file-status-deleted {
1142 background: var(--color-danger-bg);
1143 color: var(--color-danger);
1144 }
1145 .file-status-modified {
1146 background: var(--color-accent-bg);
1147 color: var(--color-accent);
1148 }
1149 .file-status-renamed {
1150 background: var(--color-merged-bg);
1151 color: var(--color-merged);
1152 }
1153 .file-status-copied {
1154 background: var(--color-merged-bg);
1155 color: var(--color-merged);
1156 }
1157 .file-nav-name {
1158 flex: 1;
1159 overflow: hidden;
1160 text-overflow: ellipsis;
1161 white-space: nowrap;
1162 font-family: var(--font-mono);
1163 }
1164 .file-nav-stat {
1165 flex-shrink: 0;
1166 display: flex;
1167 gap: var(--space-1);
1168 font-size: var(--text-xs);
1169 font-family: var(--font-mono);
1170 }
1171 .nav-add {
1172 color: var(--color-success);
1173 }
1174 .nav-del {
1175 color: var(--color-danger);
1176 }
1177 .nav-binary {
1178 color: var(--color-muted);
1179 font-size: var(--text-xs);
1180 }
1181 .file-nav-dir > details > .file-nav-list {
1182 padding-left: var(--space-4);
1183 }
1184 .file-nav-dir-toggle {
1185 display: flex;
1186 align-items: center;
1187 gap: var(--space-1);
1188 padding: var(--space-1) var(--space-3);
1189 font-size: var(--text-xs);
1190 font-family: var(--font-mono);
1191 color: var(--color-text-muted);
1192 cursor: pointer;
1193 list-style: none;
1194 user-select: none;
1195 }
1196 .file-nav-dir-toggle::-webkit-details-marker {
1197 display: none;
1198 }
1199 .file-nav-dir > details:not([open]) .file-nav-toggle-icon {
1200 transform: rotate(-90deg);
1201 }
1202
1203 /* --- Diff file cards --- */
1204 .diff-file {
1205 border: 1px solid var(--color-border);
1206 border-radius: var(--radius-lg);
1207 margin-bottom: var(--space-4);
1208 overflow: hidden;
1209 }
1210 .diff-file-header {
1211 display: flex;
1212 align-items: center;
1213 justify-content: space-between;
1214 gap: var(--space-3);
1215 padding: var(--space-3) var(--space-4);
1216 background: var(--color-bg-subtle);
1217 cursor: pointer;
1218 list-style: none;
1219 user-select: none;
1220 flex-wrap: wrap;
1221 }
1222 .diff-file-header::-webkit-details-marker {
1223 display: none;
1224 }
1225 .diff-file-header-left {
1226 display: flex;
1227 align-items: center;
1228 gap: var(--space-2);
1229 min-width: 0;
1230 flex: 1;
1231 }
1232 .diff-file-header-right {
1233 display: flex;
1234 align-items: center;
1235 gap: var(--space-2);
1236 flex-shrink: 0;
1237 flex-wrap: wrap;
1238 }
1239 .diff-file-toggle-icon {
1240 font-size: 0.7em;
1241 flex-shrink: 0;
1242 transition: transform 0.15s;
1243 }
1244 .diff-file:not([open]) .diff-file-toggle-icon {
1245 transform: rotate(-90deg);
1246 }
1247 .diff-status-badge {
1248 flex-shrink: 0;
1249 width: 18px;
1250 height: 18px;
1251 display: inline-flex;
1252 align-items: center;
1253 justify-content: center;
1254 border-radius: var(--radius-sm);
1255 font-size: 10px;
1256 font-weight: 700;
1257 font-family: var(--font-mono);
1258 }
1259 .diff-status-added {
1260 background: var(--color-success-bg);
1261 color: var(--color-success);
1262 }
1263 .diff-status-deleted {
1264 background: var(--color-danger-bg);
1265 color: var(--color-danger);
1266 }
1267 .diff-status-modified {
1268 background: var(--color-accent-bg);
1269 color: var(--color-accent);
1270 }
1271 .diff-status-renamed {
1272 background: var(--color-merged-bg);
1273 color: var(--color-merged);
1274 }
1275 .diff-status-copied {
1276 background: var(--color-merged-bg);
1277 color: var(--color-merged);
1278 }
1279 .diff-file-path {
1280 font-size: var(--text-sm);
1281 font-weight: 500;
1282 overflow: hidden;
1283 text-overflow: ellipsis;
1284 white-space: nowrap;
1285 }
1286 .diff-rename-arrow {
1287 font-size: var(--text-xs);
1288 color: var(--color-text-muted);
1289 white-space: nowrap;
1290 overflow: hidden;
1291 text-overflow: ellipsis;
1292 }
1293 .diff-stat-add {
1294 color: var(--color-success);
1295 font-size: var(--text-sm);
1296 font-family: var(--font-mono);
1297 font-weight: 600;
1298 }
1299 .diff-stat-del {
1300 color: var(--color-danger);
1301 font-size: var(--text-sm);
1302 font-family: var(--font-mono);
1303 font-weight: 600;
1304 }
1305 .diff-stat-binary {
1306 color: var(--color-muted);
1307 font-size: var(--text-sm);
1308 font-family: var(--font-mono);
1309 }
1310 .btn-xs {
1311 padding: 1px var(--space-2);
1312 font-size: var(--text-xs);
1313 border: 1px solid var(--color-border);
1314 border-radius: var(--radius-sm);
1315 background: var(--color-bg);
1316 color: var(--color-text);
1317 text-decoration: none;
1318 cursor: pointer;
1319 white-space: nowrap;
1320 font-family: var(--font-mono);
1321 display: inline-flex;
1322 align-items: center;
1323 transition: background 0.1s;
1324 }
1325 .btn-xs:hover {
1326 background: var(--color-bg-inset);
1327 }
1328
1329 /* --- Diff file body --- */
1330 .diff-binary-notice {
1331 padding: var(--space-4) var(--space-6);
1332 font-size: var(--text-sm);
1333 color: var(--color-text-muted);
1334 font-style: italic;
1335 }
1336 .diff-hunk {
1337 border-top: 1px solid var(--color-border-muted);
1338 overflow-x: auto;
1339 }
1340 .diff-hunk:first-child {
1341 border-top: none;
1342 }
1343 .diff-hunk-header {
1344 padding: var(--space-1) var(--space-4);
1345 font-family: var(--font-mono);
1346 font-size: var(--text-xs);
1347 font-weight: normal;
1348 text-align: left;
1349 background: color-mix(
1350 in srgb,
1351 var(--color-merged-bg) 50%,
1352 var(--color-bg)
1353 );
1354 color: var(--color-merged);
1355 border-bottom: 1px solid var(--color-border-muted);
1356 white-space: pre;
1357 }
1358
1359 /* --- Diff table --- */
1360 .diff-table {
1361 min-width: 100%;
1362 border-collapse: collapse;
1363 font-family: var(--font-mono);
1364 font-size: var(--text-xs);
1365 line-height: 1.5;
1366 }
1367 .diff-ln {
1368 width: 44px;
1369 min-width: 44px;
1370 text-align: right;
1371 padding: 0 var(--space-2);
1372 color: var(--color-text-muted);
1373 border-right: 1px solid var(--color-border-muted);
1374 user-select: none;
1375 vertical-align: top;
1376 white-space: nowrap;
1377 }
1378 .diff-sign {
1379 width: 18px;
1380 min-width: 18px;
1381 text-align: center;
1382 padding: 0 var(--space-1);
1383 user-select: none;
1384 vertical-align: top;
1385 }
1386 .diff-code {
1387 padding: 0 var(--space-3);
1388 white-space: pre;
1389 overflow: visible;
1390 vertical-align: top;
1391 word-break: normal;
1392 }
1393 /* Row type backgrounds */
1394 .diff-row-add {
1395 background: color-mix(
1396 in srgb,
1397 var(--color-success-bg) 70%,
1398 transparent
1399 );
1400 }
1401 .diff-row-del {
1402 background: color-mix(in srgb, var(--color-danger-bg) 70%, transparent);
1403 }
1404 .diff-row-add .diff-ln,
1405 .diff-row-add .diff-sign {
1406 background: color-mix(
1407 in srgb,
1408 var(--color-success-bg) 90%,
1409 transparent
1410 );
1411 }
1412 .diff-row-del .diff-ln,
1413 .diff-row-del .diff-sign {
1414 background: color-mix(in srgb, var(--color-danger-bg) 90%, transparent);
1415 }
1416 .diff-row-add .diff-sign {
1417 color: var(--color-success);
1418 font-weight: 700;
1419 }
1420 .diff-row-del .diff-sign {
1421 color: var(--color-danger);
1422 font-weight: 700;
1423 }
1424
1425 /* Shiki dark-mode support in diff code cells */
1426 @media (prefers-color-scheme: dark) {
1427 .diff-code span[style] {
1428 /* biome-ignore lint/complexity/noImportantStyles: required to override shiki inline styles */
1429 color: var(--shiki-dark) !important;
1430 }
1431 }
1432
1433 /* Shiki dark-mode support in file blob view */
1434 @media (prefers-color-scheme: dark) {
1435 .blob-table {
1436 background-color: var(--shiki-dark-bg);
1437 color: var(--shiki-dark);
1438 }
1439 .blob-table span[style] {
1440 /* biome-ignore lint/complexity/noImportantStyles: required to override shiki inline styles */
1441 color: var(--shiki-dark) !important;
1442 }
1443 .blob-table tr:target {
1444 background: color-mix(in srgb, #1c3a52 60%, transparent);
1445 }
1446 .blob-table tr:target .blob-ln {
1447 background: color-mix(in srgb, #1c3a52 80%, transparent);
1448 }
1449 }
1450 :root[data-theme="dark"] .blob-table {
1451 background-color: var(--shiki-dark-bg);
1452 color: var(--shiki-dark);
1453 }
1454 :root[data-theme="dark"] .blob-table span[style] {
1455 /* biome-ignore lint/complexity/noImportantStyles: required to override shiki inline styles */
1456 color: var(--shiki-dark) !important;
1457 }
1458
1459 /* --- Issue / Patch list --- */
1460 .list-header {
1461 display: flex;
1462 align-items: center;
1463 justify-content: space-between;
1464 padding: var(--space-3) var(--space-4);
1465 background: var(--color-bg-subtle);
1466 border: 1px solid var(--color-border);
1467 border-radius: var(--radius-lg) var(--radius-lg) 0 0;
1468 gap: var(--space-4);
1469 }
1470 .list-header-tabs {
1471 display: flex;
1472 gap: var(--space-2);
1473 }
1474 .list-tab {
1475 padding: var(--space-1) var(--space-3);
1476 border-radius: var(--radius-md);
1477 font-size: var(--text-sm);
1478 text-decoration: none;
1479 color: var(--color-text-muted);
1480 }
1481 .list-tab:hover {
1482 background: var(--color-bg-inset);
1483 color: var(--color-text);
1484 }
1485 .list-tab.active {
1486 background: var(--color-bg-inset);
1487 color: var(--color-text);
1488 font-weight: 600;
1489 }
1490 .issue-list {
1491 border: 1px solid var(--color-border);
1492 border-top: none;
1493 border-radius: 0 0 var(--radius-lg) var(--radius-lg);
1494 }
1495 .issue-item {
1496 padding: var(--space-4) var(--space-4);
1497 border-bottom: 1px solid var(--color-border-muted);
1498 }
1499 .issue-item:last-child {
1500 border-bottom: none;
1501 }
1502 .issue-main {
1503 display: flex;
1504 align-items: center;
1505 gap: var(--space-2);
1506 margin-bottom: var(--space-1);
1507 flex-wrap: wrap;
1508 }
1509 .issue-title {
1510 font-weight: 500;
1511 text-decoration: none;
1512 color: var(--color-text);
1513 flex: 1;
1514 }
1515 .issue-title:hover {
1516 color: var(--color-link);
1517 }
1518 .issue-meta {
1519 font-size: var(--text-xs);
1520 color: var(--color-text-muted);
1521 display: flex;
1522 gap: var(--space-3);
1523 }
1524 .issue-status-dot,
1525 .patch-status-dot {
1526 width: 8px;
1527 height: 8px;
1528 border-radius: 50%;
1529 flex-shrink: 0;
1530 }
1531 .issue-status-dot.open,
1532 .patch-status-dot.open {
1533 background: var(--color-success);
1534 }
1535 .issue-status-dot.closed,
1536 .patch-status-dot.closed {
1537 background: var(--color-danger);
1538 }
1539 .issue-status-dot.completed {
1540 background: var(--color-merged);
1541 }
1542 .patch-status-dot.merged {
1543 background: var(--color-merged);
1544 }
1545
1546 /* --- Issue detail / Timeline --- */
1547 .issue-detail-header {
1548 display: flex;
1549 align-items: center;
1550 gap: var(--space-3);
1551 margin-bottom: var(--space-6);
1552 }
1553 .issue-number {
1554 font-size: var(--text-2xl);
1555 font-weight: 600;
1556 color: var(--color-text-muted);
1557 white-space: nowrap;
1558 }
1559 .issue-detail-title {
1560 font-size: var(--text-2xl);
1561 font-weight: 600;
1562 overflow-wrap: anywhere;
1563 }
1564 .issue-detail-meta-actions {
1565 margin-left: auto;
1566 display: flex;
1567 gap: var(--space-2);
1568 }
1569 .timeline-item {
1570 border: 1px solid var(--color-border);
1571 border-radius: var(--radius-lg);
1572 margin-bottom: var(--space-4);
1573 overflow: hidden;
1574 }
1575 .timeline-author {
1576 background: var(--color-bg-subtle);
1577 padding: var(--space-3) var(--space-4);
1578 font-size: var(--text-sm);
1579 display: flex;
1580 align-items: center;
1581 justify-content: space-between;
1582 gap: var(--space-3);
1583 border-bottom: 1px solid var(--color-border);
1584 overflow-wrap: anywhere;
1585 }
1586 .timeline-author time {
1587 color: var(--color-text-muted);
1588 font-size: var(--text-xs);
1589 width: max-content;
1590 }
1591 .timeline-author-right {
1592 margin-left: auto;
1593 display: flex;
1594 align-items: center;
1595 gap: var(--space-2);
1596 }
1597 .edited-indicator {
1598 color: var(--color-text-muted);
1599 font-size: var(--text-xs);
1600 cursor: default;
1601 }
1602
1603 /* --- Avatars --- */
1604 .avatar {
1605 display: inline-flex;
1606 border-radius: 4px;
1607 overflow: hidden;
1608 flex-shrink: 0;
1609 vertical-align: middle;
1610 }
1611 .avatar-img {
1612 width: 100%;
1613 height: 100%;
1614 object-fit: cover;
1615 display: block;
1616 color: transparent;
1617 }
1618 .avatar-placeholder {
1619 display: inline-flex;
1620 align-items: center;
1621 justify-content: center;
1622 border-radius: 4px;
1623 background: var(--color-bg-inset);
1624 color: var(--color-text-muted);
1625 font-weight: 600;
1626 flex-shrink: 0;
1627 vertical-align: middle;
1628 }
1629 .avatar-settings {
1630 display: flex;
1631 align-items: flex-start;
1632 gap: var(--space-5);
1633 }
1634 .avatar-actions {
1635 display: flex;
1636 flex-direction: column;
1637 gap: var(--space-3);
1638 }
1639 .nav-user {
1640 display: inline-flex;
1641 align-items: center;
1642 gap: var(--space-2);
1643 }
1644 .timeline-body {
1645 padding: var(--space-4);
1646 }
1647 .timeline-item-new {
1648 padding: var(--space-4);
1649 }
1650 .timeline-item-new .section-title {
1651 font-size: var(--text-base);
1652 border: none;
1653 padding-bottom: 0;
1654 }
1655 /* Edit <details> (summary only) in .timeline-author; form is a sibling shown via :has() */
1656 .timeline-author-right .inline-edit-details {
1657 border: none;
1658 }
1659 .timeline-author-right .inline-edit-details > summary {
1660 padding: 0;
1661 list-style: none;
1662 }
1663 .timeline-author-right
1664 .inline-edit-details
1665 > summary::-webkit-details-marker {
1666 display: none;
1667 }
1668 .inline-edit-details .when-open {
1669 display: none;
1670 }
1671 .inline-edit-details[open] .when-closed {
1672 display: none;
1673 }
1674 .inline-edit-details[open] .when-open {
1675 display: inline;
1676 }
1677 .inline-edit-form-area {
1678 display: none;
1679 border-top: 1px solid var(--color-border-muted);
1680 }
1681 .timeline-item:has(.inline-edit-details[open]) .inline-edit-form-area {
1682 display: block;
1683 }
1684 .timeline-item:has(.inline-edit-details[open]) .timeline-body {
1685 display: none;
1686 }
1687
1688 /* Title edit in issue/patch header */
1689 .issue-detail-header {
1690 align-items: flex-start;
1691 }
1692 .title-with-edit {
1693 flex: 1;
1694 min-width: 0;
1695 display: flex;
1696 flex-direction: column;
1697 gap: var(--space-1);
1698 }
1699 .title-edit-details {
1700 border: none;
1701 align-self: flex-start;
1702 }
1703 .title-with-edit:has(.title-edit-details[open]) .issue-detail-title {
1704 display: none;
1705 }
1706 .title-with-edit:has(.title-edit-details[open]) > .title-edit-details {
1707 display: none;
1708 }
1709 .title-edit-details > summary {
1710 padding: 0;
1711 list-style: none;
1712 }
1713 .title-edit-details > summary::-webkit-details-marker {
1714 display: none;
1715 }
1716 .title-edit-form-area {
1717 display: none;
1718 }
1719 .title-with-edit:has(.title-edit-details[open]) .title-edit-form-area {
1720 display: flex;
1721 flex: 1;
1722 min-width: 0;
1723 }
1724 .title-edit-form {
1725 display: flex;
1726 flex-direction: column;
1727 gap: var(--space-2);
1728 flex: 1;
1729 min-width: 0;
1730 }
1731 .title-edit-form .form-input {
1732 min-width: 0;
1733 width: 100%;
1734 padding: var(--space-2) var(--space-3);
1735 border: 1px solid var(--color-border);
1736 border-radius: var(--radius-md);
1737 background: var(--color-bg);
1738 color: var(--color-text);
1739 font-size: var(--text-sm);
1740 }
1741 .title-edit-form .form-input:focus {
1742 outline: 2px solid var(--color-accent);
1743 outline-offset: -1px;
1744 border-color: var(--color-accent);
1745 }
1746 .title-edit-actions {
1747 display: flex;
1748 gap: var(--space-2);
1749 }
1750
1751 .inline-edit-form {
1752 padding: var(--space-4);
1753 display: flex;
1754 flex-direction: column;
1755 gap: var(--space-3);
1756 }
1757
1758 /* --- Reactions --- */
1759 .reaction-bar {
1760 display: flex;
1761 flex-wrap: wrap;
1762 gap: var(--space-2);
1763 padding: var(--space-2) var(--space-4);
1764 border-top: 1px solid var(--color-border-muted);
1765 }
1766 .reaction-form {
1767 display: inline;
1768 }
1769 .reaction-btn {
1770 display: inline-flex;
1771 align-items: center;
1772 gap: var(--space-1);
1773 padding: var(--space-1) var(--space-3);
1774 border: 1px solid var(--color-border);
1775 border-radius: var(--radius-full);
1776 background: var(--color-bg-subtle);
1777 color: var(--color-text);
1778 font-size: var(--text-sm);
1779 cursor: pointer;
1780 transition: background 0.1s;
1781 }
1782 .reaction-btn:hover {
1783 background: var(--color-bg-inset);
1784 }
1785 .reaction-btn.reacted {
1786 background: var(--color-accent-bg);
1787 border-color: var(--color-accent);
1788 }
1789 .reaction-picker {
1790 position: relative;
1791 }
1792 .reaction-add-btn {
1793 display: inline-flex;
1794 align-items: center;
1795 justify-content: center;
1796 width: 28px;
1797 height: 28px;
1798 border: 1px dashed var(--color-border);
1799 border-radius: var(--radius-full);
1800 background: transparent;
1801 cursor: pointer;
1802 font-size: var(--text-base);
1803 color: var(--color-text-muted);
1804 list-style: none;
1805 }
1806 .reaction-add-btn::-webkit-details-marker {
1807 display: none;
1808 }
1809 .reaction-picker-dropdown {
1810 position: absolute;
1811 bottom: calc(100% + var(--space-2));
1812 left: 0;
1813 background: var(--color-bg);
1814 border: 1px solid var(--color-border);
1815 border-radius: var(--radius-lg);
1816 padding: var(--space-2);
1817 display: flex;
1818 gap: var(--space-1);
1819 z-index: 10;
1820 }
1821 .reaction-picker-btn {
1822 background: none;
1823 border: none;
1824 font-size: 1.25rem;
1825 cursor: pointer;
1826 padding: var(--space-1);
1827 border-radius: var(--radius-sm);
1828 }
1829 .reaction-picker-btn:hover {
1830 background: var(--color-bg-inset);
1831 }
1832
1833 /* --- Patch subview tabs --- */
1834 .patch-tab-nav {
1835 display: flex;
1836 border-bottom: 1px solid var(--color-border);
1837 margin-bottom: var(--space-6);
1838 }
1839 .tab-count {
1840 display: inline-flex;
1841 align-items: center;
1842 justify-content: center;
1843 min-width: 1.4em;
1844 padding: 0 var(--space-1);
1845 margin-left: var(--space-1);
1846 font-size: var(--text-xs);
1847 font-weight: 500;
1848 background: var(--color-bg-inset);
1849 border-radius: 999px;
1850 color: var(--color-text-muted);
1851 }
1852
1853 /* --- Patch apply status --- */
1854 .apply-status {
1855 margin: var(--space-4) 0;
1856 }
1857 .apply-result {
1858 display: flex;
1859 align-items: flex-start;
1860 gap: var(--space-2);
1861 padding: var(--space-3) var(--space-4);
1862 border-radius: var(--radius-md);
1863 font-size: var(--text-sm);
1864 flex-direction: column;
1865 }
1866 .apply-result > div {
1867 display: flex;
1868 gap: var(--space-2);
1869 align-items: center;
1870 }
1871 .apply-clean {
1872 background: var(--color-success-bg);
1873 color: var(--color-success);
1874 border: 1px solid var(--color-success);
1875 }
1876 .apply-conflict {
1877 background: var(--color-danger-bg);
1878 color: var(--color-danger);
1879 border: 1px solid var(--color-danger);
1880 }
1881 .apply-checking,
1882 .apply-unknown {
1883 color: var(--color-text-muted);
1884 font-style: italic;
1885 font-size: var(--text-sm);
1886 }
1887 .apply-output {
1888 font-family: var(--font-mono);
1889 font-size: var(--text-xs);
1890 white-space: pre-wrap;
1891 margin-top: var(--space-2);
1892 padding: var(--space-2);
1893 background: rgba(0, 0, 0, 0.05);
1894 border-radius: var(--radius-sm);
1895 width: 100%;
1896 }
1897 .patch-actions {
1898 display: flex;
1899 gap: var(--space-3);
1900 margin: var(--space-4) 0;
1901 flex-wrap: wrap;
1902 }
1903 .patch-card-title-row {
1904 display: flex;
1905 align-items: flex-start;
1906 gap: var(--space-3);
1907 justify-content: space-between;
1908 margin-bottom: var(--space-3);
1909 }
1910 .patch-card-title-row .commit-card-subject {
1911 margin-bottom: 0;
1912 }
1913 .patch-card-description {
1914 margin-top: var(--space-4);
1915 padding-top: var(--space-4);
1916 border-top: 1px solid var(--color-border-muted);
1917 }
1918
1919 /* --- Repo home layout --- */
1920 .repo-home-layout {
1921 display: grid;
1922 gap: var(--space-8);
1923 }
1924 @media (min-width: 768px) {
1925 .repo-home-layout {
1926 grid-template-columns: 1fr 1fr;
1927 }
1928 }
1929 .readme-section {
1930 border: 1px solid var(--color-border);
1931 border-radius: var(--radius-lg);
1932 overflow: hidden;
1933 }
1934 .readme-header {
1935 background: var(--color-bg-subtle);
1936 padding: var(--space-3) var(--space-4);
1937 font-size: var(--text-sm);
1938 font-weight: 500;
1939 border-bottom: 1px solid var(--color-border);
1940 }
1941 /* --- Code setup block --- */
1942 .code-setup {
1943 background: var(--color-bg-subtle);
1944 border: 1px solid var(--color-border);
1945 border-radius: var(--radius-lg);
1946 padding: var(--space-4);
1947 font-size: var(--text-sm);
1948 margin-top: var(--space-4);
1949 overflow: auto;
1950 text-align: left;
1951 }
1952 .code-plain {
1953 background: var(--color-bg-subtle);
1954 padding: var(--space-4);
1955 overflow: auto;
1956 font-size: var(--text-sm);
1957 line-height: 1.6;
1958 }
1959
1960 /* --- Markdown body --- */
1961 .markdown-body {
1962 font-size: var(--text-sm);
1963 line-height: 1.6;
1964 color: var(--color-text);
1965 }
1966 .markdown-body h1,
1967 .markdown-body h2,
1968 .markdown-body h3,
1969 .markdown-body h4,
1970 .markdown-body h5,
1971 .markdown-body h6 {
1972 margin-top: var(--space-6);
1973 margin-bottom: var(--space-3);
1974 }
1975 .markdown-body p {
1976 margin-bottom: var(--space-4);
1977 }
1978 .markdown-body a {
1979 color: var(--color-link);
1980 }
1981 .markdown-body code {
1982 background: var(--color-bg-inset);
1983 padding: 0.1em 0.3em;
1984 border-radius: var(--radius-sm);
1985 font-size: 0.9em;
1986 }
1987 .markdown-body pre {
1988 background: var(--color-bg-subtle);
1989 border: 1px solid var(--color-border);
1990 border-radius: var(--radius-md);
1991 padding: var(--space-4);
1992 overflow: auto;
1993 margin-bottom: var(--space-4);
1994 }
1995 .markdown-body pre code {
1996 background: none;
1997 padding: 0;
1998 }
1999 .markdown-body ul,
2000 .markdown-body ol {
2001 padding-left: var(--space-6);
2002 margin-bottom: var(--space-4);
2003 }
2004 .markdown-body ul {
2005 list-style: disc;
2006 }
2007 .markdown-body ol {
2008 list-style: decimal;
2009 }
2010 .markdown-body li {
2011 margin-bottom: var(--space-1);
2012 }
2013 .markdown-body blockquote {
2014 border-left: 3px solid var(--color-border);
2015 padding-left: var(--space-4);
2016 color: var(--color-text-muted);
2017 margin: var(--space-4) 0;
2018 }
2019 .markdown-body table {
2020 width: 100%;
2021 border-collapse: collapse;
2022 margin-bottom: var(--space-4);
2023 }
2024 .markdown-body th,
2025 .markdown-body td {
2026 padding: var(--space-2) var(--space-3);
2027 border: 1px solid var(--color-border);
2028 }
2029 .markdown-body th {
2030 background: var(--color-bg-subtle);
2031 font-weight: 600;
2032 }
2033 .markdown-body hr {
2034 border: none;
2035 border-top: 1px solid var(--color-border);
2036 margin: var(--space-6) 0;
2037 }
2038 .markdown-body img {
2039 max-width: 100%;
2040 border-radius: var(--radius-md);
2041 }
2042 .markdown-body details {
2043 margin-bottom: var(--space-4);
2044 }
2045 .markdown-body summary {
2046 cursor: pointer;
2047 font-weight: 500;
2048 }
2049 .readme-section .markdown-body {
2050 padding: var(--space-4);
2051 }
2052
2053 /* --- Search form --- */
2054 .search-form {
2055 margin-bottom: var(--space-5);
2056 }
2057 .search-input-wrap {
2058 display: flex;
2059 gap: var(--space-2);
2060 max-width: 480px;
2061 }
2062 .search-input {
2063 flex: 1;
2064 padding: var(--space-2) var(--space-3);
2065 border: 1px solid var(--color-border);
2066 border-radius: var(--radius-md);
2067 background: var(--color-bg);
2068 color: var(--color-text);
2069 font-size: var(--text-sm);
2070 }
2071 .search-input:focus {
2072 outline: 2px solid var(--color-accent);
2073 outline-offset: -1px;
2074 border-color: var(--color-accent);
2075 }
2076
2077 /* --- Issue close bar --- */
2078 .issue-close-bar {
2079 display: flex;
2080 justify-content: flex-end;
2081 padding: var(--space-3) 0;
2082 border-top: 1px solid var(--color-border-muted);
2083 margin-top: var(--space-2);
2084 }
2085
2086 /* --- Auth divider --- */
2087 .auth-divider {
2088 display: flex;
2089 align-items: center;
2090 gap: var(--space-3);
2091 margin: var(--space-4) 0;
2092 color: var(--color-text-muted);
2093 font-size: var(--text-sm);
2094 }
2095 .auth-divider::before,
2096 .auth-divider::after {
2097 content: "";
2098 flex: 1;
2099 height: 1px;
2100 background: var(--color-border);
2101 }
2102
2103 /* --- Passkey UI in settings --- */
2104 .passkey-actions {
2105 display: flex;
2106 flex-direction: column;
2107 gap: var(--space-3);
2108 align-items: flex-start;
2109 margin-top: var(--space-3);
2110 }
2111 .passkey-status {
2112 font-size: var(--text-sm);
2113 }
2114
2115 /* --- Danger zone --- */
2116 .danger-zone {
2117 margin-top: var(--space-8);
2118 }
2119 .danger-title {
2120 color: var(--color-danger);
2121 border-bottom-color: var(--color-danger);
2122 }
2123 .danger-card {
2124 border-color: var(--color-danger);
2125 background: var(--color-danger-bg);
2126 }
2127 .danger-item {
2128 display: flex;
2129 align-items: center;
2130 justify-content: space-between;
2131 gap: var(--space-4);
2132 flex-wrap: wrap;
2133 }
2134 .danger-item p {
2135 margin: var(--space-1) 0 0;
2136 }
2137 .btn-danger {
2138 background: var(--color-danger);
2139 border-color: transparent;
2140 color: #fff;
2141 }
2142 .btn-danger:hover {
2143 filter: brightness(0.9);
2144 }
2145
2146 /* --- Release list items --- */
2147 .release-item-header {
2148 display: flex;
2149 gap: var(--space-3);
2150 align-items: flex-start;
2151 }
2152 .release-item-main {
2153 flex: 1;
2154 min-width: 0;
2155 }
2156 .release-item-title {
2157 font-size: var(--text-lg);
2158 font-weight: 700;
2159 text-decoration: none;
2160 color: var(--color-text);
2161 display: block;
2162 margin-bottom: var(--space-1);
2163 }
2164 .release-item-title:hover {
2165 color: var(--color-link);
2166 }
2167 .release-item-meta {
2168 display: flex;
2169 flex-wrap: wrap;
2170 gap: var(--space-3);
2171 align-items: center;
2172 font-size: var(--text-xs);
2173 color: var(--color-text-muted);
2174 }
2175 .release-item-date {
2176 display: flex;
2177 flex-direction: column;
2178 align-items: flex-end;
2179 gap: var(--space-2);
2180 font-size: var(--text-xs);
2181 color: var(--color-text-muted);
2182 white-space: nowrap;
2183 flex-shrink: 0;
2184 }
2185
2186 /* --- Release notes preview in list --- */
2187 .release-notes-section {
2188 margin-top: var(--space-3);
2189 }
2190 .release-notes-label {
2191 font-size: var(--text-xs);
2192 font-weight: 600;
2193 color: var(--color-text-muted);
2194 text-transform: uppercase;
2195 letter-spacing: 0.05em;
2196 margin-bottom: var(--space-2);
2197 }
2198 .notes-expand > summary {
2199 list-style: none;
2200 cursor: pointer;
2201 outline: none;
2202 }
2203 .notes-expand > summary::-webkit-details-marker {
2204 display: none;
2205 }
2206 .notes-preview {
2207 max-height: calc(5 * 1.6em);
2208 overflow: hidden;
2209 position: relative;
2210 white-space: pre-wrap;
2211 font-size: var(--text-sm);
2212 color: var(--color-text);
2213 line-height: 1.6;
2214 word-break: break-word;
2215 margin-bottom: var(--space-1);
2216 }
2217 .notes-preview::after {
2218 content: "";
2219 position: absolute;
2220 bottom: 0;
2221 left: 0;
2222 right: 0;
2223 height: 2.5em;
2224 background: linear-gradient(transparent, var(--color-bg));
2225 pointer-events: none;
2226 }
2227 .notes-expand[open] .notes-preview {
2228 display: none;
2229 }
2230 .notes-full {
2231 padding-top: var(--space-3);
2232 padding-bottom: var(--space-1);
2233 }
2234 .notes-expand[open] {
2235 display: flex;
2236 flex-direction: column;
2237 }
2238 .notes-expand[open] > summary {
2239 order: 1;
2240 }
2241 .notes-expand[open] > .notes-full {
2242 order: 0;
2243 }
2244 .notes-toggle-label {
2245 display: inline-block;
2246 font-size: var(--text-xs);
2247 color: var(--color-link);
2248 margin-top: var(--space-1);
2249 }
2250 .notes-toggle-label:hover {
2251 text-decoration: underline;
2252 }
2253 .notes-toggle-label::before {
2254 content: "Show more ↓";
2255 }
2256 .notes-expand[open] .notes-toggle-label::before {
2257 content: "Show less ↑";
2258 }
2259
2260 /* --- Release detail --- */
2261 .release-detail {
2262 padding: var(--space-6) 0;
2263 }
2264 .release-header {
2265 margin-bottom: var(--space-6);
2266 }
2267 .release-notes {
2268 margin-bottom: var(--space-6);
2269 }
2270 .release-assets {
2271 margin-bottom: var(--space-6);
2272 }
2273 .release-assets-heading {
2274 font-size: var(--text-base);
2275 font-weight: 600;
2276 margin-bottom: var(--space-3);
2277 }
2278 .asset-list {
2279 border: 1px solid var(--color-border);
2280 border-radius: var(--radius-lg);
2281 overflow: hidden;
2282 }
2283 .asset-item {
2284 display: flex;
2285 align-items: center;
2286 gap: var(--space-4);
2287 padding: var(--space-3) var(--space-4);
2288 border-bottom: 1px solid var(--color-border-muted);
2289 font-size: var(--text-sm);
2290 }
2291 .asset-item:last-child {
2292 border-bottom: none;
2293 }
2294 .asset-name {
2295 flex: 1;
2296 color: var(--color-link);
2297 text-decoration: none;
2298 font-family: var(--font-mono);
2299 font-size: var(--text-xs);
2300 }
2301 .asset-name:hover {
2302 text-decoration: underline;
2303 }
2304 .asset-name-pending {
2305 color: var(--color-text-muted);
2306 cursor: default;
2307 }
2308 .asset-item-pending {
2309 opacity: 0.6;
2310 }
2311 .asset-size,
2312 .asset-meta {
2313 color: var(--color-text-muted);
2314 font-size: var(--text-xs);
2315 white-space: nowrap;
2316 }
2317 .release-back {
2318 margin-top: var(--space-4);
2319 display: flex;
2320 gap: var(--space-3);
2321 align-items: center;
2322 justify-content: space-between;
2323 }
2324}
2325
2326/* ============================================================
2327 @layer utilities
2328 ============================================================ */
2329@layer utilities {
2330 .text-muted {
2331 color: var(--color-text-muted);
2332 }
2333 .text-sm {
2334 font-size: var(--text-sm);
2335 }
2336 .text-xs {
2337 font-size: var(--text-xs);
2338 }
2339 .font-mono {
2340 font-family: var(--font-mono);
2341 }
2342 .mt-1 {
2343 margin-top: var(--space-1);
2344 }
2345 .mt-2 {
2346 margin-top: var(--space-2);
2347 }
2348 .mt-4 {
2349 margin-top: var(--space-4);
2350 }
2351 .mt-6 {
2352 margin-top: var(--space-6);
2353 }
2354 .mb-4 {
2355 margin-bottom: var(--space-4);
2356 }
2357 .flex {
2358 display: flex;
2359 }
2360 .gap-2 {
2361 gap: var(--space-2);
2362 }
2363 .gap-4 {
2364 gap: var(--space-4);
2365 }
2366 .items-center {
2367 align-items: center;
2368 }
2369 .justify-between {
2370 justify-content: space-between;
2371 }
2372 .hidden {
2373 display: none;
2374 }
2375}
2376
2377/* ============================================================
2378 Pagination
2379 ============================================================ */
2380.commit-cursor-nav {
2381 display: flex;
2382 justify-content: space-between;
2383 border-top: 1px solid var(--color-border);
2384 margin-top: var(--space-2);
2385 padding: var(--space-4) 0 var(--space-2);
2386}
2387
2388.commit-cursor-prev {
2389 flex: 1;
2390}
2391.commit-cursor-next {
2392 flex: 1;
2393 text-align: right;
2394}
2395
2396.pagination {
2397 display: grid;
2398 grid-template-columns: 1fr auto 1fr;
2399 align-items: center;
2400 border-top: 1px solid var(--color-border);
2401 margin-top: var(--space-2);
2402 padding: var(--space-4) 0 var(--space-2);
2403}
2404
2405.pagination-prev {
2406 justify-self: start;
2407}
2408.pagination-next {
2409 justify-self: end;
2410}
2411
2412.pagination-info {
2413 justify-self: center;
2414 font-size: var(--text-sm);
2415 color: var(--color-text-muted);
2416}
2417
2418.pagination-btn {
2419 display: inline-flex;
2420 align-items: center;
2421 gap: var(--space-1);
2422 padding: var(--space-1) var(--space-3);
2423 border: 1px solid var(--color-border);
2424 border-radius: var(--radius-md);
2425 font-size: var(--text-sm);
2426 font-weight: 500;
2427 text-decoration: none;
2428 color: var(--color-text);
2429 background: var(--color-bg-subtle);
2430 transition:
2431 background 0.1s,
2432 border-color 0.1s;
2433 white-space: nowrap;
2434}
2435
2436.pagination-btn:hover {
2437 background: var(--color-bg-inset);
2438 border-color: var(--color-border);
2439 color: var(--color-text);
2440 text-decoration: none;
2441}
2442
2443/* Settings */
2444.theme-options {
2445 display: flex;
2446 gap: var(--space-4);
2447 margin-bottom: var(--space-4);
2448 flex-wrap: wrap;
2449}
2450.theme-option {
2451 display: flex;
2452 align-items: center;
2453 gap: var(--space-2);
2454 cursor: pointer;
2455 font-size: var(--text-sm);
2456}
2457.settings-form {
2458 display: flex;
2459 flex-direction: column;
2460 gap: var(--space-4);
2461}
2462.passkey-list {
2463 display: flex;
2464 flex-direction: column;
2465 gap: var(--space-2);
2466 margin-bottom: var(--space-4);
2467}
2468.passkey-item {
2469 display: flex;
2470 align-items: center;
2471 gap: var(--space-3);
2472 padding: var(--space-2) 0;
2473 border-bottom: 1px solid var(--color-border-muted);
2474 font-size: var(--text-sm);
2475}
2476.passkey-item:last-child {
2477 border-bottom: none;
2478}
2479.passkey-date {
2480 flex: 1;
2481 color: var(--color-text-muted);
2482}
2483.ssh-key-info {
2484 flex: 1;
2485 display: flex;
2486 flex-direction: column;
2487 gap: var(--space-1);
2488 min-width: 0;
2489}
2490.ssh-key-name {
2491 font-weight: 500;
2492}
2493.ssh-key-fingerprint {
2494 font-family: var(--font-mono);
2495 font-size: var(--text-xs);
2496 overflow: hidden;
2497 text-overflow: ellipsis;
2498 white-space: nowrap;
2499}
2500.form-textarea {
2501 resize: vertical;
2502 min-height: 4.5rem;
2503 font-family: var(--font-mono);
2504 font-size: var(--text-sm);
2505}
2506/* Clone popup */
2507.clone-popup-details {
2508 position: relative;
2509 display: inline-block;
2510}
2511.clone-popup-details > summary {
2512 list-style: none;
2513}
2514.clone-popup-details > summary::-webkit-details-marker {
2515 display: none;
2516}
2517.clone-popup {
2518 position: absolute;
2519 right: 1rem;
2520 top: calc(100% + var(--space-2));
2521 background: var(--color-bg);
2522 border: 1px solid var(--color-border);
2523 border-radius: var(--radius-lg);
2524 padding: var(--space-3);
2525 min-width: 22rem;
2526 z-index: 100;
2527 box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
2528 display: flex;
2529 flex-direction: column;
2530 gap: var(--space-2);
2531}
2532.clone-url-row {
2533 display: flex;
2534 align-items: center;
2535 gap: var(--space-2);
2536}
2537.clone-url-label {
2538 font-size: var(--text-xs);
2539 font-weight: 600;
2540 color: var(--color-text-muted);
2541 text-transform: uppercase;
2542 letter-spacing: 0.05em;
2543 min-width: 2.75rem;
2544}
2545.clone-url-input {
2546 flex: 1;
2547 font-family: var(--font-mono);
2548 font-size: var(--text-sm);
2549 background: var(--color-bg-subtle);
2550 border: 1px solid var(--color-border-muted);
2551 border-radius: var(--radius-md);
2552 padding: var(--space-1) var(--space-2);
2553 color: var(--color-text);
2554 cursor: text;
2555 min-width: 0;
2556}
2557.user-list {
2558 display: flex;
2559 flex-direction: column;
2560 gap: var(--space-2);
2561 margin-bottom: var(--space-6);
2562}
2563.user-item {
2564 display: flex;
2565 align-items: center;
2566 gap: var(--space-3);
2567 padding: var(--space-2) 0;
2568 border-bottom: 1px solid var(--color-border-muted);
2569 font-size: var(--text-sm);
2570}
2571.user-item:last-child {
2572 border-bottom: none;
2573}
2574.user-name {
2575 font-weight: 500;
2576 flex: 1;
2577}
2578.user-date {
2579 color: var(--color-text-muted);
2580 font-size: var(--text-xs);
2581}
2582