Knot server viewer.
knotview.srv.rbrt.fr
tangled
knot
1* {
2 margin: 0;
3 padding: 0;
4 box-sizing: border-box;
5}
6
7:root {
8 /* Light theme colors */
9 --bg-primary: #f9fafb;
10 --bg-secondary: #ffffff;
11 --bg-tertiary: #f3f4f6;
12 --bg-hover: #f3f4f6;
13 --bg-active: #dbeafe;
14
15 --text-primary: #111827;
16 --text-secondary: #4b5563;
17 --text-tertiary: #6b7280;
18 --text-heading: #111827;
19
20 --border-primary: #e5e7eb;
21 --border-secondary: #d1d5db;
22 --border-light: #f3f4f6;
23
24 --accent-primary: #3b82f6;
25 --accent-hover: #2563eb;
26 --accent-light: #dbeafe;
27
28 --success-bg: #dcfce7;
29 --success-text: #166534;
30 --success-border: #bbf7d0;
31
32 --error-bg: #fee2e2;
33 --error-text: #991b1b;
34 --error-border: #fecaca;
35
36 --code-bg: #f3f4f6;
37 --code-text: #111827;
38 --code-block-bg: #1f2937;
39 --code-block-text: #e5e7eb;
40 --code-block-border: #374151;
41 --code-block-line-numbers: #9ca3af;
42
43 --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
44 --shadow-md:
45 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
46}
47
48body.dark-theme {
49 /* Dark theme colors */
50 --bg-primary: #111827;
51 --bg-secondary: #1f2937;
52 --bg-tertiary: #374151;
53 --bg-hover: #374151;
54 --bg-active: #1e3a8a;
55
56 --text-primary: #f3f4f6;
57 --text-secondary: #d1d5db;
58 --text-tertiary: #9ca3af;
59 --text-heading: #ffffff;
60
61 --border-primary: #374151;
62 --border-secondary: #4b5563;
63 --border-light: #374151;
64
65 --accent-primary: #3b82f6;
66 --accent-hover: #60a5fa;
67 --accent-light: #1e3a8a;
68
69 --success-bg: #14532d;
70 --success-text: #86efac;
71 --success-border: #166534;
72
73 --error-bg: #7f1d1d;
74 --error-text: #fecaca;
75 --error-border: #991b1b;
76
77 --code-bg: #374151;
78 --code-text: #d1d5db;
79 --code-block-bg: #1f2937;
80 --code-block-text: #e5e7eb;
81 --code-block-border: #4b5563;
82 --code-block-line-numbers: #9ca3af;
83
84 --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.3);
85 --shadow-md:
86 0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.4);
87}
88
89body {
90 font-family: InterVariable, system-ui, sans-serif, ui-sans-serif;
91 background: var(--bg-primary);
92 color: var(--text-primary);
93 font-size: 14px;
94 line-height: 1.5;
95 transition:
96 background-color 0.3s ease,
97 color 0.3s ease;
98}
99
100.container {
101 max-width: 1400px;
102 margin: 0 auto;
103 padding: 20px;
104}
105
106header {
107 background: var(--bg-secondary);
108 padding: 24px;
109 border-radius: 8px;
110 box-shadow: var(--shadow-md);
111 margin-bottom: 20px;
112 border: 1px solid var(--border-primary);
113}
114
115.header-top {
116 display: flex;
117 justify-content: space-between;
118 align-items: center;
119 margin-bottom: 20px;
120}
121
122h1 {
123 font-size: 24px;
124 margin: 0;
125 color: var(--text-heading);
126 font-weight: 600;
127}
128
129.theme-toggle {
130 background: var(--bg-tertiary);
131 border: 1px solid var(--border-primary);
132 color: var(--text-primary);
133 padding: 8px 16px;
134 border-radius: 6px;
135 cursor: pointer;
136 font-size: 14px;
137 display: flex;
138 align-items: center;
139 gap: 8px;
140 transition: all 0.15s;
141}
142
143.theme-toggle:hover {
144 background: var(--bg-hover);
145 border-color: var(--border-secondary);
146}
147
148.connection-panel {
149 display: flex;
150 gap: 12px;
151 margin-bottom: 12px;
152 flex-wrap: wrap;
153}
154
155.connection-panel input {
156 flex: 1;
157 min-width: 300px;
158 padding: 10px 14px;
159 border: 1px solid var(--border-secondary);
160 border-radius: 6px;
161 font-size: 14px;
162 background: var(--bg-secondary);
163 color: var(--text-primary);
164 transition: all 0.15s;
165}
166
167.connection-panel input:focus {
168 outline: none;
169 border-color: var(--accent-primary);
170 box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
171}
172
173button {
174 padding: 10px 20px;
175 background: var(--accent-primary);
176 color: white;
177 border: none;
178 border-radius: 6px;
179 cursor: pointer;
180 font-size: 14px;
181 font-weight: 500;
182 transition: all 0.15s;
183 box-shadow: var(--shadow-sm);
184}
185
186button:hover {
187 background: var(--accent-hover);
188}
189
190button:active {
191 transform: translateY(1px);
192}
193
194button:disabled {
195 background: var(--text-tertiary);
196 cursor: not-allowed;
197 transform: none;
198}
199
200button.secondary {
201 background: var(--bg-secondary);
202 color: var(--text-secondary);
203 border: 1px solid var(--border-secondary);
204}
205
206button.secondary:hover {
207 background: var(--bg-hover);
208}
209
210.status {
211 padding: 12px 16px;
212 border-radius: 6px;
213 font-size: 13px;
214 border: 1px solid transparent;
215 margin-top: 12px;
216 font-weight: 500;
217 line-height: 1.5;
218}
219
220.status:empty {
221 display: none;
222}
223
224.status.success {
225 background: var(--success-bg);
226 color: var(--success-text);
227 border-color: var(--success-border);
228}
229
230.status.error {
231 background: var(--error-bg);
232 color: var(--error-text);
233 border-color: var(--error-border);
234 font-weight: 600;
235}
236
237.status.error::before {
238 content: "⚠️ ";
239 margin-right: 4px;
240}
241
242.status.success::before {
243 content: "✓ ";
244 margin-right: 4px;
245}
246
247.main-content {
248 display: flex;
249 gap: 20px;
250 align-items: flex-start;
251}
252
253.sidebar {
254 width: 300px;
255 background: var(--bg-secondary);
256 border-radius: 8px;
257 border: 1px solid var(--border-primary);
258 box-shadow: var(--shadow-md);
259 flex-shrink: 0;
260}
261
262.sidebar h2 {
263 font-size: 16px;
264 font-weight: 600;
265 padding: 16px 20px;
266 border-bottom: 1px solid var(--border-primary);
267 color: var(--text-heading);
268 display: flex;
269 align-items: center;
270 justify-content: space-between;
271}
272
273.repo-info {
274 padding: 20px;
275}
276
277.repo-info h3 {
278 font-size: 14px;
279 font-weight: 600;
280 margin-bottom: 12px;
281 color: var(--text-tertiary);
282}
283
284.repo-info .label {
285 font-size: 12px;
286 color: var(--text-tertiary);
287 margin-bottom: 4px;
288 font-weight: 500;
289 text-transform: uppercase;
290 letter-spacing: 0.5px;
291}
292
293.repo-info .value {
294 font-size: 13px;
295 color: var(--text-primary);
296 margin-bottom: 12px;
297 font-family: IBMPlexMono, ui-monospace, monospace;
298}
299
300.clone-url {
301 display: flex;
302 align-items: center;
303 gap: 8px;
304 background: var(--bg-tertiary);
305 padding: 8px 12px;
306 border-radius: 6px;
307 border: 1px solid var(--border-primary);
308 margin-bottom: 12px;
309}
310
311.clone-url code {
312 flex: 1;
313 font-size: 12px;
314 color: var(--text-secondary);
315 overflow: hidden;
316 text-overflow: ellipsis;
317}
318
319.copy-btn {
320 padding: 4px 8px;
321 font-size: 11px;
322 min-width: 50px;
323}
324
325.copy-btn:hover {
326 background: var(--accent-hover);
327}
328
329.branches-section {
330 border-top: 1px solid var(--border-primary);
331}
332
333.branch-list {
334 max-height: 300px;
335 overflow-y: auto;
336}
337
338.branch-item {
339 padding: 10px 20px;
340 cursor: pointer;
341 transition: background 0.15s;
342 border-bottom: 1px solid var(--border-light);
343 font-size: 13px;
344 color: var(--text-secondary);
345 display: flex;
346 align-items: center;
347 gap: 8px;
348}
349
350.branch-item:hover {
351 background: var(--bg-hover);
352}
353
354.branch-item.active {
355 background: var(--accent-light);
356 color: var(--accent-primary);
357 font-weight: 500;
358}
359
360.viewer {
361 flex: 1;
362 background: var(--bg-secondary);
363 border-radius: 8px;
364 border: 1px solid var(--border-primary);
365 box-shadow: var(--shadow-md);
366 overflow: hidden;
367}
368
369.breadcrumb {
370 padding: 16px 20px;
371 border-bottom: 1px solid var(--border-primary);
372 font-size: 13px;
373 color: var(--text-tertiary);
374 background: var(--bg-tertiary);
375 display: flex;
376 align-items: center;
377 flex-wrap: wrap;
378}
379
380.breadcrumb a {
381 color: var(--accent-primary);
382 text-decoration: none;
383 transition: color 0.15s;
384 cursor: pointer;
385}
386
387.breadcrumb a:hover {
388 color: var(--accent-hover);
389 text-decoration: underline;
390}
391
392.breadcrumb span {
393 margin: 0 8px;
394}
395
396.breadcrumb .current {
397 color: var(--text-primary);
398 font-weight: 500;
399}
400
401.file-list {
402 padding: 0;
403 list-style: none;
404 margin: 0;
405}
406
407.file-item {
408 padding: 12px 20px;
409 display: flex;
410 align-items: center;
411 gap: 12px;
412 border-bottom: 1px solid var(--border-light);
413 cursor: pointer !important;
414}
415
416.file-item:last-child {
417 border-bottom: none;
418}
419
420.file-item:hover {
421 background: var(--bg-hover);
422}
423
424.file-icon {
425 width: 20px;
426 height: 20px;
427 flex-shrink: 0;
428 color: var(--text-tertiary);
429 cursor: pointer;
430}
431
432.file-name {
433 flex: 1;
434 color: var(--text-primary);
435 font-size: 14px;
436 cursor: pointer;
437}
438
439.file-size {
440 color: var(--text-tertiary);
441 font-size: 12px;
442 cursor: pointer;
443}
444
445.file-content {
446 padding: 0;
447 overflow-x: auto;
448 background: var(--code-block-bg);
449 font-family: IBMPlexMono, Monaco, Menlo, monospace;
450 font-size: 13px;
451}
452
453.file-content pre {
454 margin: 0;
455 white-space: pre;
456 background: transparent;
457 padding: 20px;
458}
459
460.file-content code {
461 background: transparent;
462}
463
464.file-content code.hljs {
465 padding: 0;
466 background: transparent;
467}
468
469.line-numbers {
470 display: flex;
471 gap: 0;
472 background: var(--code-block-bg);
473}
474
475.line-numbers .numbers {
476 color: var(--code-block-line-numbers);
477 text-align: right;
478 user-select: none;
479 min-width: 50px;
480 padding: 20px 16px 20px 20px;
481 border-right: 1px solid var(--code-block-border);
482 background: var(--code-block-bg);
483 line-height: 1.5;
484}
485
486.line-numbers pre:not(.numbers) {
487 flex: 1;
488 padding-left: 20px;
489}
490
491.loading {
492 padding: 40px;
493 text-align: center;
494 color: var(--text-tertiary);
495}
496
497.spinner {
498 width: 40px;
499 height: 40px;
500 margin: 0 auto 16px;
501 border: 3px solid var(--border-primary);
502 border-top-color: var(--accent-primary);
503 border-radius: 50%;
504 animation: spin 0.8s linear infinite;
505}
506
507@keyframes spin {
508 to {
509 transform: rotate(360deg);
510 }
511}
512
513.empty-state {
514 padding: 60px 40px;
515 text-align: center;
516}
517
518.empty-state svg {
519 width: 64px;
520 height: 64px;
521 margin: 0 auto 20px;
522 color: var(--text-tertiary);
523 display: block;
524}
525
526.empty-state h3 {
527 font-size: 18px;
528 color: var(--text-secondary);
529 margin-bottom: 8px;
530}
531
532.empty-state p {
533 color: var(--text-tertiary);
534 font-size: 14px;
535}
536
537.welcome-hero {
538 padding: 80px 40px;
539 text-align: center;
540 max-width: 700px;
541 margin: 0 auto;
542}
543
544.welcome-hero svg {
545 width: 96px;
546 height: 96px;
547 margin: 0 auto 32px;
548 color: var(--accent-primary);
549 display: block;
550}
551
552.welcome-hero h2 {
553 font-size: 32px;
554 color: var(--text-heading);
555 margin-bottom: 16px;
556 font-weight: 700;
557}
558
559.welcome-hero .subtitle {
560 font-size: 18px;
561 color: var(--text-secondary);
562 margin-bottom: 48px;
563 line-height: 1.6;
564}
565
566.feature-list {
567 display: grid;
568 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
569 gap: 24px;
570 margin-top: 48px;
571 text-align: left;
572}
573
574.feature-item {
575 padding: 20px;
576 background: var(--bg-tertiary);
577 border-radius: 8px;
578 border: 1px solid var(--border-primary);
579}
580
581.feature-item h4 {
582 font-size: 16px;
583 color: var(--text-heading);
584 margin-bottom: 8px;
585 display: flex;
586 align-items: center;
587 gap: 8px;
588}
589
590.feature-item p {
591 font-size: 14px;
592 color: var(--text-tertiary);
593 line-height: 1.5;
594 margin: 0;
595}
596
597.getting-started {
598 margin-top: 48px;
599 padding: 24px;
600 background: var(--bg-tertiary);
601 border-radius: 8px;
602 border: 1px solid var(--border-primary);
603 text-align: left;
604}
605
606.getting-started h3 {
607 font-size: 18px;
608 color: var(--text-heading);
609 margin-bottom: 16px;
610}
611
612.getting-started ol {
613 margin-left: 20px;
614 color: var(--text-secondary);
615}
616
617.getting-started li {
618 margin-bottom: 8px;
619 line-height: 1.6;
620}
621
622.error-message {
623 padding: 40px;
624 text-align: center;
625 color: var(--error-text);
626 background: var(--error-bg);
627 margin: 20px;
628 border-radius: 8px;
629 border: 1px solid var(--error-border);
630}
631
632.file-header {
633 padding: 16px 20px;
634 border-bottom: 1px solid var(--border-primary);
635 background: var(--bg-tertiary);
636 display: flex;
637 justify-content: space-between;
638 align-items: center;
639}
640
641.file-header h3 {
642 font-size: 15px;
643 color: var(--text-primary);
644 font-weight: 600;
645}
646
647.file-actions {
648 display: flex;
649 gap: 8px;
650}
651
652.file-actions button {
653 padding: 6px 12px;
654 font-size: 12px;
655}
656
657.markdown-content {
658 padding: 20px 40px;
659 background: var(--bg-secondary);
660 font-family: InterVariable, system-ui, sans-serif;
661 font-size: 15px;
662 line-height: 1.6;
663 color: var(--text-primary);
664}
665
666.markdown-content h1,
667.markdown-content h2,
668.markdown-content h3,
669.markdown-content h4,
670.markdown-content h5,
671.markdown-content h6 {
672 margin-top: 24px;
673 margin-bottom: 16px;
674 font-weight: 600;
675 line-height: 1.25;
676 color: var(--text-heading);
677}
678
679.markdown-content h1 {
680 font-size: 2em;
681 padding-bottom: 0.3em;
682 border-bottom: 1px solid var(--border-primary);
683}
684
685.markdown-content h2 {
686 font-size: 1.5em;
687 padding-bottom: 0.3em;
688 border-bottom: 1px solid var(--border-primary);
689}
690
691.markdown-content h3 {
692 font-size: 1.25em;
693}
694
695.markdown-content h4 {
696 font-size: 1em;
697}
698
699.markdown-content h5 {
700 font-size: 0.875em;
701}
702
703.markdown-content h6 {
704 font-size: 0.85em;
705 color: var(--text-tertiary);
706}
707
708.markdown-content p {
709 margin-top: 0;
710 margin-bottom: 16px;
711}
712
713.markdown-content ul,
714.markdown-content ol {
715 margin-top: 0;
716 margin-bottom: 16px;
717 padding-left: 2em;
718}
719
720.markdown-content li + li {
721 margin-top: 0.25em;
722}
723
724.markdown-content code {
725 padding: 0.2em 0.4em;
726 margin: 0;
727 font-size: 85%;
728 background: var(--code-bg);
729 border-radius: 6px;
730 font-family: IBMPlexMono, Monaco, Menlo, monospace;
731 color: var(--code-text);
732}
733
734.markdown-content pre {
735 padding: 16px;
736 overflow: auto;
737 font-size: 85%;
738 line-height: 1.45;
739 background: var(--code-block-bg);
740 border-radius: 6px;
741 margin-bottom: 16px;
742}
743
744.markdown-content pre code {
745 display: block;
746 padding: 0;
747 margin: 0;
748 overflow: visible;
749 line-height: inherit;
750 word-wrap: normal;
751 background: transparent;
752 border: 0;
753 color: var(--code-block-text);
754}
755
756.markdown-content pre code.hljs {
757 background: transparent;
758}
759
760.markdown-content blockquote {
761 padding: 0 1em;
762 color: var(--text-tertiary);
763 border-left: 0.25em solid var(--border-secondary);
764 margin: 0 0 16px 0;
765}
766
767.markdown-content blockquote > :first-child {
768 margin-top: 0;
769}
770
771.markdown-content blockquote > :last-child {
772 margin-bottom: 0;
773}
774
775.markdown-content table {
776 border-spacing: 0;
777 border-collapse: collapse;
778 margin-bottom: 16px;
779 width: 100%;
780 overflow: auto;
781}
782
783.markdown-content table th,
784.markdown-content table td {
785 padding: 6px 13px;
786 border: 1px solid var(--border-primary);
787}
788
789.markdown-content table th {
790 font-weight: 600;
791 background: var(--bg-tertiary);
792}
793
794.markdown-content table tr {
795 background: var(--bg-secondary);
796 border-top: 1px solid var(--border-primary);
797}
798
799.markdown-content table tr:nth-child(2n) {
800 background: var(--bg-tertiary);
801}
802
803.markdown-content img {
804 max-width: 100%;
805 box-sizing: border-box;
806 border-radius: 6px;
807}
808
809.markdown-content a {
810 color: var(--accent-primary);
811 text-decoration: none;
812}
813
814.markdown-content a:hover {
815 text-decoration: underline;
816}
817
818.markdown-content hr {
819 height: 0.25em;
820 padding: 0;
821 margin: 24px 0;
822 background-color: var(--border-primary);
823 border: 0;
824}
825
826footer {
827 padding: 20px;
828 text-align: center;
829 border-top: 1px solid var(--border-primary);
830 margin-top: 40px;
831}
832
833footer p {
834 margin: 0;
835 color: var(--text-secondary);
836 font-size: 0.9rem;
837}
838
839footer a {
840 color: var(--accent-primary);
841 text-decoration: none;
842 font-weight: 500;
843}
844
845footer a:hover {
846 text-decoration: underline;
847 color: var(--accent-hover);
848}
849
850.repo-list-view {
851 padding: 0;
852}
853
854.repo-list-header {
855 padding: 20px 24px;
856 border-bottom: 1px solid var(--border-primary);
857 display: flex;
858 align-items: baseline;
859 gap: 12px;
860}
861
862.repo-list-header h2 {
863 font-size: 18px;
864 font-weight: 600;
865 color: var(--text-heading);
866}
867
868.repo-count {
869 font-size: 13px;
870 color: var(--text-tertiary);
871}
872
873.repo-cards {
874 padding: 12px;
875 display: grid;
876 grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
877 gap: 12px;
878}
879
880.repo-card {
881 padding: 16px 20px;
882 background: var(--bg-secondary);
883 border: 1px solid var(--border-primary);
884 border-radius: 8px;
885 cursor: pointer;
886 transition: all 0.15s;
887}
888
889.repo-card:hover {
890 border-color: var(--accent-primary);
891 box-shadow: 0 2px 8px rgba(59, 130, 246, 0.12);
892}
893
894.repo-card-header {
895 display: flex;
896 align-items: center;
897 justify-content: space-between;
898 gap: 12px;
899 margin-bottom: 8px;
900}
901
902.repo-card-header h3 {
903 font-size: 15px;
904 font-weight: 600;
905 color: var(--accent-primary);
906 margin: 0;
907}
908
909.repo-knot {
910 font-size: 11px;
911 color: var(--text-tertiary);
912 background: var(--bg-tertiary);
913 padding: 2px 8px;
914 border-radius: 4px;
915 white-space: nowrap;
916 font-family: IBMPlexMono, monospace;
917}
918
919.repo-card-desc {
920 font-size: 13px;
921 color: var(--text-secondary);
922 margin: 0 0 10px 0;
923 line-height: 1.5;
924 display: -webkit-box;
925 -webkit-line-clamp: 2;
926 -webkit-box-orient: vertical;
927 overflow: hidden;
928}
929
930.repo-card-meta {
931 display: flex;
932 align-items: center;
933 gap: 8px;
934 flex-wrap: wrap;
935}
936
937.repo-topics {
938 display: flex;
939 gap: 6px;
940 flex-wrap: wrap;
941}
942
943.topic-tag {
944 font-size: 11px;
945 padding: 2px 8px;
946 border-radius: 12px;
947 background: var(--accent-light);
948 color: var(--accent-primary);
949 font-weight: 500;
950}
951
952@media (max-width: 768px) {
953 .main-content {
954 flex-direction: column;
955 }
956
957 .sidebar {
958 width: 100%;
959 }
960
961 .connection-panel {
962 flex-direction: column;
963 }
964
965 .connection-panel input {
966 min-width: 100%;
967 }
968
969 .markdown-content {
970 padding: 20px;
971 }
972
973 .welcome-hero {
974 padding: 40px 20px;
975 }
976
977 .repo-cards {
978 grid-template-columns: 1fr;
979 }
980}