v3.2.2: 폴더블 폰 모바일 패널 토글 전면 수정 + 탐정앱 네트워크 분석 + 음성 유틸

- mobToggle 가드 640→1024: 음악·슬라이드·코드·날씨·언어·치과·ESP32·아두이노 앱
  (CSS max-width:1024px인데 JS guard가 >640으로 남아 폴드 내부화면에서 토글 불가)
- #mob-tabbar z-index 400/490→600, 패널 bottom 0→52px, backdrop inset 0 0 52px 0
  (backdrop이 탭바를 가려 열린 상태에서 다른 탭 전환 불가 문제 해결)
- 모든 innerWidth<=640 자동트리거 →<=1024 통일 (9개 앱)
- 탐정앱: 네트워크 분석 패널 (IP조회/Traceroute/Nmap/DNS/WHOIS/SSL/취약점/해시/웹스캔/배너/CVE)
- voice-utils.js 분리 — 서브앱 공통 음성입력+TTS 유틸
- app.js: 컨텍스트 토큰 게이지 (세션 목록에 tok/max 표시), usage 이벤트 처리
- routes-music.ts: Demucs 보컬분리 + YouTube 다운로드 잡 관리 (TTL 자동정리)
- server-v2.ts: 탐정 네트워크 API (traceroute/dns/whois/ssl/nmap/vuln/hash/webscan/cve)
- session.ts: resolveNumCtx export, /api/agent/session contextTokenEstimate 노출
- config.json: 카카오 채널 설정, ITS 교통 API 키 vault 참조
- styles.css: app-mic-btn / app-tts-btn 공통 스타일

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kim
2026-06-27 19:16:59 +09:00
co-authored by Claude Sonnet 4.6
parent 5a1ecfe36d
commit 75a36cdc7d
22 changed files with 1710 additions and 91 deletions
+6 -6
View File
@@ -462,7 +462,7 @@ input.tb-num{background:#1e1e30;border:1px solid rgba(255,255,255,.1);color:#c8c
.ms-hdr h1{font-size:13px;}
/* Sidebar → left overlay */
.ms-sb{
position:fixed;top:0;left:0;bottom:0;z-index:500;
position:fixed;top:0;left:0;bottom:52px;z-index:500;
width:82vw;max-width:300px;
transform:translateX(-100%);transition:transform .25s ease;
box-shadow:4px 0 28px rgba(0,0,0,.5);
@@ -470,16 +470,16 @@ input.tb-num{background:#1e1e30;border:1px solid rgba(255,255,255,.1);color:#c8c
.ms-sb.mob-open{transform:translateX(0);}
/* Chat → right overlay */
.ms-chat{
position:fixed;top:0;right:0;bottom:0;z-index:500;
position:fixed;top:0;right:0;bottom:52px;z-index:500;
width:92vw;max-width:360px;
transform:translateX(100%);transition:transform .25s ease;
box-shadow:-4px 0 28px rgba(0,0,0,.5);
}
.ms-chat.mob-open{transform:translateX(0);}
#mob-backdrop{display:none;position:fixed;inset:0;background:rgba(0,0,0,.55);z-index:499;}
#mob-backdrop{display:none;position:fixed;inset:0 0 52px 0;background:rgba(0,0,0,.55);z-index:499;}
#mob-backdrop.show{display:block;}
#mob-tabbar{display:flex !important;position:fixed;bottom:0;left:0;right:0;z-index:490;background:var(--studio-panel);border-top:1px solid var(--studio-border);height:52px;}
#mob-tabbar{display:flex !important;position:fixed;bottom:0;left:0;right:0;z-index:600;background:var(--studio-panel);border-top:1px solid var(--studio-border);height:52px;}
.ms-layout{padding-bottom:52px;}
@@ -3229,7 +3229,7 @@ function mobCloseAll(){
document.getElementById('mobtab-stage').classList.add('active');
}
function mobToggle(which){
if(window.innerWidth>640)return;
if(window.innerWidth>1024)return;
const filesOpen=document.querySelector('.ms-sb').classList.contains('mob-open');
const aiOpen=document.querySelector('.ms-chat').classList.contains('mob-open');
if(which==='files'&&filesOpen){mobCloseAll();return;}
@@ -3252,7 +3252,7 @@ async function sendMessage() {
const input = document.getElementById('chat-input');
const msg = input.value.trim();
if (!msg || document.getElementById('send-btn').disabled) return;
if(window.innerWidth<=640)mobToggle('ai');
if(window.innerWidth<=1024)mobToggle('ai');
input.value = ''; autoResize(input);
addChatMsg('user', escHtml(msg));
await callChat(msg);