/* BeBeam 플레이어 셸 (W-04)
   가로: [헤더·목록 320px | 뷰어]   세로: [뷰어 상단 40%] / [헤더] / [목록 스크롤] */

/* 기본 글꼴: Neo둥근모 Pro (SIL OFL 1.1, vendor/neodgm-pro). 오프라인용으로 SW가 precache한다 */
@font-face {
  font-family: "NeoDunggeunmo Pro";
  src: url("../vendor/neodgm-pro/NeoDunggeunmoPro-Regular.woff2") format("woff2");
  font-display: swap;
}

:root {
  /* shadcn/ui 기본 테마(zinc)의 값 */
  --bg: #ffffff;
  --surface: #ffffff;
  --text: #09090b;
  --muted: #71717a;
  --line: #e4e4e7;
  /* 대비(WCAG AA 4.5:1): --accent-text/--accent 17.7, --danger-text/--danger 4.83 */
  --accent: #18181b;
  --accent-text: #fafafa;
  --selected: #f4f4f5;
  --danger: #dc2626;
  --danger-text: #ffffff;
  --ring: #a1a1aa;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .05);
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .1), 0 2px 4px -2px rgba(0, 0, 0, .1);
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -4px rgba(0, 0, 0, .1);
  --viewer-bg: #000000;
  --viewer-text: #d4d4d8;
  --radius: 8px;
  --list-width: 320px;
  --header-h: 48px;
  --tap: 44px;
  font-family: "NeoDunggeunmo Pro", system-ui, -apple-system, "Apple SD Gothic Neo", "Malgun Gothic", sans-serif;
  font-size: 16px;
  font-synthesis: none;
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #09090b;
    --surface: #09090b;
    --text: #fafafa;
    --muted: #a1a1aa;
    --line: #27272a;
    --accent: #fafafa;
    --accent-text: #18181b;
    --selected: #27272a;
    --danger: #dc2626;
    --danger-text: #ffffff;
    --ring: #d4d4d8;
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);
    --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .4), 0 2px 4px -2px rgba(0, 0, 0, .4);
    --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, .5), 0 4px 6px -4px rgba(0, 0, 0, .5);
    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --bg: #09090b;
  --surface: #09090b;
  --text: #fafafa;
  --muted: #a1a1aa;
  --line: #27272a;
  --accent: #fafafa;
  --accent-text: #18181b;
  --selected: #27272a;
  --danger: #dc2626;
  --danger-text: #ffffff;
  --ring: #d4d4d8;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .4), 0 2px 4px -2px rgba(0, 0, 0, .4);
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, .5), 0 4px 6px -4px rgba(0, 0, 0, .5);
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  -webkit-text-size-adjust: 100%;
}

body { overflow: hidden; }

button { font: inherit; color: inherit; }

[hidden] { display: none !important; }

.shell {
  display: grid;
  height: 100vh;
  height: 100dvh;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  /* minmax(0, …): 긴 앱 이름(nowrap)이 열을 넓혀 화면 밖으로 밀어내지 않게 */
  grid-template-columns: var(--list-width) minmax(0, 1fr);
  grid-template-rows: var(--header-h) auto 1fr;
  /* 타이틀바·설치 배너는 목록 쪽에만 둔다. 뷰어는 위아래로 꽉 채운다 */
  grid-template-areas:
    "header viewer"
    "banner viewer"
    "library viewer";
}

.app-header {
  grid-area: header;
  display: flex;
  align-items: center;
  padding: 0 16px;
  border-bottom: 1px solid var(--line);
  border-right: 1px solid var(--line);
  background: var(--surface);
}

.brand { margin: 0; display: flex; align-items: center; gap: 8px; font-size: 1rem; font-weight: 400; }
.brand-icon { display: block; width: 24px; height: 24px; }
.header-actions { display: flex; gap: 4px; margin-left: auto; margin-right: -8px; }
/* ghost 아이콘 버튼 (shadcn size=icon) */
.icon-button {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}
.icon-button:hover { background: var(--selected); color: var(--text); }
.icon-button .icon { width: 20px; height: 20px; }

/* 선 아이콘 (js/ui/icons.js, lucide). 글자와 같은 색, 기본 16px */
.icon { flex: none; width: 16px; height: 16px; vertical-align: -3px; }

.viewer {
  grid-area: viewer;
  position: relative;
  display: grid;
  place-items: center;
  min-height: 0;
  background: var(--viewer-bg);
  color: var(--viewer-text);
  overflow: hidden;
}

.viewer-hint { margin: 0; padding: 16px; text-align: center; color: #8a8a94; }

.library {
  grid-area: library;
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-right: 1px solid var(--line);
  background: var(--surface);
}

.app-list {
  list-style: none;
  margin: 0;
  padding: 8px;
  overflow-y: auto;
  flex: 0 1 auto;
}

.empty { margin: 0; padding: 24px 16px 8px; color: var(--muted); text-align: center; line-height: 1.5; }

.library-footer { padding: 8px 8px 12px; }
.version { margin: 8px 0 0; text-align: center; color: var(--muted); font-variant-numeric: tabular-nums; }
.install-help {
  display: block;
  margin: 0 auto;
  min-height: var(--tap);
  padding: 0 12px;
  border: 0;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}
.install-help:hover { color: var(--text); text-decoration: underline; }

.footer-actions { display: flex; gap: 8px; }
.add-button, .receive-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: 0;
  white-space: nowrap;
  min-height: var(--tap);
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
}
/* [＋ 나의 앱 추가] 2/3 = primary, [앱 받기] 1/3 = outline */
.add-button { flex: 2; background: var(--accent); border-color: var(--accent); color: var(--accent-text); }
.receive-button { flex: 1; }
.add-button:hover { opacity: .9; }
.receive-button:hover { background: var(--selected); }

/* shadcn 포커스 링: 바탕색 2px 띄우고 링 2px */
:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }

.only-portrait { display: none; }

/* 세로: 뷰어 위, 목록 아래 */
@media (max-aspect-ratio: 1/1) {
  .shell {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(160px, 40%) var(--header-h) auto 1fr;
    grid-template-areas:
      "viewer"
      "header"
      "banner"
      "library";
  }
  .library, .app-header, .install-banner { border-right: 0; }
  .only-portrait { display: inline; }
  .only-landscape { display: none; }
}

/* ── 목록 항목 (F-03) ── */
.app-list li {
  display: flex;
  align-items: flex-start;
  gap: 4px;
  border-radius: var(--radius);
}
.app-list li + li { margin-top: 2px; }
.app-list li.selected { background: var(--selected); }

.app-item {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  min-height: 56px;
  padding: 8px;
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  text-align: left;
  cursor: pointer;
}
.app-list li:not(.selected) .app-item:hover { background: color-mix(in srgb, var(--selected) 50%, transparent); }

.app-icon {
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: var(--radius);
  object-fit: cover;
  background: var(--line);
}
.app-icon.large { width: 56px; height: 56px; border-radius: 12px; }

.app-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.app-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-name { color: var(--text); }
.app-desc {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  font-size: 14px;
  line-height: 1.35;
  color: var(--muted);
  word-break: keep-all; /* 한국어는 어절 단위로 줄바꿈 */
  overflow-wrap: anywhere;
}
.app-sender { unicode-bidi: isolate; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: right; font-size: 14px; color: var(--muted); }
.app-desc.none { font-style: italic; }

.app-menu-button {
  flex: none;
  margin-top: 6px;
  display: grid;
  place-items: center;
  width: var(--tap);
  height: var(--tap);
  border: 0;
  border-radius: var(--radius);
  background: transparent;
  font-size: 1.25rem;
  line-height: 1;
  color: var(--muted);
  cursor: pointer;
}
.app-menu-button:hover, .app-menu-button[aria-expanded="true"] { background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--text); }

/* ── 뷰어 (W-08 b) ── */
.viewer-card { position: relative; display: grid; justify-items: center; gap: 8px; padding: 16px; }
/* og:image 배경 (W-08 b): 검정 위에 어둡게 깔아 이름과 버튼이 잘 보이게 한다 */
.viewer-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: .55; pointer-events: none; user-select: none; }
/* 검은 뷰어 위 버튼은 테마와 무관하게 흰색 계열로 고정한다 */
.viewer-card .btn { width: min(240px, 70vw); }
.viewer-card .btn-primary { background: #fafafa; border-color: #fafafa; color: #18181b; }
.viewer-card .btn-outline { background: rgba(0, 0, 0, .35); border-color: rgba(255, 255, 255, .45); color: #fafafa; }
.viewer-card .btn:hover:not(:disabled) { opacity: .9; }
.play-button:disabled { opacity: .5; cursor: default; }
.viewer-name { margin: 0 0 4px; max-width: 90%; color: #fafafa; text-align: center; overflow-wrap: anywhere; text-shadow: 0 1px 4px rgba(0, 0, 0, .8); }

/* ── 뷰어 오류 (W-08 c) ── */
.viewer-error { max-width: 420px; text-align: center; }
.viewer-error p { margin: 0; }
.viewer-error-icon { color: #fbbf24; }
.viewer-error-icon .icon { width: 32px; height: 32px; }
.viewer-error-title { color: #fafafa; }
.viewer-error-message { color: #a1a1aa; line-height: 1.5; overflow-wrap: anywhere; }
.viewer-actions { display: flex; gap: 8px; justify-content: center; margin-top: 4px; }
.viewer-actions .btn { background: rgba(0, 0, 0, .35); border-color: rgba(255, 255, 255, .45); color: #fafafa; }
.viewer-actions .btn-danger { background: var(--danger); border-color: var(--danger); color: var(--danger-text); }
.viewer-logs { width: 100%; text-align: left; color: #a1a1aa; }
.viewer-logs pre { max-height: 30vh; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; margin: 6px 0 0; }

/* ── 실행 중 (W-09) ── */
.shell[data-screen="running"] { grid-template-columns: 1fr; grid-template-rows: 1fr; grid-template-areas: "viewer"; padding: 0; }
.shell[data-screen="running"] .app-header,
.shell[data-screen="running"] .install-banner,
.shell[data-screen="running"] .library { display: none; }

.viewer:fullscreen { width: 100vw; height: 100vh; }
.viewer.css-fullscreen {
  position: fixed;
  inset: 0;
  z-index: 40;
  width: 100vw;
  height: 100vh;
  height: 100dvh;
}
.run-stage { position: absolute; inset: 0; }
.app-frame { display: block; width: 100%; height: 100%; border: 0; background: #fff; }
.run-loading { position: absolute; margin: 0; color: #8a8a94; pointer-events: none; }
.app-frame + .run-loading, .run-stage:has(.app-frame) + .run-loading { display: none; }

.run-close {
  position: absolute;
  top: calc(8px + env(safe-area-inset-top));
  right: calc(8px + env(safe-area-inset-right));
  z-index: 2;
  width: var(--tap);
  height: var(--tap);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  font-size: 1.2rem;
  line-height: 1;
  opacity: .35;
  cursor: pointer;
  transition: opacity .15s;
}
.run-close:hover, .run-close:focus-visible, .run-close:active { opacity: 1; }

/* ── (⋯) 메뉴 (W-07) ── */
.menu {
  position: fixed;
  z-index: 50;
  min-width: 200px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-md);
}
.menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: var(--tap);
  padding: 0 8px;
  border: 0;
  border-radius: calc(var(--radius) - 2px);
  background: transparent;
  text-align: left;
  cursor: pointer;
}
.menu-item:hover:not(:disabled), .menu-item:focus-visible { background: var(--selected); outline: none; }
.menu-item:disabled { color: var(--muted); opacity: .6; cursor: default; }
.menu-item.danger { color: var(--danger); }
.menu-icon { color: var(--muted); }
.menu-item.danger .menu-icon { color: inherit; }
.menu-sep { height: 1px; margin: 4px -4px; background: var(--line); }

/* ── 설치 유도 배너 (W-02): 목록을 가리지 않도록 grid 한 행을 차지한다 ── */
.install-banner {
  grid-area: banner;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--line);
  border-right: 1px solid var(--line);
  background: var(--selected);
  font-size: 1rem;
}
.install-banner-text { margin: 0; line-height: 1.4; display: flex; align-items: flex-start; gap: 8px; }
.install-banner-text .icon { margin-top: 3px; }
.install-banner-actions { display: flex; gap: 8px; margin-left: auto; }

/* ── 설치 안내 (W-03): iOS는 Safari·Chrome 공용 3단계, 그 밖에는 브라우저 설치 메뉴 ── */
.ios-guide-steps { margin: 0; padding-left: 1.4em; line-height: 2; }
/* 단계 아이콘: 브라우저 메뉴 모양을 흉내 낸 선 그림 */
.guide-icon { width: 1.25em; height: 1.25em; vertical-align: -0.25em; fill: none; stroke: var(--accent); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ── 대화창 (W-06, W-10~W-13) ── */
.dialog {
  width: min(400px, calc(100vw - 32px));
  max-height: calc(100dvh - 32px);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-lg);
}
.dialog::backdrop { background: rgba(0, 0, 0, .8); }
.dialog-form { display: flex; flex-direction: column; gap: 16px; padding: 24px; }
.dialog-title { margin: 0; font-size: 1rem; font-weight: 400; }
.dialog-message { margin: 0; line-height: 1.5; color: var(--muted); overflow-wrap: anywhere; }
.dialog-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--tap);
  min-width: 80px;
  padding: 0 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-sm);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .15s, opacity .15s;
}
.btn:hover:not(:disabled) { background: var(--selected); }
.btn:disabled { opacity: .5; cursor: default; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }
.btn-primary:hover:not(:disabled) { background: var(--accent); opacity: .9; }
.btn-danger { background: var(--danger); border-color: var(--danger); color: var(--danger-text); }
.btn-danger:hover:not(:disabled) { background: var(--danger); opacity: .9; }

.text-input {
  width: 100%;
  min-height: var(--tap);
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: transparent;
  color: var(--text);
  box-shadow: var(--shadow-sm);
  font: inherit;
}
.text-input:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.field { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; border: 0; min-width: 0; }
.field-label { padding: 0; color: var(--text); }
.field-row { display: flex; gap: 8px; }
.field-row .text-input { flex: 1; min-width: 0; }
.field-row .btn { min-width: 0; }
.btn-square { width: var(--tap); padding: 0; flex: none; }
.field-desc { margin: 0; font-size: 14px; color: var(--muted); }
.radio-option { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius); cursor: pointer; }
.radio-option:has(input:checked) { border-color: var(--text); }
.radio-option input { margin: 4px 0 0; accent-color: var(--accent); }
.radio-text { display: flex; flex-direction: column; gap: 2px; }
.radio-desc { font-size: 14px; color: var(--muted); }
.counter { margin: -8px 0 0; text-align: right; color: var(--muted); }
.counter.over { color: var(--danger); }

.progress { width: 100%; height: 8px; accent-color: var(--accent); }

.install-head { display: flex; align-items: center; gap: 12px; }
.install-name { margin: 0; overflow-wrap: anywhere; }
.install-desc { margin: 0; color: var(--muted); overflow-wrap: anywhere; }
.install-stat { margin: 0; }
.muted { color: var(--muted); }
.warning {
  display: flex;
  gap: 10px;
  padding: 12px 16px;
  border: 1px solid color-mix(in srgb, #f59e0b 45%, transparent);
  border-radius: var(--radius);
  background: color-mix(in srgb, #f59e0b 10%, transparent);
  line-height: 1.45;
}
.warning p { margin: 0; overflow-wrap: anywhere; }

/* ── 앱 추가 시트 (W-05): 폰은 하단 시트, 넓은 화면은 가운데 ── */
.sheet-options { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.sheet-option {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 60px;
  padding: 8px 14px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  text-align: left;
  cursor: pointer;
}
.sheet-option:last-child { border-bottom: 0; }
.sheet-option { color: var(--text); }
.sheet-option:hover:not(:disabled) { background: var(--selected); }
.sheet-option:disabled { opacity: .5; cursor: default; }
.warning-icon { margin-top: 3px; color: #d97706; }
.sheet-icon { width: 20px; height: 20px; color: var(--muted); }
.sheet-text { display: flex; flex-direction: column; gap: 2px; }
.sheet-desc { color: var(--muted); }

@media (max-width: 600px) {
  .dialog.sheet {
    width: 100vw;
    max-width: 100vw;
    margin: auto 0 0;
    border-width: 1px 0 0;
    border-radius: 12px 12px 0 0;
    padding-bottom: env(safe-area-inset-bottom);
  }
}

/* ── 2.0 단방향 전송 (TASK M7) ──
   보내기: 흰 바탕에 짧은 변을 채우는 QR, 위 = "앱 보내는 중", 아래 = 안내·[속도]·[완료]. 가로면 QR 왼쪽, 정보 오른쪽.
   받기: 위 = 스캐너 정사각형(한 변 = 화면 세로의 1/2, 카메라 영상의 가운데 정사각형), 아래 = 전송 정보. */
.transfer {
  --pad: 16px;
  --safe-t: env(safe-area-inset-top);
  --safe-b: env(safe-area-inset-bottom);
  --safe-x: max(env(safe-area-inset-left), env(safe-area-inset-right));
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: calc(var(--safe-t) + 8px) calc(var(--safe-x) + var(--pad)) calc(var(--safe-b) + var(--pad));
  overflow: auto;
}
.transfer:focus { outline: none; } /* 열릴 때 컨테이너에 주는 포커스 (스크린 리더용) */
.tx-close {
  position: absolute;
  top: calc(var(--safe-t) + 10px);
  left: calc(var(--safe-x) + 10px);
  z-index: 2;
  width: 40px;
  height: 40px;
  border-radius: var(--radius);
  border: 1px solid rgba(127, 127, 127, .45);
  background: rgba(0, 0, 0, .55);
  color: #fff;
  font-size: 1.1rem;
  cursor: pointer;
}
.tx-close:focus-visible, .tx-switch:focus-visible { outline: 2px solid #a1a1aa; outline-offset: 2px; }

/* 보내기 */
.transfer.tx-send { --head: 56px; --foot: 150px; background: #fff; color: #23232b; justify-content: center; gap: 8px; }
.tx-send .tx-close { background: rgba(0, 0, 0, .06); color: #23232b; }
.tx-send-head { margin: 0; min-height: var(--head); padding: 0 48px; display: flex; align-items: center; justify-content: center; text-align: center; overflow-wrap: anywhere; }
.tx-send-sq { --side: min(100vw - 2 * var(--safe-x) - 2 * var(--pad), 100dvh - var(--safe-t) - var(--safe-b) - var(--head) - var(--foot) - 2 * var(--pad)); width: var(--side); height: var(--side); flex: none; }
.tx-qr { display: block; width: 100%; height: 100%; image-rendering: pixelated; }
.tx-send-side { display: contents; } /* 세로: 머리말은 QR 위, 안내·버튼은 아래 */
.tx-send-head { order: -1; }
.tx-send-info { display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; min-height: var(--foot); justify-content: flex-start; }
.tx-send-info p { margin: 0; line-height: 1.4; }
.tx-hint { color: #71717a; }
.tx-hint.warn { color: #b45309; }
.tx-send-actions { display: flex; gap: 8px; align-items: center; margin-top: 6px; }
.tx-speed { display: flex; align-items: center; gap: 8px; }
.tx-speed select { min-height: 44px; padding: 0 10px; border-radius: var(--radius); border: 1px solid #e4e4e7; background: #fff; color: #09090b; box-shadow: 0 1px 2px rgba(0, 0, 0, .05); font: inherit; }
.tx-send .btn { min-height: 44px; border-color: #e4e4e7; background: #fff; color: #09090b; }
.tx-send .btn-primary { border-color: #18181b; background: #18181b; color: #fafafa; }
@media (orientation: landscape) {
  .transfer.tx-send { flex-direction: row; justify-content: center; gap: 24px; }
  .tx-send-sq { --side: min(100dvh - var(--safe-t) - var(--safe-b) - 2 * var(--pad) - 8px, 60vw); order: 0; }
  .tx-send-head { order: 0; }
  .tx-send-side { display: flex; flex-direction: column; justify-content: center; gap: 8px; max-width: 320px; }
  .tx-send-head { padding: 0; min-height: 0; justify-content: flex-start; text-align: left; }
  .tx-send-info { align-items: flex-start; text-align: left; min-height: 0; }
}

/* 받기 */
.transfer.tx-recv { background: #000; color: #ececf1; gap: 14px; }
.tx-scan {
  --side: min(50dvh, 100vw - 2 * var(--safe-x) - 2 * var(--pad));
  position: relative;
  width: var(--side);
  height: var(--side);
  flex: none;
  margin-top: 48px; /* ✕·카메라 전환 버튼 줄 */
  border-radius: 14px;
  overflow: hidden;
  background: #16161b;
}
/* 정사각형 칸에 cover로 넣으면 영상의 가운데 정사각형이 보인다 = 디코더가 읽는 영역 (link.js centerCrop) */
.tx-preview { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.tx-preview.mirrored { transform: scaleX(-1); }
.tx-guide {
  --g: rgba(255, 255, 255, .92);
  --gl: 30px;
  position: absolute;
  inset: 8%;
  border-radius: 10px;
  pointer-events: none;
  background:
    linear-gradient(var(--g) 0 0) 0 0 / var(--gl) 4px, linear-gradient(var(--g) 0 0) 0 0 / 4px var(--gl),
    linear-gradient(var(--g) 0 0) 100% 0 / var(--gl) 4px, linear-gradient(var(--g) 0 0) 100% 0 / 4px var(--gl),
    linear-gradient(var(--g) 0 0) 0 100% / var(--gl) 4px, linear-gradient(var(--g) 0 0) 0 100% / 4px var(--gl),
    linear-gradient(var(--g) 0 0) 100% 100% / var(--gl) 4px, linear-gradient(var(--g) 0 0) 100% 100% / 4px var(--gl);
  background-repeat: no-repeat;
}
.tx-scan.hit .tx-guide { --g: #5fd4ff; }
.tx-switch {
  position: absolute;
  top: calc(var(--safe-t) + 10px);
  right: calc(var(--safe-x) + 10px);
  z-index: 2;
  min-height: 40px;
  padding: 0 12px;
  border-radius: var(--radius);
  border: 1px solid rgba(255, 255, 255, .35);
  background: rgba(0, 0, 0, .55);
  color: #fff;
  font: inherit;
  cursor: pointer;
}
.tx-info { width: var(--info-w, min(100%, 480px)); display: flex; flex-direction: column; gap: 8px; text-align: center; }
.tx-info p { margin: 0; line-height: 1.4; overflow-wrap: anywhere; }
.tx-headline { color: #fafafa; }
.tx-headline .icon, .tx-send-head .icon { margin-right: 6px; }
.tx-switch { display: inline-flex; align-items: center; gap: 6px; }
.tx-close, .run-close { display: inline-grid; place-items: center; }
.tx-sub { color: #a1a1aa; font-variant-numeric: tabular-nums; }
.tx-sub.warn { color: #fbbf24; }
.tx-bar { height: 8px; border-radius: 4px; background: #27272a; overflow: hidden; }
.tx-bar-fill { height: 100%; width: 0; border-radius: 4px; background: #fafafa; transition: width .3s ease-out; }
.tx-diag { font: 11px/1.4 ui-monospace, monospace; color: #8a8a96; white-space: pre-wrap; text-align: left; }

/* 끝난 뒤의 버튼과 설명은 스캐너 칸 위에 띄운다 */
.tx-panel {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 12px;
  overflow: auto;
  background: rgba(10, 10, 14, .82);
  text-align: center;
}
.tx-detail { white-space: pre-line; color: #d4d4d8; line-height: 1.45; overflow-wrap: anywhere; }
.tx-detail p { margin: 0; unicode-bidi: isolate; }
.tx-detail.lines p:first-child { color: #fff; margin-bottom: 4px; }
.tx-detail:empty { display: none; }
.tx-panel[hidden] { display: none; }
.tx-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.tx-actions .btn { border-color: #27272a; background: #09090b; color: #fafafa; }
.tx-actions .btn:hover:not(:disabled) { background: #27272a; }
.tx-actions .btn-primary, .tx-actions .btn-primary:hover:not(:disabled) { border-color: #fafafa; background: #fafafa; color: #18181b; }

.notice {
  position: fixed;
  left: 50%;
  bottom: calc(16px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  /* left:50%면 남은 폭이 절반이라 짧은 문구도 줄바꿈된다. 내용 폭을 쓰고 화면 안으로 제한 */
  width: max-content;
  max-width: min(480px, calc(100vw - 32px));
  padding: 12px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-lg);
  line-height: 1.4;
  z-index: 100;
}

/* 버튼이 있는 안내(새 버전)는 화면 가운데에 반전 색으로 띄운다 */
.notice:has(.notice-action) {
  display: flex;
  align-items: center;
  gap: 16px;
  top: 50%;
  bottom: auto;
  transform: translate(-50%, -50%);
  padding: 16px 20px;
  border-color: var(--text);
  background: var(--text);
  color: var(--bg);
  /* 검은 뷰어 위에서도 테두리가 보이게 바깥에 옅은 링 */
  box-shadow: 0 0 0 1px var(--line), var(--shadow-lg);
}

.notice-action {
  flex: none;
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid var(--bg);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  white-space: nowrap;
  cursor: pointer;
}
.notice-action:hover { opacity: .9; }

/* 세로 화면: 글자가 잘리지 않게 버튼을 다음 줄에 꽉 채운다 */
@media (max-aspect-ratio: 1/1) {
  .notice:has(.notice-action) { flex-direction: column; align-items: stretch; text-align: center; gap: 12px; }
}
