md2ui 1.0.16 → 1.0.19

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 (74) hide show
  1. package/README.md +3 -55
  2. package/bin/build.js +82 -7
  3. package/bin/md2ui.js +80 -4
  4. package/package.json +23 -9
  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 +86 -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/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
  14. 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
  15. 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
  16. 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
  17. 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
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. 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
  24. package/public/docs/06-/351/230/205/350/257/273/344/275/223/351/252/214/assets/img-1777261394722.png +0 -0
  25. 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
  26. 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
  27. 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
  28. 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
  29. 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
  30. 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
  31. 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
  32. 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
  33. 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
  34. package/src/App.vue +130 -6
  35. package/src/components/AppSidebar.vue +181 -21
  36. package/src/components/CodeBlockNodeView.vue +72 -0
  37. package/src/components/DocContent.vue +25 -14
  38. package/src/components/EditorContent.vue +257 -0
  39. package/src/components/EditorToolbar.vue +264 -0
  40. package/src/components/ImageZoom.vue +199 -2
  41. package/src/components/MathBlockNodeView.vue +160 -0
  42. package/src/components/MathInlineNodeView.vue +145 -0
  43. package/src/components/MermaidNodeView.vue +149 -0
  44. package/src/components/TableBubbleMenu.vue +177 -0
  45. package/src/components/TableOfContents.vue +138 -32
  46. package/src/components/TopBar.vue +69 -4
  47. package/src/components/TreeNode.vue +232 -39
  48. package/src/components/WelcomePage.vue +2 -2
  49. package/src/composables/useDocHash.js +9 -1
  50. package/src/composables/useDocManager.js +325 -68
  51. package/src/composables/useDocTree.js +56 -1
  52. package/src/composables/useExportPdf.js +102 -0
  53. package/src/composables/useExportWord.js +73 -10
  54. package/src/composables/useFileWatcher.js +45 -0
  55. package/src/composables/useFrontmatter.js +2 -2
  56. package/src/composables/useMarkdown.js +529 -42
  57. package/src/composables/useScroll.js +47 -5
  58. package/src/config.js +1 -1
  59. package/src/extensions/CodeBlockCustom.js +113 -0
  60. package/src/extensions/MathBlock.js +107 -0
  61. package/src/extensions/MathInline.js +100 -0
  62. package/src/extensions/MermaidBlock.js +73 -0
  63. package/src/extensions/TableControls.js +670 -0
  64. package/src/services/DocService.js +184 -0
  65. package/src/style.css +2194 -39
  66. package/vite-plugin-doc-api.js +368 -0
  67. package/vite.config.js +2 -1
  68. package/public/docs/02-Mermaid/345/233/276/350/241/250.md +0 -102
  69. 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
  70. 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
  71. 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
  72. package/public/docs/04-API/345/217/202/350/200/203/01-/347/273/204/344/273/266API.md +0 -80
  73. package/public/docs/04-API/345/217/202/350/200/203/02-Composables.md +0 -92
  74. package/src/api/docs.js +0 -106
package/src/style.css CHANGED
@@ -252,10 +252,10 @@ body {
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,
@@ -289,11 +292,7 @@ body {
289
292
 
290
293
  .markdown-content .heading-anchor:hover {
291
294
  color: var(--color-accent);
292
- }
293
-
294
- .markdown-content .heading-anchor svg {
295
- width: 0.7em;
296
- height: 0.7em;
295
+ text-decoration: none;
297
296
  }
298
297
 
299
298
  .markdown-content h1 {
@@ -389,18 +388,144 @@ body {
389
388
  }
390
389
 
391
390
  /* 表格 */
391
+
392
+ /* 表格外层容器 */
393
+ .markdown-content .table-outer {
394
+ position: relative;
395
+ margin-bottom: 16px;
396
+ }
397
+
398
+ /* 表格工具栏 */
399
+ .markdown-content .table-toolbar {
400
+ display: flex;
401
+ align-items: center;
402
+ gap: 2px;
403
+ justify-content: flex-end;
404
+ padding: 2px 0;
405
+ opacity: 0;
406
+ transition: opacity 0.15s;
407
+ z-index: 2;
408
+ }
409
+
410
+ .markdown-content .table-outer:hover .table-toolbar {
411
+ opacity: 1;
412
+ }
413
+
414
+ .markdown-content .table-toolbar-btn {
415
+ display: flex;
416
+ align-items: center;
417
+ justify-content: center;
418
+ width: 26px;
419
+ height: 26px;
420
+ border: 1px solid var(--color-border);
421
+ border-radius: 4px;
422
+ background: var(--color-bg-secondary);
423
+ color: var(--color-text-tertiary);
424
+ cursor: pointer;
425
+ transition: all 0.15s;
426
+ position: relative;
427
+ }
428
+
429
+ .markdown-content .table-toolbar-btn:hover {
430
+ color: var(--color-accent);
431
+ background: var(--color-bg);
432
+ border-color: var(--color-accent);
433
+ }
434
+
435
+ .markdown-content .table-toolbar-btn.active {
436
+ color: var(--color-accent);
437
+ background: var(--color-accent-bg);
438
+ border-color: var(--color-accent);
439
+ }
440
+
441
+ /* 工具栏按钮 tooltip */
442
+ .markdown-content .table-toolbar-btn[data-tooltip]:hover::after {
443
+ content: attr(data-tooltip);
444
+ position: absolute;
445
+ top: calc(100% + 6px);
446
+ left: 50%;
447
+ transform: translateX(-50%);
448
+ padding: 4px 8px;
449
+ background: #1f2328;
450
+ color: #fff;
451
+ font-size: 11px;
452
+ border-radius: 4px;
453
+ white-space: nowrap;
454
+ pointer-events: none;
455
+ z-index: 10;
456
+ }
457
+
458
+ .markdown-content .table-toolbar-btn[data-tooltip]:hover::before {
459
+ content: '';
460
+ position: absolute;
461
+ top: calc(100% + 2px);
462
+ left: 50%;
463
+ transform: translateX(-50%);
464
+ border: 4px solid transparent;
465
+ border-bottom-color: #1f2328;
466
+ pointer-events: none;
467
+ z-index: 10;
468
+ }
469
+
470
+ /* 表格滚动容器 */
392
471
  .markdown-content .table-wrapper {
393
472
  width: 100%;
473
+ -webkit-overflow-scrolling: touch;
474
+ }
475
+
476
+ /* 横向滚动模式 */
477
+ .markdown-content .table-wrapper-scroll {
394
478
  overflow-x: auto;
395
- margin-bottom: 16px;
479
+ }
480
+
481
+ /* 固定宽度模式:不允许横向滚动 */
482
+ .markdown-content .table-wrapper-fixed {
483
+ overflow-x: hidden;
484
+ }
485
+
486
+ /* 固定宽度模式下单元格强制换行,防止内容溢出导致右边框丢失 */
487
+ .markdown-content .table-wrapper-fixed table td,
488
+ .markdown-content .table-wrapper-fixed table th {
489
+ word-break: break-all;
490
+ overflow-wrap: break-word;
491
+ }
492
+
493
+ /* 固定高度模式:500px + 竖向滚动 */
494
+ .markdown-content .table-wrapper-fixed-height {
495
+ max-height: 500px;
496
+ overflow-y: auto;
497
+ }
498
+
499
+ /* 适应高度模式:无高度限制 */
500
+ .markdown-content .table-wrapper-auto-height {
501
+ max-height: none;
502
+ overflow-y: visible;
396
503
  }
397
504
 
398
505
  .markdown-content table {
399
- width: 100%;
400
506
  border-collapse: collapse;
401
507
  border-spacing: 0;
402
508
  }
403
509
 
510
+ /* 固定宽度:撑满容器 */
511
+ .markdown-content table.table-fit {
512
+ width: 100%;
513
+ }
514
+
515
+ /* 横向滚动:按内容撑开 */
516
+ .markdown-content table.table-scroll {
517
+ width: max-content;
518
+ min-width: 100%;
519
+ }
520
+
521
+ /* 固定高度模式下表头吸顶 */
522
+ .markdown-content .table-wrapper-fixed-height table th {
523
+ position: sticky;
524
+ top: 0;
525
+ z-index: 1;
526
+ background: var(--color-table-header-bg);
527
+ }
528
+
404
529
  .markdown-content table th,
405
530
  .markdown-content table td {
406
531
  border: 1px solid var(--color-border);
@@ -410,6 +535,7 @@ body {
410
535
  .markdown-content table th {
411
536
  background: var(--color-table-header-bg);
412
537
  font-weight: 600;
538
+ white-space: nowrap;
413
539
  }
414
540
 
415
541
  .markdown-content table tr:nth-child(2n) {
@@ -424,6 +550,124 @@ body {
424
550
  background: var(--color-table-row-alt);
425
551
  }
426
552
 
553
+ /* 表格全屏弹框 */
554
+ .table-fullscreen-overlay {
555
+ position: fixed;
556
+ inset: 0;
557
+ background: rgba(0, 0, 0, 0.6);
558
+ z-index: 9999;
559
+ display: flex;
560
+ align-items: center;
561
+ justify-content: center;
562
+ padding: 24px;
563
+ }
564
+
565
+ .table-fullscreen-dialog {
566
+ position: relative;
567
+ display: flex;
568
+ flex-direction: column;
569
+ max-width: 95vw;
570
+ max-height: 90vh;
571
+ background: var(--color-bg);
572
+ border-radius: 8px;
573
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
574
+ overflow: hidden;
575
+ }
576
+
577
+ /* 全屏模式 */
578
+ .table-fullscreen-dialog.is-maximized {
579
+ max-width: 100vw;
580
+ max-height: 100vh;
581
+ width: 100vw;
582
+ height: 100vh;
583
+ border-radius: 0;
584
+ }
585
+
586
+ .table-fullscreen-header {
587
+ display: flex;
588
+ align-items: center;
589
+ justify-content: space-between;
590
+ padding: 8px 16px;
591
+ border-bottom: 1px solid var(--color-border);
592
+ background: var(--color-bg-secondary);
593
+ flex-shrink: 0;
594
+ }
595
+
596
+ .table-fullscreen-title {
597
+ font-size: 13px;
598
+ font-weight: 500;
599
+ color: var(--color-text-secondary);
600
+ }
601
+
602
+ .table-fullscreen-actions {
603
+ display: flex;
604
+ align-items: center;
605
+ gap: 4px;
606
+ }
607
+
608
+ .table-fullscreen-action-btn {
609
+ display: flex;
610
+ align-items: center;
611
+ justify-content: center;
612
+ width: 28px;
613
+ height: 28px;
614
+ border: none;
615
+ border-radius: 4px;
616
+ background: transparent;
617
+ color: var(--color-text-tertiary);
618
+ cursor: pointer;
619
+ transition: all 0.15s;
620
+ }
621
+
622
+ .table-fullscreen-action-btn:hover {
623
+ background: var(--color-bg-tertiary);
624
+ color: var(--color-text);
625
+ }
626
+
627
+ .table-fullscreen-body {
628
+ flex: 1;
629
+ overflow: auto;
630
+ padding: 0;
631
+ }
632
+
633
+ .table-fullscreen-body table {
634
+ width: max-content;
635
+ min-width: 100%;
636
+ border-collapse: separate;
637
+ border-spacing: 0;
638
+ }
639
+
640
+ .table-fullscreen-body table th,
641
+ .table-fullscreen-body table td {
642
+ border: 1px solid var(--color-border);
643
+ border-top: none;
644
+ border-left: none;
645
+ padding: 8px 16px;
646
+ }
647
+
648
+ .table-fullscreen-body table th:first-child,
649
+ .table-fullscreen-body table td:first-child {
650
+ border-left: 1px solid var(--color-border);
651
+ }
652
+
653
+ .table-fullscreen-body table th {
654
+ background: var(--color-table-header-bg);
655
+ font-weight: 600;
656
+ white-space: nowrap;
657
+ position: sticky;
658
+ top: 0;
659
+ z-index: 1;
660
+ border-top: none;
661
+ }
662
+
663
+ .table-fullscreen-body table tr:nth-child(2n) {
664
+ background: transparent;
665
+ }
666
+
667
+ .table-fullscreen-body table tr:hover {
668
+ background: var(--color-table-row-alt);
669
+ }
670
+
427
671
  .markdown-content blockquote {
428
672
  border-left: 3px solid var(--color-blockquote-border);
429
673
  padding: 8px 16px;
@@ -440,8 +684,102 @@ body {
440
684
  margin: 4px 0;
441
685
  }
442
686
 
687
+ /* 图片容器(含复制按钮) */
688
+ .markdown-content .image-container {
689
+ position: relative;
690
+ display: inline-block;
691
+ max-width: 100%;
692
+ }
693
+
694
+ .markdown-content .image-container img {
695
+ display: block;
696
+ min-width: 64px;
697
+ min-height: 64px;
698
+ object-fit: contain;
699
+ }
700
+
701
+ .markdown-content .image-copy-btn {
702
+ position: absolute;
703
+ top: 4px;
704
+ right: 4px;
705
+ display: flex;
706
+ align-items: center;
707
+ justify-content: center;
708
+ width: 24px;
709
+ height: 24px;
710
+ border: none;
711
+ border-radius: 4px;
712
+ background: rgba(255, 255, 255, 0.85);
713
+ color: #4a5568;
714
+ cursor: pointer;
715
+ opacity: 0;
716
+ transition: opacity 0.15s, background 0.15s, color 0.15s;
717
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
718
+ z-index: 2;
719
+ }
720
+
721
+ .markdown-content .image-container:hover .image-copy-btn {
722
+ opacity: 1;
723
+ }
724
+
725
+ .markdown-content .image-copy-btn:hover {
726
+ background: #fff;
727
+ color: #2d3748;
728
+ }
729
+
730
+ .markdown-content .image-copy-btn.copied {
731
+ color: #38a169;
732
+ background: #f0fff4;
733
+ }
734
+
735
+ /* 复制提示气泡 */
736
+ .markdown-content .copy-tip {
737
+ position: absolute;
738
+ top: 8px;
739
+ right: 40px;
740
+ font-size: 12px;
741
+ font-weight: 500;
742
+ white-space: nowrap;
743
+ padding: 4px 10px;
744
+ border-radius: 6px;
745
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
746
+ z-index: 3;
747
+ animation: copyTipIn 0.15s ease-out;
748
+ pointer-events: none;
749
+ }
750
+
751
+ .markdown-content .copy-tip-ok {
752
+ background: #f0fff4;
753
+ color: #276749;
754
+ border: 1px solid #c6f6d5;
755
+ }
756
+
757
+ .markdown-content .copy-tip-fail {
758
+ background: #fff5f5;
759
+ color: #9b2c2c;
760
+ border: 1px solid #fed7d7;
761
+ }
762
+
763
+ @keyframes copyTipIn {
764
+ from { opacity: 0; transform: translateX(4px); }
765
+ to { opacity: 1; transform: translateX(0); }
766
+ }
767
+
768
+ /* Mermaid 图表复制按钮 */
769
+ .markdown-content .mermaid .mermaid-copy-btn {
770
+ position: absolute;
771
+ top: 8px;
772
+ right: 8px;
773
+ opacity: 0;
774
+ }
775
+
776
+ .markdown-content .mermaid:hover .mermaid-copy-btn {
777
+ opacity: 1;
778
+ }
779
+
443
780
  /* Mermaid */
444
781
  .markdown-content .mermaid {
782
+ position: relative;
445
783
  margin: 16px 0;
446
784
  text-align: center;
447
785
  }
@@ -469,12 +807,29 @@ body {
469
807
  border: 1px solid var(--color-pre-border);
470
808
  }
471
809
 
810
+ /* Frontmatter 代码块 */
811
+ .markdown-content .frontmatter-block {
812
+ border-left: 3px solid var(--color-primary, #5c6bc0);
813
+ margin-bottom: 20px;
814
+ }
815
+
816
+ .markdown-content .frontmatter-block .code-lang-label {
817
+ color: var(--color-primary, #5c6bc0);
818
+ font-weight: 600;
819
+ }
820
+
472
821
  .markdown-content .code-block-wrapper pre {
473
822
  margin: 0;
474
823
  border-radius: 0;
824
+ padding: 0;
475
825
  background: transparent;
476
826
  }
477
827
 
828
+ /* 代码块内 code 元素去掉 hljs 默认 padding,由 table cell 控制间距 */
829
+ .markdown-content .code-block-wrapper pre code.hljs {
830
+ padding: 0;
831
+ }
832
+
478
833
  /* header 常驻 */
479
834
  .markdown-content .code-block-header {
480
835
  display: flex;
@@ -569,50 +924,90 @@ body {
569
924
 
570
925
  /* 代码主体 */
571
926
  .code-block-body {
572
- display: flex;
573
927
  overflow-x: auto;
574
928
  }
575
929
 
576
- .line-numbers {
577
- flex-shrink: 0;
578
- padding: 16px 0;
579
- text-align: right;
580
- user-select: none;
581
- border-right: 1px solid var(--color-pre-border);
582
- background: transparent;
930
+ /* 自动换行模式 */
931
+ .code-block-body.word-wrap-enabled {
932
+ overflow-x: hidden;
583
933
  }
584
934
 
585
- .line-numbers.hidden {
586
- display: none;
935
+ .code-block-body.word-wrap-enabled code {
936
+ white-space: pre-wrap;
937
+ word-break: break-all;
587
938
  }
588
939
 
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;
594
- line-height: 1.45;
595
- color: var(--color-text-tertiary);
596
- min-width: 2em;
940
+ .code-block-body.word-wrap-enabled .hljs-ln-code {
941
+ white-space: pre-wrap;
942
+ word-break: break-all;
597
943
  }
598
944
 
599
- .code-block-body pre {
600
- flex: 1;
601
- min-width: 0;
602
- overflow-x: auto;
945
+ /* highlightjs-line-numbers 插件样式 */
946
+ .code-block-body .hljs-ln {
947
+ border-collapse: collapse;
948
+ width: 100%;
949
+ padding: 0;
603
950
  }
604
951
 
605
- .code-block-body pre code {
606
- font-size: 13px;
607
- line-height: 1.45;
608
- padding: 16px;
609
- display: block;
952
+ /* 首行和末行留出上下间距 */
953
+ .code-block-body .hljs-ln tr:first-child td {
954
+ padding-top: 10px;
955
+ }
956
+ .code-block-body .hljs-ln tr:last-child td {
957
+ padding-bottom: 10px;
958
+ }
959
+
960
+ .code-block-body .hljs-ln td {
961
+ border: none;
962
+ }
963
+
964
+ /* 行号列 */
965
+ .code-block-body td.hljs-ln-numbers {
966
+ -webkit-user-select: none;
967
+ user-select: none;
968
+ text-align: right;
969
+ vertical-align: top;
970
+ white-space: nowrap;
971
+ width: 1%;
972
+ min-width: 2em;
973
+ padding: 0;
974
+ border-right: 1px solid var(--color-pre-border);
975
+ }
976
+
977
+ /* 行号数字 */
978
+ .code-block-body .hljs-ln-n {
979
+ padding: 0 4px;
980
+ color: var(--color-text-tertiary);
981
+ opacity: 0.5;
982
+ font-size: 12px;
983
+ line-height: 1.45;
984
+ }
985
+
986
+ /* 代码列 */
987
+ .code-block-body td.hljs-ln-code {
988
+ padding: 0 0 0 10px;
989
+ vertical-align: top;
990
+ font-size: 13px;
991
+ line-height: 1.45;
992
+ }
993
+
994
+ .code-block-body pre {
995
+ flex: 1;
996
+ min-width: 0;
997
+ overflow-x: auto;
998
+ }
999
+
1000
+ .code-block-body pre code {
1001
+ font-size: 13px;
1002
+ line-height: 1.45;
1003
+ padding: 10px 8px;
1004
+ display: block;
610
1005
  }
611
1006
 
612
1007
  .code-block-body .code-plain {
613
1008
  background: none;
614
1009
  color: var(--color-text);
615
- padding: 16px;
1010
+ padding: 12px;
616
1011
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
617
1012
  font-size: 13px;
618
1013
  line-height: 1.45;
@@ -716,6 +1111,31 @@ body {
716
1111
  letter-spacing: 0.02em;
717
1112
  }
718
1113
 
1114
+ .toc-header-actions {
1115
+ display: flex;
1116
+ align-items: center;
1117
+ gap: 2px;
1118
+ }
1119
+
1120
+ .toc-action-btn {
1121
+ display: flex;
1122
+ align-items: center;
1123
+ justify-content: center;
1124
+ width: 22px;
1125
+ height: 22px;
1126
+ border: 1px solid transparent;
1127
+ background: transparent;
1128
+ color: var(--color-text-tertiary);
1129
+ cursor: pointer;
1130
+ border-radius: 4px;
1131
+ transition: all 0.15s;
1132
+ }
1133
+
1134
+ .toc-action-btn:hover {
1135
+ background: var(--color-bg-tertiary);
1136
+ color: var(--color-text-secondary);
1137
+ }
1138
+
719
1139
  .toc-toggle {
720
1140
  display: flex;
721
1141
  align-items: center;
@@ -740,7 +1160,9 @@ body {
740
1160
  }
741
1161
 
742
1162
  .toc-item {
743
- display: block;
1163
+ display: flex;
1164
+ align-items: center;
1165
+ justify-content: space-between;
744
1166
  padding: 3px 12px;
745
1167
  color: var(--color-text-secondary);
746
1168
  text-decoration: none;
@@ -750,6 +1172,44 @@ body {
750
1172
  border-left: 2px solid transparent;
751
1173
  }
752
1174
 
1175
+ .toc-item-text {
1176
+ flex: 1;
1177
+ min-width: 0;
1178
+ overflow: hidden;
1179
+ text-overflow: ellipsis;
1180
+ white-space: nowrap;
1181
+ }
1182
+
1183
+ .toc-fold-btn {
1184
+ display: flex;
1185
+ align-items: center;
1186
+ justify-content: center;
1187
+ width: 18px;
1188
+ height: 18px;
1189
+ flex-shrink: 0;
1190
+ border: none;
1191
+ background: transparent;
1192
+ color: var(--color-text-tertiary);
1193
+ cursor: pointer;
1194
+ border-radius: 3px;
1195
+ padding: 0;
1196
+ margin-left: 4px;
1197
+ transition: all 0.15s;
1198
+ }
1199
+
1200
+ .toc-fold-btn:hover {
1201
+ background: var(--color-bg-tertiary);
1202
+ color: var(--color-text-secondary);
1203
+ }
1204
+
1205
+ .toc-fold-icon {
1206
+ transition: transform 0.15s ease;
1207
+ }
1208
+
1209
+ .toc-fold-icon-open {
1210
+ transform: rotate(90deg);
1211
+ }
1212
+
753
1213
  .toc-item:hover {
754
1214
  color: var(--color-accent);
755
1215
  }
@@ -1094,7 +1554,7 @@ body {
1094
1554
  .top-bar-actions {
1095
1555
  display: flex;
1096
1556
  align-items: center;
1097
- gap: 4px;
1557
+ gap: 8px;
1098
1558
  flex-shrink: 0;
1099
1559
  }
1100
1560
 
@@ -1118,6 +1578,62 @@ body {
1118
1578
  color: var(--color-text);
1119
1579
  }
1120
1580
 
1581
+ /* GitHub 链接 - 低调融入 */
1582
+ .top-bar-divider {
1583
+ width: 1px;
1584
+ height: 18px;
1585
+ background: var(--color-border);
1586
+ flex-shrink: 0;
1587
+ }
1588
+
1589
+ .top-bar-github {
1590
+ display: flex;
1591
+ align-items: center;
1592
+ justify-content: center;
1593
+ width: 28px;
1594
+ height: 28px;
1595
+ color: var(--color-text-tertiary);
1596
+ cursor: pointer;
1597
+ border-radius: 6px;
1598
+ transition: all 0.15s;
1599
+ text-decoration: none;
1600
+ border: none;
1601
+ background: transparent;
1602
+ }
1603
+
1604
+ .top-bar-github:hover {
1605
+ color: var(--color-text-secondary);
1606
+ background: var(--color-bg-tertiary);
1607
+ }
1608
+
1609
+ /* 导出 Word 按钮 */
1610
+ .top-bar-actions .export-word-btn {
1611
+ display: inline-flex;
1612
+ align-items: center;
1613
+ gap: 5px;
1614
+ padding: 5px 12px;
1615
+ font-size: 12px;
1616
+ color: var(--color-text-secondary);
1617
+ background: transparent;
1618
+ border: 1px solid var(--color-border);
1619
+ border-radius: 5px;
1620
+ cursor: pointer;
1621
+ transition: all 0.15s;
1622
+ white-space: nowrap;
1623
+ font-family: inherit;
1624
+ }
1625
+
1626
+ .top-bar-actions .export-word-btn:hover {
1627
+ color: var(--color-accent);
1628
+ border-color: var(--color-accent);
1629
+ background: var(--color-accent-bg);
1630
+ }
1631
+
1632
+ .top-bar-actions .export-word-btn:disabled {
1633
+ opacity: 0.5;
1634
+ cursor: not-allowed;
1635
+ }
1636
+
1121
1637
  /* ===== 主体区域 ===== */
1122
1638
  .main-body {
1123
1639
  display: flex;
@@ -1367,3 +1883,1642 @@ body {
1367
1883
  max-width: 100%;
1368
1884
  }
1369
1885
  }
1886
+
1887
+ /* ===== 查看/编辑模式切换 ===== */
1888
+ .mode-switch {
1889
+ display: flex;
1890
+ align-items: center;
1891
+ background: var(--color-bg-secondary);
1892
+ border: 1px solid var(--color-border);
1893
+ border-radius: 6px;
1894
+ padding: 2px;
1895
+ gap: 2px;
1896
+ }
1897
+
1898
+ .mode-switch-btn {
1899
+ display: flex;
1900
+ align-items: center;
1901
+ gap: 4px;
1902
+ padding: 4px 10px;
1903
+ border: none;
1904
+ background: transparent;
1905
+ color: var(--color-text-tertiary);
1906
+ cursor: pointer;
1907
+ border-radius: 4px;
1908
+ font-size: 12px;
1909
+ font-family: inherit;
1910
+ transition: all 0.15s;
1911
+ white-space: nowrap;
1912
+ }
1913
+
1914
+ .mode-switch-btn:hover {
1915
+ color: var(--color-text-secondary);
1916
+ }
1917
+
1918
+ /* 查看模式激活 */
1919
+ .mode-switch-btn.active {
1920
+ background: var(--color-bg);
1921
+ color: var(--color-accent);
1922
+ box-shadow: 0 1px 2px var(--color-shadow);
1923
+ font-weight: 500;
1924
+ }
1925
+
1926
+ /* 编辑模式激活:红色 */
1927
+ .mode-switch-btn.active.mode-edit {
1928
+ color: #ef4444;
1929
+ background: #fef2f2;
1930
+ box-shadow: 0 1px 2px rgba(239, 68, 68, 0.12);
1931
+ }
1932
+
1933
+ /* 编辑模式指示条:固定在内容区顶部 */
1934
+ .editor-content::before {
1935
+ content: '';
1936
+ display: block;
1937
+ height: 2px;
1938
+ background: linear-gradient(90deg, #ef4444, #f87171);
1939
+ flex-shrink: 0;
1940
+ position: sticky;
1941
+ top: 0;
1942
+ z-index: 20;
1943
+ }
1944
+
1945
+ /* ===== 编辑器工具栏 ===== */
1946
+ .editor-toolbar {
1947
+ display: flex;
1948
+ align-items: center;
1949
+ gap: 4px;
1950
+ padding: 6px 12px;
1951
+ background: var(--color-bg);
1952
+ border-bottom: 1px solid var(--color-border-light);
1953
+ flex-wrap: wrap;
1954
+ position: sticky;
1955
+ top: 0;
1956
+ z-index: 10;
1957
+ }
1958
+
1959
+ .editor-toolbar-group {
1960
+ display: flex;
1961
+ align-items: center;
1962
+ gap: 2px;
1963
+ }
1964
+
1965
+ .editor-toolbar-divider {
1966
+ width: 1px;
1967
+ height: 20px;
1968
+ background: var(--color-border);
1969
+ margin: 0 4px;
1970
+ }
1971
+
1972
+ .editor-toolbar-btn {
1973
+ display: flex;
1974
+ align-items: center;
1975
+ justify-content: center;
1976
+ width: 28px;
1977
+ height: 28px;
1978
+ border: 1px solid transparent;
1979
+ background: transparent;
1980
+ color: var(--color-text-secondary);
1981
+ cursor: pointer;
1982
+ border-radius: 4px;
1983
+ transition: all 0.15s;
1984
+ padding: 0;
1985
+ }
1986
+
1987
+ .editor-toolbar-btn:hover {
1988
+ background: var(--color-bg-tertiary);
1989
+ color: var(--color-text);
1990
+ }
1991
+
1992
+ .editor-toolbar-btn.active {
1993
+ background: var(--color-accent-bg);
1994
+ color: var(--color-accent);
1995
+ border-color: var(--color-accent);
1996
+ }
1997
+
1998
+ .editor-toolbar-btn:disabled {
1999
+ opacity: 0.3;
2000
+ cursor: not-allowed;
2001
+ }
2002
+
2003
+ .editor-toolbar-btn.heading-btn {
2004
+ font-size: 11px;
2005
+ font-weight: 700;
2006
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
2007
+ width: auto;
2008
+ padding: 0 6px;
2009
+ }
2010
+
2011
+ .editor-toolbar-spacer {
2012
+ flex: 1;
2013
+ }
2014
+
2015
+ .editor-toolbar-save {
2016
+ display: flex;
2017
+ align-items: center;
2018
+ gap: 4px;
2019
+ padding: 4px 12px;
2020
+ border: 1px solid var(--color-accent);
2021
+ background: var(--color-accent);
2022
+ color: #fff;
2023
+ cursor: pointer;
2024
+ border-radius: 4px;
2025
+ font-size: 12px;
2026
+ font-family: inherit;
2027
+ font-weight: 500;
2028
+ transition: all 0.15s;
2029
+ }
2030
+
2031
+ .editor-toolbar-save:hover {
2032
+ background: var(--color-accent-hover);
2033
+ border-color: var(--color-accent-hover);
2034
+ }
2035
+
2036
+ /* ===== Frontmatter 编辑器代码块 ===== */
2037
+ .frontmatter-editor-block {
2038
+ margin: 0 auto 8px;
2039
+ max-width: 100%;
2040
+ }
2041
+
2042
+ .frontmatter-edit-body {
2043
+ padding: 0 !important;
2044
+ }
2045
+
2046
+ .frontmatter-edit-body pre {
2047
+ margin: 0;
2048
+ padding: 0;
2049
+ }
2050
+
2051
+ /* 行号 + textarea flex 布局 */
2052
+ .fm-edit-layout {
2053
+ display: flex;
2054
+ }
2055
+
2056
+ /* Frontmatter 行号列:复用代码块行号样式 */
2057
+ .fm-line-gutter {
2058
+ display: flex;
2059
+ flex-direction: column;
2060
+ flex-shrink: 0;
2061
+ min-width: 2em;
2062
+ padding: 10px 0;
2063
+ border-right: 1px solid var(--color-pre-border);
2064
+ user-select: none;
2065
+ -webkit-user-select: none;
2066
+ text-align: right;
2067
+ }
2068
+
2069
+ .fm-line-gutter .code-ln-num {
2070
+ padding: 0 4px;
2071
+ color: var(--color-text-tertiary);
2072
+ opacity: 0.5;
2073
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
2074
+ font-size: 12px;
2075
+ line-height: 1.45;
2076
+ }
2077
+
2078
+ .frontmatter-textarea {
2079
+ flex: 1;
2080
+ min-width: 0;
2081
+ display: block;
2082
+ border: none;
2083
+ outline: none;
2084
+ background: transparent;
2085
+ color: var(--color-pre-text);
2086
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
2087
+ font-size: 13px;
2088
+ line-height: 1.45;
2089
+ padding: 10px 10px;
2090
+ resize: none;
2091
+ overflow: hidden;
2092
+ tab-size: 2;
2093
+ white-space: pre;
2094
+ }
2095
+
2096
+ .frontmatter-textarea::placeholder {
2097
+ color: var(--color-text-tertiary);
2098
+ }
2099
+
2100
+ /* ===== Tiptap 编辑器样式 ===== */
2101
+ .editor-area .tiptap {
2102
+ outline: none;
2103
+ min-height: 400px;
2104
+ }
2105
+
2106
+ .editor-area .tiptap p.is-editor-empty:first-child::before {
2107
+ content: attr(data-placeholder);
2108
+ float: left;
2109
+ color: var(--color-text-tertiary);
2110
+ pointer-events: none;
2111
+ height: 0;
2112
+ }
2113
+
2114
+ /* Tiptap 表格样式 */
2115
+ .editor-area .tiptap table:not(.hljs-ln) {
2116
+ border-collapse: collapse;
2117
+ width: 100%;
2118
+ margin-bottom: 12px;
2119
+ }
2120
+
2121
+ .editor-area .tiptap table:not(.hljs-ln) td,
2122
+ .editor-area .tiptap table:not(.hljs-ln) th {
2123
+ border: 1px solid var(--color-border);
2124
+ padding: 6px 13px;
2125
+ min-width: 80px;
2126
+ position: relative;
2127
+ vertical-align: top;
2128
+ }
2129
+
2130
+ .editor-area .tiptap table:not(.hljs-ln) th {
2131
+ background: var(--color-table-header-bg);
2132
+ font-weight: 600;
2133
+ }
2134
+
2135
+ .editor-area .tiptap table:not(.hljs-ln) .selectedCell {
2136
+ background: var(--color-accent-bg);
2137
+ }
2138
+
2139
+ /* 行/列删除按钮 hover 时的高亮 overlay */
2140
+ .tc-highlight-overlay {
2141
+ background: rgba(255, 59, 48, 0.10);
2142
+ border: 1px solid rgba(255, 59, 48, 0.22);
2143
+ border-radius: 2px;
2144
+ transition: opacity 0.12s ease;
2145
+ }
2146
+
2147
+ /* 行/列选择条 → Excel 风格行号列头 */
2148
+ .tc-row-header,
2149
+ .tc-col-header {
2150
+ position: absolute;
2151
+ pointer-events: auto;
2152
+ cursor: pointer;
2153
+ display: flex;
2154
+ align-items: center;
2155
+ justify-content: center;
2156
+ background: var(--color-bg-secondary, #f5f5f5);
2157
+ border: 1px solid var(--color-border);
2158
+ color: var(--color-text-tertiary);
2159
+ font-size: 11px;
2160
+ font-weight: 500;
2161
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
2162
+ user-select: none;
2163
+ -webkit-user-select: none;
2164
+ z-index: 16;
2165
+ transition: background 0.12s, color 0.12s;
2166
+ }
2167
+
2168
+ .tc-row-header:hover,
2169
+ .tc-col-header:hover,
2170
+ .tc-row-header.tc-header-hover,
2171
+ .tc-col-header.tc-header-hover {
2172
+ background: var(--color-accent-bg, #e0f2fe);
2173
+ color: var(--color-accent, #4ade80);
2174
+ }
2175
+
2176
+ /* 左上角全选角标 */
2177
+ .tc-corner-btn {
2178
+ position: absolute;
2179
+ pointer-events: auto;
2180
+ cursor: pointer;
2181
+ display: flex;
2182
+ align-items: center;
2183
+ justify-content: center;
2184
+ background: var(--color-bg-secondary, #f5f5f5);
2185
+ border: 1px solid var(--color-border);
2186
+ z-index: 17;
2187
+ transition: background 0.12s;
2188
+ overflow: hidden;
2189
+ }
2190
+
2191
+ .tc-corner-btn:hover {
2192
+ background: var(--color-accent-bg, #e0f2fe);
2193
+ }
2194
+
2195
+ /* 左上角小三角指示器 */
2196
+ .tc-corner-triangle {
2197
+ position: absolute;
2198
+ right: 2px;
2199
+ bottom: 2px;
2200
+ width: 0;
2201
+ height: 0;
2202
+ border-style: solid;
2203
+ border-width: 0 0 6px 6px;
2204
+ border-color: transparent transparent var(--color-text-tertiary) transparent;
2205
+ transition: border-color 0.12s;
2206
+ }
2207
+
2208
+ .tc-corner-btn:hover .tc-corner-triangle {
2209
+ border-color: transparent transparent var(--color-accent, #4ade80) transparent;
2210
+ }
2211
+
2212
+ /* 列宽拖拽手柄 */
2213
+ .editor-area .tiptap .column-resize-handle {
2214
+ position: absolute;
2215
+ right: -2px;
2216
+ top: 0;
2217
+ bottom: 0;
2218
+ width: 4px;
2219
+ background: var(--color-accent);
2220
+ cursor: col-resize;
2221
+ z-index: 20;
2222
+ pointer-events: auto;
2223
+ }
2224
+
2225
+ .editor-area .tiptap.resize-cursor {
2226
+ cursor: col-resize;
2227
+ }
2228
+
2229
+ /* tableWrapper 由 tiptap table 扩展自动生成 */
2230
+ .editor-area .tiptap .tableWrapper {
2231
+ overflow: visible;
2232
+ margin-bottom: 12px;
2233
+ padding-left: 52px;
2234
+ padding-top: 52px;
2235
+ position: relative;
2236
+ }
2237
+
2238
+ /* Tiptap 任务列表 */
2239
+ .editor-area .tiptap ul[data-type="taskList"] {
2240
+ list-style: none;
2241
+ padding-left: 0;
2242
+ }
2243
+
2244
+ .editor-area .tiptap ul[data-type="taskList"] li {
2245
+ display: flex;
2246
+ align-items: flex-start;
2247
+ gap: 8px;
2248
+ }
2249
+
2250
+ .editor-area .tiptap ul[data-type="taskList"] li label {
2251
+ flex-shrink: 0;
2252
+ margin-top: 3px;
2253
+ }
2254
+
2255
+ .editor-area .tiptap ul[data-type="taskList"] li > div {
2256
+ flex: 1;
2257
+ }
2258
+
2259
+ /* Tiptap 代码块 — 使用自定义 NodeView,复用查看模式的 .code-block-wrapper 样式 */
2260
+ .editor-area .tiptap .editor-code-block {
2261
+ margin-bottom: 12px;
2262
+ }
2263
+
2264
+ /* NodeView 内部的 pre/code 重置 */
2265
+ .editor-area .tiptap .editor-code-block pre {
2266
+ background: transparent;
2267
+ border: none;
2268
+ border-radius: 0;
2269
+ padding: 0;
2270
+ margin: 0;
2271
+ }
2272
+
2273
+ /* 行号 + 编辑区 flex 布局 */
2274
+ .editor-area .tiptap .code-edit-layout {
2275
+ display: flex;
2276
+ }
2277
+
2278
+ /* 行号列:与查看模式 .hljs-ln-numbers 视觉一致 */
2279
+ .editor-area .tiptap .code-line-gutter {
2280
+ display: flex;
2281
+ flex-direction: column;
2282
+ flex-shrink: 0;
2283
+ min-width: 2em;
2284
+ padding: 10px 0;
2285
+ border-right: 1px solid var(--color-pre-border);
2286
+ user-select: none;
2287
+ -webkit-user-select: none;
2288
+ text-align: right;
2289
+ }
2290
+
2291
+ .editor-area .tiptap .code-ln-num {
2292
+ padding: 0 4px;
2293
+ color: var(--color-text-tertiary);
2294
+ opacity: 0.5;
2295
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
2296
+ font-size: 12px;
2297
+ line-height: 1.45;
2298
+ }
2299
+
2300
+ /* 编辑区 */
2301
+ .editor-area .tiptap .code-edit-area {
2302
+ flex: 1;
2303
+ min-width: 0;
2304
+ overflow-x: auto;
2305
+ }
2306
+
2307
+ .editor-area .tiptap .code-edit-area code {
2308
+ background: none;
2309
+ color: var(--color-pre-text);
2310
+ padding: 10px 10px;
2311
+ font-size: 13px;
2312
+ line-height: 1.45;
2313
+ display: block;
2314
+ outline: none;
2315
+ white-space: pre-wrap;
2316
+ word-break: break-all;
2317
+ }
2318
+
2319
+ /* 语言输入框 */
2320
+ .code-lang-input {
2321
+ background: transparent;
2322
+ border: none;
2323
+ outline: none;
2324
+ color: var(--color-text-tertiary);
2325
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
2326
+ font-size: 11px;
2327
+ font-weight: 500;
2328
+ letter-spacing: 0.04em;
2329
+ text-transform: uppercase;
2330
+ width: 80px;
2331
+ padding: 0;
2332
+ }
2333
+
2334
+ /* Tiptap 图片 */
2335
+ .editor-area .tiptap img {
2336
+ max-width: 100%;
2337
+ height: auto;
2338
+ border-radius: 6px;
2339
+ cursor: pointer;
2340
+ }
2341
+
2342
+ .editor-area .tiptap img.ProseMirror-selectednode {
2343
+ outline: 2px solid var(--color-accent);
2344
+ outline-offset: 2px;
2345
+ }
2346
+
2347
+ /* ===== 表格控件层样式 ===== */
2348
+ .table-controls-layer {
2349
+ pointer-events: none;
2350
+ }
2351
+
2352
+ .table-controls-layer .tc-btn {
2353
+ position: absolute;
2354
+ pointer-events: auto;
2355
+ display: flex;
2356
+ align-items: center;
2357
+ justify-content: center;
2358
+ width: 20px;
2359
+ height: 20px;
2360
+ border: 1px solid var(--color-border);
2361
+ border-radius: 4px;
2362
+ background: var(--color-bg);
2363
+ color: var(--color-text-tertiary);
2364
+ cursor: pointer;
2365
+ opacity: 0;
2366
+ transition: opacity 0.12s, background 0.1s, color 0.1s;
2367
+ padding: 0;
2368
+ z-index: 16;
2369
+ }
2370
+
2371
+ /* 按需显示:只有带 tc-visible 的按钮才可见 */
2372
+ .table-controls-layer .tc-btn.tc-visible {
2373
+ opacity: 1;
2374
+ }
2375
+
2376
+ /* 删除按钮 hover 变红 */
2377
+ .table-controls-layer .tc-del-table:hover,
2378
+ .table-controls-layer .tc-del-col:hover,
2379
+ .table-controls-layer .tc-del-row:hover {
2380
+ background: var(--color-error-bg, #fef2f2);
2381
+ border-color: var(--color-error-text, #ef4444);
2382
+ color: var(--color-error-text, #ef4444);
2383
+ }
2384
+
2385
+ /* 添加按钮样式 */
2386
+ .table-controls-layer .tc-add-col,
2387
+ .table-controls-layer .tc-add-row {
2388
+ width: 20px;
2389
+ height: 20px;
2390
+ border-radius: 50%;
2391
+ border: 1px dashed var(--color-border);
2392
+ }
2393
+
2394
+ .table-controls-layer .tc-add-col:hover,
2395
+ .table-controls-layer .tc-add-row:hover {
2396
+ background: var(--color-accent-bg);
2397
+ border-color: var(--color-accent);
2398
+ color: var(--color-accent);
2399
+ border-style: solid;
2400
+ }
2401
+
2402
+ /* ===== 选中单元格后的浮动操作菜单 ===== */
2403
+ .tc-selection-menu {
2404
+ background: var(--color-bg);
2405
+ border: 1px solid var(--color-border);
2406
+ border-radius: 8px;
2407
+ box-shadow: 0 4px 16px var(--color-shadow);
2408
+ padding: 4px;
2409
+ min-width: 140px;
2410
+ pointer-events: auto;
2411
+ }
2412
+
2413
+ .tc-menu-btn {
2414
+ display: block;
2415
+ width: 100%;
2416
+ text-align: left;
2417
+ padding: 6px 12px;
2418
+ border: none;
2419
+ background: transparent;
2420
+ color: var(--color-text);
2421
+ cursor: pointer;
2422
+ border-radius: 4px;
2423
+ font-size: 13px;
2424
+ font-family: inherit;
2425
+ line-height: 1.4;
2426
+ transition: background 0.1s;
2427
+ white-space: nowrap;
2428
+ }
2429
+
2430
+ .tc-menu-btn:hover {
2431
+ background: var(--color-bg-tertiary);
2432
+ }
2433
+
2434
+ .tc-menu-btn.danger {
2435
+ color: var(--color-error-text, #ef4444);
2436
+ }
2437
+
2438
+ .tc-menu-btn.danger:hover {
2439
+ background: var(--color-error-bg, #fef2f2);
2440
+ }
2441
+
2442
+ .tc-menu-sep {
2443
+ height: 1px;
2444
+ background: var(--color-border);
2445
+ margin: 4px 0;
2446
+ }
2447
+
2448
+ /* ===== 表格右键上下文菜单 ===== */
2449
+ .tc-context-menu {
2450
+ background: var(--color-bg);
2451
+ border: 1px solid var(--color-border);
2452
+ border-radius: 8px;
2453
+ box-shadow: 0 4px 16px var(--color-shadow);
2454
+ padding: 4px;
2455
+ min-width: 150px;
2456
+ pointer-events: auto;
2457
+ }
2458
+
2459
+ .tc-context-menu .tc-menu-btn.disabled {
2460
+ opacity: 0.35;
2461
+ cursor: not-allowed;
2462
+ }
2463
+
2464
+ .tc-context-menu .tc-menu-btn.disabled:hover {
2465
+ background: transparent;
2466
+ }
2467
+
2468
+ /* 表格行列选择器 */
2469
+ .table-picker-wrapper {
2470
+ position: relative;
2471
+ }
2472
+
2473
+ .table-picker-dropdown {
2474
+ position: absolute;
2475
+ top: 100%;
2476
+ left: 50%;
2477
+ transform: translateX(-50%);
2478
+ margin-top: 6px;
2479
+ padding: 8px;
2480
+ background: var(--color-bg);
2481
+ border: 1px solid var(--color-border);
2482
+ border-radius: 8px;
2483
+ box-shadow: 0 4px 16px var(--color-shadow);
2484
+ z-index: 100;
2485
+ }
2486
+
2487
+ .table-picker-label {
2488
+ text-align: center;
2489
+ font-size: 12px;
2490
+ color: var(--color-text-secondary);
2491
+ margin-bottom: 6px;
2492
+ font-variant-numeric: tabular-nums;
2493
+ }
2494
+
2495
+ .table-picker-grid {
2496
+ display: flex;
2497
+ flex-direction: column;
2498
+ gap: 3px;
2499
+ }
2500
+
2501
+ .table-picker-row {
2502
+ display: flex;
2503
+ gap: 3px;
2504
+ }
2505
+
2506
+ .table-picker-cell {
2507
+ width: 18px;
2508
+ height: 18px;
2509
+ border: 1px solid var(--color-border);
2510
+ border-radius: 2px;
2511
+ cursor: pointer;
2512
+ transition: all 0.08s;
2513
+ background: var(--color-bg);
2514
+ }
2515
+
2516
+ .table-picker-cell.active {
2517
+ background: var(--color-accent-bg);
2518
+ border-color: var(--color-accent);
2519
+ }
2520
+
2521
+ .table-picker-cell:hover {
2522
+ border-color: var(--color-accent);
2523
+ }
2524
+
2525
+ /* ===== Mermaid 编辑器节点样式 ===== */
2526
+ .mermaid-block-wrapper {
2527
+ margin: 16px 0;
2528
+ }
2529
+
2530
+ .mermaid-preview {
2531
+ position: relative;
2532
+ border: 1px solid var(--color-border);
2533
+ border-radius: 8px;
2534
+ padding: 20px;
2535
+ background: var(--color-bg);
2536
+ text-align: center;
2537
+ }
2538
+
2539
+ .mermaid-preview:hover .mermaid-edit-btn {
2540
+ opacity: 1;
2541
+ }
2542
+
2543
+ .mermaid-edit-btn {
2544
+ position: absolute;
2545
+ top: 8px;
2546
+ right: 8px;
2547
+ z-index: 2;
2548
+ display: flex;
2549
+ align-items: center;
2550
+ justify-content: center;
2551
+ width: 28px;
2552
+ height: 28px;
2553
+ border: 1px solid var(--color-border);
2554
+ border-radius: 6px;
2555
+ background: var(--color-bg);
2556
+ color: var(--color-text-secondary);
2557
+ cursor: pointer;
2558
+ opacity: 0;
2559
+ transition: opacity 0.2s, background 0.15s, color 0.15s;
2560
+ }
2561
+
2562
+ .mermaid-edit-btn:hover {
2563
+ background: var(--color-accent);
2564
+ color: #fff;
2565
+ border-color: var(--color-accent);
2566
+ }
2567
+
2568
+ .mermaid-svg svg {
2569
+ max-width: 100%;
2570
+ height: auto;
2571
+ }
2572
+
2573
+ .mermaid-loading {
2574
+ color: var(--color-text-tertiary);
2575
+ font-size: 13px;
2576
+ padding: 24px 0;
2577
+ }
2578
+
2579
+ .mermaid-error-tip {
2580
+ display: flex;
2581
+ align-items: center;
2582
+ justify-content: center;
2583
+ gap: 12px;
2584
+ color: var(--color-error-text, #d32f2f);
2585
+ font-size: 13px;
2586
+ padding: 24px 0;
2587
+ }
2588
+
2589
+ .mermaid-error-edit {
2590
+ padding: 4px 12px;
2591
+ border: 1px solid var(--color-border);
2592
+ border-radius: 4px;
2593
+ background: var(--color-bg);
2594
+ color: var(--color-accent);
2595
+ font-size: 12px;
2596
+ cursor: pointer;
2597
+ transition: background 0.15s;
2598
+ }
2599
+
2600
+ .mermaid-error-edit:hover {
2601
+ background: var(--color-accent-bg);
2602
+ }
2603
+
2604
+ /* Mermaid 编辑模式 */
2605
+ .mermaid-editor {
2606
+ border: 1px solid var(--color-accent);
2607
+ border-radius: 8px;
2608
+ overflow: hidden;
2609
+ }
2610
+
2611
+ .mermaid-editor-header {
2612
+ display: flex;
2613
+ align-items: center;
2614
+ justify-content: space-between;
2615
+ padding: 6px 12px;
2616
+ background: var(--color-pre-bg);
2617
+ border-bottom: 1px solid var(--color-border);
2618
+ }
2619
+
2620
+ .mermaid-editor-label {
2621
+ font-size: 11px;
2622
+ font-weight: 600;
2623
+ color: var(--color-text-tertiary);
2624
+ letter-spacing: 0.5px;
2625
+ }
2626
+
2627
+ .mermaid-editor-done {
2628
+ display: flex;
2629
+ align-items: center;
2630
+ gap: 4px;
2631
+ padding: 3px 10px;
2632
+ border: none;
2633
+ border-radius: 4px;
2634
+ background: var(--color-accent);
2635
+ color: #fff;
2636
+ font-size: 12px;
2637
+ cursor: pointer;
2638
+ transition: opacity 0.15s;
2639
+ }
2640
+
2641
+ .mermaid-editor-done:hover {
2642
+ opacity: 0.85;
2643
+ }
2644
+
2645
+ .mermaid-editor-textarea {
2646
+ display: block;
2647
+ width: 100%;
2648
+ min-height: 120px;
2649
+ padding: 12px 16px;
2650
+ border: none;
2651
+ outline: none;
2652
+ resize: none;
2653
+ background: var(--color-pre-bg);
2654
+ color: var(--color-pre-text);
2655
+ font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
2656
+ font-size: 13px;
2657
+ line-height: 1.5;
2658
+ tab-size: 2;
2659
+ }
2660
+
2661
+ /* ===== Mermaid 编辑器 NodeView ===== */
2662
+ .mermaid-block-wrapper {
2663
+ position: relative;
2664
+ margin: 16px 0;
2665
+ }
2666
+
2667
+ .mermaid-preview {
2668
+ position: relative;
2669
+ text-align: center;
2670
+ padding: 16px;
2671
+ border: 1px solid var(--color-border-light);
2672
+ border-radius: 6px;
2673
+ background: var(--color-bg);
2674
+ }
2675
+
2676
+ .mermaid-preview:hover .mermaid-edit-btn {
2677
+ opacity: 1;
2678
+ }
2679
+
2680
+ .mermaid-edit-btn {
2681
+ position: absolute;
2682
+ top: 8px;
2683
+ right: 8px;
2684
+ display: flex;
2685
+ align-items: center;
2686
+ justify-content: center;
2687
+ width: 28px;
2688
+ height: 28px;
2689
+ border: 1px solid var(--color-border);
2690
+ border-radius: 4px;
2691
+ background: var(--color-bg);
2692
+ color: var(--color-text-tertiary);
2693
+ cursor: pointer;
2694
+ opacity: 0;
2695
+ transition: all 0.15s;
2696
+ z-index: 2;
2697
+ }
2698
+
2699
+ .mermaid-edit-btn:hover {
2700
+ color: var(--color-accent);
2701
+ border-color: var(--color-accent);
2702
+ background: var(--color-accent-bg);
2703
+ }
2704
+
2705
+ .mermaid-svg svg {
2706
+ max-width: 100%;
2707
+ height: auto;
2708
+ }
2709
+
2710
+ .mermaid-error-tip {
2711
+ display: flex;
2712
+ align-items: center;
2713
+ gap: 8px;
2714
+ justify-content: center;
2715
+ padding: 12px;
2716
+ color: var(--color-error-text);
2717
+ background: var(--color-error-bg);
2718
+ border-radius: 4px;
2719
+ font-size: 13px;
2720
+ }
2721
+
2722
+ .mermaid-error-edit {
2723
+ padding: 2px 8px;
2724
+ border: 1px solid var(--color-error-border);
2725
+ border-radius: 4px;
2726
+ background: transparent;
2727
+ color: var(--color-error-text);
2728
+ cursor: pointer;
2729
+ font-size: 12px;
2730
+ }
2731
+
2732
+ .mermaid-error-edit:hover {
2733
+ background: var(--color-error-bg);
2734
+ }
2735
+
2736
+ .mermaid-loading {
2737
+ padding: 24px;
2738
+ color: var(--color-text-tertiary);
2739
+ font-size: 13px;
2740
+ }
2741
+
2742
+ .mermaid-editor {
2743
+ border: 1px solid var(--color-accent);
2744
+ border-radius: 6px;
2745
+ overflow: hidden;
2746
+ }
2747
+
2748
+ .mermaid-editor-header {
2749
+ display: flex;
2750
+ align-items: center;
2751
+ justify-content: space-between;
2752
+ padding: 4px 12px;
2753
+ background: var(--color-pre-header);
2754
+ border-bottom: 1px solid var(--color-accent);
2755
+ }
2756
+
2757
+ .mermaid-editor-label {
2758
+ font-size: 11px;
2759
+ font-weight: 500;
2760
+ color: var(--color-text-tertiary);
2761
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
2762
+ letter-spacing: 0.04em;
2763
+ }
2764
+
2765
+ .mermaid-editor-done {
2766
+ display: flex;
2767
+ align-items: center;
2768
+ gap: 4px;
2769
+ padding: 2px 8px;
2770
+ border: 1px solid var(--color-accent);
2771
+ border-radius: 4px;
2772
+ background: var(--color-accent);
2773
+ color: #fff;
2774
+ cursor: pointer;
2775
+ font-size: 12px;
2776
+ font-family: inherit;
2777
+ transition: all 0.15s;
2778
+ }
2779
+
2780
+ .mermaid-editor-done:hover {
2781
+ background: var(--color-accent-hover);
2782
+ }
2783
+
2784
+ .mermaid-editor-textarea {
2785
+ width: 100%;
2786
+ min-height: 120px;
2787
+ padding: 12px 16px;
2788
+ border: none;
2789
+ outline: none;
2790
+ background: var(--color-pre-bg);
2791
+ color: var(--color-pre-text);
2792
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
2793
+ font-size: 13px;
2794
+ line-height: 1.45;
2795
+ resize: none;
2796
+ overflow: hidden;
2797
+ }
2798
+
2799
+ /* ===== 树节点操作按钮 ===== */
2800
+ .nav-item-actions {
2801
+ display: none;
2802
+ align-items: center;
2803
+ gap: 2px;
2804
+ margin-left: auto;
2805
+ flex-shrink: 0;
2806
+ padding-left: 4px;
2807
+ }
2808
+
2809
+ .nav-item:hover .nav-item-actions {
2810
+ display: flex;
2811
+ }
2812
+
2813
+ .nav-item-btn {
2814
+ display: flex;
2815
+ align-items: center;
2816
+ justify-content: center;
2817
+ width: 20px;
2818
+ height: 20px;
2819
+ border: none;
2820
+ background: transparent;
2821
+ color: var(--color-text-tertiary);
2822
+ cursor: pointer;
2823
+ border-radius: 4px;
2824
+ padding: 0;
2825
+ transition: all 0.1s;
2826
+ }
2827
+
2828
+ .nav-item-btn:hover {
2829
+ background: var(--color-bg-tertiary);
2830
+ color: var(--color-text-secondary);
2831
+ }
2832
+
2833
+ .nav-item-btn-danger:hover {
2834
+ background: var(--color-error-bg);
2835
+ color: var(--color-error-text);
2836
+ }
2837
+
2838
+ /* ===== 拖拽排序 ===== */
2839
+ .drag-ghost {
2840
+ opacity: 0.4;
2841
+ background: var(--color-accent-bg);
2842
+ border-radius: 6px;
2843
+ }
2844
+
2845
+ .drag-ghost .nav-item {
2846
+ background: var(--color-accent-bg);
2847
+ }
2848
+
2849
+ .drag-chosen {
2850
+ opacity: 1;
2851
+ }
2852
+
2853
+ .drag-chosen > .nav-item {
2854
+ background: var(--color-bg-tertiary);
2855
+ box-shadow: 0 2px 8px var(--color-shadow);
2856
+ border-radius: 6px;
2857
+ }
2858
+
2859
+ .drag-active {
2860
+ opacity: 0.9;
2861
+ cursor: grabbing !important;
2862
+ }
2863
+
2864
+ /* 文件夹拖拽悬停高亮 */
2865
+ .nav-item.drag-over {
2866
+ background: var(--color-accent-bg);
2867
+ outline: 2px dashed var(--color-accent);
2868
+ outline-offset: -2px;
2869
+ border-radius: 6px;
2870
+ }
2871
+
2872
+ /* 拖拽时隐藏操作按钮 */
2873
+ .sortable-drag .nav-item-actions,
2874
+ .sortable-ghost .nav-item-actions {
2875
+ display: none !important;
2876
+ }
2877
+
2878
+ /* 拖拽时的光标 */
2879
+ .nav-item {
2880
+ cursor: grab;
2881
+ }
2882
+
2883
+ .nav-item:active {
2884
+ cursor: grabbing;
2885
+ }
2886
+
2887
+ /* ===== 右键菜单 ===== */
2888
+ .ctx-menu-overlay {
2889
+ position: fixed;
2890
+ inset: 0;
2891
+ z-index: 9998;
2892
+ }
2893
+
2894
+ .ctx-menu {
2895
+ background: var(--color-bg);
2896
+ border: 1px solid var(--color-border);
2897
+ border-radius: 8px;
2898
+ box-shadow: 0 4px 16px var(--color-shadow);
2899
+ padding: 4px;
2900
+ min-width: 140px;
2901
+ z-index: 9999;
2902
+ }
2903
+
2904
+ .ctx-menu-item {
2905
+ display: flex;
2906
+ align-items: center;
2907
+ gap: 8px;
2908
+ padding: 6px 10px;
2909
+ border-radius: 6px;
2910
+ cursor: pointer;
2911
+ font-size: 13px;
2912
+ color: var(--color-text);
2913
+ transition: all 0.1s;
2914
+ }
2915
+
2916
+ .ctx-menu-item:hover {
2917
+ background: var(--color-accent-bg);
2918
+ color: var(--color-accent);
2919
+ }
2920
+
2921
+ /* ===== 模态弹窗 ===== */
2922
+ .modal-overlay {
2923
+ position: fixed;
2924
+ inset: 0;
2925
+ background: rgba(0, 0, 0, 0.4);
2926
+ display: flex;
2927
+ align-items: center;
2928
+ justify-content: center;
2929
+ z-index: 10000;
2930
+ }
2931
+
2932
+ .modal-dialog {
2933
+ background: var(--color-bg);
2934
+ border: 1px solid var(--color-border);
2935
+ border-radius: 12px;
2936
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
2937
+ padding: 20px 24px;
2938
+ min-width: 320px;
2939
+ max-width: 420px;
2940
+ }
2941
+
2942
+ .modal-title {
2943
+ font-size: 15px;
2944
+ font-weight: 600;
2945
+ color: var(--color-text);
2946
+ margin-bottom: 12px;
2947
+ }
2948
+
2949
+ .modal-message {
2950
+ font-size: 13px;
2951
+ color: var(--color-text-secondary);
2952
+ line-height: 1.6;
2953
+ margin-bottom: 16px;
2954
+ }
2955
+
2956
+ .modal-warning {
2957
+ color: var(--color-error-text);
2958
+ font-size: 12px;
2959
+ }
2960
+
2961
+ .modal-input {
2962
+ width: 100%;
2963
+ padding: 8px 12px;
2964
+ border: 1px solid var(--color-border);
2965
+ border-radius: 6px;
2966
+ font-size: 13px;
2967
+ color: var(--color-text);
2968
+ background: var(--color-bg);
2969
+ outline: none;
2970
+ font-family: inherit;
2971
+ margin-bottom: 8px;
2972
+ transition: border-color 0.15s;
2973
+ }
2974
+
2975
+ .modal-input:focus {
2976
+ border-color: var(--color-accent);
2977
+ box-shadow: 0 0 0 3px var(--color-accent-bg);
2978
+ }
2979
+
2980
+ .modal-error {
2981
+ font-size: 12px;
2982
+ color: var(--color-error-text);
2983
+ margin-bottom: 8px;
2984
+ }
2985
+
2986
+ .modal-actions {
2987
+ display: flex;
2988
+ justify-content: flex-end;
2989
+ gap: 8px;
2990
+ margin-top: 16px;
2991
+ }
2992
+
2993
+ .modal-btn {
2994
+ padding: 6px 16px;
2995
+ border: 1px solid var(--color-border);
2996
+ border-radius: 6px;
2997
+ font-size: 13px;
2998
+ font-family: inherit;
2999
+ cursor: pointer;
3000
+ transition: all 0.15s;
3001
+ }
3002
+
3003
+ .modal-btn-cancel {
3004
+ background: var(--color-bg);
3005
+ color: var(--color-text-secondary);
3006
+ }
3007
+
3008
+ .modal-btn-cancel:hover {
3009
+ background: var(--color-bg-tertiary);
3010
+ color: var(--color-text);
3011
+ }
3012
+
3013
+ .modal-btn-confirm {
3014
+ background: var(--color-accent);
3015
+ color: #fff;
3016
+ border-color: var(--color-accent);
3017
+ }
3018
+
3019
+ .modal-btn-confirm:hover {
3020
+ background: var(--color-accent-hover);
3021
+ border-color: var(--color-accent-hover);
3022
+ }
3023
+
3024
+ .modal-btn-danger {
3025
+ background: var(--color-error-bg);
3026
+ color: var(--color-error-text);
3027
+ border-color: var(--color-error-border);
3028
+ }
3029
+
3030
+ .modal-btn-danger:hover {
3031
+ background: var(--color-error-text);
3032
+ color: #fff;
3033
+ border-color: var(--color-error-text);
3034
+ }
3035
+
3036
+ /* ===== Popover 气泡 ===== */
3037
+ .popover-overlay {
3038
+ position: fixed;
3039
+ inset: 0;
3040
+ z-index: 10000;
3041
+ }
3042
+
3043
+ .popover-bubble {
3044
+ background: var(--color-bg);
3045
+ border: 1px solid var(--color-border);
3046
+ border-radius: 10px;
3047
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
3048
+ padding: 12px 14px;
3049
+ min-width: 220px;
3050
+ max-width: 280px;
3051
+ }
3052
+
3053
+ .popover-input {
3054
+ width: 100%;
3055
+ padding: 6px 10px;
3056
+ border: 1px solid var(--color-border);
3057
+ border-radius: 6px;
3058
+ font-size: 13px;
3059
+ color: var(--color-text);
3060
+ background: var(--color-bg);
3061
+ outline: none;
3062
+ font-family: inherit;
3063
+ transition: border-color 0.15s;
3064
+ box-sizing: border-box;
3065
+ }
3066
+
3067
+ .popover-input:focus {
3068
+ border-color: var(--color-accent);
3069
+ box-shadow: 0 0 0 2px var(--color-accent-bg);
3070
+ }
3071
+
3072
+ .popover-error {
3073
+ font-size: 12px;
3074
+ color: var(--color-error-text);
3075
+ margin-top: 4px;
3076
+ }
3077
+
3078
+ .popover-message {
3079
+ font-size: 13px;
3080
+ color: var(--color-text-secondary);
3081
+ line-height: 1.5;
3082
+ }
3083
+
3084
+ .popover-warning {
3085
+ color: var(--color-error-text);
3086
+ font-size: 12px;
3087
+ }
3088
+
3089
+ .popover-actions {
3090
+ display: flex;
3091
+ justify-content: flex-end;
3092
+ gap: 6px;
3093
+ margin-top: 10px;
3094
+ }
3095
+
3096
+ .popover-btn {
3097
+ padding: 4px 12px;
3098
+ border: 1px solid var(--color-border);
3099
+ border-radius: 6px;
3100
+ font-size: 12px;
3101
+ font-family: inherit;
3102
+ cursor: pointer;
3103
+ transition: all 0.15s;
3104
+ }
3105
+
3106
+ .popover-btn-cancel {
3107
+ background: var(--color-bg);
3108
+ color: var(--color-text-secondary);
3109
+ }
3110
+
3111
+ .popover-btn-cancel:hover {
3112
+ background: var(--color-bg-tertiary);
3113
+ color: var(--color-text);
3114
+ }
3115
+
3116
+ .popover-btn-confirm {
3117
+ background: var(--color-accent);
3118
+ color: #fff;
3119
+ border-color: var(--color-accent);
3120
+ }
3121
+
3122
+ .popover-btn-confirm:hover {
3123
+ background: var(--color-accent-hover);
3124
+ border-color: var(--color-accent-hover);
3125
+ }
3126
+
3127
+ .popover-btn-danger {
3128
+ background: var(--color-error-bg);
3129
+ color: var(--color-error-text);
3130
+ border-color: var(--color-error-border);
3131
+ }
3132
+
3133
+ .popover-btn-danger:hover {
3134
+ background: var(--color-error-text);
3135
+ color: #fff;
3136
+ border-color: var(--color-error-text);
3137
+ }
3138
+
3139
+ /* ===== 数学公式 (KaTeX) ===== */
3140
+ .markdown-content .math-block {
3141
+ margin: 16px 0;
3142
+ overflow-x: auto;
3143
+ padding: 12px 0;
3144
+ text-align: center;
3145
+ }
3146
+
3147
+ .markdown-content .math-error {
3148
+ color: var(--color-error-text);
3149
+ background: var(--color-error-bg);
3150
+ padding: 4px 8px;
3151
+ border-radius: 4px;
3152
+ font-size: 13px;
3153
+ }
3154
+
3155
+ /* ===== 块级公式编辑器 NodeView ===== */
3156
+ .math-block-wrapper {
3157
+ position: relative;
3158
+ margin: 16px 0;
3159
+ }
3160
+
3161
+ .math-block-preview {
3162
+ position: relative;
3163
+ text-align: center;
3164
+ padding: 20px 16px;
3165
+ border: 1px solid var(--color-border-light);
3166
+ border-radius: 6px;
3167
+ background: var(--color-bg);
3168
+ cursor: pointer;
3169
+ transition: border-color 0.15s;
3170
+ }
3171
+
3172
+ .math-block-preview:hover {
3173
+ border-color: var(--color-accent);
3174
+ }
3175
+
3176
+ .math-block-preview:hover .math-block-edit-btn {
3177
+ opacity: 1;
3178
+ }
3179
+
3180
+ .math-block-edit-btn {
3181
+ position: absolute;
3182
+ top: 8px;
3183
+ right: 8px;
3184
+ display: flex;
3185
+ align-items: center;
3186
+ justify-content: center;
3187
+ width: 28px;
3188
+ height: 28px;
3189
+ border: 1px solid var(--color-border);
3190
+ border-radius: 4px;
3191
+ background: var(--color-bg);
3192
+ color: var(--color-text-tertiary);
3193
+ cursor: pointer;
3194
+ opacity: 0;
3195
+ transition: all 0.15s;
3196
+ z-index: 2;
3197
+ }
3198
+
3199
+ .math-block-edit-btn:hover {
3200
+ color: var(--color-accent);
3201
+ border-color: var(--color-accent);
3202
+ background: var(--color-accent-bg);
3203
+ }
3204
+
3205
+ .math-block-rendered .katex-display {
3206
+ margin: 0;
3207
+ }
3208
+
3209
+ .math-block-empty {
3210
+ padding: 24px;
3211
+ color: var(--color-text-tertiary);
3212
+ font-size: 13px;
3213
+ cursor: pointer;
3214
+ }
3215
+
3216
+ .math-block-error-tip {
3217
+ display: flex;
3218
+ align-items: center;
3219
+ gap: 8px;
3220
+ justify-content: center;
3221
+ padding: 12px;
3222
+ color: var(--color-error-text);
3223
+ background: var(--color-error-bg);
3224
+ border-radius: 4px;
3225
+ font-size: 13px;
3226
+ }
3227
+
3228
+ .math-block-error-edit {
3229
+ padding: 2px 8px;
3230
+ border: 1px solid var(--color-error-border);
3231
+ border-radius: 4px;
3232
+ background: transparent;
3233
+ color: var(--color-error-text);
3234
+ cursor: pointer;
3235
+ font-size: 12px;
3236
+ }
3237
+
3238
+ .math-block-error-edit:hover {
3239
+ background: var(--color-error-bg);
3240
+ }
3241
+
3242
+ /* 块级公式编辑模式 */
3243
+ .math-block-editor {
3244
+ border: 1px solid var(--color-accent);
3245
+ border-radius: 6px;
3246
+ overflow: hidden;
3247
+ }
3248
+
3249
+ .math-block-editor-header {
3250
+ display: flex;
3251
+ align-items: center;
3252
+ justify-content: space-between;
3253
+ padding: 4px 12px;
3254
+ background: var(--color-pre-header);
3255
+ border-bottom: 1px solid var(--color-border-light);
3256
+ }
3257
+
3258
+ .math-block-editor-label {
3259
+ font-size: 11px;
3260
+ font-weight: 500;
3261
+ color: var(--color-text-tertiary);
3262
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
3263
+ letter-spacing: 0.04em;
3264
+ }
3265
+
3266
+ .math-block-editor-actions {
3267
+ display: flex;
3268
+ align-items: center;
3269
+ gap: 6px;
3270
+ }
3271
+
3272
+ .math-block-editor-delete {
3273
+ display: flex;
3274
+ align-items: center;
3275
+ justify-content: center;
3276
+ width: 28px;
3277
+ height: 28px;
3278
+ border: 1px solid var(--color-border);
3279
+ border-radius: 4px;
3280
+ background: transparent;
3281
+ color: var(--color-text-tertiary);
3282
+ cursor: pointer;
3283
+ font-size: 12px;
3284
+ font-family: inherit;
3285
+ transition: all 0.15s;
3286
+ }
3287
+
3288
+ .math-block-editor-delete:hover {
3289
+ color: var(--color-error-text);
3290
+ border-color: var(--color-error-text);
3291
+ background: var(--color-error-bg);
3292
+ }
3293
+
3294
+ .math-block-editor-done {
3295
+ display: flex;
3296
+ align-items: center;
3297
+ gap: 4px;
3298
+ padding: 2px 8px;
3299
+ border: 1px solid var(--color-accent);
3300
+ border-radius: 4px;
3301
+ background: var(--color-accent);
3302
+ color: #fff;
3303
+ cursor: pointer;
3304
+ font-size: 12px;
3305
+ font-family: inherit;
3306
+ transition: all 0.15s;
3307
+ }
3308
+
3309
+ .math-block-editor-done:hover {
3310
+ background: var(--color-accent-hover);
3311
+ }
3312
+
3313
+ .math-block-editor-textarea {
3314
+ width: 100%;
3315
+ min-height: 60px;
3316
+ padding: 12px 16px;
3317
+ border: none;
3318
+ outline: none;
3319
+ background: var(--color-pre-bg);
3320
+ color: var(--color-pre-text);
3321
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
3322
+ font-size: 13px;
3323
+ line-height: 1.6;
3324
+ resize: none;
3325
+ overflow: hidden;
3326
+ }
3327
+
3328
+ .math-block-editor-textarea::placeholder {
3329
+ color: var(--color-text-tertiary);
3330
+ opacity: 0.6;
3331
+ }
3332
+
3333
+ /* 实时预览区 */
3334
+ .math-block-live-preview {
3335
+ padding: 16px;
3336
+ text-align: center;
3337
+ border-top: 1px dashed var(--color-border-light);
3338
+ background: var(--color-bg);
3339
+ min-height: 48px;
3340
+ }
3341
+
3342
+ .math-block-live-rendered .katex-display {
3343
+ margin: 0;
3344
+ }
3345
+
3346
+ .math-block-live-error {
3347
+ color: var(--color-error-text);
3348
+ font-size: 12px;
3349
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
3350
+ }
3351
+
3352
+ .math-block-live-placeholder {
3353
+ color: var(--color-text-tertiary);
3354
+ font-size: 12px;
3355
+ }
3356
+
3357
+ /* ===== 行内公式 NodeView ===== */
3358
+ .math-inline-wrapper {
3359
+ display: inline;
3360
+ position: relative;
3361
+ }
3362
+
3363
+ .math-inline-rendered {
3364
+ display: inline;
3365
+ cursor: pointer;
3366
+ border-radius: 3px;
3367
+ padding: 0 2px;
3368
+ transition: background 0.15s;
3369
+ }
3370
+
3371
+ .math-inline-rendered:hover {
3372
+ background: var(--color-accent-bg);
3373
+ }
3374
+
3375
+ .math-inline-selected {
3376
+ background: var(--color-accent-bg);
3377
+ outline: 2px solid var(--color-accent);
3378
+ outline-offset: 1px;
3379
+ border-radius: 3px;
3380
+ }
3381
+
3382
+ .math-inline-error {
3383
+ display: inline;
3384
+ padding: 1px 4px;
3385
+ background: var(--color-error-bg);
3386
+ color: var(--color-error-text);
3387
+ border-radius: 3px;
3388
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
3389
+ font-size: 0.9em;
3390
+ cursor: pointer;
3391
+ }
3392
+
3393
+ /* 行内公式编辑浮层 */
3394
+ .math-inline-popover {
3395
+ position: absolute;
3396
+ top: calc(100% + 6px);
3397
+ left: 50%;
3398
+ transform: translateX(-50%);
3399
+ z-index: 100;
3400
+ min-width: 280px;
3401
+ max-width: 420px;
3402
+ background: var(--color-bg);
3403
+ border: 1px solid var(--color-border);
3404
+ border-radius: 8px;
3405
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
3406
+ overflow: hidden;
3407
+ }
3408
+
3409
+ .math-inline-popover-header {
3410
+ display: flex;
3411
+ align-items: center;
3412
+ justify-content: space-between;
3413
+ padding: 6px 10px;
3414
+ background: var(--color-pre-header);
3415
+ border-bottom: 1px solid var(--color-border-light);
3416
+ }
3417
+
3418
+ .math-inline-popover-label {
3419
+ font-size: 11px;
3420
+ font-weight: 500;
3421
+ color: var(--color-text-tertiary);
3422
+ }
3423
+
3424
+ .math-inline-popover-actions {
3425
+ display: flex;
3426
+ align-items: center;
3427
+ gap: 4px;
3428
+ }
3429
+
3430
+ .math-inline-popover-btn {
3431
+ display: flex;
3432
+ align-items: center;
3433
+ justify-content: center;
3434
+ width: 24px;
3435
+ height: 24px;
3436
+ border: 1px solid var(--color-border);
3437
+ border-radius: 4px;
3438
+ background: transparent;
3439
+ color: var(--color-text-tertiary);
3440
+ cursor: pointer;
3441
+ transition: all 0.15s;
3442
+ }
3443
+
3444
+ .math-inline-popover-btn.done:hover {
3445
+ color: var(--color-accent);
3446
+ border-color: var(--color-accent);
3447
+ background: var(--color-accent-bg);
3448
+ }
3449
+
3450
+ .math-inline-popover-btn.delete:hover {
3451
+ color: var(--color-error-text);
3452
+ border-color: var(--color-error-border);
3453
+ background: var(--color-error-bg);
3454
+ }
3455
+
3456
+ .math-inline-popover-input {
3457
+ display: block;
3458
+ width: 100%;
3459
+ padding: 8px 12px;
3460
+ border: none;
3461
+ outline: none;
3462
+ background: var(--color-pre-bg);
3463
+ color: var(--color-pre-text);
3464
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
3465
+ font-size: 13px;
3466
+ line-height: 1.5;
3467
+ }
3468
+
3469
+ .math-inline-popover-input::placeholder {
3470
+ color: var(--color-text-tertiary);
3471
+ opacity: 0.6;
3472
+ }
3473
+
3474
+ .math-inline-popover-preview {
3475
+ padding: 8px 12px;
3476
+ text-align: center;
3477
+ border-top: 1px dashed var(--color-border-light);
3478
+ min-height: 32px;
3479
+ display: flex;
3480
+ align-items: center;
3481
+ justify-content: center;
3482
+ }
3483
+
3484
+ .math-inline-popover-error {
3485
+ color: var(--color-error-text);
3486
+ font-size: 11px;
3487
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
3488
+ }
3489
+
3490
+ /* 工具栏公式按钮 */
3491
+ .math-toolbar-btn {
3492
+ min-width: 28px;
3493
+ }
3494
+
3495
+ .math-toolbar-icon {
3496
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
3497
+ font-size: 12px;
3498
+ font-weight: 600;
3499
+ line-height: 1;
3500
+ }
3501
+
3502
+ /* ===== 文档最后更新时间 ===== */
3503
+ .doc-last-modified {
3504
+ display: flex;
3505
+ align-items: center;
3506
+ gap: 6px;
3507
+ width: 100%;
3508
+ max-width: 960px;
3509
+ margin: 0 auto;
3510
+ padding: 12px 32px 24px;
3511
+ font-size: 12px;
3512
+ color: var(--color-text-tertiary);
3513
+ border-top: 1px solid var(--color-border-light);
3514
+ }
3515
+
3516
+ .doc-last-modified svg {
3517
+ flex-shrink: 0;
3518
+ }
3519
+
3520
+ @media (max-width: 768px) {
3521
+ .doc-last-modified {
3522
+ padding: 12px 16px 24px;
3523
+ }
3524
+ }