/* ==================== 1. 全局 ==================== */ body, html { margin: 0; padding: 0; font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, sans-serif; background-color: #ffffff; color: #333; overflow-x: hidden; /* 🌟 不再给 html/body 设 height:100%(会让 body 退化为内部滚动容器, 导致 window.scrollY/scrollTo 失效;视口高度由 #chat-container 的 min-height:100vh 承担) */ } #chat-container { max-width: 95%; margin: 0 auto; padding: 20px 20px 20px 20px; min-height: 100vh; /* 🌟 至少占满整个视口高度 */ } /* ==================== 隐藏 WebEngine 原生滚动条 ==================== */ /* 改用右侧自定义 Qt 滚动条(WebScrollBar),避免内置滚动条高速滑动时的重绘延迟观感 */ ::-webkit-scrollbar { width: 0px; height: 0px; background: transparent; } /* ==================== 会话加载界面 ==================== */ .session-loading { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 999; display: flex; align-items: center; justify-content: center; background-color: #ffffff; opacity: 1; transition: opacity 0.45s ease; /* 结束后的渐变退场 */ } .session-loading.hide { opacity: 0; pointer-events: none; } .session-loading-box { display: flex; flex-direction: column; align-items: center; } .session-loading-icon { width: 72px; height: 72px; } .session-loading-bar { width: 190px; height: 4px; margin-top: 26px; background: #eceef2; border-radius: 2px; overflow: hidden; position: relative; } .session-loading-bar-fill { position: absolute; top: 0; left: 0; height: 100%; width: 36%; border-radius: 2px; background: linear-gradient(90deg, rgba(59,130,246,0) 0%, #3b82f6 50%, rgba(59,130,246,0) 100%); animation: loadingSweep 1.2s ease-in-out infinite; /* 从左到右扫描,非进度条 */ } @keyframes loadingSweep { 0% { transform: translateX(-110%); } 100% { transform: translateX(300%); } } /* ==================== 欢迎界面 ==================== */ .welcome-screen { display: flex; justify-content: center; align-items: center; position: fixed; /* 🌟 固定定位,脱离文档流 */ top: 0; left: 0; right: 0; bottom: 0; padding: 60px 20px; pointer-events: none; /* 🌟 允许点击穿透到下方的输入框 */ } .welcome-content { display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; pointer-events: auto; /* 🌟 但内容本身可以交互 */ /* 旧的渐入动画已移除:会话切换统一由加载界面完成过渡 */ } /* 欢迎页图标:main.svg */ .welcome-icon { width: 56px; height: 56px; margin-bottom: 12px; } .brand-name { font-size: 40px; font-weight: 700; margin: 0; letter-spacing: 6px; font-family: "Microsoft YaHei UI", "Microsoft YaHei", "微软雅黑", "Segoe UI", sans-serif; background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; text-fill-color: transparent; } .brand-tagline { font-size: 15px; color: #8a94a6; margin: 14px 0 0 0; font-weight: 400; letter-spacing: 5px; } /* ==================== 2. 消息气泡 ==================== */ .message-wrapper { display: flex; align-items: flex-start; margin-bottom: 30px; } .message-wrapper.user { justify-content: flex-end; } /* ==================== 3. 头像 ==================== */ .avatar { width: 32px; height: 32px; border-radius: 6px; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 14px; flex-shrink: 0; margin-top: 20px; } .assistant .avatar { background-color: #4a90d9; color: white; margin-right: 15px; } .user .avatar { background-color: #e3e3e3; color: #555; margin-left: 15px; order: 2; } /* ==================== 4. 消息内容区 ==================== */ .message-content { max-width: 85%; display: flex; flex-direction: column; } .assistant .message-content { align-items: flex-start; /* 🆕 助手气泡恒定宽度:输出中/完成后一律 85%,不随内容伸缩(流式特效不受影响) */ width: 85%; } /* 🆕 内层同步撑满:.reply-content 基类是 fit-content(贴内容缩), 可见内容块(正文段/思考卡/工具卡)都在它里面 → 必须 100% 才真正恒定 */ .assistant .reply-content { width: 100%; } .user .message-content { align-items: flex-end; } .sender-name { font-size: 11px; color: #aaa; margin-bottom: 6px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; } .reply-content { line-height: 1.6; font-size: 15px; width: fit-content; max-width: 100%; } .user .reply-content { background-color: #f4f4f4; padding: 10px 18px; border-radius: 18px; border-top-right-radius: 4px; color: #333; text-align: left; } /* ==================== 5. 思考过程 ==================== */ .think-block { margin-bottom: 12px; border-radius: 8px; background-color: #ffffff; border: 1px solid #eaeaea; overflow: hidden; transition: all 0.3s ease; width: 100%; } .think-block summary { padding: 8px 14px; font-size: 13px; color: #888; cursor: pointer; user-select: none; background-color: #fafafa; list-style: none; display: flex; align-items: center; font-weight: 500; } .think-block summary .chev { color: #b8b8b8; margin-right: 8px; } .think-block[open] summary { border-bottom: 1px dashed #eaeaea; } .think-content { padding: 12px 14px; font-size: 13px; color: #777; background-color: #fff; max-height: 400px; overflow-y: auto; } /* 🌟 流式输出中:flex 锁底,展示最新思考内容 */ /* 🌟 流式输出中:思考框保持可滚动,JS 控制锁底 */ .message-wrapper.streaming .think-content { overflow-y: auto !important; } .think-inner { flex-shrink: 0; } .think-content.markdown-body p { color: #777; margin-bottom: 8px; } /* ============ 思考/压缩气泡内:代码朴素渲染 ============ 压缩摘要充满代码:浅色语法色(#a626a4 紫)+ code-block-wrapper 边框/语言栏, 让定格后的气泡观感"紫色带边框"。此处统一朴素灰、无边框无头部; 正文气泡的代码块不受影响。 */ .think-content .code-block-wrapper { border: none; border-radius: 0; background: transparent; min-width: 0; margin: 8px 0; } .think-content .code-header { display: none; } .think-content .code-block-wrapper pre, .think-content .code-block-wrapper pre code, .think-content .code-block-wrapper .hljs, .think-content .code-block-wrapper .hljs * { color: #777 !important; background: transparent !important; } .think-content code, .think-content.markdown-body p code { color: #777; background-color: #f6f7f9; } /* ==================== 6. Markdown 基础 ==================== */ .markdown-body p { margin-top: 0; margin-bottom: 10px; } .markdown-body code { font-family: 'Consolas', 'Courier New', monospace; font-size: 13px; } .markdown-body p code { background-color: #f0f0f0; color: #e83e8c; padding: 2px 5px; border-radius: 4px; } /* ==================== 6b. 🌟 KaTeX 公式渲染 ==================== */ .katex-display { margin: 10px 0; padding: 4px 2px; overflow-x: auto; overflow-y: hidden; } .katex-display::-webkit-scrollbar { height: 6px; } .katex-display::-webkit-scrollbar-thumb { background: #d0d0d0; border-radius: 3px; } .markdown-body .katex { font-size: 1.06em; } .markdown-body .katex-display { font-size: 1.08em; } /* ==================== 7. 代码块 ==================== */ .code-block-wrapper { position: relative; border: 1px solid #e5e5e5; border-radius: 8px; margin: 12px 0; overflow: hidden; background-color: #ffffff; min-width: 500px; /* 短代码也保持基本宽度,避免气泡过窄难看 */ } .code-header { display: flex; justify-content: space-between; align-items: center; background-color: #fafafa; padding: 4px 10px; border-bottom: 1px solid #eee; } .code-lang-label { font-size: 11px; color: #aaa; font-weight: 500; text-transform: lowercase; letter-spacing: 0.3px; } .code-header-actions { display: flex; align-items: center; gap: 4px; } .code-header button { background: transparent; border: 1px solid transparent; color: #999; cursor: pointer; display: flex; align-items: center; gap: 4px; font-size: 12px; padding: 3px 8px; border-radius: 4px; transition: all 0.15s ease; font-family: inherit; outline: none; } .code-header button:hover { background-color: #f0f0f0; border-color: #e0e0e0; color: #555; } .copy-btn.copied { color: #52c41a !important; border-color: rgba(82, 196, 26, 0.3) !important; background-color: rgba(82, 196, 26, 0.06) !important; } /* 代码主体 */ .code-body { margin: 0; padding: 14px; background-color: #fafafa !important; overflow-x: auto; max-height: 5000px; } /* 修改折叠态:允许滚动但隐藏滚动条 */ .code-body.collapsed { max-height: 140px !important; overflow-y: auto !important; /* ← 从 hidden 改为 auto */ scrollbar-width: none; /* Firefox */ } .code-body.collapsed::-webkit-scrollbar { display: none; /* Chrome/Safari */ } /* 🌟 流式输出中:用 flex 布局天然展示底部代码,不依赖 JS scrollTop */ .message-wrapper.streaming .code-body.collapsed { display: flex !important; flex-direction: column !important; justify-content: flex-end !important; overflow: hidden !important; } /* 默认折叠遮罩:底部渐隐(展示顶部代码) */ .code-block-wrapper:has(.code-body.collapsed)::after { content: ''; position: absolute; bottom: 0; left: 0; right: 0; height: 40px; background: linear-gradient(transparent, #fafafa); pointer-events: none; border-radius: 0 0 8px 8px; } /* 🌟 流式输出中遮罩:顶部渐隐(展示底部最新代码) */ .message-wrapper.streaming .code-block-wrapper:has(.code-body.collapsed)::after { top: 36px; bottom: auto; border-radius: 0; background: linear-gradient(#fafafa, transparent); } /* 强制覆盖 highlight.js 深色背景 */ .code-block-wrapper pre, .code-block-wrapper pre code, .code-block-wrapper .hljs { background-color: #fafafa !important; color: #383a42 !important; } /* 浅色语法高亮 */ .code-block-wrapper .hljs-keyword, .code-block-wrapper .hljs-selector-tag, .code-block-wrapper .hljs-title, .code-block-wrapper .hljs-section, .code-block-wrapper .hljs-doctag, .code-block-wrapper .hljs-name, .code-block-wrapper .hljs-strong { color: #a626a4; } .code-block-wrapper .hljs-string, .code-block-wrapper .hljs-attr { color: #50a14f; } .code-block-wrapper .hljs-number, .code-block-wrapper .hljs-literal, .code-block-wrapper .hljs-variable, .code-block-wrapper .hljs-template-variable, .code-block-wrapper .hljs-tag .hljs-attr { color: #986801; } .code-block-wrapper .hljs-comment, .code-block-wrapper .hljs-quote { color: #a0a1a7; font-style: italic; } .code-block-wrapper .hljs-built_in, .code-block-wrapper .hljs-builtin-name { color: #c18401; } .code-block-wrapper .hljs-function .hljs-title, .code-block-wrapper .hljs-class .hljs-title { color: #4078f2; } .code-block-wrapper .hljs-type, .code-block-wrapper .hljs-params { color: #c18401; } .code-block-wrapper .hljs-meta { color: #4078f2; } .code-block-wrapper code { font-family: 'Consolas', 'Courier New', monospace; font-size: 13px; } /* ==================== 7.1 SVG 代码块:绘制/源码 切换 ==================== */ /* 渲染容器:透明背景、居中,防超大 SVG 撑破布局 */ .svg-render-body { display: flex; align-items: center; justify-content: center; padding: 14px; background: transparent; overflow: auto; max-height: 5000px; } .svg-render-body svg { min-width: 360px; /* 小图适当放大,避免渲染出来太小看不清 */ max-width: 100%; height: auto; } /* 渲染态:隐藏代码体与折叠渐隐遮罩 */ .code-block-wrapper.svg-mode .code-body { display: none !important; } .code-block-wrapper.svg-mode:has(.code-body.collapsed)::after { display: none; } /* 渲染态按钮高亮(此时按钮文案为「源码」) */ .code-header .svg-render-btn.active { color: #10a37f; border-color: rgba(16, 163, 127, 0.3); background-color: rgba(16, 163, 127, 0.06); } /* 折叠按钮被锁定时(处于渲染态) */ .code-header .fold-btn:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; } /* 流式输出中隐藏「绘制」按钮(与复制按钮同等待遇,避免重渲冲掉切换状态) */ .message-wrapper.streaming .svg-render-btn { display: none !important; } /* ==================== 8. 长文本附件卡片 ==================== */ .long-text-card { display: flex; align-items: center; gap: 12px; padding: 12px 16px; background-color: #f8f8f8; border: 1px solid #e8e8e8; border-radius: 12px; cursor: pointer; transition: all 0.2s ease; max-width: 320px; } .long-text-card:hover { background-color: #f0f0f0; border-color: #d0d0d0; box-shadow: 0 2px 8px rgba(0,0,0,0.06); } .card-icon { flex-shrink: 0; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; background-color: #fff; border-radius: 8px; border: 1px solid #eee; } .card-info { overflow: hidden; } .card-title { font-size: 13px; color: #333; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px; } .card-meta { font-size: 11px; color: #aaa; margin-top: 3px; } /* ==================== 9. 模态框 ==================== */ .content-modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0,0,0,0); display: flex; justify-content: center; align-items: center; z-index: 9999; transition: background-color 0.2s ease; } .content-modal-overlay.visible { background-color: rgba(0,0,0,0.4); } .content-modal { background-color: #fff; border-radius: 12px; width: 70%; max-width: 700px; max-height: 75vh; display: flex; flex-direction: column; box-shadow: 0 20px 60px rgba(0,0,0,0.15); transform: scale(0.95); opacity: 0; transition: all 0.2s ease; overflow: hidden; } .content-modal-overlay.visible .content-modal { transform: scale(1); opacity: 1; } .modal-header { display: flex; justify-content: space-between; align-items: center; padding: 14px 20px; border-bottom: 1px solid #eee; font-size: 14px; font-weight: 600; color: #333; } .modal-close-btn { background: transparent; border: none; font-size: 18px; color: #999; cursor: pointer; padding: 4px 8px; border-radius: 4px; transition: all 0.15s ease; line-height: 1; } .modal-close-btn:hover { background-color: #f0f0f0; color: #333; } .modal-body { padding: 16px 20px; overflow-y: auto; font-family: 'Consolas', 'Courier New', monospace; font-size: 13px; line-height: 1.6; color: #444; white-space: pre-wrap; word-break: break-all; margin: 0; background-color: #fafafa; } /* ==================== 10. 错误与动画 ==================== */ .system-error { background-color: #fef0f0; border: 1px solid #fde2e2; color: #f56c6c; padding: 10px 15px; border-radius: 8px; margin-top: 10px; font-size: 13px; font-weight: bold; display: inline-block; } /* ==================== 11. 多附件容器 ==================== */ .attachments-container { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; } .attachments-container .long-text-card { max-width: 300px; } .user .attachments-container + .reply-content { margin-top: 4px; } /* ==================== 12. 流式输出状态(纯 CSS 控制,不闪烁) ==================== */ .message-wrapper.streaming .copy-btn { display: none !important; } .message-wrapper.streaming .fold-btn { font-size: 0 !important; pointer-events: none; position: relative; } .message-wrapper.streaming .fold-btn::after { content: '输出中...'; font-size: 12px; color: #f5a623; } /* 过渡态:从 flex-end 切换到 scroll 模式,保持显示底部 */ .code-body.collapsed.scroll-locked { display: block !important; overflow-y: auto !important; justify-content: initial !important; flex-direction: initial !important; scrollbar-width: none; } .code-body.collapsed.scroll-locked::-webkit-scrollbar { display: none; } /* ==================== 13. 消息操作栏 ==================== */ .message-actions { display: flex; align-items: center; gap: 2px; margin-top: 8px; } .action-btn { display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; border: none; background: transparent; border-radius: 6px; cursor: pointer; color: #999; transition: all 0.15s ease; padding: 0; } .action-btn:hover { background-color: #f0f0f0; color: #555; } .action-btn svg { pointer-events: none; } /* 流式输出中隐藏操作栏 */ .message-wrapper.streaming .message-actions { display: none !important; } /* ================= 分支选择器 ================= */ .branch-selector { display: inline-flex; align-items: center; margin-left: 10px; background-color: #f0f0f0; border-radius: 12px; padding: 2px 6px; font-size: 11px; color: #666; user-select: none; } /* 暗色模式的话可以加这句,如果是纯亮色就不用 */ @media (prefers-color-scheme: dark) { .branch-selector { background-color: #333; color: #aaa; } } .branch-btn { background: transparent; border: none; cursor: pointer; padding: 0 4px; color: #888; font-size: 10px; font-weight: bold; display: flex; align-items: center; justify-content: center; } .branch-btn:hover:not(:disabled) { color: #111; } .branch-btn:disabled { color: #ccc; cursor: not-allowed; } .branch-text { margin: 0 4px; font-family: monospace; } /* ================= 删除确认气泡 ================= */ .delete-confirm-popover { position: absolute; bottom: 120%; /* 浮在按钮上方 */ left: 50%; transform: translateX(-50%); background-color: #fee2e2; /* 淡红色警告背景 */ border: 1px solid #f87171; border-radius: 6px; padding: 6px 10px; display: flex; align-items: center; gap: 4px; box-shadow: 0 4px 10px rgba(239, 68, 68, 0.2); z-index: 100; cursor: pointer; white-space: nowrap; width: max-content; /* 🌟 核心修复:保证气泡背景宽度根据文字自适应,不被按钮挤压 */ } .delete-confirm-popover:hover { background-color: #fecaca; } .delete-confirm-text { color: #ef4444; font-size: 12px; font-weight: bold; } .delete-confirm-popover svg { stroke: #ef4444; } /* ================= 用户消息专属操作栏 ================= */ .user-actions { display: flex; justify-content: flex-end; /* 靠右对齐 */ margin-top: 4px; opacity: 1; /* 默认隐藏,悬浮显示 */ transition: opacity 0.2s ease-in-out; } .message-wrapper.user:hover .user-actions { opacity: 1; /* 鼠标悬浮气泡时,显示操作栏 */ } /* 强制指定按钮的图标颜色、大小和边距,打破继承魔咒 */ .user-actions .action-btn { background: transparent; border: none; color: #999999; /* 强制指定为高级灰,让 SVG 显形 */ padding: 6px; margin-left: 4px; border-radius: 6px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; } .user-actions .action-btn:hover { background-color: #eaeaea; color: #333333; /* 悬浮时图标变深 */ } .user-actions .user-delete-btn:hover { background-color: #fee2e2; color: #ef4444; } /* 🌟 用户侧靠右对齐 */ .user-actions .delete-confirm-popover { left: auto; right: 0; transform: none; } /* ⚠️ 注意:删除原本文件最底部的 "确认删除弹窗基础样式" 这一大段重复代码,避免样式冲突 */ /* ================= 确认删除弹窗基础样式 ================= */ .delete-confirm-popover { position: absolute; bottom: 120%; left: 50%; transform: translateX(-50%); background-color: #fee2e2; border: 1px solid #f87171; border-radius: 6px; padding: 6px 10px; display: flex; align-items: center; gap: 4px; box-shadow: 0 4px 10px rgba(239, 68, 68, 0.2); z-index: 100; cursor: pointer; white-space: nowrap; } .delete-confirm-popover:hover { background-color: #fecaca; } .delete-confirm-text { color: #ef4444; font-size: 12px; font-weight: bold; } .delete-confirm-popover svg { stroke: #ef4444; } /* ==================== 工具执行气泡(pi tool_execution_* 事件,浅色·对齐思考气泡) ==================== */ .tool-chip { margin: 10px 0 4px 0; border-radius: 8px; background-color: #ffffff; border: 1px solid #eaeaea; overflow: hidden; transition: all 0.3s ease; width: 100%; } .tool-chip.streaming { border-color: #d6e4ff; background-color: #fbfdff; } .tool-chip summary { padding: 8px 14px; font-size: 12.5px; color: #888; cursor: pointer; user-select: none; background-color: #fafafa; list-style: none; display: flex; align-items: center; gap: 8px; font-weight: 500; } .tool-chip summary::-webkit-details-marker { display: none; } .tool-chip summary .chev { color: #b8b8b8; } .tool-chip[open] summary { border-bottom: 1px dashed #eaeaea; } .tool-chip-icon { font-size: 13px; color: #bbb; } .tool-chip-name { font-family: Consolas, Monaco, monospace; font-weight: 600; color: #666; font-size: 12px; } .tool-chip-brief { font-family: Consolas, Monaco, monospace; color: #aaa; font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; } .tool-chip-brief.done { color: #52c41a; } .tool-chip-status { margin-left: auto; flex-shrink: 0; font-size: 11px; padding: 1px 8px; border-radius: 10px; } .tool-chip-status.running { color: #4a7fd4; background: #eef4ff; animation: toolPulse 1.2s ease-in-out infinite; } .tool-chip-status.ok { color: #52c41a; background: #f6ffed; } .tool-chip-status.fail { color: #cf1322; background: #fff1f0; } @keyframes toolPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } } .tool-chip-body { padding: 10px 14px 12px 14px; max-height: 260px; overflow: auto; background-color: #fff; } .tool-chip-label { font-size: 11px; color: #bbb; font-weight: 600; margin: 6px 0 4px 0; letter-spacing: 0.5px; } .tool-chip-label:first-child { margin-top: 0; } .tool-chip-pre { margin: 0 0 6px 0; padding: 8px 10px; background-color: #f6f7f9; color: #555; border: 1px solid #eef0f3; border-radius: 6px; font-family: Consolas, Monaco, monospace; font-size: 11.5px; line-height: 1.55; white-space: pre-wrap; word-break: break-all; max-height: 150px; overflow: auto; } /* ==================== 系统提示(如:已自动压缩上下文) ==================== */ .system-note { text-align: center; font-size: 12px; color: #6b7280; background: #f3f4f6; border-radius: 10px; padding: 6px 14px; margin: 10px auto; max-width: 70%; } /* ==================== 增量流式渲染容器 ==================== */ /* 注意:不能用 display:contents —— 本机 Chromium 下父盒(.md-segment)高度坍缩为 0, 导致流式正文整段不可见(切会话重渲走无包裹路径所以可见)。用 block 规避。 */ .md-stable, .md-tail { display: block; } /* ==================== 浅色 SVG 箭头(替代文字字形) ==================== */ .chev { flex: none; display: inline-block; transition: transform 0.2s ease-in-out; } .think-block[open] .chev, .tool-chip[open] .chev { transform: rotate(90deg); } .think-label { color: inherit; } /* ==================== 深度思考:默认收起 + 进行中蓝色呼吸动画 ==================== */ .think-block.streaming-think > summary .think-label { color: #3b82f6; font-weight: 600; animation: think-breathe 1.6s ease-in-out infinite; } .think-block.streaming-think > summary .think-label::after { content: ''; display: inline-block; width: 1.2em; text-align: left; animation: think-dots 1.4s infinite; } @keyframes think-breathe { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } } @keyframes think-dots { 0% { content: ''; } 25% { content: '.'; } 50% { content: '..'; } 75% { content: '...'; } } /* ==================== 工具 chip:耗时 / 超时徽章 ==================== */ .tool-chip-time { font-size: 11px; color: #9ca3af; font-variant-numeric: tabular-nums; margin-left: 2px; } .tool-chip-timeout { font-size: 11px; color: #dc2626; font-weight: 600; margin-left: 2px; } .tool-chip-livetimer { /* 🆕 bash 运行中每秒读秒(N/Ts):琥珀色 + 等宽数字,不跳动 */ font-size: 11px; color: #d97706; font-weight: 600; font-variant-numeric: tabular-nums; margin-left: 2px; } /* ==================== 工具结果:长输出展开按钮 ==================== */ .tool-expand-btn { display: block; width: 100%; margin: 4px 0 0; padding: 3px 8px; font-size: 11px; line-height: 1.5; color: #3b82f6; background: #eff6ff; border: 1px solid #bfdbfe; border-radius: 6px; cursor: pointer; text-align: center; font-family: inherit; } .tool-expand-btn:hover { background: #dbeafe; } .tool-chip-pre.tool-chip-full { max-height: 360px; overflow: auto; } /* ==================== 时间线:正文段 / 流式光标 ==================== */ .md-segment:empty { display: none; } .md-segment > :first-child { margin-top: 0; } .md-segment > :last-child { margin-bottom: 0; } /* block 包裹下,额外压平内层首尾段落的边距,保持气泡观感 */ .md-segment > :last-child > :last-child { margin-bottom: 0; } /* 光标 "Chasing a shining star":文字顶住不动,只有 ● 缩放闪烁(星光脉冲无限循环)。 生命周期=原版:消息第一个时间线事件出现即显示 → finishMessage 移除, 思考/工具/压缩/正文全程保持(无休眠态) */ .streaming-typing { display: inline-block; margin-left: 4px; color: #3b82f6; font-size: 13px; font-family: "Cascadia Mono", "Cascadia Code", Consolas, "Lucida Console", monospace; } .streaming-typing .typing-dot { display: inline-block; animation: cursor-star 1.6s ease-in-out infinite; } @keyframes cursor-star { 0%, 100% { opacity: .25; transform: scale(.85); text-shadow: none; } 50% { opacity: 1; transform: scale(1.15); text-shadow: 0 0 6px rgba(59, 130, 246, .8), 0 0 12px rgba(59, 130, 246, .45); } } /* ========== 助手正文(流式中/完成后一致,保持透明) ========== */ .message-wrapper.assistant .reply-content .md-segment { width: 100%; box-sizing: border-box; padding: 0; color: #30343b; background: transparent; border: none; border-radius: 0; } .message-wrapper.assistant .reply-content .md-segment + .md-segment { margin-top: 6px; } /* ==================== 🆕 P1-01 渲染窗口:加载入口按钮 ==================== */ /* 上/下两端的「加载更多」入口:无边框浅灰胶囊,居中;无更多消息时由 JS 隐藏 */ .load-window-btn { display: flex; align-items: center; justify-content: center; width: 220px; margin: 14px auto; padding: 6px 14px; font-size: 12px; color: #666; background: #f4f4f6; border: 1px solid #e3e3e8; border-radius: 999px; cursor: pointer; user-select: none; transition: background 0.15s ease, color 0.15s ease; } .load-window-btn:hover { background: #eaeaf0; color: #333; } .load-window-btn[hidden] { display: none; } /* 底部入口与 scroll-anchor 的间距(scroll-anchor 自带 150px margin) */ #load-newer { margin-bottom: 4px; }