/* ============ Global Reset & Base ============ */ :root { --bg-primary: #ffffff; --bg-secondary: #f8fafc; --bg-tertiary: #f0f4f8; --bg-hover: rgba(37, 99, 235, 0.06); --bg-active: rgba(37, 99, 235, 0.12); --bg-input: #f8fafc; --bg-code: #f1f5f9; --bg-thinking: #f1f5f9; --text-primary: #1e293b; --text-secondary: #64748b; --text-tertiary: #94a3b8; --border-light: rgba(0, 0, 0, 0.06); --border-medium: rgba(0, 0, 0, 0.08); --border-input: rgba(0, 0, 0, 0.08); --accent-primary: #2563eb; --accent-primary-hover: #3b82f6; --accent-primary-light: rgba(37, 99, 235, 0.08); --accent-primary-medium: rgba(37, 99, 235, 0.15); --tool-color: #5478FF; --tool-color-hover: #3d5ce0; --tool-bg: rgba(84, 120, 255, 0.18); --tool-bg-hover: rgba(84, 120, 255, 0.28); --tool-border: rgba(84, 120, 255, 0.22); --attachment-color: #ca8a04; --attachment-color-hover: #a16207; --attachment-bg: rgba(202, 138, 4, 0.15); --success-color: #059669; --success-bg: rgba(16, 185, 129, 0.1); --danger-color: #ef4444; --danger-bg: rgba(239, 68, 68, 0.08); --scrollbar-thumb: rgba(0, 0, 0, 0.08); --scrollbar-thumb-sidebar: rgba(0, 0, 0, 0.1); --overlay-bg: rgba(0, 0, 0, 0.3); --avatar-gradient: linear-gradient(135deg, #3b82f6, #60a5fa); } [data-theme="dark"] { --bg-primary: #1a1a1a; --bg-secondary: #141414; --bg-tertiary: #0a0a0a; --bg-hover: rgba(255, 255, 255, 0.08); --bg-active: rgba(255, 255, 255, 0.12); --bg-input: #141414; --bg-code: #141414; --bg-thinking: #141414; --text-primary: #f0f0f0; --text-secondary: #a0a0a0; --text-tertiary: #606060; --border-light: rgba(255, 255, 255, 0.08); --border-medium: rgba(255, 255, 255, 0.12); --border-input: rgba(255, 255, 255, 0.1); --accent-primary: #3b82f6; --accent-primary-hover: #60a5fa; --accent-primary-light: rgba(59, 130, 246, 0.15); --accent-primary-medium: rgba(59, 130, 246, 0.25); --tool-color: #5478FF; --tool-color-hover: #7a96ff; --tool-bg: rgba(84, 120, 255, 0.28); --tool-bg-hover: rgba(84, 120, 255, 0.40); --tool-border: rgba(84, 120, 255, 0.32); --attachment-color: #facc15; --attachment-color-hover: #fde047; --attachment-bg: rgba(250, 204, 21, 0.22); --success-color: #34d399; --success-bg: rgba(52, 211, 153, 0.15); --danger-color: #f87171; --danger-bg: rgba(248, 113, 113, 0.15); --scrollbar-thumb: rgba(255, 255, 255, 0.1); --scrollbar-thumb-sidebar: rgba(255, 255, 255, 0.15); --overlay-bg: rgba(0, 0, 0, 0.6); --avatar-gradient: linear-gradient(135deg, #3b82f6, #60a5fa); } * { margin: 0; padding: 0; box-sizing: border-box; } html, body { height: 100%; overflow: hidden; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans SC', sans-serif; background: var(--bg-tertiary); background-image: radial-gradient(ellipse at 20% 50%, var(--accent-primary-light) 0%, transparent 50%), radial-gradient(ellipse at 80% 20%, rgba(168, 85, 247, 0.06) 0%, transparent 50%), radial-gradient(ellipse at 60% 80%, rgba(52, 211, 153, 0.05) 0%, transparent 50%); color: var(--text-primary); -webkit-font-smoothing: antialiased; transition: background 0.2s, color 0.2s; } #app { height: 100%; } /* ============ Main Panel (shared by ChatView, FileExplorer, etc.) ============ */ .main-panel { flex: 1 1 0; display: flex; flex-direction: column; height: 100vh; overflow: hidden; min-width: 0; background: color-mix(in srgb, var(--bg-secondary) 80%, transparent); backdrop-filter: blur(30px); -webkit-backdrop-filter: blur(30px); border-left: 1px solid var(--border-light); } /* ============ Transitions ============ */ .fade-enter-active, .fade-leave-active { transition: opacity 0.2s; } .fade-enter-from, .fade-leave-to { opacity: 0; } /* ============ Animations ============ */ @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .spinner { animation: spin 1s linear infinite; } /* ============ Markdown content shared styles ============ */ .md-content { font-size: 15px; line-height: 1.7; color: var(--text-primary); word-break: break-word; } .md-content p { margin: 0 0 8px; } .md-content p:last-child { margin-bottom: 0; } .md-content hr { border: none; border-top: 1px solid var(--border-light); margin: 16px 0; } .md-content pre { background: var(--bg-code); border: 1px solid var(--border-light); border-radius: 8px; padding: 12px; overflow-x: auto; margin: 8px 0; max-width: 100%; } .md-content pre code { font-family: 'JetBrains Mono', 'Fira Code', monospace; font-size: 13px; line-height: 1.5; } /* 代码块滚动条 */ .md-content pre::-webkit-scrollbar, .code-block pre code::-webkit-scrollbar { height: 6px; } .md-content pre::-webkit-scrollbar-track, .code-block pre code::-webkit-scrollbar-track { background: transparent; } .md-content pre::-webkit-scrollbar-thumb, .code-block pre code::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 3px; } .md-content pre::-webkit-scrollbar-thumb:hover, .code-block pre code::-webkit-scrollbar-thumb:hover { background: var(--text-tertiary); } /* 代码块头部:语言标签 + 复制按钮 */ .code-block { background: var(--bg-code); border: 1px solid var(--border-light); border-radius: 8px; margin: 8px 0; max-width: 100%; overflow: hidden; } .code-block pre { margin: 0; padding: 0; border: none; border-radius: 0; background: transparent; } .code-block pre code { display: block; padding: 12px 12px 12px 16px; overflow-x: auto; } .code-header { display: flex; align-items: center; justify-content: space-between; padding: 6px 12px 6px 16px; background: var(--bg-code); } .code-lang { color: var(--text-tertiary); font-size: 11px; font-weight: 500; } .code-copy-btn { background: none; border: none; color: var(--text-tertiary); cursor: pointer; font-size: 12px; padding: 2px 8px; border-radius: 4px; transition: all 0.15s; } .code-copy-btn:hover { color: var(--accent-primary); background: var(--accent-primary-light); } .md-content code { background: var(--accent-primary-light); color: var(--accent-primary); padding: 2px 6px; border-radius: 4px; font-size: 13px; font-family: 'JetBrains Mono', 'Fira Code', monospace; } .md-content pre code { background: none; color: inherit; padding: 0; } .md-content ul, .md-content ol { padding-left: 20px; margin: 8px 0; } .md-content blockquote { border-left: 3px solid rgba(59, 130, 246, 0.4); padding-left: 12px; color: var(--text-secondary); margin: 8px 0; } .md-content table { border-collapse: collapse; margin: 8px 0; width: 100%; } .md-content th, .md-content td { border: 1px solid var(--border-medium); padding: 8px 12px; text-align: left; } .md-content th { background: var(--bg-code); } .md-content .math-block { display: block; text-align: center; padding: 12px 0; margin: 8px 0; overflow-x: auto; } /* ============ Scrollbar ============ */ textarea::-webkit-scrollbar, .cm-scroller::-webkit-scrollbar { width: 6px; height: 6px; } textarea::-webkit-scrollbar-track, .cm-scroller::-webkit-scrollbar-track { background: transparent; } textarea::-webkit-scrollbar-thumb, .cm-scroller::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 3px; } textarea::-webkit-scrollbar-thumb:hover, .cm-scroller::-webkit-scrollbar-thumb:hover { background: var(--text-tertiary); } textarea::-webkit-resizer { background: transparent; } .cm-scroller { scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) transparent; } /* ============ Range Slider ============ */ input[type="range"] { width: 100%; height: 8px; min-height: 8px; -webkit-appearance: none; appearance: none; background: var(--border-medium); border-radius: 4px; outline: none; cursor: pointer; } input[type="range"]::-webkit-slider-runnable-track { height: 8px; border-radius: 4px; } input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 20px; height: 20px; border-radius: 50%; background: var(--accent-primary); border: 3px solid var(--bg-primary); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); cursor: pointer; margin-top: -6px; transition: transform 0.15s; } input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.15); } input[type="range"]::-moz-range-track { height: 8px; border-radius: 4px; background: var(--border-medium); } input[type="range"]::-moz-range-thumb { width: 20px; height: 20px; border-radius: 50%; background: var(--accent-primary); border: 3px solid var(--bg-primary); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2); cursor: pointer; } /* ============ Button Base ============ */ .btn-icon { display: flex; align-items: center; justify-content: center; border: none; border-radius: 8px; cursor: pointer; transition: all 0.15s ease; background: var(--bg-code); color: var(--text-tertiary); } .btn-icon:hover:not(:disabled) { background: var(--bg-hover); color: var(--text-primary); } .btn-icon:disabled { opacity: 0.5; cursor: not-allowed; } /* ============ Modal ============ */ .modal-overlay { position: fixed; inset: 0; background: var(--overlay-bg); display: flex; align-items: center; justify-content: center; z-index: 200; } .modal { background: var(--bg-primary); border-radius: 12px; width: 90%; max-width: 480px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); } .modal-content { border-radius: 16px; width: 90%; max-width: 520px; max-height: 80vh; overflow-y: auto; padding: 24px; background: color-mix(in srgb, var(--bg-primary) 75%, transparent); backdrop-filter: blur(40px); -webkit-backdrop-filter: blur(40px); border: 1px solid var(--border-medium); box-shadow: 0 25px 60px rgba(0, 0, 0, 0.2); } .modal-header { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; border-bottom: 1px solid var(--border-light); } .modal-header h3 { margin: 0; font-size: 16px; font-weight: 600; color: var(--text-primary); } .modal-body { padding: 20px; } .modal-footer { display: flex; gap: 12px; padding: 16px 20px; border-top: 1px solid var(--border-light); } .btn-close { background: none; border: none; color: var(--text-tertiary); cursor: pointer; padding: 4px; border-radius: 6px; transition: all 0.15s; display: flex; align-items: center; justify-content: center; } .btn-close:hover { color: var(--text-primary); background: var(--bg-hover); } /* ============ Action Buttons ============ */ .btn-primary, .btn-secondary, .btn-danger { flex: 1; padding: 10px 16px; border: none; border-radius: 8px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s; } .btn-primary { background: var(--accent-primary); color: white; } .btn-primary:hover:not(:disabled) { background: var(--accent-primary-hover); } .btn-primary:disabled { opacity: 0.5; cursor: not-allowed; } .btn-secondary { background: var(--bg-tertiary); color: var(--text-primary); } .btn-secondary:hover { background: var(--bg-hover); } .btn-danger { background: var(--danger-color); color: white; } .btn-danger:hover:not(:disabled) { opacity: 0.9; } .btn-danger:disabled { opacity: 0.5; cursor: not-allowed; } /* ============ Tab Navigation ============ */ .period-tabs { display: flex; gap: 2px; background: var(--bg-input); padding: 3px; border-radius: 8px; } .tab { padding: 4px 12px; border: none; background: none; color: var(--text-tertiary); font-size: 12px; cursor: pointer; border-radius: 6px; transition: all 0.2s; } .tab:hover { color: var(--text-secondary); } .tab.active { background: var(--accent-primary); color: white; box-shadow: 0 1px 3px rgba(37, 99, 235, 0.3); } /* ============ Message Bubble Shared ============ */ .message-bubble { display: flex; gap: 12px; margin-bottom: 16px; width: 100%; } .message-bubble.user { flex-direction: row-reverse; } .message-container { display: flex; flex-direction: column; min-width: 200px; width: 100%; } .message-bubble.user .message-container { align-items: flex-end; width: fit-content; max-width: 85%; } .message-bubble.assistant .message-container { align-items: flex-start; flex: 1 1 auto; width: 100%; min-width: 0; } .message-bubble.assistant .message-body { width: 100%; } .avatar { width: 32px; height: 32px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; letter-spacing: -0.3px; flex-shrink: 0; } .user .avatar { background: linear-gradient(135deg, #2563eb, #3b82f6); color: white; font-size: 12px; } .assistant .avatar { background: var(--avatar-gradient); color: white; font-size: 12px; } .message-body { flex: 1; min-width: 0; padding: 16px; border: 1px solid var(--border-light); border-radius: 12px; background: var(--bg-primary); transition: background 0.2s, border-color 0.2s; } /* ============ Form ============ */ .form-group { margin-bottom: 16px; } .form-group label { display: block; font-size: 13px; font-weight: 500; color: var(--text-secondary); margin-bottom: 8px; } .form-group input, .form-group textarea, .form-group select { width: 100%; padding: 10px 12px; background: var(--bg-input); border: 1px solid var(--border-input); border-radius: 8px; color: var(--text-primary); font-size: 14px; font-family: inherit; outline: none; transition: border-color 0.2s, background 0.2s; box-sizing: border-box; } .form-group input:focus, .form-group textarea:focus, .form-group select:focus { border-color: var(--accent-primary); } .form-group textarea { resize: vertical; min-height: 80px; } .form-group select { cursor: pointer; appearance: none; -webkit-appearance: none; -moz-appearance: none; background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; background-size: 16px; padding-right: 40px; } .form-group select:hover { border-color: var(--accent-primary); } .form-group select:focus { border-color: var(--accent-primary); box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); } .form-group select option { background: var(--bg-primary); color: var(--text-primary); padding: 10px; } [data-theme="dark"] .form-group select { background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23a0a0a0' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E"); } /* ============ Small Icon Button ============ */ .btn-icon-sm { display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; border: none; background: none; color: var(--text-tertiary); cursor: pointer; border-radius: 4px; transition: all 0.15s; } .btn-icon-sm:hover { background: var(--bg-hover); color: var(--text-primary); } .btn-icon-sm.danger:hover { background: var(--danger-bg); color: var(--danger-color); } /* ============ Ghost Button (base for small icon buttons) ============ */ .ghost-btn { display: flex; align-items: center; justify-content: center; border: none; background: none; color: var(--text-tertiary); cursor: pointer; padding: 4px; border-radius: 4px; transition: all 0.15s; } .ghost-btn:hover { background: var(--bg-hover); color: var(--text-primary); } .ghost-btn.danger:hover { background: var(--danger-bg); color: var(--danger-color); } .ghost-btn.accent:hover { background: var(--accent-primary-light); color: var(--accent-primary); } .ghost-btn.success:hover { background: var(--success-bg); color: var(--success-color); } /* ============ Empty / Loading State ============ */ .empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; flex: 1; gap: 12px; color: var(--text-tertiary); font-size: 13px; } /* ============ Thin Scrollbar (4px) ============ */ .scrollbar-thin { overflow-y: auto; } .scrollbar-thin::-webkit-scrollbar { width: 4px; } .scrollbar-thin::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 2px; } .scrollbar-thin::-webkit-scrollbar-track { background: transparent; } /* ============ Panel Header (title + actions) ============ */ .panel-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; } .panel-title { display: flex; align-items: center; gap: 8px; color: var(--text-primary); } .panel-title svg { color: var(--text-tertiary); } .panel-title h4 { margin: 0; font-size: 16px; font-weight: 600; } .header-actions { display: flex; align-items: center; gap: 12px; }