* { box-sizing: border-box; } html, body, #root { margin: 0; height: 100%; } /* 全局统一字体栈——消灭按钮/输入框回退到 Arial 的观感不一致(A档-1) */ body { font-family: system-ui, -apple-system, 'Segoe UI', 'Microsoft YaHei', 'PingFang SC', 'Noto Sans CJK SC', sans-serif; color: var(--text-primary); -webkit-font-smoothing: antialiased; } button, input, select, textarea { font-family: inherit; } svg { display: block; } /* 自定义滚动条——细+半透明+圆角 */ ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: var(--control-border); border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { background: var(--text-tertiary); } * { scrollbar-width: thin; scrollbar-color: var(--control-border) transparent; } /* Tiptap 编辑器正文(B档-7 排版打磨:CJK 阅读优化、标题层级、选区、引用/链接/表格) */ .tiptap-wrap .ProseMirror { font-size: var(--editor-font-size, 14px) !important; font-family: var(--editor-font-family, 'Microsoft YaHei', 'Source Han Sans SC', system-ui, sans-serif) !important; white-space: var(--editor-white-space, pre-wrap); min-height: 100%; /* 底部加大留白:长文档写到末尾时,光标行不会贴着编辑区底缘(配合光标跟随滚动) */ padding: 16px 24px 140px; line-height: 1.8; color: var(--text-primary); outline: none; max-width: 860px; margin: 0 auto; caret-color: var(--accent); } /* 兜底:去掉拼写/语法错误的红色波浪下划线(即使个别 contenteditable 仍开启 spellcheck) */ .tiptap-wrap [contenteditable="true"] :spelling-error, .tiptap-wrap [contenteditable="true"] :grammar-error, .tiptap-wrap .ProseMirror :spelling-error, .tiptap-wrap .ProseMirror :grammar-error { text-decoration: none; } .tiptap-wrap .ProseMirror p { margin: 0.6em 0; } .tiptap-wrap .ProseMirror h1 { font-size: 1.8em; margin: 1em 0 0.5em; font-weight: 700; color: var(--text-primary); padding-bottom: 0.25em; border-bottom: 1px solid var(--control-border); } .tiptap-wrap .ProseMirror h2 { font-size: 1.5em; margin: 0.9em 0 0.45em; font-weight: 600; color: var(--text-primary); } .tiptap-wrap .ProseMirror h3 { font-size: 1.25em; margin: 0.8em 0 0.4em; font-weight: 600; color: var(--text-primary); } .tiptap-wrap .ProseMirror h4, .tiptap-wrap .ProseMirror h5, .tiptap-wrap .ProseMirror h6 { margin: 0.7em 0 0.35em; font-weight: 600; } .tiptap-wrap .ProseMirror code { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent-text); padding: 1px 5px; border-radius: 4px; font-family: 'Consolas', 'Source Code Pro', monospace; } .tiptap-wrap .ProseMirror pre { background: var(--bg-secondary); padding: 12px 16px; border-radius: var(--radius-md); overflow: auto; border: 1px solid var(--control-border); } .tiptap-wrap .ProseMirror pre code { background: none; padding: 0; color: inherit; } .tiptap-wrap .ProseMirror a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; } .tiptap-wrap .ProseMirror ::selection { background: color-mix(in srgb, var(--accent) 30%, transparent); } /* B档-7:光标所在行高亮(TiptapEditor 动态加类) */ .tiptap-wrap .ProseMirror .is-active-line { background: color-mix(in srgb, var(--accent) 6%, transparent); border-radius: 4px; } .tiptap-wrap .ProseMirror table th { background: color-mix(in srgb, var(--accent) 10%, transparent); font-weight: 600; } /* highlight.js 暗色主题(CodeBlockLowlight 装饰 span,FR-E5) */ .tiptap-wrap .ProseMirror .hljs { color: #abb2bf; } .tiptap-wrap .ProseMirror .hljs-comment, .tiptap-wrap .ProseMirror .hljs-quote { color: #5c6370; font-style: italic; } .tiptap-wrap .ProseMirror .hljs-doctag, .tiptap-wrap .ProseMirror .hljs-keyword, .tiptap-wrap .ProseMirror .hljs-formula, .tiptap-wrap .ProseMirror .hljs-selector-tag, .tiptap-wrap .ProseMirror .hljs-tag { color: #c678dd; } .tiptap-wrap .ProseMirror .hljs-name, .tiptap-wrap .ProseMirror .hljs-section { color: #61afef; } .tiptap-wrap .ProseMirror .hljs-addition, .tiptap-wrap .ProseMirror .hljs-attribute, .tiptap-wrap .ProseMirror .hljs-attr, .tiptap-wrap .ProseMirror .hljs-string, .tiptap-wrap .ProseMirror .hljs-template-tag, .tiptap-wrap .ProseMirror .hljs-template-variable, .tiptap-wrap .ProseMirror .hljs-value { color: #98c379; } .tiptap-wrap .ProseMirror .hljs-built_in, .tiptap-wrap .ProseMirror .hljs-class .hljs-title, .tiptap-wrap .ProseMirror .hljs-title, .tiptap-wrap .ProseMirror .hljs-title.class_, .tiptap-wrap .ProseMirror .hljs-type { color: #e6c07b; } .tiptap-wrap .ProseMirror .hljs-function .hljs-title, .tiptap-wrap .ProseMirror .hljs-title.function_ { color: #61afef; } .tiptap-wrap .ProseMirror .hljs-literal, .tiptap-wrap .ProseMirror .hljs-number, .tiptap-wrap .ProseMirror .hljs-operator, .tiptap-wrap .ProseMirror .hljs-variable, .tiptap-wrap .ProseMirror .hljs-params { color: #d19a66; } .tiptap-wrap .ProseMirror .hljs-bullet, .tiptap-wrap .ProseMirror .hljs-link, .tiptap-wrap .ProseMirror .hljs-meta, .tiptap-wrap .ProseMirror .hljs-regexp, .tiptap-wrap .ProseMirror .hljs-selector-attr, .tiptap-wrap .ProseMirror .hljs-selector-class, .tiptap-wrap .ProseMirror .hljs-selector-id, .tiptap-wrap .ProseMirror .hljs-symbol, .tiptap-wrap .ProseMirror .hljs-variable.constant_ { color: #56b6c2; } .tiptap-wrap .ProseMirror .hljs-deletion { color: #d19a66; } .tiptap-wrap .ProseMirror .hljs-emphasis { font-style: italic; } .tiptap-wrap .ProseMirror .hljs-strong { font-weight: 700; } /* highlight.js 浅色主题——当 --bg-primary 为浅色时生效(latte/daylight/plain) */ :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs { color: #24292e; } :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-comment, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-quote { color: #6a737d; } :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-doctag, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-keyword, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-formula, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-selector-tag, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-tag { color: #8250df; } :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-name, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-section { color: #0969da; } :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-addition, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-attribute, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-attr, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-string, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-template-tag, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-template-variable, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-value { color: #032f62; } :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-built_in, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-class .hljs-title, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-title, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-title.class_, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-type { color: #6f42c1; } :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-function .hljs-title, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-title.function_ { color: #005cc5; } :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-literal, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-number, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-operator, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-variable, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-params { color: #005cc5; } :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-bullet, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-link, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-meta, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-regexp, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-selector-attr, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-selector-class, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-selector-id, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-symbol, :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-variable.constant_ { color: #005cc5; } :root[data-theme-group="light"] .tiptap-wrap .ProseMirror .hljs-deletion { color: #6a737d; } /* FR-E11 查找高亮 */ .tiptap-wrap .ProseMirror .find-match { background: rgba(255, 213, 79, 0.35); border-radius: 2px; } .tiptap-wrap .ProseMirror .find-match-active { background: rgba(255, 145, 0, 0.65); } /* FR-O2:标题闪烁高亮——使用主题变量,确保动画结束完全透明 */ @keyframes outline-flash-anim { 0% { background: var(--flash-bg, rgba(127,127,127,0.3)); } 100% { background: transparent; } } .tiptap-wrap .ProseMirror h1.outline-flash, .tiptap-wrap .ProseMirror h2.outline-flash, .tiptap-wrap .ProseMirror h3.outline-flash, .tiptap-wrap .ProseMirror h4.outline-flash, .tiptap-wrap .ProseMirror h5.outline-flash, .tiptap-wrap .ProseMirror h6.outline-flash { animation: outline-flash-anim 1.2s ease-out forwards; border-radius: 4px; } /* FR-O3:大纲项 hover + 当前项高亮——用 CSS :hover 避免内联 style 竞态 */ .outline-item:hover { background: var(--control-border); } .outline-item-active { background: var(--control-border) !important; border-left: 2px solid var(--accent) !important; } .tiptap-wrap .ProseMirror blockquote { border-left: 3px solid var(--accent); padding: 4px 16px; color: var(--text-secondary); margin: 0.6em 0; background: color-mix(in srgb, var(--accent) 8%, transparent); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; } .tiptap-wrap .ProseMirror ul, .tiptap-wrap .ProseMirror ol { padding-left: 24px; } .tiptap-wrap .ProseMirror table { border-collapse: collapse; } .tiptap-wrap .ProseMirror th, .tiptap-wrap .ProseMirror td { border: 1px solid var(--control-border); padding: 4px 8px; } .tiptap-wrap .ProseMirror p.is-editor-empty:first-child::before { content: attr(data-placeholder); color: var(--text-tertiary); pointer-events: none; float: left; } /* FR-X2:打印/另存为 PDF 干净排版 + 代码语法高亮 */ @media print { body * { visibility: hidden; } ::-webkit-scrollbar { display: none !important; } * { scrollbar-width: none !important; } .tiptap-wrap, .tiptap-wrap * { visibility: visible; } .tiptap-wrap { position: absolute; left: 0; top: 0; width: 100%; padding: 20px; overflow: visible !important; } .tiptap-wrap .ProseMirror { font-size: 14px !important; color: #000 !important; overflow: visible !important; } .tiptap-wrap .ProseMirror pre { background: #f4f4f4 !important; color: #333 !important; border: 1px solid #ddd; padding: 8px; border-radius: 4px; overflow: visible !important; } .tiptap-wrap .ProseMirror pre code { color: #333; } .tiptap-wrap .ProseMirror h1, .tiptap-wrap .ProseMirror h2, .tiptap-wrap .ProseMirror h3 { color: #000; } .tiptap-wrap .ProseMirror blockquote { border-color: #ccc; color: #555; } .tiptap-wrap .ProseMirror a { color: #0066cc; text-decoration: underline; } } /* FR-A12:统一过渡动效 */ button { transition: background 0.15s, color 0.15s, opacity 0.15s; } button:hover { opacity: 0.85; } /* B档-5:标题栏控制按钮 hover 背景 */ .titlebar-controls button:hover { opacity: 1; background: var(--control-border); } .titlebar-controls button:last-child:hover { background: #e81123; color: #fff; } @keyframes panel-slide-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } } .panel-slide-in { animation: panel-slide-in 0.2s ease-out; }