/* 사용 환경 전제: 태블릿을 손에 들지 않은 채, 거리도 자세도 일정하지 않다.
   그래서 조작 요소는 화면 대부분을 차지하고, 상태는 색/글자/움직임 세 가지로
   동시에 표현한다. 색만으로 구분되는 정보는 두지 않는다. */

:root {
  color-scheme: dark;
  --bg: #0e1117;
  --panel: #161b24;
  --line: #232b38;
  --fg: #e8edf5;
  --muted: #8b98ab;
  --accent: #38bd7d;
  --accent-ink: #06240f;
  --rec: #ef4444;
  --busy: #3b82f6;
  --warn: #f59e0b;
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  /* 키보드가 가린 높이. app.js 가 visualViewport 로 재서 넣는다. */
  --kb: 0px;
  /* 넓은 화면에서 본문이 쓰는 폭. 머리줄·사용량·전송 막대가 모두 이 축에 맞는다. */
  --wide: 860px;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0;
  min-height: 100%;
  background: var(--bg);
  color: var(--fg);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans KR", system-ui, sans-serif;
  /* 당겨서 새로고침만 막는다.
     예전에는 height:100% + overflow:hidden 이었는데, 그러면 화면보다 긴 내용에
     손이 닿지 않는다. 폰에서 텍스트 영역 아래의 체크박스가 보이지 않았던 이유다. */
  overscroll-behavior-y: contain;
}

/* 글은 어디서나 끌어서 고르고 복사할 수 있어야 한다.
 *
 * 예전에는 오조작을 막으려고 body 전체에서 선택을 껐는데, 그러면 대기 목록의
 * 명령문이나 지난 답변처럼 **가져다 쓰고 싶은 글까지** 고를 수 없었다.
 * 반대로 켜 두고, 누르는 것들(버튼·칩·머리줄)만 따로 끈다. 그것들은 끌어도
 * 나올 글이 없고, 오히려 손가락을 조금만 밀어도 선택이 잡혀 탭이 씹힌다. */
body { -webkit-user-select: text; user-select: text; touch-action: manipulation; }

button, a, select, label, summary,
#bar, #tabs, .chip, .chips, .now-bar, .actions,
.led, .badge-dot, #gauge, #ptr {
  -webkit-user-select: none; user-select: none;
}
/* 버튼 안의 글은 못 고르지만, 그 버튼이 담고 있는 '내용' 은 고를 수 있어야
   한다 — 추천 명령이 그렇다. 그래서 본문 조각만 되돌린다. */
.sug-body, .q-text, .log-said, .log-typed, .pj-name {
  -webkit-user-select: text; user-select: text;
}

#app {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  padding: var(--safe-t) var(--safe-r) var(--safe-b) var(--safe-l);
}

/* ---------------------------------------------------------------- 상태 바 */
/* 메뉴가 늘면서 한 줄에 다 들어가지 않게 됐다. 예전에는 버튼이 전부
   flex:none + nowrap 이라 줄어들지도 접히지도 않아서, 가로로 삐져나가고
   그 바람에 호스트 이름(맨 앞)이 화면 밖으로 밀려났다.
   넘치면 아랫줄로 접는다. */
#bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  font-size: 15px;
  border-bottom: 1px solid var(--line);
  flex: none;
}
#dot {
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--muted); flex: none;
  transition: background .2s;
}
/* 점 + 이름을 한 덩어리로 묶어 첫 줄에 두고, 메뉴는 그 아래로 흐르게 한다 */
#bar > #dot { order: 0; }
#bar > #hostname { order: 1; flex: 1 1 calc(100% - 20px); }
#bar > button, #bar > a { order: 2; }
/* 호스트 이름은 첫 줄을 혼자 쓴다. 버튼들 사이에 끼워 두면 버튼이 늘 때마다
   자리를 빼앗겨 사라진다(실제로 'Dev PC' 가 화면 밖으로 밀려났다). */
/* 이름표.
   #hostname 이 한 줄을 다 쓰므로(flex-basis 100%) 이 이름표는 상태 점 옆,
   머리말 첫 줄에 선다. 로고 자리에 해당한다. */
#brand {
  font-weight: 800; font-size: 15.5px; letter-spacing: -.01em;
  white-space: nowrap; color: var(--fg);
}

#hostname {
  flex: 1 1 100%;
  min-width: 0;
  font-weight: 600; font-size: 13px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 머리말 버튼은 아이콘이 아니라 글자로 둔다. 아이콘만 있으면 무슨 뜻인지
   알 수 없다는 지적이 있었다. */
#bar button, #bar a {
  flex: 0 0 auto; min-height: 34px; padding: 0 10px; border-radius: 9px;
  display: inline-grid; place-items: center; text-decoration: none;
  border: 1px solid var(--line); background: var(--panel); color: var(--fg);
  font-family: inherit; font-size: 12.5px; font-weight: 700; white-space: nowrap;
}
#bar button:active, #bar a:active { background: #232a34; }
#link-panel { color: var(--accent); border-color: rgba(56,189,125,.4); }

body[data-state="idle"] #dot,
body[data-state="recording"] #dot,
body[data-state="uploading"] #dot { background: var(--accent); }
body[data-state="offline"] #dot,
body[data-state="unauthorized"] #dot { background: var(--rec); }
body[data-state="connecting"] #dot { background: var(--warn); animation: blink 1s infinite; }

/* ------------------------------------------------------- 누르고 말하는 버튼 */
/* 화면 위쪽은 전부 결과가 쓰고, 녹음은 오른쪽 아래에 떠 있는 작은 원으로 둔다.
   전송 막대 바로 위라 엄지로 닿는다.

   #stage 는 자리를 차지하면 안 되지만 display:none 으로 숨기면 안 된다.
   안에 든 #ptt 가 position:fixed 라도 부모가 none 이면 아예 그려지지 않는다
   (실제로 그렇게 두어서 마이크가 통째로 사라져 있었다).
   display:contents 는 상자만 없애고 자식은 그대로 그린다. */
#stage { display: contents; }

#ptt {
  position: fixed;
  right: 14px;
  bottom: calc(80px + var(--safe-b) + var(--kb, 0px));
  z-index: 16;
  width: 62px; height: 62px;
  display: grid; place-items: center;
  border: 2px solid var(--line);
  border-radius: 50%;
  background: #1b2331;
  color: var(--fg);
  font-family: inherit;
  padding: 0;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .45);
  /* 정밀 조준 없이 눌러야 하므로, 스크롤/제스처로 새지 않게 고정한다 */
  touch-action: none;
  transition: background .12s, border-color .12s, transform .08s, bottom .16s ease;
}
#ptt:disabled { opacity: .45; }
#ptt-icon { width: 28px; height: 28px; fill: currentColor; stroke: currentColor; }
/* 원 안에는 아이콘만 둔다. 상태는 색과 아래 두 조각으로 알린다. */
#ptt-label, #ptt-sub { display: none; }
#timer {
  position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%);
  margin-bottom: 12px; padding: 3px 9px; border-radius: 999px;
  background: var(--rec); color: #fff;
  font-size: 12px; font-weight: 800; font-variant-numeric: tabular-nums;
  white-space: nowrap; opacity: 0; pointer-events: none;
}
#meter {
  position: absolute; bottom: 100%; left: 0;
  margin-bottom: 5px; width: 62px; height: 4px; border-radius: 3px;
  background: rgba(255,255,255,.12); overflow: hidden; opacity: 0;
}
#meter i { display: block; height: 100%; width: 0%; background: var(--fg); transition: width .06s linear; }

/* 녹음 중 — 색 + 글자 + 테두리 맥동, 세 가지가 동시에 바뀐다 */
body[data-state="recording"] #ptt {
  background: #3a1414;
  border-color: var(--rec);
  animation: pulse 1.1s ease-in-out infinite;
}
body[data-state="recording"] #ptt-icon { color: var(--rec); }
body[data-state="recording"] #timer,
body[data-state="recording"] #meter { opacity: 1; }

/* 고정됨 — 손을 떼도 계속 녹음되는 상태.
   맥동을 멈추고 안쪽 테두리를 둘러, 손가락을 뗀 지금이 '유지 중'임을 보인다. */
body[data-latched="1"] #ptt {
  animation: none;
  box-shadow: inset 0 0 0 4px var(--rec), 0 0 0 2px rgba(239, 68, 68, .35);
}

/* 전송/처리 중 */
body[data-state="uploading"] #ptt {
  background: #12213c;
  border-color: var(--busy);
}
body[data-state="uploading"] #ptt-icon { animation: spin 1.2s linear infinite; color: var(--busy); }

body[data-state="offline"] #ptt,
body[data-state="unauthorized"] #ptt,
body[data-state="connecting"] #ptt { background: #171b22; border-color: var(--line); }

body[data-state="error"] #ptt { border-color: var(--warn); }

/* ------------------------------------------------------------- 결과 영역 */
/* 내용만큼만 차지한다. 남으면 문서가 스크롤된다. */
#result {
  flex: 0 0 auto;
  border-top: 1px solid var(--line);
  padding: 12px 14px calc(12px + var(--safe-b));
  background: var(--panel);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* display 를 주는 선택자는 [hidden] 보다 우선하므로 명시적으로 되돌린다 */
#banner[hidden] { display: none; }
#banner {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: #2a1f14; border: 1px solid #4a3418; color: #f0c98a;
  border-radius: 12px; padding: 10px 12px; font-size: 15px;
}
#banner-text { flex: 1 1 160px; }
#banner button {
  border: 1px solid #6b4c22; background: #3a2a15; color: #f5d9a6;
  border-radius: 10px; padding: 10px 16px; font-size: 15px; font-weight: 600;
}

#text {
  width: 100%;
  min-height: 8.5em;
  max-height: 45vh;
  resize: vertical;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: #0f141c;
  color: var(--fg);
  padding: 11px 13px;
  font-size: 15px;
  line-height: 1.55;
  font-family: inherit;
}
#text:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

.actions { display: flex; gap: 10px; }
.actions + .actions { margin-top: 10px; }

/* 주 동작(전송)은 화면 아래에 붙여 둔다. 결과를 스크롤해 내려가도 따라온다.
   #actions 만 대상으로 한다 — 모달 안의 .actions 는 그대로 흘러야 한다. */
#actions {
  position: fixed;
  left: 0; right: 0;
  /* 키보드가 올라오면 그만큼 위로. 글을 쓰는 중에도 전송이 보여야 한다. */
  bottom: var(--kb, 0px);
  z-index: 15;
  margin: 0;
  padding: 10px 14px calc(10px + var(--safe-b));
  transition: bottom .16s ease;
  background: rgba(14, 17, 23, .95);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--line);
}
#actions button { max-width: 760px; margin-inline: auto; }
body.kb #actions { padding-bottom: 10px; }
/* 고정된 막대에 가려지지 않게 아래를 비워 둔다. */
#result { padding-bottom: calc(156px + var(--safe-b)); }
#actions2 { margin-top: 0; }
.actions button {
  flex: 1;
  min-height: 58px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: #202836;
  color: var(--fg);
  font-size: clamp(17px, 2.6vw, 21px);
  font-weight: 700;
  font-family: inherit;
}
/* 보조 동작은 좁게 둔다. 주 동작(붙여넣기/복사)이 손가락 목표를 크게 갖도록. */
.actions .narrow { flex: 0 0 30%; }
.actions #btn-clear { color: var(--muted); }
.actions .primary { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.actions button:disabled { opacity: .4; }
.actions button:active:not(:disabled) { transform: scale(.985); }
/* 두 번째 줄은 호스트를 건드리지 않는 동작이라 조금 낮게 */
#actions2 button { min-height: 56px; font-size: clamp(15px, 2.2vw, 18px); }

/* -------------------------------------------------------------- 대상 창 */
#targets[hidden] { display: none; }
#targets { margin-top: 2px; }
.chips { display: flex; flex-wrap: wrap; gap: 7px; }
.chip {
  min-height: 38px; padding: 0 13px;
  font-family: inherit; font-size: 13px; font-weight: 600; color: var(--muted);
  background: #171d27; border: 1px solid var(--line); border-radius: 999px;
  white-space: nowrap;
}
.chip.fg { border-color: var(--accent); }
.chip.on { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.chip:active { transform: scale(.97); }

/* 고른 프로젝트의 사이트를 새 탭으로. 결과를 보면서 다음 지시를 내릴 때 쓴다. */
#btn-site {
  display: flex; align-items: center; gap: 10px;
  min-height: 46px; padding: 8px 14px;
  border: 1px solid var(--line); border-radius: 14px;
  background: #171d27; color: var(--fg);
  font-size: 14px; text-decoration: none;
}
#btn-site[hidden] { display: none; }
#site-name {
  flex: 1 1 auto; min-width: 0; font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.site-go { color: var(--accent); font-size: 13px; font-weight: 700; flex: none; }

/* 자동 실행 토글 */
#result .check {
  display: flex; align-items: center; gap: 9px;
  min-height: 40px; color: var(--muted); font-size: 13px;
}
#result .check input { width: 19px; height: 19px; accent-color: var(--accent); }

#win-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px;
            max-height: 52vh; overflow: auto; }
#win-list button {
  display: flex; align-items: baseline; gap: 10px; width: 100%;
  padding: 13px 14px; border-radius: 12px;
  border: 1px solid var(--line); background: #202836; color: var(--fg);
  font-family: inherit; font-size: 16px; text-align: left;
}
#win-list button:disabled { opacity: .5; }
#win-list .proj { font-weight: 700; flex: 0 0 auto; }
#win-list .file {
  color: var(--muted); font-size: 13px; flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 지금 포커스된 창 — 고를 필요가 없는 항목임을 표시 */
#win-list button.current { border-color: var(--accent); background: #172130; }
#win-list .tag { font-size: 12px; color: var(--accent); flex: 0 0 auto; }
#win-list .tag.dim { color: var(--muted); }
#win-list .empty { color: var(--muted); font-size: 14px; padding: 8px 2px; }

/* ------------------------------------------------------------- 오버레이 */
/* 겹쳐 뜨는 창은 예외 없이 화면 안에 들어와야 하고, 넘치면 스크롤되어야 한다.
   대기 목록이 길어졌을 때 상자가 화면 밖으로 삐져나가 위아래가 잘리고,
   스크롤도 되지 않아 닫기 버튼에 손이 닿지 않는 일이 있었다.
   그래서 여기 한 곳에서 전부에 같은 규칙을 건다. */
#setup, #info, #queuebox {
  position: fixed; inset: 0; z-index: 20;
  background: rgba(8, 11, 16, .94);
  display: grid; place-items: center;
  padding: 12px;
}
/* 대기 화면은 세 칸으로 나눈다 — 머리줄 / 스크롤되는 목록 / 늘 보이는 조작부.
   통째로 흐르게 두면 목록이 길어질수록 아래 버튼이 화면 밖으로 밀려난다. */
#queuebox > .panel.wide {
  width: 100%; max-width: 620px;
  height: min(88dvh, 100dvh - 24px);
  display: flex; flex-direction: column;
  padding: 0; overflow: hidden;
}
#queuebox #queue-list {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 9px;
}
#queue-foot {
  flex: none;
  padding: 0 16px calc(14px + var(--safe-b));
  border-top: 1px solid var(--line);
  background: var(--panel);
}
/* 바닥 칸 안에서는 위쪽 구분선이 두 번 그어지지 않게 */
#queue-foot .qc { margin-top: 0; margin-bottom: 0; padding-top: 14px; border-top: none; }
#queue-count { font-size: 12px; color: var(--muted); font-weight: 400; margin-left: 6px; }
#setup[hidden], #info[hidden], #queuebox[hidden] { display: none; }

/* 화면을 넘지 않게 — 모든 겹침 창에 공통 */
#setup, #info, #queuebox, #lock, #nowbox, #askbox, #logbox, #setbox, #projbox,
#sttbox {
  overflow-y: auto;
  /* 상자 안에서 끝까지 내렸을 때 뒤 화면이 따라 밀리지 않게 */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* 안쪽에 따로 스크롤 영역을 둔 것들(현황·질문·기록·설정)은 이미 88dvh 로
   묶여 있다. 그렇지 않은 것들은 상자째 스크롤한다. */
#setup > .panel, #info > .panel, #lock > .panel {
  max-height: calc(100dvh - 24px);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
/* 패널 안의 버튼 줄은 본문 크기에 맞춘다(녹음 화면의 큰 버튼 규격을 쓰지 않게) */
.panel .actions button { min-height: 52px; font-size: 16px; }
.panel {
  width: 100%; max-width: 520px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 20px; padding: 24px;
}
.panel h2 { margin: 0 0 10px; font-size: 20px; }
.panel p { color: var(--muted); font-size: 15px; line-height: 1.6; margin: 0 0 14px; }
.panel .hint { font-size: 13px; margin-top: 14px; margin-bottom: 0; }
.panel pre {
  background: #0f141c; border: 1px solid var(--line); border-radius: 12px;
  padding: 12px; font-size: 12px; color: var(--muted);
  max-height: 46vh; overflow: auto; white-space: pre-wrap; word-break: break-all;
  -webkit-user-select: text; user-select: text;
}
.panel button {
  width: 100%; min-height: 60px; border-radius: 14px; border: none;
  font-size: 18px; font-weight: 700; font-family: inherit;
  background: var(--accent); color: var(--accent-ink);
}
#setup-urls { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
#setup-urls a {
  display: block; padding: 14px; border-radius: 12px; text-align: center;
  background: #202836; color: var(--fg); text-decoration: none;
  font-size: 15px; word-break: break-all;
}

/* ------------------------------------------------------------ PIN 잠금 */
#lock {
  position: fixed; inset: 0; z-index: 40;
  background: var(--bg);
  display: grid; place-items: center;
  padding: 12px;
}
#lock[hidden] { display: none; }
#lock .panel { text-align: center; max-width: 420px; }
/* 처음 들어오는 화면이라 이름이 가장 크게 보이는 자리다. */
#lock-brand {
  font-size: 12.5px; font-weight: 800; letter-spacing: .12em;
  text-transform: uppercase; color: var(--accent);
  margin-bottom: 10px;
}

#pin-dots {
  display: flex; justify-content: center; gap: 14px;
  min-height: 22px; margin: 6px 0 22px;
}
#pin-dots i {
  width: 16px; height: 16px; border-radius: 50%;
  background: transparent; border: 2px solid var(--muted);
}
#pin-dots i.on { background: var(--accent); border-color: var(--accent); }

#keypad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
#keypad button {
  min-height: 74px;
  border-radius: 16px;
  border: 1px solid var(--line);
  background: #202836;
  color: var(--fg);
  font-size: 28px;
  font-weight: 700;
  font-family: inherit;
  width: 100%;
}
#keypad button.alt { font-size: 18px; color: var(--muted); background: #171d27; }
#keypad button:active { background: #2b3648; }
#keypad button:disabled { opacity: .4; }

#lock-error { color: #f87171; min-height: 1.4em; margin: 16px 0 0; font-size: 15px; }
.panel p.err { color: #f87171; }

/* --------------------------------------------------------------- 토스트 */
/* 알림.
 *
 * 화면 아래 조그맣게 띄우면 알아채기 어려워서 한복판으로 옮겼다. 다만
 * 강조색을 배경으로 깔았더니 진한 글자와의 대비가 탁했다. 어두운 유리판에
 * 흰 글자를 얹고, 성공/실패는 **왼쪽 띠와 점**으로만 가른다. 배경은 늘
 * 같으니 글자는 어떤 경우에도 또렷하다.
 */
#toast {
  position: fixed; left: 50%; top: 50%;
  transform: translate(-50%, -50%) scale(.96);
  z-index: 45;
  display: flex; align-items: center; gap: 11px;
  max-width: min(84vw, 420px);
  padding: 15px 20px 15px 17px;
  border-radius: 14px;
  text-align: left;

  background: rgba(22, 27, 36, .92);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, .10);
  border-left: 3px solid var(--accent);
  box-shadow: 0 14px 40px rgba(0, 0, 0, .55), 0 0 0 1px rgba(0, 0, 0, .3);

  color: #f2f5f9;
  font-size: 15px; font-weight: 600; line-height: 1.5;
  letter-spacing: -.01em;
  opacity: 0; pointer-events: none;
  transition: opacity .16s ease, transform .18s cubic-bezier(.2, .9, .3, 1.2);
}
/* 왼쪽의 작은 점 — 색만으로 성공/실패가 갈린다 */
#toast::before {
  content: "";
  flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 22%, transparent);
}
#toast.show { opacity: 1; transform: translate(-50%, -50%) scale(1); }

#toast.err, #toast.bad {
  border-left-color: #ff6b6b;
}
#toast.err::before, #toast.bad::before {
  background: #ff6b6b;
  box-shadow: 0 0 0 4px rgba(255, 107, 107, .22);
}

@media (prefers-reduced-motion: reduce) {
  #toast { transition: opacity .16s ease; transform: translate(-50%, -50%); }
  #toast.show { transform: translate(-50%, -50%); }
}

@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, .45); }
  50%      { box-shadow: 0 0 0 18px rgba(239, 68, 68, 0); }
}
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes blink { 50% { opacity: .25; } }

@media (prefers-reduced-motion: reduce) {
  #ptt, #ptt-icon, #dot { animation: none !important; }
}

/* 넓은 화면 — 전부 하나의 프레임 안에.
 *
 * 예전에는 머리줄만 화면 폭을 다 쓰고 본문은 가운데 모여 있어서 따로 놀았다.
 * 게다가 머리줄이 position:fixed 라 흐름에서 빠지는 바람에, 바로 아래에 있던
 * 사용량 띠가 그 뒤에 깔려 아예 보이지 않았다.
 *
 * 그래서 넓은 화면에서는 머리줄을 고정하지 않는다. 프레임(#app)을 가운데
 * 두고 머리줄·사용량·본문을 그 안에 차례로 흐르게 둔다. 화면 아래에 붙는
 * 전송 막대와 떠 있는 원들만 fixed 로 두되, 위치는 프레임에 맞춘다.
 */
@media (min-width: 820px) {
  #app {
    width: 100%;
    max-width: var(--wide);
    margin-inline: auto;
    /* 프레임임을 알아볼 수 있게 양옆에 선을 둔다 */
    border-left: 1px solid var(--line);
    border-right: 1px solid var(--line);
    min-height: 100dvh;
  }

  /* 머리줄은 흐름 안에 둔다. 고정하면 뒤엣것을 덮는다. */
  #bar { position: static; padding: 12px 16px; }

  #usage-strip { padding: 10px 16px 11px; }

  #result {
    flex: 1 1 auto; width: 100%;
    border-top: none;
    padding-left: 16px; padding-right: 16px;
  }
  #text { max-height: 40vh; min-height: 8em; }

  /* 아래에 붙는 것들은 프레임 폭에 맞춰 가운데로 */
  #actions {
    left: 50%; right: auto;
    transform: translateX(-50%);
    width: min(var(--wide), 100%);
    border-left: 1px solid var(--line);
    border-right: 1px solid var(--line);
  }

  /* 떠 있는 원도 프레임 안쪽 오른쪽에. 화면 끝에 두면 본문에서 멀어진다. */
  #ptt { right: max(14px, calc(50% - var(--wide) / 2 + 16px)); }
}

/* ----------------------------------------------- 답을 기다리는 질문 알림 */
/* 현황 모달과 같은 규격이되 한 층 위에 뜬다. 멈춰 있다는 사실이 다른 무엇보다
   먼저 보여야 한다. */
#askbox {
  position: fixed; inset: 0; z-index: 28;
  display: grid; place-items: center; padding: 14px;
  background: rgba(10, 13, 18, .86); backdrop-filter: blur(4px);
}
#askbox[hidden] { display: none; }
#askbox .panel.wide {
  width: 100%; max-width: 620px; max-height: 88dvh;
  display: flex; flex-direction: column; gap: 0;
  padding: 0; overflow: hidden;
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line));
}
#ask-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  padding: 14px 16px calc(16px + var(--safe-b));
  display: flex; flex-direction: column; gap: 16px;
  -webkit-overflow-scrolling: touch;
}

/* 머리줄의 '질문' 배지 — 숫자가 붙는다 */
#btn-ask { position: relative; }
#btn-ask[hidden] { display: none; }
#ask-dot {
  display: inline-grid; place-items: center;
  min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 999px; background: var(--rec); color: #fff;
  font-size: 11px; font-weight: 800;
}

/* ------------------------------------------------------- 기록 / 설정 모달 */
/* 현황·질문 모달과 같은 규격을 쓴다. 화면마다 다르게 생기면 어디에 있는지
   매번 다시 찾게 된다. */
#logbox, #setbox, #projbox, #sttbox {
  position: fixed; inset: 0; z-index: 26;
  display: grid; place-items: center; padding: 14px;
  background: rgba(10, 13, 18, .82); backdrop-filter: blur(4px);
}
#logbox[hidden], #setbox[hidden], #projbox[hidden], #sttbox[hidden] { display: none; }
#logbox .panel.wide, #setbox .panel.wide, #projbox .panel.wide,
#sttbox .panel.wide {
  width: 100%; max-width: 620px; max-height: 88dvh;
  display: flex; flex-direction: column; gap: 0;
  padding: 0; overflow: hidden;
}

#log-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
}
#log-head > select {
  flex: 1; min-width: 0; min-height: 40px; padding: 0 10px;
  border-radius: 10px; font-family: inherit; font-size: 14px; font-weight: 700;
  color: var(--fg); background: #0f141c; border: 1px solid var(--line);
}
#log-head .count { flex: none; font-size: 12.5px; color: var(--muted); }

/* 대기 화면의 두 탭 — 저절로 나가는 것(대기)과 눌러야 나가는 것(입력대기).
   머리줄 바로 아래 붙여서, 어느 쪽을 보고 있는지가 늘 눈에 있게 한다. */
#queue-tabs {
  display: flex; gap: 8px; flex: none;
  padding: 10px 16px 0;
}
#queue-tabs > button {
  /* `.panel button { width:100% }` 을 이겨야 한 줄에 나란히 선다. */
  flex: 1 1 0; width: auto; min-width: 0;
  min-height: 40px; padding: 0 12px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  border-radius: 10px 10px 0 0;
  font-family: inherit; font-size: 14px; font-weight: 800;
  color: var(--muted); background: transparent;
  border: 1px solid transparent; border-bottom: 2px solid var(--line);
}
#queue-tabs > button.on {
  color: var(--fg); background: #0f141c;
  border-color: var(--line); border-bottom-color: var(--accent);
}
/* 몇 건인지. 탭을 열기 전에 알아야 담아 둔 것을 잊지 않는다. */
#queue-tabs > button > span:not(:empty) {
  display: inline-block; min-width: 18px; padding: 0 5px;
  border-radius: 999px; font-size: 11.5px; font-weight: 800;
  color: var(--ink, #06121f); background: var(--accent);
}
/* 입력대기 쪽은 강조색을 쓰지 않는다 — 저절로 나가는 것이 아니라서, 급한
   일처럼 보이면 안 된다. */
#tab-hold > span:not(:empty) { color: #06121f; background: var(--warn); }

#log-list, #set-body, #proj-list, #stt-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  padding: 14px 16px calc(16px + var(--safe-b));
  display: flex; flex-direction: column; gap: 12px;
  -webkit-overflow-scrolling: touch;
}

/* 기록 한 줄 — 패널과 같은 클래스를 쓰므로 여기서도 같은 모양이 된다 */
.log-row {
  padding: 12px 14px; border-radius: 12px;
  background: #0f141c; border: 1px solid var(--line);
}
.log-row.bad { border-color: var(--warn); }
.log-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.log-time { font-size: 12.5px; font-weight: 700; color: var(--muted); font-variant-numeric: tabular-nums; }
.log-act {
  font-size: 11.5px; font-weight: 800; padding: 2px 7px; border-radius: 999px;
  background: rgba(56,189,125,.16); color: var(--accent);
}
.log-row.bad .log-act { background: rgba(245,158,11,.16); color: var(--warn); }
.log-src { margin-left: auto; font-size: 11.5px; color: var(--muted); }
.log-said { font-size: 14px; line-height: 1.5; word-break: break-word; }
.log-typed { margin-top: 5px; font-size: 13px; line-height: 1.5; color: var(--muted); word-break: break-word; }

/* 설정 안의 한 덩어리 */
.set-sec {
  display: flex; flex-direction: column; gap: 9px;
  padding-bottom: 14px; border-bottom: 1px solid var(--line);
}
.set-sec:last-child { border-bottom: none; padding-bottom: 0; }
.set-hint { margin: 0; font-size: 13px; line-height: 1.55; color: var(--muted); }
.set-hint.tight { font-size: 12.5px; }
.set-hint b { color: var(--fg); }

.set-row { display: flex; gap: 8px; }
.set-row > input {
  flex: 1 1 auto; min-width: 0; min-height: 46px; padding: 0 13px;
  border-radius: 11px; font-family: inherit; font-size: 15px;
  color: var(--fg); background: #0f141c; border: 1px solid var(--line);
}
.set-row > input:focus { outline: none; border-color: var(--accent); }
/* `.panel button { width:100% }` 을 이겨야 한 줄에 나란히 선다 */
.set-row > button, .set-sec > button {
  flex: 0 0 auto; width: auto; min-width: 0; min-height: 46px;
  padding: 0 16px; border-radius: 11px; cursor: pointer;
  font-family: inherit; font-size: 14px; font-weight: 800;
  color: var(--fg); background: #202836; border: 1px solid var(--line);
}
.set-row > button.primary, .set-sec > button.primary {
  color: var(--accent-ink); background: var(--accent); border-color: var(--accent);
}
.set-row > button:disabled, .set-sec > button:disabled { opacity: .45; }

#set-ex-filter, #set-new-name {
  width: 100%; box-sizing: border-box; min-height: 44px; padding: 0 13px;
  border-radius: 11px; font-family: inherit; font-size: 14px;
  color: var(--fg); background: #0f141c; border: 1px solid var(--line);
}
#set-ex-list { max-height: 40vh; overflow-y: auto; }

/* 폴더 칩 — 켜진 것(쓰는 것)이 또렷하고, 끈 것은 흐리다 */
.set-chips { display: flex; flex-wrap: wrap; gap: 7px; }
.set-chips > button {
  width: auto; min-width: 0; min-height: 36px; padding: 0 12px;
  border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 700;
  color: var(--muted); background: #0f141c; border: 1px solid var(--line);
}
.set-chips > button.on {
  color: var(--fg); background: #202836;
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line));
}
.set-chips > button:active { transform: translateY(1px); }

/* ------------------------------------------------------------ 대기 목록 */
/* 숫자 배지가 붙는 머리줄 버튼은 글자와 배지가 나란히 흘러야 한다.
   `#bar button` 이 inline-grid 여서, 그대로 두면 글자와 배지가 각각 한 칸씩
   차지해 위아래로 겹쳐 앉고 '대기'/'질문' 글자를 가린다.

   `#btn-queue` 만으로는 이기지 못한다. `#bar button` 은 ID+요소라 명시도가
   (1,0,1) 이고 ID 하나짜리 (1,0,0) 보다 높다. 그래서 #bar 를 앞에 붙인다. */
/* `:not([hidden])` 가 꼭 있어야 한다.
   이 선택자는 ID 두 개라 `#btn-ask[hidden] { display:none }`(ID 하나 + 속성
   하나)보다 세다. 그냥 두면 hidden 을 걸어도 display 가 되살아나서, 질문이
   없는데도 '질문' 버튼이 계속 떠 있었다. */
#bar #btn-queue:not([hidden]), #bar #btn-ask:not([hidden]) {
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
}

/* 상자 전체가 스크롤되므로 목록에는 따로 높이 제한을 두지 않는다.
   두 겹으로 스크롤되면 어디를 밀고 있는지 알 수 없다. */
#queue-list { display: flex; flex-direction: column; gap: 9px; }
#queue-list .empty { color: var(--muted); font-size: 14px; padding: 10px 2px; text-align: center; }

.q-row {
  padding: 10px 12px; border-radius: 12px;
  background: #171d27; border: 1px solid var(--line); text-align: left;
}
.q-row.s-done      { opacity: .6; }
.q-row.s-cancelled { opacity: .5; }
.q-row.s-failed    { border-color: var(--warn); }

.q-head { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.q-badge {
  font-size: 11px; padding: 2px 8px; border-radius: 999px;
  background: rgba(88,166,255,.16); color: var(--accent); white-space: nowrap;
}
.s-failed .q-badge { background: rgba(240,201,138,.16); color: var(--warn); }
.s-done   .q-badge { background: rgba(255,255,255,.10); color: var(--muted); }
.q-when { font-size: 12px; color: var(--muted); }
.q-text { font-size: 14px; line-height: 1.45; word-break: break-word; }
.q-err  { font-size: 12px; color: var(--warn); margin-top: 5px; }

/* -------------------------------------------------- Claude 진행 상태 */
/* 칩 안의 작은 불. 앞의 지시가 끝났는지 호스트 화면을 안 보고도 알게 한다. */
.chip .led {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  margin-right: 7px; vertical-align: middle; flex: none;
}
/* 상태마다 색을 못 박는다.
 *
 * 예전에는 busy 가 var(--accent) 였는데 이 페이지의 --accent 는 초록이라,
 * 일하는 중과 기다리는 중이 둘 다 초록이었다 (깜빡이는 것만 달랐다).
 *   일하는 중  파랑 (깜빡임)   .busy
 *   방금 끝남  빨강            .chip.done .led.idle  — 답이 와 있다는 뜻
 *   기다리는 중 초록            .idle
 */
.chip .led.idle { background: #3fb950; }
.chip .led.busy { background: var(--busy); animation: led-pulse 1s infinite; }
.chip.on .led.busy { background: var(--accent-ink); }
.chip.on .led.idle { background: var(--accent-ink); opacity: .5; }

/* 방금 답이 끝난 프로젝트 — 며칠 묵은 것들 사이에서 바로 눈에 들어와야 한다 */
.chip.done {
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  background: color-mix(in srgb, var(--accent) 12%, #202836);
}
/* 고른 칩은 '완료' 여도 고른 것처럼 보여야 한다.
 *
 * `.chip.on`(0,2,0) 과 `.chip.done`(0,2,0) 은 명시도가 같고 done 이 뒤에 있어서,
 * 둘 다 붙은 칩은 done 의 배경이 이겼다. `.chip.on` 은 색만 정하고 배경은 못
 * 정하니 **글자색만 바뀌고 배경은 그대로**였다 — 눌러도 고른 티가 안 났다.
 * 그래서 둘 다 붙은 경우를 (0,3,0) 으로 따로 적는다.
 *
 * 빨간 점(.chip.done .led.idle)과 배지는 그대로 둔다. 골랐다고 해서 '답이 와
 * 있다' 는 사실이 사라지는 것은 아니다. */
.chip.on.done {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: transparent;
}
/* `.chip.on .led.idle` 보다 뒤에 둔다 — 같은 명시도(0,3,0)라 나중 것이 이긴다.
   고른 칩이라도 '완료' 면 빨간 점이 보여야 한다. */
.chip.done .led.idle { background: var(--rec); }
.chip-done {
  margin-left: 5px; padding: 1px 6px; border-radius: 999px;
  font-style: normal; font-size: 10.5px; font-weight: 800;
  color: var(--accent-ink); background: var(--accent);
  white-space: nowrap;
}
.chip.on .chip-done { color: var(--accent); background: var(--accent-ink); }
@keyframes led-pulse { 50% { opacity: .25; } }

#claude-state {
  padding: 9px 13px; border-radius: 12px; font-size: 13.5px; font-weight: 600;
  border: 1px solid var(--line); background: #171d27; color: var(--muted);
}
#claude-state[hidden] { display: none; }
#claude-state.busy { color: var(--accent); border-color: rgba(88,166,255,.45); }
#claude-state.idle { color: #7ee08a; border-color: rgba(63,185,80,.35); }

/* 헤더의 글자 버튼 (아이콘만 두면 무슨 뜻인지 알 수 없다) */
#queue-dot {
  display: inline-grid; place-items: center;
  min-width: 19px; height: 19px; padding: 0 5px;
  font-size: 11.5px; font-weight: 800; line-height: 1;
  color: var(--accent-ink); background: var(--accent); border-radius: 999px;
}
#queue-dot[hidden] { display: none; }

/* 대기 목록의 프로젝트 이름 */
.q-proj {
  font-size: 12px; font-weight: 700; color: var(--fg);
  padding: 2px 8px; border-radius: 999px;
  background: rgba(255,255,255,.07); white-space: nowrap;
}

/* ------------------------------------------------- 지난 대화 요약 */
#recap {
  display: flex; flex-direction: column; gap: 7px;
  padding: 12px 13px; border-radius: 12px;
  border: 1px solid var(--line); background: #141a23;
}
#recap[hidden] { display: none; }
.recap-wait { color: var(--muted); font-size: 13px; }
.recap-row { display: flex; gap: 9px; font-size: 13.5px; line-height: 1.5; }
.recap-cap {
  flex: 0 0 52px; color: var(--muted); font-size: 12px; font-weight: 700;
  padding-top: 2px;
}
.recap-val { flex: 1 1 auto; min-width: 0; word-break: break-word; }
.recap-row.next .recap-val { color: var(--accent); }
/* 아직 답을 기다리는 중. 끝난 내용과 헷갈리지 않게 흐리게 둔다. */
.recap-row.pending .recap-val { color: var(--muted); font-style: italic; }
.recap-more {
  align-self: flex-start; margin-top: 3px;
  min-height: 34px; padding: 0 12px;
  font-family: inherit; font-size: 12.5px; font-weight: 700; color: var(--muted);
  background: transparent; border: 1px solid var(--line); border-radius: 9px;
}
.recap-more:active { background: #1f2733; }

/* 버튼 설명 문구 */
.note {
  margin: 2px 0 0; font-size: 12.5px; line-height: 1.6; color: var(--muted);
}
.note b { color: var(--fg); font-weight: 700; }

/* 체크박스 안의 보조 설명 */
.check em { font-style: normal; color: var(--muted); opacity: .8; }

/* 요약의 '한 일' 목록 */
.recap-list {
  flex: 1 1 auto; min-width: 0;
  margin: 0; padding-left: 17px;
  display: flex; flex-direction: column; gap: 4px;
}
.recap-list li { word-break: break-word; }

/* ------------------------------------------------------------- 사용량 띠 */
/* 명령을 보내기 전에 보는 값이라 머리말 바로 아래에 늘 띄워 둔다. */
#usage-strip {
  flex: none;
  padding: 9px 16px 10px;
  border-bottom: 1px solid var(--line);
  background: var(--panel);
}
#usage-strip[hidden] { display: none; }
#usage-line { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.usage-cap { font-size: 12.5px; color: var(--muted); }
#usage-pct { font-size: 15px; font-weight: 800; }
#usage-reset { font-size: 12.5px; color: var(--muted); }
#gauge {
  height: 6px; margin-top: 7px; border-radius: 999px; overflow: hidden;
  background: #0b0f15; border: 1px solid var(--line);
}
#gauge i { display: block; height: 100%; width: 0; background: var(--accent); transition: width .3s ease; }
#gauge[data-level="warn"]    i { background: var(--warn); }
#gauge[data-level="danger"]  i { background: var(--rec); }
#gauge[data-level="unknown"] i { background: var(--muted); }

/* ------------------------------------------------------------- 현황 모달 */
/* 폰 화면이라 가로가 좁다. 세로로만 흐르게 두고, 긴 목록은 안에서 스크롤한다. */
#nowbox { position: fixed; inset: 0; z-index: 25;
  display: grid; place-items: center; padding: 14px;
  background: rgba(10, 13, 18, .82); backdrop-filter: blur(4px); }
#nowbox[hidden] { display: none; }
/* 안엣것이 캔버스 하나뿐이라 높이를 못박는다. max-height 만 두면 상자가
   안엣것에 맞춰 줄어드는데(판의 최소 높이 320px), 넓은 화면에서 그만한
   판은 기둥 하나 반밖에 안 들어온다. */
#nowbox .panel.wide {
  width: 100%; max-width: 900px; height: 86dvh; max-height: 86dvh;
  display: flex; flex-direction: column; gap: 0;
  padding: 0; overflow: hidden;
}

.now-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px; border-bottom: 1px solid var(--line);
  background: var(--panel);
}
.now-bar h2 { flex: 1; min-width: 0; margin: 0; font-size: 17px; font-weight: 800;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* `.panel button { width:100% }` 과 명시도가 같아 width 만 그쪽이 남는다.
   그러면 닫기 버튼이 머리줄을 통째로 먹고 제목이 밀려 나간다. 한 단계 올린다. */
.now-bar > button {
  flex: 0 0 auto; width: auto; min-width: 0;
  min-height: 36px; padding: 0 13px; border-radius: 10px;
  border: 1px solid var(--line); background: #1b2331; color: var(--fg);
  font-family: inherit; font-size: 13.5px; font-weight: 700;
}
.now-bar button[hidden] { display: none; }
.now-bar button:active { background: #232a34; }

#now-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  padding: 14px 16px calc(16px + var(--safe-b));
  display: flex; flex-direction: column; gap: 14px;
  -webkit-overflow-scrolling: touch;
}

/* 현황은 캔버스 하나다. 판이 본문을 통째로 쓴다.
 *
 * 본문은 스크롤하지 않는다. 판 위에서 미는 손가락이 본문까지 끌고 가면 창이
 * 통째로 움직이는 것처럼 보인다 — 무엇을 잡았는지 알 수 없다. 판 안에서만
 * 움직이고, 글(요약·원문)은 카드를 눌러 뜨는 창에서 읽는다. */
#nowbox #now-body { padding: 0; gap: 0; overflow: hidden; }
#now-board { display: flex; flex: 1 1 auto; min-height: 0; }
.ov-list { display: flex; flex-direction: column; gap: 10px; }
.now-sec { display: flex; flex-direction: column; gap: 10px; }
.now-h3 { margin: 0; font-size: 14px; font-weight: 800; color: var(--fg); }

/* --------------------------------------------------------- 당겨서 새로고침 */
/* 페이지를 통째로 다시 읽지 않는다. 보이는 값(창 목록·사용량·대기)만 다시
   받아 온다. 새로 고쳤다고 녹음이나 적어 둔 글이 날아가면 안 된다. */
#ptr {
  position: fixed; top: 0; left: 0; right: 0; z-index: 30;
  display: flex; align-items: flex-end; justify-content: center;
  height: 0; overflow: hidden;
  background: linear-gradient(180deg, rgba(56,189,125,.18), transparent);
  pointer-events: none;
  transition: height .18s ease;
}
#ptr.dragging { transition: none; }
#ptr-text {
  padding: 6px 14px 8px;
  font-size: 12.5px; font-weight: 800; color: var(--accent);
  white-space: nowrap;
}
#ptr.ready #ptr-text { color: var(--fg); }
#ptr.busy #ptr-text { color: var(--muted); }

/* ------------------------------------------------------------- 프로젝트 창 */
#proj-head {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
}
#proj-head > input {
  flex: 1 1 auto; min-width: 0; min-height: 40px; padding: 0 12px;
  border-radius: 10px; font-family: inherit; font-size: 14px;
  color: var(--fg); background: #0f141c; border: 1px solid var(--line);
}
#proj-head > input:focus { outline: none; border-color: var(--accent); }
#proj-head > button {
  flex: 0 0 auto; width: auto; min-width: 0; min-height: 40px;
  padding: 0 13px; border-radius: 10px; cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 700;
  color: var(--fg); background: #202836; border: 1px solid var(--line);
}
#proj-new {
  display: flex; flex-direction: column; gap: 8px;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
}
#proj-new[hidden] { display: none; }
#proj-new > input {
  width: 100%; box-sizing: border-box; min-height: 46px; padding: 0 13px;
  border-radius: 11px; font-family: inherit; font-size: 15px;
  color: var(--fg); background: #0f141c; border: 1px solid var(--accent);
}
#proj-new > input:focus { outline: none; }
#proj-count { font-size: 12px; color: var(--muted); font-weight: 400; margin-left: 6px; }

/* ------------------------------------------------- 지금 바로 전송 */
/* 마이크 원 바로 위에 작게. 순차 전송을 켜 두었어도 이것만은 즉시 나간다.
   (마이크는 62px, 아래에서 80px 위 → 그 위로 8px 띄운다) */
#btn-now-send {
  position: fixed;
  right: 22px;
  bottom: calc(150px + var(--safe-b) + var(--kb, 0px));
  z-index: 16;
  width: 46px; height: 46px; padding: 0;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 2px solid var(--line);
  background: #1b2331;
  color: var(--accent);
  box-shadow: 0 5px 14px rgba(0, 0, 0, .4);
  touch-action: none;
  transition: background .12s, border-color .12s, transform .08s, bottom .16s ease;
}
#btn-now-send svg { width: 20px; height: 20px; fill: currentColor; }
#btn-now-send:active { transform: translateY(1px); background: #232c3a; }
#btn-now-send:disabled { opacity: .35; }
/* 녹음 중에는 '여기서 끊고 바로 보낸다' 는 뜻이 되므로 눈에 띄게 둔다 */
body[data-state="recording"] #btn-now-send {
  color: var(--accent-ink); background: var(--accent); border-color: var(--accent);
}
body[data-state="offline"] #btn-now-send,
body[data-state="unauthorized"] #btn-now-send,
body[data-state="connecting"] #btn-now-send { display: none; }

/* 키보드가 올라온 동안에는 떠다니는 원들을 감춘다. 좁아진 화면에서 글을
   가리기만 하고, 어차피 지금 하는 일은 타이핑이다. */
body.kb #ptt, body.kb #btn-now-send { opacity: 0; pointer-events: none; }

/* 넓은 화면에서 '바로 전송' 도 프레임 안쪽에.
   이 규칙은 파일 맨 끝에 있어야 한다 — 위의 #btn-now-send 기본 규칙과
   명시도가 같아서, 앞에 두면 그쪽이 이긴다. */
@media (min-width: 820px) {
  #btn-now-send { right: max(22px, calc(50% - var(--wide) / 2 + 24px)); }
}

/* 처음 화면의 전체 진행 상황 */
.recap-head {
  font-size: 11.5px; font-weight: 800; letter-spacing: .03em;
  color: var(--muted); margin-bottom: 9px;
}
#recap .ov-list { display: flex; flex-direction: column; gap: 9px; }

/* ------------------------------------------------------------- 페이지 */
/* 머리줄 메뉴로 여는 것들은 '겹쳐 뜬 상자' 가 아니라 '넘어간 페이지' 로 보이게
   한다. 폰에서는 화면을 가득 채우고 모서리도 없앤다 — 뒤가 비쳐 보이면 지금
   어디에 있는지 헷갈린다. 뒤로가기로도 닫힌다(app.js). */
@media (max-width: 819px) {
  #nowbox, #askbox, #logbox, #setbox, #projbox, #queuebox, #info, #sttbox {
    padding: 0;
    background: var(--bg);
    backdrop-filter: none;
  }
  /* `.panel.wide` 규칙(max-height:88dvh)이 클래스 둘이라 더 구체적이다.
     같은 수로 맞춰야 화면을 가득 채운다. */
  #nowbox > .panel.wide, #askbox > .panel.wide, #logbox > .panel.wide,
  #setbox > .panel.wide, #projbox > .panel.wide, #queuebox > .panel.wide,
  #sttbox > .panel.wide,
  #nowbox > .panel, #askbox > .panel, #logbox > .panel,
  #setbox > .panel, #projbox > .panel, #queuebox > .panel, #info > .panel,
  #sttbox > .panel {
    width: 100%; max-width: none;
    height: 100dvh; max-height: 100dvh;
    border: none; border-radius: 0;
  }
  /* 머리줄은 화면 맨 위에 붙는다. 안전 영역(노치)만큼 내려서 시작한다. */
  #nowbox .now-bar, #askbox .now-bar, #logbox .now-bar,
  #setbox .now-bar, #projbox .now-bar, #queuebox .now-bar, #info .now-bar,
  #sttbox .now-bar {
    padding-top: calc(14px + var(--safe-t));
  }
  /* 정보 창은 안쪽 여백을 따로 갖고 있었다 — 페이지가 되면 머리줄이 대신한다 */
  #info > .panel { padding: 0; display: flex; flex-direction: column; }
  #info > .panel > *:not(.now-bar) { padding-left: 16px; padding-right: 16px; }
  #info-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
}

/* 오른쪽 위 X */
.now-bar > button.x {
  flex: 0 0 auto; width: 36px; min-width: 36px; padding: 0;
  font-size: 17px; line-height: 1; font-weight: 700;
  color: var(--muted);
}
.now-bar > button.x:active { background: #232a34; color: var(--fg); }

/* 메인 화면 상태 줄의 중지 버튼 */
#claude-state { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
#claude-state[hidden] { display: none; }
.state-stop {
  margin-left: auto;
  width: auto; min-width: 0; min-height: 32px;
  padding: 0 13px; border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: 12px; font-weight: 800;
  color: var(--fg); background: #202836; border: 1px solid var(--line);
}
.state-stop.armed { color: #fff; background: #b3261e; border-color: #b3261e; }
.state-stop:disabled { opacity: .5; }
.state-stop:active:not(:disabled) { transform: translateY(1px); }

/* 메인 화면의 '다음 할 것' */
#suggest-main {
  display: flex; flex-direction: column; gap: 10px;
  padding-top: 12px; margin-top: 2px;
  border-top: 1px solid var(--line);
}
#suggest-main[hidden] { display: none; }

/* ------------------------------------------------- 대기 목록 멈춤/재개
   손수 끼어들어 손볼 때 기다리던 것들이 밀려 들어오지 않게 세운다.
   멈춘 것은 '보내는 일' 뿐이고 목록은 그대로 남는다. */
.now-bar > button#btn-queue-pause.on {
  color: var(--accent-ink);
  background: var(--warn);
  border-color: var(--warn);
}

/* 멈춰 둔 동안 목록 위에 늘 보이는 띠.
   버튼 글자만 바꾸면 스크롤한 뒤에는 멈춘 줄 모른다. */
#queue-paused:not([hidden]) {
  display: block;
  margin: 0; padding: 11px 16px;
  font-size: 13.5px; line-height: 1.5;
  color: var(--fg);
  background: color-mix(in srgb, var(--warn) 16%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--warn) 45%, transparent);
}
#queue-paused b { color: var(--warn); }

/* 멈춰 두면 '대기' 오른쪽 위에 작은 빨간 점.
 *
 * 글자색만 바꿔 봤는데 메뉴를 훑을 때 눈에 들지 않았다. 점 하나가 훨씬 빨리
 * 읽힌다. 이미 있는 대기 건수 배지(#queue-dot)와 자리가 겹치지 않게 모서리에
 * 얹는다 — 건수는 글자 옆, 멈춤은 모서리다.
 *
 * `#bar button` 이 (1,0,1) 이라 ID 하나짜리로는 못 이긴다. #bar 를 앞에 붙여
 * (2,1,0) 으로 올린다.
 */
#bar #btn-queue { position: relative; }
#bar #btn-queue.paused::after {
  content: "";
  position: absolute;
  top: 3px; right: 3px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--rec);
  /* 버튼 테두리에 걸쳐도 점 모양이 뭉개지지 않게 한 겹 두른다. */
  box-shadow: 0 0 0 1.5px var(--panel);
}


/* ------------------------------------------------------------------ 보드 */
/* 판의 높이는 '보드' 칸이 통째로 준다(#now-board). 판이 제 높이를 우기면
   상자 밖으로 흘러넘쳐 아래 목록을 덮는다 — 그래서 여기서 높이를 못 박지
   않는다. 자세한 사정은 status.css 의 .bd 주석에 적어 두었다. */


/* ------------------------------------------------- 실행대기 붙박이 단추
 *
 * 담아 둔 것이 있다는 사실은 늘 보여야 한다 — 안 보이면 담아 둔 것을 잊는다.
 * 그렇다고 크게 두면 화면을 가린다. 그래서 아주 작게, 회색으로, 왼쪽 아래에
 * 붙박는다. 오른쪽 아래는 말하기 단추 자리다.
 *
 * 회색인 것은 일부러다. 이건 '지금 할 일' 이 아니라 '나중에 할 일' 이라,
 * 강조색을 주면 눈이 자꾸 그리로 간다.
 */
#hold-fab:not([hidden]) {
  position: fixed; z-index: 40;
  left: calc(14px + var(--safe-l, 0px));
  /* 전송 막대 **위**에 앉힌다.
     아래 10px 로 두었더니 가로 전체를 쓰는 #btn-run(전송) 위에 그대로 겹쳤다.
     말하기 단추(#ptt)와 같은 자리 셈을 쓴다 — 둘이 같은 줄에 서고, 키보드가
     올라와도(--kb) 함께 밀린다. */
  bottom: calc(80px + var(--safe-b) + var(--kb, 0px));
  display: flex; align-items: center; gap: 5px;
  min-height: 30px; padding: 0 9px;
  border-radius: 999px; cursor: pointer;
  /* 바탕은 불투명하게. 뒤가 비치면 글자와 겹쳐 흐리멍덩해진다. */
  color: var(--muted); background: #1b2331;
  border: 1px solid var(--line);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  font-family: inherit; font-size: 12px; font-weight: 800;
  box-shadow: 0 4px 12px rgba(0, 0, 0, .35);
}
/* 담아 둔 것이 없을 때. 자리는 지키되 조금 물러나 있는다.
   .42 까지 내렸더니 "너무 투명하다" 가 됐다 — 물러나는 것과 안 보이는 것은
   다르다. 글자색만 흐리게 두고 상자는 또렷하게 남긴다. */
#hold-fab.empty { color: var(--muted); opacity: .85; }
#hold-fab:not(.empty) { color: var(--fg); opacity: 1; }
#hold-fab:hover, #hold-fab:focus-visible { opacity: 1; }
#hold-fab:active { transform: translateY(1px); }
#hold-fab > svg {
  width: 15px; height: 15px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
/* 몇 건인지. 숫자가 없으면 눌러 보기 전에는 알 수 없다. */
#hold-fab > span:empty { display: none; }
#hold-fab > span { font-variant-numeric: tabular-nums; }
