Code editor layout: Karpathy toggle, CSS grid layout, AI panel fixes

- 🧠 Karpathy 코딩 가이드라인 토글 버튼 추가 (시스템 프롬프트 주입)
- 모델 셀렉터를 AI 패널 헤더 내부로 이동 (채팅창 너비 연동)
- CSS Grid 레이아웃으로 전환: AI 패널이 파일 탭 상단까지 연장
- 오른쪽 공백 수정: auto 컬럼 → CSS 변수(--ai-panel-w) 제어
- 입력창 소실 수정: #code-ai-panel에 overflow:hidden 추가
- 터미널 불작동 수정: .code-bottom-panels overflow:hidden 제거
- body padding/gap 초기화로 전체 여백 제거

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kim
2026-06-10 15:10:59 +09:00
co-authored by Claude Sonnet 4.6
parent 158a156746
commit f00c453de9
3 changed files with 442 additions and 665 deletions
+20 -19
View File
@@ -161,7 +161,7 @@
.code-skin-sw{width:20px;height:20px;border-radius:4px;cursor:pointer;border:2px solid var(--line);transition:.15s;box-sizing:border-box;flex-shrink:0;} .code-skin-sw{width:20px;height:20px;border-radius:4px;cursor:pointer;border:2px solid var(--line);transition:.15s;box-sizing:border-box;flex-shrink:0;}
.code-skin-sw.active{border-color:var(--brand) !important;box-shadow:0 0 0 2px var(--brand);transform:scale(1.15);} .code-skin-sw.active{border-color:var(--brand) !important;box-shadow:0 0 0 2px var(--brand);transform:scale(1.15);}
.code-skin-sw:hover{transform:scale(1.1);} .code-skin-sw:hover{transform:scale(1.1);}
body { margin: 0; background: var(--bg); color: var(--text); font-family: 'Nanum Gothic', system-ui, sans-serif; display: flex; flex-direction: column; overflow: hidden; } body { margin: 0; padding: 0; gap: 0; background: var(--bg); color: var(--text); font-family: 'Nanum Gothic', system-ui, sans-serif; display: flex; flex-direction: column; overflow: hidden; height: 100dvh; }
.code-page-header { display: flex; align-items: center; gap: 10px; padding: 8px 14px; background: var(--panel); border-bottom: 1px solid var(--line); flex-shrink: 0; } .code-page-header { display: flex; align-items: center; gap: 10px; padding: 8px 14px; background: var(--panel); border-bottom: 1px solid var(--line); flex-shrink: 0; }
.code-page-header h1 { font-size: 14px; font-weight: 700; margin: 0; } .code-page-header h1 { font-size: 14px; font-weight: 700; margin: 0; }
.code-page-header .sub { font-size: 11px; color: var(--muted); } .code-page-header .sub { font-size: 11px; color: var(--muted); }
@@ -336,45 +336,44 @@
<!-- ── Code Editor View (mirrors #code-view in index.html) ─────────────── --> <!-- ── Code Editor View (mirrors #code-view in index.html) ─────────────── -->
<div id="code-view" class="active"> <div id="code-view" class="active">
<!-- File tabs bar --> <!-- Editor column: tabs + diff + editor -->
<div class="code-editor-col">
<div class="code-tabs-bar"> <div class="code-tabs-bar">
<div id="code-file-tabs" style="display:flex;flex:1"></div> <div id="code-file-tabs" style="display:flex;flex:1"></div>
<div id="code-ai-model-card" style="display:flex;align-items:center;gap:7px;padding:3px 10px 3px 12px;border-left:1px solid #1a4a35;flex-shrink:0;align-self:stretch">
<span style="font-size:16px;line-height:1">🤖</span>
<div style="display:flex;flex-direction:column;gap:1px">
<span style="font-size:9px;font-weight:700;color:#22c55e;text-transform:uppercase;letter-spacing:.07em;line-height:1">Coder AI</span>
<div class="csb-model-select-wrap" style="min-width:120px">
<select id="csb-model-select" onchange="csbModelChanged()" style="font-size:12px;font-weight:700"></select>
</div> </div>
</div>
</div>
</div>
<!-- Diff review bar (full-width, above editor) -->
<div id="code-diff-bar" style="display:none"> <div id="code-diff-bar" style="display:none">
<span id="code-diff-label">🔀 AI 제안 변경 사항</span> <span id="code-diff-label">🔀 AI 제안 변경 사항</span>
<span id="code-diff-hunk-info" style="font-size:11px;color:var(--muted)"></span> <span id="code-diff-hunk-info" style="font-size:11px;color:var(--muted)"></span>
<button id="code-diff-accept" onclick="acceptAllHunks()">✅ 모두 적용</button> <button id="code-diff-accept" onclick="acceptAllHunks()">✅ 모두 적용</button>
<button id="code-diff-reject" onclick="rejectAllHunks()">❌ 모두 취소</button> <button id="code-diff-reject" onclick="rejectAllHunks()">❌ 모두 취소</button>
</div> </div>
<!-- Editor + AI panel -->
<div class="code-body">
<div id="code-editor-container"></div> <div id="code-editor-container"></div>
</div>
<div class="code-vresize" id="code-vresize"></div> <div class="code-vresize" id="code-vresize"></div>
<!-- AI panel: starts at the very top, side by side with editor -->
<div id="code-ai-panel"> <div id="code-ai-panel">
<div id="code-ai-panel-header" style="display:flex;align-items:center;padding:4px 8px;border-bottom:1px solid #1a3a28;background:#0d1f1a;flex-shrink:0;gap:6px">
<div style="display:flex;align-items:center;gap:7px;flex:1;min-width:0">
<span style="font-size:16px;line-height:1;flex-shrink:0">🤖</span>
<div style="display:flex;flex-direction:column;gap:1px;flex:1;min-width:0">
<span style="font-size:9px;font-weight:700;color:#22c55e;text-transform:uppercase;letter-spacing:.07em;line-height:1">Coder AI</span>
<div class="csb-model-select-wrap" style="min-width:0;width:100%">
<select id="csb-model-select" onchange="csbModelChanged()" style="font-size:12px;font-weight:700;width:100%"></select>
</div>
</div>
</div>
<button id="code-opt-karpathy" class="csb-term-btn" onclick="csbKarpathy(!_karpathyMode)" title="Karpathy 코딩 가이드라인 적용" style="font-size:11px;padding:4px 8px;border-radius:4px;flex-shrink:0">🧠 Karpathy</button>
</div>
<div id="code-ai-messages"> <div id="code-ai-messages">
<div class="code-ai-msg thinking">코드를 선택하고 "AI에게 전송"을 누르거나, 아래에 질문을 입력하세요.</div> <div class="code-ai-msg thinking">코드를 선택하고 "AI에게 전송"을 누르거나, 아래에 질문을 입력하세요.</div>
</div> </div>
<!-- 세션 상태 바 -->
<div id="code-ai-session-bar" style="display:flex;align-items:center;padding:5px 10px;border-top:1px solid #1a3a28;background:#0a1812;flex-shrink:0;gap:8px"> <div id="code-ai-session-bar" style="display:flex;align-items:center;padding:5px 10px;border-top:1px solid #1a3a28;background:#0a1812;flex-shrink:0;gap:8px">
<!-- 세션 정보 -->
<div style="display:flex;align-items:center;gap:5px;min-width:0;flex:1;overflow:hidden"> <div style="display:flex;align-items:center;gap:5px;min-width:0;flex:1;overflow:hidden">
<span style="font-size:10px;color:#4a7a5c;font-weight:700;text-transform:uppercase;letter-spacing:.05em;flex-shrink:0">세션</span> <span style="font-size:10px;color:#4a7a5c;font-weight:700;text-transform:uppercase;letter-spacing:.05em;flex-shrink:0">세션</span>
<span id="code-ai-session-bar-project" style="font-size:11px;color:#86c9a0;font-family:'IBM Plex Mono',monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600">(전체)</span> <span id="code-ai-session-bar-project" style="font-size:11px;color:#86c9a0;font-family:'IBM Plex Mono',monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600">(전체)</span>
<span id="code-ai-session-bar-count" style="font-size:10px;color:#4a7a5c;flex-shrink:0"></span> <span id="code-ai-session-bar-count" style="font-size:10px;color:#4a7a5c;flex-shrink:0"></span>
</div> </div>
<!-- 목록으로 버튼 -->
<button id="code-ai-back-btn" onclick="_backToSessionList()" title="세션 목록으로" style="display:none;flex-shrink:0;background:none;border:1px solid #2a4a38;color:#5a9e78;border-radius:4px;padding:2px 7px;font-size:10px;cursor:pointer;font-family:'IBM Plex Mono',monospace" onmouseover="this.style.borderColor='#22c55e';this.style.color='#22c55e'" onmouseout="this.style.borderColor='#2a4a38';this.style.color='#5a9e78'">← 목록</button> <button id="code-ai-back-btn" onclick="_backToSessionList()" title="세션 목록으로" style="display:none;flex-shrink:0;background:none;border:1px solid #2a4a38;color:#5a9e78;border-radius:4px;padding:2px 7px;font-size:10px;cursor:pointer;font-family:'IBM Plex Mono',monospace" onmouseover="this.style.borderColor='#22c55e';this.style.color='#22c55e'" onmouseout="this.style.borderColor='#2a4a38';this.style.color='#5a9e78'">← 목록</button>
<!-- 컨텍스트 사용량 -->
<div id="code-ai-ctx-wrap" title="클릭하면 최대값 재확인" onclick="_codeAiCtxMaxFetchedFor='';_fetchModelCtxMax(codeAiModel);" style="display:none;flex-shrink:0;align-items:center;gap:5px;cursor:pointer"> <div id="code-ai-ctx-wrap" title="클릭하면 최대값 재확인" onclick="_codeAiCtxMaxFetchedFor='';_fetchModelCtxMax(codeAiModel);" style="display:none;flex-shrink:0;align-items:center;gap:5px;cursor:pointer">
<span id="code-ai-ctx-label" style="font-size:11px;color:#86c9a0;white-space:nowrap;font-family:'IBM Plex Mono',monospace"></span> <span id="code-ai-ctx-label" style="font-size:11px;color:#86c9a0;white-space:nowrap;font-family:'IBM Plex Mono',monospace"></span>
<div style="width:56px;height:4px;background:#1a3a28;border-radius:4px;overflow:hidden;flex-shrink:0"> <div style="width:56px;height:4px;background:#1a3a28;border-radius:4px;overflow:hidden;flex-shrink:0">
@@ -389,7 +388,8 @@
<button id="code-ai-send-btn" class="code-tool-btn primary" onclick="codeAiSend()" style="flex-shrink:0;align-self:flex-end">전송</button> <button id="code-ai-send-btn" class="code-tool-btn primary" onclick="codeAiSend()" style="flex-shrink:0;align-self:flex-end">전송</button>
</div> </div>
</div> </div>
</div> <!-- Bottom panels: terminal + preview (grid-area: term) -->
<div class="code-bottom-panels">
<!-- Code editor terminal panel --> <!-- Code editor terminal panel -->
<div id="code-term-panel" style="display:none;flex-direction:column;flex-shrink:0;height:260px;min-height:80px;border-top:2px solid #1a4a35;background:#0c0c0c;position:relative"> <div id="code-term-panel" style="display:none;flex-direction:column;flex-shrink:0;height:260px;min-height:80px;border-top:2px solid #1a4a35;background:#0c0c0c;position:relative">
<div id="code-term-drag" style="position:absolute;top:0;left:0;right:0;height:5px;cursor:ns-resize;z-index:2;transition:background .15s"></div> <div id="code-term-drag" style="position:absolute;top:0;left:0;right:0;height:5px;cursor:ns-resize;z-index:2;transition:background .15s"></div>
@@ -421,6 +421,7 @@
<iframe id="code-preview-iframe" src="" style="flex:1;border:none;background:#fff;min-height:0" sandbox="allow-scripts allow-same-origin allow-forms allow-modals allow-popups"></iframe> <iframe id="code-preview-iframe" src="" style="flex:1;border:none;background:#fff;min-height:0" sandbox="allow-scripts allow-same-origin allow-forms allow-modals allow-popups"></iframe>
</div> </div>
</div> </div>
</div>
</div> </div>
+366 -610
View File
File diff suppressed because it is too large Load Diff
+26 -6
View File
@@ -2358,12 +2358,18 @@
/* ── Code Editor View ────────────────────────────────────────── */ /* ── Code Editor View ────────────────────────────────────────── */
#code-view { #code-view {
display: none; display: none;
flex-direction: column;
height: 100%; height: 100%;
background: var(--bg); background: var(--bg);
overflow: hidden; overflow: hidden;
} }
#code-view.active { display: flex; } #code-view.active {
display: grid;
grid-template-columns: 1fr 5px var(--ai-panel-w, 360px);
grid-template-rows: 1fr auto;
grid-template-areas:
"editor vresize ai"
"term term term";
}
.code-tabs-bar { .code-tabs-bar {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
@@ -2417,22 +2423,33 @@
.code-tool-btn.btn-save { background:#0d1f2e; border-color:#1a4a6b; color:#60a5fa; } .code-tool-btn.btn-save { background:#0d1f2e; border-color:#1a4a6b; color:#60a5fa; }
.code-tool-btn.primary { background:#166534; border-color:#22c55e; color:#fff; } .code-tool-btn.primary { background:#166534; border-color:#22c55e; color:#fff; }
.code-tool-btn.primary.busy { background:#7f1d1d; border-color:#ef4444; } .code-tool-btn.primary.busy { background:#7f1d1d; border-color:#ef4444; }
.code-body { .code-editor-col {
display: flex; flex: 1; min-height: 0; overflow: hidden; grid-area: editor;
display: flex;
flex-direction: column;
min-width: 0;
overflow: hidden;
} }
#code-editor-container { #code-editor-container {
flex: 1; min-width: 0; position: relative; background: #1e1e1e; flex: 1; min-width: 0; position: relative; background: #1e1e1e;
} }
.code-vresize { .code-vresize {
grid-area: vresize;
width: 5px; cursor: col-resize; background: #333; flex-shrink: 0; width: 5px; cursor: col-resize; background: #333; flex-shrink: 0;
transition: background .15s; transition: background .15s;
} }
.code-vresize:hover { background: #3b78ff; } .code-vresize:hover { background: #3b78ff; }
#code-ai-panel { #code-ai-panel {
width: 360px; min-width: 220px; max-width: 60%; grid-area: ai;
min-width: 220px;
display: flex; flex-direction: column; display: flex; flex-direction: column;
background: #080f0c; border-left: 1px solid #1a3a28; background: #080f0c; border-left: 1px solid #1a3a28;
flex-shrink: 0; overflow: hidden;
}
.code-bottom-panels {
grid-area: term;
display: flex;
flex-direction: column;
} }
.code-ai-header { .code-ai-header {
display: flex; align-items: center; justify-content: space-between; display: flex; align-items: center; justify-content: space-between;
@@ -2673,6 +2690,9 @@
cursor: pointer; cursor: pointer;
padding-right: 20px; padding-right: 20px;
color-scheme: dark; color-scheme: dark;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
.csb-model-select-wrap select option { .csb-model-select-wrap select option {
background: #1a2a1a; background: #1a2a1a;