md2ui 1.0.18 → 1.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +51 -58
  2. package/bin/build.js +95 -9
  3. package/bin/md2ui.js +102 -13
  4. package/package.json +24 -10
  5. package/public/docs/00-/345/277/253/351/200/237/345/274/200/345/247/213.md +48 -28
  6. package/public/docs/01-/345/212/237/350/203/275/347/211/271/346/200/247.md +55 -40
  7. package/public/docs/02-Markdown/346/270/262/346/237/223/00-/345/237/272/347/241/200/350/257/255/346/263/225.md +88 -0
  8. package/public/docs/02-Markdown/346/270/262/346/237/223/01-/344/273/243/347/240/201/345/235/227.md +91 -0
  9. package/public/docs/02-Markdown/346/270/262/346/237/223/02-/350/241/250/346/240/274.md +187 -0
  10. package/public/docs/02-Markdown/346/270/262/346/237/223/03-Mermaid/345/233/276/350/241/250.md +101 -0
  11. package/public/docs/02-Markdown/346/270/262/346/237/223/04-Frontmatter.md +32 -0
  12. package/public/docs/02-Markdown/346/270/262/346/237/223/05-/346/225/260/345/255/246/345/205/254/345/274/217.md +47 -0
  13. package/public/docs/02-Markdown/346/270/262/346/237/223/06-Mermaid/345/244/215/346/235/202/345/233/276/350/241/250/346/265/213/350/257/225.md +1376 -0
  14. package/public/docs/02-Markdown/346/270/262/346/237/223/assets/img-1777383093712.png +0 -0
  15. package/public/docs/03-/345/257/274/350/210/252/344/270/216/345/270/203/345/261/200/00-/344/270/211/346/240/217/345/270/203/345/261/200.md +33 -0
  16. package/public/docs/03-/345/257/274/350/210/252/344/270/216/345/270/203/345/261/200/01-/347/233/256/345/275/225/346/240/221/345/257/274/350/210/252.md +43 -0
  17. package/public/docs/03-/345/257/274/350/210/252/344/270/216/345/270/203/345/261/200/02-/346/226/207/346/241/243/345/244/247/347/272/262.md +51 -0
  18. package/public/docs/03-/345/257/274/350/210/252/344/270/216/345/270/203/345/261/200/03-/344/270/212/344/270/213/347/257/207/345/257/274/350/210/252.md +29 -0
  19. package/public/docs/03-/345/257/274/350/210/252/344/270/216/345/270/203/345/261/200/04-/347/253/231/345/206/205/351/223/276/346/216/245.md +39 -0
  20. package/public/docs/03-/345/257/274/350/210/252/344/270/216/345/270/203/345/261/200/05-/345/244/247/347/272/262/345/216/213/345/212/233/346/265/213/350/257/225.md +340 -0
  21. package/public/docs/04-/346/220/234/347/264/242/345/212/237/350/203/275/00-/345/205/250/346/226/207/346/220/234/347/264/242.md +46 -0
  22. package/public/docs/05-/347/274/226/350/276/221/345/212/237/350/203/275/00-/347/274/226/350/276/221/345/231/250/345/237/272/347/241/200.md +65 -0
  23. package/public/docs/05-/347/274/226/350/276/221/345/212/237/350/203/275/01-/350/207/252/345/212/250/344/277/235/345/255/230.md +38 -0
  24. package/public/docs/06-/351/230/205/350/257/273/344/275/223/351/252/214/00-/351/230/205/350/257/273/350/277/233/345/272/246.md +43 -0
  25. package/public/docs/06-/351/230/205/350/257/273/344/275/223/351/252/214/01-/345/233/276/347/211/207/346/224/276/345/244/247.md +40 -0
  26. package/public/docs/06-/351/230/205/350/257/273/344/275/223/351/252/214/02-/350/277/224/345/233/236/351/241/266/351/203/250.md +38 -0
  27. package/public/docs/06-/351/230/205/350/257/273/344/275/223/351/252/214/assets/img-1777261394722.png +0 -0
  28. package/public/docs/07-/347/247/273/345/212/250/347/253/257/351/200/202/351/205/215/00-/345/223/215/345/272/224/345/274/217/345/270/203/345/261/200.md +37 -0
  29. package/public/docs/08-/346/226/207/346/241/243/347/256/241/347/220/206/00-/346/226/260/345/273/272/344/270/216/345/210/240/351/231/244.md +47 -0
  30. package/public/docs/09-/345/257/274/345/207/272/345/212/237/350/203/275/00-/345/257/274/345/207/272Word.md +77 -0
  31. package/public/docs/10-/351/203/250/347/275/262/344/270/216/351/205/215/347/275/256/00-CLI/345/267/245/345/205/267.md +52 -0
  32. package/public/docs/10-/351/203/250/347/275/262/344/270/216/351/205/215/347/275/256/01-SSG/351/235/231/346/200/201/346/236/204/345/273/272.md +44 -0
  33. package/public/docs/10-/351/203/250/347/275/262/344/270/216/351/205/215/347/275/256/02-/350/207/252/345/256/232/344/271/211/351/205/215/347/275/256.md +58 -0
  34. package/public/docs/11-/345/244/232/347/272/247/347/233/256/345/275/225/346/265/213/350/257/225/00-/344/270/200/347/272/247/346/226/207/346/241/243.md +20 -0
  35. package/public/docs/11-/345/244/232/347/272/247/347/233/256/345/275/225/346/265/213/350/257/225/01-/345/255/220/347/233/256/345/275/225/00-/344/272/214/347/272/247/346/226/207/346/241/243.md +13 -0
  36. package/public/docs/11-/345/244/232/347/272/247/347/233/256/345/275/225/346/265/213/350/257/225/01-/345/255/220/347/233/256/345/275/225/01-/346/267/261/345/261/202/345/265/214/345/245/227/00-/344/270/211/347/272/247/346/226/207/346/241/243.md +23 -0
  37. package/src/App.vue +111 -12
  38. package/src/components/AppSidebar.vue +181 -21
  39. package/src/components/CodeBlockNodeView.vue +72 -0
  40. package/src/components/DocContent.vue +25 -14
  41. package/src/components/EditorContent.vue +257 -0
  42. package/src/components/EditorToolbar.vue +264 -0
  43. package/src/components/ImageZoom.vue +88 -5
  44. package/src/components/MathBlockNodeView.vue +160 -0
  45. package/src/components/MathInlineNodeView.vue +145 -0
  46. package/src/components/MermaidNodeView.vue +157 -0
  47. package/src/components/MobileSearch.vue +97 -0
  48. package/src/components/TableOfContents.vue +174 -32
  49. package/src/components/TopBar.vue +69 -4
  50. package/src/components/TreeNode.vue +232 -39
  51. package/src/components/WelcomePage.vue +2 -2
  52. package/src/composables/useDocHash.js +9 -1
  53. package/src/composables/useDocManager.js +452 -105
  54. package/src/composables/useDocTree.js +33 -2
  55. package/src/composables/useExportWord.js +73 -10
  56. package/src/composables/useFileWatcher.js +45 -0
  57. package/src/composables/useFrontmatter.js +2 -2
  58. package/src/composables/useMarkdown.js +450 -52
  59. package/src/composables/useMermaidCache.js +15 -0
  60. package/src/composables/useScroll.js +354 -27
  61. package/src/composables/useSearch.js +12 -11
  62. package/src/config.js +1 -4
  63. package/src/extensions/CodeBlockCustom.js +113 -0
  64. package/src/extensions/MathBlock.js +107 -0
  65. package/src/extensions/MathInline.js +100 -0
  66. package/src/extensions/MermaidBlock.js +73 -0
  67. package/src/extensions/TableControls.js +670 -0
  68. package/src/services/DocService.js +168 -0
  69. package/src/style.css +2416 -36
  70. package/src/utils/imageConverter.js +129 -0
  71. package/vite-plugin-doc-api.js +369 -0
  72. package/vite.config.js +7 -2
  73. package/public/docs/02-Mermaid/345/233/276/350/241/250.md +0 -102
  74. package/public/docs/03-/350/277/233/351/230/266/346/214/207/345/215/227/01-/347/233/256/345/275/225/347/273/223/346/236/204.md +0 -55
  75. package/public/docs/03-/350/277/233/351/230/266/346/214/207/345/215/227/02-/350/207/252/345/256/232/344/271/211/351/205/215/347/275/256.md +0 -63
  76. package/public/docs/03-/350/277/233/351/230/266/346/214/207/345/215/227/03-/351/203/250/347/275/262/346/226/271/346/241/210.md +0 -73
  77. package/public/docs/04-API/345/217/202/350/200/203/01-/347/273/204/344/273/266API.md +0 -80
  78. package/public/docs/04-API/345/217/202/350/200/203/02-Composables.md +0 -92
  79. package/src/api/docs.js +0 -106
  80. package/src/components/SearchPanel.vue +0 -90
package/src/style.css CHANGED
@@ -248,14 +248,14 @@ body {
248
248
  max-width: 960px;
249
249
  margin: 0 auto;
250
250
  background: var(--color-bg);
251
- padding: 24px 32px;
251
+ padding: 24px 20px;
252
252
  }
253
253
 
254
254
  /* Markdown 内容样式 */
255
- /* 标题锚点链接 */
255
+ /* 标题锚点链接 — hover 显示 # 符号 */
256
256
  .markdown-content .heading-anchor {
257
257
  position: absolute;
258
- left: -1.5em;
258
+ left: -1.2em;
259
259
  top: 50%;
260
260
  transform: translateY(-50%);
261
261
  display: flex;
@@ -267,6 +267,9 @@ body {
267
267
  color: var(--color-text-tertiary);
268
268
  text-decoration: none;
269
269
  transition: opacity 0.15s, color 0.15s;
270
+ font-size: 0.85em;
271
+ font-weight: 400;
272
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
270
273
  }
271
274
 
272
275
  .markdown-content h1,
@@ -276,6 +279,19 @@ body {
276
279
  .markdown-content h5,
277
280
  .markdown-content h6 {
278
281
  position: relative;
282
+ scroll-margin-top: 60px;
283
+ }
284
+
285
+ /* 标题锚点跳转高亮闪烁动画 */
286
+ @keyframes heading-flash {
287
+ 0% { background-color: transparent; }
288
+ 15% { background-color: rgba(66, 184, 131, 0.15); }
289
+ 100% { background-color: transparent; }
290
+ }
291
+
292
+ .markdown-content .heading-flash {
293
+ animation: heading-flash 1.5s ease-out;
294
+ border-radius: 4px;
279
295
  }
280
296
 
281
297
  .markdown-content h1:hover .heading-anchor,
@@ -289,11 +305,45 @@ body {
289
305
 
290
306
  .markdown-content .heading-anchor:hover {
291
307
  color: var(--color-accent);
308
+ text-decoration: none;
309
+ }
310
+
311
+ /* 锚点提示气泡(hover + 点击复制共用同一位置) */
312
+ .markdown-content .heading-anchor::after {
313
+ content: '复制链接';
314
+ position: absolute;
315
+ left: 0.7em;
316
+ bottom: calc(100% + 4px);
317
+ padding: 1px 6px;
318
+ background: var(--color-bg-tertiary);
319
+ color: var(--color-text-secondary);
320
+ font-size: 10px;
321
+ font-weight: 400;
322
+ border-radius: 3px;
323
+ white-space: nowrap;
324
+ pointer-events: none;
325
+ opacity: 0;
326
+ transition: opacity 0.15s;
327
+ z-index: 10;
328
+ }
329
+
330
+ .markdown-content .heading-anchor:hover::after {
331
+ opacity: 1;
332
+ }
333
+
334
+ /* 点击复制后切换为"已复制"状态 */
335
+ .markdown-content .heading-anchor.anchor-copied::after {
336
+ content: '已复制';
337
+ background: var(--color-success-bg, #dafbe1);
338
+ color: var(--color-success, #1a7f37);
339
+ opacity: 1;
292
340
  }
293
341
 
294
- .markdown-content .heading-anchor svg {
295
- width: 0.7em;
296
- height: 0.7em;
342
+ .markdown-content .heading-anchor.anchor-copy-error::after {
343
+ content: '复制失败';
344
+ background: var(--color-error-bg, #ffebe9);
345
+ color: var(--color-error-text, #cf222e);
346
+ opacity: 1;
297
347
  }
298
348
 
299
349
  .markdown-content h1 {
@@ -334,6 +384,22 @@ body {
334
384
  font-weight: 600;
335
385
  }
336
386
 
387
+ .markdown-content h5 {
388
+ font-size: 0.95em;
389
+ margin-top: 14px;
390
+ margin-bottom: 6px;
391
+ color: var(--color-text);
392
+ font-weight: 600;
393
+ }
394
+
395
+ .markdown-content h6 {
396
+ font-size: 0.9em;
397
+ margin-top: 12px;
398
+ margin-bottom: 6px;
399
+ color: var(--color-text-secondary);
400
+ font-weight: 600;
401
+ }
402
+
337
403
  .markdown-content p {
338
404
  margin-bottom: 12px;
339
405
  color: var(--color-text);
@@ -389,18 +455,144 @@ body {
389
455
  }
390
456
 
391
457
  /* 表格 */
458
+
459
+ /* 表格外层容器 */
460
+ .markdown-content .table-outer {
461
+ position: relative;
462
+ margin-bottom: 16px;
463
+ }
464
+
465
+ /* 表格工具栏 */
466
+ .markdown-content .table-toolbar {
467
+ display: flex;
468
+ align-items: center;
469
+ gap: 2px;
470
+ justify-content: flex-end;
471
+ padding: 2px 0;
472
+ opacity: 0;
473
+ transition: opacity 0.15s;
474
+ z-index: 2;
475
+ }
476
+
477
+ .markdown-content .table-outer:hover .table-toolbar {
478
+ opacity: 1;
479
+ }
480
+
481
+ .markdown-content .table-toolbar-btn {
482
+ display: flex;
483
+ align-items: center;
484
+ justify-content: center;
485
+ width: 26px;
486
+ height: 26px;
487
+ border: 1px solid var(--color-border);
488
+ border-radius: 4px;
489
+ background: var(--color-bg-secondary);
490
+ color: var(--color-text-tertiary);
491
+ cursor: pointer;
492
+ transition: all 0.15s;
493
+ position: relative;
494
+ }
495
+
496
+ .markdown-content .table-toolbar-btn:hover {
497
+ color: var(--color-accent);
498
+ background: var(--color-bg);
499
+ border-color: var(--color-accent);
500
+ }
501
+
502
+ .markdown-content .table-toolbar-btn.active {
503
+ color: var(--color-accent);
504
+ background: var(--color-accent-bg);
505
+ border-color: var(--color-accent);
506
+ }
507
+
508
+ /* 工具栏按钮 tooltip */
509
+ .markdown-content .table-toolbar-btn[data-tooltip]:hover::after {
510
+ content: attr(data-tooltip);
511
+ position: absolute;
512
+ top: calc(100% + 6px);
513
+ left: 50%;
514
+ transform: translateX(-50%);
515
+ padding: 4px 8px;
516
+ background: #1f2328;
517
+ color: #fff;
518
+ font-size: 11px;
519
+ border-radius: 4px;
520
+ white-space: nowrap;
521
+ pointer-events: none;
522
+ z-index: 10;
523
+ }
524
+
525
+ .markdown-content .table-toolbar-btn[data-tooltip]:hover::before {
526
+ content: '';
527
+ position: absolute;
528
+ top: calc(100% + 2px);
529
+ left: 50%;
530
+ transform: translateX(-50%);
531
+ border: 4px solid transparent;
532
+ border-bottom-color: #1f2328;
533
+ pointer-events: none;
534
+ z-index: 10;
535
+ }
536
+
537
+ /* 表格滚动容器 */
392
538
  .markdown-content .table-wrapper {
393
539
  width: 100%;
540
+ -webkit-overflow-scrolling: touch;
541
+ }
542
+
543
+ /* 横向滚动模式 */
544
+ .markdown-content .table-wrapper-scroll {
394
545
  overflow-x: auto;
395
- margin-bottom: 16px;
546
+ }
547
+
548
+ /* 固定宽度模式:不允许横向滚动 */
549
+ .markdown-content .table-wrapper-fixed {
550
+ overflow-x: hidden;
551
+ }
552
+
553
+ /* 固定宽度模式下单元格强制换行,防止内容溢出导致右边框丢失 */
554
+ .markdown-content .table-wrapper-fixed table td,
555
+ .markdown-content .table-wrapper-fixed table th {
556
+ word-break: break-all;
557
+ overflow-wrap: break-word;
558
+ }
559
+
560
+ /* 固定高度模式:500px + 竖向滚动 */
561
+ .markdown-content .table-wrapper-fixed-height {
562
+ max-height: 500px;
563
+ overflow-y: auto;
564
+ }
565
+
566
+ /* 适应高度模式:无高度限制 */
567
+ .markdown-content .table-wrapper-auto-height {
568
+ max-height: none;
569
+ overflow-y: visible;
396
570
  }
397
571
 
398
572
  .markdown-content table {
399
- width: 100%;
400
573
  border-collapse: collapse;
401
574
  border-spacing: 0;
402
575
  }
403
576
 
577
+ /* 固定宽度:撑满容器 */
578
+ .markdown-content table.table-fit {
579
+ width: 100%;
580
+ }
581
+
582
+ /* 横向滚动:按内容撑开 */
583
+ .markdown-content table.table-scroll {
584
+ width: max-content;
585
+ min-width: 100%;
586
+ }
587
+
588
+ /* 固定高度模式下表头吸顶 */
589
+ .markdown-content .table-wrapper-fixed-height table th {
590
+ position: sticky;
591
+ top: 0;
592
+ z-index: 1;
593
+ background: var(--color-table-header-bg);
594
+ }
595
+
404
596
  .markdown-content table th,
405
597
  .markdown-content table td {
406
598
  border: 1px solid var(--color-border);
@@ -410,6 +602,7 @@ body {
410
602
  .markdown-content table th {
411
603
  background: var(--color-table-header-bg);
412
604
  font-weight: 600;
605
+ white-space: nowrap;
413
606
  }
414
607
 
415
608
  .markdown-content table tr:nth-child(2n) {
@@ -424,6 +617,124 @@ body {
424
617
  background: var(--color-table-row-alt);
425
618
  }
426
619
 
620
+ /* 表格全屏弹框 */
621
+ .table-fullscreen-overlay {
622
+ position: fixed;
623
+ inset: 0;
624
+ background: rgba(0, 0, 0, 0.6);
625
+ z-index: 9999;
626
+ display: flex;
627
+ align-items: center;
628
+ justify-content: center;
629
+ padding: 24px;
630
+ }
631
+
632
+ .table-fullscreen-dialog {
633
+ position: relative;
634
+ display: flex;
635
+ flex-direction: column;
636
+ max-width: 95vw;
637
+ max-height: 90vh;
638
+ background: var(--color-bg);
639
+ border-radius: 8px;
640
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
641
+ overflow: hidden;
642
+ }
643
+
644
+ /* 全屏模式 */
645
+ .table-fullscreen-dialog.is-maximized {
646
+ max-width: 100vw;
647
+ max-height: 100vh;
648
+ width: 100vw;
649
+ height: 100vh;
650
+ border-radius: 0;
651
+ }
652
+
653
+ .table-fullscreen-header {
654
+ display: flex;
655
+ align-items: center;
656
+ justify-content: space-between;
657
+ padding: 8px 16px;
658
+ border-bottom: 1px solid var(--color-border);
659
+ background: var(--color-bg-secondary);
660
+ flex-shrink: 0;
661
+ }
662
+
663
+ .table-fullscreen-title {
664
+ font-size: 13px;
665
+ font-weight: 500;
666
+ color: var(--color-text-secondary);
667
+ }
668
+
669
+ .table-fullscreen-actions {
670
+ display: flex;
671
+ align-items: center;
672
+ gap: 4px;
673
+ }
674
+
675
+ .table-fullscreen-action-btn {
676
+ display: flex;
677
+ align-items: center;
678
+ justify-content: center;
679
+ width: 28px;
680
+ height: 28px;
681
+ border: none;
682
+ border-radius: 4px;
683
+ background: transparent;
684
+ color: var(--color-text-tertiary);
685
+ cursor: pointer;
686
+ transition: all 0.15s;
687
+ }
688
+
689
+ .table-fullscreen-action-btn:hover {
690
+ background: var(--color-bg-tertiary);
691
+ color: var(--color-text);
692
+ }
693
+
694
+ .table-fullscreen-body {
695
+ flex: 1;
696
+ overflow: auto;
697
+ padding: 0;
698
+ }
699
+
700
+ .table-fullscreen-body table {
701
+ width: max-content;
702
+ min-width: 100%;
703
+ border-collapse: separate;
704
+ border-spacing: 0;
705
+ }
706
+
707
+ .table-fullscreen-body table th,
708
+ .table-fullscreen-body table td {
709
+ border: 1px solid var(--color-border);
710
+ border-top: none;
711
+ border-left: none;
712
+ padding: 8px 16px;
713
+ }
714
+
715
+ .table-fullscreen-body table th:first-child,
716
+ .table-fullscreen-body table td:first-child {
717
+ border-left: 1px solid var(--color-border);
718
+ }
719
+
720
+ .table-fullscreen-body table th {
721
+ background: var(--color-table-header-bg);
722
+ font-weight: 600;
723
+ white-space: nowrap;
724
+ position: sticky;
725
+ top: 0;
726
+ z-index: 1;
727
+ border-top: none;
728
+ }
729
+
730
+ .table-fullscreen-body table tr:nth-child(2n) {
731
+ background: transparent;
732
+ }
733
+
734
+ .table-fullscreen-body table tr:hover {
735
+ background: var(--color-table-row-alt);
736
+ }
737
+
427
738
  .markdown-content blockquote {
428
739
  border-left: 3px solid var(--color-blockquote-border);
429
740
  padding: 8px 16px;
@@ -440,8 +751,102 @@ body {
440
751
  margin: 4px 0;
441
752
  }
442
753
 
754
+ /* 图片容器(含复制按钮) */
755
+ .markdown-content .image-container {
756
+ position: relative;
757
+ display: inline-block;
758
+ max-width: 100%;
759
+ }
760
+
761
+ .markdown-content .image-container img {
762
+ display: block;
763
+ min-width: 64px;
764
+ min-height: 64px;
765
+ object-fit: contain;
766
+ }
767
+
768
+ .markdown-content .image-copy-btn {
769
+ position: absolute;
770
+ top: 4px;
771
+ right: 4px;
772
+ display: flex;
773
+ align-items: center;
774
+ justify-content: center;
775
+ width: 24px;
776
+ height: 24px;
777
+ border: none;
778
+ border-radius: 4px;
779
+ background: rgba(255, 255, 255, 0.85);
780
+ color: #4a5568;
781
+ cursor: pointer;
782
+ opacity: 0;
783
+ transition: opacity 0.15s, background 0.15s, color 0.15s;
784
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
785
+ z-index: 2;
786
+ }
787
+
788
+ .markdown-content .image-container:hover .image-copy-btn {
789
+ opacity: 1;
790
+ }
791
+
792
+ .markdown-content .image-copy-btn:hover {
793
+ background: #fff;
794
+ color: #2d3748;
795
+ }
796
+
797
+ .markdown-content .image-copy-btn.copied {
798
+ color: #38a169;
799
+ background: #f0fff4;
800
+ }
801
+
802
+ /* 复制提示气泡 */
803
+ .markdown-content .copy-tip {
804
+ position: absolute;
805
+ top: 8px;
806
+ right: 40px;
807
+ font-size: 12px;
808
+ font-weight: 500;
809
+ white-space: nowrap;
810
+ padding: 4px 10px;
811
+ border-radius: 6px;
812
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
813
+ z-index: 3;
814
+ animation: copyTipIn 0.15s ease-out;
815
+ pointer-events: none;
816
+ }
817
+
818
+ .markdown-content .copy-tip-ok {
819
+ background: #f0fff4;
820
+ color: #276749;
821
+ border: 1px solid #c6f6d5;
822
+ }
823
+
824
+ .markdown-content .copy-tip-fail {
825
+ background: #fff5f5;
826
+ color: #9b2c2c;
827
+ border: 1px solid #fed7d7;
828
+ }
829
+
830
+ @keyframes copyTipIn {
831
+ from { opacity: 0; transform: translateX(4px); }
832
+ to { opacity: 1; transform: translateX(0); }
833
+ }
834
+
835
+ /* Mermaid 图表复制按钮 */
836
+ .markdown-content .mermaid .mermaid-copy-btn {
837
+ position: absolute;
838
+ top: 8px;
839
+ right: 8px;
840
+ opacity: 0;
841
+ }
842
+
843
+ .markdown-content .mermaid:hover .mermaid-copy-btn {
844
+ opacity: 1;
845
+ }
846
+
443
847
  /* Mermaid */
444
848
  .markdown-content .mermaid {
849
+ position: relative;
445
850
  margin: 16px 0;
446
851
  text-align: center;
447
852
  }
@@ -469,12 +874,29 @@ body {
469
874
  border: 1px solid var(--color-pre-border);
470
875
  }
471
876
 
877
+ /* Frontmatter 代码块 */
878
+ .markdown-content .frontmatter-block {
879
+ border-left: 3px solid var(--color-primary, #5c6bc0);
880
+ margin-bottom: 20px;
881
+ }
882
+
883
+ .markdown-content .frontmatter-block .code-lang-label {
884
+ color: var(--color-primary, #5c6bc0);
885
+ font-weight: 600;
886
+ }
887
+
472
888
  .markdown-content .code-block-wrapper pre {
473
889
  margin: 0;
474
890
  border-radius: 0;
891
+ padding: 0;
475
892
  background: transparent;
476
893
  }
477
894
 
895
+ /* 代码块内 code 元素去掉 hljs 默认 padding,由 table cell 控制间距 */
896
+ .markdown-content .code-block-wrapper pre code.hljs {
897
+ padding: 0;
898
+ }
899
+
478
900
  /* header 常驻 */
479
901
  .markdown-content .code-block-header {
480
902
  display: flex;
@@ -569,31 +991,71 @@ body {
569
991
 
570
992
  /* 代码主体 */
571
993
  .code-block-body {
572
- display: flex;
573
994
  overflow-x: auto;
574
995
  }
575
996
 
576
- .line-numbers {
577
- flex-shrink: 0;
578
- padding: 16px 0;
579
- text-align: right;
997
+ /* 自动换行模式 */
998
+ .code-block-body.word-wrap-enabled {
999
+ overflow-x: hidden;
1000
+ }
1001
+
1002
+ .code-block-body.word-wrap-enabled code {
1003
+ white-space: pre-wrap;
1004
+ word-break: break-all;
1005
+ }
1006
+
1007
+ .code-block-body.word-wrap-enabled .hljs-ln-code {
1008
+ white-space: pre-wrap;
1009
+ word-break: break-all;
1010
+ }
1011
+
1012
+ /* highlightjs-line-numbers 插件样式 */
1013
+ .code-block-body .hljs-ln {
1014
+ border-collapse: collapse;
1015
+ width: 100%;
1016
+ padding: 0;
1017
+ }
1018
+
1019
+ /* 首行和末行留出上下间距 */
1020
+ .code-block-body .hljs-ln tr:first-child td {
1021
+ padding-top: 10px;
1022
+ }
1023
+ .code-block-body .hljs-ln tr:last-child td {
1024
+ padding-bottom: 10px;
1025
+ }
1026
+
1027
+ .code-block-body .hljs-ln td {
1028
+ border: none;
1029
+ }
1030
+
1031
+ /* 行号列 */
1032
+ .code-block-body td.hljs-ln-numbers {
1033
+ -webkit-user-select: none;
580
1034
  user-select: none;
1035
+ text-align: right;
1036
+ vertical-align: top;
1037
+ white-space: nowrap;
1038
+ width: 1%;
1039
+ min-width: 2em;
1040
+ padding: 0;
581
1041
  border-right: 1px solid var(--color-pre-border);
582
- background: transparent;
583
1042
  }
584
1043
 
585
- .line-numbers.hidden {
586
- display: none;
1044
+ /* 行号数字 */
1045
+ .code-block-body .hljs-ln-n {
1046
+ padding: 0 4px;
1047
+ color: var(--color-text-tertiary);
1048
+ opacity: 0.5;
1049
+ font-size: 12px;
1050
+ line-height: 1.45;
587
1051
  }
588
1052
 
589
- .line-numbers .line-num {
590
- display: block;
591
- padding: 0 12px;
592
- font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
593
- font-size: 12px;
1053
+ /* 代码列 */
1054
+ .code-block-body td.hljs-ln-code {
1055
+ padding: 0 0 0 10px;
1056
+ vertical-align: top;
1057
+ font-size: 13px;
594
1058
  line-height: 1.45;
595
- color: var(--color-text-tertiary);
596
- min-width: 2em;
597
1059
  }
598
1060
 
599
1061
  .code-block-body pre {
@@ -605,14 +1067,14 @@ body {
605
1067
  .code-block-body pre code {
606
1068
  font-size: 13px;
607
1069
  line-height: 1.45;
608
- padding: 16px;
1070
+ padding: 10px 8px;
609
1071
  display: block;
610
1072
  }
611
1073
 
612
1074
  .code-block-body .code-plain {
613
1075
  background: none;
614
1076
  color: var(--color-text);
615
- padding: 16px;
1077
+ padding: 12px;
616
1078
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
617
1079
  font-size: 13px;
618
1080
  line-height: 1.45;
@@ -654,9 +1116,9 @@ body {
654
1116
  align-items: center;
655
1117
  justify-content: center;
656
1118
  gap: 1px;
657
- background: var(--color-bg);
658
- color: var(--color-text-secondary);
659
- border: 1px solid var(--color-border);
1119
+ background: #fff;
1120
+ color: var(--color-accent);
1121
+ border: 1px solid var(--color-accent);
660
1122
  border-radius: 6px;
661
1123
  cursor: pointer;
662
1124
  box-shadow: 0 1px 3px var(--color-shadow);
@@ -665,9 +1127,9 @@ body {
665
1127
  }
666
1128
 
667
1129
  .back-to-top:hover {
668
- background: var(--color-bg-secondary);
669
- color: var(--color-text);
670
- border-color: var(--color-border);
1130
+ background: var(--color-accent);
1131
+ color: #fff;
1132
+ border-color: var(--color-accent);
671
1133
  }
672
1134
 
673
1135
  .progress-text {
@@ -703,6 +1165,11 @@ body {
703
1165
  justify-content: space-between;
704
1166
  padding: 0 12px 8px;
705
1167
  border-bottom: 1px solid var(--color-border);
1168
+ position: sticky;
1169
+ top: 0;
1170
+ background: var(--color-bg);
1171
+ z-index: 1;
1172
+ padding-top: 0;
706
1173
  }
707
1174
 
708
1175
  .toc-title {
@@ -716,6 +1183,31 @@ body {
716
1183
  letter-spacing: 0.02em;
717
1184
  }
718
1185
 
1186
+ .toc-header-actions {
1187
+ display: flex;
1188
+ align-items: center;
1189
+ gap: 2px;
1190
+ }
1191
+
1192
+ .toc-action-btn {
1193
+ display: flex;
1194
+ align-items: center;
1195
+ justify-content: center;
1196
+ width: 22px;
1197
+ height: 22px;
1198
+ border: 1px solid transparent;
1199
+ background: transparent;
1200
+ color: var(--color-text-tertiary);
1201
+ cursor: pointer;
1202
+ border-radius: 4px;
1203
+ transition: all 0.15s;
1204
+ }
1205
+
1206
+ .toc-action-btn:hover {
1207
+ background: var(--color-bg-tertiary);
1208
+ color: var(--color-text-secondary);
1209
+ }
1210
+
719
1211
  .toc-toggle {
720
1212
  display: flex;
721
1213
  align-items: center;
@@ -737,17 +1229,81 @@ body {
737
1229
 
738
1230
  .toc-nav {
739
1231
  padding: 8px 0;
1232
+ position: relative;
1233
+ }
1234
+
1235
+ /* 左侧连续竖线 */
1236
+ .toc-track {
1237
+ position: absolute;
1238
+ left: 0;
1239
+ top: 8px;
1240
+ bottom: 8px;
1241
+ width: 2px;
1242
+ background: var(--color-border-light);
1243
+ border-radius: 1px;
1244
+ }
1245
+
1246
+ /* marker 滑块 — 平滑过渡 */
1247
+ .toc-marker {
1248
+ position: absolute;
1249
+ left: 0;
1250
+ width: 2px;
1251
+ background: var(--color-accent);
1252
+ border-radius: 1px;
1253
+ transition: top 0.25s cubic-bezier(0.65, 0, 0.35, 1),
1254
+ height 0.25s cubic-bezier(0.65, 0, 0.35, 1),
1255
+ opacity 0.25s;
1256
+ z-index: 1;
740
1257
  }
741
1258
 
742
1259
  .toc-item {
743
- display: block;
1260
+ display: flex;
1261
+ align-items: center;
1262
+ justify-content: space-between;
744
1263
  padding: 3px 12px;
745
1264
  color: var(--color-text-secondary);
746
1265
  text-decoration: none;
747
1266
  font-size: 12px;
748
1267
  line-height: 1.5;
749
1268
  transition: all 0.1s;
750
- border-left: 2px solid transparent;
1269
+ }
1270
+
1271
+ .toc-item-text {
1272
+ flex: 1;
1273
+ min-width: 0;
1274
+ overflow: hidden;
1275
+ text-overflow: ellipsis;
1276
+ white-space: nowrap;
1277
+ }
1278
+
1279
+ .toc-fold-btn {
1280
+ display: flex;
1281
+ align-items: center;
1282
+ justify-content: center;
1283
+ width: 18px;
1284
+ height: 18px;
1285
+ flex-shrink: 0;
1286
+ border: none;
1287
+ background: transparent;
1288
+ color: var(--color-text-tertiary);
1289
+ cursor: pointer;
1290
+ border-radius: 3px;
1291
+ padding: 0;
1292
+ margin-left: 4px;
1293
+ transition: all 0.15s;
1294
+ }
1295
+
1296
+ .toc-fold-btn:hover {
1297
+ background: var(--color-bg-tertiary);
1298
+ color: var(--color-text-secondary);
1299
+ }
1300
+
1301
+ .toc-fold-icon {
1302
+ transition: transform 0.15s ease;
1303
+ }
1304
+
1305
+ .toc-fold-icon-open {
1306
+ transform: rotate(90deg);
751
1307
  }
752
1308
 
753
1309
  .toc-item:hover {
@@ -756,7 +1312,6 @@ body {
756
1312
 
757
1313
  .toc-item.active {
758
1314
  color: var(--color-accent);
759
- border-left-color: var(--color-accent);
760
1315
  font-weight: 500;
761
1316
  background: var(--color-accent-bg);
762
1317
  border-radius: 0 4px 4px 0;
@@ -772,6 +1327,8 @@ body {
772
1327
  .toc-item.toc-level-2 { padding-left: 20px; }
773
1328
  .toc-item.toc-level-3 { padding-left: 28px; font-size: 11px; }
774
1329
  .toc-item.toc-level-4 { padding-left: 36px; font-size: 11px; }
1330
+ .toc-item.toc-level-5 { padding-left: 44px; font-size: 11px; }
1331
+ .toc-item.toc-level-6 { padding-left: 52px; font-size: 11px; }
775
1332
 
776
1333
  /* ===== 拖拽条 ===== */
777
1334
  .resizer {
@@ -1054,7 +1611,7 @@ body {
1054
1611
 
1055
1612
  @media (max-width: 768px) {
1056
1613
  .markdown-content {
1057
- padding: 16px;
1614
+ padding: 16px 20px;
1058
1615
  width: 100%;
1059
1616
  }
1060
1617
  .back-to-top {
@@ -1094,7 +1651,7 @@ body {
1094
1651
  .top-bar-actions {
1095
1652
  display: flex;
1096
1653
  align-items: center;
1097
- gap: 4px;
1654
+ gap: 8px;
1098
1655
  flex-shrink: 0;
1099
1656
  }
1100
1657
 
@@ -1118,6 +1675,62 @@ body {
1118
1675
  color: var(--color-text);
1119
1676
  }
1120
1677
 
1678
+ /* GitHub 链接 - 低调融入 */
1679
+ .top-bar-divider {
1680
+ width: 1px;
1681
+ height: 18px;
1682
+ background: var(--color-border);
1683
+ flex-shrink: 0;
1684
+ }
1685
+
1686
+ .top-bar-github {
1687
+ display: flex;
1688
+ align-items: center;
1689
+ justify-content: center;
1690
+ width: 28px;
1691
+ height: 28px;
1692
+ color: var(--color-text-tertiary);
1693
+ cursor: pointer;
1694
+ border-radius: 6px;
1695
+ transition: all 0.15s;
1696
+ text-decoration: none;
1697
+ border: none;
1698
+ background: transparent;
1699
+ }
1700
+
1701
+ .top-bar-github:hover {
1702
+ color: var(--color-text-secondary);
1703
+ background: var(--color-bg-tertiary);
1704
+ }
1705
+
1706
+ /* 导出 Word 按钮 */
1707
+ .top-bar-actions .export-word-btn {
1708
+ display: inline-flex;
1709
+ align-items: center;
1710
+ gap: 5px;
1711
+ padding: 5px 12px;
1712
+ font-size: 12px;
1713
+ color: var(--color-text-secondary);
1714
+ background: transparent;
1715
+ border: 1px solid var(--color-border);
1716
+ border-radius: 5px;
1717
+ cursor: pointer;
1718
+ transition: all 0.15s;
1719
+ white-space: nowrap;
1720
+ font-family: inherit;
1721
+ }
1722
+
1723
+ .top-bar-actions .export-word-btn:hover {
1724
+ color: var(--color-accent);
1725
+ border-color: var(--color-accent);
1726
+ background: var(--color-accent-bg);
1727
+ }
1728
+
1729
+ .top-bar-actions .export-word-btn:disabled {
1730
+ opacity: 0.5;
1731
+ cursor: not-allowed;
1732
+ }
1733
+
1121
1734
  /* ===== 主体区域 ===== */
1122
1735
  .main-body {
1123
1736
  display: flex;
@@ -1367,3 +1980,1770 @@ body {
1367
1980
  max-width: 100%;
1368
1981
  }
1369
1982
  }
1983
+
1984
+ /* ===== 查看/编辑模式切换 ===== */
1985
+ .mode-switch {
1986
+ display: flex;
1987
+ align-items: center;
1988
+ background: var(--color-bg-secondary);
1989
+ border: 1px solid var(--color-border);
1990
+ border-radius: 6px;
1991
+ padding: 2px;
1992
+ gap: 2px;
1993
+ }
1994
+
1995
+ .mode-switch-btn {
1996
+ display: flex;
1997
+ align-items: center;
1998
+ gap: 4px;
1999
+ padding: 4px 10px;
2000
+ border: none;
2001
+ background: transparent;
2002
+ color: var(--color-text-tertiary);
2003
+ cursor: pointer;
2004
+ border-radius: 4px;
2005
+ font-size: 12px;
2006
+ font-family: inherit;
2007
+ transition: all 0.15s;
2008
+ white-space: nowrap;
2009
+ }
2010
+
2011
+ .mode-switch-btn:hover {
2012
+ color: var(--color-text-secondary);
2013
+ }
2014
+
2015
+ /* 查看模式激活 */
2016
+ .mode-switch-btn.active {
2017
+ background: var(--color-bg);
2018
+ color: var(--color-accent);
2019
+ box-shadow: 0 1px 2px var(--color-shadow);
2020
+ font-weight: 500;
2021
+ }
2022
+
2023
+ /* 编辑模式激活:红色 */
2024
+ .mode-switch-btn.active.mode-edit {
2025
+ color: #ef4444;
2026
+ background: #fef2f2;
2027
+ box-shadow: 0 1px 2px rgba(239, 68, 68, 0.12);
2028
+ }
2029
+
2030
+ /* 编辑模式指示条:固定在内容区顶部 */
2031
+ .editor-content::before {
2032
+ content: '';
2033
+ display: block;
2034
+ height: 2px;
2035
+ background: linear-gradient(90deg, #ef4444, #f87171);
2036
+ flex-shrink: 0;
2037
+ position: sticky;
2038
+ top: 0;
2039
+ z-index: 20;
2040
+ }
2041
+
2042
+ /* ===== 编辑器工具栏 ===== */
2043
+ .editor-toolbar {
2044
+ display: flex;
2045
+ align-items: center;
2046
+ gap: 4px;
2047
+ padding: 6px 12px;
2048
+ background: var(--color-bg);
2049
+ border-bottom: 1px solid var(--color-border-light);
2050
+ flex-wrap: wrap;
2051
+ position: sticky;
2052
+ top: 0;
2053
+ z-index: 10;
2054
+ }
2055
+
2056
+ .editor-toolbar-group {
2057
+ display: flex;
2058
+ align-items: center;
2059
+ gap: 2px;
2060
+ }
2061
+
2062
+ .editor-toolbar-divider {
2063
+ width: 1px;
2064
+ height: 20px;
2065
+ background: var(--color-border);
2066
+ margin: 0 4px;
2067
+ }
2068
+
2069
+ .editor-toolbar-btn {
2070
+ display: flex;
2071
+ align-items: center;
2072
+ justify-content: center;
2073
+ width: 28px;
2074
+ height: 28px;
2075
+ border: 1px solid transparent;
2076
+ background: transparent;
2077
+ color: var(--color-text-secondary);
2078
+ cursor: pointer;
2079
+ border-radius: 4px;
2080
+ transition: all 0.15s;
2081
+ padding: 0;
2082
+ }
2083
+
2084
+ .editor-toolbar-btn:hover {
2085
+ background: var(--color-bg-tertiary);
2086
+ color: var(--color-text);
2087
+ }
2088
+
2089
+ .editor-toolbar-btn.active {
2090
+ background: var(--color-accent-bg);
2091
+ color: var(--color-accent);
2092
+ border-color: var(--color-accent);
2093
+ }
2094
+
2095
+ .editor-toolbar-btn:disabled {
2096
+ opacity: 0.3;
2097
+ cursor: not-allowed;
2098
+ }
2099
+
2100
+ .editor-toolbar-btn.heading-btn {
2101
+ font-size: 11px;
2102
+ font-weight: 700;
2103
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
2104
+ width: auto;
2105
+ padding: 0 6px;
2106
+ }
2107
+
2108
+ .editor-toolbar-spacer {
2109
+ flex: 1;
2110
+ }
2111
+
2112
+ .editor-toolbar-save {
2113
+ display: flex;
2114
+ align-items: center;
2115
+ gap: 4px;
2116
+ padding: 4px 12px;
2117
+ border: 1px solid var(--color-accent);
2118
+ background: var(--color-accent);
2119
+ color: #fff;
2120
+ cursor: pointer;
2121
+ border-radius: 4px;
2122
+ font-size: 12px;
2123
+ font-family: inherit;
2124
+ font-weight: 500;
2125
+ transition: all 0.15s;
2126
+ }
2127
+
2128
+ .editor-toolbar-save:hover {
2129
+ background: var(--color-accent-hover);
2130
+ border-color: var(--color-accent-hover);
2131
+ }
2132
+
2133
+ /* ===== Frontmatter 编辑器代码块 ===== */
2134
+ .frontmatter-editor-block {
2135
+ margin: 0 auto 8px;
2136
+ max-width: 100%;
2137
+ }
2138
+
2139
+ .frontmatter-edit-body {
2140
+ padding: 0 !important;
2141
+ }
2142
+
2143
+ .frontmatter-edit-body pre {
2144
+ margin: 0;
2145
+ padding: 0;
2146
+ }
2147
+
2148
+ /* 行号 + textarea flex 布局 */
2149
+ .fm-edit-layout {
2150
+ display: flex;
2151
+ }
2152
+
2153
+ /* Frontmatter 行号列:复用代码块行号样式 */
2154
+ .fm-line-gutter {
2155
+ display: flex;
2156
+ flex-direction: column;
2157
+ flex-shrink: 0;
2158
+ min-width: 2em;
2159
+ padding: 10px 0;
2160
+ border-right: 1px solid var(--color-pre-border);
2161
+ user-select: none;
2162
+ -webkit-user-select: none;
2163
+ text-align: right;
2164
+ }
2165
+
2166
+ .fm-line-gutter .code-ln-num {
2167
+ padding: 0 4px;
2168
+ color: var(--color-text-tertiary);
2169
+ opacity: 0.5;
2170
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
2171
+ font-size: 12px;
2172
+ line-height: 1.45;
2173
+ }
2174
+
2175
+ .frontmatter-textarea {
2176
+ flex: 1;
2177
+ min-width: 0;
2178
+ display: block;
2179
+ border: none;
2180
+ outline: none;
2181
+ background: transparent;
2182
+ color: var(--color-pre-text);
2183
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
2184
+ font-size: 13px;
2185
+ line-height: 1.45;
2186
+ padding: 10px 10px;
2187
+ resize: none;
2188
+ overflow: hidden;
2189
+ tab-size: 2;
2190
+ white-space: pre;
2191
+ }
2192
+
2193
+ .frontmatter-textarea::placeholder {
2194
+ color: var(--color-text-tertiary);
2195
+ }
2196
+
2197
+ /* ===== Tiptap 编辑器样式 ===== */
2198
+ .editor-area .tiptap {
2199
+ outline: none;
2200
+ min-height: 400px;
2201
+ }
2202
+
2203
+ .editor-area .tiptap p.is-editor-empty:first-child::before {
2204
+ content: attr(data-placeholder);
2205
+ float: left;
2206
+ color: var(--color-text-tertiary);
2207
+ pointer-events: none;
2208
+ height: 0;
2209
+ }
2210
+
2211
+ /* Tiptap 表格样式 */
2212
+ .editor-area .tiptap table:not(.hljs-ln) {
2213
+ border-collapse: collapse;
2214
+ width: 100%;
2215
+ margin-bottom: 12px;
2216
+ }
2217
+
2218
+ .editor-area .tiptap table:not(.hljs-ln) td,
2219
+ .editor-area .tiptap table:not(.hljs-ln) th {
2220
+ border: 1px solid var(--color-border);
2221
+ padding: 6px 13px;
2222
+ min-width: 80px;
2223
+ position: relative;
2224
+ vertical-align: top;
2225
+ }
2226
+
2227
+ .editor-area .tiptap table:not(.hljs-ln) th {
2228
+ background: var(--color-table-header-bg);
2229
+ font-weight: 600;
2230
+ }
2231
+
2232
+ .editor-area .tiptap table:not(.hljs-ln) .selectedCell {
2233
+ background: var(--color-accent-bg);
2234
+ }
2235
+
2236
+ /* 行/列删除按钮 hover 时的高亮 overlay */
2237
+ .tc-highlight-overlay {
2238
+ background: rgba(255, 59, 48, 0.10);
2239
+ border: 1px solid rgba(255, 59, 48, 0.22);
2240
+ border-radius: 2px;
2241
+ transition: opacity 0.12s ease;
2242
+ }
2243
+
2244
+ /* 行/列选择条 → Excel 风格行号列头 */
2245
+ .tc-row-header,
2246
+ .tc-col-header {
2247
+ position: absolute;
2248
+ pointer-events: auto;
2249
+ cursor: pointer;
2250
+ display: flex;
2251
+ align-items: center;
2252
+ justify-content: center;
2253
+ background: var(--color-bg-secondary, #f5f5f5);
2254
+ border: 1px solid var(--color-border);
2255
+ color: var(--color-text-tertiary);
2256
+ font-size: 11px;
2257
+ font-weight: 500;
2258
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
2259
+ user-select: none;
2260
+ -webkit-user-select: none;
2261
+ z-index: 16;
2262
+ transition: background 0.12s, color 0.12s;
2263
+ }
2264
+
2265
+ .tc-row-header:hover,
2266
+ .tc-col-header:hover,
2267
+ .tc-row-header.tc-header-hover,
2268
+ .tc-col-header.tc-header-hover {
2269
+ background: var(--color-accent-bg, #e0f2fe);
2270
+ color: var(--color-accent, #4ade80);
2271
+ }
2272
+
2273
+ /* 左上角全选角标 */
2274
+ .tc-corner-btn {
2275
+ position: absolute;
2276
+ pointer-events: auto;
2277
+ cursor: pointer;
2278
+ display: flex;
2279
+ align-items: center;
2280
+ justify-content: center;
2281
+ background: var(--color-bg-secondary, #f5f5f5);
2282
+ border: 1px solid var(--color-border);
2283
+ z-index: 17;
2284
+ transition: background 0.12s;
2285
+ overflow: hidden;
2286
+ }
2287
+
2288
+ .tc-corner-btn:hover {
2289
+ background: var(--color-accent-bg, #e0f2fe);
2290
+ }
2291
+
2292
+ /* 左上角小三角指示器 */
2293
+ .tc-corner-triangle {
2294
+ position: absolute;
2295
+ right: 2px;
2296
+ bottom: 2px;
2297
+ width: 0;
2298
+ height: 0;
2299
+ border-style: solid;
2300
+ border-width: 0 0 6px 6px;
2301
+ border-color: transparent transparent var(--color-text-tertiary) transparent;
2302
+ transition: border-color 0.12s;
2303
+ }
2304
+
2305
+ .tc-corner-btn:hover .tc-corner-triangle {
2306
+ border-color: transparent transparent var(--color-accent, #4ade80) transparent;
2307
+ }
2308
+
2309
+ /* 列宽拖拽手柄 */
2310
+ .editor-area .tiptap .column-resize-handle {
2311
+ position: absolute;
2312
+ right: -2px;
2313
+ top: 0;
2314
+ bottom: 0;
2315
+ width: 4px;
2316
+ background: var(--color-accent);
2317
+ cursor: col-resize;
2318
+ z-index: 20;
2319
+ pointer-events: auto;
2320
+ }
2321
+
2322
+ .editor-area .tiptap.resize-cursor {
2323
+ cursor: col-resize;
2324
+ }
2325
+
2326
+ /* tableWrapper 由 tiptap table 扩展自动生成 */
2327
+ .editor-area .tiptap .tableWrapper {
2328
+ overflow: visible;
2329
+ margin-bottom: 12px;
2330
+ padding-left: 52px;
2331
+ padding-top: 52px;
2332
+ position: relative;
2333
+ }
2334
+
2335
+ /* Tiptap 任务列表 */
2336
+ .editor-area .tiptap ul[data-type="taskList"] {
2337
+ list-style: none;
2338
+ padding-left: 0;
2339
+ }
2340
+
2341
+ .editor-area .tiptap ul[data-type="taskList"] li {
2342
+ display: flex;
2343
+ align-items: flex-start;
2344
+ gap: 8px;
2345
+ }
2346
+
2347
+ .editor-area .tiptap ul[data-type="taskList"] li label {
2348
+ flex-shrink: 0;
2349
+ margin-top: 3px;
2350
+ }
2351
+
2352
+ .editor-area .tiptap ul[data-type="taskList"] li > div {
2353
+ flex: 1;
2354
+ }
2355
+
2356
+ /* Tiptap 代码块 — 使用自定义 NodeView,复用查看模式的 .code-block-wrapper 样式 */
2357
+ .editor-area .tiptap .editor-code-block {
2358
+ margin-bottom: 12px;
2359
+ }
2360
+
2361
+ /* NodeView 内部的 pre/code 重置 */
2362
+ .editor-area .tiptap .editor-code-block pre {
2363
+ background: transparent;
2364
+ border: none;
2365
+ border-radius: 0;
2366
+ padding: 0;
2367
+ margin: 0;
2368
+ }
2369
+
2370
+ /* 行号 + 编辑区 flex 布局 */
2371
+ .editor-area .tiptap .code-edit-layout {
2372
+ display: flex;
2373
+ }
2374
+
2375
+ /* 行号列:与查看模式 .hljs-ln-numbers 视觉一致 */
2376
+ .editor-area .tiptap .code-line-gutter {
2377
+ display: flex;
2378
+ flex-direction: column;
2379
+ flex-shrink: 0;
2380
+ min-width: 2em;
2381
+ padding: 10px 0;
2382
+ border-right: 1px solid var(--color-pre-border);
2383
+ user-select: none;
2384
+ -webkit-user-select: none;
2385
+ text-align: right;
2386
+ }
2387
+
2388
+ .editor-area .tiptap .code-ln-num {
2389
+ padding: 0 4px;
2390
+ color: var(--color-text-tertiary);
2391
+ opacity: 0.5;
2392
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
2393
+ font-size: 12px;
2394
+ line-height: 1.45;
2395
+ }
2396
+
2397
+ /* 编辑区 */
2398
+ .editor-area .tiptap .code-edit-area {
2399
+ flex: 1;
2400
+ min-width: 0;
2401
+ overflow-x: auto;
2402
+ }
2403
+
2404
+ .editor-area .tiptap .code-edit-area code {
2405
+ background: none;
2406
+ color: var(--color-pre-text);
2407
+ padding: 10px 10px;
2408
+ font-size: 13px;
2409
+ line-height: 1.45;
2410
+ display: block;
2411
+ outline: none;
2412
+ white-space: pre-wrap;
2413
+ word-break: break-all;
2414
+ }
2415
+
2416
+ /* 语言输入框 */
2417
+ .code-lang-input {
2418
+ background: transparent;
2419
+ border: none;
2420
+ outline: none;
2421
+ color: var(--color-text-tertiary);
2422
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
2423
+ font-size: 11px;
2424
+ font-weight: 500;
2425
+ letter-spacing: 0.04em;
2426
+ text-transform: uppercase;
2427
+ width: 80px;
2428
+ padding: 0;
2429
+ }
2430
+
2431
+ /* Tiptap 图片 */
2432
+ .editor-area .tiptap img {
2433
+ max-width: 100%;
2434
+ height: auto;
2435
+ border-radius: 6px;
2436
+ cursor: pointer;
2437
+ }
2438
+
2439
+ .editor-area .tiptap img.ProseMirror-selectednode {
2440
+ outline: 2px solid var(--color-accent);
2441
+ outline-offset: 2px;
2442
+ }
2443
+
2444
+ /* ===== 表格控件层样式 ===== */
2445
+ .table-controls-layer {
2446
+ pointer-events: none;
2447
+ }
2448
+
2449
+ .table-controls-layer .tc-btn {
2450
+ position: absolute;
2451
+ pointer-events: auto;
2452
+ display: flex;
2453
+ align-items: center;
2454
+ justify-content: center;
2455
+ width: 20px;
2456
+ height: 20px;
2457
+ border: 1px solid var(--color-border);
2458
+ border-radius: 4px;
2459
+ background: var(--color-bg);
2460
+ color: var(--color-text-tertiary);
2461
+ cursor: pointer;
2462
+ opacity: 0;
2463
+ transition: opacity 0.12s, background 0.1s, color 0.1s;
2464
+ padding: 0;
2465
+ z-index: 16;
2466
+ }
2467
+
2468
+ /* 按需显示:只有带 tc-visible 的按钮才可见 */
2469
+ .table-controls-layer .tc-btn.tc-visible {
2470
+ opacity: 1;
2471
+ }
2472
+
2473
+ /* 删除按钮 hover 变红 */
2474
+ .table-controls-layer .tc-del-table:hover,
2475
+ .table-controls-layer .tc-del-col:hover,
2476
+ .table-controls-layer .tc-del-row:hover {
2477
+ background: var(--color-error-bg, #fef2f2);
2478
+ border-color: var(--color-error-text, #ef4444);
2479
+ color: var(--color-error-text, #ef4444);
2480
+ }
2481
+
2482
+ /* 添加按钮样式 */
2483
+ .table-controls-layer .tc-add-col,
2484
+ .table-controls-layer .tc-add-row {
2485
+ width: 20px;
2486
+ height: 20px;
2487
+ border-radius: 50%;
2488
+ border: 1px dashed var(--color-border);
2489
+ }
2490
+
2491
+ .table-controls-layer .tc-add-col:hover,
2492
+ .table-controls-layer .tc-add-row:hover {
2493
+ background: var(--color-accent-bg);
2494
+ border-color: var(--color-accent);
2495
+ color: var(--color-accent);
2496
+ border-style: solid;
2497
+ }
2498
+
2499
+ /* ===== 选中单元格后的浮动操作菜单 ===== */
2500
+ .tc-selection-menu {
2501
+ background: var(--color-bg);
2502
+ border: 1px solid var(--color-border);
2503
+ border-radius: 8px;
2504
+ box-shadow: 0 4px 16px var(--color-shadow);
2505
+ padding: 4px;
2506
+ min-width: 140px;
2507
+ pointer-events: auto;
2508
+ }
2509
+
2510
+ .tc-menu-btn {
2511
+ display: block;
2512
+ width: 100%;
2513
+ text-align: left;
2514
+ padding: 6px 12px;
2515
+ border: none;
2516
+ background: transparent;
2517
+ color: var(--color-text);
2518
+ cursor: pointer;
2519
+ border-radius: 4px;
2520
+ font-size: 13px;
2521
+ font-family: inherit;
2522
+ line-height: 1.4;
2523
+ transition: background 0.1s;
2524
+ white-space: nowrap;
2525
+ }
2526
+
2527
+ .tc-menu-btn:hover {
2528
+ background: var(--color-bg-tertiary);
2529
+ }
2530
+
2531
+ .tc-menu-btn.danger {
2532
+ color: var(--color-error-text, #ef4444);
2533
+ }
2534
+
2535
+ .tc-menu-btn.danger:hover {
2536
+ background: var(--color-error-bg, #fef2f2);
2537
+ }
2538
+
2539
+ .tc-menu-sep {
2540
+ height: 1px;
2541
+ background: var(--color-border);
2542
+ margin: 4px 0;
2543
+ }
2544
+
2545
+ /* ===== 表格右键上下文菜单 ===== */
2546
+ .tc-context-menu {
2547
+ background: var(--color-bg);
2548
+ border: 1px solid var(--color-border);
2549
+ border-radius: 8px;
2550
+ box-shadow: 0 4px 16px var(--color-shadow);
2551
+ padding: 4px;
2552
+ min-width: 150px;
2553
+ pointer-events: auto;
2554
+ }
2555
+
2556
+ .tc-context-menu .tc-menu-btn.disabled {
2557
+ opacity: 0.35;
2558
+ cursor: not-allowed;
2559
+ }
2560
+
2561
+ .tc-context-menu .tc-menu-btn.disabled:hover {
2562
+ background: transparent;
2563
+ }
2564
+
2565
+ /* 表格行列选择器 */
2566
+ .table-picker-wrapper {
2567
+ position: relative;
2568
+ }
2569
+
2570
+ .table-picker-dropdown {
2571
+ position: absolute;
2572
+ top: 100%;
2573
+ left: 50%;
2574
+ transform: translateX(-50%);
2575
+ margin-top: 6px;
2576
+ padding: 8px;
2577
+ background: var(--color-bg);
2578
+ border: 1px solid var(--color-border);
2579
+ border-radius: 8px;
2580
+ box-shadow: 0 4px 16px var(--color-shadow);
2581
+ z-index: 100;
2582
+ }
2583
+
2584
+ .table-picker-label {
2585
+ text-align: center;
2586
+ font-size: 12px;
2587
+ color: var(--color-text-secondary);
2588
+ margin-bottom: 6px;
2589
+ font-variant-numeric: tabular-nums;
2590
+ }
2591
+
2592
+ .table-picker-grid {
2593
+ display: flex;
2594
+ flex-direction: column;
2595
+ gap: 3px;
2596
+ }
2597
+
2598
+ .table-picker-row {
2599
+ display: flex;
2600
+ gap: 3px;
2601
+ }
2602
+
2603
+ .table-picker-cell {
2604
+ width: 18px;
2605
+ height: 18px;
2606
+ border: 1px solid var(--color-border);
2607
+ border-radius: 2px;
2608
+ cursor: pointer;
2609
+ transition: all 0.08s;
2610
+ background: var(--color-bg);
2611
+ }
2612
+
2613
+ .table-picker-cell.active {
2614
+ background: var(--color-accent-bg);
2615
+ border-color: var(--color-accent);
2616
+ }
2617
+
2618
+ .table-picker-cell:hover {
2619
+ border-color: var(--color-accent);
2620
+ }
2621
+
2622
+ /* ===== Mermaid 编辑器节点样式 ===== */
2623
+ .mermaid-block-wrapper {
2624
+ margin: 16px 0;
2625
+ }
2626
+
2627
+ .mermaid-preview {
2628
+ position: relative;
2629
+ border: 1px solid var(--color-border);
2630
+ border-radius: 8px;
2631
+ padding: 20px;
2632
+ background: var(--color-bg);
2633
+ text-align: center;
2634
+ }
2635
+
2636
+ .mermaid-preview:hover .mermaid-edit-btn {
2637
+ opacity: 1;
2638
+ }
2639
+
2640
+ .mermaid-edit-btn {
2641
+ position: absolute;
2642
+ top: 8px;
2643
+ right: 8px;
2644
+ z-index: 2;
2645
+ display: flex;
2646
+ align-items: center;
2647
+ justify-content: center;
2648
+ width: 28px;
2649
+ height: 28px;
2650
+ border: 1px solid var(--color-border);
2651
+ border-radius: 6px;
2652
+ background: var(--color-bg);
2653
+ color: var(--color-text-secondary);
2654
+ cursor: pointer;
2655
+ opacity: 0;
2656
+ transition: opacity 0.2s, background 0.15s, color 0.15s;
2657
+ }
2658
+
2659
+ .mermaid-edit-btn:hover {
2660
+ background: var(--color-accent);
2661
+ color: #fff;
2662
+ border-color: var(--color-accent);
2663
+ }
2664
+
2665
+ .mermaid-svg svg {
2666
+ max-width: 100%;
2667
+ height: auto;
2668
+ }
2669
+
2670
+ .mermaid-loading {
2671
+ color: var(--color-text-tertiary);
2672
+ font-size: 13px;
2673
+ padding: 24px 0;
2674
+ }
2675
+
2676
+ .mermaid-error-tip {
2677
+ display: flex;
2678
+ align-items: center;
2679
+ justify-content: center;
2680
+ gap: 12px;
2681
+ color: var(--color-error-text, #d32f2f);
2682
+ font-size: 13px;
2683
+ padding: 24px 0;
2684
+ }
2685
+
2686
+ .mermaid-error-edit {
2687
+ padding: 4px 12px;
2688
+ border: 1px solid var(--color-border);
2689
+ border-radius: 4px;
2690
+ background: var(--color-bg);
2691
+ color: var(--color-accent);
2692
+ font-size: 12px;
2693
+ cursor: pointer;
2694
+ transition: background 0.15s;
2695
+ }
2696
+
2697
+ .mermaid-error-edit:hover {
2698
+ background: var(--color-accent-bg);
2699
+ }
2700
+
2701
+ /* Mermaid 编辑模式 */
2702
+ .mermaid-editor {
2703
+ border: 1px solid var(--color-accent);
2704
+ border-radius: 8px;
2705
+ overflow: hidden;
2706
+ }
2707
+
2708
+ .mermaid-editor-header {
2709
+ display: flex;
2710
+ align-items: center;
2711
+ justify-content: space-between;
2712
+ padding: 6px 12px;
2713
+ background: var(--color-pre-bg);
2714
+ border-bottom: 1px solid var(--color-border);
2715
+ }
2716
+
2717
+ .mermaid-editor-label {
2718
+ font-size: 11px;
2719
+ font-weight: 600;
2720
+ color: var(--color-text-tertiary);
2721
+ letter-spacing: 0.5px;
2722
+ }
2723
+
2724
+ .mermaid-editor-done {
2725
+ display: flex;
2726
+ align-items: center;
2727
+ gap: 4px;
2728
+ padding: 3px 10px;
2729
+ border: none;
2730
+ border-radius: 4px;
2731
+ background: var(--color-accent);
2732
+ color: #fff;
2733
+ font-size: 12px;
2734
+ cursor: pointer;
2735
+ transition: opacity 0.15s;
2736
+ }
2737
+
2738
+ .mermaid-editor-done:hover {
2739
+ opacity: 0.85;
2740
+ }
2741
+
2742
+ .mermaid-editor-textarea {
2743
+ display: block;
2744
+ width: 100%;
2745
+ min-height: 120px;
2746
+ padding: 12px 16px;
2747
+ border: none;
2748
+ outline: none;
2749
+ resize: none;
2750
+ background: var(--color-pre-bg);
2751
+ color: var(--color-pre-text);
2752
+ font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
2753
+ font-size: 13px;
2754
+ line-height: 1.5;
2755
+ tab-size: 2;
2756
+ }
2757
+
2758
+ /* ===== Mermaid 编辑器 NodeView ===== */
2759
+ .mermaid-block-wrapper {
2760
+ position: relative;
2761
+ margin: 16px 0;
2762
+ }
2763
+
2764
+ .mermaid-preview {
2765
+ position: relative;
2766
+ text-align: center;
2767
+ padding: 16px;
2768
+ border: 1px solid var(--color-border-light);
2769
+ border-radius: 6px;
2770
+ background: var(--color-bg);
2771
+ }
2772
+
2773
+ .mermaid-preview:hover .mermaid-edit-btn {
2774
+ opacity: 1;
2775
+ }
2776
+
2777
+ .mermaid-edit-btn {
2778
+ position: absolute;
2779
+ top: 8px;
2780
+ right: 8px;
2781
+ display: flex;
2782
+ align-items: center;
2783
+ justify-content: center;
2784
+ width: 28px;
2785
+ height: 28px;
2786
+ border: 1px solid var(--color-border);
2787
+ border-radius: 4px;
2788
+ background: var(--color-bg);
2789
+ color: var(--color-text-tertiary);
2790
+ cursor: pointer;
2791
+ opacity: 0;
2792
+ transition: all 0.15s;
2793
+ z-index: 2;
2794
+ }
2795
+
2796
+ .mermaid-edit-btn:hover {
2797
+ color: var(--color-accent);
2798
+ border-color: var(--color-accent);
2799
+ background: var(--color-accent-bg);
2800
+ }
2801
+
2802
+ .mermaid-svg svg {
2803
+ max-width: 100%;
2804
+ height: auto;
2805
+ }
2806
+
2807
+ .mermaid-error-tip {
2808
+ display: flex;
2809
+ align-items: center;
2810
+ gap: 8px;
2811
+ justify-content: center;
2812
+ padding: 12px;
2813
+ color: var(--color-error-text);
2814
+ background: var(--color-error-bg);
2815
+ border-radius: 4px;
2816
+ font-size: 13px;
2817
+ }
2818
+
2819
+ .mermaid-error-edit {
2820
+ padding: 2px 8px;
2821
+ border: 1px solid var(--color-error-border);
2822
+ border-radius: 4px;
2823
+ background: transparent;
2824
+ color: var(--color-error-text);
2825
+ cursor: pointer;
2826
+ font-size: 12px;
2827
+ }
2828
+
2829
+ .mermaid-error-edit:hover {
2830
+ background: var(--color-error-bg);
2831
+ }
2832
+
2833
+ .mermaid-loading {
2834
+ padding: 24px;
2835
+ color: var(--color-text-tertiary);
2836
+ font-size: 13px;
2837
+ }
2838
+
2839
+ .mermaid-editor {
2840
+ border: 1px solid var(--color-accent);
2841
+ border-radius: 6px;
2842
+ overflow: hidden;
2843
+ }
2844
+
2845
+ .mermaid-editor-header {
2846
+ display: flex;
2847
+ align-items: center;
2848
+ justify-content: space-between;
2849
+ padding: 4px 12px;
2850
+ background: var(--color-pre-header);
2851
+ border-bottom: 1px solid var(--color-accent);
2852
+ }
2853
+
2854
+ .mermaid-editor-label {
2855
+ font-size: 11px;
2856
+ font-weight: 500;
2857
+ color: var(--color-text-tertiary);
2858
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
2859
+ letter-spacing: 0.04em;
2860
+ }
2861
+
2862
+ .mermaid-editor-done {
2863
+ display: flex;
2864
+ align-items: center;
2865
+ gap: 4px;
2866
+ padding: 2px 8px;
2867
+ border: 1px solid var(--color-accent);
2868
+ border-radius: 4px;
2869
+ background: var(--color-accent);
2870
+ color: #fff;
2871
+ cursor: pointer;
2872
+ font-size: 12px;
2873
+ font-family: inherit;
2874
+ transition: all 0.15s;
2875
+ }
2876
+
2877
+ .mermaid-editor-done:hover {
2878
+ background: var(--color-accent-hover);
2879
+ }
2880
+
2881
+ .mermaid-editor-textarea {
2882
+ width: 100%;
2883
+ min-height: 120px;
2884
+ padding: 12px 16px;
2885
+ border: none;
2886
+ outline: none;
2887
+ background: var(--color-pre-bg);
2888
+ color: var(--color-pre-text);
2889
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
2890
+ font-size: 13px;
2891
+ line-height: 1.45;
2892
+ resize: none;
2893
+ overflow: hidden;
2894
+ }
2895
+
2896
+ /* ===== 树节点操作按钮 ===== */
2897
+ .nav-item-actions {
2898
+ display: none;
2899
+ align-items: center;
2900
+ gap: 2px;
2901
+ margin-left: auto;
2902
+ flex-shrink: 0;
2903
+ padding-left: 4px;
2904
+ }
2905
+
2906
+ .nav-item:hover .nav-item-actions {
2907
+ display: flex;
2908
+ }
2909
+
2910
+ .nav-item-btn {
2911
+ display: flex;
2912
+ align-items: center;
2913
+ justify-content: center;
2914
+ width: 20px;
2915
+ height: 20px;
2916
+ border: none;
2917
+ background: transparent;
2918
+ color: var(--color-text-tertiary);
2919
+ cursor: pointer;
2920
+ border-radius: 4px;
2921
+ padding: 0;
2922
+ transition: all 0.1s;
2923
+ }
2924
+
2925
+ .nav-item-btn:hover {
2926
+ background: var(--color-bg-tertiary);
2927
+ color: var(--color-text-secondary);
2928
+ }
2929
+
2930
+ .nav-item-btn-danger:hover {
2931
+ background: var(--color-error-bg);
2932
+ color: var(--color-error-text);
2933
+ }
2934
+
2935
+ /* ===== 拖拽排序 ===== */
2936
+ .drag-ghost {
2937
+ opacity: 0.4;
2938
+ background: var(--color-accent-bg);
2939
+ border-radius: 6px;
2940
+ }
2941
+
2942
+ .drag-ghost .nav-item {
2943
+ background: var(--color-accent-bg);
2944
+ }
2945
+
2946
+ .drag-chosen {
2947
+ opacity: 1;
2948
+ }
2949
+
2950
+ .drag-chosen > .nav-item {
2951
+ background: var(--color-bg-tertiary);
2952
+ box-shadow: 0 2px 8px var(--color-shadow);
2953
+ border-radius: 6px;
2954
+ }
2955
+
2956
+ .drag-active {
2957
+ opacity: 0.9;
2958
+ cursor: grabbing !important;
2959
+ }
2960
+
2961
+ /* 文件夹拖拽悬停高亮 */
2962
+ .nav-item.drag-over {
2963
+ background: var(--color-accent-bg);
2964
+ outline: 2px dashed var(--color-accent);
2965
+ outline-offset: -2px;
2966
+ border-radius: 6px;
2967
+ }
2968
+
2969
+ /* 拖拽时隐藏操作按钮 */
2970
+ .sortable-drag .nav-item-actions,
2971
+ .sortable-ghost .nav-item-actions {
2972
+ display: none !important;
2973
+ }
2974
+
2975
+ /* 拖拽时的光标 */
2976
+ .nav-item {
2977
+ cursor: grab;
2978
+ }
2979
+
2980
+ .nav-item:active {
2981
+ cursor: grabbing;
2982
+ }
2983
+
2984
+ /* ===== 右键菜单 ===== */
2985
+ .ctx-menu-overlay {
2986
+ position: fixed;
2987
+ inset: 0;
2988
+ z-index: 9998;
2989
+ }
2990
+
2991
+ .ctx-menu {
2992
+ background: var(--color-bg);
2993
+ border: 1px solid var(--color-border);
2994
+ border-radius: 8px;
2995
+ box-shadow: 0 4px 16px var(--color-shadow);
2996
+ padding: 4px;
2997
+ min-width: 140px;
2998
+ z-index: 9999;
2999
+ }
3000
+
3001
+ .ctx-menu-item {
3002
+ display: flex;
3003
+ align-items: center;
3004
+ gap: 8px;
3005
+ padding: 6px 10px;
3006
+ border-radius: 6px;
3007
+ cursor: pointer;
3008
+ font-size: 13px;
3009
+ color: var(--color-text);
3010
+ transition: all 0.1s;
3011
+ }
3012
+
3013
+ .ctx-menu-item:hover {
3014
+ background: var(--color-accent-bg);
3015
+ color: var(--color-accent);
3016
+ }
3017
+
3018
+ /* ===== 模态弹窗 ===== */
3019
+ .modal-overlay {
3020
+ position: fixed;
3021
+ inset: 0;
3022
+ background: rgba(0, 0, 0, 0.4);
3023
+ display: flex;
3024
+ align-items: center;
3025
+ justify-content: center;
3026
+ z-index: 10000;
3027
+ }
3028
+
3029
+ .modal-dialog {
3030
+ background: var(--color-bg);
3031
+ border: 1px solid var(--color-border);
3032
+ border-radius: 12px;
3033
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
3034
+ padding: 20px 24px;
3035
+ min-width: 320px;
3036
+ max-width: 420px;
3037
+ }
3038
+
3039
+ .modal-title {
3040
+ font-size: 15px;
3041
+ font-weight: 600;
3042
+ color: var(--color-text);
3043
+ margin-bottom: 12px;
3044
+ }
3045
+
3046
+ .modal-message {
3047
+ font-size: 13px;
3048
+ color: var(--color-text-secondary);
3049
+ line-height: 1.6;
3050
+ margin-bottom: 16px;
3051
+ }
3052
+
3053
+ .modal-warning {
3054
+ color: var(--color-error-text);
3055
+ font-size: 12px;
3056
+ }
3057
+
3058
+ .modal-input {
3059
+ width: 100%;
3060
+ padding: 8px 12px;
3061
+ border: 1px solid var(--color-border);
3062
+ border-radius: 6px;
3063
+ font-size: 13px;
3064
+ color: var(--color-text);
3065
+ background: var(--color-bg);
3066
+ outline: none;
3067
+ font-family: inherit;
3068
+ margin-bottom: 8px;
3069
+ transition: border-color 0.15s;
3070
+ }
3071
+
3072
+ .modal-input:focus {
3073
+ border-color: var(--color-accent);
3074
+ box-shadow: 0 0 0 3px var(--color-accent-bg);
3075
+ }
3076
+
3077
+ .modal-error {
3078
+ font-size: 12px;
3079
+ color: var(--color-error-text);
3080
+ margin-bottom: 8px;
3081
+ }
3082
+
3083
+ .modal-actions {
3084
+ display: flex;
3085
+ justify-content: flex-end;
3086
+ gap: 8px;
3087
+ margin-top: 16px;
3088
+ }
3089
+
3090
+ .modal-btn {
3091
+ padding: 6px 16px;
3092
+ border: 1px solid var(--color-border);
3093
+ border-radius: 6px;
3094
+ font-size: 13px;
3095
+ font-family: inherit;
3096
+ cursor: pointer;
3097
+ transition: all 0.15s;
3098
+ }
3099
+
3100
+ .modal-btn-cancel {
3101
+ background: var(--color-bg);
3102
+ color: var(--color-text-secondary);
3103
+ }
3104
+
3105
+ .modal-btn-cancel:hover {
3106
+ background: var(--color-bg-tertiary);
3107
+ color: var(--color-text);
3108
+ }
3109
+
3110
+ .modal-btn-confirm {
3111
+ background: var(--color-accent);
3112
+ color: #fff;
3113
+ border-color: var(--color-accent);
3114
+ }
3115
+
3116
+ .modal-btn-confirm:hover {
3117
+ background: var(--color-accent-hover);
3118
+ border-color: var(--color-accent-hover);
3119
+ }
3120
+
3121
+ .modal-btn-danger {
3122
+ background: var(--color-error-bg);
3123
+ color: var(--color-error-text);
3124
+ border-color: var(--color-error-border);
3125
+ }
3126
+
3127
+ .modal-btn-danger:hover {
3128
+ background: var(--color-error-text);
3129
+ color: #fff;
3130
+ border-color: var(--color-error-text);
3131
+ }
3132
+
3133
+ /* ===== Popover 气泡 ===== */
3134
+ .popover-overlay {
3135
+ position: fixed;
3136
+ inset: 0;
3137
+ z-index: 10000;
3138
+ }
3139
+
3140
+ .popover-bubble {
3141
+ background: var(--color-bg);
3142
+ border: 1px solid var(--color-border);
3143
+ border-radius: 10px;
3144
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
3145
+ padding: 12px 14px;
3146
+ min-width: 220px;
3147
+ max-width: 280px;
3148
+ }
3149
+
3150
+ .popover-input {
3151
+ width: 100%;
3152
+ padding: 6px 10px;
3153
+ border: 1px solid var(--color-border);
3154
+ border-radius: 6px;
3155
+ font-size: 13px;
3156
+ color: var(--color-text);
3157
+ background: var(--color-bg);
3158
+ outline: none;
3159
+ font-family: inherit;
3160
+ transition: border-color 0.15s;
3161
+ box-sizing: border-box;
3162
+ }
3163
+
3164
+ .popover-input:focus {
3165
+ border-color: var(--color-accent);
3166
+ box-shadow: 0 0 0 2px var(--color-accent-bg);
3167
+ }
3168
+
3169
+ .popover-error {
3170
+ font-size: 12px;
3171
+ color: var(--color-error-text);
3172
+ margin-top: 4px;
3173
+ }
3174
+
3175
+ .popover-message {
3176
+ font-size: 13px;
3177
+ color: var(--color-text-secondary);
3178
+ line-height: 1.5;
3179
+ }
3180
+
3181
+ .popover-warning {
3182
+ color: var(--color-error-text);
3183
+ font-size: 12px;
3184
+ }
3185
+
3186
+ .popover-actions {
3187
+ display: flex;
3188
+ justify-content: flex-end;
3189
+ gap: 6px;
3190
+ margin-top: 10px;
3191
+ }
3192
+
3193
+ .popover-btn {
3194
+ padding: 4px 12px;
3195
+ border: 1px solid var(--color-border);
3196
+ border-radius: 6px;
3197
+ font-size: 12px;
3198
+ font-family: inherit;
3199
+ cursor: pointer;
3200
+ transition: all 0.15s;
3201
+ }
3202
+
3203
+ .popover-btn-cancel {
3204
+ background: var(--color-bg);
3205
+ color: var(--color-text-secondary);
3206
+ }
3207
+
3208
+ .popover-btn-cancel:hover {
3209
+ background: var(--color-bg-tertiary);
3210
+ color: var(--color-text);
3211
+ }
3212
+
3213
+ .popover-btn-confirm {
3214
+ background: var(--color-accent);
3215
+ color: #fff;
3216
+ border-color: var(--color-accent);
3217
+ }
3218
+
3219
+ .popover-btn-confirm:hover {
3220
+ background: var(--color-accent-hover);
3221
+ border-color: var(--color-accent-hover);
3222
+ }
3223
+
3224
+ .popover-btn-danger {
3225
+ background: var(--color-error-bg);
3226
+ color: var(--color-error-text);
3227
+ border-color: var(--color-error-border);
3228
+ }
3229
+
3230
+ .popover-btn-danger:hover {
3231
+ background: var(--color-error-text);
3232
+ color: #fff;
3233
+ border-color: var(--color-error-text);
3234
+ }
3235
+
3236
+ /* ===== 数学公式 (KaTeX) ===== */
3237
+ .markdown-content .math-block {
3238
+ margin: 16px 0;
3239
+ overflow-x: auto;
3240
+ padding: 12px 0;
3241
+ text-align: center;
3242
+ }
3243
+
3244
+ .markdown-content .math-error {
3245
+ color: var(--color-error-text);
3246
+ background: var(--color-error-bg);
3247
+ padding: 4px 8px;
3248
+ border-radius: 4px;
3249
+ font-size: 13px;
3250
+ }
3251
+
3252
+ /* ===== 块级公式编辑器 NodeView ===== */
3253
+ .math-block-wrapper {
3254
+ position: relative;
3255
+ margin: 16px 0;
3256
+ }
3257
+
3258
+ .math-block-preview {
3259
+ position: relative;
3260
+ text-align: center;
3261
+ padding: 20px 16px;
3262
+ border: 1px solid var(--color-border-light);
3263
+ border-radius: 6px;
3264
+ background: var(--color-bg);
3265
+ cursor: pointer;
3266
+ transition: border-color 0.15s;
3267
+ }
3268
+
3269
+ .math-block-preview:hover {
3270
+ border-color: var(--color-accent);
3271
+ }
3272
+
3273
+ .math-block-preview:hover .math-block-edit-btn {
3274
+ opacity: 1;
3275
+ }
3276
+
3277
+ .math-block-edit-btn {
3278
+ position: absolute;
3279
+ top: 8px;
3280
+ right: 8px;
3281
+ display: flex;
3282
+ align-items: center;
3283
+ justify-content: center;
3284
+ width: 28px;
3285
+ height: 28px;
3286
+ border: 1px solid var(--color-border);
3287
+ border-radius: 4px;
3288
+ background: var(--color-bg);
3289
+ color: var(--color-text-tertiary);
3290
+ cursor: pointer;
3291
+ opacity: 0;
3292
+ transition: all 0.15s;
3293
+ z-index: 2;
3294
+ }
3295
+
3296
+ .math-block-edit-btn:hover {
3297
+ color: var(--color-accent);
3298
+ border-color: var(--color-accent);
3299
+ background: var(--color-accent-bg);
3300
+ }
3301
+
3302
+ .math-block-rendered .katex-display {
3303
+ margin: 0;
3304
+ }
3305
+
3306
+ .math-block-empty {
3307
+ padding: 24px;
3308
+ color: var(--color-text-tertiary);
3309
+ font-size: 13px;
3310
+ cursor: pointer;
3311
+ }
3312
+
3313
+ .math-block-error-tip {
3314
+ display: flex;
3315
+ align-items: center;
3316
+ gap: 8px;
3317
+ justify-content: center;
3318
+ padding: 12px;
3319
+ color: var(--color-error-text);
3320
+ background: var(--color-error-bg);
3321
+ border-radius: 4px;
3322
+ font-size: 13px;
3323
+ }
3324
+
3325
+ .math-block-error-edit {
3326
+ padding: 2px 8px;
3327
+ border: 1px solid var(--color-error-border);
3328
+ border-radius: 4px;
3329
+ background: transparent;
3330
+ color: var(--color-error-text);
3331
+ cursor: pointer;
3332
+ font-size: 12px;
3333
+ }
3334
+
3335
+ .math-block-error-edit:hover {
3336
+ background: var(--color-error-bg);
3337
+ }
3338
+
3339
+ /* 块级公式编辑模式 */
3340
+ .math-block-editor {
3341
+ border: 1px solid var(--color-accent);
3342
+ border-radius: 6px;
3343
+ overflow: hidden;
3344
+ }
3345
+
3346
+ .math-block-editor-header {
3347
+ display: flex;
3348
+ align-items: center;
3349
+ justify-content: space-between;
3350
+ padding: 4px 12px;
3351
+ background: var(--color-pre-header);
3352
+ border-bottom: 1px solid var(--color-border-light);
3353
+ }
3354
+
3355
+ .math-block-editor-label {
3356
+ font-size: 11px;
3357
+ font-weight: 500;
3358
+ color: var(--color-text-tertiary);
3359
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
3360
+ letter-spacing: 0.04em;
3361
+ }
3362
+
3363
+ .math-block-editor-actions {
3364
+ display: flex;
3365
+ align-items: center;
3366
+ gap: 6px;
3367
+ }
3368
+
3369
+ .math-block-editor-delete {
3370
+ display: flex;
3371
+ align-items: center;
3372
+ justify-content: center;
3373
+ width: 28px;
3374
+ height: 28px;
3375
+ border: 1px solid var(--color-border);
3376
+ border-radius: 4px;
3377
+ background: transparent;
3378
+ color: var(--color-text-tertiary);
3379
+ cursor: pointer;
3380
+ font-size: 12px;
3381
+ font-family: inherit;
3382
+ transition: all 0.15s;
3383
+ }
3384
+
3385
+ .math-block-editor-delete:hover {
3386
+ color: var(--color-error-text);
3387
+ border-color: var(--color-error-text);
3388
+ background: var(--color-error-bg);
3389
+ }
3390
+
3391
+ .math-block-editor-done {
3392
+ display: flex;
3393
+ align-items: center;
3394
+ gap: 4px;
3395
+ padding: 2px 8px;
3396
+ border: 1px solid var(--color-accent);
3397
+ border-radius: 4px;
3398
+ background: var(--color-accent);
3399
+ color: #fff;
3400
+ cursor: pointer;
3401
+ font-size: 12px;
3402
+ font-family: inherit;
3403
+ transition: all 0.15s;
3404
+ }
3405
+
3406
+ .math-block-editor-done:hover {
3407
+ background: var(--color-accent-hover);
3408
+ }
3409
+
3410
+ .math-block-editor-textarea {
3411
+ width: 100%;
3412
+ min-height: 60px;
3413
+ padding: 12px 16px;
3414
+ border: none;
3415
+ outline: none;
3416
+ background: var(--color-pre-bg);
3417
+ color: var(--color-pre-text);
3418
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
3419
+ font-size: 13px;
3420
+ line-height: 1.6;
3421
+ resize: none;
3422
+ overflow: hidden;
3423
+ }
3424
+
3425
+ .math-block-editor-textarea::placeholder {
3426
+ color: var(--color-text-tertiary);
3427
+ opacity: 0.6;
3428
+ }
3429
+
3430
+ /* 实时预览区 */
3431
+ .math-block-live-preview {
3432
+ padding: 16px;
3433
+ text-align: center;
3434
+ border-top: 1px dashed var(--color-border-light);
3435
+ background: var(--color-bg);
3436
+ min-height: 48px;
3437
+ }
3438
+
3439
+ .math-block-live-rendered .katex-display {
3440
+ margin: 0;
3441
+ }
3442
+
3443
+ .math-block-live-error {
3444
+ color: var(--color-error-text);
3445
+ font-size: 12px;
3446
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
3447
+ }
3448
+
3449
+ .math-block-live-placeholder {
3450
+ color: var(--color-text-tertiary);
3451
+ font-size: 12px;
3452
+ }
3453
+
3454
+ /* ===== 行内公式 NodeView ===== */
3455
+ .math-inline-wrapper {
3456
+ display: inline;
3457
+ position: relative;
3458
+ }
3459
+
3460
+ .math-inline-rendered {
3461
+ display: inline;
3462
+ cursor: pointer;
3463
+ border-radius: 3px;
3464
+ padding: 0 2px;
3465
+ transition: background 0.15s;
3466
+ }
3467
+
3468
+ .math-inline-rendered:hover {
3469
+ background: var(--color-accent-bg);
3470
+ }
3471
+
3472
+ .math-inline-selected {
3473
+ background: var(--color-accent-bg);
3474
+ outline: 2px solid var(--color-accent);
3475
+ outline-offset: 1px;
3476
+ border-radius: 3px;
3477
+ }
3478
+
3479
+ .math-inline-error {
3480
+ display: inline;
3481
+ padding: 1px 4px;
3482
+ background: var(--color-error-bg);
3483
+ color: var(--color-error-text);
3484
+ border-radius: 3px;
3485
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
3486
+ font-size: 0.9em;
3487
+ cursor: pointer;
3488
+ }
3489
+
3490
+ /* 行内公式编辑浮层 */
3491
+ .math-inline-popover {
3492
+ position: absolute;
3493
+ top: calc(100% + 6px);
3494
+ left: 50%;
3495
+ transform: translateX(-50%);
3496
+ z-index: 100;
3497
+ min-width: 280px;
3498
+ max-width: 420px;
3499
+ background: var(--color-bg);
3500
+ border: 1px solid var(--color-border);
3501
+ border-radius: 8px;
3502
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
3503
+ overflow: hidden;
3504
+ }
3505
+
3506
+ .math-inline-popover-header {
3507
+ display: flex;
3508
+ align-items: center;
3509
+ justify-content: space-between;
3510
+ padding: 6px 10px;
3511
+ background: var(--color-pre-header);
3512
+ border-bottom: 1px solid var(--color-border-light);
3513
+ }
3514
+
3515
+ .math-inline-popover-label {
3516
+ font-size: 11px;
3517
+ font-weight: 500;
3518
+ color: var(--color-text-tertiary);
3519
+ }
3520
+
3521
+ .math-inline-popover-actions {
3522
+ display: flex;
3523
+ align-items: center;
3524
+ gap: 4px;
3525
+ }
3526
+
3527
+ .math-inline-popover-btn {
3528
+ display: flex;
3529
+ align-items: center;
3530
+ justify-content: center;
3531
+ width: 24px;
3532
+ height: 24px;
3533
+ border: 1px solid var(--color-border);
3534
+ border-radius: 4px;
3535
+ background: transparent;
3536
+ color: var(--color-text-tertiary);
3537
+ cursor: pointer;
3538
+ transition: all 0.15s;
3539
+ }
3540
+
3541
+ .math-inline-popover-btn.done:hover {
3542
+ color: var(--color-accent);
3543
+ border-color: var(--color-accent);
3544
+ background: var(--color-accent-bg);
3545
+ }
3546
+
3547
+ .math-inline-popover-btn.delete:hover {
3548
+ color: var(--color-error-text);
3549
+ border-color: var(--color-error-border);
3550
+ background: var(--color-error-bg);
3551
+ }
3552
+
3553
+ .math-inline-popover-input {
3554
+ display: block;
3555
+ width: 100%;
3556
+ padding: 8px 12px;
3557
+ border: none;
3558
+ outline: none;
3559
+ background: var(--color-pre-bg);
3560
+ color: var(--color-pre-text);
3561
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
3562
+ font-size: 13px;
3563
+ line-height: 1.5;
3564
+ }
3565
+
3566
+ .math-inline-popover-input::placeholder {
3567
+ color: var(--color-text-tertiary);
3568
+ opacity: 0.6;
3569
+ }
3570
+
3571
+ .math-inline-popover-preview {
3572
+ padding: 8px 12px;
3573
+ text-align: center;
3574
+ border-top: 1px dashed var(--color-border-light);
3575
+ min-height: 32px;
3576
+ display: flex;
3577
+ align-items: center;
3578
+ justify-content: center;
3579
+ }
3580
+
3581
+ .math-inline-popover-error {
3582
+ color: var(--color-error-text);
3583
+ font-size: 11px;
3584
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
3585
+ }
3586
+
3587
+ /* 工具栏公式按钮 */
3588
+ .math-toolbar-btn {
3589
+ min-width: 28px;
3590
+ }
3591
+
3592
+ .math-toolbar-icon {
3593
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
3594
+ font-size: 12px;
3595
+ font-weight: 600;
3596
+ line-height: 1;
3597
+ }
3598
+
3599
+ /* ===== 文档最后更新时间 ===== */
3600
+ .doc-last-modified {
3601
+ display: flex;
3602
+ align-items: center;
3603
+ gap: 6px;
3604
+ width: 100%;
3605
+ max-width: 960px;
3606
+ margin: 0 auto;
3607
+ padding: 12px 32px 24px;
3608
+ font-size: 12px;
3609
+ color: var(--color-text-tertiary);
3610
+ border-top: 1px solid var(--color-border-light);
3611
+ }
3612
+
3613
+ .doc-last-modified svg {
3614
+ flex-shrink: 0;
3615
+ }
3616
+
3617
+ @media (max-width: 768px) {
3618
+ .doc-last-modified {
3619
+ padding: 12px 16px 24px;
3620
+ }
3621
+ }
3622
+
3623
+ /* ===== 移动端搜索页面 ===== */
3624
+ .mobile-search-page {
3625
+ flex: 1;
3626
+ display: flex;
3627
+ flex-direction: column;
3628
+ min-width: 0;
3629
+ background: var(--color-bg);
3630
+ overflow: hidden;
3631
+ }
3632
+
3633
+ .mobile-search-header {
3634
+ display: flex;
3635
+ align-items: center;
3636
+ gap: 8px;
3637
+ padding: 12px;
3638
+ border-bottom: 1px solid var(--color-border);
3639
+ flex-shrink: 0;
3640
+ }
3641
+
3642
+ .mobile-search-input-wrapper {
3643
+ flex: 1;
3644
+ display: flex;
3645
+ align-items: center;
3646
+ gap: 8px;
3647
+ padding: 8px 12px;
3648
+ background: var(--color-bg-secondary);
3649
+ border: 1px solid var(--color-border);
3650
+ border-radius: 8px;
3651
+ }
3652
+
3653
+ .mobile-search-input-wrapper:focus-within {
3654
+ border-color: var(--color-accent);
3655
+ box-shadow: 0 0 0 3px var(--color-accent-bg);
3656
+ }
3657
+
3658
+ .mobile-search-icon {
3659
+ color: var(--color-text-tertiary);
3660
+ flex-shrink: 0;
3661
+ }
3662
+
3663
+ .mobile-search-input {
3664
+ flex: 1;
3665
+ border: none;
3666
+ outline: none;
3667
+ background: transparent;
3668
+ font-size: 15px;
3669
+ color: var(--color-text);
3670
+ min-width: 0;
3671
+ }
3672
+
3673
+ .mobile-search-input::placeholder {
3674
+ color: var(--color-text-tertiary);
3675
+ }
3676
+
3677
+ .mobile-search-clear {
3678
+ display: flex;
3679
+ align-items: center;
3680
+ justify-content: center;
3681
+ width: 20px;
3682
+ height: 20px;
3683
+ border: none;
3684
+ background: var(--color-bg-tertiary);
3685
+ color: var(--color-text-secondary);
3686
+ border-radius: 50%;
3687
+ cursor: pointer;
3688
+ flex-shrink: 0;
3689
+ padding: 0;
3690
+ }
3691
+
3692
+ .mobile-search-cancel {
3693
+ border: none;
3694
+ background: transparent;
3695
+ color: var(--color-accent);
3696
+ font-size: 14px;
3697
+ cursor: pointer;
3698
+ white-space: nowrap;
3699
+ padding: 4px 0;
3700
+ }
3701
+
3702
+ .mobile-search-results {
3703
+ flex: 1;
3704
+ overflow-y: auto;
3705
+ -webkit-overflow-scrolling: touch;
3706
+ }
3707
+
3708
+ .mobile-search-item {
3709
+ display: flex;
3710
+ align-items: center;
3711
+ gap: 10px;
3712
+ padding: 12px 16px;
3713
+ cursor: pointer;
3714
+ border-bottom: 1px solid var(--color-border-light);
3715
+ transition: background 0.1s;
3716
+ }
3717
+
3718
+ .mobile-search-item:active,
3719
+ .mobile-search-item.active {
3720
+ background: var(--color-accent-bg);
3721
+ }
3722
+
3723
+ .mobile-search-item-icon {
3724
+ color: var(--color-text-tertiary);
3725
+ flex-shrink: 0;
3726
+ }
3727
+
3728
+ .mobile-search-item-title {
3729
+ flex: 1;
3730
+ font-size: 14px;
3731
+ color: var(--color-text);
3732
+ overflow: hidden;
3733
+ text-overflow: ellipsis;
3734
+ white-space: nowrap;
3735
+ }
3736
+
3737
+ .mobile-search-empty {
3738
+ padding: 32px 16px;
3739
+ text-align: center;
3740
+ color: var(--color-text-tertiary);
3741
+ font-size: 14px;
3742
+ }
3743
+
3744
+ .mobile-search-tip {
3745
+ padding: 24px 16px;
3746
+ text-align: center;
3747
+ color: var(--color-text-tertiary);
3748
+ font-size: 13px;
3749
+ }