/* 액체 채팅 입력바(ui/liquidChatBar.js) · 음성 오브(ui/fluidOrb.js) · AI 대기 표시(ui/thinkingState.js) — 2026-09-23 오너.
 *   원본 = Bencho CommandBar(MIT) · aicss.dev ThinkingState · FluidOrb. 색·글꼴은 Framer 다크 토큰으로 바꿨다.
 *   이 파일은 호스트별 입력바 규칙(interview.css · project-episodes.css · project-panes.css · components.css)보다 **뒤에** 로드된다.
 *   ⚠️ 실제 바는 투명이다 — 모양은 뒤의 실루엣 판이 그린다. 호스트 규칙이 바에 채움·테두리를 주면 실루엣 위에 두 번째 상자가
 *      겹쳐 목(neck)이 끊겨 보인다. 그래서 바의 채움·테두리·그림자만 !important 로 걷는다(#episodesView 처럼 ID 가 걸린 규칙이 있다). */

.lqc-defs { position: absolute; width: 0; height: 0; overflow: hidden; pointer-events: none; }

/* 이 파일만의 값 — 토큰으로 못 옮기는 둘만 여기 한 번 정의한다.
 *   --lqc-slab: goo 실루엣 판은 불투명이어야 한다(아래 .lqc 주석). framer.css 의 --surface-2 와 같은 #1c1c1c 이지만 크롬 안에서 그 토큰은
 *     liquid-glass 층이 알파로 바꿔 쓰므로 값을 따로 둔다.
 *   --lqc-orb-glow: 오브 그림자 — 액센트 35%. ⚠️ :root 가 아니라 .voice-orb 에 둔다 — 새 셸 --accent 는 body.shell-v2 에 있어
 *     :root 에서 풀면 tokens.css 의 옛 파랑을 잡는다(오브는 body 에 붙어 새 셸 값을 물려받는다). */

.lqc {
  /* 불투명이어야 한다 — goo 의 알파 대비(22a − 11)가 0.5 아래를 지운다. 크롬 안에서 --surface-2 는 알파로 바뀌므로 못 쓴다. */
  --lqc-slab: #1c1c1c;
  --lqc-go: 40px;              /* 전송 버튼 지름 */
  --lqc-go-w: var(--lqc-go);   /* 전송 버튼 폭 — 크레딧 칩이 서면 알약으로 넓어진다(liquidChatBar.syncGoWidth · 2026-10-16) */
  --lqc-gap: 8px;              /* 바와 버튼 사이 */
  --lqc-r: 24px;               /* 바 모서리 */
  --lqc-ease: cubic-bezier(0.22, 1.3, 0.71, 1);   /* 원본 morph 전이 — 살짝 넘쳤다 돌아온다 */
  --lqc-dur: 520ms;
  position: relative; isolation: isolate;
  display: flex; align-items: flex-end; gap: var(--lqc-gap);
  width: 100%; min-width: 0;
}

/* ── 실루엣 층: 여기에만 필터 — 글자는 이 층에 없다 ── */
.lqc-sil {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  display: flex; align-items: flex-end; gap: var(--lqc-gap);
  filter: url(#lqc-goo);
}
.lqc-sil-bar { flex: 1 1 auto; align-self: stretch; min-height: 100%; border-radius: var(--lqc-r); background: var(--lqc-slab); }
.lqc-sil-go, .lqc > .btn.lqc-go {
  flex: none; width: var(--lqc-go-w); height: var(--lqc-go); border-radius: calc(var(--lqc-go) / 2);
  /* 쉴 때: 음수 왼쪽 여백(= 버튼 + 간격)으로 버튼이 차지할 자리를 0 으로 만들어 **바가 끝까지 꽉 찬다**.
   *   포커스·글이 생기면 여백이 0 으로 풀리며 바가 줄어들고, 그 오른쪽 끝에서 버튼이 떨어져 나온다(2026-09-23 오너
   *   *"채팅 인풋이 꽉차있다가 커서를 올리면 줄어들면서 … 전송 버튼이 뜨는 애니메이션"*). 원본은 자리를 비워 두고 버튼만
   *   옮겼다(transform) — 그러면 쉴 때 바 오른쪽에 빈 틈이 남는다. 실루엣 판도 **같은 규칙**이라 두 층이 한 몸으로 움직인다. */
  margin: 0 0 4px calc(-1 * (var(--lqc-go-w) + var(--lqc-gap)));
  transition: margin-left var(--lqc-dur) var(--lqc-ease), background 220ms ease, color 220ms ease, opacity 160ms ease;
}
.lqc-sil-go { background: var(--lqc-slab); }
body.shell-v2 .lqc[data-has='true'] .lqc-sil-go,
body.shell-v2 .lqc[data-has='true'] > .btn.lqc-go.iv-send-btn { margin-left: 0; }

/* ── 실제 바: 투명 — 판은 실루엣이 그린다 ── */
.lqc > .lqc-bar {
  position: relative; z-index: 1;
  flex: 1 1 auto; min-width: 0; max-width: none; margin: 0;
  display: flex; align-items: flex-end; gap: 4px;
  min-height: 48px; padding: 6px 6px 6px 18px;
  border-radius: var(--lqc-r);
  background: transparent !important; border: 0 !important; box-shadow: none !important;
}
/* 특이도: interview.css `body.shell-v2 .iv-root .iv-textarea`(0,3,1) · project-episodes.css `#episodesView .ep-refine-bar .iv-textarea`(1,2,0)
 *   가 여백·줄높이를 덮었다(FCV 2026-09-23 — 두 화면만 1~2px 어긋남). 여섯 입력이 같은 칸이 되도록 여기서만 !important. */
.lqc > .lqc-bar > .iv-textarea {
  padding: 7px 0 !important; line-height: 22px !important;
  flex: 1 1 auto; min-width: 0; align-self: center;
  min-height: 36px; margin: 0;
  background: transparent; border: 0; box-shadow: none; outline: none; resize: none;
  color: var(--ink); line-height: 22px;
}
.lqc > .lqc-bar > .iv-textarea::placeholder { color: var(--ink-48); }

/* ── 전송 버튼: 판과 같은 색으로 나와서, 글이 생기면 흰 알약(주 CTA 문법)으로 켜진다 ──
 *   특이도: interview.css 의 `body.shell-v2 .iv-root .btn.iv-send-btn`(0,4,1)을 이겨야 한다. */
body.shell-v2 .lqc > .btn.lqc-go.iv-send-btn {
  position: relative; z-index: 1; width: var(--lqc-go-w); min-width: var(--lqc-go-w); height: var(--lqc-go); min-height: 0; padding: 0;
  margin: 0 0 4px calc(-1 * (var(--lqc-go-w) + var(--lqc-gap))); /* 실루엣 판과 같은 자리 — 버튼 층 규칙이 margin 을 0 으로 덮는다 */
  border: 0; opacity: 0; pointer-events: none;
  background: var(--lqc-slab); color: var(--ink-80);
}
/* 나올 때 글리프는 판이 바 밖으로 반쯤 나온 뒤에 켠다 — 처음부터 켜면 바 안의 마이크 위에 화살표가 겹쳐 지나간다 */
body.shell-v2 .lqc[data-has='true'] > .btn.lqc-go.iv-send-btn { opacity: 1; pointer-events: auto; transition-delay: 0s, 0s, 0s, 110ms; /* margin-left · background · color · opacity */ }
body.shell-v2 .lqc > .btn.lqc-go.iv-send-btn[data-armed='true']:not(:disabled) { background: var(--ink); color: var(--canvas); }
body.shell-v2 .lqc > .btn.lqc-go.iv-send-btn[data-armed='true']:not(:disabled):hover { background: var(--ink-80); color: var(--canvas); }
body.shell-v2 .lqc > .btn.lqc-go.iv-send-btn:disabled { opacity: 1; background: var(--lqc-slab); color: var(--ink-48); }
body.shell-v2 .lqc[data-has='false'] > .btn.lqc-go.iv-send-btn:disabled { opacity: 0; }
body.shell-v2 .lqc > .btn.lqc-go.iv-send-btn:active:not(:disabled) { transform: scale(0.92); transition: transform 120ms ease; }
body.shell-v2 .lqc > .btn.lqc-go.iv-send-btn:focus-visible { box-shadow: var(--ring-focus); }

/* 전송 버튼 안 크레딧 칩 — [↑ │ ⓒ 17] (2026-10-16). 폭은 --lqc-go-w 가 판과 함께 정한다. */
body.shell-v2 .lqc > .btn.lqc-go.iv-send-btn:has(> .credit-chip:not([hidden])) { padding: 0 13px; gap: 6px; }

/* ── 마이크: 사라질 때 opacity 만 ── */
body.shell-v2 .lqc .btn.lqc-mic {
  position: relative; flex: none; width: 36px; min-width: 36px; height: 36px; padding: 0;
  border-radius: 50%; border: 0; background: transparent; color: var(--ink-48);
  opacity: 0; pointer-events: none; transition: opacity 150ms ease, color 150ms ease;
}
body.shell-v2 .lqc .btn.lqc-mic[data-show='true'] { opacity: 1; pointer-events: auto; }
body.shell-v2 .lqc .btn.lqc-mic:hover { background: transparent; color: var(--ink); }
body.shell-v2 .lqc .btn.lqc-mic:focus-visible { box-shadow: var(--ring-focus); }
/* 녹음 중: 마이크 자리는 멈춤(네모) 글리프 — 큰 오브는 화면 하단 중앙에 따로 뜬다(.voice-orb) */
body.shell-v2 .lqc .btn.lqc-mic.is-on { color: var(--accent); }
/* 터치: 보이는 원은 36px 그대로, 누르는 자리만 44px — 바 모양(goo)과 전송 버튼 자리를 흔들지 않는다. 조상에 overflow:hidden 이 없어 잘리지 않는다. */
@media (max-width: 810px) {
  body.shell-v2 .lqc .btn.lqc-mic::before { content: ''; position: absolute; inset: -4px; border-radius: 50%; }
}

/* ── 음성 입력 오브(ui/voiceOrb.js) — 화면 하단 중앙 · 음성 크기에 반응 ── */
.voice-orb {
  --lqc-orb-glow: color-mix(in srgb, var(--accent) 35%, transparent);
  position: fixed; left: 50%; bottom: 128px; z-index: 900;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  transform: translate(-50%, 12px) scale(0.92); opacity: 0; pointer-events: none;
  transition: opacity 200ms ease, transform 320ms cubic-bezier(0.22, 1.3, 0.71, 1);
}
/* 래퍼는 열려도 클릭을 통과시킨다 — 받는 것은 오브와 [×] 뿐(래퍼가 받으면 밑의 입력바·칩이 안 눌렸다). */
.voice-orb.is-open { opacity: 1; transform: translate(-50%, 0) scale(1); }
.voice-orb.is-open :is(.voice-orb-hit, .voice-orb-cancel) { pointer-events: auto; }
.voice-orb-stage { position: relative; }
/* 취소는 오브 오른쪽 옆 — 절대 위치라 오브는 화면 가운데를 지킨다.
   ⚠️ 위치를 transform 으로 잡지 않는다 — `.btn:hover` 의 scale 이 transform 을 통째로 덮어 단추가 호버 중에 튄다(2026-10-05 · dropCentering.test). */
.voice-orb-cancel.btn { position: absolute; left: calc(100% + 12px); top: 50%; margin-top: -22px; width: 44px; height: 44px; min-width: 44px; padding: 0; border-radius: 50%; justify-content: center; color: var(--ink-80); background: var(--surface-2); border-color: transparent; }
.voice-orb-cancel.btn:hover { color: var(--ink); background: var(--surface-3); }
.voice-orb-hit { display: block; padding: 0; border: 0; border-radius: 50%; background: transparent; cursor: pointer; filter: drop-shadow(0 12px 40px var(--lqc-orb-glow)); }
.voice-orb-hit:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.voice-orb-hit:disabled { cursor: progress; }
.voice-orb-label { min-height: 18px; font-size: var(--fs-fine); line-height: 18px; font-weight: 500; color: var(--ink-80); }
.voice-orb .fluid-orb { background: transparent; }
.voice-orb-progress { font-size: var(--fs-footnote); line-height: 16px; color: var(--ink-48); font-variant-numeric: tabular-nums; }
/* 좁은 화면 — 하단 128px 은 입력바 위 칩 줄(인터뷰 답 칩·회차 보완 칩)과 겹쳤다. 화면 위쪽 1/3 에 띄운다. */
@media (max-width: 810px) { .voice-orb { bottom: auto; top: 28dvh; } }

.fluid-orb { display: block; border-radius: 50%; overflow: hidden; background: var(--accent); }
.fluid-orb > canvas { display: block; width: 100%; height: 100%; }

/* ── 호스트별 자리 ── */
.iv-bottom > .lqc { max-width: 720px; margin-inline: auto; }
.agent-ask > .lqc { flex: none; }

/* ── AI 대기 표시 ── */
.thinking-shimmer {
  display: inline-block;
  font-size: var(--fs-fine); line-height: 18px; font-weight: 500;
  color: transparent; -webkit-text-fill-color: transparent;
  /* 흐린 글자(--ink-48)가 45% 로 옅어졌다 돌아오는 빛 — 옛 하드코딩 회색은 새 셸의 --ink-48 과 같은 값이었다. */
  --shine-dim: color-mix(in srgb, var(--ink-48) 45%, transparent);
  background: linear-gradient(90deg, var(--ink-48) 0%, var(--ink-48) 30%, var(--shine-dim) 45%, var(--shine-dim) 55%, var(--ink-48) 70%, var(--ink-48) 100%);
  background-size: 300% 100%;
  -webkit-background-clip: text; background-clip: text;
  animation: thinking-shine 2.25s cubic-bezier(0.25, 0.1, 0.25, 1) infinite;
}
@keyframes thinking-shine {
  0%, 18% { background-position: 100% 0; }
  82%, 100% { background-position: 0% 0; }
}
.thinking-row { padding: 2px 2px; }
.thinking-done { font-size: var(--fs-fine); line-height: 18px; font-weight: 500; color: var(--ink-48); }

@media (prefers-reduced-motion: reduce) {
  .lqc-sil-go, body.shell-v2 .lqc > .btn.lqc-go.iv-send-btn { transition: opacity 160ms ease, background 220ms ease, color 220ms ease; }
  .thinking-shimmer { animation: none; background-position: 50% 0; }
  .voice-orb { transition: opacity 160ms ease; transform: translate(-50%, 0); }
  .voice-orb.is-open { transform: translate(-50%, 0); }
}
/* 컨셉아트 — 바 왼쪽 끝에 첨부 버튼이 먼저 선다(글자 여백이 아니라 버튼 여백) */
.lqc > .lqc-bar.ca-prompt-bar { padding-left: 6px; }
