/* 모바일 데모 화면 스타일. 데스크톱 style.css 는 #stage/#panel 레이아웃 전용이라 여기선 안 쓴다 —
   토큰만 따로 갖는다 (design 캔버스 시안에서 쓴 것과 같은 값).
   담당: 수연 (R5) */

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../../../vendor/fonts/archivo/archivo-latin-variable.woff2') format('woff2');
}
/* 사이트 전체 폰트(2026-09-20) — 한글이 시스템 폰트(OS마다 다른 맑은 고딕 등)로 떨어지던 걸
   Pretendard 로 통일한다. 로고 워드마크만 예외로 Archivo 를 그대로 쓴다(아래 --font-wordmark). */
@font-face {
  font-family: 'Pretendard Variable';
  font-style: normal;
  font-weight: 45 920;
  font-display: swap;
  src: url('../../../vendor/fonts/pretendard/pretendard-variable.woff2') format('woff2-variations');
}

:root {
  --color-bg: #f3f2f2;
  --color-surface: #eae9e9;
  --color-text: #201e1d;
  /* accent — 순하게 어두운 빨강(H0 S100 L43, #db0000)에서 주황기를 아주 살짝만(H0→8, 2026-09-20
     요청) 얹었다. 채도·명도는 그대로. 파생 톤(100/300/600/700/800)도 같은 밝기 간격
     (base 대비 ±.47/.36/-.04/-.16/-.25 L)으로 다시 뽑았다 — 톤 하나만 바꾸면 hover 가 더
     밝아지거나 팔레트가 어긋난다. */
  --color-accent: #db1d00;
  --color-divider: color-mix(in srgb, #201e1d 40%, transparent);
  --color-neutral-100: #f8f4f4;
  --color-neutral-300: #d7d3d3;
  --color-neutral-500: #9b9797;
  --color-neutral-600: #7d7979;
  --color-neutral-700: #605d5d;
  --color-neutral-800: #444141;
  --color-neutral-900: #2d2b2b;
  --color-accent-100: #ffd3cc;
  --color-accent-300: #ffa294;
  --color-accent-600: #c71b00;
  --color-accent-700: #8a1200;
  --color-accent-800: #5c0c00;
  --font-heading: 'Pretendard Variable', 'Pretendard', 'Malgun Gothic', system-ui, sans-serif;
  --font-body: 'Pretendard Variable', 'Pretendard', 'Malgun Gothic', system-ui, sans-serif;
  --font-wordmark: 'Archivo', 'Malgun Gothic', system-ui, sans-serif; /* "livlur" 로고 전용 */
}

* , *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; height: 100%; color: var(--color-text); font-family: var(--font-body); word-break: keep-all; overflow-wrap: break-word; }
/* 데스크톱 창은 넓다 — 폰 카드를 가운데 띄우고 바깥은 배경으로 채운다. 실제 폰(뷰포트 ≤430px)에선
   .m-app 이 그냥 화면 전체를 채워서 이 여백이 안 보인다. */
body {
  display: flex;
  justify-content: center;
  background: var(--color-neutral-300);
}
/* body 의 유일한 실제 자식(#app, script 태그는 display:none 이라 레이아웃에서 빠진다)이
   너비 auto 인 채로 percentage 자식(.m-app)을 품으면 브라우저가 콘텐츠 기준으로 좁게
   접어버린다 — #app 을 직접 flex 컨테이너로 만들어 body 폭을 그대로 물려준다.
   align-items:center 는 가로모드용이다 — .m-app.m-landscape 는 높이가 100% 보다 짧게 고정되는데,
   고정 높이는 stretch 가 안 먹어서 기본값(flex-start)대로 화면 위에 붙어버렸었다. */
#app { display: flex; justify-content: center; align-items: center; width: 100%; height: 100%; }
h2 { font-family: var(--font-heading); font-weight: 800; letter-spacing: -0.02em; font-size: 24px; margin: 0 0 4px; }
p { margin: 0; }
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.text-muted { color: color-mix(in srgb, var(--color-text) 55%, transparent); }

.wm { font-family: var(--font-wordmark); font-weight: 800; letter-spacing: -0.03em; }

/* 워드마크: accent 사각형 마크 + "li"는 또렷하게, "vlur"는 블러 — 가리는 서비스라는 뜻을 로고 자체가 보여준다.
   (logo.js) */
.m-logo { display: inline-flex; align-items: center; gap: 6px; }
.m-logo-mark { width: 11px; height: 11px; flex: none; background: var(--color-accent); }
.m-logo-blur { filter: blur(1.1px); }
.kick { font: 600 10px/1 var(--font-heading); letter-spacing: 0.12em; text-transform: uppercase; color: var(--color-accent); margin-bottom: 6px; }

/* 버튼 — desktop.html 쪽 style.css 의 .btn 계열과 같은 언어 */
.btn {
  display: inline-flex; align-items: center; justify-content: flex-start; gap: 6px;
  cursor: pointer; text-align: left;
  font-family: var(--font-heading); font-weight: 800; font-size: 14px;
  border: 1px solid var(--color-divider); border-radius: 0;
  padding: 12px 14px; min-height: 48px;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease, transform .08s ease;
}
.btn:active { transform: scale(.97); }
.btn-primary { background: var(--color-accent); color: var(--color-bg); border-color: var(--color-accent); }
.btn-primary:hover { background: var(--color-accent-600); border-color: var(--color-accent-600); }
.btn-primary:active { background: var(--color-accent-700); border-color: var(--color-accent-700); }
.btn-secondary { background: transparent; color: var(--color-text); }
/* 배경이 투명이라(밝은 화면·어두운 화면 둘 다 쓴다) currentColor 를 살짝 섞는다 — 글자색이
   문맥마다 달라도(.m-register-overlay .btn-secondary 등) 자동으로 어울리는 톤이 나온다. */
.btn-secondary:hover { background: color-mix(in srgb, currentColor 10%, transparent); }
.btn-secondary:active { background: color-mix(in srgb, currentColor 18%, transparent); }
.btn-block { width: 100%; }

/* ── 앱 셸 ── */
.m-app {
  position: relative; /* 첫 진입 스플래시(.m-splash)가 이 카드 전체를 덮는 절대위치 기준 */
  display: flex; flex-direction: column; height: 100dvh; width: 100%; max-width: 430px;
  min-width: 0; /* flex 아이템 기본값(min-width:auto)이면 안 줄어드는 내용(로그 텍스트 등) 때문에
                   max-width 를 무시하고 카드가 늘어난다 — 탭마다 폭이 달라지던 원인 */
  overflow: hidden; background: var(--color-bg);
  box-shadow: 0 12px 32px color-mix(in srgb, #2d2b2b 22%, transparent);
}
/* 가로모드 — 실기기를 눕히거나(자동 감지) 가로로 찍힌 영상을 넣었을 때(수동 전환) 세로 카드 대신
   훨씬 넓고 낮은 카드를 쓴다. 실제 폰을 눕혔을 때 비율(약 2:1~2.3:1)에 맞춰 세로 카드보다
   비율이 확실히 더 길어야 "가로모드답게" 보인다. */
.m-app.m-landscape {
  height: min(100dvh, 420px); width: 100%; max-width: min(97vw, 980px);
}
.m-app-body { position: relative; flex: 1; min-height: 0; overflow: hidden; display: flex; }

.m-screen { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.m-screen-dark { background: var(--color-neutral-900); }
.m-screen-light { background: var(--color-bg); overflow-y: auto; }

/* 방송 종료 뒤 안내 — 제목·설명·뒤로가기를 한 덩어리로 화면 정중앙에 둔다. */
.m-post-capture { align-items: center; justify-content: center; padding: 24px 18px; text-align: center; }
.m-post-capture-content { width: 100%; max-width: 320px; }
.m-post-capture-content h2 { margin: 0 0 6px; }
.m-post-capture-content .m-page-sub + .m-page-sub { margin-top: 4px; }
.m-post-capture-actions { width: 100%; display: flex; align-items: center; justify-content: center; margin-top: 24px; }
.m-post-capture-back { width: min(100%, 240px); align-items: center; justify-content: center; text-align: center; }

/* ── 촬영 화면 ── */
.m-capture-viewport { position: relative; flex: 1; min-height: 0; overflow: hidden; container-type: size; }   /* cqh: 프레임 폭을 높이에서 계산 (아래) */
/* 방송 중임을 알리는 빨간 테두리 — 프레임 가장자리에서 2px 띄운 자리에 1.5px 선.
   ::after 로 얹는다(새 DOM 노드 없이, 탭 박스·버튼 클릭을 안 막게 pointer-events:none). */
.m-capture-viewport::after {
  content: ''; position: absolute; inset: 2px; z-index: 5; pointer-events: none;
  border: 1.5px solid var(--color-accent);
  box-shadow: inset 0 0 24px color-mix(in srgb, var(--color-accent) 12%, transparent);
}
.m-det-mask {
  position: absolute; inset: 0;
  background-image: repeating-conic-gradient(from 0deg, #6d6a68 0% 25%, #3a3735 0% 50%);
  background-size: 8px 8px;
}

.m-topbar { position: absolute; left: 0; right: 0; top: max(12px, env(safe-area-inset-top)); padding: 0 12px; }
.m-topbar-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* LIVE 배지 아래 한 줄 — 녹화 오류·「확인된 개인정보만 가림」처럼 나가는 것과 직결되는 상태만 (capture-screen.js subLabel) */
.m-topbar-note { margin-top: 6px; font: 700 11px/1.3 var(--font-heading); color: #fff; background: rgba(32,30,29,.82); border: 1px solid rgba(255,255,255,.22); padding: 5px 9px; display: inline-block; }
/* LIVE 배지 — 예전엔 여기 브랜드 워드마크가 있었다. 방송 느낌을 내려고 점 깜빡임 + 경과 시간으로 바꿨다(capture-screen.js LiveBadge). */
.m-brand-pill { display: flex; align-items: center; gap: 8px; background: var(--color-accent); padding: 7px 11px; flex: none; }
.m-live-label { color: #fff; font: 800 12px/1 var(--font-heading); letter-spacing: 0.08em; }
.m-live-sep { width: 1px; height: 12px; background: rgba(255, 255, 255, .4); }
.m-live-time { color: #fff; font: 600 12px/1 var(--font-body); font-variant-numeric: tabular-nums; }
/* 방향 전환 버튼 — 항상 맨 오른쪽으로 민다. 네모 상자 대신 동그라미, 테두리는 없앴다(요청) — 아이콘 자체가
   흰 선(#fff stroke)이라 옅은 배경만 살짝 깔아 임의의 영상 위에서도 보이게 하고, 호버하면 더 진한 회색으로 꽉 채운다. */
.m-rotate-icon {
  margin-left: auto; flex: none; width: 32px; height: 32px; padding: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; background: rgba(32,30,29,.4); border: none;
  transition: background-color .15s ease, transform .08s ease;
}
.m-rotate-icon:hover { background: rgba(32,30,29,.8); }
.m-rotate-icon:active { background: rgba(32,30,29,.92); transform: scale(.92); }
.m-livedot { width: 9px; height: 9px; border-radius: 50%; background: #fff; animation: m-livedot 1.1s ease-in-out infinite; }
@keyframes m-livedot { 0%, 100% { opacity: 1 } 50% { opacity: .25 } }
.m-buffer-track { margin-top: 7px; height: 4px; background: rgba(255,255,255,.18); }
.m-buffer-fill { height: 100%; background: var(--color-accent); }

.m-sheet-backdrop { position: absolute; inset: 0; background: rgba(32,30,29,.62); display: flex; align-items: flex-end; }
.m-sheet { width: 100%; background: var(--color-bg); border-top: 2px solid var(--color-text); padding: 20px 18px max(22px, env(safe-area-inset-bottom)); }
.m-sheet-actions { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }

/* 녹화 완료 알림은 화면 아래가 아니라 현재 화면 가운데에 띄운다. */
.m-rec-save-backdrop { align-items: center; justify-content: center; padding: 20px; }
.m-rec-save {
  width: min(100%, 340px); padding: 18px; border: 1px solid var(--color-divider);
  box-shadow: 0 16px 36px rgba(32,30,29,.24);
}
.m-rec-save-title { font-size: 17px; margin: 0 0 6px; }
.m-rec-save-meta { font: 600 12px/1.4 var(--font-heading); color: var(--color-neutral-700); }
.m-rec-save-note { margin-top: 4px; font: 400 11px/1.5 var(--font-body); color: var(--color-neutral-600); }
.m-rec-save-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.m-rec-save-btn { min-height: 34px; padding: 7px 14px; font-size: 12px; justify-content: center; }

/* 가로 영상을 골랐을 때 가로모드로 볼지 묻는 확인창 — .m-app 카드 밖(뷰포트 전체)에 뜬다 */
.m-landscape-ask-backdrop {
  position: fixed; inset: 0; z-index: 30;
  background: rgba(32,30,29,.62); display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.m-landscape-ask {
  width: 100%; max-width: 320px; background: var(--color-bg); padding: 20px;
  box-shadow: 0 12px 32px color-mix(in srgb, #2d2b2b 30%, transparent);
}
.m-landscape-ask-text { font: 700 14px/1.5 var(--font-heading); color: var(--color-text); margin-bottom: 16px; }
.m-landscape-ask-actions { display: flex; gap: 8px; }
.m-landscape-ask-actions .btn { flex: 1; justify-content: center; }

/* 종료 버튼 — 영상 위에 뜨는 원형 버튼. 예전엔 하단에 따로 자리를 차지하는 바(.m-controlbar)였는데,
   그 자리를 접고 영상 위 오버레이로 옮겨서 .m-capture-viewport(flex:1)가 카드 전체 높이를 쓰게 했다. */
.m-end-scrim { position: absolute; left: 0; right: 0; bottom: 0; height: 168px; background: linear-gradient(180deg, rgba(0, 0, 0, 0), rgba(0, 0, 0, .6) 70%); z-index: 6; pointer-events: none; }
.m-end-wrap { position: absolute; left: 0; right: 0; bottom: max(36px, env(safe-area-inset-bottom)); display: flex; flex-direction: column; align-items: center; gap: 10px; z-index: 7; }
.m-end-btn {
  position: relative; width: 72px; height: 72px; border-radius: 50%; background: rgba(23, 22, 21, .55);
  border: 2px solid var(--color-accent); box-shadow: 0 6px 20px rgba(0, 0, 0, .45);
  display: flex; align-items: center; justify-content: center; padding: 0; cursor: pointer;
  transition: background-color .15s ease, transform .08s ease;
}
.m-end-btn:hover { background: rgba(23, 22, 21, .75); }
.m-end-btn:active { background: rgba(23, 22, 21, .9); transform: scale(.94); }
.m-end-btn-ring { position: absolute; inset: 5px; border-radius: 50%; border: 1.5px solid #fff; pointer-events: none; }
.m-end-btn-icon { width: 24px; height: 24px; background: var(--color-accent); border-radius: 6px; transition: transform .15s ease; }
.m-end-btn:hover .m-end-btn-icon { transform: scale(1.15); }
.m-end-caption { color: var(--color-accent); font: 700 11px/1 var(--font-heading); letter-spacing: 0.04em; text-shadow: 0 1px 3px rgba(0, 0, 0, .6); }

/* 종료 확인창 — "정말 끌까요?" + 6초 카운트다운(capture-screen.js END_COUNTDOWN_S) + 아니요/종료하기 */
.m-end-confirm-backdrop { position: absolute; inset: 0; z-index: 10; background: rgba(0, 0, 0, .68); display: flex; align-items: center; justify-content: center; }
.m-end-confirm-card { width: 280px; max-width: calc(100% - 40px); box-sizing: border-box; background: #201e1d; border: 1.5px solid var(--color-accent); padding: 26px 22px; display: flex; flex-direction: column; align-items: center; gap: 16px; box-shadow: 0 20px 50px rgba(0, 0, 0, .5); }
.m-end-confirm-text { color: #fff; font: 800 16px/1.4 var(--font-heading); text-align: center; }
.m-end-confirm-count { color: var(--color-accent); font: 800 44px/1 var(--font-heading); font-variant-numeric: tabular-nums; }
.m-end-confirm-actions { display: flex; gap: 10px; width: 100%; }
.m-end-confirm-actions .btn { flex: 1; justify-content: center; text-align: center; }
.m-end-confirm-card .btn-secondary { color: #fff; border-color: rgba(255, 255, 255, .4); }

/* 가로모드 — 영상이 카드 전체를 채운다.
   ① .m-capture-frame 은 원래 16:9 고정 비율 박스라, 카드가 16:9보다 더 넓어지면(가로모드 카드는
      약 2.3:1) 높이를 max-height 에 맞추고 너비는 그 비율대로 줄어들어 오른쪽에 빈 칸이 남는다.
      가로모드에선 그 비율을 버리고 뷰포트 전체(inset:0)를 그대로 쓴다.
   ② object-fit:cover 로 버퍼(16:9)를 박스 비율에 맞게 잘라서 채운다 — 기본값(늘리기)이면
      영상이 옆으로 눌려 보인다.
   ③ 종료 버튼을 하단 중앙 대신 오른쪽 가장자리에 세로 중앙 정렬로 — 가로 화면은 옆 여백이 넓다. */
.m-app.m-landscape .m-capture-frame { position: absolute; inset: 0; width: auto; aspect-ratio: auto; max-height: none; transform: none; }
.m-app.m-landscape .m-out-canvas { object-fit: cover; }
.m-app.m-landscape .m-end-scrim { left: auto; bottom: 0; top: 0; right: 0; width: 140px; height: auto; background: linear-gradient(270deg, rgba(0, 0, 0, .5), rgba(0, 0, 0, 0)); }
.m-app.m-landscape .m-end-wrap { left: auto; right: 20px; bottom: auto; top: 50%; transform: translateY(-50%); }
.m-app.m-landscape .m-end-btn { width: 60px; height: 60px; }
.m-app.m-landscape .m-end-btn-icon { width: 20px; height: 20px; border-radius: 5px; }

/* 가로모드 — 영상이 카드 전체를 채운다.
   ① .m-capture-frame 은 원래 16:9 고정 비율 박스라, 카드가 16:9보다 더 넓어지면(가로모드 카드는
      약 2.3:1) 높이를 max-height 에 맞추고 너비는 그 비율대로 줄어들어 오른쪽에 빈 칸이 남는다.
      가로모드에선 그 비율을 버리고 뷰포트 전체(inset:0)를 그대로 쓴다.
   ② object-fit:cover 로 버퍼(16:9)를 박스 비율에 맞게 잘라서 채운다 — 기본값(늘리기)이면
      영상이 옆으로 눌려 보인다.
   ③ 컨트롤바를 원래 자리(하단 전체 폭 바)에서 빼고 영상 위에 뜨는 작은 버튼으로 바꾼다 —
      그만큼 .m-capture-viewport(flex:1)가 카드 전체 높이로 늘어난다. */
.m-app.m-landscape .m-capture-frame { position: absolute; inset: 0; width: auto; aspect-ratio: auto; max-height: none; transform: none; }
.m-app.m-landscape .m-out-canvas { object-fit: cover; }
.m-app.m-landscape .m-controlbar {
  position: absolute; left: 12px; bottom: max(12px, env(safe-area-inset-bottom)); z-index: 5;
  width: auto; padding: 0; background: none; border-top: 0;
}

/* ── 세팅 화면 페이지 헤더 (setup-screen.js) ── */
.m-page-head { padding: max(14px, env(safe-area-inset-top)) 18px 12px; }
.m-page-sub { font: 400 12px/1.5 var(--font-body); color: var(--color-neutral-700); }
/* "촬영 전 세팅 · Setup" 킥 문구를 뺀 자리만큼 로고를 키운다 — 다른 곳(브랜드 필 등)의
   .m-logo 는 그대로 작게 둬야 해서 이 헤더 안에서만 크기를 올린다. */
.m-page-head-big-logo { padding-bottom: 16px; }
.m-page-head-big-logo .m-logo { gap: 10px; }
.m-page-head-big-logo .m-logo-mark { width: 22px; height: 22px; }
.m-page-head-big-logo .wm { font-size: 30px; }

/* ── 새 항목 등록 화면. 세팅 화면 위를 덮는 전체 화면(register-target-screen.js) ── */
.m-register-overlay {
  position: absolute; inset: 0; z-index: 20;
  display: flex; flex-direction: column;
  background: var(--color-neutral-900);
}
.m-register-close {
  position: absolute; top: max(14px, env(safe-area-inset-top)); right: 14px; z-index: 21;
  width: 36px; height: 36px; display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.22);
  color: #fff; cursor: pointer; padding: 0;
  transition: background-color .15s ease;
}
.m-register-close:hover { background: rgba(255,255,255,.22); }
.m-register-close:active { background: rgba(255,255,255,.32); }
/* 카메라 ↔ 사진 업로드 전환. 닫기 버튼과 안 겹치게 왼쪽에 둔다 */
.m-register-mode {
  position: absolute; top: max(14px, env(safe-area-inset-top)); left: 14px; z-index: 21;
  display: inline-flex; border: 1px solid rgba(255,255,255,.22);
}
.m-register-mode-opt {
  padding: 8px 12px; font: 700 11px/1 var(--font-heading); letter-spacing: .02em;
  background: rgba(255,255,255,.06); color: rgba(255,255,255,.7);
  border: 0; cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.m-register-mode-opt:hover { background: rgba(255,255,255,.16); color: #fff; }
.m-register-mode-opt:active { background: rgba(255,255,255,.26); }
.m-register-mode-opt + .m-register-mode-opt { border-left: 1px solid rgba(255,255,255,.22); }
.m-register-mode-opt-on { background: var(--color-accent); color: #fff; }
.m-register-mode-opt-on:hover { background: var(--color-accent-600); }
.m-register-mode-opt-on:active { background: var(--color-accent-700); }
.m-register-frame {
  flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center;
}
.m-register-guide {
  width: 62%; max-height: 88%; /* 가로모드처럼 프레임이 낮을 때 오벌이 위아래로 삐져나가지 않게 */
  border: 2px dashed rgba(255,255,255,.85);
  display: flex; align-items: center; justify-content: center;
  transition: border-color .2s;
  /* position 이 없으면 안의 video(position:absolute)가 이 오벌이 아니라 화면 전체(.m-register-overlay)에
     붙어서 꽉 채워버린다 — 실측: 카메라가 붙자마자 오벌 테두리·안내 카드가 전부 화면 밑에 깔려 안 보였다.
     relative 로 기준을 여기로 못박고, overflow:hidden 으로 영상을 오벌/사각 모양에 맞게 자른다. */
  position: relative; overflow: hidden;
}
.m-register-guide-oval { aspect-ratio: 3 / 4; border-radius: 50%; }
.m-register-guide-rect { aspect-ratio: 16 / 10; border-radius: 4px; }
.m-register-guide-photo {
  border-style: solid;
  color: rgba(255,255,255,.6); /* UploadIcon 이 currentColor 를 쓴다 */
  cursor: pointer; /* 사진을 아직 안 골랐을 때만 누를 수 있다 — 원 자체가 업로드 버튼이다 */
  /* 사진을 고른 뒤엔 이 안이 드래그·핀치 영역이다(photo-crop.js) — touch-action:none 이 없으면
     모바일 브라우저가 한 손가락 드래그를 페이지 스크롤로, 두 손가락 핀치를 화면 확대로 먼저 채간다. */
  touch-action: none;
}
/* 업로드 아이콘 둘레의 동그란 호버 영역 — 오벌 전체가 버튼이지만, 호버하면 아이콘 바로
   둘레에만 진한 회색 원이 떠서 "여기를 누른다"가 더 분명해지게 */
.m-register-upload-icon {
  display: flex; align-items: center; justify-content: center;
  padding: 18px; border-radius: 50%;
  transition: background-color .15s ease;
}
.m-register-guide-photo:hover .m-register-upload-icon { background: rgba(120, 116, 114, .45); color: #fff; }
.m-register-guide-photo:active .m-register-upload-icon { background: rgba(120, 116, 114, .65); }
.m-register-check {
  width: 56px; height: 56px; border-radius: 50%;
  background: var(--color-accent);
  display: flex; align-items: center; justify-content: center;
}
/* 카메라 모드 안내 카드 — 지금 뭘 해야 하는지 + 몇 초 남았는지를 화면(오벌) 위에 바로 보여준다.
   .m-register-guide 가 flex 로 가운데 정렬하고 있어서 별도 position 없이 그 자리에 뜬다. */
.m-register-hint {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  background: rgba(32,30,29,.55); padding: 14px 20px; border-radius: 10px;
}
.m-register-hint-text { font: 700 12px/1.3 var(--font-heading); color: #fff; letter-spacing: 0.02em; }
.m-register-countdown {
  font: 800 40px/1 var(--font-heading); color: #fff;
  animation: m-register-countdown-pulse .35s ease-out; /* 숫자가 바뀔 때마다(key 변경) 다시 재생 */
}
@keyframes m-register-countdown-pulse {
  from { transform: scale(1.35); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}
/* 네이티브 파일 입력은 안 보이게 — 버튼(.m-register-photo-actions button)이 클릭을 대신 받는다 */
.m-register-file-input { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; pointer-events: none; }
.m-register-photo-actions { display: flex; gap: 8px; margin-top: 14px; }
.m-register-photo-actions .btn { width: auto; flex: 1; justify-content: center; }
/* .btn-secondary 기본값(어두운 글자·옅은 테두리)은 밝은 배경 화면 기준이다 — 이 등록 화면(.m-register-overlay)은
   전체가 어두운 배경이라 그대로 두면 그 안 모든 보조 버튼의 글자·테두리가 거의 안 보인다. */
.m-register-overlay .btn-secondary { color: #fff; border-color: rgba(255,255,255,.55); }
.m-register-footer {
  flex: none; padding: 20px 20px max(24px, env(safe-area-inset-bottom));
  background: rgba(255,255,255,.04); border-top: 2px solid var(--color-accent);
}
.m-register-title { font: 800 18px/1.25 var(--font-heading); color: #fff; margin-bottom: 4px; }
.m-register-sub { font: 400 12px/1.5 var(--font-body); color: rgba(255,255,255,.6); margin-bottom: 14px; }
.m-register-progress { height: 4px; background: rgba(255,255,255,.18); }
.m-register-progress-fill { height: 100%; background: var(--color-accent); transition: width 1s linear; }

/* 등록 누르면 카메라/사진 업로드 중 뭘로 할지부터 고르는 화면 — 고르기 전엔 카메라를 안 켠다 */
.m-register-picker {
  flex: 1; min-height: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  padding: 24px; gap: 4px;
}
.m-register-picker .m-register-title { margin-top: 4px; }
.m-register-picker .m-register-sub { margin-bottom: 20px; }
.m-register-picker-actions { display: flex; flex-direction: column; gap: 10px; width: 100%; max-width: 280px; }

/* ── 세팅 화면 ── */
.m-setup { padding-bottom: 14px; }
/* 구분선은 border-bottom 대신 ::after 로 — border 는 섹션 폭 그대로라 양쪽 꽉 채운 선이 되는데,
   양쪽에 3~4px 여백을 주려면 선을 섹션보다 짧게 안쪽으로 넣어야 한다. */
.m-setup-section { position: relative; padding: 16px 18px; }   /* 다닥다닥 붙어 보인다는 피드백으로 11px→16px (요청) */
.m-setup-section::after { content: ''; position: absolute; left: 18px; right: 18px; bottom: 0; height: 1px; background: var(--color-divider); }
.m-setup-section:last-of-type::after { display: none; }
.m-setup-section h2 { font-size: 15px; margin-bottom: 0; }
.m-setup-start { padding: 12px 18px; }
.m-setup-status { margin-bottom: 1px; color: #c65312; }
.m-setup-start .btn-primary:disabled,
.m-setup-start .btn-primary:disabled:hover {
  cursor: not-allowed; background: var(--color-neutral-300); border-color: var(--color-neutral-300);
  color: var(--color-neutral-600); transform: none;
}

/* 섹션 제목 옆 설명 아이콘 — 예전엔 제목 밑에 회색 문단으로 항상 떠 있어서 화면을 많이 먹었다.
   이제 필요할 때만(호버·포커스) 말풍선으로 보여준다 (SectionHead, setup-screen.js). */
.m-section-head { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.m-info-icon {
  position: relative; display: inline-flex; flex: none; align-items: center; justify-content: center;
  width: 14px; height: 14px; border-radius: 50%; border: 1px solid var(--color-neutral-500);
  font: 700 9px/1 var(--font-heading); color: var(--color-neutral-600); cursor: help;
}
.m-info-tooltip {
  position: absolute; left: 0; top: 20px; z-index: 6; width: max-content; max-width: 220px;
  background: var(--color-neutral-900); color: #fff; font: 400 12px/1.7 var(--font-body);
  padding: 10px 12px; opacity: 0; visibility: hidden; transition: opacity .12s;
  box-shadow: 0 10px 24px color-mix(in srgb, #2d2b2b 30%, transparent);
}
.m-info-icon:hover .m-info-tooltip, .m-info-icon:focus-visible .m-info-tooltip { opacity: 1; visibility: visible; }

.m-seg { display: flex; border: 1px solid var(--color-divider); margin: 10px 0; }
/* 선택 안 된 쪽은 연한 글자색 + 회색 바탕 — 선택된 쪽(accent 빨강)과 대비를 준다 */
.m-seg-opt {
  flex: 1; padding: 10px; font: 700 12px/1 var(--font-heading); background: var(--color-neutral-100);
  border: 0; cursor: pointer; color: var(--color-neutral-500);
  transition: background-color .15s ease, color .15s ease;
}
.m-seg-opt:hover { background: var(--color-neutral-300); color: var(--color-neutral-700); }
.m-seg-opt:active { background: var(--color-neutral-500); color: #fff; }
.m-seg-opt + .m-seg-opt { border-left: 1px solid var(--color-divider); }
.m-seg-opt-on { background: var(--color-accent); color: #fff; }
.m-seg-opt-on:hover { background: var(--color-accent-600); color: #fff; }
.m-seg-opt-on:active { background: var(--color-accent-700); color: #fff; }
.m-seg-sub { margin-bottom: 10px; }                                 /* 카메라 후면/전면 선택. 바로 아래 체크 행과 사이 간격 */
/* PC 브라우저에서 후면/전면을 눌렀을 때 잠깐 뜨는 안내 (setup-screen.js pickFacing) */
.m-facing-note { margin: -4px 0 10px; font: 600 11px/1.4 var(--font-heading); color: #fff; background: rgba(32,30,29,.9); border: 1px solid var(--color-accent); padding: 6px 9px; }
.m-seg-sub .m-seg-opt { padding: 8px; font-size: 11px; }

/* 슬라이더 — accent-color 하나로 네이티브 썸·트랙 색을 바꾼다(브라우저 기본 렌더 유지, 커스텀 트랙 없음) */
.m-slider { width: 100%; margin: 0; accent-color: var(--color-accent); }
.m-slider-row { display: flex; align-items: center; gap: 8px; margin: 4px 0 8px; }
.m-slider-end { flex: none; font: 700 10px/1 var(--font-heading); color: var(--color-neutral-600); white-space: nowrap; }
.m-setup-intensity-label { font: 600 11px/1 var(--font-heading); color: var(--color-neutral-700); }

/* 모자이크/블러 미리보기 — 슬라이더 옆에서 강도가 실제로 얼마나 가리는지 바로 보여준다 */
.m-mosaic-row { display: flex; align-items: center; gap: 14px; margin-top: 8px; }
.m-mosaic-preview {
  position: relative; flex: none; width: 72px; height: 72px; overflow: hidden;
  border: 1px solid var(--color-divider);
}
.m-mosaic-controls { flex: 1; min-width: 0; }
.m-mosaic-controls .m-slider { margin-top: 0; }

/* ── 화이트리스트 리스트 ── */
.m-wl-list { display: flex; flex-direction: column; margin: 8px 0; }
.m-wl-row { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-top: 1px solid var(--color-divider); }
.m-wl-list .m-wl-row:first-child { border-top: none; }   /* 제목 바로 밑에 선 하나가 더 생겨 보이던 것 (요청) */
.m-wl-thumb { width: 44px; height: 44px; flex: none; background: var(--color-surface); display: flex; align-items: center; justify-content: center; }
.m-wl-thumb span { font: 400 8px/1.2 var(--font-body); color: var(--color-neutral-600); }
.m-wl-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.m-wl-label { font: 700 13px/1.2 var(--font-heading); cursor: pointer; }
.m-wl-label-input { font: 700 13px/1.2 var(--font-heading); border: 1px solid var(--color-accent); padding: 2px 4px; width: 100%; background: var(--color-bg); color: var(--color-text); }
.m-wl-type { font: 400 9px/1 var(--font-body); letter-spacing: 0.05em; text-transform: uppercase; color: var(--color-neutral-600); }
.m-wl-edit { flex: none; font: 700 11px/1 var(--font-heading); padding: 6px 8px; border: 1px solid var(--color-divider); background: transparent; cursor: pointer; color: var(--color-text); transition: background-color .15s ease; }
.m-wl-edit:hover { background: var(--color-neutral-100); }
.m-wl-edit:active { background: var(--color-neutral-300); }

.m-wl-remove { flex: none; font: 700 11px/1 var(--font-heading); padding: 6px 8px; border: 1px solid var(--color-accent); color: var(--color-accent); background: transparent; cursor: pointer; transition: background-color .15s ease, color .15s ease; }
.m-wl-remove:hover { background: var(--color-accent); color: #fff; }
.m-wl-remove:active { background: var(--color-accent-700); border-color: var(--color-accent-700); color: #fff; }

/* ── 배경 영상 ── */
.m-bg-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.m-det-mask-blur { background-image: none; }

/* ── 더블탭 안내 토스트 ── */
.m-tap-toast {
  position: absolute; top: -34px; left: 0; white-space: nowrap;
  background: rgba(32,30,29,.92); color: #fff; font: 600 10px/1.3 var(--font-heading);
  padding: 5px 8px; border: 1px solid var(--color-accent);
}

/* ── 실제 파이프라인 연결 (현찬 R2) ──────────────────────
   가려진 화면은 canvas 하나로 나온다. 탭 박스는 같은 사각형 안에 %로 얹혀 캔버스와 자리가 맞는다. */
/* 프레임 = 영상 사각형. 비율은 카메라가 준 대로(--frame-ar = 폭/높이, capture-screen.js 가 live.frame 으로 준다; 없으면 16:9).
   폭·높이 중 먼저 모자라는 쪽에 맞춰 가운데 — 높이에 걸릴 때 left/right:0 이면 폭이 남아 캔버스가 눌린다. 폰 세로 카메라(9:16)는 폭을 다 쓴다 */
.m-capture-frame { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); aspect-ratio: var(--frame-ar, 1.7778); width: min(100%, calc(100cqh * var(--frame-ar, 1.7778))); }
.m-out-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; background: #000; }
/* 탭 영역. 평소엔 투명 — 가려진 얼굴마다 빨간 테두리가 붙어 있으면 송출 화면이 트래킹 데모처럼 보인다(준형, 2026-09-20).
   대기(첫 탭)·해제됨 테두리는 capture-screen.js TapBox 가 인라인으로 준다. PC 는 마우스를 올리면 옅게 보여 탭할 수 있음을 알린다 */
.m-det-box { z-index: 2; border: 0; }
@media (hover: hover) { .m-det-box:not(.m-det-box-armed):not(.m-det-box-off):hover { border: 2px solid rgba(255,255,255,.55) !important; } }
.m-det-off {
  position: absolute; left: 0; top: -20px; font: 700 10px/1.6 var(--font-heading);
  background: rgba(255,255,255,.9); color: var(--color-neutral-900); padding: 0 6px; white-space: nowrap;
}
.m-file-row { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.m-file-input { font: 500 12px/1.4 var(--font-body); }
.m-save-row { display: flex; align-items: flex-start; gap: 8px; margin: 8px -8px 0; padding: 8px; font: 500 13px/1.4 var(--font-body); color: var(--color-neutral-900); cursor: pointer; transition: background-color .15s ease; }
.m-save-row input { margin: 2px 0 0; flex: none; accent-color: var(--color-accent); }   /* 기본(브라우저 파랑) 대신 빨강 (요청) */
.m-save-row small { display: block; font: 400 11px/1.5 var(--font-body); color: var(--color-neutral-700); }
.m-save-row-sub { margin: 4px 0 0 26px; }
/* 저장 아이콘 — 이 행은 설명 글이 길어 줄바꿈되므로(align-items:flex-start) 마이크·삽입 토글처럼
   체크박스를 숨기진 않고 아이콘만 곁들인다. 켜짐이면 아이콘만 accent 빨강 (요청) */
.m-save-row-icon { flex: none; margin-top: 1px; color: var(--color-neutral-600); }
.m-save-row-icon-on { color: var(--color-accent); }
/* 파일 저장 화면 (save-screen.js) */
.m-save-bar { height: 10px; margin-top: 12px; background: var(--color-divider); overflow: hidden; }
.m-save-fill { height: 100%; background: var(--color-accent); transition: width .3s linear; }
.m-save-line { margin-top: 8px; font: 700 13px/1.4 var(--font-heading); color: var(--color-neutral-900); }
.m-save-preview { padding: 0 18px; }
.m-save-frame { position: relative; width: 100%; aspect-ratio: var(--frame-ar, 1.7778); background: #000; }   /* 비율은 영상이 준 대로 (save-screen.js) */
.m-setup-error {
  font: 600 13px/1.5 var(--font-body); color: #fff; background: var(--color-accent);
  padding: 8px 10px; margin-bottom: 8px;
}
/* 세팅 화면 머리의 「모바일 화면으로 보기」— PC 배치(?layout=desktop)에서 돌아가는 버튼만 남았다.
   진입 버튼("PC 화면으로 보기")은 화면을 더 간단하게 하려고 뺐다(요청). 폰 폭에선 뜻이 없어 숨긴다. */
.m-layout-switch {
  margin-left: auto; padding: 6px 10px; cursor: pointer;
  font: 700 11px/1 var(--font-heading); letter-spacing: .02em;
  background: transparent; color: var(--color-neutral-700); border: 1px solid var(--color-divider);
}
.m-layout-switch:hover { color: var(--color-text); border-color: var(--color-text); }
@media (max-width: 430px) { .m-layout-switch { display: none; } }
.m-register-preview { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* 카운트다운이 끝나 찍은 정지 사진 — 실시간 영상 위를 덮어서 "이게 등록될 사진이다"를 보여준다 */
.m-register-captured-photo { position: absolute; inset: 0; background-size: cover; background-position: center; }

/* 아이콘 + 글자로 보여주는 체크 토글 — 영상 파일 삽입·마이크 켜기가 같이 쓴다(setup-screen.js
   icons.js MicIcon/UploadIcon). 글자 라벨만 있던 자리에 아이콘을 넣으면서(요청) 네모 체크박스는
   화면에서 숨기고, 켜짐이면 아이콘·글자가 같이 accent 빨강(둘 다 currentColor), 꺼짐이면 회색. */
.m-icon-check { display: flex; align-items: center; gap: 8px; padding: 9px 0; cursor: pointer; color: var(--color-neutral-600); }
.m-icon-check-on { color: var(--color-accent); }
/* 입력 토글 두 개의 클릭 영역을 호버 배경으로 알려준다. 모서리는 안 둥글린다 — livlur 는
   각진 미니멀 언어를 쓴다(요청, 2026-09-20 녹화 완료 패널 리디자인 때 확정) */
.m-file-toggle-wrap > .m-icon-check { width: fit-content; max-width: 100%; padding: 10px 12px; transition: background-color .15s ease; }
@media (hover: hover) {
  .m-file-toggle-wrap > .m-icon-check:hover { background-color: var(--color-neutral-200, #e5e3e1); }
}
.m-icon-check-label { font: 700 13px/1 var(--font-heading); }

/* 「가릴 것」— 세 항목이 한 줄에, 각 항목은 동그라미(라디오)와 글자가 나란히(detect-section.js).
   전엔 동그라미를 글자 위에 쌓아서 28px 동그라미 밑에 11px 글자가 따로 노는 비례였다 — 아이콘 체크
   토글(.m-icon-check)과 같은 비례로 맞춰 나란히 놓는다. 네이티브 input 은 화면에서만
   숨기고 그대로 둔다 — 키보드·스크린리더는 이걸 그대로 쓴다. */
.m-check-row-group { display: flex; gap: 4px; }
.m-check-col { position: relative; flex: 1 1 0; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 6px; padding: 10px 2px; cursor: pointer; transition: background-color .15s ease; }
.m-check-input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.m-radio-dot {
  position: relative; width: 18px; height: 18px; flex: none; border-radius: 50%;
  border: 2px solid var(--color-neutral-500); transition: border-color .15s ease;
}
.m-radio-dot::after {
  content: ''; position: absolute; inset: 3px; border-radius: 50%; background: var(--color-accent);
  opacity: 0; transform: scale(.5); transition: opacity .15s ease, transform .15s ease;
}
.m-check-input:checked + .m-radio-dot { border-color: var(--color-accent); }
.m-check-input:checked + .m-radio-dot::after { opacity: 1; transform: scale(1); }
.m-check-input:focus-visible + .m-radio-dot { box-shadow: 0 0 0 3px var(--color-accent-100); }
.m-check-col-label { display: flex; align-items: center; gap: 2px; font-weight: 700; font-size: 16px; color: var(--color-neutral-900); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (hover: hover) {
  .m-check-col:hover, .m-save-row:hover { background-color: var(--color-neutral-300); }
}

/* 스플래시는 실제 앱 카드 안에서 재생한다. PC의 폰 미리보기에도 같은 에셋을 쓴다. */
.m-splash {
  position: absolute; inset: 0; z-index: 50; background: #f7f6f4;
  display: flex; align-items: center; justify-content: center;
  opacity: 1; transition: opacity .45s ease;
}
.m-splash-leaving { opacity: 0; pointer-events: none; }
.m-splash-storyboard { display: block; width: min(100%, 390px); height: auto; }
