diff --git a/wsai/dashboard.py b/wsai/dashboard.py
index 669cffe..5f1c425 100644
--- a/wsai/dashboard.py
+++ b/wsai/dashboard.py
@@ -936,7 +936,13 @@ PAGE = r"""
main{padding-bottom:46px}
.logdock{position:fixed;left:0;right:0;bottom:0;z-index:15;background:#0a0e13;
border-top:1px solid var(--line);display:flex;flex-direction:column;
- max-height:45vh;box-shadow:0 -8px 24px rgba(0,0,0,.35)}
+ max-height:90vh;box-shadow:0 -8px 24px rgba(0,0,0,.35)}
+ .logresize{height:7px;cursor:ns-resize;background:#0d141c;border-bottom:1px solid var(--line);
+ flex:0 0 auto;touch-action:none}
+ .logresize:hover{background:#1d3d54}
+ .logresize::before{content:"";display:block;width:44px;height:3px;margin:2px auto 0;
+ border-radius:2px;background:#2a3a49}
+ .logdock.collapsed .logresize{display:none}
.logbar{display:flex;align-items:center;gap:8px;padding:6px 12px;border-bottom:1px solid var(--line);
background:#0d141c;flex-wrap:wrap}
.logtoggle{background:none;border:none;color:var(--fg);font-size:12.5px;cursor:pointer;font-weight:600;padding:4px 6px}
@@ -1071,6 +1077,7 @@ PAGE = r"""
아직 대화가 없습니다. 사용자가 말하면 여기에 단계별로 나타납니다.
+
@@ -1509,6 +1516,26 @@ $('logToggle').onclick = ()=>{
syncDockPad();
};
window.addEventListener('resize', syncDockPad);
+// Drag the top edge of the log dock to resize its height (persisted).
+(function(){
+ const dock=$('logdock'), body=$('logbody'), handle=$('logResize');
+ const KEY='wsai_logH';
+ const maxH = ()=> Math.round(window.innerHeight*0.82);
+ function setH(px){ const h=Math.max(80, Math.min(maxH(), Math.round(px)));
+ body.style.height=h+'px'; localStorage.setItem(KEY, h); syncDockPad(); }
+ setH(parseInt(localStorage.getItem(KEY)||'180', 10));
+ let startY=0, startH=0, dragging=false;
+ handle.addEventListener('pointerdown', (e)=>{
+ if(dock.classList.contains('collapsed')) return;
+ dragging=true; startY=e.clientY; startH=body.offsetHeight;
+ try{ handle.setPointerCapture(e.pointerId); }catch(_){}
+ e.preventDefault();
+ });
+ handle.addEventListener('pointermove', (e)=>{ if(dragging) setH(startH + (startY - e.clientY)); });
+ const end=(e)=>{ if(!dragging) return; dragging=false; try{ handle.releasePointerCapture(e.pointerId); }catch(_){} };
+ handle.addEventListener('pointerup', end);
+ handle.addEventListener('pointercancel', end);
+})();
$('logSearch').oninput = renderLogs;
$('logLevel').onchange = renderLogs;
$('logClear').onclick = async ()=>{