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);
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: #1a1a2e;
13 --text-muted: #6b7280;
14 --border: #e5e7eb;
15 --primary: #2563eb;
16 --primary-hover: #1d4ed8;
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, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
23 --radius: 6px;
24 --font: "Barlow", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, 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: #58a6ff;
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: #58a6ff;
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
69a { color: var(--primary); text-decoration: none; }
70a:hover { text-decoration: underline; }
71
72h1, h2, h3, h4, h5 {
73 font-family: var(--heading-font);
74 font-weight: 500;
75}
76
77/* Navbar */
78.navbar {
79 display: flex;
80 align-items: center;
81 justify-content: space-between;
82 padding: 0.75rem 1.5rem;
83 border-bottom: 1px solid var(--border);
84 background: var(--bg-card);
85}
86
87.logo {
88 font-weight: 500;
89 font-size: 1.1rem;
90 color: var(--text);
91}
92
93.nav-right {
94 display: flex;
95 align-items: center;
96 gap: 1rem;
97}
98
99.nav-user { color: var(--text-muted); }
100
101/* Buttons */
102.btn {
103 display: inline-block;
104 padding: 0.5rem 1rem;
105 background: var(--primary);
106 color: #fff;
107 border: 1px solid var(--primary);
108 border-radius: var(--radius);
109 cursor: pointer;
110 font-size: 0.875rem;
111 font-family: inherit;
112 text-decoration: none;
113}
114
115.btn:hover { background: var(--primary-hover); text-decoration: none; }
116.btn-sm { padding: 0.3rem 0.7rem; font-size: 0.8rem; }
117.btn-lg { padding: 0.7rem 1.5rem; font-size: 1rem; }
118.btn-outline {
119 background: transparent;
120 color: var(--primary);
121}
122.btn-outline:hover { background: var(--primary); color: #fff; }
123.btn-danger.btn-outline:hover { background: var(--danger); border-color: var(--danger); color: #fff; }
124.btn-link {
125 background: none;
126 border: none;
127 color: var(--text-muted);
128 cursor: pointer;
129 font-size: inherit;
130 font-family: inherit;
131}
132.btn-link:hover { color: var(--text); }
133.btn-oauth {
134 background: var(--bg);
135 color: var(--text);
136 border: 1px solid var(--border);
137 display: block;
138 text-align: center;
139 margin-bottom: 0.5rem;
140}
141.btn-oauth:hover { background: var(--border); }
142
143/* Main */
144main {
145 max-width: 1200px;
146 margin: 0 auto;
147 padding: 2rem 1.5rem;
148}
149
150/* Alerts */
151.alert {
152 padding: 0.75rem 1rem;
153 border-radius: var(--radius);
154 margin-bottom: 1rem;
155}
156
157.alert-error {
158 background: var(--alert-error-bg);
159 color: var(--danger);
160 border: 1px solid var(--alert-error-border);
161}
162
163/* Auth pages */
164.auth-page {
165 max-width: 400px;
166 margin: 2rem auto;
167}
168
169.auth-form label {
170 display: block;
171 margin-bottom: 1rem;
172 font-size: 0.875rem;
173 font-weight: 500;
174}
175
176.auth-form input, .auth-form select, .auth-form textarea {
177 display: block;
178 width: 100%;
179 margin-top: 0.25rem;
180 padding: 0.5rem 0.75rem;
181 border: 1px solid var(--border);
182 border-radius: var(--radius);
183 font-size: 0.9rem;
184 font-family: inherit;
185}
186
187.auth-form textarea { resize: vertical; }
188.auth-form .btn { width: 100%; margin-top: 0.5rem; }
189
190.auth-divider {
191 text-align: center;
192 margin: 1.5rem 0;
193 color: var(--text-muted);
194 font-size: 0.8rem;
195}
196
197.auth-divider span {
198 background: var(--bg);
199 padding: 0 1rem;
200}
201
202.auth-switch {
203 text-align: center;
204 margin-top: 1rem;
205 font-size: 0.875rem;
206 color: var(--text-muted);
207}
208
209/* Landing */
210.landing {
211 text-align: center;
212 padding: 4rem 0;
213}
214
215.landing h1 { font-size: 2.5rem; margin-bottom: 1rem; }
216.landing p { font-size: 1.1rem; font-weight: 400; margin-bottom: 2rem; }
217.landing-actions { display: flex; gap: 1rem; justify-content: center; }
218
219.landing-header {
220 text-align: center;
221}
222
223.landing-content {
224 color: var(--text-secondary);
225 display: grid;
226 grid-template-columns: 1fr 1fr;
227 gap: 2rem;
228 text-align: left;
229 margin-bottom: 2rem;
230}
231
232.landing-hr {
233 margin: 2rem 0;
234}
235
236@media (max-width: 640px) {
237 .landing-content {
238 grid-template-columns: 1fr;
239 }
240}
241
242/* Dashboard */
243.dashboard-header {
244 display: flex;
245 justify-content: space-between;
246 align-items: center;
247 margin-bottom: 1.5rem;
248}
249
250.view-toggle {
251 display: flex;
252 gap: 0.25rem;
253}
254
255.view-toggle button {
256 background: none;
257 border: 1px solid var(--border);
258 border-radius: var(--radius);
259 padding: 0.25rem 0.5rem;
260 cursor: pointer;
261 color: var(--text-muted);
262 font-size: 1rem;
263 line-height: 1;
264}
265
266.view-toggle button.active {
267 background: var(--bg-card);
268 border-color: var(--primary);
269 color: var(--primary);
270}
271
272.repo-list {
273 display: grid;
274 grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
275 gap: 1rem;
276}
277
278.repo-list.list-view {
279 grid-template-columns: 1fr;
280 gap: 0;
281}
282
283.repo-list.list-view .repo-card {
284 border-radius: 0;
285 border-bottom: none;
286 display: flex;
287 align-items: baseline;
288 gap: 1rem;
289 padding: 0.75rem 1rem;
290}
291
292.repo-list.list-view .repo-card:first-child { border-radius: var(--radius) var(--radius) 0 0; }
293.repo-list.list-view .repo-card:last-child { border-radius: 0 0 var(--radius) var(--radius); border-bottom: 1px solid var(--border); }
294.repo-list.list-view .repo-card:only-child { border-radius: var(--radius); border-bottom: 1px solid var(--border); }
295
296.repo-list.list-view .repo-card h3 { margin-bottom: 0; font-size: 1rem; font-weight: 500; }
297.repo-list.list-view .repo-card time { margin-top: 0; margin-left: auto; }
298.repo-list.list-view .repo-card:hover { border-color: var(--border); background: color-mix(in srgb, var(--primary) 5%, var(--bg-card)); }
299
300.repo-card {
301 display: block;
302 padding: 1.25rem;
303 background: var(--bg-card);
304 border: 1px solid var(--border);
305 border-radius: var(--radius);
306 color: var(--text);
307 transition: border-color 0.15s;
308}
309
310.repo-card:hover { border-color: var(--primary); text-decoration: none; }
311.repo-card h3 { margin-bottom: 0.5rem; }
312.repo-card p { color: var(--text-muted); font-size: 0.875rem; margin-bottom: 0.5rem; }
313.repo-vis { font-size: 0.75rem; background: var(--bg); padding: 0.15rem 0.5rem; border-radius: 999px; }
314.repo-card time { display: block; font-size: 0.75rem; color: var(--text-muted); margin-top: 0.5rem; }
315
316/* File browser */
317.repo-page { }
318.repo-header { margin-bottom: 1.5rem; }
319.repo-header h2 { margin-bottom: 0.25rem; }
320.repo-header p { color: var(--text-muted); }
321
322.file-browser {
323 background: var(--bg-card);
324 border: 1px solid var(--border);
325 border-radius: var(--radius);
326}
327
328.file-browser-header {
329 display: flex;
330 justify-content: space-between;
331 align-items: center;
332 padding: 0.75rem 1rem;
333 border-bottom: 1px solid var(--border);
334 font-weight: 600;
335}
336
337.file-list { list-style: none; }
338
339.file-list li {
340 display: flex;
341 justify-content: space-between;
342 align-items: center;
343 padding: 0.6rem 1rem;
344 border-bottom: 1px solid var(--border);
345}
346
347.file-list li:last-child { border-bottom: none; }
348.file-actions { display: flex; gap: 0.5rem; }
349
350/* File page */
351.file-page, .history-page, .diff-page { }
352
353.file-header {
354 display: flex;
355 justify-content: space-between;
356 align-items: center;
357 margin-bottom: 1.5rem;
358}
359
360.breadcrumb {
361 display: flex;
362 align-items: center;
363 gap: 0.5rem;
364 font-size: 0.9rem;
365}
366
367.breadcrumb span { color: var(--text-muted); }
368
369/* Version table */
370.version-table {
371 width: 100%;
372 border-collapse: collapse;
373 background: var(--bg-card);
374 border: 1px solid var(--border);
375 border-radius: var(--radius);
376 font-size: 0.875rem;
377}
378
379.version-table th, .version-table td {
380 padding: 0.6rem 0.75rem;
381 text-align: left;
382 border-bottom: 1px solid var(--border);
383}
384
385.version-table th { background: var(--bg); font-weight: 600; }
386
387.diff-controls { margin-bottom: 1rem; }
388
389/* Dialog */
390dialog {
391 border: 1px solid var(--border);
392 border-radius: var(--radius);
393 padding: 1.5rem;
394 max-width: 400px;
395}
396
397dialog::backdrop { background: rgba(0,0,0,0.3); }
398.dialog-actions { display: flex; gap: 0.5rem; justify-content: flex-end; margin-top: 1rem; }
399
400/* Empty state */
401.empty-state {
402 text-align: center;
403 padding: 2rem;
404 color: var(--text-muted);
405}
406
407/* Status indicators */
408.status-unsaved { color: #d97706; font-size: 0.8rem; }
409.status-saved { color: var(--success); font-size: 0.8rem; }
410.status-error { color: var(--danger); font-size: 0.8rem; }