chore: import original project baseline

Import the pre-repair source tree as the history baseline.
Runtime data (data/), virtualenvs, bytecode caches and logs are
gitignored so local secrets and user state stay out of the repo.
This commit is contained in:
2026-09-17 16:40:01 +08:00
commit a7412824e0
124 changed files with 26747 additions and 0 deletions
+902
View File
@@ -0,0 +1,902 @@
/* ==================== 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(贴内容缩),
可见气泡(md-segment 背景/思考卡/工具卡)都在它里面 → 必须 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.assistant 是死代码(JS 只挂 message-wrapper 类),背景从未渲染 */
/* 🆕 用户决定:助手正文气泡【透明】——不要背景/边框/圆角/内边距(2026-07 像素取证调试后明确:
原死选择器 P0 修复带来的浅灰底不是想要的效果),正文直接裸排在 85% 定宽列内 */
.message-wrapper.assistant .reply-content .md-segment + .md-segment {
margin-top: 6px;
}