code.css
Raw
1@layer components {
2 /* --- File tree --- */
3 .file-tree {
4 width: 100%;
5 border: 1px solid var(--color-border);
6 border-radius: var(--radius-lg);
7 border-collapse: collapse;
8 overflow: hidden;
9 margin-bottom: var(--space-6);
10 }
11 .file-tree-row {
12 border-bottom: 1px solid var(--color-border-muted);
13 }
14 .file-tree-row:last-child {
15 border-bottom: none;
16 }
17 .file-tree-row:hover {
18 background: var(--color-bg-subtle);
19 }
20 .file-icon,
21 .file-name,
22 .file-size {
23 padding: var(--space-2) var(--space-3);
24 font-size: var(--text-sm);
25 vertical-align: middle;
26 }
27 .file-icon {
28 width: 36px;
29 padding-right: var(--space-1);
30 text-align: center;
31 line-height: 0;
32 }
33 .file-name {
34 width: 100%;
35 }
36 .file-name a {
37 color: var(--color-link);
38 text-decoration: none;
39 }
40 .file-name a:hover {
41 text-decoration: underline;
42 }
43 .file-name a.file-name-dir {
44 font-weight: 500;
45 }
46 .file-size {
47 text-align: right;
48 color: var(--color-text-muted);
49 font-size: var(--text-xs);
50 white-space: nowrap;
51 padding-right: var(--space-4);
52 }
53 .file-icon-dir {
54 color: var(--color-link);
55 }
56 .file-icon-file {
57 color: var(--color-text-muted);
58 }
59 .tree-icon {
60 display: inline-block;
61 vertical-align: text-bottom;
62 }
63 .file-tree-row-up .file-name a {
64 color: var(--color-text-muted);
65 }
66 .file-tree-row-up .file-name a:hover {
67 color: var(--color-link);
68 }
69
70 /* --- File blob --- */
71 .file-blob-header {
72 display: flex;
73 align-items: center;
74 justify-content: space-between;
75 flex-wrap: wrap;
76 gap: var(--space-2);
77 padding: var(--space-3) var(--space-4);
78 background: var(--color-bg-subtle);
79 border: 1px solid var(--color-border);
80 border-radius: var(--radius-lg) var(--radius-lg) 0 0;
81 margin-top: var(--space-4);
82 }
83 .file-blob-name {
84 font-size: var(--text-sm);
85 font-weight: 500;
86 min-width: 0;
87 overflow: hidden;
88 text-overflow: ellipsis;
89 white-space: nowrap;
90 }
91 .file-blob-actions {
92 display: flex;
93 align-items: center;
94 gap: var(--space-2);
95 }
96 .file-blob-actions-wrap {
97 flex-wrap: wrap;
98 }
99 .file-blob-body {
100 border: 1px solid var(--color-border);
101 border-top: none;
102 border-radius: 0 0 var(--radius-lg) var(--radius-lg);
103 overflow: auto;
104 }
105 .file-edit-textarea {
106 display: block;
107 width: 100%;
108 box-sizing: border-box;
109 font-family: var(--font-mono);
110 font-size: var(--text-sm);
111 line-height: 1.6;
112 padding: var(--space-4);
113 background: var(--color-bg);
114 color: var(--color-text);
115 border: none;
116 resize: vertical;
117 min-height: 400px;
118 }
119 .file-edit-textarea:focus {
120 outline: 2px solid var(--color-accent);
121 outline-offset: -2px;
122 }
123 /* Blob line-number table */
124 .blob-table {
125 min-width: 100%;
126 border-collapse: collapse;
127 font-family: var(--font-mono);
128 font-size: var(--text-sm);
129 line-height: 1.6;
130 background-color: var(--shiki-light-bg, #fff);
131 color: var(--shiki-light, inherit);
132 }
133 .blob-ln {
134 width: 1%;
135 min-width: 48px;
136 text-align: right;
137 padding: 0 var(--space-3);
138 color: var(--color-text-muted);
139 border-right: 1px solid var(--color-border-muted);
140 user-select: none;
141 white-space: nowrap;
142 vertical-align: top;
143 }
144 .blob-ln a {
145 color: inherit;
146 text-decoration: none;
147 }
148 .blob-ln a:hover {
149 color: var(--color-link);
150 }
151 .blob-code {
152 padding: 0 var(--space-4);
153 white-space: pre;
154 overflow: visible;
155 vertical-align: top;
156 }
157 .blob-table tr:target {
158 background: color-mix(in srgb, #ddf4ff 60%, transparent);
159 }
160 .blob-table tr:target .blob-ln {
161 background: color-mix(in srgb, #ddf4ff 80%, transparent);
162 }
163 .file-download-notice {
164 padding: var(--space-8);
165 text-align: center;
166 color: var(--color-text-muted);
167 }
168 .file-download-notice p {
169 margin-bottom: var(--space-4);
170 }
171 .file-media {
172 padding: var(--space-4);
173 display: flex;
174 justify-content: center;
175 background: var(--color-bg-subtle);
176 }
177 .file-media-img {
178 max-width: 100%;
179 height: auto;
180 display: block;
181 }
182 .file-media-audio {
183 width: 100%;
184 max-width: 600px;
185 }
186 .file-media-video {
187 max-width: 100%;
188 max-height: 80vh;
189 }
190
191 /* --- Commit list --- */
192 .commit-list {
193 display: flex;
194 flex-direction: column;
195 }
196 .commit-item {
197 display: flex;
198 flex-direction: column;
199 padding: var(--space-3) 0;
200 border-bottom: 1px solid var(--color-border-muted);
201 gap: var(--space-2);
202 }
203 .commit-item:last-child {
204 border-bottom: none;
205 }
206 .commit-subject {
207 color: var(--color-text);
208 text-decoration: none;
209 font-size: var(--text-sm);
210 font-weight: 500;
211 }
212 .commit-subject:hover {
213 color: var(--color-link);
214 }
215 .commit-meta {
216 display: flex;
217 align-items: center;
218 justify-content: space-between;
219 gap: var(--space-3);
220 font-size: var(--text-xs);
221 color: var(--color-text-muted);
222 }
223 .commit-meta-right {
224 display: flex;
225 align-items: center;
226 gap: var(--space-3);
227 white-space: nowrap;
228 }
229 .commit-hash {
230 font-family: var(--font-mono);
231 color: var(--color-link);
232 text-decoration: none;
233 background: var(--color-bg-inset);
234 padding: 1px var(--space-2);
235 border-radius: var(--radius-sm);
236 }
237 .commit-hash:hover {
238 text-decoration: underline;
239 }
240 .mono {
241 font-family: var(--font-mono);
242 }
243
244 /* --- Commit detail viewer --- */
245 .commit-page-top {
246 display: flex;
247 align-items: center;
248 justify-content: space-between;
249 margin-bottom: var(--space-4);
250 }
251 .commit-card {
252 border: 1px solid var(--color-border);
253 border-radius: var(--radius-lg);
254 margin-bottom: var(--space-4);
255 overflow: hidden;
256 }
257 .commit-card-subject {
258 font-size: var(--text-xl);
259 font-weight: 600;
260 padding: var(--space-5) var(--space-6);
261 border-bottom: 1px solid var(--color-border);
262 line-height: 1.3;
263 }
264 .commit-card-subject-empty {
265 color: var(--color-text-muted);
266 font-style: italic;
267 font-weight: 400;
268 font-size: var(--text-sm);
269 }
270 .commit-card-body {
271 padding: var(--space-4) var(--space-6);
272 font-family: inherit;
273 font-size: var(--text-sm);
274 color: var(--color-text-muted);
275 border-bottom: 1px solid var(--color-border);
276 overflow-x: auto;
277 }
278 .commit-card-meta {
279 padding: var(--space-4) var(--space-6);
280 display: flex;
281 flex-direction: column;
282 gap: var(--space-2);
283 background: var(--color-bg-subtle);
284 }
285 .commit-card-meta-row {
286 display: flex;
287 align-items: baseline;
288 gap: var(--space-3);
289 font-size: var(--text-sm);
290 flex-wrap: wrap;
291 }
292 .commit-meta-label {
293 font-weight: 600;
294 color: var(--color-text-muted);
295 min-width: 5rem;
296 font-size: var(--text-xs);
297 text-transform: uppercase;
298 letter-spacing: 0.04em;
299 }
300 .commit-sha-full {
301 font-size: var(--text-xs);
302 background: var(--color-bg-inset);
303 padding: 2px var(--space-2);
304 border-radius: var(--radius-sm);
305 word-break: break-all;
306 }
307 .commit-stats-bar {
308 font-size: var(--text-sm);
309 color: var(--color-text-muted);
310 margin-bottom: var(--space-4);
311 }
312
313 /* --- Commit layout (sidebar + diffs) --- */
314 .commit-layout {
315 display: grid;
316 grid-template-columns: 1fr;
317 gap: var(--space-5);
318 align-items: start;
319 }
320 .commit-diffs {
321 min-width: 0;
322 }
323 @media (min-width: 900px) {
324 .commit-layout {
325 grid-template-columns: 220px 1fr;
326 }
327 .commit-layout:has(.file-nav-details:not([open])) {
328 grid-template-columns: auto 1fr;
329 }
330 }
331
332 /* --- File nav sidebar --- */
333 .commit-file-nav {
334 position: sticky;
335 top: calc(56px + var(--space-4));
336 max-height: calc(100vh - 140px);
337 overflow-y: auto;
338 }
339 .file-nav-details {
340 border: 1px solid var(--color-border);
341 border-radius: var(--radius-lg);
342 background: var(--color-bg-subtle);
343 overflow: hidden;
344 }
345 .file-nav-toggle {
346 display: flex;
347 align-items: center;
348 gap: var(--space-2);
349 padding: var(--space-3) var(--space-4);
350 font-size: var(--text-sm);
351 font-weight: 500;
352 cursor: pointer;
353 list-style: none;
354 user-select: none;
355 border-bottom: 1px solid var(--color-border);
356 }
357
358 .file-nav-details:not([open]) .file-nav-toggle {
359 border-bottom: none;
360 }
361 .file-nav-toggle-icon {
362 font-size: 1em;
363 transition: transform 0.15s;
364 }
365 .file-nav-details:not([open]) .file-nav-toggle-icon {
366 transform: rotate(-90deg);
367 }
368 .file-nav-list {
369 padding: var(--space-1) 0;
370 list-style: none;
371 }
372 .file-nav-item {
373 display: flex;
374 align-items: center;
375 gap: var(--space-2);
376 padding: var(--space-1) var(--space-3);
377 font-size: var(--text-xs);
378 text-decoration: none;
379 color: var(--color-text);
380 border-radius: 0;
381 overflow: hidden;
382 }
383 .file-nav-item:hover {
384 background: var(--color-bg-inset);
385 }
386 .file-nav-status {
387 flex-shrink: 0;
388 width: 16px;
389 height: 16px;
390 display: inline-flex;
391 align-items: center;
392 justify-content: center;
393 border-radius: var(--radius-sm);
394 font-size: 9px;
395 font-weight: 700;
396 font-family: var(--font-mono);
397 }
398 .file-status-added {
399 background: var(--color-success-bg);
400 color: var(--color-success);
401 }
402 .file-status-deleted {
403 background: var(--color-danger-bg);
404 color: var(--color-danger);
405 }
406 .file-status-modified {
407 background: var(--color-accent-bg);
408 color: var(--color-accent);
409 }
410 .file-status-renamed {
411 background: var(--color-merged-bg);
412 color: var(--color-merged);
413 }
414 .file-status-copied {
415 background: var(--color-merged-bg);
416 color: var(--color-merged);
417 }
418 .file-nav-name {
419 flex: 1;
420 overflow: hidden;
421 text-overflow: ellipsis;
422 white-space: nowrap;
423 font-family: var(--font-mono);
424 }
425 .file-nav-stat {
426 flex-shrink: 0;
427 display: flex;
428 gap: var(--space-1);
429 font-size: var(--text-xs);
430 font-family: var(--font-mono);
431 }
432 .nav-add {
433 color: var(--color-success);
434 }
435 .nav-del {
436 color: var(--color-danger);
437 }
438 .nav-binary {
439 color: var(--color-text-muted);
440 font-size: var(--text-xs);
441 }
442 .file-nav-dir > details > .file-nav-list {
443 padding-left: var(--space-4);
444 }
445 .file-nav-dir-toggle {
446 display: flex;
447 align-items: center;
448 gap: var(--space-1);
449 padding: var(--space-1) var(--space-3);
450 font-size: var(--text-xs);
451 font-family: var(--font-mono);
452 color: var(--color-text-muted);
453 cursor: pointer;
454 list-style: none;
455 user-select: none;
456 }
457
458 .file-nav-dir > details:not([open]) .file-nav-toggle-icon {
459 transform: rotate(-90deg);
460 }
461
462 /* --- Diff file cards --- */
463 .diff-file {
464 border: 1px solid var(--color-border);
465 border-radius: var(--radius-lg);
466 margin-bottom: var(--space-4);
467 overflow: hidden;
468 }
469 .diff-file-header {
470 display: flex;
471 align-items: center;
472 justify-content: space-between;
473 gap: var(--space-3);
474 padding: var(--space-3) var(--space-4);
475 background: var(--color-bg-subtle);
476 cursor: pointer;
477 list-style: none;
478 user-select: none;
479 flex-wrap: wrap;
480 }
481
482 .diff-file-header-left {
483 display: flex;
484 align-items: center;
485 gap: var(--space-2);
486 min-width: 0;
487 flex: 1;
488 }
489 .diff-file-header-right {
490 display: flex;
491 align-items: center;
492 gap: var(--space-2);
493 flex-shrink: 0;
494 flex-wrap: wrap;
495 }
496 .diff-file-toggle-icon {
497 font-size: 0.7em;
498 flex-shrink: 0;
499 transition: transform 0.15s;
500 }
501 .diff-file:not([open]) .diff-file-toggle-icon {
502 transform: rotate(-90deg);
503 }
504 .diff-status-badge {
505 flex-shrink: 0;
506 width: 18px;
507 height: 18px;
508 display: inline-flex;
509 align-items: center;
510 justify-content: center;
511 border-radius: var(--radius-sm);
512 font-size: 10px;
513 font-weight: 700;
514 font-family: var(--font-mono);
515 }
516 .diff-status-added {
517 background: var(--color-success-bg);
518 color: var(--color-success);
519 }
520 .diff-status-deleted {
521 background: var(--color-danger-bg);
522 color: var(--color-danger);
523 }
524 .diff-status-modified {
525 background: var(--color-accent-bg);
526 color: var(--color-accent);
527 }
528 .diff-status-renamed {
529 background: var(--color-merged-bg);
530 color: var(--color-merged);
531 }
532 .diff-status-copied {
533 background: var(--color-merged-bg);
534 color: var(--color-merged);
535 }
536 .diff-file-path {
537 font-size: var(--text-sm);
538 font-weight: 500;
539 overflow: hidden;
540 text-overflow: ellipsis;
541 white-space: nowrap;
542 }
543 .diff-rename-arrow {
544 font-size: var(--text-xs);
545 color: var(--color-text-muted);
546 white-space: nowrap;
547 overflow: hidden;
548 text-overflow: ellipsis;
549 }
550 .diff-stat-add {
551 color: var(--color-success);
552 font-size: var(--text-sm);
553 font-family: var(--font-mono);
554 font-weight: 600;
555 }
556 .diff-stat-del {
557 color: var(--color-danger);
558 font-size: var(--text-sm);
559 font-family: var(--font-mono);
560 font-weight: 600;
561 }
562 .diff-stat-binary {
563 color: var(--color-text-muted);
564 font-size: var(--text-sm);
565 font-family: var(--font-mono);
566 }
567 .btn-xs {
568 padding: 1px var(--space-2);
569 font-size: var(--text-xs);
570 border: 1px solid var(--color-border);
571 border-radius: var(--radius-sm);
572 background: var(--color-bg);
573 color: var(--color-text);
574 text-decoration: none;
575 cursor: pointer;
576 white-space: nowrap;
577 font-family: var(--font-mono);
578 display: inline-flex;
579 align-items: center;
580 transition: background 0.1s;
581 }
582 .btn-xs:hover {
583 background: var(--color-bg-inset);
584 }
585
586 /* --- Diff file body --- */
587 .diff-binary-notice {
588 padding: var(--space-4) var(--space-6);
589 font-size: var(--text-sm);
590 color: var(--color-text-muted);
591 font-style: italic;
592 }
593 .diff-hunk {
594 border-top: 1px solid var(--color-border-muted);
595 overflow-x: auto;
596 }
597 .diff-hunk:first-child {
598 border-top: none;
599 }
600 .diff-hunk-header {
601 padding: var(--space-1) var(--space-4);
602 font-family: var(--font-mono);
603 font-size: var(--text-xs);
604 font-weight: normal;
605 text-align: left;
606 background: color-mix(
607 in srgb,
608 var(--color-merged-bg) 50%,
609 var(--color-bg)
610 );
611 color: var(--color-merged);
612 border-bottom: 1px solid var(--color-border-muted);
613 white-space: pre;
614 }
615
616 /* --- Diff table --- */
617 .diff-table {
618 min-width: 100%;
619 border-collapse: collapse;
620 font-family: var(--font-mono);
621 font-size: var(--text-xs);
622 line-height: 1.5;
623 }
624 .diff-ln {
625 width: 44px;
626 min-width: 44px;
627 text-align: right;
628 padding: 0 var(--space-2);
629 color: var(--color-text-muted);
630 border-right: 1px solid var(--color-border-muted);
631 user-select: none;
632 vertical-align: top;
633 white-space: nowrap;
634 }
635 .diff-sign {
636 width: 18px;
637 min-width: 18px;
638 text-align: center;
639 padding: 0 var(--space-1);
640 user-select: none;
641 vertical-align: top;
642 }
643 .diff-code {
644 padding: 0 var(--space-3);
645 white-space: pre;
646 overflow: visible;
647 vertical-align: top;
648 word-break: normal;
649 }
650 /* Row type backgrounds */
651 .diff-row-add {
652 background: color-mix(
653 in srgb,
654 var(--color-success-bg) 70%,
655 transparent
656 );
657 }
658 .diff-row-del {
659 background: color-mix(in srgb, var(--color-danger-bg) 70%, transparent);
660 }
661 .diff-row-add .diff-ln,
662 .diff-row-add .diff-sign {
663 background: color-mix(
664 in srgb,
665 var(--color-success-bg) 90%,
666 transparent
667 );
668 }
669 .diff-row-del .diff-ln,
670 .diff-row-del .diff-sign {
671 background: color-mix(in srgb, var(--color-danger-bg) 90%, transparent);
672 }
673 .diff-row-add .diff-sign {
674 color: var(--color-success);
675 font-weight: 700;
676 }
677 .diff-row-del .diff-sign {
678 color: var(--color-danger);
679 font-weight: 700;
680 }
681
682 .diff-ctrl {
683 color: #f0f0f0;
684 background: #c0392b;
685 border-radius: 2px;
686 font-weight: bold;
687 padding: 0 1px;
688 }
689
690 /* Shiki dark-mode support in diff code cells */
691 @media (prefers-color-scheme: dark) {
692 .diff-code span[style] {
693 /* biome-ignore lint/complexity/noImportantStyles: required to override shiki inline styles */
694 color: var(--shiki-dark) !important;
695 }
696 }
697
698 /* Shiki dark-mode support in file blob view */
699 @media (prefers-color-scheme: dark) {
700 .blob-table {
701 background-color: var(--shiki-dark-bg);
702 color: var(--shiki-dark);
703 }
704 .blob-table span[style] {
705 /* biome-ignore lint/complexity/noImportantStyles: required to override shiki inline styles */
706 color: var(--shiki-dark) !important;
707 }
708 .blob-table tr:target {
709 background: color-mix(in srgb, #1c3a52 60%, transparent);
710 }
711 .blob-table tr:target .blob-ln {
712 background: color-mix(in srgb, #1c3a52 80%, transparent);
713 }
714 }
715 :root[data-theme="dark"] .blob-table {
716 background-color: var(--shiki-dark-bg);
717 color: var(--shiki-dark);
718 }
719 :root[data-theme="dark"] .blob-table span[style] {
720 /* biome-ignore lint/complexity/noImportantStyles: required to override shiki inline styles */
721 color: var(--shiki-dark) !important;
722 }
723}
724