Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol
diffdown.com
1@import url(https://fonts.bunny.net/css?family=barlow:100,200,300,400,500,600|lexend:100,200,300,400,500,600,700,800,900|albert-sans:100,200,300,400,450,500,600,700,800,900);
2
3*, *::before, *::after {
4 box-sizing: border-box;
5 margin: 0;
6 padding: 0;
7}
8
9:root {
10 --bg: #fafafa;
11 --bg-card: #fff;
12 --text: #090909;
13 --text-muted: #6b7280;
14 --border: #e5e7eb;
15 --primary: #2563eb;
16 --primary-hover: #1549d6;
17 --danger: #dc2626;
18 --success: #16a34a;
19 --code-bg: #f3f4f6;
20 --alert-error-bg: #fef2f2;
21 --alert-error-border: #fecaca;
22 --heading-font: "Lexend", -apple-system, Roboto, BlinkMacSystemFont, "Segoe UI", sans-serif;
23 --radius: 6px;
24 --font: "Albert Sans", -apple-system, Roboto, BlinkMacSystemFont, "Segoe UI", sans-serif;
25 --font-mono: "JetBrains Mono", "Fira Code", "Cascadia Code", monospace;
26}
27
28[data-theme="dark"] {
29 --bg: #0d1117;
30 --bg-card: #161b22;
31 --text: #e6edf3;
32 --text-muted: #ededed;
33 --text-secondary: #d4d4d4;
34 --border: #30363d;
35 --code-bg: #1f2428;
36 --primary: #388bfd;
37 --primary-hover: #62a3ee;
38 --danger: #f85149;
39 --success: #3fb950;
40 --alert-error-bg: #1c0608;
41 --alert-error-border: #6e1c20;
42}
43
44@media (prefers-color-scheme: dark) {
45 :root:not([data-theme="light"]) {
46 --bg: #0d1117;
47 --bg-card: #161b22;
48 --text: #e6edf3;
49 --text-muted: #ededed;
50 --text-secondary: #d4d4d4;
51 --border: #30363d;
52 --code-bg: #1f2428;
53 --primary: #388bfd;
54 --primary-hover: #62a3ee;
55 --danger: #f85149;
56 --success: #3fb950;
57 --alert-error-bg: #1c0608;
58 --alert-error-border: #6e1c20;
59 }
60}
61
62body {
63 font-family: var(--font);
64 background: var(--bg);
65 color: var(--text);
66 line-height: 1.5;
67}
68
69strong {
70 font-weight: 500;
71}
72
73a { color: var(--primary); text-decoration: none; }
74a:hover { text-decoration: underline; }
75
76h1, h2, h3, h4, h5 {
77 font-family: var(--heading-font);
78 font-weight: 450;
79 margin-top: 1.5rem;
80 margin-bottom: 0.5rem;
81}
82
83ul {
84 list-style: disc;
85 margin-left: 1.5rem;
86}
87
88li {
89 margin-bottom: 0.25rem;
90 margin-left: 1rem;
91}
92
93p {
94 margin-bottom: 1rem;
95 line-height: 1.4;
96}
97
98/* Navbar */
99.navbar {
100 display: flex;
101 align-items: center;
102 justify-content: space-between;
103 padding: 0.75rem 1.5rem;
104 border-bottom: 1px solid var(--border);
105 background: var(--bg-card);
106}
107
108.logo {
109 font-weight: 500;
110 font-size: 1.1rem;
111 color: var(--text);
112}
113
114.nav-right {
115 display: flex;
116 align-items: center;
117 gap: 1rem;
118}
119
120.nav-user { color: var(--text-muted); }
121
122/* Buttons */
123.btn {
124 display: inline-block;
125 padding: 0.5rem 1rem;
126 background: var(--primary);
127 color: #fff;
128 border: 1px solid var(--primary);
129 border-radius: var(--radius);
130 cursor: pointer;
131 font-size: 0.875rem;
132 font-family: inherit;
133 text-decoration: none;
134}
135
136.btn:hover { background: var(--primary-hover); text-decoration: none;}
137.btn-sm { padding: 0.3rem 0.7rem; font-size: 0.8rem; }
138.btn-lg { padding: 0.7rem 1.5rem; font-size: 1rem; }
139.btn-outline {
140 background: transparent;
141 color: var(--primary);
142}
143.btn-outline:hover { background: var(--primary); color: #fff; }
144.btn-danger.btn-outline:hover { background: var(--danger); border-color: var(--danger); color: #fff; }
145.btn-link {
146 background: none;
147 border: none;
148 color: var(--text-muted);
149 cursor: pointer;
150 font-size: inherit;
151 font-family: inherit;
152}
153.btn-link:hover { color: var(--text); }
154.btn-oauth {
155 background: var(--bg);
156 color: var(--text);
157 border: 1px solid var(--border);
158 display: block;
159 text-align: center;
160 margin-bottom: 0.5rem;
161}
162.btn-oauth:hover { background: var(--border); }
163
164/* Main */
165main {
166 max-width: 1200px;
167 margin: 0 auto;
168 padding: 2rem 1.5rem;
169}
170
171/* Alerts */
172.alert {
173 padding: 0.75rem 1rem;
174 border-radius: var(--radius);
175 margin-bottom: 1rem;
176}
177
178.alert-error {
179 background: var(--alert-error-bg);
180 color: var(--danger);
181 border: 1px solid var(--alert-error-border);
182}
183
184.warning {
185 color: var(--danger);
186}
187
188/* Auth pages */
189.auth-page {
190 max-width: 400px;
191 margin: 2rem auto;
192}
193
194.auth-form label {
195 display: block;
196 margin-bottom: 1rem;
197 font-size: 0.875rem;
198 font-weight: 500;
199}
200
201.auth-form input, .auth-form select, .auth-form textarea {
202 display: block;
203 width: 100%;
204 margin-top: 0.25rem;
205 padding: 0.5rem 0.75rem;
206 border: 1px solid var(--border);
207 border-radius: var(--radius);
208 font-size: 0.9rem;
209 font-family: inherit;
210}
211
212.auth-form textarea { resize: vertical; }
213.auth-form .btn { width: 100%; margin-top: 0.5rem; }
214
215.auth-divider {
216 text-align: center;
217 margin: 1.5rem 0;
218 color: var(--text-muted);
219 font-size: 0.8rem;
220}
221
222.auth-divider span {
223 background: var(--bg);
224 padding: 0 1rem;
225}
226
227.auth-switch {
228 text-align: center;
229 margin-top: 1rem;
230 font-size: 0.875rem;
231 color: var(--text-muted);
232}
233
234/* Landing */
235.landing {
236 text-align: center;
237 padding: 4rem 0;
238}
239
240.landing h1, .about-page h1 { font-size: 2.5rem; margin-bottom: 1.25rem; }
241.landing p, .about-page p { margin-bottom: 1.25rem; }
242.landing-actions { display: flex; gap: 1rem; justify-content: center; }
243
244.landing-header, .about-header {
245 text-align: center;
246}
247
248.landing-header p {
249 text-align: center;
250 font-size: 1.1rem; margin-bottom: 1.25rem;
251}
252
253.about-header {
254 text-align: left;
255}
256
257.about-header p {
258 text-align: left;
259 font-size: 1.1rem;
260 margin-bottom: 1.25rem;
261}
262
263.about-content {
264 color: var(--text-secondary);
265 display: grid;
266 grid-template-columns: 1fr 1fr;
267 gap: 4rem;
268 text-align: left;
269 margin-bottom: 2rem;
270}
271
272.landing-hr, .about-hr {
273 margin: 2rem 0;
274}
275
276@media (max-width: 640px) {
277 .landing-content, .about-content {
278 grid-template-columns: 1fr;
279 }
280}
281
282/* Dashboard */
283.dashboard-header {
284 display: flex;
285 justify-content: space-between;
286 align-items: center;
287 margin-bottom: 1.5rem;
288}
289
290.view-toggle {
291 display: flex;
292 gap: 0.25rem;
293}
294
295.view-toggle button {
296 background: none;
297 border: 1px solid var(--border);
298 border-radius: var(--radius);
299 padding: 0.25rem 0.5rem;
300 cursor: pointer;
301 color: var(--text-muted);
302 font-size: 1rem;
303 line-height: 1;
304}
305
306.view-toggle button.active {
307 background: var(--bg-card);
308 border-color: var(--primary);
309 color: var(--primary);
310}
311
312.repo-list {
313 display: grid;
314 grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
315 gap: 1rem;
316}
317
318.repo-list.list-view {
319 grid-template-columns: 1fr;
320 gap: 0;
321}
322
323.repo-list.list-view .repo-card {
324 border-radius: 0;
325 border-bottom: none;
326 display: flex;
327 align-items: baseline;
328 gap: 1rem;
329 padding: 0.75rem 1rem;
330}
331
332.repo-list.list-view .repo-card:first-child { border-radius: var(--radius) var(--radius) 0 0; }
333.repo-list.list-view .repo-card:last-child { border-radius: 0 0 var(--radius) var(--radius); border-bottom: 1px solid var(--border); }
334.repo-list.list-view .repo-card:only-child { border-radius: var(--radius); border-bottom: 1px solid var(--border); }
335
336.repo-list.list-view .repo-card h3 { margin-bottom: 0; font-size: 1rem; font-weight: 450; }
337.repo-list.list-view .repo-card time { margin-top: 0; margin-left: auto; }
338.repo-list.list-view .repo-card:hover { border-color: var(--border); background: color-mix(in srgb, var(--primary) 5%, var(--bg-card)); }
339
340.repo-card {
341 display: block;
342 padding: 1.25rem;
343 background: var(--bg-card);
344 border: 1px solid var(--border);
345 border-radius: var(--radius);
346 color: var(--text);
347 transition: border-color 0.15s;
348}
349
350.repo-card:hover { border-color: var(--primary); text-decoration: none; }
351.repo-card h3 { margin-bottom: 0.5rem; }
352.repo-card p { color: var(--text-muted); font-size: 0.875rem; margin-bottom: 0.5rem; }
353.repo-vis { font-size: 0.75rem; background: var(--bg); padding: 0.15rem 0.5rem; border-radius: 999px; }
354.repo-card time { display: block; font-size: 0.75rem; color: var(--text-muted); margin-top: 0.5rem; }
355
356/* File browser */
357.repo-header { margin-bottom: 1.5rem; }
358.repo-header h2 { margin-bottom: 0.25rem; }
359.repo-header p { color: var(--text-muted); }
360
361.file-browser {
362 background: var(--bg-card);
363 border: 1px solid var(--border);
364 border-radius: var(--radius);
365}
366
367.file-browser-header {
368 display: flex;
369 justify-content: space-between;
370 align-items: center;
371 padding: 0.75rem 1rem;
372 border-bottom: 1px solid var(--border);
373 font-weight: 550;
374}
375
376.file-list { list-style: none; }
377
378.file-list li {
379 display: flex;
380 justify-content: space-between;
381 align-items: center;
382 padding: 0.6rem 1rem;
383 border-bottom: 1px solid var(--border);
384}
385
386.file-list li:last-child { border-bottom: none; }
387.file-actions { display: flex; gap: 0.5rem; }
388
389/* File page */
390.file-header {
391 display: flex;
392 justify-content: space-between;
393 align-items: center;
394 margin-bottom: 1.5rem;
395}
396
397.breadcrumb {
398 display: flex;
399 align-items: center;
400 gap: 0.5rem;
401 font-size: 0.9rem;
402}
403
404.breadcrumb span { color: var(--text-muted); }
405
406/* Version table */
407.version-table {
408 width: 100%;
409 border-collapse: collapse;
410 background: var(--bg-card);
411 border: 1px solid var(--border);
412 border-radius: var(--radius);
413 font-size: 0.875rem;
414}
415
416.version-table th, .version-table td {
417 padding: 0.6rem 0.75rem;
418 text-align: left;
419 border-bottom: 1px solid var(--border);
420}
421
422.version-table th { background: var(--bg); font-weight: 550; }
423
424.diff-controls { margin-bottom: 1rem; }
425
426/* Dialog */
427dialog {
428 border: 1px solid var(--border);
429 border-radius: var(--radius);
430 padding: 1.5rem;
431 max-width: 400px;
432}
433
434dialog::backdrop { background: rgba(0,0,0,0.3); }
435.dialog-actions { display: flex; gap: 0.5rem; justify-content: flex-end; margin-top: 1rem; }
436
437/* Empty state */
438.empty-state {
439 text-align: center;
440 padding: 2rem;
441 color: var(--text-muted);
442}
443
444/* Status indicators */
445.status-unsaved { color: #d97706; font-size: 0.8rem; }
446.status-saved { color: var(--success); font-size: 0.8rem; }
447.status-error { color: var(--danger); font-size: 0.8rem; }