Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol
diffdown.com
1.editor-page {
2 position: fixed;
3 top: 49px; /* navbar height */
4 left: 0;
5 right: 0;
6 bottom: 0;
7 display: flex;
8 flex-direction: column;
9}
10
11.editor-toolbar {
12 display: flex;
13 justify-content: space-between;
14 align-items: center;
15 padding: 0.5rem 1rem;
16 border-bottom: 1px solid var(--border);
17 background: var(--bg-card);
18 flex-shrink: 0;
19}
20
21.toolbar-actions {
22 display: flex;
23 align-items: center;
24 gap: 0.75rem;
25 flex-shrink: 0;
26}
27
28@media (max-width: 600px) {
29 .editor-toolbar {
30 flex-wrap: wrap;
31 gap: 0.4rem;
32 padding: 0.4rem 0.75rem;
33 }
34
35 .breadcrumb {
36 flex: 1 1 100%;
37 min-width: 0;
38 }
39
40 .toolbar-actions {
41 flex: 1 1 100%;
42 gap: 0.4rem;
43 overflow-x: auto;
44 padding-bottom: 0.1rem;
45 }
46}
47
48.btn-outline.active {
49 background: var(--primary);
50 color: #fff;
51}
52
53.title-input {
54 background: transparent;
55 border: none;
56 border-bottom: 1px solid transparent;
57 color: var(--text);
58 font-size: 0.9rem;
59 padding: 0.1rem 0.25rem;
60 min-width: 12rem;
61 max-width: 30rem;
62 outline: none;
63}
64
65.title-input:hover,
66.title-input:focus {
67 border-bottom-color: var(--border);
68}
69
70.editor-split {
71 display: flex;
72 flex: 1;
73 overflow: hidden;
74 min-height: 0;
75}
76
77.editor-pane {
78 flex: 1;
79 overflow: hidden;
80 min-height: 0;
81 border-right: 1px solid var(--border);
82}
83
84#editor {
85 height: 100%;
86}
87
88.editor-pane .cm-editor {
89 height: 100%;
90}
91
92.preview-pane {
93 flex: 1;
94 overflow: auto;
95 padding: 1.5rem;
96 background: var(--bg-card);
97}
98
99/* Rich text (WYSIWYG) editor container */
100.editor-rich {
101 flex: 1;
102 overflow: auto;
103 padding: 2rem 1.5rem;
104 display: flex;
105 flex-direction: column;
106 align-items: center;
107 background: var(--bg);
108}
109
110.editor-rich .milkdown {
111 width: 100%;
112 max-width: 720px;
113 outline: none;
114 cursor: text;
115 background: var(--bg-card);
116 border: 1px solid var(--border);
117 border-radius: var(--radius);
118 box-shadow: 0 2px 12px rgba(0,0,0,0.08);
119 padding: 3rem 3.5rem;
120}
121
122/* Milkdown prose styles — match markdown.css */
123.editor-rich .milkdown .ProseMirror {
124 outline: none;
125 min-height: 60vh;
126}
127
128.editor-rich .milkdown .ProseMirror p {
129 margin-bottom: 1.25em;
130}
131
132.editor-rich .milkdown .ProseMirror ul,
133.editor-rich .milkdown .ProseMirror ol {
134 padding-left: 1.5rem;
135}
136
137.editor-rich .milkdown .ProseMirror li {
138 margin-bottom: 0.25em;
139}
140
141.editor-rich .milkdown .ProseMirror li > p {
142 margin-bottom: 0;
143}
144
145/* Source/Wrap/Preview buttons hidden in rich text mode */
146.source-only {
147 display: none;
148}
149
150/* Link editing tooltip */
151.link-tooltip {
152 position: fixed;
153 z-index: 200;
154 display: none;
155 align-items: center;
156 gap: 0.4rem;
157 background: var(--bg-card);
158 border: 1px solid var(--border);
159 border-radius: var(--radius);
160 padding: 0.35rem 0.5rem;
161 box-shadow: 0 4px 16px rgba(0,0,0,0.15);
162}
163
164.link-tooltip.visible {
165 display: flex;
166}
167
168.link-tooltip input {
169 width: 260px;
170 border: 1px solid var(--border);
171 border-radius: var(--radius);
172 background: var(--bg);
173 color: var(--text);
174 padding: 0.2rem 0.5rem;
175 font-size: 0.83rem;
176 outline: none;
177}
178
179.link-tooltip input:focus {
180 border-color: var(--primary);
181}
182
183.link-tooltip button {
184 background: none;
185 border: 1px solid var(--border);
186 border-radius: var(--radius);
187 color: var(--text-muted);
188 cursor: pointer;
189 font-size: 0.8rem;
190 padding: 0.2rem 0.45rem;
191 white-space: nowrap;
192 line-height: 1.4;
193}
194
195.link-tooltip button:first-of-type {
196 background: var(--primary);
197 border-color: var(--primary);
198 color: #fff;
199}
200
201.link-tooltip button:hover { opacity: 0.8; }
202
203/* ── Collaboration: Presence ─────────────────────────────────────────────── */
204
205.presence-list {
206 display: flex;
207 align-items: center;
208 gap: 4px;
209}
210
211.presence-avatar {
212 display: inline-block;
213 width: 22px;
214 height: 22px;
215 border-radius: 50%;
216 border: 2px solid var(--bg-card);
217 box-shadow: 0 0 0 1px var(--border);
218 flex-shrink: 0;
219 transition: transform 0.15s;
220 object-fit: cover;
221}
222
223.presence-avatar:hover {
224 transform: scale(1.15);
225}
226
227/* ── Collaboration: Comment sidebar ──────────────────────────────────────── */
228
229.comment-sidebar {
230 position: fixed;
231 right: 0;
232 top: 49px; /* below navbar */
233 bottom: 0;
234 width: 260px;
235 background: var(--bg-card);
236 border-left: 1px solid var(--border);
237 display: flex;
238 flex-direction: column;
239 z-index: 50;
240 overflow: hidden;
241}
242
243.comment-sidebar-header {
244 padding: 0.75rem 1rem;
245 font-size: 0.85rem;
246 font-weight: 600;
247 border-bottom: 1px solid var(--border);
248 flex-shrink: 0;
249 color: var(--text-muted);
250 text-transform: uppercase;
251 letter-spacing: 0.05em;
252}
253
254.comment-threads {
255 flex: 1;
256 overflow-y: auto;
257 padding: 0.75rem;
258 display: flex;
259 flex-direction: column;
260 gap: 0.75rem;
261}
262
263.comment-empty {
264 color: var(--text-muted);
265 font-size: 0.85rem;
266 text-align: center;
267 margin-top: 2rem;
268}
269
270.comment-thread {
271 background: var(--bg);
272 border: 1px solid var(--border);
273 border-radius: var(--radius);
274 overflow: hidden;
275 cursor: pointer;
276}
277
278.comment-thread:hover {
279 border-color: var(--primary);
280}
281
282@keyframes para-highlight {
283 0% { box-shadow: inset 0 0 0 2px rgba(37, 99, 235, 0.7), 0 0 0 4px rgba(37, 99, 235, 0.15); }
284 100% { box-shadow: inset 0 0 0 2px rgba(37, 99, 235, 0), 0 0 0 4px rgba(37, 99, 235, 0); }
285}
286
287.para-highlight {
288 animation: para-highlight 1.4s ease-out forwards;
289 border-radius: 3px;
290}
291
292.comment-thread-label {
293 font-size: 0.75rem;
294 color: var(--text-muted);
295 padding: 0.3rem 0.6rem;
296 background: var(--border);
297 border-bottom: 1px solid var(--border);
298}
299
300.comment-item {
301 padding: 0.5rem 0.6rem;
302 border-top: 1px solid var(--border);
303}
304
305.comment-item:first-of-type {
306 border-top: none;
307}
308
309.comment-author {
310 font-size: 0.75rem;
311 font-weight: 600;
312 color: var(--primary);
313 margin-bottom: 0.2rem;
314}
315
316.comment-text {
317 font-size: 0.85rem;
318 line-height: 1.45;
319 word-break: break-word;
320}
321
322.comment-time {
323 font-size: 0.7rem;
324 color: var(--text-muted);
325 margin-top: 0.25rem;
326}
327
328/* ── Collaboration: Comment button & form ────────────────────────────────── */
329
330.comment-btn {
331 position: fixed;
332 z-index: 100;
333 padding: 0.25rem 0.6rem;
334 font-size: 0.78rem;
335 background: var(--primary);
336 color: #fff;
337 border: none;
338 border-radius: var(--radius);
339 cursor: pointer;
340 box-shadow: 0 2px 8px rgba(0,0,0,0.15);
341}
342
343.comment-btn:hover {
344 opacity: 0.88;
345}
346
347.comment-form {
348 position: fixed;
349 z-index: 110;
350 background: var(--bg-card);
351 border: 1px solid var(--border);
352 border-radius: var(--radius);
353 box-shadow: 0 4px 20px rgba(0,0,0,0.15);
354 padding: 0.75rem;
355 width: 280px;
356}
357
358.comment-form textarea {
359 width: 100%;
360 box-sizing: border-box;
361 background: var(--bg);
362 border: 1px solid var(--border);
363 border-radius: var(--radius);
364 color: var(--text);
365 padding: 0.4rem 0.5rem;
366 font-size: 0.85rem;
367 resize: vertical;
368 outline: none;
369 font-family: inherit;
370}
371
372.comment-form textarea:focus {
373 border-color: var(--primary);
374}
375
376.comment-form-actions {
377 display: flex;
378 gap: 0.5rem;
379 margin-top: 0.5rem;
380 justify-content: flex-end;
381}
382
383/* When comment sidebar is visible, shrink editor to avoid overlap */
384.editor-page:has(~ .comment-sidebar) {
385 right: 260px;
386}
387
388/* ── Collaboration: Invite modal ─────────────────────────────────────────── */
389
390.invite-modal {
391 position: fixed;
392 inset: 0;
393 background: rgba(0,0,0,0.4);
394 display: flex;
395 align-items: center;
396 justify-content: center;
397 z-index: 200;
398}
399
400.invite-modal-box {
401 background: var(--bg-card);
402 border: 1px solid var(--border);
403 border-radius: var(--radius);
404 box-shadow: 0 8px 32px rgba(0,0,0,0.2);
405 width: 440px;
406 max-width: calc(100vw - 2rem);
407}
408
409.invite-modal-header {
410 display: flex;
411 align-items: center;
412 justify-content: space-between;
413 padding: 0.75rem 1rem;
414 border-bottom: 1px solid var(--border);
415 font-weight: 600;
416 font-size: 0.9rem;
417}
418
419.invite-modal-close {
420 background: none;
421 border: none;
422 color: var(--text-muted);
423 cursor: pointer;
424 font-size: 1rem;
425 padding: 0.1rem 0.3rem;
426 line-height: 1;
427}
428
429.invite-modal-close:hover {
430 color: var(--text);
431}
432
433.invite-modal-body {
434 padding: 1rem;
435}