:root { --bg: #071326; --panel: #0e1d35; --panel-2: #102443; --line: #28456f; --text: #dce9ff; --muted: #97b2d8; --accent: #4fa0ff; --ok: #49c47c; --warn: #e5b94d; --bad: #ff7a7a; --left: 15%; --center: 65%; --right: 20%; --splitter: 1px; --outer-gap: 10px; --title-row-h: 34px; --control-row-h: 42px; --top-control-btn-h: 34px; --top-control-font-size: 15px; } * { box-sizing: border-box; } html, body { height: 100%; overflow: hidden; } body { margin: 0; font-family: "IBM Plex Sans", "Segoe UI", sans-serif; color: var(--text); background: radial-gradient(circle at top left, #11315f 0%, #091930 30%, var(--bg) 100%); } .layout { display: grid; grid-template-columns: calc((100% - (2 * var(--outer-gap)) - (2 * var(--splitter))) * (var(--left) / 100%)) var(--splitter) calc((100% - (2 * var(--outer-gap)) - (2 * var(--splitter))) * (var(--center) / 100%)) var(--splitter) calc((100% - (2 * var(--outer-gap)) - (2 * var(--splitter))) * (var(--right) / 100%)); height: 100vh; min-height: 100vh; overflow: hidden; padding: 0 var(--outer-gap); box-sizing: border-box; } .panel { padding: 10px 6px; display: flex; flex-direction: column; height: 100%; min-width: 0; min-height: 0; overflow: hidden; background: linear-gradient(180deg, var(--panel-2) 0%, var(--panel) 100%); } #tree-panel, #editor-panel, #right-panel { min-height: 0; } .panel h2 { margin: 0; font-size: 15px; color: var(--muted); } .row-header { display: flex; align-items: center; min-height: var(--title-row-h); height: var(--title-row-h); margin-bottom: 8px; } .row-controls { display: flex; align-items: center; min-height: var(--control-row-h); height: var(--control-row-h); gap: 8px; flex-wrap: nowrap; margin-bottom: 8px; } .row-header h2 { line-height: 1; } .right-controls { justify-content: flex-end; } .scroll { overflow: auto; } #tree-root { flex: 1; min-height: 200px; border: 1px solid var(--line); border-radius: 6px; padding: 6px; background: #0b1830; } .badge { padding: 4px 8px; border-radius: 999px; background: #1b3156; border: 1px solid var(--line); color: var(--muted); } button, textarea { background: #12284b; color: var(--text); border: 1px solid var(--line); border-radius: 6px; } button { padding: 6px 10px; cursor: pointer; } button:hover { border-color: var(--accent); } button:disabled { opacity: 0.55; cursor: not-allowed; } textarea { width: 100%; padding: 8px; } .hidden { display: none !important; } .picker-label { display: inline-flex; align-items: center; justify-content: center; height: var(--top-control-btn-h); padding: 0 14px; border: 1px solid var(--line); border-radius: 6px; background: #12284b; color: var(--text); cursor: pointer; font-size: var(--top-control-font-size); line-height: 1; white-space: nowrap; } .picker-label:hover { border-color: var(--accent); } .picker-input { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } .splitter { background: var(--line); cursor: col-resize; } .splitter:hover { background: #3a6597; } .tabs-row { border-bottom: 1px solid var(--line); padding-bottom: 8px; margin-bottom: 8px; } .tabs { flex: 1; display: flex; align-items: center; gap: 6px; overflow-x: auto; overflow-y: hidden; white-space: nowrap; min-width: 0; scrollbar-gutter: stable both-edges; scrollbar-width: thin; scrollbar-color: #2f5f99 transparent; } .tabs::-webkit-scrollbar { height: 2px; } .tabs::-webkit-scrollbar-track { background: transparent; } .tabs::-webkit-scrollbar-thumb { background: #2f5f99; border-radius: 999px; } .new-tab-btn { flex-shrink: 0; height: var(--top-control-btn-h); padding: 0 14px; font-size: var(--top-control-font-size); line-height: 1; } .tab-item { display: inline-flex; align-items: center; flex: 0 0 auto; height: 30px; border: 1px solid var(--line); border-radius: 6px; overflow: hidden; background: #12284b; } .tab-main { display: inline-block; flex: 0 0 auto; border: none; border-right: 1px solid var(--line); border-radius: 0; background: transparent; color: var(--muted); padding: 4px 8px; white-space: nowrap; min-width: max-content; max-width: 32ch; overflow: hidden; text-overflow: ellipsis; } .tab-close { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 24px; border: none; border-radius: 0; width: 24px; min-width: 24px; height: 24px; padding: 0; background: transparent; color: var(--text); font-weight: 700; font-size: 14px; line-height: 1; } .row-controls > button { height: var(--top-control-btn-h); padding: 0 14px; font-size: var(--top-control-font-size); line-height: 1; white-space: nowrap; } .tab-close:hover, .tab-main:hover { background: #183563; } .tab-item.active { border-color: var(--accent); } .tab-item.active .tab-main { color: var(--text); } .tab-item.dirty { border-color: var(--warn); } .tab-item.dirty .tab-main { color: #ffd88b; } .editor-workspace { position: relative; display: flex; flex-direction: column; flex: 1; min-height: 0; overflow: hidden; } .editor-empty-state { flex: 1; min-height: 0; border: 1px dashed var(--line); border-radius: 6px; display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: 14px; background: #0b1830; } .md-toggle { position: static; z-index: 0; display: inline-flex; align-items: center; justify-content: center; width: var(--top-control-btn-h); min-width: var(--top-control-btn-h); height: var(--top-control-btn-h); padding: 0; border-radius: 999px; font-size: 16px; line-height: 1; background: #163057; flex-shrink: 0; text-align: center; } .md-toggle.active { border-color: var(--accent); } .file-editor { background: #0b1830; border: 1px solid var(--line); border-radius: 6px; padding: 10px; margin: 0; color: var(--text); resize: none; width: 100%; font-family: "IBM Plex Mono", "Consolas", monospace; font-size: 14px; line-height: 1.35; } .file-editor:read-only { color: var(--muted); } .file-editor.large { flex: 1; } .file-editor.monaco-host { padding: 0; overflow: hidden; } .md-preview { background: #0b1830; border: 1px solid var(--line); border-radius: 6px; padding: 12px; overflow: auto; } .md-preview.large { flex: 1; } .md-preview h1, .md-preview h2, .md-preview h3, .md-preview h4, .md-preview h5, .md-preview h6 { margin: 10px 0 6px; color: #f1f6ff; } .md-preview p { margin: 6px 0; } .md-preview code { background: #163057; padding: 1px 4px; border-radius: 4px; } .md-preview pre { background: #081427; border: 1px solid var(--line); border-radius: 6px; padding: 10px; overflow: auto; } .md-preview ul { margin: 6px 0; padding-left: 18px; } .md-preview a { color: #81b9ff; } .md-preview .mermaid { margin: 10px 0; padding: 8px; border: 1px solid var(--line); border-radius: 6px; background: #081427; overflow: auto; } .md-preview .mermaid-error { color: #ffd7d7; font-family: "IBM Plex Mono", "Consolas", monospace; white-space: pre-wrap; } .editor-footer { margin-top: 8px; border: 1px solid var(--line); border-radius: 6px; background: #0b1830; padding: 8px; display: flex; height: 56px; min-height: 56px; justify-content: space-between; align-items: center; gap: 10px; } .editor-info { color: var(--muted); font-size: 12px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .rag-status { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-size: 12px; flex-shrink: 0; white-space: nowrap; } .rag-dot { width: 10px; height: 10px; border-radius: 999px; border: 1px solid #315685; box-shadow: 0 0 0 1px #0f2343 inset; } .rag-red { background: #cf4b57; } .rag-yellow { background: #d7b84d; } .rag-green { background: #49c47c; } .editor-actions { display: flex; gap: 8px; flex-shrink: 0; } .tree-footer { display: grid; grid-template-rows: 1fr 1fr; align-items: center; justify-items: start; row-gap: 0; } .tree-footer-line { width: 100%; min-width: 0; } .chat-wrap, .review-wrap { display: flex; flex-direction: column; min-height: 0; } .chat-wrap { flex: 1; } .review-wrap { flex: 1 1 auto; min-height: 0; height: 100%; margin-top: 0; overflow: auto; overflow-x: hidden; padding-right: 2px; padding-bottom: 12px; scrollbar-gutter: stable both-edges; } .editor-review { flex: 1; min-height: 0; } .chat-log, .diff-view { border: 1px solid var(--line); border-radius: 6px; padding: 8px; background: #0b1830; } .chat-log { flex: 1; min-height: 0; min-width: 0; overflow-y: auto; overflow-x: hidden; display: flex; flex-direction: column; justify-content: flex-start; scrollbar-gutter: stable both-edges; font-size: 13px; } .chat-entry { margin-bottom: 8px; padding: 6px 8px; border: 1px solid rgba(121, 149, 196, 0.25); border-radius: 8px; max-width: 88%; min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; word-wrap: break-word; align-self: flex-start; } .chat-entry-user { color: var(--text); align-self: flex-end; text-align: right; background: #14335f; } .chat-entry-system { color: #9ab0d7; background: rgba(33, 56, 94, 0.35); } .chat-entry-error { color: #ff8d8d; background: rgba(80, 30, 37, 0.35); } .chat-entry-assistant { color: #f6f8ff; background: rgba(26, 44, 77, 0.5); max-width: 85%; } .chat-entry-intermediate { color: #b8bfd0; } .chat-task-progress { margin-top: 8px; width: 100%; height: 4px; border-radius: 4px; overflow: hidden; background: rgba(191, 202, 226, 0.25); } .chat-task-progress-bar { height: 100%; width: 0%; border-radius: 4px; background: #e6ecfa; transition: width 180ms ease; } .chat-entry:last-child { margin-bottom: 0; } .chat-sse-window { padding: 6px 8px; background: rgba(20, 31, 52, 0.65); border: none; max-width: 85%; } .chat-sse-window-complete { border-color: rgba(141, 157, 186, 0.25); } .chat-sse-list { height: 110px; display: flex; flex-direction: column; justify-content: flex-start; gap: 4px; overflow-y: scroll; overflow-x: hidden; scrollbar-gutter: stable; font-size: 12px; } .chat-sse-line { color: #97a4bd; display: flex; flex-direction: column; gap: 6px; flex-shrink: 0; } .chat-sse-text { white-space: pre-wrap; overflow-wrap: anywhere; word-break: normal; line-height: 1.35; } .chat-sse-line .chat-task-progress { margin-top: 2px; } .chat-form { margin-top: 8px; display: grid; grid-template-rows: 1fr auto; gap: 8px; flex: 0 0 20%; min-height: 120px; } #chat-input { min-height: 0; height: 100%; resize: none; overflow: auto; } .change-list { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; } .change-btn { border: 1px solid var(--line); background: #12284b; color: var(--muted); padding: 4px 8px; border-radius: 6px; cursor: pointer; } .change-btn.active { border-color: var(--accent); color: var(--text); } .toolbar { display: flex; flex-wrap: wrap; gap: 6px; } .diff-view { min-height: 120px; overflow: visible; flex: 0 0 auto; display: flex; flex-direction: column; gap: 10px; } .review-file { display: flex; flex-direction: column; gap: 8px; } .review-file-header { display: flex; align-items: center; justify-content: space-between; gap: 10px; } .review-file-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); font-size: 14px; font-weight: 600; } .review-file-actions { display: inline-flex; align-items: center; gap: 6px; margin-left: auto; } .review-file-actions > button { height: 28px; padding: 0 10px; font-size: 12px; } .diff-block { border: 1px solid var(--line); border-radius: 6px; overflow: hidden; cursor: pointer; } .diff-block.accepted { border-color: #2f8f64; } .diff-block.rejected { border-color: #9a3d48; } .diff-block-actions { display: flex; align-items: center; justify-content: space-between; gap: 6px; padding: 6px 8px; border-bottom: 1px solid var(--line); background: #12284b; } .diff-block-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: 12px; } .diff-block-controls { display: inline-flex; align-items: center; gap: 6px; margin-left: auto; } .diff-block-body { display: block; } .diff-block.collapsed .diff-block-body { display: none; } .diff-block-actions > button { height: 26px; padding: 0 10px; font-size: 12px; } .diff-block-actions > button.active { border-color: var(--accent); } .diff-line { display: block; font-family: "IBM Plex Mono", "Consolas", monospace; font-size: 12px; padding: 2px 8px; white-space: pre-wrap; } .diff-line.add { background: #113224; } .diff-line.remove { background: #3a2027; } .diff-line.context { color: var(--muted); background: #0b1830; } .tree-item { padding: 2px 4px; cursor: pointer; user-select: none; border-radius: 4px; } .tree-item:hover { background: #133056; } .tree-item-selected { background: #183563; } .tree-item-dir { color: var(--muted); } .tree-context-menu { position: fixed; z-index: 10000; min-width: 220px; display: flex; flex-direction: column; padding: 6px; gap: 4px; border: 1px solid var(--line); border-radius: 8px; background: #0f2343; box-shadow: 0 10px 24px rgba(0, 0, 0, 0.35); } .tree-context-menu > button { height: 32px; text-align: left; padding: 0 10px; font-size: 13px; border-radius: 6px; } .tree-inline-input { width: 100%; height: 28px; padding: 0 8px; border: 1px solid var(--accent); border-radius: 6px; background: #0b1830; color: var(--text); font-size: 13px; line-height: 1; } .indexing-modal { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; background: rgba(4, 10, 20, 0.78); backdrop-filter: blur(2px); } .indexing-card { width: min(640px, calc(100vw - 40px)); border: 1px solid var(--line); border-radius: 10px; padding: 16px; background: linear-gradient(180deg, #112648 0%, #0c1a33 100%); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4); } .indexing-card h3 { margin: 0 0 12px; font-size: 18px; color: var(--text); } .indexing-row { display: grid; grid-template-columns: 130px 1fr; gap: 8px; margin-bottom: 8px; min-height: 20px; } .indexing-label { color: var(--muted); font-size: 13px; } .indexing-value { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); font-size: 13px; } .indexing-progress { margin-top: 8px; height: 8px; border: 1px solid var(--line); border-radius: 999px; background: #0b1830; overflow: hidden; } .indexing-progress-bar { height: 100%; width: 0%; background: linear-gradient(90deg, #2f5f99 0%, #4fa0ff 100%); transition: width 0.2s ease; } .indexing-progress.indeterminate .indexing-progress-bar { width: 35%; animation: indexing-indeterminate-slide 1s linear infinite; } .indexing-actions { display: flex; justify-content: flex-end; margin-top: 14px; } @keyframes indexing-indeterminate-slide { 0% { transform: translateX(-120%); } 100% { transform: translateX(320%); } } @media (max-width: 1100px) { .layout { grid-template-columns: 1fr; } .splitter { display: none; } }