/* =============================================================================
   Subto — 자막 편집 도구 화면
   -----------------------------------------------------------------------------
   ★shell.css 를 먼저 불러온 뒤에 이 파일을 불러온다(index.html 의 순서가 계약이다).★
   토큰(:root), 밑바탕, 왼쪽 레일, 작업 표시줄, 계정 배지는 전부 shell.css 에 있다 —
   그것들은 앞으로 만들 다른 도구 문서도 그대로 쓴다. 여기에는 자막 화면만 둔다.
   ※ 클래스, ID 계약은 그대로 유지(app.js/index.html이 참조).
   ========================================================================== */

/* ---- 랜딩(업로드) — 2단: 왼쪽 업로드 / 오른쪽 작업목록. 메인(페이지) 스크롤 없음 ----
   ★높이를 calc(100vh - 48px) 로 재지 않는다.★ 예전에는 헤더 48px 를 빼는 계산이었는데,
   지금은 작업 칸 안에서 표시줄 아래 남는 만큼을 flex 가 준다 — 표시줄이 감춰져도(로그인 전)
   숫자가 어긋나지 않는다. */
#landing { max-width:var(--content-max); width:100%; flex:1; min-height:0; margin:0 auto; padding:24px 20px 20px;
  display:flex; flex-direction:column; overflow:hidden;
  padding-inline:var(--gutter);
}
.landing-grid { flex:1; min-height:0; display:grid; grid-template-columns:1fr 300px; gap:20px; }
.landing-main { min-width:0; overflow:visible; }
@media (max-width:760px) { .landing-grid { grid-template-columns:1fr; } }
#drop { border:1.5px dashed var(--line); border-radius:14px; padding:52px 24px; text-align:center; color:var(--dim);
  background:var(--surface); transition:border-color .15s, background .15s; }
#drop.hot { border-color:var(--ink); background:var(--ink-fill); color:var(--tx); }
#drop b { color:var(--tx); font-size:var(--t-xl); font-weight:600; display:block; margin-bottom:20px; letter-spacing:-.01em; }
#drop #pickBtn { font-size:var(--t-lg); padding:11px 24px; border-radius:8px; }
#drop small { display:block; margin-top:16px; font-size:var(--t-sm); color:var(--dim); }

/* ---- 작업 목록(히스토리) — 오른쪽 사이드바, 날짜별 폴더 ---- */
#history { min-width:0; min-height:0; display:flex; flex-direction:column; }
.hist-head { font-size:var(--t-sm); color:var(--dim); margin-bottom:8px; display:flex; align-items:center; gap:8px; font-weight:600; letter-spacing:.02em; flex:none; }
.hist-search { width:100%; background:var(--bg); border:1px solid var(--line); border-radius:7px; padding:7px 10px;
  color:var(--tx); font:inherit; font-size:var(--t-md); margin-bottom:8px; flex:none; }
.hist-search:focus { outline:none; border-color:var(--ink-soft); }
/* ★테두리 색만으로는 탭으로 온 것을 알기 어렵다.★ 키보드일 때만 링을 더한다. */
.hist-search:focus-visible { outline:2px solid var(--ink); outline-offset:2px; }
.hist-search::placeholder { color:var(--dim); }
.hist-note { color:var(--dim); font-size:var(--t-xs); margin-bottom:8px; }
#histList { overflow-y:auto; flex:1; min-height:0; padding-right:2px; }
/* 시작 화면은 문서 하나가 스크롤된다. 편집 화면의 플레이어/자막 레이아웃은 별도다. */
body:has(#landing:not(.hidden)) { height:auto; min-height:100vh; overflow:auto; }
body:has(#landing:not(.hidden)) > .pane { height:auto; min-height:100vh; overflow:visible; }
body:has(#landing:not(.hidden)) #navRail { position:sticky; top:0; align-self:flex-start; }
body:has(#landing:not(.hidden)) .appbar { position:sticky; top:0; z-index:35; background:var(--bg); }
body:has(#landing:not(.hidden)) #landing { flex:none; overflow:visible; padding-bottom:48px; }
body:has(#landing:not(.hidden)) .landing-grid { flex:none; align-items:start; grid-template-columns:minmax(0,1fr) 280px; gap:28px; }
body:has(#landing:not(.hidden)) #histList { overflow:visible; flex:none; }
@media (max-width:1050px) { body:has(#landing:not(.hidden)) .landing-grid { grid-template-columns:minmax(0,1fr); } }
.hist-empty { color:var(--dim); font-size:var(--t-md); border:1px dashed var(--line); border-radius:10px; padding:28px 16px; text-align:center; line-height:1.7; }
/* 날짜 폴더 */
.hist-day { margin-bottom:2px; }
.hist-day-head { width:100%; display:flex; align-items:center; gap:8px; text-align:left; background:transparent; border:none;
  padding:8px 6px; color:var(--tx-2); font-size:var(--t-md); font-weight:600; border-radius:6px; }
.hist-day-head:hover { color:var(--tx); background:var(--surface); }
/* 펼침 표시 — 계정 배지와 같은 SVG 를 쓴다. 글리프(▸)는 폰트마다 크기가 달라 점처럼 보였다.
   닫힌 상태는 오른쪽(-90°), 열린 상태는 아래(0°)를 가리킨다. */
.hd-caret {
  width: 12px; height: 12px; flex: none; color: var(--tx-2);
  transform: rotate(-90deg); transition: transform .12s, color .12s;
}
.hist-day-head:hover .hd-caret { color: var(--tx); }
.hist-day-head.open .hd-caret { transform: rotate(0deg); }
.hd-label { flex:1; }
.hd-count { color:var(--dim); font-weight:400; font-size:var(--t-xs); background:var(--surface-2); border:1px solid var(--line); border-radius:5px; padding:0 6px; }
.hist-day-body { display:flex; flex-direction:column; gap:6px; padding:2px 0 8px 4px; }

/* ---- 설치(첫 방문 모델 캐시) 배너 ---- */
#setupBanner { display:flex; flex-wrap:wrap; align-items:center; gap:10px 12px; margin-bottom:18px;
  padding:14px 16px; border:1px solid var(--line); border-radius:12px; background:var(--surface); }
#setupBanner .spinner { width:17px; height:17px; }
#setupBanner .setup-txt { display:flex; flex-direction:column; gap:2px; min-width:0; flex:1; }
#setupBanner .setup-txt b { color:var(--tx); font-size:var(--t-lg); font-weight:600; }
#setupBanner .setup-txt small { color:var(--dim); font-size:var(--t-sm); }
#setupBanner .setup-bar { flex:1 1 100%; height:5px; border-radius:5px; background:var(--line); overflow:hidden; }
#setupBanner #setupBarFill { height:100%; width:0; background:var(--ink); transition:width .25s; }
#setupBanner.indet #setupBarFill { width:35%; animation:setupIndet 1.1s ease-in-out infinite; }
@keyframes setupIndet { 0% { margin-left:-35%; } 100% { margin-left:100%; } }

/* ---- 작업 화면(2단) ---- */
#stage { display:grid; grid-template-columns:minmax(320px,1fr) minmax(380px,1.15fr);
  flex:1; min-height:0; }
.left { border-right:1px solid var(--line); overflow:auto; padding:16px;
  padding-inline:var(--gutter);
}
.right { display:flex; flex-direction:column; overflow:hidden; min-width:0; }
video { width:100%; background:#000; border-radius:10px; max-height:42vh; display:block; }
#attachVideoBtn { width:100%; margin-top:8px; }

/* 진행 단계 */
.steps { margin-top:16px; display:flex; flex-direction:column; gap:6px; }
.st { padding:8px 12px; border:1px solid var(--line-soft); border-radius:8px; color:var(--dim); font-size:var(--t-md);
  display:flex; align-items:center; gap:9px; }
.st.active { border-color:var(--ink); color:var(--tx); }
/* 완료는 초록이 아니라 조용함이다 — 색을 빼고 글자만 한 단계 밝힌다(--ok = ink-2). */
.st.done { color:var(--ok); border-color:var(--line); }
.st .dot { width:7px; height:7px; border-radius:50%; background:var(--line); flex:none; }
.st.active .dot { background:var(--ink); }
.st.done .dot { background:var(--ok); }
.barWrap { height:5px; background:var(--surface-2); border-radius:5px; margin:14px 0 5px; overflow:hidden; }
.bar { height:100%; width:0; background:var(--ink); transition:width .2s; }
.barLabel { color:var(--tx-2); font-size:var(--t-sm); }
.eta { color:var(--dim); font-size:var(--t-sm); margin-top:3px; letter-spacing:.2px; }
.meta { color:var(--dim); font-size:var(--t-sm); margin-top:12px; }
/* 파이프라인 실패 고지 — 항상 렌더하고 가시성만 토글(자리 예약, 등장 시 레이아웃 안 튐) */
.pipe-notice { color:var(--flag); font-size:var(--t-sm); line-height:1.6; margin-top:8px; min-height:19px; }
.pipe-notice.invisible { visibility:hidden; }

/* ---- 자막 목록 ---- */
.toolbar { padding:9px 14px; border-bottom:1px solid var(--line); display:flex; align-items:center; gap:8px;
  font-size:var(--t-sm); color:var(--dim); flex-wrap:wrap; }
.badge { background:var(--surface-2); border:1px solid var(--line); border-radius:6px; padding:1px 7px; font-size:var(--t-xs); color:var(--tx-2); }
.toolbar .hint { color:var(--dim); font-size:var(--t-sm); }

.cues { overflow:auto; flex:1; padding:4px 0; }
.cue { display:grid; grid-template-columns:64px 1fr auto; gap:10px; padding:6px 14px 6px 12px;
  border-bottom:1px solid var(--line-soft); border-left:2px solid transparent; cursor:pointer; }
.cue:hover { background:var(--surface); }
/* 지금 재생 중인 줄 — 왼쪽 선을 강조색으로 세운다(흰 선은 남색 위에서 자막 글자와 헷갈린다). */
.cue.active { background:var(--surface-3); border-left-color:var(--ink); }
.cue.active .txt { color:var(--tx); font-weight:600; }
.cue.active .tc { color:var(--tx-2); }
.tc { color:var(--dim); font:11px/1.7 ui-monospace,"SF Mono",Menlo,monospace; font-variant-numeric:tabular-nums; }
.cue .txt { border-radius:5px; padding:2px 5px; min-height:20px; color:var(--tx); }
.cue.edited .txt { color:var(--flag); }
.cue .txt:focus { background:var(--bg); box-shadow:0 0 0 1px var(--ink-soft); }
/* STT 가 놓친 구간에 끼워 넣은 빈 자막 — 비어 있으면 '없는 것'이 목록에서 안 보이므로 안내를 띄운다.
   :empty 만으로는 부족하다(공백 한 칸이 들어가면 해제된다) — 그래서 JS 가 data-empty 를 관리한다. */
.cue .txt[data-empty="1"]::before { content:'(전사 안 됨 — 들어보고 채워주세요)'; color:var(--ink-soft); font-style:italic; }
.cue .txt[data-empty="1"]:focus::before { content:''; }

/* 확인 필요 / 나락 = 이모지 없이 작은 태그(tint 배경 + 색 글자) */
.cue.flagged { background:var(--cue-flag); }
.cue.flagged:hover { background:var(--flag-fill); }
.cue .flag { display:inline-block; padding:0 6px; border-radius:4px;
  background:var(--flag-fill); color:var(--flag); font-size:var(--t-xs); font-weight:600; letter-spacing:.02em; cursor:help; }

/* ── 딱지 줄 ──
   시각 칸(64px)에 같이 두었더니 「반드시 확인」이 「반 / 드시 확인」으로 쪼개졌다.
   자막 쪽 폭을 그대로 쓰는 줄로 내리고, 딱지 하나는 절대 안 쪼개지게 nowrap 을 건다.
   여러 개면 줄바꿈은 딱지 사이에서만 일어난다. */
.cue .cbody { min-width:0; }
.cue .marks { display:flex; flex-wrap:wrap; align-items:center; gap:5px; margin:0 0 3px 5px; }
.cue .marks > * { white-space:nowrap; margin-left:0; }
/* 컷 격자가 뺀 맞장구를 되살리는 칩 — 누르면 자막 앞에 붙는다. 알림(cursor:help)이 아니라
   실제로 누르는 것이라 pointer 로 두고 hover 를 준다. */
.cue .undrop { display:inline-block; margin-left:6px; padding:0 6px; border-radius:4px;
  background:var(--noun-fill); color:var(--noun-tx); font-size:var(--t-xs); font-weight:600; cursor:pointer; user-select:none; }
.cue .undrop:hover { background:var(--noun-line); color:var(--tx); }
.cue.risk { background:var(--cue-risk); }
.cue.risk:hover { background:var(--risk-fill); }
.risk-tag { display:inline-block; margin-left:6px; padding:0 6px; border-radius:4px;
  background:var(--risk-fill); color:var(--risk); font-size:var(--t-xs); font-weight:600; letter-spacing:.02em; cursor:help; }

/* 필터 토글 */
#flagOnly.active { color:var(--flag); border-color:var(--flag-line); background:var(--flag-fill); }
#riskOnly.active { color:var(--risk); border-color:var(--risk-line); background:var(--risk-fill); }
/* ── 고유명사 ──
   확인 필요(노랑), 나락(빨강), 강조(네온) 어디와도 안 겹치는 보라 계열(원어썸 info).
   예전엔 옅은 파랑이었는데 남색 바탕 위에서는 바탕에 묻혀 딱지로 안 읽힌다.
   위 관문(.nounGate)과 자막 딱지가 같은 색이라 「저 위 목록의 그것」임이 색으로 이어진다. */
.cue.noun { background:var(--cue-noun); }
.cue.noun:hover { background:var(--noun-fill); }
.noun-tag { display:inline-block; padding:0 6px; border-radius:4px;
  background:var(--noun-fill); color:var(--noun-tx); font-size:var(--t-xs); font-weight:600;
  letter-spacing:.02em; cursor:pointer; user-select:none; }
.noun-tag:hover { background:var(--noun-line); color:var(--tx); }
#nounOnly.active { color:var(--noun-tx); border-color:var(--noun-line); background:var(--noun-fill); }
/* 딱지를 눌러 관문으로 왔을 때 어느 줄인지 — 목록이 길면 스크롤만으로는 못 찾는다. */

.cues.only-flagged .cue:not(.flagged) { display:none; }
/* 「반드시 확인」과 확인 안 한 고유명사가 든 자막만 남긴다 — 둘 다 봐야 넘어가는 것이다. */
.cues.only-noun .cue:not(.noun):not(.must) { display:none; }
.cues.only-risk .cue:not(.risk) { display:none; }

/* ---- 모달 ---- */
.overlay { position:fixed; inset:0; background:var(--veil); backdrop-filter:blur(2px);
  z-index:25; display:flex; align-items:center; justify-content:center; padding:16px; }
.modal { position:relative; background:var(--surface); border:1px solid var(--line); border-radius:14px;
  width:min(460px,94vw); max-height:86vh; overflow:auto; padding:22px; box-shadow:var(--shadow-3); }
/* 모달 오른쪽 위 닫기 — 제목과 겹치지 않게 h2 의 오른쪽 여백을 함께 비운다. */
.mclose { position:absolute; top:10px; right:10px; width:30px; height:30px; padding:0; line-height:1;
  display:flex; align-items:center; justify-content:center; font-size:19px; border-radius:8px;
  background:transparent; border:1px solid transparent; color:var(--dim); }
.mclose:hover { background:var(--bg); border-color:var(--line); color:var(--tx); }
.modal:has(.mclose) h2 { padding-right:34px; }
.modal h2 { margin:0 0 6px; font-size:var(--t-xl); font-weight:700; letter-spacing:-.01em; }
.mnote { color:var(--dim); font-size:var(--t-md); margin:6px 0 14px; line-height:1.6; }
.modal input, .modal textarea { width:100%; background:var(--bg); border:1px solid var(--line); border-radius:8px;
  padding:10px 12px; color:var(--tx); font:inherit; font-size:var(--t-md); margin-bottom:10px; }
.modal input:focus, .modal textarea:focus { outline:none; border-color:var(--ink-soft); }
.modal input:focus-visible, .modal textarea:focus-visible { outline:2px solid var(--ink); outline-offset:2px; }
.modal textarea { min-height:104px; }
.mfoot { display:flex; gap:10px; justify-content:flex-end; align-items:center; }
.msg { color:var(--flag); font-size:var(--t-sm); min-height:15px; }
.msg.ok { color:var(--ok); }
.glabel { display:block; font-size:var(--t-sm); color:var(--dim); margin:4px 0 6px; }

/* 커스텀 드롭다운(채널 선택) — 항상 아래로 */
.dropdown { position:relative; margin-bottom:12px; }
.dropbtn { width:100%; text-align:left; background:var(--bg); border:1px solid var(--line); border-radius:8px;
  padding:10px 12px; color:var(--tx); font-size:var(--t-md); display:flex; align-items:center; justify-content:space-between; gap:8px; }
.dropbtn:hover { border-color:var(--line-strong); }
/* 드롭다운 펼침 표시 — 계정 배지, 작업 목록과 같은 SVG 로 통일한다. */
.dropbtn .caret { width:12px; height:12px; flex:none; color:var(--tx-2); transition:transform .12s, color .12s; }
.dropbtn:hover .caret { color:var(--tx); }
/* 열림 판정은 메뉴의 .hidden 으로 한다 — 이 드롭다운은 컨테이너에 .open 을 달지 않는다. */
.dropdown:has(.dropmenu:not(.hidden)) .dropbtn .caret { transform:rotate(180deg); color:var(--tx); }
.dropmenu { position:absolute; top:calc(100% + 4px); left:0; right:0; background:var(--surface); border:1px solid var(--line);
  border-radius:8px; max-height:240px; overflow:auto; z-index:30; box-shadow:var(--shadow-2); padding:4px; }
.dropmenu .dgroup { color:var(--dim); font-size:var(--t-xs); padding:7px 8px 3px; }
/* 채널 검색 — 목록이 최대 74개라 훑어 고를 수 없다. 스크롤해도 검색칸은 붙어 있어야 한다. */
.dropmenu .dsearch { position:sticky; top:-4px; background:var(--surface); padding:4px 2px 6px; margin:-4px -2px 0; z-index:1; }
.dropmenu .dsearch input { width:100%; box-sizing:border-box; padding:7px 9px; font-size:var(--t-md); color:var(--tx);
  background:var(--surface-2); border:1px solid var(--line); border-radius:6px; }
.dropmenu .dsearch input:focus { border-color:var(--ink-soft); }
.dropmenu .ditem { padding:8px 10px; border-radius:6px; cursor:pointer; font-size:var(--t-md); color:var(--tx-2); }
.dropmenu .ditem:hover { background:var(--surface-2); color:var(--tx); }
.dropmenu .ditem.sel { color:var(--ink-soft); }

/* ---- 사용법(가이드) ---- */
.guide { font-size:var(--t-md); line-height:1.7; color:var(--tx-2); }
.guide h3 { font-size:var(--t-md); margin:15px 0 6px; color:var(--tx); font-weight:600; }
.guide ol, .guide ul { margin:0; padding-left:20px; }
.guide li { margin:0 0 5px; }
.guide b { color:var(--tx); font-weight:600; }

/* ---- 진행 스피너 ---- */
.spinner { display:inline-block; width:13px; height:13px; vertical-align:-2px; margin-right:2px;
  border:2px solid var(--line); border-top-color:var(--ink-soft); border-radius:50%; animation:spin .7s linear infinite; }
@keyframes spin { to { transform:rotate(360deg); } }

/* 오디오 파형 */
#wave { width:100%; height:84px; display:block; border-radius:8px; margin-top:8px; background:var(--surface); border:1px solid var(--line); cursor:crosshair; }
/* 자막 품질(QA) 뱃지 */

/* 오픈소스 라이선스 고지 — 작고 눈에 띄지 않게(가이드 하단) */
.oss-credit { margin:14px 2px 0; font-size:var(--t-xs); line-height:1.5; color:var(--dim); opacity:.55; }

/* ── 영상 위 자막 오버레이 ──
   자막은 목록이 아니라 화면에서 판단해야 한다(줄 길이, 겹침, 사라지는 타이밍).
   실제 방송 자막과 비슷하게 보이도록 하단 중앙, 외곽선으로 배경 대비를 준다.
   ★여기만 앱 팔레트를 안 따른다.★ 이 글자가 놓이는 바탕은 우리 화면이 아니라 남의 영상이라
   어떤 색이 뒤에 올지 모른다. 검은 외곽선 위 흰 글자는 그 조건에서 정해진 답이다. */
.videoWrap { position: relative; display: block; line-height: 0; container-type: inline-size; }
.videoWrap > video { width: 100%; min-height: 200px; display: block; object-fit: contain; }
.subOverlay {
  position: absolute;
  /* 두 줄로 표시되는 네이티브 재생 컨트롤 위에 여유를 둔다. */
  inset: 8px 5% 88px;
  display: flex; justify-content: center; align-items: flex-end;
  pointer-events: none;          /* 영상 클릭, 스크럽을 막지 않는다 */
  line-height: 1.3;
}
.subOverlay span {
  display: inline-block;
  flex: 0 1 auto; min-width: 0;
  max-width: min(100%, 32ch);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: keep-all;
  text-wrap-style: balance;
  text-align: center;
  /* 브라우저 창 대신 실제 플레이어 폭에 맞춘다. */
  font-size: clamp(12px, 3.5cqw, 20px);
  font-weight: 700;
  color: #fff;
  /* 어떤 배경에서도 읽히도록 외곽선 + 그림자. text-stroke 미지원 브라우저는 그림자만으로도 읽힌다. */
  -webkit-text-stroke: 3px rgba(0, 0, 0, .85);
  paint-order: stroke fill;
  text-shadow: 0 2px 6px rgba(0, 0, 0, .6);
}
.subOverlay.off { display: none; }
/* 확인 필요(flag)나 나락 위험 자막은 오버레이에서도 즉시 눈에 띄게 — 검수 중 놓치지 않도록. */
.subOverlay span.flagged { color: #ffd479; }
.subOverlay span.risk { color: #ff9b9b; }
.ovToggle { display: block; margin: 6px 0 0; font-size:var(--t-sm); color: var(--tx-2); cursor: pointer; }
.ovToggle input { vertical-align: middle; margin-right: 4px; }

/* ── 영상 정보 패널 (랜딩, 「반 필수」) ──
   예전엔 헤더 모달 안에만 있어서 사실상 숨은 기능이었다. 랜딩의 남는 세로 공간에 꺼내 두되,
   드롭존을 밀어내지 않도록 접힘 상태를 기본으로 쓴다(비어 있으면 펼친 채로 시작한다 — app.js).
   색과 반경은 .cutPick 과 같은 계열로 맞춘다. 새 디자인 언어를 들이지 않는다. */
.metaPanel {
  margin-top: 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px 16px;
  background: var(--panel-tint);
  text-align: left;
}
/* 아직 아무것도 안 채운 상태는 테두리로 드러낸다 — '있는 줄 몰랐다'가 이 기능의 실패 원인이었다. */
.metaPanel.empty { border-color: var(--flag-line); background: var(--cue-flag); }
/* 양식 txt 를 끌어다 놓는 중 — 드롭존과 같은 신호를 쓴다(여기도 받는다는 걸 알려야 한다). */
.metaPanel.hot { border-color: var(--ink); background: var(--ink-fill); }
.meta-head { display: flex; align-items: center; gap: 10px; }
.meta-toggle {
  display: flex; align-items: center; gap: 8px;
  background: transparent; border: none; padding: 0; border-radius: 6px;
}
.meta-toggle:hover { background: transparent; border-color: transparent; }
.meta-toggle .hd-caret { transform: rotate(-90deg); transition: transform .12s; }
.meta-toggle[aria-expanded="true"] .hd-caret { transform: rotate(0deg); }
.meta-title { color: var(--tx); font-size:var(--t-lg); font-weight: 600; letter-spacing: -.01em; }
.metaPanel.empty #metaCount { color: var(--flag); border-color: var(--flag-line); background: var(--flag-fill); }
.meta-summary { color: var(--dim); font-size:var(--t-sm); text-align: right; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.meta-why { margin: 8px 0 0; font-size:var(--t-md); line-height: 1.6; color: var(--dim); }
.meta-why b { color: var(--tx-2); font-weight: 600; }
.metaPanel.collapsed .meta-why, .metaPanel.collapsed .meta-body { display: none; }
.meta-body { margin-top: 12px; }
.meta-hint { color: var(--dim); font-weight: 400; }
/* 두 칸 배치 — 필드가 6개라 한 줄씩 쌓으면 드롭존이 화면 밖으로 밀린다. */
.meta-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
.meta-cell { min-width: 0; }
.meta-cell.full { grid-column: 1 / -1; }
/* 말하는 사람 — 출연자와 같은 칸에 둔다(「출연자 다음에 인원」이 읽는 순서다). */
.spk-label { display: block; margin-top: 8px; }
.spk-pick { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; min-height: 34px; }
/* ★white-space: nowrap 과 flex: none 이 둘 다 필요하다.★ 없으면 flex 안에서 라벨이
   줄어들어 「한 명」이 「한 / 명」으로, 「여러 명」이 글자마다 세로로 접혔다(실측). */
.spk-opt { display: inline-flex; align-items: center; gap: 6px; flex: none; white-space: nowrap;
  font-size:var(--t-md); color: var(--tx-2); cursor: pointer; }
.spk-opt input { accent-color: var(--ink); cursor: pointer; }
.spk-opt:has(input:checked) { color: var(--tx); }
/* ★#metaFields input 이 ID 선택자라 클래스 하나로는 못 이긴다.★ 실측에서 이 칸이
   24px 로 찌그러졌다 — 같은 ID 특이도로 맞춰 준다. */
/* ★flex: none 이 필요하다.★ .spk-pick 이 flex 라 기본 flex-shrink 로 칸이 줄어든다 —
   width 를 88px 로 줘도 실제로 58px 로 찌그러졌다(실측). */
#metaFields .spk-pick .spk-input { width: 88px; flex: none; margin: 0; }
.spk-pick .spk-input[hidden] { display: none; }
/* 인식 결과가 기대와 다를 때만 뜨는 딱지. 확인 필요(노랑)와 같은 결이지만 자막 하나가
   아니라 ★영상 전체★에 대한 말이라 작업 표시줄에 둔다.
   ★max-width 를 건다★ — 안 걸면 문장이 길어 표시줄이 가로로 밀리고 페이지에 가로
   스크롤이 생겼다(실측 352px). 넘치면 말줄임하고 전문은 title 로 보여준다. */
.spk-warn { display: inline-flex; align-items: center; padding: 2px 9px;
  border-radius: 999px; font-size:var(--t-sm); line-height: 1.7;
  max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--flag); background: var(--flag-fill); border: 1px solid var(--flag-line); }
/* 랜딩(모달 밖)에도 같은 입력칸 모양이 필요하다 — .modal input/textarea 규칙에 기대지 않고
   ID 선택자로 두 곳 모두에 같은 스타일을 건다(같은 노드가 오가므로 모양이 변하면 안 된다). */
#metaFields input, #metaFields textarea {
  width: 100%; background: var(--bg); border: 1px solid var(--line); border-radius: 8px;
  padding: 9px 11px; color: var(--tx); font: inherit; font-size:var(--t-md); margin-bottom: 10px;
}
/* ★60px → 132px.★ 60px 는 세 줄이라 출연자·용어처럼 목록이 들어가는 칸이 곧장 스크롤이
   됐다(성진님: 「높이가 너무 낮아」 2026-09-09). 리사이즈 손잡이를 앱 전체에서 뗀 뒤라
   사용자가 직접 늘릴 길도 없으니 기본값이 넉넉해야 한다. 같은 줄에 나란히 놓이는 두 칸
   (출연자|주제, 용어|기획 의도)은 높이가 같아야 줄이 안 흔들려 넷을 같은 값으로 둔다. */
#metaFields textarea { min-height:76px; overflow:hidden; resize:none; line-height:1.7; }
#metaFields textarea[hidden] { display:none; }
.meta-section { padding:20px 0; border-bottom:1px solid var(--line); }
.meta-section h3 { margin:0 0 12px; font-size:var(--t-md); color:var(--tx); font-weight:600; }
.meta-section > .meta-hint { margin:0 0 12px; font-size:var(--t-sm); }
.meta-library { border-bottom:1px solid var(--line); padding:18px 0; }
#metaLibrary > summary { display:grid; grid-template-columns:16px minmax(0,1fr) auto; gap:10px; align-items:center;
  min-height:48px; padding:11px 12px; border:1px solid var(--line); border-radius:8px;
  background:var(--surface-2); color:var(--tx); cursor:pointer; list-style:none;
  font-size:var(--t-lg); font-weight:600; line-height:1.5;
  transition:background .12s, border-color .12s; }
#metaLibrary > summary::-webkit-details-marker { display:none; }
#metaLibrary > summary:hover { background:var(--surface-3); border-color:var(--line-strong); }
#metaLibrary > summary:focus-visible { outline:2px solid var(--ink); outline-offset:2px; }
#metaLibrary[open] > summary { border-color:var(--ink-line); background:var(--ink-fill); }
#metaLibrary[open] > summary:hover { border-color:var(--ink); }
#metaLibrary .meta-library-caret { display:block; width:16px; height:16px; color:var(--tx-2);
  transform:rotate(-90deg); transition:transform .12s; }
#metaLibrary[open] .meta-library-caret { transform:rotate(0deg); }
#metaLibrary .meta-library-title { min-width:0; }
#metaLibraryCount { justify-self:end; font-variant-numeric:tabular-nums; }
#metaLibrary > .meta-grid { margin-top:16px; }
.meta-library .meta-hint { font-size:var(--t-sm); line-height:1.6; }
#metaFields .badge, #metaCount { display:inline-flex; gap:4px; align-items:center; border:1px solid var(--line); border-radius:999px; padding:3px 8px; font-size:11px; line-height:1.3; font-weight:500; background:var(--surface-2); color:var(--tx-2); white-space:nowrap; }
#metaFields .meta-grid { gap:12px 20px; }
#metaFields .glabel { display:block; color:var(--tx-2); margin:0 0 8px; }
.tag-editor { min-width:0; }
.tag-editor-head { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:8px; color:var(--dim); font-size:var(--t-sm); }
.tag-editor-head:empty { display:none; }
.tag-entry { display:flex; align-items:stretch; gap:8px; }
#metaFields .tag-entry input { flex:1; min-width:0; width:0; min-height:44px; margin:0; }
.tag-entry .tag-add { flex:none; width:44px; min-height:44px; padding:0; border:1px solid var(--line-strong); border-radius:8px; background:var(--surface-2); color:var(--tx); font-size:22px; line-height:1; }
.tag-entry .tag-add:hover:not(:disabled) { border-color:var(--ink); background:var(--ink-fill); }
.tag-list { display:flex; flex-wrap:wrap; align-items:flex-start; gap:6px; min-width:0; margin-top:12px; padding-top:12px; border-top:1px solid var(--line); }
.tag-list:empty { display:none; }
.tag-item { display:inline-flex; align-items:center; gap:4px; max-width:100%; min-height:28px; padding:2px 3px 2px 9px; box-sizing:border-box; border:1px solid var(--line); border-radius:6px; background:var(--surface-2); color:var(--tx); font-size:var(--t-sm); line-height:1.5; }
.tag-text { min-width:0; overflow-wrap:anywhere; }
.tag-item .tag-remove { display:inline-flex; align-items:center; justify-content:center; flex:none; width:24px; min-height:24px; height:24px; padding:0; border:0; border-radius:4px; background:transparent; color:var(--dim); font-size:18px; line-height:1; }
.tag-item .tag-remove:hover { background:var(--surface); color:var(--tx); }
.tag-expand { min-height:32px; margin-top:10px; padding:5px 10px; border:1px solid var(--line); border-radius:6px; background:transparent; color:var(--tx-2); font-size:var(--t-sm); }
.tag-expand:hover { border-color:var(--line-strong); color:var(--tx); }
#metaFields .tag-search { min-width:0; min-height:40px; margin:12px 0 0; }
.tag-editor [hidden], #metaFields .tag-search[hidden] { display:none; }
.tag-status { margin:8px 0 0; color:var(--dim); font-size:var(--t-sm); line-height:1.5; overflow-wrap:anywhere; }
.tag-status:empty { display:none; }
.tag-status.err { color:var(--flag); }
.rule-head, .rule-row { display:grid; grid-template-columns:minmax(0,1fr) 24px minmax(0,1fr) 32px; align-items:center; gap:8px; }
.rule-head { margin-bottom:8px; color:var(--dim); font-size:var(--t-sm); }
.rule-row { margin-bottom:8px; }
#metaFields .rule-row input { margin:0; min-width:0; min-height:40px; }
.rule-arrow { text-align:center; color:var(--dim); }
.rule-remove { width:32px; height:32px; padding:0; border:0; background:transparent; font-size:20px; color:var(--dim); }
.rule-remove:hover { color:var(--flag); background:var(--flag-fill); }
.rule-add { margin:4px 0 14px; background:transparent; min-height:36px; }
#metaFields input[aria-invalid="true"] { border-color:var(--flag); }
/* 표기 규칙만 3줄을 담는다 — 자리표시가 세 줄인데 칸이 60px(두 줄 반)이라 처음 열자마자 칸 안에
   제 스크롤바가 생겼다. 바깥 칸도 스크롤 중이라 스크롤바가 겹쳐 보인다.
   ⚠️ `#metaRules` 만 쓰면 안 된다 — 바로 위 `#metaFields textarea` 가 명시도(0,1,0,1)로 이긴다. */
#metaFields textarea#metaRules { min-height: 132px; }
#metaFields input:focus, #metaFields textarea:focus { outline: none; border-color: var(--ink-soft); }
#metaFields input:focus-visible, #metaFields textarea:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
#metaFields input::placeholder, #metaFields textarea::placeholder { color: var(--dim); }
/* 입력을 요청받은 칸(확인 단계에서 「입력하러 가기」)은 어디를 채워야 하는지 바로 보이게. */
#metaFields textarea.nudge, #metaFields input.nudge { border-color: var(--flag); }
.meta-rules-info { margin: -4px 0 10px; font-size:var(--t-sm); line-height: 1.5; color: var(--dim); }
.meta-rules-info.err { color: var(--flag); }
.meta-rules-info:empty { display: none; }
.meta-more { margin: 2px 0 10px; }
.meta-more summary { font-size:var(--t-sm); color: var(--dim); cursor: pointer; padding: 4px 0; }
.meta-more summary:hover { color: var(--tx-2); }
/* 동작 줄 — 좁아지면 줄바꿈시키되 두 줄이 서로 붙지 않게 row-gap 을 따로 준다.
   gap 을 14px 로 벌린 것은 '서로 다른 일'끼리의 거리다. 같은 일끼리는 .btn-group 이 6px 로 붙인다. */
.meta-actions, .meta-foot { display: flex; gap: 14px; row-gap: 10px; align-items: center; flex-wrap: wrap; }
/* 입력칸 무더기와 동작 줄 사이에 경계를 준다 — 이게 없으면 마지막 입력칸에 딸린 버튼처럼 보인다. */
.meta-actions { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.meta-foot { margin-top: 12px; }
.meta-actions button, .meta-foot button { flex: none; }
/* 한 쌍으로 읽혀야 하는 버튼 묶음(내려받기 ↔ 불러오기). */
.btn-group { display: inline-flex; gap: 6px; align-items: center; }
/* 모달 바닥(닫기 / 저장하고 닫기)이 위 동작 줄에 딱 붙어 두 줄이 한 덩어리로 보였다. */
#glossSlot + .mfoot { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
/* 모달 안에서는 폭이 460px 라 두 칸이 안 들어간다 — 같은 노드지만 한 칸으로 떨어뜨린다. */
#glossSlot .meta-grid { grid-template-columns: 1fr; }
@media (max-width: 760px) { .meta-grid { grid-template-columns: 1fr; } }

/* 「반 필수」 확인 단계 — 근거를 공허한 문구가 아니라 구체적 손해로 적는다. */
.gate-why { margin: 0 0 14px; padding-left: 18px; font-size:var(--t-md); line-height: 1.7; color: var(--tx-2); }
.gate-why li { margin-bottom: 6px; }
.gate-why b { color: var(--tx); font-weight: 600; }
.gate-file { margin: 0 0 14px; font-size:var(--t-sm); color: var(--dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gate-file b { color: var(--tx-2); font-weight: 600; }

/* 로그인 전 — 작업 영역은 app.js 가 .hidden 으로 막고, 도구 단추는 여기서 숨긴다.
   ★레일은 감추지 않는다.★ 레일이 이 사이트의 유일한 지도라서, 로그인 창만 덜렁 뜨면
   여기가 어디인지 알 수 없다. 막는 자리는 각 도구의 작업 영역이지 지도가 아니다.
   ★우회 가능한 UX 게이트다.★ 실제 차단은 서버가 세션 없는 요청을 401 로 거절해서 한다. */
body.logged-out .hgroup, body.logged-out #modelStat { display: none; }

/* ── 편집 컷 선택 (드롭존 아래 별도 블록) ──
   주 동작(파일 선택)과 한 상자에 넣었더니 필수 입력처럼 보이고 글이 뭉쳤다.
   카드로 분리하고 제목/설명/동작을 각각 다른 줄, 다른 크기로 둔다. */
.cutPick {
  margin-top: 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px 16px;
  background: var(--panel-tint);
  text-align: left;
}
.cutPick-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.cutPick-title { color: var(--tx); font-size:var(--t-lg); font-weight: 600; letter-spacing: -.01em; }
/* '선택' 배지 — 필수가 아님을 한눈에 */
.cutPick-title .opt {
  margin-left: 6px; padding: 2px 7px; border-radius: 999px;
  border: 1px solid var(--line); background: transparent;
  font-size:var(--t-xs); font-weight: 600; color: var(--dim); letter-spacing: 0;
}
.cutPick-desc { margin: 8px 0 0; font-size:var(--t-md); line-height: 1.6; color: var(--dim); }
.cutPick-desc code {
  padding: 1px 5px; border-radius: 4px;
  background: var(--chip); color: var(--tx-2);
  font-size:var(--t-sm);
}
.cutPick .ghost { flex: none; font-size:var(--t-md); padding: 7px 14px; border-radius: 8px; }
/* 결과 줄 — 비어 있을 때 자리를 차지하지 않게 */
.cutInfo { margin: 0; font-size:var(--t-md); line-height: 1.5; color: var(--tx-2); }
.cutInfo:empty { display: none; }
.cutInfo:not(:empty) { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.cutInfo.err { color: var(--risk); }

/* ── 로그인 화면 ──
   앱 전체를 막는 게이트라 '어디에 왔는지'와 '무엇을 눌러야 하는지'가 한눈에 보여야 한다. */
.loginCard { max-width: 380px; text-align: center; padding: 32px 28px 24px; }
/* 로고와 글자를 한 줄에 — 레일 브랜드와 같은 짝이다(로그인 전에도 레일이 보여서 둘이 나란히 읽힌다). */
.loginBrand {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size:var(--t-md); font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-soft); margin-bottom: 18px;
}
.loginMark { width: 20px; height: 20px; object-fit: contain; flex: none; }
.loginCard h2 { font-size: 19px; margin-bottom: 8px; }
.loginCard .mnote { margin-bottom: 26px; }

/* 구글 버튼 — 브랜드 가이드대로 흰 배경에 컬러 마크. 우리 primary 파랑과 섞지 않는다. */
.googleBtn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; padding: 12px 16px;
  background: #fff; color: #1f1f1f; border: 1px solid #dadce0; border-radius: 9px;
  font-size:var(--t-lg); font-weight: 600; letter-spacing: -.01em;
  transition: background .15s, box-shadow .15s;
}
.googleBtn:hover { background: #f7f8f8; border-color: #dadce0; color: #1f1f1f; box-shadow: 0 1px 3px rgba(0,0,0,.28); }
.googleBtn:active { background: #eef0f1; }
.googleBtn:disabled { opacity: .6; }
.gmark { width: 18px; height: 18px; flex: none; }
/* 진행 표시가 들어가면 흰 배경 위라 기본 스피너 색이 안 보인다 */
.googleBtn .spinner { border-color: rgba(0,0,0,.25); border-top-color: #1f1f1f; }

.loginMsg { min-height: 18px; margin: 14px 0 0; }
.loginMsg:not(:empty) { color: var(--risk); }
.loginHint { margin: 16px 0 0; font-size:var(--t-sm); color: var(--dim); }


/* 언어 선택(말하는 언어 → 자막 언어). 둘이 다르면 번역이 걸린다. */
.lang-row { display:flex; align-items:center; gap:8px; margin:14px 0 0; }
/* 채널 선택과 같은 드롭다운 컴포넌트를 쓴다 — 첫 화면에 두 가지 선택 UI 가 섞이면 안 된다. */
.lang-row .dropdown { flex:1 1 0; min-width:0; margin-bottom:0; }
/* 안은 글자가 아니라 그림이다(index.html 주석). 두 자리 모두 같은 크기로 선다. */
.lang-arrow, .gate-arrow { color:var(--dim); flex:none; display:flex; align-items:center; }
.lang-arrow svg, .gate-arrow svg { width:14px; height:14px; }
.lang-note { margin:6px 0 0; font-size:var(--t-sm); color:var(--dim); }
/* 번역이 걸리는 상태를 눈에 보이게 — 기본값(한국어→한국어)과 구별되어야 한다. */
.lang-row.on .dropbtn { border-color:var(--ink-soft); }
.lang-note.on { color:var(--ink-soft); }

/* 헤더 안 드롭다운 — 랜딩의 전폭 드롭다운과 달리 내용 폭이고 메뉴가 오른쪽에 붙는다. */
.hdrop { margin-bottom:0; }
.hdrop .dropbtn { width:auto; padding:6px 10px; font-size:var(--t-md); gap:6px; }
.hdrop .dropmenu { left:auto; right:0; min-width:190px; }

/* ---- 시작 전 확인 창의 카테고리 선택(필수) ---- */
/* 카테고리는 못 고르면 시작이 막히는 값이라, 다른 안내문과 같은 무게로 두면 안 된다. */
.gate-ch { display:flex; align-items:center; gap:10px; margin:14px 0 6px; }
.gate-ch label { font-size:var(--t-md); color:var(--tx); font-weight:600; white-space:nowrap; }
.gate-ch .req { color:var(--risk); font-size:var(--t-xs); font-weight:700; margin-left:2px; }
/* 말하는 사람 - 카테고리 칸과 ★같은 결★로 맞춘다(필수 항목이 둘인데 모양이 다르면 안 된다). */
.gate-spk { display:flex; align-items:center; gap:10px; margin:12px 0 6px; flex-wrap:wrap; }
.gate-spk > label { font-size:var(--t-md); color:var(--tx); font-weight:600; white-space:nowrap; }
.gate-spk .req { color:var(--risk); font-size:var(--t-xs); font-weight:700; margin-left:2px; }
.gate-spk-pick { display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
/* ★인원 칸은 좁게.★ 상세정보 양식의 .spk-input 은 그 칸 폭에 맞춰 width:100% 라,
   그대로 두면 줄을 통째로 차지해 라디오가 아래로 밀린다(실측 205px). 여기서만 좁힌다. */
.gate-spk .spk-input { width:88px; flex:none; }
/* 앱 공용 드롭다운을 그대로 쓴다 — 여기서는 가로로 놓이므로 아래 여백만 없앤다. */
.gate-ch .dropdown { flex:1; min-width:0; margin-bottom:0; }
/* 안 고른 상태를 눈에 띄게 — 빨간 테두리가 곧 「여기가 막는 자리」다. */
.gate-ch .dropbtn.missing { border-color:var(--risk); }
/* ★목록이 열리면 이 창만 넘침을 푼다.★ .modal 은 overflow:auto 라 절대위치 목록이
   창 아래에서 잘린다. 다른 모달(용어집)은 내용이 길어 스크롤이 필요하므로 건드리지 않고,
   내용이 짧은 이 창에만 건다. */
#metaGate .modal:has(.dropmenu:not(.hidden)) { overflow:visible; }
/* 목록이 창 밖으로 크게 삐져나가지 않게 — 검색으로 좁히는 것이 기본 동선이다. */
#metaGate .dropmenu { max-height:200px; }
.gate-warn { margin:4px 0 0; font-size:var(--t-md); color:var(--risk); font-weight:600; }

/* ---- 반드시 확인 ---- */
/* 「확인 필요」와 색과 말이 달라야 한다. 확인 필요는 참고, 이건 안 보면 내보내기가 막힌다. */
.mustbar { margin:0 0 8px; padding:9px 12px; border-radius:8px; font-size:var(--t-md);
  background:var(--risk-fill); border:1px solid var(--risk-line); color:var(--tx); display:flex; align-items:center; gap:10px; }
.mustbar b { color:var(--risk); }
.mustbar button { padding:4px 10px; font-size:var(--t-sm); background:var(--risk-fill); border-color:var(--risk-line); color:var(--tx-2);
  flex:0 0 auto; white-space:nowrap; }
.mustbar button:hover { border-color:var(--risk); color:var(--tx); }
/* ★안내 문구를 한 덩이로 묶는다.★ flex 아래서는 글자와 <b> 가 ★각각 flex 항목★이 되어
   폭이 모자라면 세로로 눌린다 — 단추를 하나 더 넣자 「반드시 확인」이 네 줄이 됐다.
   .swapbar 때와 같은 부류다(그때는 flex-wrap 이었다). 띠 안에 무언가 더할 때는 이걸 먼저 본다. */
.mustbar .msg { flex:1 1 auto; min-width:0; }
/* 띠 안의 주된 행동 — 나머지 단추와 눈에 띄게 갈라 둔다(안 그러면 안 눌린다). */
.mustbar button.prim { background:var(--risk); border-color:var(--risk); color:var(--ink-on); font-weight:700; }
.mustbar button.prim:hover { background:var(--risk); border-color:var(--risk); box-shadow:0 0 0 3px var(--risk-fill); }
/* 도구줄의 「반드시 확인 N개」도 남은 일이 있으면 붉게 — 띠와 같은 일이라는 것이 보이게. */
#nounOnly.pending { background:var(--risk-fill); border-color:var(--risk-line); color:var(--risk); font-weight:700; }
#nounOnly.pending:hover { border-color:var(--risk); color:var(--tx); }
.cue.must { border-left:3px solid var(--risk); background:var(--cue-risk); }
/* 확인 단추 자리 — 줄 오른쪽 세로 가운데. 딱지 사이에 끼우면 낱말이 늘수록 밀려 안 보인다. */
.cact { align-self:center; display:flex; align-items:center; justify-content:flex-end; min-width:0; }
.cact:empty { display:none; }
.must-tag { margin-left:6px; padding:1px 6px; border-radius:5px; font-size:var(--t-xs); font-weight:700;
  background:var(--risk-fill); color:var(--risk); border:1px solid var(--risk-line); }
.must-ok { padding:3px 12px; font-size:var(--t-sm); border-radius:6px; white-space:nowrap;
  background:var(--risk-fill); border:1px solid var(--risk-line); color:var(--tx-2); }
.must-ok:hover { border-color:var(--risk); color:var(--tx); }
.must-done { padding:2px 8px; border-radius:6px; font-size:var(--t-xs); white-space:nowrap; color:var(--ok); border:1px solid var(--line); }
.cue.just-seen { outline:2px solid var(--ok); outline-offset:-2px; }

/* ---- 낱말 일괄 수정 ---- */
/* 「반드시 확인」과 색이 달라야 한다. 이건 막는 것이 아니라 물어보는 것이다. */
.swapbar { margin:0 0 8px; padding:9px 12px; border-radius:8px; font-size:var(--t-md);
  background:var(--surface-2); border:1px solid var(--ink-line); color:var(--tx-2);
  display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.swapbar b { color:var(--tx); }
.swapbar button { padding:4px 10px; font-size:var(--t-sm); }
.swapbar button:disabled { opacity:.4; cursor:default; }
.swapbar input[type=text], .swapbar #swapFrom, .swapbar #swapTo {
  background:var(--surface-2); color:var(--tx); border:1px solid var(--line);
  border-radius:6px; padding:5px 9px; font-size:var(--t-md); width:150px; }
.swapbar #swapFrom:focus, .swapbar #swapTo:focus { border-color:var(--ink-soft); }
.swapbar .sp { flex:1; }
/* ★미리보기는 세로로 쌓인다.★ 높이를 묶지 않으면 자막 목록을 밀어내 화면이 멈춘다
   (고유명사 관문에서 이미 겪었다 — 23개에 목록이 8px 가 됐다). */
/* ★flex-wrap 을 반드시 끈다.★ 위쪽 .swapbar 규칙의 wrap 이 남아 있으면, 세로 칸이 넘칠 때
   목록이 ★옆으로 새 열을 만들어★ 오른쪽으로 밀려나고 화면 밖으로 나간다(성진님 신고 2회).
   높이는 .sw-list 가 스크롤로 감당한다. */
.swapbar { flex-direction:column; flex-wrap:nowrap; align-items:stretch; max-height:38vh; overflow:hidden; }
.sw-head { display:flex; align-items:center; gap:8px; flex-wrap:wrap; flex:none; }
.sw-note { font-size:var(--t-sm); margin:6px 0 4px; flex:none; }
.sw-list { overflow:auto; min-height:0; border-top:1px solid var(--line-soft); }
.sw-row { display:grid; grid-template-columns:18px 46px 1fr; gap:8px; align-items:center;
  padding:5px 2px; border-bottom:1px solid var(--line-soft); font-size:var(--t-sm); cursor:pointer; }
.sw-row:hover { background:var(--surface-2); }
.sw-at { color:var(--ink-soft); font-size:var(--t-xs); cursor:pointer; }
.sw-at:hover { text-decoration:underline; color:var(--tx); }
/* ★줄 폭을 다 쓴다.★ 가운데로 모았더니 넓은 화면에서 좌우에 200px 씩 빈 공간이 생기고
   정작 글자는 241px 로 눌렸다(성진님 화면 1920px 실측). 둘이 반씩 나눠 갖고,
   앞은 오른쪽 끝에 붙여 화살표 바로 앞에서 끝나게 한다 — 그래야 짝이 눈에 이어진다. */
.sw-pair { display:flex; align-items:center; gap:10px; min-width:0; flex:1; }
.sw-b, .sw-a { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; flex:1 1 0; }
.sw-b { color:var(--dim); text-align:right; }
.sw-ar { color:var(--dim); flex:none; }
.sw-a { color:var(--tx); }
/* 바뀌는 낱말 — 어디가 바뀌는지 한눈에. 빼는 쪽은 빨강, 넣는 쪽은 초록. */
.sw-old { background:none; color:var(--risk); font-weight:700; }
.sw-new { background:none; color:var(--ink); font-weight:700; }
.sw-row:has(input:not(:checked)) .sw-a { color:var(--dim); text-decoration:line-through; }
.sw-row:has(input:not(:checked)) .sw-new { color:var(--dim); }
#swapYes { border-color:var(--ink-line); color:var(--ink); }
#swapYes:hover { border-color:var(--ink); color:var(--ink); box-shadow:0 0 0 3px var(--ink-fill); }

/* ---- 시작 전 확인 창의 언어 줄 ---- */
.gate-lang { display:flex; align-items:center; gap:8px; margin-top:10px; flex-wrap:wrap; }
.gate-lang > label { font-size:var(--t-md); color:var(--dim); min-width:52px; }
.gate-lang .dropbtn { font-size:var(--t-md); padding:6px 10px; }
/* .gate-arrow 의 색과 크기는 위 .lang-arrow 와 한 줄에 함께 적혀 있다. */
.gate-lang-note { margin:6px 0 0 60px; font-size:var(--t-sm); color:var(--dim); }
/* 번역이 걸릴 때는 눈에 띄어야 한다 — 잘못 두면 영상 전체가 엉뚱한 언어로 나간다. */
.gate-lang-note.on { color:var(--ink-soft); font-weight:600; }

/* 검수 작업은 자막을 읽고 원음을 듣는 것이 중심이다. 상태 설명은 보조 크기로 둔다. */
#stage { grid-template-columns:minmax(330px, .9fr) minmax(400px, 1.3fr); }
.left { padding-block:var(--gutter); }
.cue { padding:var(--sp-4) var(--gutter); gap:var(--sp-4); }
.cue .txt { font-size:16px; line-height:1.65; }
.cue .tc { padding-top:5px; font-size:var(--t-sm); }
.toolbar { padding:var(--sp-4) var(--gutter); }
.editor-shortcuts { flex-basis:100%; font-size:var(--t-sm); color:var(--dim); }
@media (max-width:900px) {
  #stage { grid-template-columns:minmax(0, 1fr); overflow:auto; display:block; }
  #stage .left { border-right:0; border-bottom:1px solid var(--line); overflow:visible; }
  #stage .right { min-height:420px; overflow:visible; }
  #stage .cues { overflow:visible; }
  #stage video { max-height:36vh; }
}

/* 입력과 결과에 집중하는 첫 화면 */
.hist-retention, .cutPick-format { display:block; font-size:11px; color:var(--dim); margin:8px 0; }
body:has(#glossOverlay:not(.hidden)) { overflow:hidden; }
.meta-rules-info:empty, .lang-note:empty, .cutInfo:empty { display:none; }
#drop { border-radius:12px; }
#glossSlot .meta-grid { grid-template-columns:1fr 1fr; }
@media(max-width:640px) { #glossSlot .meta-grid { grid-template-columns:1fr; } }

/* 새 작업, 설정, 저장 작업을 각기 하나의 영역으로 읽도록 구분한다. */
.landing-create { padding:16px; border:1px solid var(--line-strong); border-radius:12px; background:var(--surface); margin-bottom:20px; }
.landing-create #drop { background:var(--bg); padding:36px 20px; }
.landing-create .lang-row { margin-bottom:0; }
#history { background:var(--surface); border:1px solid var(--line-strong); border-radius:12px; padding:18px; }
.hist-head { color:var(--tx); font-size:var(--t-lg); }
.hist-empty { border:0; background:var(--bg); }
.metaPanel, .metaPanel.empty { background:var(--surface); border-color:var(--line-strong); }
.metaPanel:not(.collapsed) .meta-head { border-bottom:1px solid var(--line-strong); padding-bottom:14px; margin-bottom:18px; }
.metaPanel:not(.collapsed) .meta-summary { display:none; }
.meta-toggle { flex-shrink:0; }
.meta-title { white-space:nowrap; }
.meta-summary { min-width:0; }
.meta-section h3 { font-size:var(--t-lg); }
.meta-section, .meta-library { border-bottom-color:var(--line-strong); }
.cutPick { background:var(--surface); border-color:var(--line-strong); margin-top:20px; }
@media(max-width:640px) {
  .landing-create { padding:12px; }
  .meta-summary { display:none; }
  #metaLibrary > summary { gap:8px; padding-inline:10px; }
}
