/* ==========================================================================
   우리의 영화관 — W3 UI 스타일
   톤: 따뜻한 극장(짙은 청록 밤 + 크림 종이 + 놋쇠 금) · 마스코트 = 윤기 구체 + 캡슐 눈
   구조: 모바일 우선(기본 = 좁은 화면), 900px 이상에서 2단 작업대로 확장
   레이어: 무대 오버레이 2~4 < 랜딩 6 < 투영 플레이어 8 < 토스트 40 < dialog(top layer)
   ========================================================================== */

:root {
  color-scheme: dark;

  /* 팔레트 (shared/world.js THEME와 같은 계열) */
  --night: #070d10;
  --night-2: #0b1418;
  --night-3: #101c21;
  --ink: #1d1a17;
  --ink-soft: #4c443c;
  --ink-mute: #7d7266;
  --paper: #f7efe2;
  --paper-2: #fdf8ee;
  --paper-line: #e4d6c2;
  --brass: #c9a063;
  --brass-bright: #e3bd83;
  --coral: #e08c73;
  --teal: #7fb6b0;
  --teal-bright: #9fd8d2;
  --maroon: #4a3330;
  --warm: #ffd9ab;
  --danger: #d98a76;

  --radius-s: 10px;
  --radius-m: 14px;
  --radius-l: 20px;
  --radius-xl: 26px;

  --shadow-panel: 0 12px 34px rgba(0, 0, 0, .26);
  --shadow-float: 0 20px 60px rgba(0, 0, 0, .42);

  --sans: 'Noto Sans KR', system-ui, sans-serif;
  --latin: 'DM Sans', var(--sans);

  --pad: 16px;
  --topbar-h: 58px;
  --ease: cubic-bezier(.22, .8, .3, 1);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  min-height: 100%;
}

body {
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  color: #f6efe3;
  background:
    radial-gradient(1200px 600px at 8% -10%, rgba(127, 182, 176, .14), transparent 60%),
    radial-gradient(900px 520px at 105% 0%, rgba(224, 140, 115, .12), transparent 55%),
    linear-gradient(180deg, var(--night-2), var(--night) 62%);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

button, input, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }
button:disabled { cursor: not-allowed; opacity: .48; }
[hidden] { display: none !important; }

:focus-visible {
  outline: 3px solid var(--teal-bright);
  outline-offset: 3px;
  border-radius: 6px;
}

::selection { background: rgba(201, 160, 99, .38); }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

kbd {
  display: inline-block;
  min-width: 18px;
  padding: 1px 5px;
  color: #f4ead9;
  border: 1px solid rgba(255, 245, 230, .22);
  border-bottom-width: 2px;
  border-radius: 5px;
  background: rgba(255, 245, 230, .08);
  font: 600 11px/1.5 var(--latin);
  text-align: center;
}

/* --------------------------------------------------------------------------
   마스코트: 윤기 나는 검은 구체 + 오른쪽 위로 몰린 흰 캡슐 눈
-------------------------------------------------------------------------- */
.orb {
  position: relative;
  display: inline-block;
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 26%, rgba(255, 255, 255, .5), rgba(255, 255, 255, 0) 34%),
    radial-gradient(circle at 68% 82%, #2a3540, #10161b 58%, #070a0d 100%);
  box-shadow:
    inset 0 -2px 4px rgba(0, 0, 0, .6),
    0 0 0 1px rgba(201, 160, 99, .28),
    0 4px 14px rgba(0, 0, 0, .38);
}

.orb::before,
.orb::after {
  content: '';
  position: absolute;
  top: 30%;
  width: 14%;
  height: 26%;
  border-radius: 999px;
  background: linear-gradient(180deg, #fffdf7, #e6ded1);
  transform: rotate(10deg);
}

.orb::before { left: 44%; }
.orb::after { left: 64%; }

.orb-hero { width: 62px; height: 62px; }
.orb-large { width: 74px; height: 74px; margin-bottom: 12px; }
.orb-small { width: 20px; height: 20px; }
.orb-tiny { width: 16px; height: 16px; }

/* --------------------------------------------------------------------------
   상단 바
-------------------------------------------------------------------------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    'brand room'
    'actions actions';
  align-items: center;
  gap: 8px 12px;
  padding: 10px var(--pad);
  border-bottom: 1px solid rgba(201, 160, 99, .16);
  background: rgba(7, 13, 16, .88);
  backdrop-filter: blur(18px);
}

.brand {
  grid-area: brand;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: #fbf3e5;
  text-decoration: none;
  font-weight: 800;
  letter-spacing: -.03em;
}

.brand-orb { width: 32px; height: 32px; }

.brand-copy { font-size: 15px; line-height: 1.15; }
.brand-copy small {
  display: block;
  margin-top: 2px;
  color: rgba(201, 160, 99, .85);
  font: 700 8px/1 var(--latin);
  letter-spacing: .2em;
}

.topbar-room {
  grid-area: room;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
}

.room-name {
  max-width: 100%;
  overflow: hidden;
  color: #f3e6d3;
  font-size: 13px;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.viewer-count {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px;
  color: #e7dcca;
  border: 1px solid rgba(201, 160, 99, .26);
  border-radius: 999px;
  background: rgba(201, 160, 99, .08);
  font: 600 11px/1.6 var(--latin);
  white-space: nowrap;
}

.viewer-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--teal-bright);
  box-shadow: 0 0 8px rgba(159, 216, 210, .9);
}

.connection {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: #b9cfc9;
  font-size: 11px;
  white-space: nowrap;
}

.connection::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--teal);
}

.connection[data-tone="ok"] { color: #a9d8c4; }
.connection[data-tone="ok"]::before { background: #86cfa6; box-shadow: 0 0 8px #86cfa6; }
.connection[data-tone="warn"] { color: var(--warm); }
.connection[data-tone="warn"]::before { background: var(--warm); animation: pulse 1.4s infinite; }
.connection[data-tone="error"] { color: #f0a795; }
.connection[data-tone="error"]::before { background: var(--danger); }

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .3; }
}

.topbar-actions {
  grid-area: actions;
  display: flex;
  align-items: center;
  gap: 6px;
  overflow-x: auto;
  padding-bottom: 2px;
  scrollbar-width: none;
}

.topbar-actions::-webkit-scrollbar { display: none; }

.icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  min-height: 34px;
  min-width: 34px;
  padding: 6px 8px;
  color: #efe6d8;
  border: 1px solid rgba(235, 220, 198, .2);
  border-radius: 10px;
  background: rgba(255, 247, 233, .06);
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  transition: background .16s, border-color .16s, transform .16s;
}

.icon-button svg {
  width: 17px;
  height: 17px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.icon-button:hover { background: rgba(255, 247, 233, .12); border-color: rgba(235, 220, 198, .34); }
.icon-button:active { transform: translateY(1px); }
.icon-button.danger { color: #f0b4a4; border-color: rgba(217, 138, 118, .3); }
.icon-button.danger:hover { background: rgba(217, 138, 118, .16); }
.icon-button kbd { margin-left: 2px; font-size: 9px; }

.icon-button.labeled span { display: none; }

/* 버튼 기본 */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 38px;
  padding: 8px 14px;
  border: 0;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: -.01em;
  transition: background .16s, color .16s, border-color .16s, transform .16s;
}

.button-brass {
  color: #241a10;
  background: linear-gradient(180deg, var(--brass-bright), var(--brass));
  box-shadow: 0 4px 14px rgba(201, 160, 99, .22);
}

.button-brass:hover { background: linear-gradient(180deg, #efcc94, #d3ab6e); }

.button-ghost {
  color: #e9dfd0;
  border: 1px solid rgba(235, 220, 198, .22);
  background: rgba(255, 247, 233, .06);
}

.button-ghost:hover { background: rgba(255, 247, 233, .13); }

.button-outline {
  color: #ead9bf;
  border: 1px solid rgba(235, 220, 198, .3);
  background: transparent;
}

.button-outline:hover { background: rgba(255, 247, 233, .09); }

/* --------------------------------------------------------------------------
   작업대
-------------------------------------------------------------------------- */
/* 게임 화면 하나가 작업대 전체를 쓴다 — 오른쪽 대화 레일은 없앴다. */
.workspace {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 12px var(--pad) 22px;
}

.stage-column { flex: 1; min-width: 0; }

.stage-wrap {
  position: relative;
  height: clamp(340px, 56vh, 480px);
  overflow: hidden;
  border: 1px solid rgba(201, 160, 99, .2);
  border-radius: var(--radius-l);
  background: #05090b;
  box-shadow: var(--shadow-panel);
  isolation: isolate;
}

.cinema-scene {
  position: absolute;
  inset: 0;
  /* 3D 장면 전체(배경·CSS3D·캔버스)를 한 덩어리 스택으로 묶는다.
     내부 순서: backdrop 0 < css3d 2 < 캔버스 3 < 구멍 위 오버레이 4.
     무대 위 텍스트/HUD(z 3+)는 이 묶음보다 위에 놓인다. */
  z-index: 2;
  overflow: hidden;
}

.cinema-scene canvas {
  /* 캔버스는 CSS3D 판보다 **위**여야 구멍으로만 영상이 보인다. position 이 없으면
     z-index 가 무시돼 CSS3D(z 2)가 캔버스를 덮어 영상이 3D 앞에 떠 버린다. */
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
}

/* CSS3D 스크린 레이어: WebGL 캔버스 **뒤**(z 2 < 캔버스 3). 캔버스에 뚫린 스크린 구멍으로만
   YouTube iframe 이 보인다. 포인터는 받지 않는다 — 카메라 조작은 캔버스가 계속 담당.
   적층 순서(체크리스트 P0-3): backdrop 0 / 베일 1 / css3d 2 / 캔버스 3 / UI 4+. */
.cinema-css3d {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  overflow: hidden;
}
.cinema-css3d > div { pointer-events: none; }

/* 스크린 평면 컨테이너: 검은 몸체 + 16:9 레터박스. YouTube 제목/끝 화면이 새지 않게 자른다.
   변환이 매 프레임 갱신되므로 will-change 로 승격해 재래스터화 떨림을 막는다. */
.cinema-screen-portal {
  background: #000;
  overflow: hidden;
  will-change: transform;
}
.cinema-screen-portal > * { will-change: transform; }
/* 영상이 없을 때는 iframe 을 노출하지 않는다(빈 썸네일·흰 화면 방지). */
.cinema-screen-portal:not(.has-video) iframe { visibility: hidden; }
/* 로딩/커버 전환 중: YouTube 썸네일·흰 플래시를 가린다. */
.cinema-screen-portal.yt-wait iframe { opacity: 0; }
.cinema-screen-portal-fit { overflow: hidden; background: #000; }
.cinema-screen-portal-fit iframe {
  width: 100% !important;
  height: 100% !important;
  border: 0;
  pointer-events: none;
}

/* 자동재생이 막혔을 때만 나타나는 '재생' 버튼(캔버스 위 레이어). */
.cinema-screen-overlay { pointer-events: none; }
.screen-play-nudge {
  min-width: 84px;
  padding: 13px 26px;
  border: 1px solid rgba(255, 236, 200, .55);
  border-radius: 999px;
  color: #10201e;
  background: rgba(255, 240, 214, .94);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .5);
  font: 700 15px/1 var(--sans, system-ui, sans-serif);
  letter-spacing: .02em;
  cursor: pointer;
  pointer-events: auto;
}
.screen-play-nudge:hover { background: #fff6e4; }

/* 무대 위 그라데이션 베일 (가독성). CSS3D 레이어(z 2)보다 아래(z 1)에 두어
   YouTube 영상만 어두워지는 일이 없게 한다(카메라 씬은 캔버스가 z 2 로 덮는다). */
.stage-wrap::after {
  content: '';
  position: absolute;
  z-index: 1;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(5, 9, 11, .68), transparent 26%),
    linear-gradient(0deg, rgba(5, 9, 11, .6), transparent 24%);
}

/* 무대 위 텍스트 — 투영 중에는 숨긴다(영상이 제목을 덮는 결함 방지) */
.stage-heading {
  position: absolute;
  z-index: 2;
  top: 18px;
  left: 18px;
  max-width: min(64%, 430px);
  pointer-events: none;
  text-shadow: 0 2px 20px rgba(0, 0, 0, .55);
  transition: opacity .25s var(--ease);
}

.eyebrow,
.mini-label {
  color: rgba(201, 160, 99, .95);
  font: 700 10px/1.4 var(--latin);
  letter-spacing: .2em;
}

.stage-heading h1 {
  margin: 6px 0 0;
  color: #fdf6e9;
  font-size: clamp(24px, 5.4vw, 40px);
  font-weight: 800;
  line-height: 1.16;
  letter-spacing: -.055em;
}

.stage-heading p {
  margin: 8px 0 0;
  color: #d6d0c4;
  font-size: 13px;
}

.live-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 6px;
  border-radius: 50%;
  background: var(--coral);
  box-shadow: 0 0 9px rgba(224, 140, 115, .85);
  vertical-align: middle;
}

.scene-badge {
  position: absolute;
  z-index: 2;
  top: 18px;
  right: 18px;
  display: none;
  padding: 7px 12px;
  color: #f2e6d4;
  border: 1px solid rgba(201, 160, 99, .32);
  border-radius: 999px;
  background: rgba(8, 14, 17, .62);
  font: 700 9px/1 var(--latin);
  letter-spacing: .16em;
  backdrop-filter: blur(10px);
}

.zone-badge {
  position: absolute;
  z-index: 3;
  top: 14px;
  left: 14px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: calc(100% - 28px);
  padding: 5px 11px;
  color: #f0e5d3;
  border: 1px solid rgba(201, 160, 99, .26);
  border-radius: 999px;
  background: rgba(8, 14, 17, .6);
  font-size: 11px;
  font-weight: 700;
  backdrop-filter: blur(10px);
}

/* 구역 배지 안의 '상영관 선택' 버튼 — 누르면 상영관 선택 시트가 열린다(공용 상영관일 때만). */
.zone-badge-hall {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  min-width: 0;
  padding: 1px 2px 1px 6px;
  color: var(--teal-bright);
  border: 0;
  border-left: 1px solid rgba(201, 160, 99, .28);
  border-radius: 0 999px 999px 0;
  background: transparent;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.zone-badge-hall:hover,
.zone-badge-hall:focus-visible {
  color: #cdeeea;
  outline: none;
}
.zone-badge-hall:hover .instance-label { text-decoration: underline; text-underline-offset: 2px; }

.zone-badge-cue {
  color: rgba(201, 160, 99, .8);
  font-size: 9px;
  line-height: 1;
}

.zone-badge .live-dot { margin-right: 0; width: 5px; height: 5px; }

.instance-label {
  color: var(--teal-bright);
  font-weight: 600;
}

.scene-help {
  position: absolute;
  z-index: 2;
  bottom: 14px;
  left: 50%;
  transform: translateX(-50%);
  display: none;
  padding: 6px 12px;
  color: #eee6d8;
  border: 1px solid rgba(255, 245, 230, .16);
  border-radius: 999px;
  background: rgba(8, 14, 17, .6);
  font-size: 11px;
  white-space: nowrap;
  pointer-events: none;
  backdrop-filter: blur(10px);
}

.stage-caption {
  position: absolute;
  z-index: 2;
  right: 18px;
  bottom: 16px;
  display: none;
  gap: 14px;
  color: #b7ada0;
  font-size: 11px;
  pointer-events: none;
}

.stage-caption span:first-child { color: #ecdfc9; font-weight: 700; }

/* 투영 중: 무대 위 장식 텍스트는 숨겨 영상과 겹치지 않게 한다.
   HUD 는 이제 재생·음량·예약의 유일한 조작판이므로 숨기지 않고 살짝 죽여 둔다
   (마우스를 올리거나 포커스가 들어오면 원래 밝기). */
.stage-wrap.is-projected .stage-heading,
.stage-wrap.is-projected .zone-badge,
.stage-wrap.is-projected .scene-badge,
.stage-wrap.is-projected .scene-help,
.stage-wrap.is-projected .stage-caption,
.stage-wrap.is-projected .mobile-stage-controls {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.stage-wrap.is-projected .theater-hud {
  opacity: .72;
  transition: opacity .2s var(--ease);
}

.stage-wrap.is-projected .theater-hud:hover,
.stage-wrap.is-projected .theater-hud:focus-within { opacity: 1; }

/* --------------------------------------------------------------------------
   상영관 HUD
   · 기본(모바일): 화면 아래 띠. 조이스틱·버튼과 겹치지 않게 높이를 --hud-offset 으로 알린다.
   · 넓은 화면: 화면 왼쪽에 세로로 붙는 패널(폭 --hud-w). 대화 목록만 안에서 스크롤한다.
-------------------------------------------------------------------------- */
.theater-hud {
  position: absolute;
  z-index: 4;
  left: 12px;
  right: 12px;
  bottom: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  padding: 10px;
  color: #f2e9dc;
  border: 1px solid rgba(201, 160, 99, .24);
  border-radius: var(--radius-m);
  background: rgba(8, 14, 17, .84);
  box-shadow: var(--shadow-panel);
  backdrop-filter: blur(16px);
  transition: opacity .25s var(--ease);
}

/* 접기/펼치기 머리줄: 데스크톱 패널에서만 보인다. */
.hud-head {
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.hud-title {
  color: rgba(201, 160, 99, .95);
  font: 700 9px/1.4 var(--latin);
  letter-spacing: .18em;
  text-transform: uppercase;
}

.hud-collapse {
  flex: none;
  width: 24px;
  height: 22px;
  padding: 0;
  color: #d9cbb7;
  border: 1px solid rgba(235, 220, 198, .18);
  border-radius: 7px;
  background: transparent;
  font-size: 11px;
  line-height: 1;
}
.hud-collapse:hover { background: rgba(255, 247, 233, .12); }

/* 접었을 때 왼쪽 가장자리에 남는 손잡이. */
.hud-restore {
  position: absolute;
  z-index: 4;
  left: 0;
  top: 50%;
  display: none;
  padding: 10px 8px;
  color: #f2e9dc;
  border: 1px solid rgba(201, 160, 99, .3);
  border-left: 0;
  border-radius: 0 10px 10px 0;
  background: rgba(8, 14, 17, .88);
  font-size: 11px;
  font-weight: 700;
  transform: translateY(-50%);
  backdrop-filter: blur(12px);
}
.hud-restore:hover { background: rgba(201, 160, 99, .22); }

/* 조작 바 접힘: 화면을 가리지 않고 손잡이만 남긴다. */
.stage-wrap.hud-collapsed .theater-hud { display: none; }
.stage-wrap.hud-collapsed .hud-restore { display: inline-flex; }

.hud-playback {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}

/* 2줄: 소리·건너뛰기·크게 보기·시점·얼굴. 폭이 모자라면 같은 줄에서 줄바꿈한다. */
.hud-tools {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}

.hud-time {
  color: #b9b0a3;
  font: 600 11px/1 var(--latin);
  font-variant-numeric: tabular-nums;
}

.hud-playback input[type="range"] {
  flex: 1;
  min-width: 30px;
  accent-color: var(--teal);
}

.hud-button {
  flex: none;
  min-width: 32px;
  height: 30px;
  padding: 0 8px;
  color: #f2e9dc;
  border: 1px solid rgba(235, 220, 198, .2);
  border-radius: 8px;
  background: rgba(255, 247, 233, .07);
  font-size: 12px;
  line-height: 1;
}

.hud-button:hover { background: rgba(255, 247, 233, .14); }
.hud-skip { color: var(--warm); }
.skip-votes { color: var(--warm); font-size: 10px; }

/* 내 소리: 음소거 버튼 + ▾ (위로 펼쳐지는 세로 볼륨 슬라이더 — 첫 줄 폭을 먹지 않는다). */
.hud-audio { position: relative; display: flex; flex: none; }

.hud-volume-toggle {
  min-width: 18px;
  padding: 0 3px;
  border-left: 0;
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  font-size: 9px;
}

.hud-volume-pop {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: calc(100% + 8px);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 132px;
  padding: 10px 0;
  border: 1px solid rgba(201, 160, 99, .32);
  border-radius: 12px;
  background: rgba(8, 14, 17, .96);
  box-shadow: var(--shadow-panel);
  transform: translateX(-50%);
}

/* 세로 슬라이더: range 를 90° 돌리고 폭·높이를 맞바꾼다. */
.hud-volume-pop input[type="range"] {
  width: 104px;
  height: 18px;
  margin: 0;
  accent-color: var(--teal);
  transform: rotate(-90deg);
}

/* 예약 개수 배지 겸 펼치기 버튼 */
.hud-queue-toggle {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  color: #e9dfd0;
}

.hud-queue-badge {
  display: inline-grid;
  place-items: center;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  color: #1b120a;
  border-radius: 999px;
  background: var(--brass);
  font: 700 9px/1 var(--latin);
}

.hud-queue-toggle[aria-expanded="true"] {
  border-color: rgba(201, 160, 99, .6);
  background: rgba(201, 160, 99, .18);
}

/* 관객 안내: 링크 입력 줄 바로 아래 한 줄(운영자·스태프에게는 숨긴다). */
.hud-viewer-note {
  margin: -2px 0 0;
  padding: 5px 9px;
  color: #f0cf9c;
  border-radius: 8px;
  background: rgba(201, 160, 99, .13);
  font-size: 10.5px;
  line-height: 1.4;
}

/* 예약 목록(접이식): '#queue-toggle' 로 펼치고 링크 줄 아래에 놓는다. */
.hud-queue {
  min-width: 0;
  margin: 0;
  padding: 8px 9px;
  border: 1px solid rgba(201, 160, 99, .22);
  border-radius: 10px;
  background: rgba(255, 248, 236, .05);
}

.hud-queue-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  flex-wrap: wrap;
}

.hud-queue-head h3 {
  margin: 0;
  color: #efe4d3;
  font-size: 11.5px;
  font-weight: 800;
}

.hud-queue-head h3 span {
  display: inline-block;
  min-width: 18px;
  margin-left: 3px;
  padding: 1px 6px;
  color: #241a10;
  border-radius: 999px;
  background: var(--brass);
  font: 700 10px/1.6 var(--latin);
  text-align: center;
}

.hud-queue-actions { display: flex; gap: 4px; }

.hud-queue-action {
  padding: 4px 7px;
  color: #e2d6c4;
  border: 1px solid rgba(235, 220, 198, .2);
  border-radius: 7px;
  background: transparent;
  font-size: 10.5px;
  font-weight: 600;
}
.hud-queue-action:hover { background: rgba(255, 247, 233, .1); }
.hud-queue-action:disabled { color: rgba(242, 233, 220, .32); border-color: rgba(235, 220, 198, .12); }

.queue-list {
  list-style: none;
  max-height: 104px;
  overflow-y: auto;
  margin: 7px 0 0;
  padding: 0;
  scrollbar-width: thin;
}

.queue-list li {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 6px 0;
  border-top: 1px solid rgba(235, 220, 198, .12);
  font-size: 11.5px;
  color: #ddd3c4;
}

.queue-list li:first-child { border-top: 0; }

.queue-index {
  flex: none;
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  color: #f1e6d3;
  border-radius: 50%;
  background: rgba(201, 160, 99, .26);
  font: 700 10px/1 var(--latin);
}

.queue-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.queue-by { color: #9aa5a1; font-size: 10px; }

.queue-remove {
  flex: none;
  padding: 3px 6px;
  color: #f0b4a4;
  border: 0;
  border-radius: 6px;
  background: transparent;
  font-size: 10.5px;
}
.queue-remove:hover { background: rgba(217, 138, 118, .16); }
.queue-remove:disabled { color: rgba(242, 233, 220, .3); }

.queue-empty { margin: 7px 0 0; color: #9aa5a1; font-size: 11px; line-height: 1.5; }

.queue-note {
  margin: 7px 0 0;
  color: #f0cf9c;
  font-size: 10.5px;
  line-height: 1.45;
}
.queue-note:empty { display: none; }

/* 이미 건너뛰기에 동의한 상태 */
.hud-button.is-voted,
.icon-button.is-voted {
  color: #241a10;
  border-color: var(--brass);
  background: var(--brass);
}
.icon-button.is-voted { color: #241a10; }

.hud-video { display: flex; flex-wrap: wrap; gap: 6px; }

.hud-video input {
  flex: 1;
  min-width: 0;
  height: 36px;
  padding: 0 11px;
  color: #f5ecdf;
  border: 1px solid rgba(235, 220, 198, .2);
  border-radius: 9px;
  background: rgba(255, 248, 236, .07);
  font-size: 13px;
}

.hud-video .button { min-height: 36px; padding: 0 12px; font-size: 12px; }

.hud-video input::placeholder { color: #8f9a98; }

/* 리액션 수신 표시(보내는 버튼은 2026-11-01 에 없앴다 — 서버 이벤트를 여기로 흘려보내면
   engine/avatar.js 가 이 노드를 지켜보며 아바타 표정을 짓는다). */
.reaction-toasts {
  position: absolute;
  z-index: 3;
  left: 50%;
  bottom: 122px;
  display: grid;
  gap: 4px;
  transform: translateX(-50%);
  pointer-events: none;
  text-align: center;
}

.reaction-toast {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  color: #fff6e8;
  border: 1px solid rgba(201, 160, 99, .3);
  border-radius: 999px;
  background: rgba(12, 18, 22, .9);
  font-size: 14px;
  animation: reaction-pop .32s var(--ease);
}

@keyframes reaction-pop {
  from { opacity: 0; transform: translateY(10px) scale(.88); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

/* 모바일 조작 */
.mobile-stage-controls {
  position: absolute;
  z-index: 5;
  /* 상영관 HUD는 아래쪽을 넓게 차지한다. 겹치면 버튼이 눌리지 않으므로 HUD 높이(--hud-offset)만큼 띄운다. */
  inset: auto 0 calc(12px + var(--hud-offset, 0px));
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  padding: 0 12px;
  pointer-events: none;
}

.joystick-guide {
  position: relative;
  width: 96px;
  height: 96px;
  border: 1px solid rgba(255, 245, 230, .18);
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, rgba(201, 160, 99, .16), rgba(8, 14, 17, .28) 62%);
  backdrop-filter: blur(4px);
}

.joystick-knob {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 30%, rgba(255, 255, 255, .38), transparent 42%),
    #1a2228;
  box-shadow: 0 4px 12px rgba(0, 0, 0, .5), 0 0 0 1px rgba(201, 160, 99, .34);
  transform: translate(-50%, -50%);
}

.joystick-arrow {
  position: absolute;
  width: 0;
  height: 0;
  border: 5px solid transparent;
  opacity: .55;
}
.joystick-arrow.up { top: 8px; left: 50%; margin-left: -5px; border-bottom-color: #e8dcc8; border-top-width: 0; }
.joystick-arrow.down { bottom: 8px; left: 50%; margin-left: -5px; border-top-color: #e8dcc8; border-bottom-width: 0; }
.joystick-arrow.left { left: 8px; top: 50%; margin-top: -5px; border-right-color: #e8dcc8; border-left-width: 0; }
.joystick-arrow.right { right: 8px; top: 50%; margin-top: -5px; border-left-color: #e8dcc8; border-right-width: 0; }

.mobile-actions {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
  /* 왼쪽 조이스틱 폭만 비켜 주고, 나머지는 버튼 넷이 쓰게 한다. */
  max-width: calc(100% - 96px);
  pointer-events: auto;
}

.mobile-action {
  min-width: 52px;
  min-height: 44px;
  padding: 8px 10px;
  color: #f6ecdd;
  border: 1px solid rgba(201, 160, 99, .36);
  border-radius: 13px;
  background: rgba(10, 17, 21, .82);
  font-size: 12px;
  font-weight: 700;
  backdrop-filter: blur(8px);
}

.mobile-action[aria-pressed="true"] { color: #241a10; background: var(--brass); }
.mobile-action:active { transform: scale(.95); }

/* 시점 버튼도 눌린 상태(3인칭)를 분명히 보여 준다. */
#camera-toggle-mobile[aria-pressed="true"],
#camera-toggle-hud[aria-pressed="true"] {
  color: #241a10;
  border-color: var(--brass);
  background: var(--brass);
}

/* 얼굴 보기(C): 3인칭에서만 쓸 수 있으므로 1인칭이면 흐리게 보인다. */
.hud-face,
#face-view-mobile {
  color: var(--brass);
  border-color: rgba(201, 160, 99, .5);
}

.hud-face:disabled,
#face-view-mobile:disabled {
  color: rgba(242, 233, 220, .34);
  border-color: rgba(235, 220, 198, .14);
}

.hud-face:disabled:hover { background: rgba(255, 247, 233, .07); }

/* 좁은 화면에서는 재생 바가 한 줄에 다 들어가지 않는다. HUD의 시점·얼굴 버튼은 숨기고
   모바일 조작 버튼(camera-toggle-mobile·face-view-mobile)으로 조작한다.
   폭이 넓어도 주 입력이 터치(가로로 눕힌 폰)면 같은 규칙을 쓴다 — 시점·얼굴 버튼이
   무대 안 조작 줄과 HUD 양쪽에 겹쳐 뜨지 않게. */
@media (max-width: 719px), (hover: none) and (pointer: coarse) {
  #camera-toggle-hud,
  #face-view-hud { display: none; }
}

@media (max-width: 719px) {
  /* 조이스틱 옆 남은 폭에 버튼 다섯이 한 줄로 서도록 폭을 조금 줄인다. */
  .mobile-actions { flex-wrap: nowrap; gap: 5px; }
  .mobile-action { min-width: 40px; padding: 8px 6px; }
}

/* --------------------------------------------------------------------------
   랜딩(입장)
-------------------------------------------------------------------------- */
.landing-overlay {
  position: absolute;
  z-index: 6;
  inset: 0;
  display: flex;
  align-items: flex-end;
  padding: 12px;
  overflow-y: auto;
  background: linear-gradient(180deg, rgba(4, 8, 10, .18), rgba(4, 8, 10, .66) 62%);
}

.landing-card {
  width: 100%;
  max-height: 100%;
  overflow-y: auto;
  padding: 18px;
  color: var(--ink);
  border: 1px solid rgba(255, 255, 255, .66);
  border-radius: var(--radius-l);
  background:
    radial-gradient(circle at 96% 0, rgba(224, 140, 115, .2), transparent 11rem),
    radial-gradient(circle at 0 100%, rgba(127, 182, 176, .16), transparent 12rem),
    var(--paper);
  box-shadow: var(--shadow-float);
}

.landing-top { display: flex; align-items: center; justify-content: space-between; }

.landing-ticket {
  padding: 4px 9px;
  color: #7a6344;
  border: 1px dashed rgba(122, 99, 68, .5);
  border-radius: 5px;
  font: 700 9px/1.4 var(--latin);
  letter-spacing: .22em;
}

.landing-close {
  width: 32px;
  height: 32px;
  padding: 0;
  color: #7c705f;
  border: 0;
  border-radius: 50%;
  background: transparent;
  font-size: 24px;
  line-height: 1;
}
.landing-close:hover { background: rgba(74, 51, 48, .1); }

.landing-hero {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 13px 0 15px;
}

.landing-card h2 {
  margin: 0;
  color: #211d19;
  font-size: clamp(22px, 5.6vw, 28px);
  font-weight: 800;
  line-height: 1.18;
  letter-spacing: -.055em;
}

.landing-hero p {
  margin: 7px 0 0;
  color: #6a6157;
  font-size: 12.5px;
  line-height: 1.6;
}

.nickname-field { margin-bottom: 12px; }

.nickname-field > label {
  display: block;
  margin-bottom: 5px;
  color: #6f6355;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .02em;
}

.nickname-row {
  display: flex;
  align-items: stretch;
  gap: 6px;
  padding: 4px;
  border: 1px solid var(--paper-line);
  border-radius: 12px;
  background: var(--paper-2);
}

.nickname-row:focus-within { border-color: var(--brass); box-shadow: 0 0 0 3px rgba(201, 160, 99, .18); }

.nickname-row input {
  flex: 1;
  min-width: 0;
  height: 40px;
  padding: 0 10px;
  color: #2b241e;
  border: 0;
  outline: none;
  background: transparent;
  font-size: 16px;
  font-weight: 600;
}

.nickname-shuffle {
  flex: none;
  padding: 0 12px;
  color: #5c4a33;
  border: 1px solid rgba(201, 160, 99, .4);
  border-radius: 9px;
  background: #f6e7cf;
  font-size: 12px;
  font-weight: 700;
}
.nickname-shuffle:hover { background: #f0dcc0; }

.public-button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  min-height: 62px;
  padding: 10px 16px 10px 18px;
  color: #fdf6e9;
  border: 0;
  border-radius: var(--radius-m);
  background:
    radial-gradient(circle at 88% 20%, rgba(159, 216, 210, .3), transparent 60%),
    linear-gradient(135deg, #2c5150, #1d3a3c 62%, #173033);
  box-shadow: 0 10px 24px rgba(24, 58, 58, .34);
  text-align: left;
  transition: transform .16s var(--ease), box-shadow .16s;
}

.public-button:hover { transform: translateY(-1px); box-shadow: 0 14px 30px rgba(24, 58, 58, .44); }

.public-button-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 16px;
  font-weight: 800;
  letter-spacing: -.03em;
}

.public-button-label small {
  color: var(--warm);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .08em;
}

.public-arrow {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(255, 245, 230, .14);
  font: 500 18px/1 var(--latin);
}

.public-note {
  margin: 8px 0 12px;
  color: #857868;
  font-size: 11px;
  line-height: 1.5;
  text-align: center;
}


.landing-primary { color: #f8f0e2; background: var(--maroon); }
.landing-primary:hover { background: #5b3f3b; }
.landing-secondary { color: #4d4237; border: 1px solid var(--paper-line); background: #efe4d2; }
.landing-secondary:hover { background: #e7d9c3; }

.landing-status {
  margin: 10px 0 0;
  color: #a04a37;
  font-size: 12px;
  line-height: 1.5;
}
.landing-status:empty { display: none; }

.landing-style {
  width: 100%;
  min-height: 44px;
  margin-top: 12px;
  color: #4c4136;
  border: 1px dashed rgba(201, 160, 99, .55);
  background: rgba(201, 160, 99, .1);
}
.landing-style:hover { background: rgba(201, 160, 99, .18); }
.landing-style .orb { margin-right: 2px; }

/* --------------------------------------------------------------------------
   상영관 선택
   · 입장 시트(#hall-pick): 닉네임 아래 '자동 배정 + 관별 한 줄' 목록.
   · 상영관 안 시트(#hall-dialog): 지금 여기 + '이동'.
   톤은 이 앱의 것: 종이(--paper) 카드 위에 놋쇠 테두리, 관마다 놋쇠 도장(seal).
   좁은 화면에서는 목록을 접고(#hall-toggle = 지금 고른 관 요약) 눌러서 펼친다 —
   입장 버튼이 첫 화면 안에 남아야 해서다.
-------------------------------------------------------------------------- */
.hall-pick { margin: 0 0 10px; }

.hall-pick-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
  color: #6f6355;
  font-size: 11px;
  font-weight: 700;
}

.hall-pick-head .mini-label { color: #9a7c4d; font-size: 9px; }

.hall-pick-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 72%;
  min-height: 28px;
  padding: 2px 9px;
  color: #5f5344;
  border: 1px solid rgba(201, 160, 99, .5);
  border-radius: 999px;
  background: rgba(201, 160, 99, .12);
  font-family: inherit;
  font-size: 11.5px;
  font-weight: 700;
}
.hall-pick-toggle:hover { background: rgba(201, 160, 99, .2); }
.hall-pick-toggle:focus-visible { outline: 2px solid var(--brass); outline-offset: 1px; }
.hall-pick-toggle #hall-pick-summary {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 펼친 상태의 요약: 테두리만 남기고 화살표를 위로 돌린다. */
.hall-pick.is-open .hall-pick-toggle { border-color: rgba(201, 160, 99, .28); background: transparent; }

.hall-toggle-cue {
  flex: none;
  color: #9a7c4d;
  font-size: 9px;
  transition: transform .16s;
}
.hall-pick.is-open .hall-toggle-cue { transform: rotate(180deg); }

.hall-pick-list {
  display: grid;
  gap: 5px;
  max-height: 172px;
  overflow-y: auto;
  padding-right: 2px;
  overscroll-behavior: contain;
}

.hall-pick-list[aria-busy="true"] { opacity: .6; }

.hall-row {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  min-width: 0;
  padding: 7px 10px 7px 8px;
  color: var(--ink);
  border: 1px solid var(--paper-line);
  border-radius: 11px;
  background: var(--paper-2);
  font-family: inherit;
  text-align: left;
}

.hall-pick-row { cursor: pointer; transition: border-color .16s, background .16s; }
.hall-pick-row:hover { border-color: rgba(201, 160, 99, .55); background: #fff5e6; }
.hall-pick-row:focus-visible { outline: 2px solid var(--brass); outline-offset: 1px; }
.hall-pick-row.is-picked { border-color: var(--brass); background: #fdf1dc; }

.hall-seal {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  color: #6b5432;
  border: 1px solid rgba(151, 119, 70, .45);
  border-radius: 8px;
  background:
    radial-gradient(circle at 30% 25%, rgba(255, 255, 255, .55), transparent 62%),
    linear-gradient(180deg, #f4e3c5, #e5ceac);
  font: 800 13px/1 var(--latin);
  letter-spacing: .02em;
}

.hall-seal-soft {
  color: #7f7361;
  border-style: dashed;
  border-color: rgba(122, 99, 68, .35);
  background: #f1e6d5;
  font-size: 15px;
}

.hall-copy {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.hall-line {
  display: flex;
  align-items: baseline;
  gap: 7px;
  min-width: 0;
}

.hall-name {
  color: #2b241e;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
}

.hall-count {
  color: #8a7c68;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.hall-title {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  overflow: hidden;
  color: #6f6355;
  font-size: 11.5px;
  line-height: 1.4;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hall-play {
  flex: none;
  color: #4f7d62;
  font-size: 9px;
}

.hall-check {
  flex: none;
  width: 16px;
  color: #8a6a34;
  font-size: 13px;
  font-weight: 800;
  text-align: center;
}

.hall-pick-note {
  margin: 6px 0 0;
  color: #8a7c68;
  font-size: 11px;
  line-height: 1.45;
}
.hall-pick-note[hidden] { display: none; }

/* 상영관 안 시트(종이 다이얼로그) */
.hall-sheet-list {
  display: grid;
  gap: 6px;
  max-height: min(52vh, 380px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.hall-sheet-row { padding: 8px 9px; }
.hall-sheet-row.is-here { border-color: rgba(201, 160, 99, .65); background: #fdf1dc; }

.hall-move {
  flex: none;
  min-width: 66px;
  min-height: 32px;
  padding: 0 10px;
  color: #2c5150;
  border: 1px solid rgba(44, 81, 80, .3);
  border-radius: 9px;
  background: #eef0e6;
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
}
.hall-move:hover:not(:disabled) { background: #e3e8d7; }
.hall-move:disabled { cursor: default; }

.hall-move.is-here {
  color: #7c6642;
  border-color: rgba(201, 160, 99, .5);
  background: rgba(201, 160, 99, .18);
}

.hall-empty {
  margin: 4px 0;
  color: #8a7c68;
  font-size: 12px;
}

#hall-sheet-note[data-tone="warn"] { color: #a04a37; }


/* #player 가 엔진 스크린 포털로 옮겨지기 전까지의 자리. 화면에 그리지 않는다. */
.player-holder { display: none; }

/* --------------------------------------------------------------------------
   토스트 · 재연결 배너
-------------------------------------------------------------------------- */
.toast {
  position: fixed;
  z-index: 40;
  left: 50%;
  bottom: max(20px, env(safe-area-inset-bottom));
  max-width: min(430px, calc(100vw - 32px));
  padding: 12px 17px;
  color: #fdf5e7;
  border: 1px solid rgba(201, 160, 99, .34);
  border-radius: 12px;
  background: rgba(13, 21, 25, .96);
  box-shadow: var(--shadow-float);
  font-size: 13px;
  line-height: 1.45;
  opacity: 0;
  transform: translate(-50%, 12px);
  transition: opacity .2s var(--ease), transform .2s var(--ease);
  pointer-events: none;
}

.toast.is-visible { opacity: 1; transform: translate(-50%, 0); }
.toast[data-tone="error"] { border-color: rgba(217, 138, 118, .6); color: #ffd9cd; }
.toast[data-tone="ok"] { border-color: rgba(159, 216, 210, .5); }

.reconnect-banner {
  position: fixed;
  z-index: 35;
  left: 50%;
  top: calc(var(--topbar-h) + 10px);
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 15px;
  color: #ffe9c9;
  border: 1px solid rgba(255, 217, 171, .45);
  border-radius: 999px;
  background: rgba(38, 27, 14, .94);
  box-shadow: var(--shadow-float);
  font-size: 12.5px;
  font-weight: 600;
  transform: translateX(-50%);
  animation: banner-in .28s var(--ease);
}

@keyframes banner-in {
  from { opacity: 0; transform: translate(-50%, -8px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

/* --------------------------------------------------------------------------
   다이얼로그(종이 시트)
-------------------------------------------------------------------------- */
dialog {
  padding: 0;
  color: var(--ink);
  border: 1px solid rgba(255, 255, 255, .6);
  border-radius: var(--radius-l);
  background: var(--paper);
  box-shadow: var(--shadow-float);
}

dialog::backdrop { background: rgba(4, 7, 9, .68); backdrop-filter: blur(3px); }

.paper-dialog {
  width: min(440px, calc(100vw - 24px));
  max-height: min(86vh, 720px);
  overflow-y: auto;
  padding: 18px;
}

.sheet-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 4px;
}

.sheet-heading h2 {
  margin: 2px 0 0;
  color: #262019;
  font-size: 19px;
  font-weight: 800;
  letter-spacing: -.04em;
}

.sheet-close {
  flex: none;
  width: 34px;
  height: 34px;
  padding: 0;
  color: #7c705f;
  border: 0;
  border-radius: 50%;
  background: transparent;
  font-size: 24px;
  line-height: 1;
}
.sheet-close:hover { background: rgba(74, 51, 48, .1); }

.sheet-note {
  margin: 6px 0 12px;
  color: #7c705f;
  font-size: 12px;
  line-height: 1.55;
}

.sheet-status {
  min-height: 1.2em;
  margin: 8px 0 4px;
  color: #a04a37;
  font-size: 12px;
}

.sheet-status:empty { min-height: 0; }

/* 방 설정 */
#room-settings-form { display: grid; gap: 4px; }

#room-settings-form label {
  margin-top: 8px;
  color: #5c5041;
  font-size: 12px;
  font-weight: 700;
}

#room-settings-form input:not([type="checkbox"]),
#room-settings-form textarea,
#room-settings-form select {
  width: 100%;
  padding: 10px 11px;
  color: #2c261f;
  border: 1px solid var(--paper-line);
  border-radius: 10px;
  background: var(--paper-2);
  font-size: 14px;
}

#room-settings-form textarea { resize: vertical; min-height: 74px; }

#room-settings-form input:disabled,
#room-settings-form textarea:disabled {
  color: #8d8275;
  background: #f1e8da;
}

#room-settings-save { margin-top: 12px; min-height: 44px; }

/* 꾸미기 */
#closet-dialog {
  width: min(620px, calc(100vw - 20px));
  max-height: min(90vh, 760px);
  overflow: hidden;
}

/* 닫힌 dialog는 UA 기본값(display:none)을 유지해야 문서 흐름을 밀지 않는다. */
#closet-dialog[open] {
  display: flex;
  flex-direction: column;
}

.closet-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 14px 16px 6px;
}

.closet-title-wrap { display: flex; align-items: center; gap: 10px; }
.closet-heading h2 { margin: 1px 0 0; color: #262019; font-size: 18px; letter-spacing: -.04em; }

.closet-body {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
  padding: 6px 16px 10px;
  min-height: 0;
  overflow: hidden;
}

.closet-preview {
  position: relative;
  display: grid;
  overflow: hidden;
  min-height: 190px;
  border: 1px solid rgba(201, 160, 99, .34);
  border-radius: var(--radius-m);
  background:
    radial-gradient(circle at 50% 34%, rgba(159, 216, 210, .14), transparent 58%),
    radial-gradient(circle at 50% 46%, #1e2b30, #0b1215 74%);
}

#closet-canvas {
  width: 100%;
  height: 100%;
  min-height: 190px;
  touch-action: none;
  cursor: grab;
}
#closet-canvas:active { cursor: grabbing; }

.closet-drag-hint {
  position: absolute;
  top: 9px;
  left: 50%;
  transform: translateX(-50%);
  color: rgba(240, 231, 218, .55);
  font-size: 10px;
  pointer-events: none;
}

#closet-random {
  position: absolute;
  left: 10px;
  bottom: 10px;
  min-height: 32px;
  padding: 6px 11px;
  color: #f6ecdd;
  border-color: rgba(235, 220, 198, .3);
  background: rgba(10, 17, 21, .68);
  backdrop-filter: blur(6px);
}
#closet-random:hover { background: rgba(24, 36, 41, .9); }

.closet-controls {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
}

.closet-tabs {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  scrollbar-width: none;
}
.closet-tabs::-webkit-scrollbar { display: none; }

.closet-tabs button {
  flex: 1 0 auto;
  padding: 8px 9px;
  color: #61544a;
  border: 1px solid var(--paper-line);
  border-radius: 9px;
  background: #fffdf7;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

.closet-tabs button[aria-selected="true"] {
  color: #fdf5e7;
  border-color: var(--maroon);
  background: var(--maroon);
}

.closet-panel {
  flex: 1;
  min-height: 0;
  max-height: 236px;
  overflow-y: auto;
  display: grid;
  gap: 10px;
  padding-right: 3px;
  scrollbar-width: thin;
}

.closet-section h3 {
  margin: 0 0 6px;
  color: #85745e;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .04em;
}

.closet-hint {
  margin: 7px 0 0;
  color: #9a8b76;
  font-size: 10.5px;
  line-height: 1.5;
}

.closet-row { display: flex; flex-wrap: wrap; gap: 6px; }

.swatch {
  width: 32px;
  height: 32px;
  padding: 0;
  border: 2px solid rgba(255, 255, 255, .7);
  border-radius: 50%;
  background: var(--swatch);
  box-shadow: 0 0 0 1px rgba(74, 51, 48, .22);
}

.swatch[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--brass), 0 0 0 4px rgba(201, 160, 99, .3); }

.closet-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  color: #5a4d40;
  border: 1px solid var(--paper-line);
  border-radius: 999px;
  background: #fffdf7;
  font-size: 12px;
}

.closet-item[aria-pressed="true"] { color: #fdf5e7; border-color: var(--maroon); background: var(--maroon); }

.closet-item-dot { width: 15px; height: 15px; border-radius: 50%; background: var(--item-dot, #6f5d4a); }
.closet-item[aria-pressed="true"] .closet-item-dot { background: #d9c3a0; }
.closet-item-dot[data-slot="hat"] { border-radius: 5px 5px 2px 2px; }
.closet-item-dot[data-slot="wig"] { border-radius: 50% 50% 42% 42%; }
.closet-item-dot[data-slot="accessory"] { background: var(--item-dot, var(--teal)); }

.closet-shape-glyph { position: relative; display: block; width: 16px; height: 16px; flex: 0 0 16px; }

.closet-shape-glyph[data-key="body_shape"][data-shape="sphere"] { border-radius: 50%; background: #4a3f36; }
.closet-shape-glyph[data-key="body_shape"][data-shape="drop"] { border-radius: 50% 50% 50% 50% / 62% 62% 38% 38%; background: #4a3f36; }
.closet-shape-glyph[data-key="body_shape"][data-shape="cloud"] {
  background: #4a3f36;
  border-radius: 50%;
  box-shadow: -5px 3px 0 -2px #4a3f36, 5px 2px 0 -2px #4a3f36, 0 -4px 0 -3px #4a3f36;
}
.closet-shape-glyph[data-key="body_shape"][data-shape="pill"] { width: 10px; margin: 0 3px; border-radius: 999px; background: #4a3f36; }
.closet-shape-glyph[data-key="eye_shape"] { background: #fdfaf3; box-shadow: 0 0 0 1px rgba(74, 51, 48, .3); }
.closet-shape-glyph[data-key="eye_shape"][data-shape="capsule"] { width: 6px; margin: 0 5px; border-radius: 999px; }
.closet-shape-glyph[data-key="eye_shape"][data-shape="tilted"] { width: 6px; margin: 0 5px; border-radius: 999px; transform: rotate(20deg); }
.closet-shape-glyph[data-key="eye_shape"][data-shape="wide"] { height: 6px; margin: 5px 0; border-radius: 999px; }
.closet-shape-glyph[data-key="eye_shape"][data-shape="dot"] { width: 7px; height: 7px; margin: 4.5px; border-radius: 50%; }

.closet-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 16px 14px;
  border-top: 1px solid rgba(122, 99, 68, .16);
}

.closet-note { color: #8d7f6d; font-size: 11px; }
#closet-save { min-height: 40px; min-width: 92px; }

/* 사람 목록 */
.people-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
  max-height: min(52vh, 420px);
  overflow-y: auto;
}

.people-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border: 1px solid rgba(122, 99, 68, .16);
  border-radius: var(--radius-m);
  background: #fffaf2;
}

.people-row .orb { width: 30px; height: 30px; }

.people-row.is-self { border-color: rgba(201, 160, 99, .55); background: #fdf3e2; }
.people-row.is-offline { opacity: .55; }

.people-main { flex: 1; min-width: 0; }

.people-name {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #372e24;
  font-size: 13px;
  font-weight: 700;
}

.people-meta { margin-top: 1px; color: #8d7f6d; font-size: 11px; }

/* 강퇴 투표 진행(서버 notice). 표가 없으면 [hidden] 규칙으로 접힌다. */
.people-kick-progress {
  margin-left: 6px;
  padding: 1px 6px;
  color: #8c4a33;
  border-radius: 999px;
  background: #f7e2d7;
  font-size: 10px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.badge {
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .02em;
}
.badge-operator { color: #5c3a12; background: #f6dfae; }
.badge-staff { color: #21514b; background: #d9ece4; }
.badge-self { color: #21514b; background: #e6e9ee; }
.badge-off { color: #7b6d5c; background: #ece2d2; }

.people-actions { display: flex; gap: 4px; flex: none; }

.people-action {
  padding: 5px 8px;
  color: #6a5a46;
  border: 1px solid rgba(122, 99, 68, .26);
  border-radius: 7px;
  background: transparent;
  font-size: 11px;
  white-space: nowrap;
}
.people-action:hover { background: #f4e9d8; }
.people-action.danger { color: #a2543d; border-color: rgba(162, 84, 61, .3); }
.people-action.danger:hover { background: #f8e3d9; }

/* 운영자 로그인(사람 패널 하단). 키는 저장하지 않고, 제출하면 입력창을 비운다. */
.operator-login {
  margin-top: 12px;
  padding-top: 11px;
  border-top: 1px dashed rgba(122, 99, 68, .22);
}

.operator-role:empty,
.operator-status:empty { display: none; }

.operator-role { margin: 2px 0 0; color: #6a4a1d; font-size: 11px; }

.operator-row { display: flex; gap: 6px; margin-top: 6px; }

.operator-row input {
  flex: 1;
  min-width: 0;
  height: 34px;
  padding: 0 10px;
  color: #372e24;
  border: 1px solid var(--paper-line);
  border-radius: 8px;
  background: #fffaf2;
  font-size: 12px;
}

.operator-row .button {
  flex: none;
  min-height: 34px;
  padding: 0 11px;
  /* 종이 시트 위이라 어두운 배경용 .button-outline 색은 쓰지 않는다. */
  color: #5b4c3c;
  border-color: var(--paper-line);
  background: #fffaf2;
  font-size: 11.5px;
}

.operator-row .button:hover { background: #f4e9d8; }

.operator-status { margin: 6px 0 0; color: #8d7f6d; font-size: 11px; }

/* 도움말 */
.help-grid {
  display: grid;
  gap: 14px;
  margin: 4px 0 10px;
}

.help-grid h3 {
  margin: 0 0 6px;
  color: #43382c;
  font-size: 13px;
  font-weight: 800;
}

.help-grid dl { margin: 0; display: grid; gap: 6px; }
.help-grid dl > div { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.help-grid dt { flex: none; display: flex; gap: 3px; }
.help-grid dd { margin: 0; color: #6f6355; font-size: 12px; text-align: right; }

/* 만든 사람: 도움말 맨 아래 한 줄. 로고 없이 이름만 놋쇠색 링크로 둔다. */
.help-maker {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 8px;
  margin: 0 0 4px;
  padding-top: 10px;
  color: #9a8d7c;
  border-top: 1px solid rgba(201, 160, 99, .26);
  font-size: 11.5px;
}

.help-maker a {
  color: #8a6c3f;
  font-weight: 700;
  text-decoration: none;
  border-bottom: 1px solid rgba(201, 160, 99, .45);
}

.help-maker a:hover { color: #6a4a1d; border-bottom-color: #8a6c3f; }

/* 확인(넘기기 투표) */
.confirm-dialog { width: min(360px, calc(100vw - 32px)); padding: 20px; }
.confirm-dialog h2 { margin: 0 0 6px; color: #262019; font-size: 19px; letter-spacing: -.04em; }
.confirm-dialog p { margin: 0 0 16px; color: #6f6355; font-size: 13px; line-height: 1.55; }
.sheet-actions { display: flex; gap: 8px; }
.sheet-actions .button { flex: 1; min-height: 42px; }
.confirm-dialog .button-outline { color: #5b4c3c; border-color: var(--paper-line); }

/* ==========================================================================
   로비 기능(§11): 가방 핫바 · 상호작용 힌트 · 상점 · 티켓 · 3D 안경
   톤은 기존 토큰 그대로: 짙은 밤(--night-2) 위에 따뜻한 종이(--paper) + 놋쇠(--brass).
   ========================================================================== */

/* --- 가방 핫바 ------------------------------------------------------------ */
.hotbar {
  position: absolute;
  z-index: 6;
  top: 10px;
  right: 10px;
  display: grid;
  grid-template-columns: repeat(5, 32px);
  gap: 3px;
  padding: 6px;
  border: 1px solid rgba(201, 160, 99, .26);
  border-radius: 13px;
  background: rgba(8, 14, 17, .72);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .34);
  backdrop-filter: blur(12px);
  transition: opacity .28s var(--ease);
}

.hotbar.is-idle { opacity: .3; }
.hotbar:not(.is-idle):hover { opacity: 1; }

.hotbar-slot {
  position: relative;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  color: #f6ecdd;
  border: 1px solid rgba(201, 160, 99, .34);
  border-radius: 8px;
  background: rgba(21, 31, 36, .88);
  font-size: 16px;
  line-height: 1;
  transition: transform .12s var(--ease), border-color .16s, background .16s;
}

.hotbar-slot.is-empty {
  border-style: dashed;
  border-color: rgba(201, 160, 99, .22);
  background: rgba(10, 17, 21, .42);
}

.hotbar-slot.is-held {
  border-color: var(--brass-bright);
  background: rgba(201, 160, 99, .26);
  box-shadow: 0 0 0 1px rgba(227, 189, 131, .45), 0 0 14px rgba(201, 160, 99, .25);
  transform: translateY(-1px);
}

.hotbar-slot:active { transform: scale(.94); }

.hotbar-key {
  position: absolute;
  top: 1px;
  left: 3px;
  color: rgba(242, 233, 220, .58);
  font: 700 8px/1.2 var(--latin);
}

.hotbar-emoji { display: block; }

.hotbar-count {
  position: absolute;
  right: 2px;
  bottom: 0;
  color: var(--brass-bright);
  font: 700 9px/1.2 var(--latin);
  text-shadow: 0 1px 2px rgba(0, 0, 0, .8);
}

.hotbar-trash {
  grid-column: 1 / -1;
  display: grid;
  place-items: center;
  height: 24px;
  padding: 0;
  color: #d9cbb7;
  border: 1px solid rgba(201, 160, 99, .22);
  border-radius: 7px;
  background: rgba(10, 17, 21, .5);
  font-size: 12px;
  line-height: 1;
}
.hotbar-trash:disabled { opacity: .34; }
.hotbar-trash:not(:disabled):hover { border-color: rgba(217, 138, 118, .6); color: #ffd9cd; }

/* --- 상호작용 힌트 알약 ---------------------------------------------------- */
.interact-hint {
  position: absolute;
  z-index: 6;
  left: 50%;
  top: calc(50% + 44px);
  max-width: min(92%, 560px);
  padding: 8px 15px;
  color: #f8f0e2;
  border: 1px solid rgba(201, 160, 99, .34);
  border-radius: 999px;
  background: rgba(8, 14, 17, .82);
  box-shadow: 0 8px 22px rgba(0, 0, 0, .34);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.4;
  text-align: center;
  white-space: normal;
  transform: translateX(-50%);
  backdrop-filter: blur(10px);
  animation: hint-in .18s var(--ease);
  touch-action: manipulation;
}

.interact-hint:hover { border-color: rgba(227, 189, 131, .6); }

/* 넓은 화면은 E 키가 있으니 알약이 마우스 시점 회전을 가로채지 않게 통과시킨다.
   터치(거친 포인터)는 폭과 무관하게 탭 = E. */
@media (min-width: 720px) and (hover: hover) and (pointer: fine) {
  .interact-hint { pointer-events: none; }
}

@keyframes hint-in {
  from { opacity: 0; transform: translate(-50%, 6px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

/* 패널·티켓·촬영이 떠 있는 동안 장면 위 조작은 물러난다(포커스·클릭 가로채기 방지). */
.stage-wrap.is-modal .hotbar,
.stage-wrap.is-modal .interact-hint,
.stage-wrap.is-modal .mobile-stage-controls,
.stage-wrap.is-modal .scene-help {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* --- 1인칭 3D 안경(가장자리 빨강·파랑) ------------------------------------- */
.glasses-3d {
  position: absolute;
  z-index: 4;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(226, 74, 82, .2), transparent 14%, transparent 86%, rgba(74, 132, 226, .2)),
    linear-gradient(180deg, rgba(226, 74, 82, .12), transparent 18%, transparent 82%, rgba(74, 132, 226, .12));
  mix-blend-mode: screen;
  animation: glasses-settle .5s var(--ease);
}

@keyframes glasses-settle {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* --- 상점 패널 ------------------------------------------------------------ */
.shop-overlay {
  position: fixed;
  z-index: 45;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 14px;
  background: rgba(4, 7, 9, .62);
  backdrop-filter: blur(3px);
}

.shop {
  display: flex;
  flex-direction: column;
  width: min(720px, 100%);
  max-height: min(86vh, 760px);
  overflow: hidden;
  padding: 16px 16px 12px;
  color: var(--ink);
  border: 1px solid rgba(255, 255, 255, .62);
  border-radius: var(--radius-l);
  background:
    radial-gradient(circle at 100% 0, rgba(224, 140, 115, .16), transparent 12rem),
    radial-gradient(circle at 0 100%, rgba(127, 182, 176, .12), transparent 13rem),
    var(--paper);
  box-shadow: var(--shadow-float);
  animation: shop-in .22s var(--ease);
}

@keyframes shop-in {
  from { opacity: 0; transform: translateY(12px) scale(.985); }
  to { opacity: 1; transform: none; }
}

.shop-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}

.shop-head h2 {
  margin: 2px 0 0;
  color: #262019;
  font-size: 21px;
  font-weight: 800;
  letter-spacing: -.045em;
}

.shop-head .mini-label { color: #9a7c4d; }

.shop-sub {
  margin: 4px 0 12px;
  color: #7c705f;
  font-size: 12px;
  line-height: 1.5;
}

.shop-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(136px, 1fr));
  gap: 9px;
  overflow-y: auto;
  padding: 2px 2px 8px;
  min-height: 0;
}

.shop-group {
  grid-column: 1 / -1;
  margin: 8px 0 0;
  padding: 0 2px 5px;
  color: #8a6c3f;
  border-bottom: 1px solid rgba(201, 160, 99, .34);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .02em;
}
.shop-group:first-child { margin-top: 0; }

.shop-combos {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  gap: 9px;
}

.shop-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 12px 10px 10px;
  border: 1px solid rgba(122, 99, 68, .22);
  border-radius: var(--radius-m);
  background: var(--paper-2);
  text-align: center;
}

.shop-card-combo {
  border-color: rgba(201, 160, 99, .55);
  background:
    radial-gradient(circle at 50% 0, rgba(201, 160, 99, .18), transparent 60%),
    var(--paper-2);
}

/* 아이콘 무대: 크림 접시 위에 물건을 얹는다. 아이콘 자체는 1em 이라
   여기 font-size 가 곧 크기다(낱개 58px, 콤보 76px — 조합이 겹쳐도 읽히게). */
.shop-emoji {
  display: grid;
  place-items: center;
  width: 88px;
  height: 88px;
  margin: 0 auto 2px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 38%, rgba(255, 255, 255, .92), rgba(255, 255, 255, 0) 58%),
    radial-gradient(circle at 50% 50%, var(--paper-2) 0 58%, #f2e6d3 60% 100%);
  box-shadow:
    inset 0 0 0 1px rgba(201, 160, 99, .34),
    inset 0 -6px 12px rgba(122, 99, 68, .1),
    0 3px 10px rgba(74, 51, 48, .08);
  font-size: 58px;
  line-height: 1;
}

.shop-emoji svg { display: block; width: 1em; height: 1em; }

.shop-card-combo .shop-emoji {
  width: 96px;
  height: 96px;
  font-size: 76px;
}

.shop-name {
  margin: 2px 0 0;
  color: #332a20;
  font-size: 13.5px;
  font-weight: 800;
  letter-spacing: -.02em;
}

.shop-desc {
  margin: 0;
  min-height: 2.6em;
  color: #857768;
  font-size: 11px;
  line-height: 1.4;
}

.shop-price {
  margin-top: 2px;
  color: #9a7c4d;
  font-size: 11px;
  font-weight: 700;
}

.shop-buy {
  width: 100%;
  min-height: 32px;
  margin-top: 6px;
  padding: 6px 8px;
  color: #241a10;
  border: 0;
  border-radius: 9px;
  background: linear-gradient(180deg, var(--brass-bright), var(--brass));
  font-size: 12px;
  font-weight: 800;
}

.shop-buy:hover:not(:disabled) { background: linear-gradient(180deg, #efcc94, #d3ab6e); }

.shop-buy:disabled {
  color: #6f6355;
  border: 1px solid rgba(122, 99, 68, .24);
  background: #efe5d6;
  opacity: 1;
}

.shop-card[data-state="refill"] .shop-buy {
  color: #21514b;
  border: 1px solid rgba(33, 81, 75, .28);
  background: #dcece5;
}

.shop-foot {
  margin: 8px 0 0;
  color: #9a8d7c;
  font-size: 11px;
  text-align: center;
}

/* --- 로컬 발권 종이 티켓 ---------------------------------------------------
   세로형 ADMIT ONE. 크림 종이 + 놋쇠박 띠 + 짙은 초록 스텁.
   · 위 왼쪽 놋쇠 고리 안이 뚫린 구멍(마스크), 아래쪽 점선 뜯는 선 양옆에 반원 노치.
   · 스텁 높이(--stub-h)와 노치 위치가 맞물린다 — 한쪽만 바꾸면 노치가 어긋난다.
-------------------------------------------------------------------------- */
.ticket-overlay {
  position: fixed;
  z-index: 46;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 14px;
  background: rgba(4, 7, 9, .66);
  backdrop-filter: blur(3px);
}

.ticket-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: min(360px, 100%);
  max-height: 100%;
  overflow-y: auto;
  color: var(--ink);
  scrollbar-width: thin;
}

.ticket-card.is-printing { animation: ticket-print .46s var(--ease) both; }

/* 슬롯에서 종이가 올라오듯 — 살짝만 움직인다(화면을 크게 흔들지 않게). */
@keyframes ticket-print {
  from { opacity: 0; transform: translateY(-16px) scale(.985); }
  55% { opacity: 1; }
  to { opacity: 1; transform: none; }
}

.ticket-paper {
  --stub-h: 78px;
  --punch: radial-gradient(circle 7px at 31px 28px, transparent 0 96%, #000 100%);
  --notch-l: radial-gradient(circle 10px at 0 calc(100% - var(--stub-h) - 8px), transparent 0 96%, #000 100%);
  --notch-r: radial-gradient(circle 10px at 100% calc(100% - var(--stub-h) - 8px), transparent 0 96%, #000 100%);
  position: relative;
  width: 100%;
  overflow: hidden;
  border-radius: 16px 16px 13px 13px;
  background:
    repeating-linear-gradient(90deg, rgba(122, 99, 68, .045) 0 1px, transparent 1px 7px),
    radial-gradient(circle at 100% 0, rgba(201, 160, 99, .22), transparent 12rem),
    var(--paper);
  box-shadow: 0 22px 56px rgba(0, 0, 0, .5), 0 0 0 1px rgba(255, 255, 255, .16);
  /* 구멍·노치를 진짜로 뚫는다(아래 배경이 비친다). 미지원 브라우저는 그냥 각진 종이. */
  -webkit-mask-image: var(--punch), var(--notch-l), var(--notch-r);
  -webkit-mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-composite: source-in;
  mask-image: var(--punch), var(--notch-l), var(--notch-r);
  mask-size: 100% 100%;
  mask-repeat: no-repeat;
  mask-composite: intersect;
}

/* 놋쇠박 띠: 우리 이름과 관 번호. */
.ticket-band {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 15px 16px 13px 18px;
  color: #f3e6cc;
  background:
    linear-gradient(100deg, #14312c 0%, #1d4a41 42%, #163830 100%),
    #14312c;
  box-shadow: inset 0 -1px 0 rgba(201, 160, 99, .55), inset 0 1px 0 rgba(255, 255, 255, .08);
}

/* 놋쇠 고리 — 가운데는 위 마스크가 뚫는다(구멍). */
.ticket-orb {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 30%, #f0d3a0, #c9a063 58%, #9d7740 100%);
  box-shadow: inset 0 0 0 1px rgba(255, 236, 200, .55);
}

.ticket-brand {
  color: #f7ead0;
  font-size: 14px;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -.03em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ticket-brand-latin {
  display: block;
  grid-column: 2;
  margin-top: 2px;
  color: rgba(201, 160, 99, .92);
  font: 700 8px/1 var(--latin);
  letter-spacing: .26em;
}

.ticket-hall-tag {
  grid-column: 3;
  grid-row: 1 / span 2;
  padding: 3px 9px;
  color: #f0d9ae;
  border: 1px solid rgba(201, 160, 99, .62);
  border-radius: 999px;
  font-size: 10px;
  font-weight: 800;
  white-space: nowrap;
}

.ticket-main {
  position: relative;
  padding: 16px 18px 18px;
}

/* 지금 상영 영상의 썸네일을 미니 포스터로. 16:9 · 놋쇠 실선. */
.ticket-poster {
  position: relative;
  margin: 0 0 12px;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 9px;
  background: #d9c6a6;
  box-shadow: inset 0 0 0 1px rgba(122, 99, 68, .35), 0 6px 16px rgba(74, 51, 48, .18);
}

.ticket-poster img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity .2s var(--ease);
}

.ticket-poster.is-broken img { opacity: 0; }

/* 썸네일이 없거나 깨졌을 때: 놋쇠 줄무늬 + 필름 구멍. */
.ticket-poster-fallback {
  position: absolute;
  inset: 0;
  opacity: 0;
  background:
    radial-gradient(circle at 50% 50%, rgba(247, 239, 226, .18), transparent 70%),
    repeating-linear-gradient(135deg, rgba(122, 99, 68, .16) 0 10px, transparent 10px 22px),
    linear-gradient(160deg, #2c4f47, #17342e);
  transition: opacity .2s var(--ease);
}

.ticket-poster-fallback::before,
.ticket-poster-fallback::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  width: 7px;
  background: repeating-linear-gradient(180deg,
    rgba(247, 239, 226, .5) 0 6px, transparent 6px 13px);
}

.ticket-poster-fallback::before { left: 0; }
.ticket-poster-fallback::after { right: 0; }

.ticket-poster:not(.has-poster) .ticket-poster-fallback,
.ticket-poster.is-broken .ticket-poster-fallback { opacity: 1; }

.ticket-now { padding-right: 4px; }

.ticket-kicker {
  margin: 0 0 4px;
  color: #9a7c4d;
  font: 700 8.5px/1.4 var(--latin);
  letter-spacing: .24em;
}

.ticket-title {
  margin: 0;
  color: #262019;
  font-size: 21px;
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: -.045em;
  word-break: keep-all;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.ticket-by {
  margin: 4px 0 0;
  min-height: 1.4em;
  color: #8a7c6b;
  font-size: 11px;
  font-weight: 600;
}

.ticket-rows {
  display: grid;
  gap: 0;
  margin: 14px 0 0;
  padding: 0;
  border-top: 1px solid rgba(201, 160, 99, .3);
}

.ticket-rows > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 0;
  border-bottom: 1px solid rgba(201, 160, 99, .2);
}
.ticket-rows > div:last-child { border-bottom: 0; }

.ticket-rows dt {
  flex: none;
  color: #9a8d7c;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .04em;
}

.ticket-rows dd {
  margin: 0;
  color: #332a20;
  font-size: 12.5px;
  font-weight: 700;
  text-align: right;
}

/* 눌러 찍은 듯한 놋쇠 도장 — 포스터 오른쪽 위 모서리에 살짝 기울여 얹는다. */
.ticket-seal {
  position: absolute;
  top: 22px;
  right: 24px;
  display: grid;
  place-items: center;
  width: 62px;
  height: 62px;
  padding: 6px;
  color: #8a6a33;
  border: 2px solid currentColor;
  border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(138, 106, 51, .45) inset;
  font-size: 10px;
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: .06em;
  text-align: center;
  text-transform: uppercase;
  opacity: .82;
  transform: rotate(-9deg);
  mix-blend-mode: multiply;
  pointer-events: none;
}

.ticket-seal::after {
  content: '';
  position: absolute;
  inset: 4px;
  border: 1px dashed currentColor;
  border-radius: 50%;
  opacity: .55;
}

/* 뜯는 선: 양옆 반원 노치(마스크) + 점선. */
.ticket-cut {
  position: relative;
  height: 16px;
  margin: 0 14px;
  display: flex;
  align-items: center;
}

.ticket-perf {
  flex: 1;
  height: 0;
  border-top: 2px dashed rgba(122, 99, 68, .46);
}

.ticket-notch {
  flex: none;
  width: 0;
  height: 0;
}

/* 스텁: 짙은 초록 띠 + 크림 바코드. 위 여백은 --stub-h 와 함께 움직인다. */
.ticket-stub {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  min-height: var(--stub-h);
  padding: 12px 18px 14px 20px;
  color: #efe2c8;
  background:
    linear-gradient(100deg, rgba(201, 160, 99, .1), transparent 42%),
    linear-gradient(180deg, #1b463e, #152f2a);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07);
}

.ticket-stub-copy {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 0;
}

.ticket-stub-label {
  color: rgba(201, 160, 99, .95);
  font: 700 8.5px/1.3 var(--latin);
  letter-spacing: .16em;
  white-space: nowrap;
}

.ticket-serial {
  color: #f3e6cc;
  font: 700 13px/1 var(--latin);
  letter-spacing: .1em;
}

.ticket-barcode {
  flex: none;
  width: 104px;
  height: 38px;
  padding: 4px 6px;
  color: #f7edda;
  border-radius: 5px;
  background: rgba(247, 237, 218, .1);
}

.ticket-barcode svg { display: block; width: 100%; height: 100%; }

/* 닫기: 종이 밖(어두운 배경)에 있어 밝은 외곽선 그대로 쓴다. */
.ticket-card .ticket-close {
  width: min(360px, 100%);
  min-height: 38px;
  color: #f2e9dc;
  border-color: rgba(235, 220, 198, .32);
  background: rgba(8, 14, 17, .55);
  font-size: 12.5px;
}
.ticket-card .ticket-close:hover { background: rgba(201, 160, 99, .2); }

/* 좁은 화면: 여백만 조금 줄여 세로 길이를 아낀다. */
@media (max-width: 719px) {
  .ticket-main { padding: 14px 14px 16px; }
  .ticket-band { padding: 14px 14px 12px 16px; }
  .ticket-stub { padding: 12px 14px 14px 16px; }
  .ticket-title { font-size: 19px; }
  .ticket-seal { top: 18px; right: 20px; width: 56px; height: 56px; font-size: 9px; }
  .ticket-barcode { width: 88px; height: 34px; }
}

/* 모바일 조작: R/F 버튼은 위 줄, 기존 다섯 버튼은 아래 줄(겹치지 않게 세로로 쌓는다). */
.mobile-actions {
  flex-direction: column;
  align-items: flex-end;
  flex-wrap: nowrap;
  gap: 6px;
}

.mobile-item-actions,
.mobile-action-row {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
  flex-wrap: nowrap;
}

.mobile-item-action {
  color: var(--brass-bright);
  border-color: rgba(201, 160, 99, .5);
}

.mobile-item-action:disabled {
  color: rgba(242, 233, 220, .32);
  border-color: rgba(235, 220, 198, .14);
}

.mobile-item-action[hidden] { display: none !important; }

/* 좁은 화면: 조이스틱 옆 남은 폭에 다섯 버튼이 한 줄로 서도록 글자·여백을 조인다.
   라벨이 두 줄로 쪼개지지 않게 줄바꿈을 막고(keep-all + nowrap), 버튼이 찌그러지지
   않게 flex-shrink 를 끈다. 그래도 폭이 모자라면(≤360px) 줄 전체가 오른쪽 정렬로
   두 줄이 된다 — 넘쳐서 잘리는 것보다 낫고, 최소 높이 44px 는 그대로라 탭 영역은 유지된다. */
@media (max-width: 719px) {
  .mobile-action {
    flex: 0 0 auto;
    min-width: 0;
    padding: 8px 5px;
    font-size: 11px;
    white-space: nowrap;
    word-break: keep-all;
  }
  .mobile-item-action { padding: 8px 6px; }
  .mobile-action-row { flex-wrap: wrap; row-gap: 5px; }
}

/* 좁은 화면: 장면 제목(좌상단)과 겹치지 않게 핫바를 조금 조인다.
   세로 위치는 구역 배지 띠(위 14px + 높이 ~28px) 아래로 내렸다 — 예전 top:10px
   에서는 같은 띠에 서는 배지가 길어지는 순간(인스턴스 표기) 알약 밑으로 파고들었고,
   3D 로 그려진 '우리의 상영관' 사인도 가운데부터 덮었다. 핫바는 3D 사인 위에 뜨는
   DOM 이므로, 띠를 비켜 두면 둘 다 읽힌다. inset 이 아니라 top/right 를 쓰는
   데스크톱 규칙(.hotbar{top:64px;right:24px})은 그대로 둔다. */
@media (max-width: 719px) {
  .hotbar {
    top: 50px;
    grid-template-columns: repeat(5, 26px);
    gap: 2px;
    padding: 5px;
    border-radius: 11px;
  }
  .hotbar-slot { width: 26px; height: 26px; border-radius: 7px; font-size: 14px; }
  .hotbar-key { font-size: 7px; left: 2px; }
  .hotbar-count { font-size: 8px; right: 1px; }
  .hotbar-trash { height: 20px; font-size: 11px; }

  /* 좁은 화면: 구역 배지(좌상단)가 길어지면(관 이름 + 구역)
     우상단 핫바 아래로 파고들었다. 핫바 폭(26px×5 + gap·padding ≈ 150px)과
     사이 여백 10px 만큼 배지를 오른쪽에서 잘라 두 겹이 겹치지 않게 한다.
     배지 글자는 줄바꿈 대신 말줄임으로 — 알약 높이가 커지면 3D 뷰를 더 덮는다. */
  .zone-badge {
    max-width: calc(100% - 184px);
    white-space: nowrap;
  }
  .zone-badge-hall {
    min-width: 0;
    flex-shrink: 1;
  }
  .zone-badge-hall .instance-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  #zone-label { flex: none; }

  /* 좁은 화면의 상영관 선택 목록: 손가락으로 누르기 좋게 조금 더 크게, 높이는 줄인다. */
  .hall-pick-list { max-height: 148px; }
  .hall-sheet-list { max-height: min(54vh, 340px); }
  .hall-row { min-height: 44px; }


  /* 좁은 화면: 힌트 알약은 조이스틱·버튼 아래 띠를 피해 무대 가운데 아래에 둔다.
     (조작 바가 무대 밖으로 나가 아래 띠가 비었지만, 버튼 줄이 가운데까지 뻗어
      바닥에 붙이면 알약이 버튼을 덮는다.) */
  .interact-hint {
    top: calc(50% + 24px);
    bottom: auto;
    width: max-content;
    max-width: calc(100% - 24px);
    padding: 0 10px;
    font-size: 10px;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}


/* --------------------------------------------------------------------------
   데스크톱
-------------------------------------------------------------------------- */
@media (min-width: 720px) {
  :root { --pad: 20px; }

  .topbar {
    grid-template-columns: auto 1fr auto;
    grid-template-areas: 'brand room actions';
    min-height: 66px;
    padding: 10px var(--pad);
  }

  .icon-button.labeled span { display: inline; }
  .brand-copy { font-size: 16px; }

  .topbar-room { justify-content: center; }
  .room-name { font-size: 14px; }

  .stage-wrap { height: clamp(420px, 62vh, 640px); }

  /* 왼쪽 조작 바 자리와 겹치는 장식 제목은 넓은 화면에서 숨긴다(제목 텍스트는 DOM에 남는다). */
  .stage-heading { display: none; }
  /* 구역 배지는 조작 바를 피해 오른쪽 위로 보낸다. 장식용 'OUR THEATER' 는 숨긴다. */
  .zone-badge { top: 22px; left: auto; right: 28px; }
  .scene-badge { display: none; }
  /* 핫바는 오른쪽 위 그대로 — 조작 바는 왼쪽이라 겹치지 않는다. */
  .hotbar { top: 64px; right: 24px; }
  /* 단축키 줄은 조작 바 오른쪽의 남은 폭에서 가운데 선다(왼쪽 패널과 겹치지 않게).
     아래 오른쪽 구석은 장식 캡션(.stage-caption) 몫이라 그 위로 올린다 —
     캡션은 bottom 16·높이 ~16px, 이 줄은 bottom 44·높이 ~34px 로 12px 띠를 비워 둔다. */
  .scene-help {
    display: inline-flex;
    left: calc(48px + min(var(--hud-w, 360px), 100% - 48px));
    right: 24px;
    bottom: 44px;
    justify-content: center;
    transform: none;
  }
  /* 포커스/입력 알약도 같은 띠의 중심축에 맞춘다(오른쪽 캡션과 겹치지 않게). */
  .interact-hint { left: calc((100% + 24px + min(var(--hud-w, 360px), 100% - 48px)) / 2); }
  .stage-caption { display: flex; }

  /* 조작 바: 게임 화면 왼쪽 가장자리에 붙는 패널. 채팅이 없어져 내용만큼만 높아진다
     (예전엔 위아래를 붙여 화면 끝까지 늘렸고, 그 빈 아래쪽이 크게 남았다).
     길어져도 예약 목록이 안에서 스크롤하므로 max-height 를 넘길 일이 드물고,
     넘기더라도 자르지 않는다 — 볼륨 팝오버가 패널 아래로 내려오기 때문이다. */
  .theater-hud {
    left: 24px;
    right: auto;
    top: 24px;
    bottom: auto;
    width: min(var(--hud-w, 360px), calc(100% - 48px));
    max-height: calc(100% - 48px);
  }

  /* 패널이 위쪽을 잘라 내므로 볼륨 팝오버는 아래로 펼친다(모바일은 위로 펼친다). */
  .hud-volume-pop {
    bottom: auto;
    top: calc(100% + 8px);
  }

  .hud-head { display: flex; }

  .reaction-toasts { bottom: 150px; }

  .mobile-stage-controls { display: none; }

  .landing-overlay {
    align-items: center;
    justify-content: flex-start;
    padding: 24px;
    background: linear-gradient(90deg, rgba(4, 8, 10, .55), transparent 62%);
  }

  .landing-card { width: min(380px, 46%); padding: 22px; }

  .closet-body { grid-template-columns: minmax(0, .92fr) minmax(0, 1fr); }
  .closet-preview { min-height: 300px; }
  #closet-canvas { min-height: 300px; }
  .closet-panel { max-height: 300px; }

  .help-grid { grid-template-columns: 1fr 1fr; gap: 18px; }
}

@media (min-width: 1020px) {
  :root { --pad: 24px; --hud-w: 360px; }

  /* 게임 화면이 작업대 높이를 그대로 쓴다 — 옆 레일이 없어졌으므로 한 칸이다. */
  .workspace {
    height: calc(100dvh - 66px);
    min-height: 620px;
    padding: 16px var(--pad) 18px;
  }

  .stage-column,
  .stage-wrap { height: 100%; min-height: 0; }

  .stage-wrap { height: 100%; }
}

/* 낮은 화면(노트북 가로): 조작 바가 빽빽해지므로 목록·간격만 살짝 줄인다. */
@media (max-height: 720px) and (min-width: 720px) {
  .queue-list { max-height: 84px; }
  .theater-hud { gap: 6px; padding: 9px; }
  .hud-video input, .hud-video .button { height: 32px; min-height: 32px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    scroll-behavior: auto !important;
    transition: none !important;
    animation: none !important;
  }
}

/* --------------------------------------------------------------------------
   둘러보기 모드(모바일 전용)
   · 데스크톱은 켤 것이 없다 — 캔버스 위 마우스 이동이 곧 시점이다(engine/input.js).
   · 모바일은 조작 줄의 '둘러보기' 토글 버튼(ui/look.js 가 만든다)이 이 상태를 켠다.
-------------------------------------------------------------------------- */
.look-guide {
  position: absolute;
  z-index: 7;
  left: 50%;
  max-width: min(92%, 420px);
  margin: 0;
  padding: 7px 14px;
  color: #f6ecdd;
  border: 1px solid rgba(201, 160, 99, .32);
  border-radius: 999px;
  background: rgba(8, 14, 17, .74);
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.4;
  text-align: center;
  transform: translateX(-50%);
  pointer-events: none;
  backdrop-filter: blur(10px);
}

.look-guide { bottom: 18px; }

/* 넓은 화면: 커서/둘러보기 알약은 단축키 줄과 같은 오른쪽 띠에서 그 '위'에 선다.
   기본 규칙(50%·18px)이 이 미디어 쿼리보다 위에 있어 여기서 덮어쓴다.
   예전에는 알약도 아래 18px 가운데 정렬이라 단축키 줄 왼쪽을 덮었다.
   가운데를 띠의 중심으로 옮기고(왼쪽 조작 바를 넘지 않게) 폭도 띠 안으로 묶는다.
   bottom 90px = 단축키 줄(아래 44px + 높이 ~34px) + 12px 여백. */
@media (min-width: 720px) {
  .look-guide {
    left: calc((100% + 24px + min(var(--hud-w, 360px), 100% - 48px)) / 2);
    bottom: 90px;
    max-width: calc(100% - 72px - min(var(--hud-w, 360px), 100% - 48px));
  }
}

#look-toggle-mobile[aria-pressed="true"] {
  color: #241a10;
  border-color: var(--brass);
  background: var(--brass);
}

/* 모바일: 둘러보기 토글이 점프·앉기 줄 아래 자기 줄에 서서 다른 버튼과 겹치지 않는다. */
.mobile-look-row { align-items: stretch; }
#look-toggle-mobile { min-width: 88px; }

/* 모바일 둘러보기 중: 무대 오버레이는 거두고 안내만 남긴다. */
.stage-wrap.is-look-mode .theater-hud,
.stage-wrap.is-look-mode .mobile-stage-controls,
.stage-wrap.is-look-mode .stage-heading,
.stage-wrap.is-look-mode .zone-badge,
.stage-wrap.is-look-mode .scene-badge,
.stage-wrap.is-look-mode .scene-help,
.stage-wrap.is-look-mode .stage-caption {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* 터치 둘러보기: 손가락이 화면을 밀어도 새로고침·스크롤이 일어나지 않게. */
.stage-wrap.is-look-mode #cinema-scene { touch-action: none; }

/* 데스크톱: 캔버스 위 마우스 이동이 곧 시점이라 커서가 화면을 가린다 — 캔버스 위에서만 숨긴다.
   HUD·버튼·패널은 캔버스 위 별도 요소라 그 위로 가면 커서가 다시 보인다. */
@media (hover: hover) and (pointer: fine) {
  #cinema-scene canvas { cursor: none; }
  /* 커서 모드(Alt·Esc): 시점이 멈추고 커서가 돌아온다. */
  .stage-wrap.is-cursor-mode #cinema-scene canvas { cursor: default; }
}

@media (max-width: 719px) {
  /* 좁은 화면: 조작 바는 무대 위가 아니라 무대 바로 아래 본문 흐름에 선다.
     무대는 그만큼 넓게 쓰고(3D 뷰를 가리지 않는다), 페이지는 필요할 때만 민다. */
  .workspace { padding-bottom: 10px; }

  .stage-wrap {
    height: clamp(300px, 56svh, 520px);
  }

  .hud-dock:empty { display: none; }

  .theater-hud {
    position: static;
    width: auto;
    margin: 10px 0 0;
    /* 내용만큼만 서고, 넘치면 안에서 스크롤한다(페이지 끝까지 늘어나지 않게). */
    max-height: none;
  }

  /* 무대 아래에서는 머리줄(접기 단추)이 있어야 본문을 접을 수 있다. */
  .hud-head { display: flex; }

  /* 무대 밖에 있으므로 투영 중 반투명 처리는 하지 않는다(영상과 겹치지 않는데 흐려질 이유가 없다). */
  .stage-wrap.is-projected .theater-hud { opacity: 1; }

  /* 접으면 패널이 사라지고 무대 가장자리의 '조작 ▸' 손잡이만 남는다.
     .hud-dock 은 #theater-hud 의 새 부모라 접힘 클래스가 여기에도 붙는다(ui/index.js). */
  .hud-dock.hud-collapsed .theater-hud { display: none; }

  /* 볼륨 팝오버: 무대 아래 띠에서는 단추 위로, 가로로 펼친다.
     세로로 길게 펼치면 패널이 페이지 맨 아래라 화면 밖으로 넘치고, 무대 가장자리의
     조이스틱 자리까지 올라와 겹친다. 가로 슬라이더는 조작 줄 바로 위(패널 안)에서 끝난다. */
  .hud-volume-pop {
    left: 0;
    right: auto;
    bottom: calc(100% + 8px);
    top: auto;
    width: 132px;
    height: 40px;
    padding: 0 10px;
    transform: none;
  }

  .hud-volume-pop input[type="range"] {
    width: 104px;
    height: 18px;
    transform: none;
  }

  /* 좁은 화면은 모바일 조작 줄의 토글이 둘러보기를 맡는다.
     안내는 무대 아래 가장자리에 세우고, 힌트 알약과 같은 줄을 쓰므로
     힌트가 떠 있는 동안에는 한 칸 더 올린다(둘 다 떠도 서로 덮지 않게).
     조작 바가 무대 밖으로 나가 --hud-offset 은 0 이지만, JS 가 늦게 갱신해도
     겹치지 않도록 변수를 그대로 더한다. */
  .mobile-look-row .mobile-action { min-height: 40px; padding: 6px 10px; }
  .look-guide { bottom: calc(var(--hud-offset, 0px) + 18px); }
  .interact-hint:not([hidden]) ~ .look-guide { bottom: calc(var(--hud-offset, 0px) + 46px); }

  /* 랜딩하는 동안 무대 위에 있던 장식 제목은 입장하면 거둔다(3D 뷰를 가리지 않게).
     랜딩 시트 자체는 overlay 가 맡는다. */
  .stage-wrap.is-entered .stage-heading { display: none; }
}

/* --------------------------------------------------------------------------
   터치 기기(폰을 가로로 눕힌 경우 포함)
   · 판정은 폭이 아니라 주 입력이다 — (hover: none) and (pointer: coarse).
     가로 폰(812×375 등)은 폭이 720px 을 넘어 데스크톱 규칙이 걸리므로, 마우스용
     배치(왼쪽 세로 HUD 패널·무대 위 R/F 키 안내)와 좁은 화면용 조작 줄(조이스틱·버튼)이
     서로 겹치고 버튼이 사라졌다. 여기서 '터치 = 조작 줄 + 무대 아래 HUD'로 통일한다.
   · 데스크톱(마우스)은 폭과 무관하게 그대로다 — 이 블록은 거친 포인터에서만 걸린다.
   · 위치가 아래쪽에서 결정되므로 반드시 파일 끝(기존 @media 뒤)에 둔다.
-------------------------------------------------------------------------- */
@media (hover: none) and (pointer: coarse) {
  /* 세로 폰과 같은 기본형: 무대 바로 아래 본문 흐름에 HUD 띠, 조이스틱·버튼은 무대 위. */
  .stage-wrap.is-projected .theater-hud { opacity: 1; }

  /* 무대 위 R/F 키 안내·장식 캡션은 손가락 기기에서 쓸 일이 없다. */
  .scene-help,
  .stage-caption { display: none; }

  /* 상호작용 힌트: 손가락으로 눌러 E 를 쓰는 알약이므로 누를 수 있어야 하고,
     가로 폰에서도 화면 가운데(무대 위)에 서야 한다 — 데스크톱 규칙은 HUD 패널 폭을
     비켜 오른쪽으로 밀어 두었다. */
  .interact-hint {
    left: 50%;
    max-width: calc(100% - 24px);
    pointer-events: auto;
  }

  /* 둘러보기 안내도 가운데 아래에(넓은 터치 화면에서 오른쪽 띠로 밀리지 않게). */
  .look-guide {
    left: 50%;
    bottom: calc(var(--hud-offset, 0px) + 18px);
    max-width: min(92%, 420px);
  }

  /* 손가락용으로 조금 키운 기본 크기(세로 폰 규칙과 같은 값을 여기서도 보장한다). */
  .mobile-action {
    flex: 0 0 auto;
    min-width: 0;
    padding: 8px 5px;
    font-size: 11px;
    white-space: nowrap;
    word-break: keep-all;
  }
  .mobile-item-action { padding: 8px 6px; }
  .mobile-action-row { flex-wrap: wrap; row-gap: 5px; }

  /* HUD 는 폭과 무관하게 무대 아래(#hud-dock)에 선다. 배치는 ui/index.js placeHud() 가 맡는다.
     (데스크톱 규칙은 무대 위 왼쪽 세로 패널이다.) */
  .theater-hud {
    position: static;
    width: auto;
    max-height: none;
    margin: 10px 0 0;
  }
  .hud-head { display: flex; }
  .hud-dock.hud-collapsed .theater-hud { display: none; }

  /* 볼륨 팝오버는 단추 위로 가로로 편다(무대 아래 띠에서 화면 밖으로 넘치지 않게).
     좁은 화면 규칙과 같은 모양이라 세로↔가로 전환이 매끄럽다. */
  .hud-volume-pop {
    left: 0;
    right: auto;
    bottom: calc(100% + 8px);
    top: auto;
    width: 132px;
    height: 40px;
    padding: 0 10px;
    transform: none;
  }
  .hud-volume-pop input[type="range"] {
    width: 104px;
    height: 18px;
    transform: none;
  }
}

/* 조작 줄 세 줄 쌓기 → 두 줄로 감기.
   기본 .mobile-actions 는 세로 column 이라 짧은 무대에서 줄이 위로 길게 올라오고, 맨 윗줄
   (R/F)은 오른쪽 위 가방(핫바) 뒤로 숨어 눌리지 않는다. 줄을 가로로 감아 두 줄로 끝낸다
   — 주 버튼 다섯(점프·앉기·웅크리기·1인칭·얼굴)이 첫 줄, R·F 와 '둘러보기' 가 둘째 줄.
   적용 범위: 넓은 터치 기기(가로·세로 모두) + 폭과 무관하게 짧은 가로 화면(568×320 등).
   세로 폰(375×812)은 column 그대로 — 원래 세 줄이 화면 아래에 여유 있게 들어간다. */
@media (hover: none) and (pointer: coarse) and (min-width: 720px),
       (hover: none) and (pointer: coarse) and (orientation: landscape) and (max-height: 520px) {
  .mobile-actions {
    flex-flow: row wrap;
    align-items: flex-end;
    justify-content: flex-end;
    gap: 6px;
    /* 묶음 폭을 220px 로 잡아 두 줄로 감는다. 폭을 풀어 두면 세 줄이 한 줄로 늘어서
       무대 가운데까지 뻗는다. */
    max-width: min(220px, calc(100% - 120px));
  }
  .mobile-actions > .mobile-action-row:not(.mobile-look-row) { order: 1; flex: none; }
  .mobile-actions > .mobile-item-actions { order: 2; flex: none; }
  .mobile-actions > .mobile-look-row { order: 3; flex: none; }
  /* 버튼 줄은 폭이 모자라면 접는다(잘리느니 여러 줄이 낫다). */
  .mobile-action-row { flex-wrap: wrap; row-gap: 5px; }
}

/* 넓은 터치 기기·가로 폰: 조작 줄을 되살리고 무대를 화면 비율로 키운다.
   판정은 폭이 아니라 주 입력이다. 세로 폰(≤719px)은 위 규칙 그대로 둔다. */
@media (hover: none) and (pointer: coarse) and (min-width: 720px) {
  /* 데스크톱 규칙이 조작 줄을 숨긴다 — 되살린다. */
  .mobile-stage-controls { display: flex; }

  /* HUD 가 무대 밖(#hud-dock)이라 '작업대 높이 고정'(min-width:1020px)을 풀고,
     세로 폰과 같은 비율로 무대를 키운다. */
  .workspace { height: auto; min-height: 0; }
  .stage-wrap { height: clamp(300px, 56svh, 520px); }
}

/* 짧은 가로 화면(폰을 눕힌 812×375·844×390·915×412 등, 높이 ≤ 520px)
   · 상단 바가 두 줄로 접히면 100px 를 먹어 무대가 화면 밖으로 밀린다 → 한 줄로 눕힌다.
     폭과 무관하게 적용한다 — 667×375·568×320 같은 작은 가로 폰도 같은 이유로
     무대 바닥과 조작 줄이 화면 밖으로 나갔다.
   · 아래쪽(무대를 100svh 로 키우고 조이스틱 여백을 줄이는 것)은 폭이 넓은 가로 폰
     (720px 이상)에만 — 좁은 화면은 세로 폰 규칙의 무대 높이를 그대로 두고 상한만 건다. */
@media (hover: none) and (pointer: coarse) and (orientation: landscape) and (max-height: 520px) {
  .topbar {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 0;
    padding: 6px 12px;
  }
  .brand { flex: none; }
  .brand-orb { width: 26px; height: 26px; }
  .brand-copy { font-size: 13px; }
  .brand-copy small { display: none; }
  /* 방 정보는 남기되 한 줄로 자른다(세 줄로 접히면 막대가 다시 두꺼워진다). */
  .topbar-room {
    flex: 0 1 auto;
    min-width: 0;
    flex-wrap: nowrap;
    overflow: hidden;
  }
  .room-name { min-width: 0; font-size: 12px; }
  .topbar-actions {
    flex: 1 1 auto;
    min-width: 0;
    flex-wrap: nowrap;
    padding-bottom: 0;
  }
  .icon-button { min-height: 32px; min-width: 32px; padding: 5px 7px; }
  /* 손가락 기기에는 Tab 키가 없다 — 키캡만 걷어 폭을 아낀다. */
  .icon-button kbd { display: none; }

  /* 무대 높이는 '남은 화면'을 넘지 않게 — 좁은 가로 폰(568×320 등)은 300px 하한만으로는
     무대 바닥이 화면 밖으로 나가 조작 줄 아래쪽이 잘렸다. 넓은 화면(720px 이상)은
     아래 블록이 100svh 로 다시 잡으므로 여기서는 상한 핀만 건다. */
  .stage-wrap { height: min(clamp(300px, 56svh, 520px), calc(100svh - 64px)); }
}

@media (hover: none) and (pointer: coarse) and (min-width: 720px) and (orientation: landscape) and (max-height: 520px) {
  .workspace { height: auto; min-height: 0; padding-top: 8px; }
  .stage-wrap { height: calc(100svh - 64px); min-height: 220px; }
  .mobile-stage-controls { inset: auto 0 10px; }

  /* 짧은 무대에서는 조이스틱 쪽 여백을 조금 덜 잡아 버튼 묶음을 오른쪽에 더 붙인다. */
  .mobile-actions { max-width: min(220px, calc(100% - 108px)); }

  /* 상호작용 힌트는 무대 가운데가 아니라 조이스틱과 버튼 사이 아래쪽에(짧은 무대에서
     가운데를 덮지 않게). 조작 줄 바로 위에 앉는다. */
  .interact-hint {
    top: auto;
    bottom: calc(10px + 96px + 8px);
    max-width: calc(100% - 232px);
  }
}


