+19
app.js
+19
app.js
···
2
2
document.addEventListener("alpine:init", () => {
3
3
Alpine.data("app", () => ({
4
4
// State
5
+
darkTheme: localStorage.getItem("darkTheme") !== "false",
5
6
serverUrl: "https://knot.srv.rbrt.fr",
6
7
isConnected: false,
7
8
status: {
···
34
35
35
36
// Initialization
36
37
init() {
38
+
// Apply saved theme
39
+
this.applyTheme();
40
+
37
41
// Make this component globally accessible for onclick handlers
38
42
window.appInstance = this;
39
43
···
65
69
66
70
// Restore from URL on load
67
71
this.restoreFromURL();
72
+
},
73
+
74
+
// Theme
75
+
toggleTheme() {
76
+
this.darkTheme = !this.darkTheme;
77
+
localStorage.setItem("darkTheme", this.darkTheme);
78
+
this.applyTheme();
79
+
},
80
+
81
+
applyTheme() {
82
+
if (this.darkTheme) {
83
+
document.body.classList.add("dark-theme");
84
+
} else {
85
+
document.body.classList.remove("dark-theme");
86
+
}
68
87
},
69
88
70
89
// Connection
+58
-6
index.html
+58
-6
index.html
···
22
22
<body>
23
23
<div class="container" x-data="app" x-init="init()">
24
24
<header>
25
-
<h1>KnotView</h1>
25
+
<div class="header-top">
26
+
<h1>KnotView</h1>
27
+
<button class="theme-toggle" @click="toggleTheme">
28
+
<span x-show="!darkTheme">🌙</span>
29
+
<span x-show="darkTheme">☀️</span>
30
+
<span x-text="darkTheme ? 'Light' : 'Dark'"></span>
31
+
</button>
32
+
</div>
26
33
<div class="connection-panel">
27
34
<input
28
35
type="text"
···
129
136
<!-- Empty State -->
130
137
<div
131
138
x-show="!loading && !error && !state.currentRepo && view === 'empty'"
132
-
class="empty-state"
139
+
class="welcome-hero"
133
140
>
134
141
<svg
135
142
xmlns="http://www.w3.org/2000/svg"
···
144
151
d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"
145
152
/>
146
153
</svg>
147
-
<h3>No Repository Selected</h3>
148
-
<p>
149
-
Connect to a server and select a repository to
150
-
browse its contents.
154
+
<h2>Welcome to KnotView</h2>
155
+
<p class="subtitle">
156
+
A web-based repository browser for AT Protocol
157
+
repositories. Browse, explore, and download content
158
+
from Knot servers.
151
159
</p>
160
+
161
+
<div class="feature-list">
162
+
<div class="feature-item">
163
+
<h4>🗂️ Browse Repositories</h4>
164
+
<p>
165
+
Navigate through files and folders with an
166
+
intuitive interface
167
+
</p>
168
+
</div>
169
+
<div class="feature-item">
170
+
<h4>🌿 Branch Support</h4>
171
+
<p>
172
+
Switch between different branches seamlessly
173
+
</p>
174
+
</div>
175
+
<div class="feature-item">
176
+
<h4>📄 File Viewer</h4>
177
+
<p>
178
+
View files with syntax highlighting and
179
+
markdown rendering
180
+
</p>
181
+
</div>
182
+
<div class="feature-item">
183
+
<h4>📦 Download Archives</h4>
184
+
<p>Download entire repositories as archives</p>
185
+
</div>
186
+
</div>
187
+
188
+
<div class="getting-started">
189
+
<h3>Getting Started</h3>
190
+
<ol>
191
+
<li>
192
+
Enter your Knot server URL in the input
193
+
above
194
+
</li>
195
+
<li>
196
+
Click "Connect" to connect to the server
197
+
</li>
198
+
<li>Select a repository from the list</li>
199
+
<li>
200
+
Browse files, switch branches, and explore!
201
+
</li>
202
+
</ol>
203
+
</div>
152
204
</div>
153
205
154
206
<!-- Users/Repos List -->
+2
readme.md
+2
readme.md
···
9
9
Once PR [#903](https://tangled.org/tangled.org/core/pulls/903) is merged in tangled/core, the UX of browsing a knot will be better.
10
10
In the meantime, you need to know the did and the repo name of the repository you want to browse.
11
11
12
+
In case of CORS issues, configure the Knot server to allow CORS requests from the domain hosting KnotView. Or simply use a browser extension to disable CORS check on the domain.
13
+
12
14
## License
13
15
14
16
[MIT](license)
+310
-114
styles.css
+310
-114
styles.css
···
4
4
box-sizing: border-box;
5
5
}
6
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
+
48
+
body.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
+
7
89
body {
8
-
font-family:
9
-
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu,
10
-
Cantarell, sans-serif;
11
-
background: #f1f5f9;
12
-
color: #1e293b;
90
+
font-family: InterVariable, system-ui, sans-serif, ui-sans-serif;
91
+
background: var(--bg-primary);
92
+
color: var(--text-primary);
13
93
font-size: 14px;
14
94
line-height: 1.5;
95
+
transition:
96
+
background-color 0.3s ease,
97
+
color 0.3s ease;
15
98
}
16
99
17
100
.container {
···
21
104
}
22
105
23
106
header {
24
-
background: white;
107
+
background: var(--bg-secondary);
25
108
padding: 24px;
26
109
border-radius: 8px;
27
-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
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;
28
119
margin-bottom: 20px;
29
-
border: 1px solid #e2e8f0;
30
120
}
31
121
32
122
h1 {
33
123
font-size: 24px;
34
-
margin-bottom: 20px;
35
-
color: #0f172a;
124
+
margin: 0;
125
+
color: var(--text-heading);
36
126
font-weight: 600;
37
127
}
38
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
+
39
148
.connection-panel {
40
149
display: flex;
41
150
gap: 12px;
···
47
156
flex: 1;
48
157
min-width: 300px;
49
158
padding: 10px 14px;
50
-
border: 1px solid #cbd5e1;
159
+
border: 1px solid var(--border-secondary);
51
160
border-radius: 6px;
52
161
font-size: 14px;
53
-
background: white;
162
+
background: var(--bg-secondary);
163
+
color: var(--text-primary);
54
164
transition: all 0.15s;
55
165
}
56
166
57
167
.connection-panel input:focus {
58
168
outline: none;
59
-
border-color: #3b82f6;
169
+
border-color: var(--accent-primary);
60
170
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
61
171
}
62
172
63
173
button {
64
174
padding: 10px 20px;
65
-
background: #3b82f6;
175
+
background: var(--accent-primary);
66
176
color: white;
67
177
border: none;
68
178
border-radius: 6px;
···
70
180
font-size: 14px;
71
181
font-weight: 500;
72
182
transition: all 0.15s;
73
-
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
183
+
box-shadow: var(--shadow-sm);
74
184
}
75
185
76
186
button:hover {
77
-
background: #2563eb;
187
+
background: var(--accent-hover);
78
188
}
79
189
80
190
button:active {
···
82
192
}
83
193
84
194
button:disabled {
85
-
background: #94a3b8;
195
+
background: var(--text-tertiary);
86
196
cursor: not-allowed;
87
197
transform: none;
88
198
}
89
199
90
200
button.secondary {
91
-
background: white;
92
-
color: #475569;
93
-
border: 1px solid #cbd5e1;
201
+
background: var(--bg-secondary);
202
+
color: var(--text-secondary);
203
+
border: 1px solid var(--border-secondary);
94
204
}
95
205
96
206
button.secondary:hover {
97
-
background: #f8fafc;
207
+
background: var(--bg-hover);
98
208
}
99
209
100
210
.status {
···
106
216
}
107
217
108
218
.status.success {
109
-
background: #dcfce7;
110
-
color: #166534;
111
-
border-color: #bbf7d0;
219
+
background: var(--success-bg);
220
+
color: var(--success-text);
221
+
border-color: var(--success-border);
112
222
}
113
223
114
224
.status.error {
115
-
background: #fee2e2;
116
-
color: #991b1b;
117
-
border-color: #fecaca;
225
+
background: var(--error-bg);
226
+
color: var(--error-text);
227
+
border-color: var(--error-border);
118
228
}
119
229
120
230
.main-content {
···
125
235
126
236
.sidebar {
127
237
width: 300px;
128
-
background: white;
238
+
background: var(--bg-secondary);
129
239
border-radius: 8px;
130
-
border: 1px solid #e2e8f0;
131
-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
240
+
border: 1px solid var(--border-primary);
241
+
box-shadow: var(--shadow-md);
132
242
flex-shrink: 0;
133
243
}
134
244
···
136
246
font-size: 16px;
137
247
font-weight: 600;
138
248
padding: 16px 20px;
139
-
border-bottom: 1px solid #e2e8f0;
140
-
color: #0f172a;
249
+
border-bottom: 1px solid var(--border-primary);
250
+
color: var(--text-heading);
141
251
display: flex;
142
252
align-items: center;
143
253
justify-content: space-between;
···
145
255
146
256
.repo-info {
147
257
padding: 20px;
148
-
background: white;
149
-
border-radius: 8px;
150
-
border: 1px solid #e2e8f0;
151
-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
152
-
margin-bottom: 20px;
153
258
}
154
259
155
260
.repo-info h3 {
156
261
font-size: 14px;
157
262
font-weight: 600;
158
263
margin-bottom: 12px;
159
-
color: #64748b;
264
+
color: var(--text-tertiary);
160
265
}
161
266
162
267
.repo-info .label {
163
268
font-size: 12px;
164
-
color: #64748b;
269
+
color: var(--text-tertiary);
165
270
margin-bottom: 4px;
166
271
font-weight: 500;
167
272
text-transform: uppercase;
···
170
275
171
276
.repo-info .value {
172
277
font-size: 13px;
173
-
color: #1e293b;
278
+
color: var(--text-primary);
174
279
margin-bottom: 12px;
175
-
font-family: monospace;
280
+
font-family: IBMPlexMono, ui-monospace, monospace;
176
281
}
177
282
178
283
.clone-url {
179
284
display: flex;
180
285
align-items: center;
181
286
gap: 8px;
182
-
background: #f8fafc;
287
+
background: var(--bg-tertiary);
183
288
padding: 8px 12px;
184
289
border-radius: 6px;
185
-
border: 1px solid #e2e8f0;
290
+
border: 1px solid var(--border-primary);
186
291
margin-bottom: 12px;
187
292
}
188
293
189
294
.clone-url code {
190
295
flex: 1;
191
296
font-size: 12px;
192
-
color: #475569;
297
+
color: var(--text-secondary);
193
298
overflow: hidden;
194
299
text-overflow: ellipsis;
195
300
}
···
201
306
}
202
307
203
308
.copy-btn:hover {
204
-
background: #2563eb;
309
+
background: var(--accent-hover);
205
310
}
206
311
207
312
.branches-section {
208
-
border-top: 1px solid #e2e8f0;
313
+
border-top: 1px solid var(--border-primary);
209
314
}
210
315
211
316
.branch-list {
···
217
322
padding: 10px 20px;
218
323
cursor: pointer;
219
324
transition: background 0.15s;
220
-
border-bottom: 1px solid #f1f5f9;
325
+
border-bottom: 1px solid var(--border-light);
221
326
font-size: 13px;
222
-
color: #475569;
327
+
color: var(--text-secondary);
223
328
display: flex;
224
329
align-items: center;
225
330
gap: 8px;
226
331
}
227
332
228
333
.branch-item:hover {
229
-
background: #f8fafc;
334
+
background: var(--bg-hover);
230
335
}
231
336
232
337
.branch-item.active {
233
-
background: #eff6ff;
234
-
color: #1e40af;
338
+
background: var(--accent-light);
339
+
color: var(--accent-primary);
235
340
font-weight: 500;
236
341
}
237
342
238
343
.viewer {
239
344
flex: 1;
240
-
background: white;
345
+
background: var(--bg-secondary);
241
346
border-radius: 8px;
242
-
border: 1px solid #e2e8f0;
243
-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
347
+
border: 1px solid var(--border-primary);
348
+
box-shadow: var(--shadow-md);
244
349
overflow: hidden;
245
350
}
246
351
247
352
.breadcrumb {
248
353
padding: 16px 20px;
249
-
border-bottom: 1px solid #e2e8f0;
354
+
border-bottom: 1px solid var(--border-primary);
250
355
font-size: 13px;
251
-
color: #64748b;
252
-
background: #f8fafc;
356
+
color: var(--text-tertiary);
357
+
background: var(--bg-tertiary);
253
358
display: flex;
254
359
align-items: center;
255
360
flex-wrap: wrap;
256
361
}
257
362
258
363
.breadcrumb a {
259
-
color: #3b82f6;
364
+
color: var(--accent-primary);
260
365
text-decoration: none;
261
366
transition: color 0.15s;
262
367
cursor: pointer;
263
368
}
264
369
265
370
.breadcrumb a:hover {
266
-
color: #2563eb;
371
+
color: var(--accent-hover);
267
372
text-decoration: underline;
268
373
}
269
374
···
272
377
}
273
378
274
379
.breadcrumb .current {
275
-
color: #1e293b;
380
+
color: var(--text-primary);
276
381
font-weight: 500;
277
382
}
278
383
···
287
392
display: flex;
288
393
align-items: center;
289
394
gap: 12px;
290
-
border-bottom: 1px solid #f1f5f9;
395
+
border-bottom: 1px solid var(--border-light);
291
396
cursor: pointer !important;
292
397
}
293
398
···
296
401
}
297
402
298
403
.file-item:hover {
299
-
background: #f8fafc;
404
+
background: var(--bg-hover);
300
405
}
301
406
302
407
.file-icon {
303
408
width: 20px;
304
409
height: 20px;
305
410
flex-shrink: 0;
306
-
color: #64748b;
411
+
color: var(--text-tertiary);
307
412
cursor: pointer;
308
413
}
309
414
310
415
.file-name {
311
416
flex: 1;
312
-
color: #1e293b;
417
+
color: var(--text-primary);
313
418
font-size: 14px;
314
419
cursor: pointer;
315
420
}
316
421
317
422
.file-size {
318
-
color: #64748b;
423
+
color: var(--text-tertiary);
319
424
font-size: 12px;
320
425
cursor: pointer;
321
426
}
···
323
428
.file-content {
324
429
padding: 0;
325
430
overflow-x: auto;
326
-
background: #0d1117;
327
-
font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace;
431
+
background: var(--code-block-bg);
432
+
font-family: IBMPlexMono, Monaco, Menlo, monospace;
328
433
font-size: 13px;
329
434
}
330
435
···
347
452
.line-numbers {
348
453
display: flex;
349
454
gap: 0;
350
-
background: #0d1117;
455
+
background: var(--code-block-bg);
351
456
}
352
457
353
458
.line-numbers .numbers {
354
-
color: #6e7681;
459
+
color: var(--code-block-line-numbers);
355
460
text-align: right;
356
461
user-select: none;
357
462
min-width: 50px;
358
463
padding: 20px 16px 20px 20px;
359
-
border-right: 1px solid #30363d;
360
-
background: #0d1117;
464
+
border-right: 1px solid var(--code-block-border);
465
+
background: var(--code-block-bg);
361
466
line-height: 1.5;
362
467
}
363
468
···
369
474
.loading {
370
475
padding: 40px;
371
476
text-align: center;
372
-
color: #64748b;
477
+
color: var(--text-tertiary);
373
478
}
374
479
375
480
.spinner {
376
481
width: 40px;
377
482
height: 40px;
378
483
margin: 0 auto 16px;
379
-
border: 3px solid #e2e8f0;
380
-
border-top-color: #3b82f6;
484
+
border: 3px solid var(--border-primary);
485
+
border-top-color: var(--accent-primary);
381
486
border-radius: 50%;
382
487
animation: spin 0.8s linear infinite;
383
488
}
···
397
502
width: 64px;
398
503
height: 64px;
399
504
margin: 0 auto 20px;
400
-
color: #cbd5e1;
505
+
color: var(--text-tertiary);
401
506
display: block;
402
507
}
403
508
404
509
.empty-state h3 {
405
510
font-size: 18px;
406
-
color: #475569;
511
+
color: var(--text-secondary);
407
512
margin-bottom: 8px;
408
513
}
409
514
410
515
.empty-state p {
411
-
color: #64748b;
516
+
color: var(--text-tertiary);
412
517
font-size: 14px;
413
518
}
414
519
520
+
.welcome-hero {
521
+
padding: 80px 40px;
522
+
text-align: center;
523
+
max-width: 700px;
524
+
margin: 0 auto;
525
+
}
526
+
527
+
.welcome-hero svg {
528
+
width: 96px;
529
+
height: 96px;
530
+
margin: 0 auto 32px;
531
+
color: var(--accent-primary);
532
+
display: block;
533
+
}
534
+
535
+
.welcome-hero h2 {
536
+
font-size: 32px;
537
+
color: var(--text-heading);
538
+
margin-bottom: 16px;
539
+
font-weight: 700;
540
+
}
541
+
542
+
.welcome-hero .subtitle {
543
+
font-size: 18px;
544
+
color: var(--text-secondary);
545
+
margin-bottom: 48px;
546
+
line-height: 1.6;
547
+
}
548
+
549
+
.feature-list {
550
+
display: grid;
551
+
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
552
+
gap: 24px;
553
+
margin-top: 48px;
554
+
text-align: left;
555
+
}
556
+
557
+
.feature-item {
558
+
padding: 20px;
559
+
background: var(--bg-tertiary);
560
+
border-radius: 8px;
561
+
border: 1px solid var(--border-primary);
562
+
}
563
+
564
+
.feature-item h4 {
565
+
font-size: 16px;
566
+
color: var(--text-heading);
567
+
margin-bottom: 8px;
568
+
display: flex;
569
+
align-items: center;
570
+
gap: 8px;
571
+
}
572
+
573
+
.feature-item p {
574
+
font-size: 14px;
575
+
color: var(--text-tertiary);
576
+
line-height: 1.5;
577
+
margin: 0;
578
+
}
579
+
580
+
.getting-started {
581
+
margin-top: 48px;
582
+
padding: 24px;
583
+
background: var(--bg-tertiary);
584
+
border-radius: 8px;
585
+
border: 1px solid var(--border-primary);
586
+
text-align: left;
587
+
}
588
+
589
+
.getting-started h3 {
590
+
font-size: 18px;
591
+
color: var(--text-heading);
592
+
margin-bottom: 16px;
593
+
}
594
+
595
+
.getting-started ol {
596
+
margin-left: 20px;
597
+
color: var(--text-secondary);
598
+
}
599
+
600
+
.getting-started li {
601
+
margin-bottom: 8px;
602
+
line-height: 1.6;
603
+
}
604
+
415
605
.error-message {
416
606
padding: 40px;
417
607
text-align: center;
418
-
color: #991b1b;
419
-
background: #fee2e2;
608
+
color: var(--error-text);
609
+
background: var(--error-bg);
420
610
margin: 20px;
421
611
border-radius: 8px;
422
-
border: 1px solid #fecaca;
612
+
border: 1px solid var(--error-border);
423
613
}
424
614
425
615
.file-header {
426
616
padding: 16px 20px;
427
-
border-bottom: 1px solid #e2e8f0;
428
-
background: #f8fafc;
617
+
border-bottom: 1px solid var(--border-primary);
618
+
background: var(--bg-tertiary);
429
619
display: flex;
430
620
justify-content: space-between;
431
621
align-items: center;
···
433
623
434
624
.file-header h3 {
435
625
font-size: 15px;
436
-
color: #1e293b;
626
+
color: var(--text-primary);
437
627
font-weight: 600;
438
628
}
439
629
···
454
644
.user-header {
455
645
font-size: 16px;
456
646
font-weight: 600;
457
-
color: #0f172a;
647
+
color: var(--text-heading);
458
648
margin-bottom: 12px;
459
649
padding: 12px;
460
-
background: #f8fafc;
650
+
background: var(--bg-tertiary);
461
651
border-radius: 6px;
462
652
}
463
653
464
654
.repo-item {
465
655
padding: 12px;
466
656
margin-bottom: 8px;
467
-
background: white;
468
-
border: 1px solid #e2e8f0;
657
+
background: var(--bg-secondary);
658
+
border: 1px solid var(--border-primary);
469
659
border-radius: 6px;
470
660
cursor: pointer;
471
661
transition: all 0.15s;
472
662
}
473
663
474
664
.repo-item:hover {
475
-
border-color: #3b82f6;
665
+
border-color: var(--accent-primary);
476
666
box-shadow: 0 2px 4px rgba(59, 130, 246, 0.1);
477
667
}
478
668
479
669
.repo-item strong {
480
670
display: block;
481
671
font-size: 14px;
482
-
color: #1e293b;
672
+
color: var(--text-primary);
483
673
margin-bottom: 4px;
484
674
}
485
675
486
676
.repo-item small {
487
677
font-size: 12px;
488
-
color: #64748b;
489
-
font-family: monospace;
678
+
color: var(--text-tertiary);
679
+
font-family: IBMPlexMono, monospace;
490
680
}
491
681
492
682
.markdown-content {
493
683
padding: 20px 40px;
494
-
background: white;
495
-
font-family:
496
-
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu,
497
-
Cantarell, sans-serif;
684
+
background: var(--bg-secondary);
685
+
font-family: InterVariable, system-ui, sans-serif;
498
686
font-size: 15px;
499
687
line-height: 1.6;
500
-
color: #1e293b;
688
+
color: var(--text-primary);
501
689
}
502
690
503
691
.markdown-content h1,
···
510
698
margin-bottom: 16px;
511
699
font-weight: 600;
512
700
line-height: 1.25;
513
-
color: #0f172a;
701
+
color: var(--text-heading);
514
702
}
515
703
516
704
.markdown-content h1 {
517
705
font-size: 2em;
518
706
padding-bottom: 0.3em;
519
-
border-bottom: 1px solid #e2e8f0;
707
+
border-bottom: 1px solid var(--border-primary);
520
708
}
521
709
522
710
.markdown-content h2 {
523
711
font-size: 1.5em;
524
712
padding-bottom: 0.3em;
525
-
border-bottom: 1px solid #e2e8f0;
713
+
border-bottom: 1px solid var(--border-primary);
526
714
}
527
715
528
716
.markdown-content h3 {
···
539
727
540
728
.markdown-content h6 {
541
729
font-size: 0.85em;
542
-
color: #64748b;
730
+
color: var(--text-tertiary);
543
731
}
544
732
545
733
.markdown-content p {
···
562
750
padding: 0.2em 0.4em;
563
751
margin: 0;
564
752
font-size: 85%;
565
-
background: #f1f5f9;
753
+
background: var(--code-bg);
566
754
border-radius: 6px;
567
-
font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace;
568
-
color: #e11d48;
755
+
font-family: IBMPlexMono, Monaco, Menlo, monospace;
756
+
color: var(--code-text);
569
757
}
570
758
571
759
.markdown-content pre {
···
573
761
overflow: auto;
574
762
font-size: 85%;
575
763
line-height: 1.45;
576
-
background: #0d1117;
764
+
background: var(--code-block-bg);
577
765
border-radius: 6px;
578
766
margin-bottom: 16px;
579
767
}
···
587
775
word-wrap: normal;
588
776
background: transparent;
589
777
border: 0;
590
-
color: #c9d1d9;
778
+
color: var(--code-block-text);
591
779
}
592
780
593
781
.markdown-content pre code.hljs {
···
596
784
597
785
.markdown-content blockquote {
598
786
padding: 0 1em;
599
-
color: #64748b;
600
-
border-left: 0.25em solid #cbd5e1;
787
+
color: var(--text-tertiary);
788
+
border-left: 0.25em solid var(--border-secondary);
601
789
margin: 0 0 16px 0;
602
790
}
603
791
···
620
808
.markdown-content table th,
621
809
.markdown-content table td {
622
810
padding: 6px 13px;
623
-
border: 1px solid #e2e8f0;
811
+
border: 1px solid var(--border-primary);
624
812
}
625
813
626
814
.markdown-content table th {
627
815
font-weight: 600;
628
-
background: #f8fafc;
816
+
background: var(--bg-tertiary);
629
817
}
630
818
631
819
.markdown-content table tr {
632
-
background: white;
633
-
border-top: 1px solid #e2e8f0;
820
+
background: var(--bg-secondary);
821
+
border-top: 1px solid var(--border-primary);
634
822
}
635
823
636
824
.markdown-content table tr:nth-child(2n) {
637
-
background: #f8fafc;
825
+
background: var(--bg-tertiary);
638
826
}
639
827
640
828
.markdown-content img {
···
644
832
}
645
833
646
834
.markdown-content a {
647
-
color: #3b82f6;
835
+
color: var(--accent-primary);
648
836
text-decoration: none;
649
837
}
650
838
···
656
844
height: 0.25em;
657
845
padding: 0;
658
846
margin: 24px 0;
659
-
background-color: #e2e8f0;
847
+
background-color: var(--border-primary);
660
848
border: 0;
661
849
}
662
850
···
665
853
flex-direction: column;
666
854
}
667
855
856
+
.sidebar {
857
+
width: 100%;
858
+
}
859
+
668
860
.connection-panel {
669
861
flex-direction: column;
670
862
}
···
675
867
676
868
.markdown-content {
677
869
padding: 20px;
870
+
}
871
+
872
+
.welcome-hero {
873
+
padding: 40px 20px;
678
874
}
679
875
}