Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol diffdown.com
at 26872a2cb545df9a3e9d60038a2cd7ce33fcaca4 435 lines 8.9 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@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}