Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol diffdown.com
at 7fffbda0e0d0dad99d79ddad822d927504bd7c8a 468 lines 9.6 kB view raw
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 283.comment-thread-label { 284 font-size: 0.75rem; 285 color: var(--text-muted); 286 padding: 0.3rem 0.6rem; 287 background: var(--border); 288 border-bottom: 1px solid var(--border); 289} 290 291.comment-item { 292 padding: 0.5rem 0.6rem; 293 border-top: 1px solid var(--border); 294} 295 296.comment-item:first-of-type { 297 border-top: none; 298} 299 300.comment-author { 301 font-size: 0.75rem; 302 font-weight: 600; 303 color: var(--primary); 304 margin-bottom: 0.2rem; 305} 306 307.comment-text { 308 font-size: 0.85rem; 309 line-height: 1.45; 310 word-break: break-word; 311} 312 313.comment-time { 314 font-size: 0.7rem; 315 color: var(--text-muted); 316 margin-top: 0.25rem; 317} 318 319/* ── Collaboration: Comment button & form ────────────────────────────────── */ 320 321.comment-btn { 322 position: fixed; 323 z-index: 100; 324 padding: 0.25rem 0.6rem; 325 font-size: 0.78rem; 326 background: var(--primary); 327 color: #fff; 328 border: none; 329 border-radius: var(--radius); 330 cursor: pointer; 331 box-shadow: 0 2px 8px rgba(0,0,0,0.15); 332} 333 334.comment-btn:hover { 335 opacity: 0.88; 336} 337 338.comment-form { 339 position: fixed; 340 z-index: 110; 341 background: var(--bg-card); 342 border: 1px solid var(--border); 343 border-radius: var(--radius); 344 box-shadow: 0 4px 20px rgba(0,0,0,0.15); 345 padding: 0.75rem; 346 width: 280px; 347} 348 349.comment-form textarea { 350 width: 100%; 351 box-sizing: border-box; 352 background: var(--bg); 353 border: 1px solid var(--border); 354 border-radius: var(--radius); 355 color: var(--text); 356 padding: 0.4rem 0.5rem; 357 font-size: 0.85rem; 358 resize: vertical; 359 outline: none; 360 font-family: inherit; 361} 362 363.comment-form textarea:focus { 364 border-color: var(--primary); 365} 366 367.comment-form-actions { 368 display: flex; 369 gap: 0.5rem; 370 margin-top: 0.5rem; 371 justify-content: flex-end; 372} 373 374/* When comment sidebar is visible, shrink editor to avoid overlap */ 375.editor-page:has(~ .comment-sidebar) { 376 right: 260px; 377} 378 379/* ── Comment mark highlight ──────────────────────────────────────────────── */ 380 381.comment-highlight { 382 background: rgba(234, 179, 8, 0.2); 383 border-bottom: 2px solid rgba(234, 179, 8, 0.6); 384 cursor: pointer; 385 border-radius: 2px; 386} 387 388.comment-highlight:hover { 389 background: rgba(234, 179, 8, 0.35); 390} 391 392.comment-thread-detached .comment-thread-label { 393 color: var(--danger, #ef4444); 394} 395 396.comment-thread-detached { 397 opacity: 0.7; 398} 399 400/* ── Collaboration: Invite modal ─────────────────────────────────────────── */ 401 402.invite-modal { 403 position: fixed; 404 inset: 0; 405 background: rgba(0,0,0,0.4); 406 display: flex; 407 align-items: center; 408 justify-content: center; 409 z-index: 200; 410} 411 412.invite-modal-box { 413 background: var(--bg-card); 414 border: 1px solid var(--border); 415 border-radius: var(--radius); 416 box-shadow: 0 8px 32px rgba(0,0,0,0.2); 417 width: 440px; 418 max-width: calc(100vw - 2rem); 419} 420 421.invite-modal-header { 422 display: flex; 423 align-items: center; 424 justify-content: space-between; 425 padding: 0.75rem 1rem; 426 border-bottom: 1px solid var(--border); 427 font-weight: 600; 428 font-size: 0.9rem; 429} 430 431.invite-modal-close { 432 background: none; 433 border: none; 434 color: var(--text-muted); 435 cursor: pointer; 436 font-size: 1rem; 437 padding: 0.1rem 0.3rem; 438 line-height: 1; 439} 440 441.invite-modal-close:hover { 442 color: var(--text); 443} 444 445.invite-modal-body { 446 padding: 1rem; 447} 448 449/* Comment threading */ 450.comment-thread-header { 451 display: flex; 452 justify-content: space-between; 453 align-items: center; 454 padding-bottom: 8px; 455 border-bottom: 1px solid var(--border-color); 456 margin-bottom: 8px; 457} 458 459.comment-item-reply { 460 margin-left: 24px; 461 padding-left: 12px; 462 border-left: 2px solid var(--border-color); 463} 464 465.btn-active { 466 background-color: var(--success-color); 467 color: white; 468}