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