/* 1. 글로벌 테마 및 리셋 */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  user-select: none;
}

body, html {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: #0b0f19;
  /* 여름 카툰 테마 — 본문은 고운돋움(둥글고 순한 한글), 숫자·라틴은 Outfit 폴백 */
  font-family: 'Noto Sans KR', 'Outfit', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: #f3f4f6;
}

canvas {
  display: block;
  width: 100%;
  height: 100%;
  background-color: #050202;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
}

/* 2. 오버레이 공통 스타일 (Glassmorphism) */
:root {
  --overlay-pad: 40px;   /* .overlay 위아래 여백 — 높이 단계별로 줄인다 */
  --panel-pad: 40px;     /* .glass-panel 안쪽 여백 — 하단 고정 버튼이 이 값을 되물린다 */
}

.overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  /* 여름 들판 — 인게임과 같은 잔디 베이크를 깔고 위를 따뜻하게 밝힌다 */
  background: radial-gradient(ellipse at 50% 18%, rgba(255, 244, 197, 0.34) 0%, rgba(38, 68, 30, 0.18) 62%, rgba(20, 40, 18, 0.42) 100%),
              url('assets/generated/arena-summer.png') center center / 720px 720px repeat;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  z-index: 10;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  overflow-y: auto;
  padding: var(--overlay-pad) 0;
  opacity: 1;
  transition: opacity 0.3s ease;
}

.hidden {
  display: none !important;
  opacity: 0;
  pointer-events: none;
}

.glass-panel {
  background: rgba(12, 18, 32, 0.82);
  border: 1px solid rgba(96, 165, 250, 0.14);
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(148, 197, 255, 0.12);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: 24px;
  padding: var(--panel-pad);
  text-align: center;
  max-width: 480px;
  width: 90%;
  margin: auto;
}

/* 3. 대기/스타트 스크린 */
.skull-emblem {
  font-size: 3.8rem;
  margin-bottom: 5px;
  filter: drop-shadow(0 0 15px rgba(239, 68, 68, 0.65));
  animation: skullPulse 1.8s infinite ease-in-out;
  display: inline-block;
}

@keyframes skullPulse {
  0% { transform: scale(0.95); filter: drop-shadow(0 0 10px rgba(239, 68, 68, 0.5)); }
  50% { transform: scale(1.05); filter: drop-shadow(0 0 25px rgba(239, 68, 68, 0.9)); }
  100% { transform: scale(0.95); filter: drop-shadow(0 0 10px rgba(239, 68, 68, 0.5)); }
}

.logo {
  font-size: 3.5rem;
  font-weight: 800;
  letter-spacing: 4px;
  background: linear-gradient(135deg, #ff3333 0%, #8b0000 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  margin-bottom: 8px;
  text-shadow: 0 0 25px rgba(239, 68, 68, 0.4);
}

.tagline {
  color: #9ca3af;
  margin-bottom: 35px;
  font-size: 1.05rem;
}

.input-group {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 480px;   /* 왼쪽 칸이 넓어져도 닉네임 입력·버튼은 적당한 폭 유지 (서버 목록은 넓게) */
}

#username-input {
  background: rgba(17, 24, 39, 0.8);
  border: 2px solid rgba(239, 68, 68, 0.2);
  border-radius: 12px;
  padding: 16px 20px;
  font-size: 1.1rem;
  color: #fff;
  outline: none;
  text-align: center;
  transition: border-color 0.2s, box-shadow 0.2s;
}

/* 관전자 모드에서 이름은 '관전자'로 고정된다 — 잠긴 상태를 눈으로 알려준다 */
#username-input.is-locked {
  color: #4facfe;
  border-color: rgba(79, 172, 254, 0.45);
  background: rgba(79, 172, 254, 0.08);
  cursor: not-allowed;
}

#username-input:focus {
  border-color: #ef4444;
  box-shadow: 0 0 15px rgba(239, 68, 68, 0.3);
}

#start-button, .accent-btn {
  background: linear-gradient(135deg, #dc2626 0%, #7f1d1d 100%);
  border: none;
  border-radius: 12px;
  padding: 16px;
  font-size: 1.1rem;
  font-weight: 700;
  color: #f3f4f6;
  cursor: pointer;
  transition: transform 0.1s, box-shadow 0.2s;
  box-shadow: 0 8px 20px rgba(220, 38, 38, 0.25);
}

#start-button:hover, .accent-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 25px rgba(220, 38, 38, 0.4);
}

#start-button:active, .accent-btn:active {
  transform: translateY(0);
}

.controls-guide {
  background: rgba(17, 24, 39, 0.4);
  border-radius: 16px;
  padding: 20px;
  text-align: left;
  border: 1px solid rgba(255, 255, 255, 0.03);
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

.controls-guide h3 {
  font-size: 1rem;
  margin-bottom: 12px;
  color: #e5e7eb;
}

.controls-guide ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.controls-guide li {
  font-size: 0.9rem;
  color: #9ca3af;
}

.controls-guide strong {
  color: #4facfe;
}

/* ── 메인(스타트) 화면 — 여름 들판 테마 ─────────────────────────────
   왼쪽에 닉네임·서버 목록을 세로로 쌓고 오른쪽에 간단 조작법.
   패널은 크림색 카드(어두운 글자), 하단에 4직업 치비 퍼레이드.
   대기실·결과 화면은 어두운 패널을 유지하므로 색은 #start-screen 에만 얹는다. */
.start-box {
  max-width: 1320px !important;   /* 1080 → 1320 (17차): 와이드 화면에서 좌우가 너무 비었다 */
  width: min(94vw, 1320px);
  /* .overlay 가 위아래 40px 씩 패딩을 주므로 그만큼 빼야 오버레이가 스크롤되지 않는다 */
  max-height: calc(100vh - 80px);
  padding: 26px 34px 14px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow: hidden;          /* 스크롤은 각 컬럼이 알아서 한다 */
}

#start-screen .glass-panel {
  background: rgba(253, 246, 225, 0.74);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  border: 3px solid rgba(122, 96, 48, 0.35);
  box-shadow: 0 24px 60px rgba(24, 42, 16, 0.45), inset 0 2px 0 rgba(255, 255, 255, 0.65);
  color: #3d3527;
}

.start-header {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  text-align: left;
  flex-shrink: 0;
}

.mascot-emblem {
  height: 88px;
  image-rendering: auto;
  filter: drop-shadow(0 6px 8px rgba(31, 54, 18, 0.35));
  animation: mascotBob 2.6s infinite ease-in-out;
}

@keyframes mascotBob {
  0%, 100% { transform: translateY(0) rotate(-3deg); }
  50% { transform: translateY(-6px) rotate(3deg); }
}

.start-title { display: flex; flex-direction: column; }

#start-screen .logo {
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-size: 2.7rem;
  font-weight: 400;
  letter-spacing: 2px;
  background: none;
  color: #203b2b;
  -webkit-text-fill-color: currentColor;
  text-shadow: 0 1px 1px rgba(255, 253, 244, 0.7);
  margin-bottom: 2px;
}

#start-screen .tagline {
  margin-bottom: 0;
  font-size: 0.95rem;
  color: #7d7053;
}

.start-grid {
  display: grid;
  /* 왼쪽(닉네임·서버목록)을 유동으로 크게, 조작법 가이드는 고정 폭으로 작게 */
  grid-template-columns: minmax(0, 1fr) minmax(260px, 340px);
  gap: 16px;
  flex: 1;
  min-height: 0;
  text-align: left;
}

/* 왼쪽 세로 스택: 닉네임 카드 + 서버 목록 카드 */
.start-stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-height: 0;
  min-width: 0;
}

.start-col--rooms { flex: 1; }

.start-col {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
  min-width: 0;
  background: rgba(255, 253, 244, 0.74);
  border: 2px solid rgba(150, 122, 68, 0.28);
  border-radius: 18px;
  padding: 16px 18px;
}

/* 조작법은 이미 컬럼이 판을 깔았으므로 자기 배경은 벗긴다 (이중 카드 방지) */
.start-col .controls-guide {
  background: none;
  border: none;
  border-radius: 0;
  padding: 0;
}

.start-col-title,
#start-screen .room-list-header h3,
#start-screen .controls-guide h3 {
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-size: 1.05rem;
  font-weight: 400;
  color: #4a5f2a;
}

#start-screen .controls-guide { overflow-y: auto; }
#start-screen .controls-guide h3 { margin-bottom: 8px; }
#start-screen .controls-guide h3 + ul { margin-bottom: 14px; }
#start-screen .controls-guide li { color: #6b5f47; font-size: 0.92rem; line-height: 1.5; }
#start-screen .controls-guide strong { color: #3f7d23; }

/* 입력·버튼·체크박스 — 크림 카드 위의 순한 톤 */
#start-screen #username-input,
#start-screen #room-name-input {
  background: #fffdf4;
  border: 2px solid rgba(150, 122, 68, 0.35);
  color: #3d3527;
}

#start-screen #username-input::placeholder,
#start-screen #room-name-input::placeholder { color: #a89a78; }

#start-screen #username-input:focus,
#start-screen #room-name-input:focus:not(:disabled) {
  border-color: #6cbb45;
  box-shadow: 0 0 12px rgba(108, 187, 69, 0.35);
}

#start-screen .accent-btn {
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-weight: 400;
  letter-spacing: 1px;
  background: linear-gradient(180deg, #7cc24f 0%, #4c8a2e 100%);
  color: #fffef6;
  box-shadow: 0 6px 0 #3a6b22, 0 10px 18px rgba(58, 107, 34, 0.35);
}

#start-screen .accent-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 8px 0 #3a6b22, 0 14px 22px rgba(58, 107, 34, 0.45);
}

#start-screen .accent-btn:active:not(:disabled) {
  transform: translateY(3px);
  box-shadow: 0 3px 0 #3a6b22, 0 6px 12px rgba(58, 107, 34, 0.4);
}

#start-screen .accent-btn:disabled { opacity: 0.55; box-shadow: none; }

#start-screen .checkbox-label { color: #6b5f47; }

#start-screen .refresh-btn {
  background: #fffdf4;
  border: 2px solid rgba(150, 122, 68, 0.35);
  color: #4a5f2a;
}

#start-screen .room-list-container {
  background: rgba(244, 234, 205, 0.65);
  border: 2px dashed rgba(150, 122, 68, 0.3);
  border-radius: 14px;
}

#start-screen .no-rooms-msg { color: #a3936f; }

#start-screen .room-item {
  background: #fffdf4;
  border: 2px solid rgba(150, 122, 68, 0.25);
}

#start-screen .room-item:hover {
  border-color: #6cbb45;
  background: #f4fbea;
}

#start-screen .room-item-name { color: #3d3527; }
#start-screen .room-item-count,
#start-screen .room-item-teams { color: #7d7053; }

/* 시그니처 — 네 캐릭터가 잔디 띠 양 끝에서 방향을 바꿔 달린다. */
.char-parade {
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: 40px;
  padding: 4px 0 10px;
  background: linear-gradient(180deg, transparent 0%, transparent 58%, rgba(124, 184, 69, 0.35) 59%, rgba(96, 152, 52, 0.5) 100%);
  border-radius: 0 0 14px 14px;
}

.char-parade img {
  height: 98px;
  image-rendering: auto;
  filter: drop-shadow(0 5px 5px rgba(31, 54, 18, 0.3));
  flex-shrink: 0;
}

@media (prefers-reduced-motion: reduce) {
  .char-parade img, .mascot-emblem { animation: none; }
}

.start-box .footer-copyright {
  margin-top: 0;
  flex-shrink: 0;
}

#start-screen .footer-copyright { color: #414a36; }
#start-screen .footer-copyright .build-tag { opacity: 0.85; }

/* 좁은 화면에서는 조작법이 아래로 내려간다.
   (14차) 1열로 서면 세로로 길어져 오히려 잘림이 심해지므로 940px 까지는 2열을 지킨다 */
@media (max-width: 940px) {
  .start-grid { grid-template-columns: 1fr; }
  .start-col--guide { max-height: 32vh; }
  .char-parade { display: none; }
}

@media (max-width: 720px) {
  .start-box { max-height: none; overflow-y: auto; }
  .start-header { flex-direction: column; text-align: center; gap: 8px; }
  .start-col--guide { max-height: none; }
}


/* 4. 게임 HUD 플레이 상태 */
#game-ui {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 5;
  pointer-events: none;
}

/* HUD 패널 공통 */
.hud-panel {
  position: absolute;
  background: rgba(15, 23, 42, 0.75);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 16px;
  padding: 16px;
  pointer-events: auto;
  box-shadow: 0 10px 30px rgba(0,0,0,0.3);
}

/* 접속 유저 현황 (좌측 상단) */
.stats-panel {
  top: 20px;
  left: 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  color: #d1d5db;
}

.stat-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.stat-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
}

.stat-dot.total { background: #38bdf8; box-shadow: 0 0 8px #38bdf8; }
.stat-dot.survivors { background: #4ade80; box-shadow: 0 0 8px #4ade80; }
.stat-dot.dead { background: #f87171; box-shadow: 0 0 8px #f87171; }

.danger-banner {
  width: 196px;
  background: linear-gradient(135deg, rgba(220, 38, 38, 0.95) 0%, rgba(153, 27, 27, 0.95) 100%);
  border: 1.5px solid #ef4444;
  box-shadow: 0 4px 15px rgba(239, 68, 68, 0.3);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 0.72rem;
  font-weight: 800;
  color: #ffffff;
  pointer-events: auto;
  text-align: center;
  white-space: normal;
  line-height: 1.4;
  animation: dangerPulse 1.5s infinite alternate;
  z-index: 6;
}

@keyframes dangerPulse {
  from { transform: scale(1); box-shadow: 0 0 10px rgba(239, 68, 68, 0.3); }
  to { transform: scale(1.03); box-shadow: 0 0 20px rgba(239, 68, 68, 0.55); }
}

/* 우측 상단 그룹 (미니맵 + 킬피드) */
.top-right-group {
  position: absolute;
  top: 20px;
  right: 20px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 16px;
  z-index: 6;
}

/* 미니맵 */
.minimap-container {
  background: rgba(15, 23, 42, 0.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 2px solid rgba(255, 255, 255, 0.1);
  border-radius: 16px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  pointer-events: auto;
  box-shadow: 0 10px 30px rgba(0,0,0,0.3);
}

.minimap-container canvas {
  position: relative;
  background: #090c15;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.05);
}

.minimap-label {
  font-size: 0.65rem;
  font-weight: 800;
  color: #9ca3af;
  margin-top: 6px;
  letter-spacing: 1.5px;
}

/* 킬 피드 */
.kill-feed {
  width: 280px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  pointer-events: none;
}

.kill-item {
  background: rgba(15, 23, 42, 0.85);
  border-left: 4px solid #ef4444;
  padding: 10px 14px;
  border-radius: 6px;
  font-size: 0.85rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: space-between;
  animation: slideInRight 0.3s forwards, fadeOut 0.5s 4.5s forwards;
  box-shadow: 0 4px 10px rgba(0,0,0,0.2);
}

@keyframes slideInRight {
  from { transform: translateX(50px); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}

@keyframes fadeOut {
  to { opacity: 0; transform: translateY(-10px); }
}

/* 캐릭터 상태 (좌측 하단) */
/* 좌하단 스택 — 아군 상태 HUD가 캐릭터 패널 위에 얹힌다.
   각자 absolute 좌표를 잡으면 캐릭터 패널 높이가 바뀔 때마다 겹치므로 flex로 쌓는다. */
.hud-left-bottom {
  position: absolute;
  left: 20px;
  bottom: 20px;
  width: 320px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 12px;
  pointer-events: none;   /* 자식 패널만 마우스를 받는다 */
  z-index: 5;
}

.char-panel {
  position: static;       /* .hud-left-bottom 이 배치를 담당 */
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.player-profile {
  display: flex;
  align-items: center;
  gap: 12px;
}

.level-badge {
  background: #ffcc00;
  color: #111827;
  font-weight: 800;
  font-size: 0.85rem;
  padding: 4px 8px;
  border-radius: 6px;
  box-shadow: 0 0 10px rgba(255, 204, 0, 0.3);
}

.player-names {
  display: flex;
  flex-direction: column;
}

.char-name {
  font-size: 1.1rem;
  font-weight: 700;
  color: #fff;
}

.kills-badge {
  font-size: 0.75rem;
  color: #ef4444;
  font-weight: 800;
  letter-spacing: 0.5px;
}

/* ❤️ 목숨 표시 (한눈에 보이도록 별도 강조) */
.lives-display {
  margin-left: auto;
  font-size: 1.3rem;
  letter-spacing: 2px;
  background: rgba(239, 68, 68, 0.1);
  border: 1px solid rgba(239, 68, 68, 0.3);
  border-radius: 10px;
  padding: 4px 10px;
  white-space: nowrap;
  filter: drop-shadow(0 0 6px rgba(239, 68, 68, 0.5));
}

/* 프로그레스 바 공통 */
.bar-container {
  position: relative;
  width: 100%;
  height: 20px;
  background: rgba(17, 24, 39, 0.8);
  border: 1px solid rgba(255,255,255,0.05);
  border-radius: 6px;
  overflow: hidden;
}

.bar-fill {
  height: 100%;
  transition: width 0.1s ease-out;
}

.bar-text {
  position: absolute;
  width: 100%;
  text-align: center;
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.75rem;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}

.hp-fill {
  background: linear-gradient(90deg, #ef4444, #f87171);
  box-shadow: 0 0 10px rgba(239, 68, 68, 0.3);
}

.xp-fill {
  background: linear-gradient(90deg, #10b981, #34d399);
  box-shadow: 0 0 10px rgba(16, 185, 129, 0.3);
}

/* 장비 그리드 */
.gear-status h4 {
  font-size: 0.8rem;
  color: #9ca3af;
  margin-bottom: 8px;
  letter-spacing: 0.5px;
}

.gear-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr); /* 4열 -> 3열로 변경하여 3x2 정렬 */
  gap: 6px;
}

.gear-slot {
  background: rgba(17, 24, 39, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 8px;
  padding: 6px;
  text-align: center;
  font-size: 0.95rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
}

/* 주무기 전용 슬롯 데코레이션 */
.gear-slot.weapon-slot {
  border-color: rgba(251, 191, 36, 0.5); /* 골드 네온 보더 */
  background: rgba(251, 191, 36, 0.1);
}

.gear-slot.weapon-slot .gear-lvl {
  color: #fbbf24;
  font-weight: 700;
}

.gear-lvl {
  font-size: 0.65rem;
  font-weight: 700;
  color: #9ca3af;
}

.gear-slot.active-upgrade {
  border-color: rgba(79, 172, 254, 0.5);
  background: rgba(79, 172, 254, 0.1);
}

.gear-slot.active-upgrade .gear-lvl {
  color: #38bdf8;
}

/* 5. 레벨업 업그레이드 선택 - 하단 상시 UI (비블로킹) */
.upgrade-bar {
  position: fixed;
  left: 50%;
  bottom: 130px;
  transform: translateX(-50%);
  z-index: 8;
  display: flex;
  align-items: center;
  gap: 12px;
  background: rgba(22, 14, 14, 0.85);
  border: 1px solid rgba(255, 204, 0, 0.3);
  border-radius: 16px;
  padding: 10px 16px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
  pointer-events: auto;
  animation: scaleUp 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes scaleUp {
  from { transform: translateX(-50%) scale(0.9); opacity: 0; }
  to { transform: translateX(-50%) scale(1); opacity: 1; }
}

.upgrade-bar-label {
  font-weight: 800;
  color: #ffcc00;
  text-shadow: 0 0 10px rgba(255, 204, 0, 0.4);
  font-size: 0.85rem;
  white-space: nowrap;
}

.upgrade-bar-badge {
  background: rgba(255, 51, 102, 0.15);
  border: 1px solid rgba(255, 51, 102, 0.3);
  color: #ff3366;
  font-size: 0.75rem;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 12px;
  white-space: nowrap;
}

.upgrade-bar-cards {
  display: flex;
  gap: 8px;
}

/* 무기 강화가 레벨 조건 때문에 카드에서 빠져 있을 때의 안내.
   조용히 사라지면 "왜 안 나오지"가 되므로 언제 다시 나오는지를 적는다. */
.upgrade-bar-gate {
  font-size: 0.72rem;
  font-weight: 700;
  color: #94a3b8;
  background: rgba(148, 163, 184, 0.1);
  border: 1px solid rgba(148, 163, 184, 0.2);
  border-radius: 10px;
  padding: 5px 9px;
  white-space: nowrap;
}

.upgrade-mini-card {
  position: relative;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  padding: 6px 10px;
  cursor: pointer;
  transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 84px;
}

.mini-hotkey {
  position: absolute;
  top: -8px;
  right: -6px;
  min-width: 16px;
  text-align: center;
  background: #ffcc00;
  color: #111827;
  font-size: 0.55rem;
  font-weight: 800;
  padding: 1px 5px;
  border-radius: 6px;
  box-shadow: 0 0 6px rgba(255, 204, 0, 0.4);
}

.upgrade-mini-card:hover {
  transform: translateY(-4px);
  border-color: #ffcc00;
  box-shadow: 0 8px 18px rgba(255, 204, 0, 0.2);
}

.upgrade-mini-card .mini-icon {
  font-size: 1.5rem;
}

.upgrade-mini-card .mini-name {
  font-size: 0.68rem;
  font-weight: 700;
  color: #fff;
  text-align: center;
}

.upgrade-mini-card .mini-lvl {
  font-size: 0.6rem;
  color: #ffcc00;
}

/* 6. 게임 오버 화면 */
.gameover-box {
  border-color: rgba(239, 68, 68, 0.3) !important;
}

.gameover-title {
  font-size: 3rem;
  font-weight: 800;
  color: #ef4444;
  text-shadow: 0 0 25px rgba(239, 68, 68, 0.4);
  margin-bottom: 12px;
}

.gameover-msg {
  color: #9ca3af;
  margin-bottom: 30px;
}

.summary-stats {
  display: flex;
  justify-content: space-around;
  background: rgba(17, 24, 39, 0.5);
  border-radius: 16px;
  padding: 20px;
  margin-bottom: 30px;
}

.summary-item {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.summary-item .label {
  font-size: 0.85rem;
  color: #9ca3af;
}

.summary-item .value {
  font-size: 1.5rem;
  font-weight: 800;
  color: #fff;
}

#respawn-button {
  width: 100%;
}

/* 시작 무기 선택 UI 스타일 */
.start-weapon-container {
  text-align: left;
  margin-top: 15px;
  width: 100%;
}

.start-weapon-label {
  font-size: 0.95rem;
  font-weight: 700;
  color: #d1d5db;
  margin-bottom: 8px;
  letter-spacing: 0.5px;
}

.start-weapon-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.start-weapon-card {
  background: rgba(17, 24, 39, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 12px;
  padding: 12px 8px;
  cursor: pointer;
  text-align: center;
  transition: transform 0.2s, border-color 0.2s, box-shadow 0.2s;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.start-weapon-card:hover {
  transform: translateY(-3px);
  border-color: rgba(251, 191, 36, 0.4);
}

.start-weapon-card.active {
  border-color: #fbbf24;
  background: rgba(251, 191, 36, 0.08);
  box-shadow: 0 0 15px rgba(251, 191, 36, 0.2);
}

.start-weapon-icon {
  font-size: 2.2rem;
}

.start-weapon-name {
  font-size: 0.85rem;
  font-weight: 800;
  color: #ffffff;
}

.start-weapon-desc {
  font-size: 0.65rem;
  color: #9ca3af;
  line-height: 1.3;
}

/* [신설] 제한시간 타이머 스타일 */
.top-center-group {
  position: absolute;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  z-index: 6;
  gap: 8px;
  pointer-events: none;
}

.timer-display {
  background: rgba(15, 23, 42, 0.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  padding: 8px 20px;
  font-size: 1.3rem;
  font-weight: 800;
  color: #fbbf24;
  text-shadow: 0 0 10px rgba(251, 191, 36, 0.4);
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
  pointer-events: auto;
}

/* [신설] 우승 세레머니 화면 스타일 */
.victory-box {
  border-color: rgba(251, 191, 36, 0.4) !important;
  box-shadow: 0 20px 50px rgba(251, 191, 36, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

.victory-title {
  font-size: 3.5rem;
  font-weight: 800;
  color: #fbbf24;
  text-shadow: 0 0 30px rgba(251, 191, 36, 0.6);
  margin-bottom: 12px;
}

.victory-msg {
  color: #e5e7eb;
  margin-bottom: 30px;
  font-size: 1.05rem;
}

/* scaleUp 은 레벨업 바(left:50% + translateX(-50%)) 전용이라 translateX 가 들어 있다.
   승리창은 flex 로 가운데 정렬되므로 그 키프레임을 쓰면 0.3초간 폭의 절반만큼 왼쪽에
   떴다가 제자리로 튄다 (13차 수정) — translate 없는 panelPopIn 을 쓴다 */
.animate-victory {
  animation: victoryPulse 2s infinite alternate, panelPopIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes panelPopIn {
  from { transform: scale(0.9); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

@keyframes victoryPulse {
  from { box-shadow: 0 20px 50px rgba(251, 191, 36, 0.15); }
  to { box-shadow: 0 20px 60px rgba(251, 191, 36, 0.35); }
}

/* [신설] 하단 HUD 통합 스타일 (소모품 + 스킬) */
.bottom-center-hud {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 20px;
  pointer-events: auto;
  z-index: 6;
}

/* 스킬 바 */
.skill-bar {
  background: rgba(15, 23, 42, 0.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 16px;
  padding: 10px 16px;
  display: flex;
  gap: 12px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.4);
}

.skill-slot {
  position: relative;
  width: 72px;
  height: 72px;
  background: rgba(17, 24, 39, 0.8);
  border: 2px solid rgba(56, 189, 248, 0.3); /* 연파랑 보더 */
  box-shadow: 0 0 8px rgba(56, 189, 248, 0.15);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  transition: border-color 0.25s, box-shadow 0.25s, filter 0.25s;
}

/* 스킬 잠금 해제 활성화 */
.skill-slot.unlocked {
  border-color: #38bdf8;
  box-shadow: 0 0 12px rgba(56, 189, 248, 0.3);
  background: rgba(56, 189, 248, 0.05);
}

/* 3차 전직 궁극기 특화 */
.skill-slot[data-skill="E"].unlocked {
  border-color: #f59e0b; /* 황금색 */
  box-shadow: 0 0 15px rgba(245, 158, 11, 0.3);
  background: rgba(245, 158, 11, 0.05);
}

/* 대시 스킬 특화 (초록 계열) */
.skill-slot[data-skill="Space"] {
  border-color: #10b981;
  box-shadow: 0 0 12px rgba(16, 185, 129, 0.3);
  background: rgba(16, 185, 129, 0.05);
}

.skill-slot[data-skill="Space"] .skill-num {
  color: #10b981;
}

/* 스킬 미각성 상태 */
.skill-slot.locked {
  border-color: rgba(255, 255, 255, 0.05);
  filter: grayscale(1);
  opacity: 0.6;
}

.skill-num {
  position: absolute;
  top: 4px;
  left: 6px;
  font-size: 0.65rem;
  font-weight: 800;
  color: #38bdf8;
  background: rgba(0,0,0,0.4);
  padding: 1px 4px;
  border-radius: 4px;
}

.skill-slot[data-skill="E"] .skill-num {
  color: #f59e0b;
}

.skill-icon {
  font-size: 1.6rem;
  margin-top: 4px;
}

.skill-name {
  font-size: 0.65rem;
  font-weight: 700;
  color: #9ca3af;
  margin-top: 2px;
  text-align: center;
}

.skill-slot.unlocked .skill-name {
  color: #e5e7eb;
}

/* 쿨타임 딤드 오버레이 효과 */
.skill-cooldown-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 0%; /* JS에서 동적으로 설정 */
  background: rgba(15, 23, 42, 0.75);
  transition: height 0.1s linear;
  pointer-events: none;
}

.skill-cooldown-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 1.1rem;
  font-weight: 800;
  color: #ffcc00;
  text-shadow: 0 2px 4px rgba(0,0,0,0.9);
  pointer-events: none;
}

/* 대기실 듀오 팀 선택 UI */
.lobby-team-section {
  margin: 16px 0;
  padding: 12px;
  background: rgba(15, 23, 42, 0.4);
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.05);
}

.lobby-team-section h3 {
  font-size: 0.9rem;
  color: #9ca3af;
  margin-bottom: 8px;
  text-align: center;
}

/* 🚩 LoL 스타일 팀 보드 */

/* 헤더 부제 — 허용 조합을 상시 노출 */
.team-rule {
  font-size: 0.72rem;
  font-weight: 600;
  color: #94a3b8;
  margin-left: 6px;
}

/* 시작 가능 여부 실시간 배너 */
.team-start-status {
  text-align: center;
  font-size: 0.82rem;
  font-weight: 700;
  padding: 7px 10px;
  border-radius: 8px;
  margin-bottom: 10px;
  background: rgba(239, 68, 68, 0.1);
  border: 1px solid rgba(239, 68, 68, 0.35);
  color: #fca5a5;
}

.team-start-status.ok {
  background: rgba(16, 185, 129, 0.12);
  border-color: rgba(16, 185, 129, 0.45);
  color: #6ee7b7;
}

/* 미선택 영역을 라벨과 함께 명확히 구분 */
.team-unassigned-wrap {
  background: rgba(15, 23, 42, 0.35);
  border: 1px dashed rgba(148, 163, 184, 0.28);
  border-radius: 10px;
  padding: 7px 9px;
  margin-bottom: 10px;
}

.team-unassigned-label {
  font-size: 0.7rem;
  font-weight: 700;
  color: #94a3b8;
  text-align: center;
  margin-bottom: 5px;
  letter-spacing: 0.5px;
}

/* 팀별 인원 카운터 */
.team-count {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  color: #cbd5e1;
  background: rgba(255, 255, 255, 0.07);
  border-radius: 10px;
  padding: 1px 8px;
  margin-left: 4px;
  vertical-align: middle;
}

.team-count.full {
  background: rgba(239, 68, 68, 0.18);
  color: #fca5a5;
}

/* 팀 컬럼에 소속 색을 입혀 좌우 구분을 강화 */
.team-column-1 {
  border: 1px solid rgba(239, 68, 68, 0.3);
  box-shadow: inset 0 0 22px rgba(239, 68, 68, 0.06);
}

.team-column-2 {
  border: 1px solid rgba(59, 130, 246, 0.3);
  box-shadow: inset 0 0 22px rgba(59, 130, 246, 0.06);
}

/* 본인 카드 강조 — 내가 어느 팀인지 즉시 식별 */
.team-member-card.is-self {
  border-color: rgba(34, 211, 238, 0.7);
  box-shadow: 0 0 10px rgba(34, 211, 238, 0.25);
}

.self-badge {
  display: inline-block;
  font-size: 0.62rem;
  font-weight: 800;
  background: #22d3ee;
  color: #06283d;
  border-radius: 8px;
  padding: 0 6px;
  margin-left: 5px;
  vertical-align: middle;
}

.team-unassigned-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-height: 10px;
  margin-bottom: 10px;
  justify-content: center;
}

.team-board {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.team-column {
  background: rgba(15, 23, 42, 0.5);
  border-radius: 10px;
  padding: 8px;
  min-height: 90px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.team-column-header {
  text-align: center;
  font-weight: 800;
  font-size: 0.9rem;
  padding: 4px 0 8px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  margin-bottom: 2px;
}

.team-header-1 {
  color: #ef4444;
}

.team-header-2 {
  color: #3b82f6;
}

.team-member-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 8px;
  padding: 6px 8px;
  font-size: 0.8rem;
  font-weight: 600;
}

.team-member-card.is-host {
  border-color: rgba(251, 191, 36, 0.35);
}

.team-member-card.is-bot {
  border-color: rgba(148, 163, 184, 0.35);
}

.team-card-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.team-mini-controls {
  display: flex;
  gap: 3px;
  flex-shrink: 0;
}

.team-mini-btn {
  width: 20px;
  height: 20px;
  border-radius: 5px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  background: rgba(31, 41, 55, 0.8);
  color: #9ca3af;
  font-size: 0.7rem;
  font-weight: 800;
  cursor: pointer;
  line-height: 1;
}

.team-mini-btn:hover {
  border-color: rgba(255, 255, 255, 0.4);
}

.team-mini-btn.active:nth-child(1) {
  background: rgba(239, 68, 68, 0.25);
  border-color: #ef4444;
  color: #ef4444;
}

.team-mini-btn.active:nth-child(2) {
  background: rgba(59, 130, 246, 0.25);
  border-color: #3b82f6;
  color: #3b82f6;
}

/* 7. 멀티 매칭 시스템 추가 스타일 */
.room-action-section {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
}

/* 🎓 튜토리얼 버튼 */
.tutorial-btn {
  width: 100%;
  border: 2px solid rgba(96, 165, 250, 0.55) !important;
  color: #bfdbfe !important;
}

/* ── 🎓 튜토리얼 말풍선 ──
   화면 정중앙에 선 내 캐릭터 머리 위에 떠서 꼬리가 캐릭터를 가리킨다.
   본체는 클릭을 통과시키고(공격 조준을 막지 않도록) 버튼만 받는다. */
.tut-bubble {
  position: fixed;
  left: 50%;
  top: calc(50% - 205px);
  transform: translateX(-50%);
  z-index: 230;
  display: flex;
  gap: 12px;
  align-items: flex-start;
  width: min(520px, calc(100vw - 32px));
  padding: 14px 16px 12px;
  background: linear-gradient(160deg, rgba(255, 251, 235, 0.98) 0%, rgba(254, 243, 199, 0.98) 100%);
  border: 3px solid #b45309;
  border-radius: 18px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35), inset 0 0 0 2px rgba(255, 255, 255, 0.6);
  color: #3b2a12;
  font-size: 0.95rem;
  line-height: 1.5;
  pointer-events: none;
  animation: tutPop 0.28s ease-out;
}
@keyframes tutPop { from { opacity: 0; transform: translate(-50%, 10px) scale(0.96); } to { opacity: 1; transform: translate(-50%, 0) scale(1); } }
.tut-bubble .tut-tail {
  position: absolute;
  left: 50%;
  bottom: -18px;
  width: 0; height: 0;
  transform: translateX(-50%);
  border-left: 14px solid transparent;
  border-right: 14px solid transparent;
  border-top: 18px solid #b45309;
}
.tut-bubble .tut-tail::after {
  content: '';
  position: absolute;
  left: -10px; top: -19px;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-top: 14px solid #fef3c7;
}
.tut-avatar {
  flex: 0 0 auto;
  width: 46px; height: 46px;
  display: grid; place-items: center;
  font-size: 1.7rem;
  background: #fde68a;
  border: 2px solid #d97706;
  border-radius: 50%;
}
.tut-body { flex: 1 1 auto; min-width: 0; }
.tut-title { font-weight: 900; font-size: 0.8rem; letter-spacing: 0.04em; color: #b45309; margin-bottom: 4px; text-transform: uppercase; }
.tut-text { font-weight: 600; word-break: keep-all; }
.tut-text b, .tut-text kbd {
  display: inline-block;
  padding: 0 6px;
  border-radius: 6px;
  background: #1f2937;
  color: #fde68a;
  font-weight: 800;
  font-family: inherit;
  line-height: 1.35;
}
.tut-progress {
  margin-top: 8px;
  font-weight: 900;
  font-size: 0.85rem;
  color: #92400e;
}
.tut-actions { display: flex; align-items: center; gap: 10px; margin-top: 10px; pointer-events: auto; }
.tut-next {
  padding: 8px 18px;
  border: 0;
  border-radius: 10px;
  background: linear-gradient(135deg, #f59e0b, #d97706);
  color: #fff;
  font-weight: 900;
  font-size: 0.9rem;
  cursor: pointer;
  box-shadow: 0 3px 0 #92400e;
}
.tut-next:active { transform: translateY(2px); box-shadow: 0 1px 0 #92400e; }
.tut-skip {
  margin-left: auto;
  padding: 4px 8px;
  border: 0;
  background: transparent;
  color: #92400e;
  font-size: 0.75rem;
  font-weight: 700;
  text-decoration: underline;
  cursor: pointer;
  opacity: 0.8;
}
/* 칭찬 상태 — 초록으로 바뀌며 살짝 튄다 */
.tut-bubble.is-praise {
  background: linear-gradient(160deg, rgba(240, 253, 244, 0.98) 0%, rgba(187, 247, 208, 0.98) 100%);
  border-color: #15803d;
  color: #14532d;
  animation: tutPraise 0.45s ease-out;
}
.tut-bubble.is-praise .tut-tail { border-top-color: #15803d; }
.tut-bubble.is-praise .tut-tail::after { border-top-color: #bbf7d0; }
.tut-bubble.is-praise .tut-title { color: #15803d; }
.tut-bubble.is-praise .tut-avatar { background: #bbf7d0; border-color: #15803d; }
@keyframes tutPraise { 0% { transform: translate(-50%, 0) scale(0.96); } 50% { transform: translate(-50%, -8px) scale(1.03); } 100% { transform: translate(-50%, 0) scale(1); } }

/* 목표 화살표 — 수호자 위치를 가리킨다. 화면 밖이면 가장자리에 붙어 방향만 알린다 */
.tut-arrow {
  position: fixed;
  left: 0; top: 0;
  z-index: 225;
  font-size: 2.4rem;
  color: #fbbf24;
  text-shadow: 0 0 6px #000, 0 0 14px rgba(251, 191, 36, 0.8);
  pointer-events: none;
  transform-origin: center;
  animation: tutArrowPulse 0.7s ease-in-out infinite alternate;
}
@keyframes tutArrowPulse { from { opacity: 0.75; } to { opacity: 1; } }

/* 스탯 설명 단계 — 캐릭터 패널을 금색 테두리로 짚어 준다 */
.tut-highlight { outline: 4px solid #fbbf24 !important; outline-offset: 4px; box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.25) !important; animation: tutHl 0.9s ease-in-out infinite alternate; position: relative; z-index: 226; }
@keyframes tutHl { from { outline-color: #fbbf24; } to { outline-color: #fff7ed; } }

/* 종료 페이드 — 로비로 돌아가기 전 검게 잠긴다 */
.tut-fade {
  position: fixed;
  inset: 0;
  z-index: 260;
  background: #000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 1.1s ease;
}
.tut-fade.show { opacity: 1; pointer-events: auto; }

@media (max-height: 640px) {
  .tut-bubble { top: 70px; font-size: 0.85rem; }
}

/* 🧪 테스트 모드 버튼 — 개발용임이 한눈에 보이도록 점선 테두리 */
.test-mode-btn {
  width: 100%;
  border: 2px dashed rgba(250, 204, 21, 0.55) !important;
  color: #fde68a !important;
}

#room-name-input {
  width: 100%;
  box-sizing: border-box;
  background: rgba(17, 24, 39, 0.8);
  border: 2px solid rgba(79, 172, 254, 0.1);
  border-radius: 12px;
  padding: 14px 16px;
  font-size: 0.95rem;
  color: #fff;
  outline: none;
  transition: border-color 0.2s;
}

.mode-select {
  width: 100%;
  box-sizing: border-box;
  background: rgba(17, 24, 39, 0.8);
  border: 2px solid rgba(79, 172, 254, 0.1);
  border-radius: 12px;
  padding: 14px 16px;
  font-size: 0.95rem;
  color: #fff;
  outline: none;
  cursor: pointer;
  transition: border-color 0.2s;
}

#create-room-btn {
  width: 100%;
  box-sizing: border-box;
  padding: 14px;
}

.mode-select:focus:not(:disabled) {
  border-color: #ef4444;
}

#room-name-input:focus:not(:disabled) {
  border-color: #ef4444;
}

#room-name-input:disabled,
#create-room-btn:disabled,
#refresh-rooms-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  transform: none !important;
  box-shadow: none !important;
}

.room-list-section {
  text-align: left;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

.room-list-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.room-list-header h3 {
  font-size: 1rem;
  color: #e5e7eb;
}

.refresh-btn {
  background: rgba(79, 172, 254, 0.15);
  border: 1px solid rgba(79, 172, 254, 0.3);
  color: #38bdf8;
  border-radius: 8px;
  padding: 6px 12px;
  font-size: 0.8rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.2s, transform 0.1s;
}

.refresh-btn:hover:not(:disabled) {
  background: rgba(79, 172, 254, 0.3);
  transform: translateY(-1px);
}

.room-list-container {
  background: rgba(17, 24, 39, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 12px;
  flex: 1;
  min-height: 140px;         /* 항목 하나(이름·인원·팀 칩 3줄)가 잘리지 않고 다 보이는 높이 */
  overflow-y: auto;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.no-rooms-msg {
  text-align: center;
  color: #6b7280;
  font-size: 0.85rem;
  margin-top: 40px;
}

.room-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;                 /* 정보 칸과 참가 버튼 사이 — 좁아질 때 글자가 버튼에 닿지 않게 */
  background: rgba(30, 41, 59, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 8px;
  padding: 8px 12px;         /* 10/14 → 8/12: 낮은 창에서 항목 3줄이 컨테이너 안에 들어오게 */
  transition: border-color 0.2s;
}

.room-item:hover {
  border-color: rgba(79, 172, 254, 0.4);
}

.room-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;              /* flex 자식의 기본 min-width:auto 가 내용 폭을 고집해 오른쪽이 잘렸다 */
}

.room-item-name {
  font-size: 0.9rem;
  font-weight: 700;
  color: #fff;
}

.room-item-count {
  font-size: 0.75rem;
  color: #9ca3af;
  white-space: normal;       /* 관전자 수·마감 표기가 붙어 길어지면 줄을 바꾼다 */
  line-height: 1.35;
  overflow-wrap: anywhere;
}

/* 방 목록에 팀별 인원을 노출해 진입 전에 상황을 파악할 수 있게 함 */
.room-item-teams {
  display: flex;
  flex-wrap: wrap;           /* 팀 칩 두 개가 한 줄에 안 들어가면 아래로 */
  gap: 6px;
  margin-top: 3px;
}

.team-chip {
  font-size: 0.68rem;
  font-weight: 700;
  border-radius: 8px;
  padding: 1px 7px;
}

.team-chip-1 {
  background: rgba(239, 68, 68, 0.15);
  color: #fca5a5;
  border: 1px solid rgba(239, 68, 68, 0.3);
}

.team-chip-2 {
  background: rgba(59, 130, 246, 0.15);
  color: #93c5fd;
  border: 1px solid rgba(59, 130, 246, 0.3);
}

/* 정원이 찬 방은 흐리게 처리하고 참가 버튼을 잠근다 */
.room-item.room-full {
  opacity: 0.55;
}

.room-item.room-full:hover {
  border-color: rgba(255, 255, 255, 0.05);
}

.room-full-tag {
  font-size: 0.65rem;
  font-weight: 800;
  background: rgba(239, 68, 68, 0.2);
  color: #fca5a5;
  border: 1px solid rgba(239, 68, 68, 0.4);
  border-radius: 8px;
  padding: 0 6px;
  margin-left: 5px;
  vertical-align: middle;
}

.join-room-btn:disabled {
  background: rgba(100, 116, 139, 0.5);
  cursor: not-allowed;
  opacity: 0.7;
}

.join-room-btn {
  flex: 0 0 auto;
  white-space: nowrap;
  background: linear-gradient(135deg, #10b981 0%, #059669 100%);
  border: none;
  color: #fff;
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 0.8rem;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 4px 10px rgba(16, 185, 129, 0.2);
  transition: transform 0.1s;
}

.join-room-btn:hover {
  transform: translateY(-1px);
}

/* 대기실 (Lobby) */
.lobby-box {
  /* 세로로 길게 쌓이면 인원이 늘 때마다 스크롤이 생긴다. 가로로 넓게 펴서
     1팀 · 2팀 · 사이드(미선택·관전자·봇)를 한 화면에 나란히 둔다. */
  max-width: 1180px !important;
  width: min(96vw, 1180px);
  max-height: 92vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}

#lobby-room-name {
  font-size: 2rem;
  font-weight: 800;
  color: #38bdf8;
  margin-bottom: 4px;
}

#lobby-players-count {
  font-size: 0.95rem;
  color: #9ca3af;
  margin-bottom: 25px;
}

.lobby-members-section {
  text-align: left;
  background: rgba(17, 24, 39, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.05);
  border-radius: 16px;
  padding: 20px;
  margin-bottom: 25px;
}

.lobby-members-section h3 {
  font-size: 0.95rem;
  color: #d1d5db;
  margin-bottom: 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  padding-bottom: 8px;
}

.lobby-members-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 180px;
  overflow-y: auto;
}

.lobby-member-tag {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: rgba(30, 41, 59, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.03);
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 0.9rem;
  font-weight: 600;
  color: #fff;
}

.lobby-member-tag.is-host {
  border-color: rgba(251, 191, 36, 0.3);
  background: rgba(251, 191, 36, 0.05);
}

/* 🎥 관전자 슬롯 표기 */
.lobby-member-tag.is-observer {
  border-color: rgba(34, 211, 238, 0.35);
  background: rgba(34, 211, 238, 0.06);
}

/* 🤖 봇 표기 */
.lobby-member-tag.is-bot {
  border-color: rgba(148, 163, 184, 0.35);
  background: rgba(148, 163, 184, 0.06);
}

.host-badge {
  background: #fbbf24;
  color: #111827;
  font-size: 0.65rem;
  font-weight: 800;
  padding: 2px 6px;
  border-radius: 4px;
}

.lobby-member-tag.is-observer .host-badge {
  background: #22d3ee;
}

.lobby-member-tag.is-bot .host-badge {
  background: #94a3b8;
}

.lobby-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

/* 버튼이 패널 폭 전체로 늘어나 지나치게 길어 보였다.
   글자 길이에 맞추되 최소 폭만 확보해 누르기 편한 크기를 유지한다.
   대기 메시지는 안내문이므로 폭을 그대로 채운다. */
.lobby-actions .accent-btn,
.lobby-actions .danger-btn {
  width: auto;
  min-width: 200px;
  padding-left: 34px;
  padding-right: 34px;
}

.lobby-actions .waiting-msg {
  align-self: stretch;
}

.waiting-msg {
  color: #fbbf24;
  font-size: 0.9rem;
  font-weight: 700;
  padding: 14px;
  background: rgba(251, 191, 36, 0.05);
  border: 1px dashed rgba(251, 191, 36, 0.3);
  border-radius: 12px;
  text-align: center;
  animation: waitPulse 1.5s infinite alternate;
}

@keyframes waitPulse {
  from { opacity: 0.7; }
  to { opacity: 1; }
}

.danger-btn {
  background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
  border: none;
  color: #fff;
  border-radius: 12px;
  padding: 14px;
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(239, 68, 68, 0.2);
  transition: transform 0.1s;
}

.danger-btn:hover {
  transform: translateY(-2px);
}

/* 🤖 대기실 봇 추가/제거 */
.lobby-bot-section {
  margin: 16px 0;
  padding-top: 12px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.lobby-bot-controls {
  display: flex;
  gap: 10px;
  margin-top: 8px;
}

.secondary-btn {
  flex: 1;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.15);
  color: #f3f4f6;
  border-radius: 12px;
  padding: 10px;
  font-size: 0.9rem;
  font-weight: 700;
  cursor: pointer;
  transition: transform 0.1s, border-color 0.15s;
}

.secondary-btn:hover {
  transform: translateY(-2px);
  border-color: rgba(255, 204, 0, 0.4);
}

/* 직업 선택 */
.class-select-box {
  max-width: 580px !important;
}

#select-class-btn {
  width: 100%;
  margin-top: 25px;
}

.hidden-wait-msg {
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.hidden-wait-msg p {
  color: #fbbf24;
  font-weight: 700;
  font-size: 0.95rem;
}

/* 스피너 */
.spinner {
  width: 32px;
  height: 32px;
  border: 3px solid rgba(251, 191, 36, 0.1);
  border-top-color: #fbbf24;
  border-radius: 50%;
  animation: spin 1s infinite linear;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.hidden-wait-msg.hidden {
  display: none !important;
}

/* --- 🎥 7. 관전자(옵저버) 및 팀 HUD 스타일 --- */

/* 관전자 체크박스 */
.observer-checkbox-container {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: -8px;
  margin-bottom: 8px;
}

.checkbox-label {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: 0.95rem;
  color: #9ca3af;
  transition: color 0.2s;
}

.checkbox-label:hover {
  color: #4facfe;
}

.checkbox-label input[type="checkbox"] {
  display: none;
}

.custom-checkbox {
  width: 18px;
  height: 18px;
  border: 2px solid rgba(79, 172, 254, 0.4);
  border-radius: 4px;
  display: inline-block;
  position: relative;
  transition: background 0.2s, border-color 0.2s;
}

.checkbox-label input[type="checkbox"]:checked + .custom-checkbox {
  background: #4facfe;
  border-color: #00f2fe;
}

.checkbox-label input[type="checkbox"]:checked + .custom-checkbox::after {
  content: '✓';
  position: absolute;
  top: -2px;
  left: 3px;
  color: #fff;
  font-size: 0.8rem;
  font-weight: bold;
}

/* 👥 팀원 상태 HUD (좌측 하단 캐릭터 패널 위) */
.team-status-panel {
  position: static;       /* .hud-left-bottom 이 배치를 담당 */
  width: 100%;
  max-height: 34vh;
  overflow-y: auto;
  background: rgba(18, 25, 41, 0.75);
  border: 1px solid rgba(16, 185, 129, 0.2); /* 초록빛 테두리 */
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3), 0 0 10px rgba(16, 185, 129, 0.05);
}

.team-status-panel h4 {
  font-size: 0.9rem;
  margin-bottom: 10px;
  color: #10b981;
  letter-spacing: 1px;
}

.team-members-container {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.team-member-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px 10px;
  background: rgba(255, 255, 255, 0.03);
  border-radius: 8px;
  border-left: 3px solid #10b981;
}

.team-member-row.dead {
  border-left-color: #ef4444;
  opacity: 0.6;
}

.team-member-info {
  display: flex;
  justify-content: space-between;
  font-size: 0.85rem;
}

.team-member-name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 140px;
}

.team-member-hp-bar-bg {
  width: 100%;
  height: 6px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 3px;
  overflow: hidden;
}

.team-member-hp-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, #10b981 0%, #059669 100%);
  border-radius: 3px;
  transition: width 0.15s ease-out;
}

.team-member-row.dead .team-member-hp-bar-fill {
  background: #4b5563;
}

/* 🎥 옵저버 스코어보드 독 — LoL 관전 화면처럼 중앙 하단 가로 배치.
   예전에는 좌측 세로 사이드바(max-height:400px)라 10명이면 내용 592px 로 194px 이 잘려
   반드시 스크롤해야 했다. 팀을 좌우 두 열로 세우면 5행이면 끝나서 스크롤이 사라진다. */
/* 관전 HUD 의 옛 '하단 가로 독' 규칙은 14차 중계 HUD 개편에서 전부 대체되었다.
   (좌우 세로 레일 · 스코어 바 · TAB 상세표 — 파일 끝의 14차 블록 참조)
   남겨 두면 min-width 같은 잔여 선언이 새 규칙과 섞여 카드 폭을 밀어낸다. */

/* 좁은 화면에서는 팀을 위아래로 쌓는다 */
@media (max-width: 760px) {
  .obs-team-grid { grid-template-columns: 1fr; }
  .obs-player-row { grid-template-columns: 30px minmax(0, 1fr) 64px 46px; }
}

/* 8. 저작권 푸터 */
.footer-copyright {
  text-align: center;
  font-size: 0.8rem;
  color: rgba(156, 163, 175, 0.45);
  margin-top: 25px;
  pointer-events: none;
  font-family: 'Outfit', sans-serif;
  letter-spacing: 1px;
}




/* ── 아이템 즉시 발동 토스트 ─────────────────────────────
   아이템 슬롯/단축키가 폐지되어 무엇이 터졌는지 알 방법이 없으므로
   스킬 바 위쪽에 짧은 알림을 쌓아 보여준다. */
.item-toast-stack {
  position: absolute;
  bottom: 130px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: 6px;
  pointer-events: none;
  z-index: 8;
}

.item-toast {
  padding: 8px 18px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 15px;
  white-space: nowrap;
  color: #f8fafc;
  background: rgba(15, 23, 42, 0.9);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid currentColor;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.45);
  animation: itemToastIn 0.18s ease-out;
  transition: opacity 0.35s ease, transform 0.35s ease;
}

.item-toast.fade-out {
  opacity: 0;
  transform: translateY(-14px);
}

@keyframes itemToastIn {
  from { opacity: 0; transform: translateY(12px) scale(0.94); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ── 부쉬 은신 상태 표시 ─────────────────────────────────────────── */
/* 은신은 화면에서 즉시 알 수 있어야 한다. 부쉬 테두리 강조만으로는
   "지금 정말 안 보이는 상태인지"가 모호해 별도 배너를 둔다. */
.stealth-indicator {
  position: absolute;
  left: 50%;
  bottom: 190px;
  transform: translateX(-50%);
  padding: 7px 18px;
  border-radius: 999px;
  background: rgba(9, 32, 19, 0.82);
  border: 1px solid rgba(125, 255, 176, 0.55);
  color: #7dffb0;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-shadow: 0 0 10px rgba(125, 255, 176, 0.55);
  box-shadow: 0 0 22px rgba(45, 200, 120, 0.25);
  pointer-events: none;
  z-index: 40;
  animation: stealthPulse 1.6s ease-in-out infinite;
}

@keyframes stealthPulse {
  0%, 100% { opacity: 0.78; }
  50%      { opacity: 1; }
}

/* ── 피격 / 저체력 비네트 ────────────────────────────────────────── */
/* 체력이 위험한지 HUD 숫자를 확인하지 않고도 알 수 있어야 한다.
   opacity는 client.js가 매 프레임 계산해 넣는다. */
.hit-vignette {
  position: fixed;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  z-index: 25;
  background: radial-gradient(ellipse at center,
    rgba(255, 0, 0, 0) 42%,
    rgba(180, 0, 0, 0.35) 78%,
    rgba(130, 0, 0, 0.75) 100%);
  transition: opacity 90ms linear;
}

/* ── 정글 캠프 처치 버프 HUD ─────────────────────────────────────── */
/* 남은 시간이 보여야 "버프 있을 때 밀어붙일지"를 판단할 수 있다. */
.buff-bar {
  position: fixed;
  left: 50%;
  top: 96px;
  transform: translateX(-50%);
  display: flex;
  gap: 8px;
  pointer-events: none;
  z-index: 30;
}

.buff-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px 6px 9px;
  border-radius: 10px;
  background: rgba(9, 14, 25, 0.86);
  border: 1px solid var(--buff, #8b7cf6);
  box-shadow: 0 0 16px color-mix(in srgb, var(--buff, #8b7cf6) 35%, transparent);
  animation: buffIn 220ms ease-out;
}

.buff-icon { font-size: 18px; line-height: 1; }

.buff-text { display: flex; flex-direction: column; line-height: 1.2; }
.buff-text b { color: var(--buff, #8b7cf6); font-size: 12px; font-weight: 700; }
.buff-text i { color: #b8c4dc; font-size: 10px; font-style: normal; }

.buff-time {
  color: var(--buff, #8b7cf6);
  font: 700 14px/1 'Outfit', monospace;
  min-width: 30px;
  text-align: right;
}

@keyframes buffIn {
  from { opacity: 0; transform: translateY(-8px) scale(0.9); }
  to   { opacity: 1; transform: none; }
}

/* ── 승리 화면: 우승 팀 명단 ─────────────────────────────────────── */
/* 승리는 팀 단위이므로 누가 함께 이겼는지 보여야 한다. */
.victory-roster-title {
  margin: 18px 0 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 2px;
  color: #9fb3d0;
}

.victory-roster {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 190px;
  overflow-y: auto;
}

.victory-member {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.09);
  font-size: 13px;
}

.victory-member.is-me {
  background: rgba(251, 191, 36, 0.12);
  border-color: rgba(251, 191, 36, 0.5);
}

.victory-member .vm-rank { width: 22px; text-align: center; font-weight: 700; color: #fbbf24; }
.victory-member .vm-name { flex: 1; text-align: left; font-weight: 600; color: #eaf2ff; }
.victory-member .vm-stat { color: #9fb3d0; font-size: 12px; }
.victory-member .vm-down { color: #f87171; font-size: 11px; }

.victory-actions { margin-top: 18px; }

/* 인게임 승리 배너 — 오버레이가 뜨기 전에 화면에서 먼저 알린다 */
.victory-banner {
  position: fixed;
  left: 50%;
  top: 32%;
  transform: translate(-50%, -50%);
  padding: 18px 44px;
  border-radius: 16px;
  background: rgba(10, 16, 28, 0.86);
  border: 2px solid #fbbf24;
  box-shadow: 0 0 46px rgba(251, 191, 36, 0.45);
  color: #fbbf24;
  font-size: 34px;
  font-weight: 800;
  letter-spacing: 4px;
  text-align: center;
  pointer-events: none;
  z-index: 60;
  animation: victoryBannerIn 480ms cubic-bezier(.2, 1.4, .4, 1);
}

.victory-banner small {
  display: block;
  margin-top: 6px;
  font-size: 14px;
  letter-spacing: 1px;
  color: #ffe9b0;
  font-weight: 600;
}

@keyframes victoryBannerIn {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.7); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

/* ── 대기실: 가로 3열 레이아웃 ──────────────────────────────────── */
.lobby-header { margin-bottom: 10px; }
#lobby-room-name { margin-bottom: 2px; }
#lobby-players-count { margin-bottom: 0; }

.lobby-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 0.82fr;
  gap: 14px;
  align-items: start;
  margin: 14px 0 18px;
  text-align: left;
}

.lobby-grid .team-column {
  min-height: 330px;
  padding: 12px;
  gap: 8px;
}

.lobby-grid .team-column-header {
  font-size: 1rem;
  padding-bottom: 8px;
}

/* 폭이 넓어져 5명이 스크롤 없이 들어간다 */
.lobby-grid .team-column-list {
  display: flex;
  flex-direction: column;
  gap: 7px;
  max-height: none;
  overflow: visible;
}

.lobby-side {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.side-block {
  background: rgba(15, 23, 42, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 10px;
  padding: 10px 12px;
}

.side-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 0.82rem;
  font-weight: 700;
  color: #cbd5e1;
  margin-bottom: 8px;
}

.side-count { color: #94a3b8; font-weight: 600; }

.side-empty {
  color: #64748b;
  font-size: 0.78rem;
  text-align: center;
  padding: 8px 0;
}

.lobby-observer-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.lobby-side .lobby-member-tag {
  padding: 8px 10px;
  font-size: 0.82rem;
}

.lobby-side .lobby-bot-section {
  background: rgba(15, 23, 42, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 10px;
  padding: 10px 12px;
  margin: 0;
}

.lobby-side .lobby-bot-controls {
  display: flex;
  gap: 8px;
}

.lobby-side .lobby-bot-controls .secondary-btn {
  flex: 1;
  padding: 8px 4px;
  font-size: 0.8rem;
}

.lobby-side .team-rule {
  font-size: 0.74rem;
  color: #64748b;
  text-align: center;
  line-height: 1.5;
}

.team-start-status { margin-bottom: 0; }

/* 좁은 화면에서는 다시 세로로 접는다 */
@media (max-width: 900px) {
  .lobby-grid { grid-template-columns: 1fr; }
  .lobby-grid .team-column { min-height: 0; }
}

/* 패널 안 스크롤바를 얇고 어둡게 */
.lobby-box::-webkit-scrollbar { width: 7px; }
.lobby-box::-webkit-scrollbar-thumb {
  background: rgba(148, 163, 184, 0.28);
  border-radius: 4px;
}
.lobby-box::-webkit-scrollbar-track { background: transparent; }

/* ── FPS 미터 (우측 상단, 미니맵 위) ─────────────── */
#fps-meter {
  font: 700 0.78rem/1.4 'Cascadia Code', Consolas, monospace;
  color: #4ade80;
  background: rgba(10, 14, 25, 0.72);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  padding: 3px 10px;
  pointer-events: none;
  letter-spacing: 0.02em;
}
#fps-meter.fps-warn { color: #fbbf24; }
#fps-meter.fps-bad { color: #f87171; }

/* ══════════════════════════════════════════════════════════════════
   모바일 터치 조작 + 소형 화면 HUD 축소
   활성 조건: JS 가 터치 기기 감지 시 body.touch-device 부여
   ══════════════════════════════════════════════════════════════════ */

/* ── 터치 스틱 (시각 전용 — 터치 이벤트는 캔버스가 받는다) ── */
#touch-controls { position: fixed; inset: 0; pointer-events: none; z-index: 7; }
.touch-stick {
  position: absolute;
  width: 104px; height: 104px;
  margin: -52px 0 0 -52px;         /* 중심 기준 배치 */
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.25);
  background: rgba(15, 23, 42, 0.35);
}
.touch-stick .stick-knob {
  position: absolute;
  left: 50%; top: 50%;
  width: 46px; height: 46px;
  margin: -23px 0 0 -23px;
  border-radius: 50%;
  background: rgba(148, 163, 184, 0.55);
  border: 2px solid rgba(255, 255, 255, 0.5);
}
.touch-stick.aim .stick-knob {
  background: rgba(248, 113, 113, 0.5);   /* 조준 스틱 = 공격 톤 */
  border-color: rgba(248, 113, 113, 0.8);
}

/* ── 터치 기기 공통 ── */
body.touch-device { -webkit-tap-highlight-color: transparent; overscroll-behavior: none; }
body.touch-device #game-canvas { touch-action: none; }
/* 터치에서는 스킬 슬롯이 곧 버튼 — 탭 타깃 확보 */
body.touch-device .skill-slot { min-width: 56px; min-height: 56px; }
body.touch-device .bottom-center-hud { pointer-events: auto; }
/* 📱 스킬 버튼 드래그 조준 — 쥐고 있는 동안 밝게, 버튼 위로 되돌려 취소 대기면 붉게 */
body.touch-device .skill-slot.aiming {
  border-color: #f8fafc;
  box-shadow: 0 0 0 3px rgba(248, 250, 252, 0.35), 0 0 18px rgba(56, 189, 248, 0.6);
  transform: scale(1.06);
}
body.touch-device .skill-slot.aiming.cancel {
  border-color: #f87171;
  box-shadow: 0 0 0 3px rgba(248, 113, 113, 0.4), 0 0 18px rgba(248, 113, 113, 0.6);
  filter: grayscale(0.4);
}

/* ── 세로 모드 안내 (게임 중 + 세로 + 터치 기기) ── */
#rotate-hint {
  display: none;
  position: fixed; inset: 0; z-index: 60;
  background: rgba(5, 8, 15, 0.92);
  color: #e2e8f0;
  font: 700 1.1rem/1.6 Outfit, sans-serif;
  align-items: center; justify-content: center; text-align: center;
  padding: 24px;
}
@media (orientation: portrait) {
  /* 게임 화면뿐 아니라 시작 화면·대기실에서도 세로면 돌려 달라고 한다. 예전에는
     #game-ui 가 보일 때만 띄웠는데, 시작 화면이 세로에서 조작법 칸만 길게 늘어져
     닉네임·서버 목록을 쓸 수 없었다. #rotate-hint 는 화면 전체를 덮는 fixed 라
     어느 화면 위에도 그대로 덮인다. */
  body.touch-device #rotate-hint { display: flex; }
}

/* ── 폰 가로(게임 플레이) — HUD 압축 ── */
/* 터치 기기이면 화면이 커도 이 레이아웃을 쓴다. 예전에는 (max-height: 560px) 로 묶여
   있어, 펼친 폴더블처럼 세로가 긴 터치 기기에서는 하나도 걸리지 않았다. 그 결과
   좌하단 체력 패널이 이동 스틱 자리에 그대로 남아 조작을 가렸다.
   아래 규칙은 전부 body.touch-device 로 한정되어 있어 데스크톱에는 영향이 없다. */
  body.touch-device .stats-panel { transform: scale(0.75); transform-origin: top left; top: 8px; left: 8px; }
  body.touch-device .hud-left-bottom { transform: scale(0.62); transform-origin: bottom left; }
  /* 미니맵은 통째로 축소(scale 0.58)하면 정보가 안 읽힌다. 배치만 당기고
     크기는 client.js sizeMinimap() 이 캔버스 해상도로 잡는다 — 선명함이 유지된다. */
  body.touch-device .top-right-group { transform: none; top: 6px; right: max(6px, env(safe-area-inset-right)); gap: 4px; pointer-events: none; }
  body.touch-device .kill-feed { display: none; }  /* 폰 화면에선 소음 — 킬로그는 배너로 충분 */
  body.touch-device .top-center-group { transform: translateX(-50%) scale(0.78); transform-origin: top center; top: 6px; }
  /* HUD 패널이 터치를 삼키면 그 위에서 스틱을 시작할 수 없다 — 조작이 우선 */
  body.touch-device .stats-panel,
  body.touch-device .hud-left-bottom,
  body.touch-device .team-status-panel { pointer-events: none; }
  body.touch-device #fps-meter { display: none; }

  /* 스킬 바 = 터치 버튼: 오른쪽 세로 열, 엄지 닿는 자리 (조준 스틱 위) */
  body.touch-device .bottom-center-hud {
    left: auto; right: max(12px, env(safe-area-inset-right)); bottom: 12px;
    top: auto; transform: none; width: auto;
  }
  body.touch-device .skill-bar { flex-direction: column; padding: 8px; gap: 8px; }

  /* 레벨업 카드 — 하단 중앙 유지, 탭 타깃 축소 없이 컴팩트 */
  body.touch-device .upgrade-bar { transform: translateX(-50%) scale(0.85); transform-origin: bottom center; bottom: 6px; }

  body.touch-device .buff-bar { transform: scale(0.8); transform-origin: bottom left; }
  body.touch-device .stealth-indicator { transform: translateX(-50%) scale(0.85); }

/* ── 폰 세로(로비·로그인 메뉴) — 폼이 화면을 넘지 않게 ── */
@media (max-width: 600px) {
  body.touch-device .glass-panel { max-width: 94vw; --panel-pad: 18px; }
  body.touch-device input[type="text"] { font-size: 16px; }   /* iOS 포커스 줌 방지 */
  body.touch-device .accent-btn, body.touch-device .secondary-btn,
  body.touch-device .danger-btn, body.touch-device .refresh-btn { min-height: 44px; }
  body.touch-device .start-weapon-card { min-height: 44px; }
  body.touch-device .team-columns { flex-direction: column; }
}


/* =====================================================================
   여름 테마 확장 (2026-08-26) — 대기실·직업선택·인게임 HUD·결과창을
   메인 화면과 같은 크림 카드 + 잔디 배경 톤으로 통일한다.
   뒤에 붙는 동일 특이도 규칙이 이기는 캐스케이드를 이용한 오버라이드 모음.
   ===================================================================== */

/* ── 공통 패널 ── */
.glass-panel {
  background: rgba(253, 246, 225, 0.96);
  border: 3px solid rgba(122, 96, 48, 0.35);
  box-shadow: 0 24px 60px rgba(24, 42, 16, 0.45), inset 0 2px 0 rgba(255, 255, 255, 0.65);
  color: #3d3527;
}

.glass-panel h2, .glass-panel h3 {
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-weight: 400;
  color: #4a5f2a;
}

.glass-panel .tagline { color: #7d7053; }

.accent-btn {
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-weight: 400;
  letter-spacing: 1px;
  background: linear-gradient(180deg, #7cc24f 0%, #4c8a2e 100%);
  color: #fffef6;
  box-shadow: 0 6px 0 #3a6b22, 0 10px 18px rgba(58, 107, 34, 0.35);
}

.accent-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 8px 0 #3a6b22, 0 14px 22px rgba(58, 107, 34, 0.45);
}

.accent-btn:disabled { opacity: 0.55; box-shadow: none; }

.secondary-btn {
  background: #fffdf4;
  border: 2px solid rgba(150, 122, 68, 0.35);
  color: #4a5f2a;
}

.secondary-btn:hover { background: #f4fbea; border-color: #6cbb45; }

/* ── 대기실 ── */
.lobby-header h2 { font-size: 1.9rem; letter-spacing: 2px; }
.lobby-header p { color: #7d7053; }

.team-start-status {
  background: rgba(240, 180, 40, 0.16);
  border: 2px dashed rgba(150, 122, 68, 0.4);
  color: #8a6d1f;
}

.team-start-status.ok {
  background: rgba(124, 194, 79, 0.18);
  border-color: rgba(76, 138, 46, 0.5);
  color: #3f7d23;
}

.team-column {
  background: rgba(255, 253, 244, 0.9);
  border: 2px solid rgba(150, 122, 68, 0.28);
}

.team-column-1 { border-color: rgba(220, 90, 90, 0.45); }
.team-column-2 { border-color: rgba(80, 130, 220, 0.45); }

.team-column-header { color: #3d3527; background: none; }
.team-header-1 { color: #b0413e; }
.team-header-2 { color: #2f5f9e; }

.team-member-card {
  background: #fffdf4;
  border: 1px solid rgba(150, 122, 68, 0.25);
  color: #3d3527;
}

.team-member-card.is-self { border-color: #6cbb45; background: #f4fbea; }

.side-block {
  background: rgba(255, 253, 244, 0.9);
  border: 2px solid rgba(150, 122, 68, 0.28);
}

.side-title { color: #4a5f2a; font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif; font-weight: 400; }
.side-count { color: #7d7053; }
.team-rule { color: #a3936f; }
.lobby-observer-list, .lobby-observer-list * { color: #6b5f47; }

.waiting-msg { color: #8a6d1f; background: rgba(240, 180, 40, 0.14); border-radius: 12px; }

#start-screen .logo--illustrated {
  position: relative;
  width: min(440px, 70vw);
  aspect-ratio: 5.5;
  margin: 0 auto 4px;
  overflow: hidden;
  line-height: 0;
}
#start-screen .logo--illustrated img {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: auto;
  transform: translateY(-50%);
}
body.touch-device #start-screen .logo--illustrated {
  width: min(240px, 46vw);
  margin: 0 auto 2px;
}

#start-screen .logo-sub.logo-sub--illustrated {
  position: relative;
  width: min(300px, 55vw);
  aspect-ratio: 9.5;
  margin: 0 auto;
  overflow: hidden;
  background: none;
  line-height: 0;
}
#start-screen .logo-sub--illustrated img {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: auto;
  transform: translateY(-47.5%);
}
body.touch-device #start-screen .logo-sub.logo-sub--illustrated {
  width: min(180px, 36vw);
  margin: 0 auto;
}

/* ── 모바일 참가 QR ── */
.qr-block { text-align: center; }

.qr-wrap {
  position: relative;
  display: inline-block;
  margin: 6px auto 2px;
  padding: 6px;
  background: #fffdf4;
  border: 2px solid rgba(150, 122, 68, 0.35);
  border-radius: 12px;
  line-height: 0;
}

.qr-wrap canvas { width: 132px; height: 132px; image-rendering: pixelated; }

.qr-center-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 28px;
  height: 28px;
  border-radius: 6px;
  background: #fffdf4;
  padding: 2px;
  box-shadow: 0 0 0 2px rgba(150, 122, 68, 0.3);
}

.qr-hint { font-size: 0.78rem; color: #a3936f; line-height: 1.4; margin-top: 4px; }

/* ── 하드웨어 가속 안내 ── */
.hw-accel-notice {
  flex-shrink: 0;
  background: rgba(240, 180, 40, 0.18);
  border: 2px solid rgba(216, 150, 30, 0.5);
  border-radius: 12px;
  padding: 10px 16px;
  font-size: 0.9rem;
  color: #7a5a12;
  text-align: center;
}

.hw-accel-notice strong { color: #8a4d0f; }

/* ── 직업 선택 ── */
.class-select-box { max-width: 720px !important; }

.start-weapon-card {
  background: #fffdf4;
  border: 2px solid rgba(150, 122, 68, 0.28);
}

.start-weapon-card:hover { border-color: #6cbb45; transform: translateY(-3px); }

.start-weapon-card.active {
  border-color: #4c8a2e;
  background: #f4fbea;
  box-shadow: 0 0 16px rgba(108, 187, 69, 0.35);
}

.start-weapon-name { color: #3d3527; font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif; font-weight: 400; }
.start-weapon-desc { color: #7d7053; }

.class-portrait {
  position: relative;
  height: 104px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.class-portrait-img {
  height: 100px;
  filter: drop-shadow(0 4px 4px rgba(31, 54, 18, 0.3));
}

.class-weapon-badge {
  position: absolute;
  right: -6px;
  bottom: -4px;
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fffdf4;
  border: 2px solid rgba(150, 122, 68, 0.4);
  border-radius: 10px;
  box-shadow: 0 2px 5px rgba(31, 54, 18, 0.25);
}

.class-weapon-badge img {
  max-width: 30px;
  max-height: 26px;
  image-rendering: pixelated;
}

/* 서포터 뱃지(craftpix 물방울)는 벡터라 부드럽게 */
#support-class-card .class-weapon-badge img { image-rendering: auto; }

.hidden-wait-msg { color: #7d7053; }

/* ── 인게임 HUD ── */
.hud-panel {
  background: rgba(253, 246, 225, 0.92);
  border: 2px solid rgba(122, 96, 48, 0.35);
  box-shadow: 0 8px 20px rgba(24, 42, 16, 0.25);
  color: #3d3527;
}

.stat-row { color: #5c5138; }
.char-name { color: #3d3527; }
.hud-panel h4, .team-status-panel h4 { color: #4a5f2a; }
.team-member-name { color: #3d3527; }
.team-member-hp { color: #7d7053; }

.minimap-container {
  background: rgba(253, 246, 225, 0.92);
  border: 2px solid rgba(122, 96, 48, 0.35);
}

.minimap-label { color: #6b5f47; }

.timer-display {
  background: rgba(253, 246, 225, 0.95);
  border: 2px solid rgba(122, 96, 48, 0.4);
  color: #6d4708;
}

#fps-meter {
  background: rgba(253, 246, 225, 0.9);
  border: 1px solid rgba(122, 96, 48, 0.35);
}

.gear-slot {
  background: #fffdf4;
  border: 1px solid rgba(150, 122, 68, 0.3);
  color: #5c5138;
}

.gear-slot .gear-lvl { color: #6b5f47; }

.upgrade-bar {
  background: rgba(253, 246, 225, 0.94);
  border: 2px solid rgba(122, 96, 48, 0.4);
}

.upgrade-bar-label { color: #8a6d1f; }

.skill-bar {
  background: rgba(253, 246, 225, 0.9);
  border: 2px solid rgba(122, 96, 48, 0.35);
}

.skill-slot {
  background: #fffdf4;
  border: 2px solid rgba(150, 122, 68, 0.3);
}

.skill-slot .skill-name { color: #6b5f47; }

.item-toast-stack .item-toast,
.item-toast {
  background: rgba(253, 246, 225, 0.95);
  color: #3d3527;
  border: 2px solid rgba(122, 96, 48, 0.4);
}

/* ── 결과 화면 ── */
.gameover-title {
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-weight: 400;
}

.victory-title { font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif; font-weight: 400; }

.summary-stats {
  background: rgba(255, 253, 244, 0.9);
  border: 2px solid rgba(150, 122, 68, 0.28);
}

.summary-stats .label { color: #7d7053; }
.summary-stats .value { color: #3d3527; }
.victory-msg, .gameover-msg { color: #6b5f47; }
.victory-roster-title { color: #4a5f2a; }

.victory-roster .roster-row, .victory-roster > div {
  background: #fffdf4;
  border: 1px solid rgba(150, 122, 68, 0.25);
  color: #3d3527;
}

/* QR 캔버스는 게임 캔버스용 전역 canvas 규칙(absolute·100%)을 되돌린다 */
.qr-wrap canvas {
  position: static;
  display: block;
  width: 132px;
  height: 132px;
  background: none;
}

.lobby-side .lobby-bot-section,
.lobby-bot-section {
  background: rgba(255, 253, 244, 0.9);
  border: 2px solid rgba(150, 122, 68, 0.28);
  color: #3d3527;
}

/* 직업 4종을 한 줄에 — 3+1 줄바꿈은 서포터만 외톨이로 보인다 */
.class-select-box { max-width: 880px !important; }
.class-select-box .start-weapon-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 760px) {
  .class-select-box .start-weapon-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* 레벨업 미니 카드·스킬 슬롯 텍스트 — 크림 배경 위에서 어두운 잉크로 */
.upgrade-mini-card {
  background: #fffdf4;
  border: 2px solid rgba(150, 122, 68, 0.3);
}

.upgrade-mini-card:hover { border-color: #6cbb45; background: #f4fbea; }
.upgrade-mini-card .mini-name { color: #3d3527; }
.upgrade-mini-card .mini-lvl { color: #7d7053; }

.skill-slot .skill-name,
.skill-slot.unlocked .skill-name { color: #5c5138; }

.skill-slot[data-skill="Space"] {
  background: rgba(124, 194, 79, 0.14);
  border-color: #4c8a2e;
  box-shadow: 0 0 10px rgba(108, 187, 69, 0.3);
}

.skill-slot[data-skill="Space"] .skill-num { color: #3f7d23; background: rgba(255, 253, 244, 0.8); }
.skill-num { background: rgba(255, 253, 244, 0.85); color: #2f5f9e; }
.skill-slot[data-skill="E"] .skill-num { color: #b07a10; }
.skill-slot.locked { border-color: rgba(150, 122, 68, 0.2); }

/* =====================================================================
   실플레이 피드백 2차 (2026-08-26 밤)
   ===================================================================== */

/* ① 인게임 HUD 투명도 — 크림 판이 시야를 가리지 않게 낮춘다 */
.hud-panel { background: rgba(253, 246, 225, 0.76); }
.minimap-container { background: rgba(253, 246, 225, 0.78); }
.skill-bar { background: rgba(253, 246, 225, 0.72); }
.upgrade-bar { background: rgba(253, 246, 225, 0.85); }
.skill-slot { background: rgba(255, 253, 244, 0.75); }
.gear-slot { background: rgba(255, 253, 244, 0.7); }
#server-stats.hud-panel { background: rgba(253, 246, 225, 0.6); }
#fps-meter { background: rgba(253, 246, 225, 0.6); }

/* ② 대기실 팀칸 축소 — 5칸 기준 과했던 높이를 3칸 기준으로 */
.lobby-grid .team-column { min-height: 190px; }
.lobby-box { max-width: 980px !important; }

/* ③ 팀 이동 버튼 — "1|2" 미니 버튼을 대체하는 명시적 이동 버튼 */
.team-move-btn {
  margin-left: auto;
  padding: 4px 10px;
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-size: 0.78rem;
  color: #3f7d23;
  background: #f4fbea;
  border: 2px solid rgba(76, 138, 46, 0.45);
  border-radius: 999px;
  cursor: pointer;
  transition: transform 0.1s, background 0.15s;
  flex-shrink: 0;
}

.team-move-btn:hover { background: #e3f5d2; transform: translateY(-1px); }

.team-member-card { display: flex; align-items: center; gap: 8px; }

/* ④ 빨간 버튼·UI → 여름 팔레트의 진갈색/호박색 */
.danger-btn {
  background: linear-gradient(180deg, #c98a2e 0%, #a0672a 100%);
  border: none;
  color: #fff8ea;
  box-shadow: 0 5px 0 #7c4c1d, 0 8px 14px rgba(124, 76, 29, 0.35);
}

.danger-btn:hover {
  background: linear-gradient(180deg, #d69a3c 0%, #b07430 100%);
  box-shadow: 0 6px 0 #7c4c1d, 0 10px 16px rgba(124, 76, 29, 0.45);
}

.gameover-title { color: #a0672a; text-shadow: none; }
.team-header-1 { color: #c26b32; }
.team-column-1 { border-color: rgba(201, 138, 46, 0.5); }
.danger-banner {
  background: rgba(240, 180, 40, 0.9);
  color: #5c3d0a;
  border: 2px solid rgba(160, 103, 42, 0.6);
}

/* ⑤ 직업 뱃지 — 이전 선택창의 무기 이모지로 (도트 스프라이트는 작아서 안 읽혔다) */
.class-weapon-badge { font-size: 1.35rem; line-height: 1; }

/* 전적 행 텍스트 — 크림 배경 위 잉크색으로 */
.victory-member { background: #fffdf4; border: 1px solid rgba(150, 122, 68, 0.25); }
.victory-member .vm-name { color: #3d3527; }
.victory-member .vm-stat { color: #6b5f47; }
.victory-member .vm-rank { color: #8a6d1f; }
.victory-member.is-me { background: #fdf3d0; border-color: rgba(216, 150, 30, 0.55); }

/* ── 스킨 선택 (직업당 에셋 팩 2개일 때) ── */
.skin-picker {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin: 4px 0 10px;
}

.skin-picker-label {
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  color: #4a5f2a;
  font-size: 1rem;
}

.skin-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px 6px 8px;
  background: #fffdf4;
  border: 2px solid rgba(150, 122, 68, 0.3);
  border-radius: 14px;
  cursor: pointer;
  font-family: 'Noto Sans KR', sans-serif;
  font-size: 0.9rem;
  color: #6b5f47;
  transition: transform 0.1s, border-color 0.15s;
}

.skin-option img { height: 46px; }
.skin-option:hover { transform: translateY(-2px); border-color: #6cbb45; }

.skin-option.active {
  border-color: #4c8a2e;
  background: #f4fbea;
  color: #3f7d23;
  box-shadow: 0 0 10px rgba(108, 187, 69, 0.3);
}

/* 무기 뱃지가 이모지에서 실제 무기 아트로 — 벡터라 부드럽게 */
.class-weapon-badge img { max-width: 30px; max-height: 30px; image-rendering: auto; }

/* =====================================================================
   실플레이 피드백 3차 (2026-08-26 밤 2) — 정글 버튼 · 대기실 상하 팀 ·
   미니맵 반투명 · 로비 문구 정리
   ===================================================================== */

/* ── 정글 카툰 버튼 텍스처 (btn_green / btn_amber, 9-slice) ── */
.accent-btn, #start-button {
  border: 22px solid transparent;
  border-image: url('assets/craftpix/ui/btn_green.png') 56 fill / 22px stretch;
  background: none;
  border-radius: 0;
  padding: 2px 18px;
  color: #fffef6;
  text-shadow: 0 2px 0 rgba(38, 68, 20, 0.55);
  box-shadow: 0 6px 14px rgba(38, 68, 20, 0.3);
}

.accent-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  filter: brightness(1.07);
  box-shadow: 0 9px 18px rgba(38, 68, 20, 0.4);
}

.accent-btn:active:not(:disabled) { transform: translateY(1px); filter: brightness(0.97); }
.accent-btn:disabled { opacity: 0.55; box-shadow: none; }

.danger-btn {
  border: 22px solid transparent;
  border-image: url('assets/craftpix/ui/btn_amber.png') 56 fill / 22px stretch;
  background: none;
  border-radius: 0;
  padding: 2px 18px;
  color: #fff8ea;
  text-shadow: 0 2px 0 rgba(96, 58, 12, 0.55);
  box-shadow: 0 6px 14px rgba(96, 58, 12, 0.3);
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-weight: 400;
}

.danger-btn:hover { transform: translateY(-2px); filter: brightness(1.07); }

/* ── 대기실: 1팀/2팀 상하 배치, 사이드는 오른쪽 유지 ── */
.lobby-grid {
  grid-template-columns: minmax(0, 1fr) 300px;
  align-items: stretch;
}

.lobby-grid .team-column-1 { grid-column: 1; grid-row: 1; }
.lobby-grid .team-column-2 { grid-column: 1; grid-row: 2; }
.lobby-grid .lobby-side { grid-column: 2; grid-row: 1 / 3; }

.lobby-grid .team-column { min-height: 120px; }

/* 팀이 가로로 넓어졌으니 멤버 카드는 한 줄에 여러 장 흐르게 */
.lobby-grid .team-column-list {
  flex-direction: row;
  flex-wrap: wrap;
  align-content: flex-start;
}

.lobby-grid .team-member-card { flex: 0 1 240px; }

/* 게임 시작 / 방 나가기 가로 배치 */
.lobby-actions { flex-direction: row; justify-content: center; gap: 16px; }
.lobby-actions .waiting-msg { flex-basis: 100%; text-align: center; }

/* ── 미니맵: 여름 나무 프레임 + 투명도 50% ── */
.minimap-container {
  background: rgba(253, 246, 225, 0.5);
  border: 3px solid rgba(122, 96, 48, 0.5);
  border-radius: 16px;
  box-shadow: 0 6px 14px rgba(24, 42, 16, 0.2);
}

.minimap-container canvas {
  background: rgba(26, 42, 20, 0.5) !important;
  border-radius: 10px;
}

.minimap-label { color: rgba(107, 95, 71, 0.85); }

/* =====================================================================
   실플레이 피드백 4차 (2026-08-26 밤 3) — 숲 배경 일러스트 · 대기실 폭 축소 ·
   탈락 관전 배너
   ===================================================================== */

/* ── 메뉴 화면 배경 — 잔디 타일 대신 카툰 숲 정경 일러스트 ──
   화면마다 다른 정경(1: 메인 / 2: 대기실 / 3: 직업 선택 / 4: 결과)을 깔고,
   위에 옅은 비네트를 얹어 크림색 패널이 묻히지 않게 한다. */
.overlay {
  background-image:
    radial-gradient(ellipse at 50% 20%, rgba(255, 244, 197, 0.16) 0%, rgba(24, 46, 20, 0.14) 60%, rgba(14, 30, 12, 0.42) 100%),
    url('assets/craftpix/bg/forest_1.png');
  background-size: cover, cover;
  background-position: center center, center center;
  background-repeat: no-repeat, no-repeat;
}

#lobby-screen {
  background-image:
    radial-gradient(ellipse at 50% 20%, rgba(255, 244, 197, 0.16) 0%, rgba(24, 46, 20, 0.14) 60%, rgba(14, 30, 12, 0.42) 100%),
    url('assets/craftpix/bg/forest_2.png');
}

#class-select-screen {
  background-image:
    radial-gradient(ellipse at 50% 20%, rgba(255, 244, 197, 0.16) 0%, rgba(24, 46, 20, 0.14) 60%, rgba(14, 30, 12, 0.42) 100%),
    url('assets/craftpix/bg/forest_3.png');
}

/* 결과 화면은 전적에 시선이 가야 하므로 배경을 더 어둡게 누른다 */
#gameover-screen,
#victory-screen {
  background-image:
    linear-gradient(rgba(16, 28, 12, 0.52), rgba(16, 28, 12, 0.62)),
    url('assets/craftpix/bg/forest_4.png');
}

/* ── 대기실 팀칸 — 가로 폭 축소, 멤버 카드는 한 줄에 1명 ── */
.lobby-box { max-width: 1120px !important; }   /* 720 → 1120 (17차): 대기실도 가로로 넓게 */
.lobby-grid { grid-template-columns: minmax(0, 1fr) 300px; }

.lobby-grid .team-column-list {
  flex-direction: column;
  flex-wrap: nowrap;
}

.lobby-grid .team-member-card { flex: none; width: 100%; }

/* ── 탈락 관전 배너 — 사망 후 팀원 시야로 이동했음을 알린다 ── */
#spectate-banner {
  position: fixed;
  bottom: 84px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 8;
  padding: 9px 22px;
  border-radius: 999px;
  background: rgba(253, 246, 225, 0.88);
  border: 2px solid rgba(150, 122, 68, 0.4);
  color: #3d3527;
  font-size: 0.95rem;
  pointer-events: none;
  box-shadow: 0 6px 14px rgba(24, 42, 16, 0.25);
}

#spectate-banner strong { color: #3f7d23; }

/* =====================================================================
   실플레이 피드백 5차 (2026-08-27) — 정글 버튼 마감 · 결과창/메인 버튼 축소 ·
   직업 카드 뱃지 · HUD 더 투명 · 내보내기 버튼
   ===================================================================== */

/* ── 정글 버튼 마감 ──
   · 텍스처 안쪽을 단색으로 편 새 텍스처에 맞춰 slice 를 잡고, 테두리 폭을 18px 로
     줄여 버튼 전체 높이를 낮춘다.
   · 9-slice 조각 사이의 실금(이음새)은 조각 뒤에 본체색 배경을 깔고 border-radius 로
     모서리만 둥글게 잘라 감춘다 — border-image 는 radius 의 영향을 받지 않으므로
     텍스처 모서리 밖으로 배경이 삐져나오지 않게 radius 를 텍스처보다 조금 크게 둔다.
   · hover 의 filter 는 조각을 다시 래스터화해 이음새를 드러내므로 뺀다.
   · #start-screen .accent-btn 이 특이성으로 이겨 초록 그라데이션 판을 다시 깔았다 —
     같은 특이성으로 여기서 덮는다. */
.accent-btn, #start-button, #start-screen .accent-btn {
  border: 18px solid transparent;
  border-image: url('assets/craftpix/ui/btn_green.png') 56 fill / 18px stretch;
  background: #509120;
  border-radius: 17px;
  padding: 3px 16px;
  filter: none;
  box-shadow: 0 5px 12px rgba(38, 68, 20, 0.28);
}

/* hover/active 는 배경·그림자·필터만 덮는다 — 여기에 padding 을 두면 특이성이
   `.lobby-actions .accent-btn`(34px) 을 이겨 호버 순간 버튼이 줄어든다 */
.accent-btn:hover:not(:disabled), #start-screen .accent-btn:hover:not(:disabled) {
  background: #509120;
  filter: none;
  transform: translateY(-2px);
  box-shadow: 0 8px 16px rgba(38, 68, 20, 0.36);
}

.accent-btn:active:not(:disabled), #start-screen .accent-btn:active:not(:disabled) {
  background: #509120;
  filter: none;
  transform: translateY(1px);
  box-shadow: 0 5px 12px rgba(38, 68, 20, 0.28);
}

.accent-btn:disabled, #start-screen .accent-btn:disabled { opacity: 0.55; box-shadow: none; }

.danger-btn {
  border: 18px solid transparent;
  border-image: url('assets/craftpix/ui/btn_amber.png') 56 fill / 18px stretch;
  background: #914520;
  border-radius: 17px;
  padding: 3px 16px;
  filter: none;
  box-shadow: 0 5px 12px rgba(96, 58, 12, 0.28);
}

.danger-btn:hover {
  background: #914520;
  filter: none;
  transform: translateY(-2px);
  box-shadow: 0 8px 16px rgba(96, 58, 12, 0.36);
}

.danger-btn:active {
  background: #914520;
  filter: none;
  transform: translateY(1px);
  box-shadow: 0 5px 12px rgba(96, 58, 12, 0.28);
}

/* 키보드 포커스 링은 텍스처 바깥에 두고, 마우스 클릭 포커스에는 띄우지 않는다 */
.accent-btn:focus, .danger-btn:focus { outline: none; }
.accent-btn:focus-visible, .danger-btn:focus-visible { outline: 3px solid #f0b428; outline-offset: 2px; }

/* ── 메인 화면 '서버 생성하기' — 카드 폭을 꽉 채우던 것을 가운데 작게 ── */
#start-screen #create-room-btn {
  width: 72%;
  display: block;
  margin: 6px auto 0;
  font-size: 1.05rem;
}

/* ── 결과 화면 버튼 — 전적표 아래 가운데 작게 ── */
#respawn-button, #victory-lobby-button {
  width: auto;
  min-width: 230px;
  display: inline-block;
  margin: 10px auto 0;
  font-size: 1.05rem;
}

.gameover-box, .victory-box { text-align: center; }

/* ── 직업 카드 — 무기 뱃지가 캐릭터를 가리지 않게 캐릭터를 왼쪽으로, 뱃지는 오른쪽 끝 ── */
.class-portrait-img { margin-right: 30px; }

.class-weapon-badge {
  right: 0;
  bottom: 6px;
  width: 36px;
  height: 36px;
}

/* ── 인게임 HUD — 더 투명하게 ── */
.hud-panel { background: rgba(253, 246, 225, 0.42); }
.minimap-container { background: rgba(253, 246, 225, 0.4); }
.minimap-container canvas { background: rgba(26, 42, 20, 0.4) !important; }
.skill-bar { background: rgba(253, 246, 225, 0.4); }
.upgrade-bar { background: rgba(253, 246, 225, 0.62); }
.skill-slot { background: rgba(255, 253, 244, 0.45); }
.gear-slot { background: rgba(255, 253, 244, 0.4); }
#server-stats.hud-panel { background: rgba(253, 246, 225, 0.32); }
#fps-meter { background: rgba(253, 246, 225, 0.32); }
.timer-display { background: rgba(253, 246, 225, 0.5); }
.danger-banner { background: rgba(240, 180, 40, 0.6); }
.buff-bar { background: rgba(253, 246, 225, 0.45); }

/* ── 대기실 내보내기(✕) — 방장에게만 보이는 작은 호박색 버튼 ── */
.team-kick-btn {
  flex: none;
  width: 26px;
  height: 26px;
  margin-left: 4px;
  border: 2px solid rgba(160, 103, 42, 0.55);
  border-radius: 50%;
  background: rgba(240, 180, 40, 0.25);
  color: #8a4d0f;
  font-size: 0.8rem;
  font-weight: 800;
  line-height: 1;
  cursor: pointer;
}

.team-kick-btn:hover { background: #f0b428; color: #3d2a08; }

.lobby-member-tag .team-kick-btn { margin-left: auto; }

/* =====================================================================
   모바일 UI 점검 (2026-08-27) — 폰 가로(짧은 세로)에서 메뉴 화면이 잘리던 문제
   ===================================================================== */

/* 폰 가로(예: 844×390)는 폭은 넓고 높이만 짧다. 기존 720px 폭 기준 규칙에
   안 걸려서 .start-box 가 max-height 310px + overflow hidden 으로 카드를
   짓눌러 겹쳐 보였다. 높이 기준으로 스크롤을 열고 머리 장식을 줄인다. */
@media (max-height: 600px) {
  .overlay { padding: 10px 0; }
  .start-box {
    max-height: none;
    overflow-y: auto;
    padding: 12px 18px 8px;
    gap: 10px;
  }
  .start-header { gap: 10px; }
  .mascot-emblem { height: 46px; animation: none; }
  #start-screen .logo { font-size: 1.7rem; }
  .start-col--guide { max-height: none; }
  .char-parade { display: none; }
  .lobby-box, .class-select-box, .gameover-box, .victory-box { max-height: none; }
}

/* 폰 가로는 700px 이상 폭이 나오므로 메인 화면을 2열로 유지한다 (1열이면 끝없이 길어진다) */
@media (max-height: 600px) and (min-width: 700px) {
  .start-grid { grid-template-columns: minmax(0, 1fr) 300px; }
}

/* 폰 세로 대기실: 4차에서 넣은 2열 그리드(팀 | 사이드 264px)가 900px 이하 규칙보다
   뒤에 와서 이겼다 — 폰에서 팀칸이 세로 띠로 짓눌렸다. 1열로 되돌리고 행 순서를
   1팀 → 2팀 → 사이드로 다시 지정한다. 시작/나가기 버튼은 한 줄에 둘이 들어가게 줄인다. */
@media (max-width: 900px) {
  .lobby-grid { grid-template-columns: minmax(0, 1fr); }
  .lobby-grid .team-column-1 { grid-column: 1; grid-row: 1; }
  .lobby-grid .team-column-2 { grid-column: 1; grid-row: 2; }
  .lobby-grid .lobby-side { grid-column: 1; grid-row: 3; }
  .lobby-actions { flex-wrap: wrap; gap: 10px; }
  .lobby-actions .accent-btn, .lobby-actions .danger-btn {
    min-width: 0;
    flex: 1 1 45%;
    padding-left: 8px;
    padding-right: 8px;
    white-space: nowrap;
    font-size: 0.9rem;
  }
}

/* =====================================================================
   실플레이 피드백 7차 (2026-08-27) — 자체 알림 모달 · 작은 글자 키움
   ===================================================================== */

/* ── 알림 모달 (브라우저 alert 대체) — 크림 카드 + 정글 버튼 ── */
.ui-modal {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(14, 28, 10, 0.55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

.ui-modal-box {
  background: rgba(253, 246, 225, 0.98);
  border: 3px solid rgba(122, 96, 48, 0.4);
  border-radius: 22px;
  padding: 24px 30px 20px;
  min-width: 300px;
  max-width: min(90vw, 460px);
  text-align: center;
  color: #3d3527;
  box-shadow: 0 24px 60px rgba(24, 42, 16, 0.45), inset 0 2px 0 rgba(255, 255, 255, 0.65);
  animation: uiModalPop 0.22s ease-out;
}

@keyframes uiModalPop {
  from { transform: translateY(12px) scale(0.96); opacity: 0; }
  to { transform: none; opacity: 1; }
}

.ui-modal-title {
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-size: 1.5rem;
  color: #3f7d23;
  margin-bottom: 8px;
}

.ui-modal-msg {
  font-size: 1rem;
  line-height: 1.6;
  white-space: pre-line;
  margin-bottom: 18px;
}

.ui-modal .ui-modal-ok { min-width: 170px; }

/* (10차 관전 스코어보드 오버라이드는 14차 중계 HUD 개편에서 대체되었다) */

/* ── 9차: 결과 전적표 — 팀명 한 줄, 행 낮게, 표 스크롤 없이 전부 펼침 ── */
.victory-roster { max-height: none; overflow: visible; gap: 5px; }
.victory-member { padding: 5px 12px; font-size: 13px; }
.victory-member .vm-rank { width: auto; min-width: 82px; white-space: nowrap; text-align: left; }
.victory-member .vm-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.victory-member .vm-stat { white-space: nowrap; }

/* ── 8차: 미니맵 테두리 얇게 · 장비/무기 강화 현황 시인성 ── */
.minimap-container { border-width: 1.5px; border-color: rgba(122, 96, 48, 0.55); padding: 6px; }
/* 안쪽 캔버스 테두리도 바깥 프레임과 같은 두께·색 (11차: 'MINI MAP' 라벨 삭제) */
.minimap-container canvas { border: 1.5px solid rgba(122, 96, 48, 0.55); }

/* ── 11차: 관전자 토글을 서버 목록 머리로 · 관전 시 방 생성 차단 안내 ── */
.room-list-header { display: flex; align-items: center; gap: 10px; }
.room-list-header h3 { margin-right: auto; }
.room-list-header .observer-checkbox-container { margin: 0; }
.room-list-header .checkbox-label { font-size: 0.86rem; white-space: nowrap; }
.observer-create-hint { margin-top: 8px; font-size: 0.8rem; color: #a3936f; text-align: center; }

/* ── 11차: 결과 전적표 MVP 표시 ── */
.victory-member.is-mvp { border-color: rgba(216, 150, 30, 0.75); background: #fff6d6; }
.victory-member .vm-mvp {
  flex: none;
  margin-left: 4px;
  padding: 1px 6px;
  border-radius: 999px;
  background: linear-gradient(180deg, #ffd45c 0%, #f0b428 100%);
  color: #5c3a06;
  font-size: 10px;
  font-weight: 800;
  box-shadow: 0 1px 0 rgba(120, 80, 0, 0.35);
}

.victory-member .vm-rank { min-width: 72px; }
.victory-member .vm-name { min-width: 0; }

.hud-panel h4 { color: #2f3f1c; font-weight: 700; }

.gear-slot {
  background: rgba(255, 253, 244, 0.88);
  border: 1.5px solid rgba(122, 96, 48, 0.45);
  color: #2b2617;
  font-size: 1.05rem;
  font-weight: 700;
  padding: 7px 4px;
}

.gear-slot .gear-lvl { color: #2b2617; font-size: 0.82rem; font-weight: 700; }
.gear-slot.weapon-slot { background: rgba(255, 236, 170, 0.92); border-color: rgba(201, 138, 46, 0.7); }
.gear-slot.weapon-slot .gear-lvl { color: #8a4d0f; }
.gear-slot.active-upgrade { background: rgba(214, 240, 196, 0.92); border-color: #4c8a2e; }
.gear-slot.active-upgrade .gear-lvl { color: #2f6a14; }

/* ── 레벨업 바 — 'LEVEL UP' 은 카드 위, '무기 강화 Lv5부터' 는 카드 아래로 세로 배치 ── */
.upgrade-bar {
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 10px 16px 9px;
}

.upgrade-bar-label { font-size: 0.95rem; color: #6d4708; letter-spacing: 1px; }

.upgrade-bar-badge {
  position: absolute;
  top: 8px;
  right: 12px;
  background: rgba(240, 180, 40, 0.3);
  border-color: rgba(201, 138, 46, 0.6);
  color: #8a4d0f;
}

.upgrade-bar-gate {
  font-size: 0.84rem;
  color: #5c3a06;
  background: #f6d27a;                 /* 불투명 — 뒤 울타리·잔디가 비쳐 안 읽히던 문제 */
  border: 1.5px solid rgba(160, 103, 42, 0.7);
}

/* 레벨업 바 자체도 다른 HUD 보다 불투명하게 — 선택지는 읽혀야 한다 */
.upgrade-bar { background: rgba(253, 246, 225, 0.86); }

/* ── 작은 글자 키움 — 레벨업 카드 단축키·이름·레벨, 스킬 슬롯 키 표시 ── */
.mini-hotkey { font-size: 0.82rem; min-width: 22px; padding: 2px 8px; top: -10px; right: -8px; }
.upgrade-mini-card .mini-name { font-size: 0.86rem; }
.upgrade-mini-card .mini-lvl { font-size: 0.76rem; }
.skill-num { font-size: 0.84rem; }
.skill-slot .skill-name { font-size: 0.82rem; }
.gear-slot { font-size: 0.82rem; }
.stat-row { font-size: 0.92rem; }

/* 폰 가로 인게임: 오른쪽 세로 스킬 바(3칸 ≈ 250px)가 미니맵 아래의 구역 알림 배너를
   덮었다. 0.72 배로 줄여(탭 타깃 52px 유지) 배너 아래에서 시작하게 한다. */
@media (max-height: 560px) {
  body.touch-device .bottom-center-hud { transform: scale(0.72); transform-origin: bottom right; }
}

/* ── 12차: 결과 전적표 MVP 배지를 이름 앞으로 · 관전자 결과 화면의 큰 MVP 카드 ── */
.victory-member .vm-mvp { margin-left: 0; margin-right: 2px; }

.victory-mvp { display: flex; justify-content: center; margin: 2px 0 16px; }
.victory-mvp-card {
  position: relative;
  width: min(100%, 340px);
  padding: 12px 18px 14px;
  border-radius: 18px;
  background: linear-gradient(180deg, #fff9e0 0%, #fff0b8 100%);
  border: 2px solid rgba(216, 150, 30, 0.75);
  box-shadow: 0 12px 30px rgba(150, 100, 16, 0.22), inset 0 1px 0 #fffdf0;
  animation: panelPopIn 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.vmvp-eyebrow {
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-size: 16px;
  letter-spacing: 4px;
  color: #8a5a06;
}
.vmvp-portrait {
  width: 136px;
  height: 136px;
  margin: 8px auto 8px;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 38%, #ffeaa8 0%, #f5c54a 58%, #d8951a 100%);
  border: 3px solid #ffd45c;
  box-shadow: 0 0 0 4px rgba(216, 150, 30, 0.28), 0 8px 20px rgba(150, 100, 16, 0.3);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  overflow: hidden;
}
.vmvp-portrait img {
  height: 122px;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  filter: drop-shadow(0 4px 4px rgba(0, 0, 0, 0.3));
}
.vmvp-name {
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-size: 28px;
  line-height: 1.1;
  color: #3d2a06;
}
.vmvp-team { margin-top: 3px; font-size: 13px; color: #7d6a3b; }
.vmvp-stats {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: 10px;
  font-size: 13px;
  font-weight: 700;
  color: #5c3a06;
}
.vmvp-stats span {
  padding: 3px 11px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid rgba(216, 150, 30, 0.45);
  white-space: nowrap;
}

/* ── 12차: 소리 토글(우상단 고정) · 시작 로딩 막 ── */
.sound-toggle {
  /* 우상단 고정(13차, 사용자 요청). 인게임 우상단 묶음(FPS·미니맵)은 그만큼 아래로 내린다 */
  position: fixed;
  top: 12px;
  right: 12px;
  z-index: 250;
  color: #3f7d23;
  width: 38px;
  height: 38px;
  padding: 0;
  border-radius: 50%;
  border: 2px solid rgba(122, 96, 48, 0.55);
  background: rgba(253, 246, 225, 0.92);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(24, 42, 16, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
}
.sound-toggle:hover { background: #fffdf4; transform: scale(1.06); }
.sound-toggle:focus-visible { outline: 3px solid rgba(255, 212, 92, 0.9); outline-offset: 2px; }

.load-veil {
  position: fixed;
  inset: 0;
  z-index: 240;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(ellipse at 50% 40%, rgba(46, 82, 34, 0.97) 0%, rgba(18, 36, 14, 0.99) 100%);
  opacity: 1;
  transition: opacity 0.33s ease;
  pointer-events: none;
}
.load-veil.fade { opacity: 0; }
.load-veil-card { text-align: center; color: #f3ecd2; }
.load-veil-spin {
  width: 46px;
  height: 46px;
  margin: 0 auto 18px;
  border-radius: 50%;
  border: 4px solid rgba(255, 224, 138, 0.22);
  border-top-color: #ffe08a;
  animation: veilSpin 0.9s linear infinite;
}
@keyframes veilSpin { to { transform: rotate(360deg); } }
.load-veil-title {
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-size: 34px;
  letter-spacing: 2px;
  color: #ffe08a;
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.45);
}
.load-veil-sub { margin-top: 10px; font-size: 14px; color: #cfe3b6; }
@media (prefers-reduced-motion: reduce) { .load-veil-spin { animation: none; } }

/* ── 13차: 메인 화면 — 닉네임 칸은 원래 폭(380px), 조작법 칸은 그 나머지, 전체 프레임만
   1080 → 960px 로 줄인다. 고블린 엠블럼은 삭제, 로고 아래 'Team Prompt Maestro' 부제 ── */
.start-box { max-width: 1320px !important; width: min(94vw, 1320px); }   /* 17차: 960 → 1320, 와이드 화면에서 좌우 여백이 과했다 */
.start-header { justify-content: center; text-align: center; }
.start-title { align-items: center; }
#start-screen .logo-sub {
  margin: -2px 0 0;
  font-family: 'Outfit', 'Noto Sans KR', sans-serif;
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: 4px;
  text-transform: uppercase;
  background: linear-gradient(90deg, #2f7cf6 0%, #7c5cf5 50%, #e040c0 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* 13차: 피격 비네트 — 프레임마다 값을 쓰는데 CSS 전이가 매번 다시 시작돼 깜빡이는 것처럼
   보였다. 감쇠는 JS 가 이미 프레임 단위로 하므로 전이를 끈다 */
.hit-vignette { transition: none; }
.sound-toggle svg { width: 20px; height: 20px; display: block; }

/* 인게임에서는 소리 버튼도 HUD 와 같은 비율로 줄인다 */
body:has(#game-ui:not(.hidden)) .sound-toggle {
  top: var(--sound-edge, 12px);
  right: var(--sound-edge, 12px);
  width: clamp(26px, 3.4vh, 38px);
  height: clamp(26px, 3.4vh, 38px);
}
body:has(#game-ui:not(.hidden)) .sound-toggle svg {
  width: clamp(13px, 1.8vh, 20px);
  height: clamp(13px, 1.8vh, 20px);
}
.sound-toggle[data-mode="sfx"] { color: #8a6d1f; }
.sound-toggle[data-mode="off"] { color: #b04a3a; background: rgba(253, 236, 225, 0.92); }
#game-ui .top-right-group { top: 60px; }
body.touch-device .sound-toggle { top: 6px; right: 6px; width: 30px; height: 30px; }
body.touch-device .sound-toggle svg { width: 16px; height: 16px; }
body.touch-device #game-ui .top-right-group { top: 42px; }

/* ── 13차: 시작 카운트다운 — 막 위에 3·2·1, 로딩이 끝나면 막을 반투명으로 낮춘다 ── */
.load-veil-count {
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-size: 104px;
  line-height: 1;
  color: #ffe08a;
  text-shadow: 0 5px 0 rgba(0, 0, 0, 0.45), 0 0 34px rgba(255, 224, 138, 0.55);
  min-height: 104px;
}
.load-veil-count.pop { animation: countPop 0.55s cubic-bezier(0.2, 1.4, 0.4, 1); }
.load-veil-count.go { color: #a8ff8a; font-size: 84px; animation: countPop 0.4s cubic-bezier(0.2, 1.4, 0.4, 1); }
@keyframes countPop {
  0% { transform: scale(1.7); opacity: 0.15; }
  100% { transform: scale(1); opacity: 1; }
}
.load-veil.ready { background: rgba(18, 36, 14, 0.42); }
.load-veil.ready .load-veil-spin { display: none; }
.load-veil-count:empty + .load-veil-title { margin-top: 0; }
.load-veil-count:not(:empty) + .load-veil-title { font-size: 26px; margin-top: 10px; }
@media (prefers-reduced-motion: reduce) { .load-veil-count.pop, .load-veil-count.go { animation: none; } }

/* ── 13차: 타격 시 "UI 가 깨지는 듯한 번쩍임" 대책 ──
   ① 인게임 HUD 의 backdrop-filter 제거 — 피격 흔들림(shake)으로 캔버스가 요동칠 때 블러된
      뒷배경이 매 프레임 다시 샘플링돼 패널이 깨지듯 일렁였다. 크림색 반투명 배경이면 충분하다.
   ② 피격 비네트를 HUD 아래(z -1)로 — 패널까지 붉게 덮이던 것을 캔버스 위에만 깐다.
   (③ 글자 풀 재설계는 pixi-renderer.js, ④ 비네트 CSS 전이 제거는 위 블록) */
#game-ui .hud-panel, #game-ui .minimap-container, #game-ui .timer-display, #game-ui .skill-bar,
#game-ui .upgrade-bar, #game-ui .item-toast, #game-ui .observer-dock-toggle, #game-ui .observer-dock-body,
#game-ui .kill-item, #game-ui .buff-bar, #game-ui .danger-banner, #game-ui #fps-meter, #game-ui .spectate-banner {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.hit-vignette { z-index: -1; }

/* ══════════════════════════════════════════════════════════════════════
   14차: 창 크기 반응형 — 전체화면이 아닌 창에서 내용이 잘리던 문제
   ----------------------------------------------------------------------
   원인은 두 가지가 겹친 것이었다.
   ① .start-box 가 overflow:hidden 인데 안쪽 카드들이 min-height:0 이라
      내용보다 작게 눌렸다. 눌린 카드의 내용은 밖으로 삐져나와 다음 카드
      위에 겹쳐 그려졌고, 그 결과 서버 목록이 조작법 카드에 통째로 덮였다.
   ② 로고·치비 퍼레이드·여백이 높이와 무관하게 고정이라, 세로가 조금만
      줄어도 남는 높이가 카드 최소 높이의 합보다 작아졌다.
   그래서 (1) 카드가 내용 밑으로 눌리지 않게 막고, (2) 그래도 모자라면
   겹치는 대신 패널이 스크롤되게 하며, (3) 높이 단계마다 장식과 여백을
   걷어내 스크롤 자체가 좀처럼 생기지 않게 한다.
   ══════════════════════════════════════════════════════════════════════ */

/* ── (1) 세로 스택의 카드는 내용보다 작아지지 않는다 ────────────────
   min-height 를 auto 로 돌려놓으면 플렉스 항목이 최소 내용 높이 아래로
   압축되지 않으므로, 버튼이 옆 카드 위로 삐져나오는 일이 사라진다. */
/* 그리드는 패널 안에 딱 맞게 줄어든다 (min-height:0). 넘치는 몫은 그리드가 아니라
   각 칸이 자기 안에서 스크롤로 감당한다. 그래야 그리드가 저작권 줄 위로 올라타지 않는다. */
.start-grid { min-height: 0; }

/* 왼쪽 세로 스택 — 카드 자체는 내용 밑으로 눌리지 않게 두되(flex-shrink:0),
   스택 전체가 모자라면 스택이 스크롤한다. 예전에는 카드가 눌리면서 내용이
   밖으로 삐져나와 아래 카드 위에 겹쳐 그려졌고, 그래서 서버 목록이 사라졌다. */
.start-stack { min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
/* 닉네임 카드만 고정 크기다. 서버 목록 칸까지 여기 걸리면(선택자 특이도가 높아
   뒤의 .start-col--rooms 규칙을 이긴다) 줄어들지 못해 스택이 통째로 스크롤됐다. */
.start-stack > .start-col:not(.start-col--rooms) { min-height: auto; flex-shrink: 0; }
/* 서버 목록 칸만은 줄어들어도 된다 — 안쪽 목록이 스스로 스크롤하기 때문이다.
   다만 여백·머리줄·목록 최소 높이를 합친 만큼은 바닥으로 잡아 둬야, 그 밑으로
   눌려 내용이 밖으로 삐져나오는 원래 증상이 되살아나지 않는다. */
.start-stack > .start-col--rooms { flex: 1 1 auto; min-height: 156px; }
.room-list-section { min-height: 0; }

/* 조작법 칸을 스크롤 컨테이너로 만든다. 그리드 행의 높이는 칸들의 '최소 내용
   높이' 중 가장 큰 값으로 정해지는데, overflow 가 visible 인 칸은 min-height:0
   을 줘도 내용 전체 높이를 그대로 주장한다. 그래서 조작법 목록(약 540px)이 행을
   끌어올려, 세로가 짧으면 패널 전체가 스크롤됐다. 스크롤 컨테이너가 되면 그
   주장이 0 으로 떨어져 행이 서버 목록 쪽 최소 높이에 맞춰진다. */
.start-col--guide { min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
/* 로고 줄과 저작권 줄도 눌리지 않게 — 눌리면 그리드가 그 위로 올라탄다 */
.start-header, .start-box .footer-copyright { flex-shrink: 0; }

/* ── (2) 마지막 안전망 — 넘치면 겹치지 말고 패널이 스크롤된다 ────── */
.start-box {
  max-height: calc(100vh - var(--overlay-pad) * 2);
  max-height: calc(100dvh - var(--overlay-pad) * 2);
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
}

.start-box::-webkit-scrollbar { width: 7px; }
.start-box::-webkit-scrollbar-thumb { background: rgba(150, 122, 68, 0.35); border-radius: 4px; }
.start-box::-webkit-scrollbar-track { background: transparent; }

/* 첫 컬럼은 자리가 있으면 380px 를 그대로 쓰고, 좁아지면 300px 까지만 줄인다.
   고정 380px 이면 940~1000px 구간에서 조작법 칸이 눌려 2열이 무너졌다. */
.start-grid { grid-template-columns: minmax(0, 1fr) minmax(260px, 340px); }

/* 서버 목록 머리줄 — 제목·관전 체크·새로고침이 한 줄에 안 들어가면 단어 중간에서
   꺾여 '서 / 버 목록' 처럼 읽혔다. 낱말은 붙여 두고 줄 단위로 넘긴다. */
.room-list-header { flex-wrap: wrap; row-gap: 6px; }
.room-list-header h3,
.room-list-header .refresh-btn,
.room-list-header .checkbox-label { white-space: nowrap; }

/* ── (3) 높이 단계 — 세로가 줄면 장식부터 걷어낸다 ──────────────── */

/* 1단계 (≤ 860px): 치비 퍼레이드를 내리고 로고와 여백을 줄인다.
   퍼레이드는 잔디 띠까지 합쳐 120px 가까이 차지하는 순수 장식이다. */
@media (max-height: 860px) {
  :root { --overlay-pad: 22px; }
  .char-parade { display: none; }
  #start-screen .logo { font-size: 2.1rem; }
  #start-screen .logo-sub { font-size: 0.88rem; letter-spacing: 3px; }
  .start-box { padding: 18px 26px 12px; gap: 12px; }
  .start-grid, .start-stack { gap: 12px; }
  .start-col { padding: 13px 15px; }
  .start-box .footer-copyright { font-size: 0.74rem; }
}

/* 2단계 (≤ 700px): 조작법 글자와 서버 목록 최소 높이까지 줄인다.
   서버 목록은 방이 없어도 최소 두 줄은 보여야 목록임을 알 수 있다. */
@media (max-height: 700px) {
  :root { --overlay-pad: 12px; }
  #start-screen .logo { font-size: 1.8rem; }
  #start-screen .logo-sub { font-size: 0.8rem; }
  .start-box { padding: 14px 20px 9px; gap: 9px; }
  .start-grid, .start-stack { gap: 10px; }
  .start-col { padding: 10px 13px; }
  .room-list-container { min-height: 82px; }
  #start-screen .controls-guide li { font-size: 0.86rem; line-height: 1.42; }
  #start-screen .controls-guide h3 { margin-bottom: 5px; }
  #start-screen .controls-guide h3 + ul { margin-bottom: 9px; }
  #start-screen #username-input { padding: 11px 16px; font-size: 1rem; }
  #start-screen .accent-btn { padding-top: 11px; padding-bottom: 11px; }
}

/* ── 대기실 — 시작·나가기 버튼이 스크롤 밖으로 밀려나던 문제 ──────
   .lobby-box 는 max-height 92vh 로 스스로 스크롤되는데, 인원이 차면
   정작 눌러야 할 '게임 시작' 이 접힌 아래로 내려가 보이지 않았다.
   버튼 줄을 패널 바닥에 고정해 스크롤과 무관하게 항상 손이 닿게 한다. */
.lobby-box { padding-bottom: 0; }

.lobby-actions {
  position: sticky;
  bottom: 0;
  z-index: 3;
  margin: 10px calc(var(--panel-pad) * -1) 0;
  padding: 12px var(--panel-pad) 18px;
  /* 위쪽은 살짝 흐리게 이어 붙여 잘린 내용이 밑으로 이어짐을 알린다 */
  background: linear-gradient(180deg, rgba(253, 246, 225, 0) 0%, #fdf6e1 26%, #fdf6e1 100%);
  border-radius: 0 0 22px 22px;
}

@media (max-height: 780px) {
  .lobby-box { max-height: calc(100dvh - var(--overlay-pad) * 2); }
  #lobby-room-name { font-size: 1.5rem; }
  .qr-wrap canvas { width: 96px; height: 96px; }
  .lobby-grid .team-column { min-height: 0; }
}

/* ── 결과 화면 — '로비로 가기' 가 화면 밖으로 밀려나던 문제 ────────
   9차에서 전적표를 스크롤 없이 전부 펼치도록 바꾸면서, 10인 로스터가
   패널을 화면보다 길게 만들어 버튼이 아래로 사라졌다. 전적표는 그대로
   펼쳐 두고, 패널에 높이 상한을 준 뒤 버튼만 바닥에 고정한다. */
#victory-screen .glass-panel,
#gameover-screen .glass-panel {
  max-height: calc(100vh - var(--overlay-pad) * 2);
  max-height: calc(100dvh - var(--overlay-pad) * 2);
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  padding-bottom: 0;
}

.victory-actions {
  position: sticky;
  bottom: 0;
  z-index: 3;
  margin: 16px calc(var(--panel-pad) * -1) 0;
  padding: 12px var(--panel-pad) 18px;
  background: linear-gradient(180deg, rgba(253, 246, 225, 0) 0%, #fdf6e1 26%, #fdf6e1 100%);
  border-radius: 0 0 22px 22px;
  /* 🔄 다시하기(방장)와 나가기가 나란히, 좁으면 줄바꿈 */
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 10px;
}
/* 비방장에게 보이는 '방장을 기다리는 중' 안내 — 버튼 줄 전체 폭을 차지한다 */
.replay-wait-msg { width: 100%; margin: 0; padding: 10px 14px; font-size: 0.85rem; }

#victory-screen .glass-panel::-webkit-scrollbar,
#gameover-screen .glass-panel::-webkit-scrollbar { width: 7px; }
#victory-screen .glass-panel::-webkit-scrollbar-thumb,
#gameover-screen .glass-panel::-webkit-scrollbar-thumb { background: rgba(150, 122, 68, 0.35); border-radius: 4px; }

@media (max-height: 900px) {
  .victory-title, .gameover-title { font-size: 2.4rem; margin-bottom: 6px; }
  .victory-msg, .gameover-msg { margin-bottom: 14px; font-size: 0.95rem; }
  .summary-stats { padding: 12px; margin-bottom: 14px; }
  .victory-roster-title { margin: 12px 0 6px; }
  .victory-mvp { margin: 0 0 10px; }
  .victory-member { padding: 4px 10px; font-size: 12.5px; }
  .victory-roster { gap: 4px; }
  #victory-screen .glass-panel, #gameover-screen .glass-panel { --panel-pad: 26px; padding-top: 22px; }
}

@media (max-height: 700px) {
  .victory-title, .gameover-title { font-size: 1.9rem; }
  .victory-msg, .gameover-msg { margin-bottom: 10px; font-size: 0.9rem; }
  .summary-stats { padding: 9px; margin-bottom: 10px; }
  .victory-member { padding: 3px 9px; font-size: 12px; }
}

/* ── 직업 선택 — 카드 4장이 세로로 커 세로 여백이 모자랄 때 대비 ── */
#class-select-screen .glass-panel {
  max-height: calc(100vh - var(--overlay-pad) * 2);
  max-height: calc(100dvh - var(--overlay-pad) * 2);
  overflow-y: auto;
  overflow-x: hidden;
}

/* (인게임 HUD 축소는 파일 끝의 '창 크기 연동 HUD' 블록이 담당한다 — 고정 px
   단계 축소로는 700x600 같은 작은 창에서 좌측 패널이 세로의 92%를 먹었다) */

/* ══════════════════════════════════════════════════════════════════════
   14차: 관전 중계 HUD 개편 — LoL 관전 화면 구성 + 해상도 반응형
   ----------------------------------------------------------------------
   옛 구조는 하단 가로 독 하나였다. 높이가 409px 로 고정이라 1350x673 화면
   에서 세로의 61%(면적 50%)를 가렸고, wholeMapZoom() 이 그 높이를 빼는 바람에
   전체 맵 보기가 세로 200px 안에 눌려 그려졌다.
   새 구조는 선수 정보를 좌우 세로 레일로 밀어내고 중앙을 비운다. 그리고
   모든 치수를 --obs-u 하나에 걸어, 가로·세로 중 더 좁은 쪽에 맞춰 함께
   커지고 줄어든다. 고정 px 은 테두리 두께 정도만 남긴다.
   ══════════════════════════════════════════════════════════════════════ */

/* 기준 단위 — 가로와 세로 중 더 빡빡한 쪽을 따른다. 세로를 함께 보지 않으면
   넓고 낮은 창에서 카드 5장이 화면 밖으로 밀려난다.
   미니맵·타이머는 관전 독의 자식이 아니므로 body 에 선언해야 물려받는다. */
body.observing {
  --obs-u: clamp(9.5px, min(0.84vw, 1.72vh), 15px);
  --obs-rail: clamp(140px, 14vw, 236px);       /* 레일 폭 */
  --obs-gap: calc(var(--obs-u) * 0.34);
  --obs-pad: calc(var(--obs-u) * 0.62);
  --obs-edge: clamp(6px, 0.7vw, 18px);         /* 화면 가장자리 여백 */
}

.observer-dock {
  /* 관전 화면 밖(테스트·미리보기)에서도 값이 있어야 무너지지 않는다 */
  --obs-u: clamp(9.5px, min(0.84vw, 1.72vh), 15px);
  --obs-rail: clamp(140px, 14vw, 236px);
  --obs-gap: calc(var(--obs-u) * 0.34);
  --obs-pad: calc(var(--obs-u) * 0.62);
  --obs-edge: clamp(6px, 0.7vw, 18px);

  /* 레이아웃은 자식들이 각자 화면 모서리에 붙는다 */
  position: absolute;
  inset: 0;
  left: 0;
  bottom: 0;
  width: auto;
  transform: none;
  display: block;
  z-index: 6;
  pointer-events: none;
}

/* ── ①② 상단 중앙 스코어 바 ─────────────────────────────────── */
.obs-scorebar {
  position: absolute;
  top: var(--obs-edge);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: stretch;
  gap: 0;
  pointer-events: auto;
  background: rgba(12, 20, 34, 0.82);
  border: 1px solid rgba(122, 96, 48, 0.45);
  border-radius: calc(var(--obs-u) * 0.7);
  box-shadow: 0 calc(var(--obs-u) * 0.5) calc(var(--obs-u) * 1.6) rgba(0, 0, 0, 0.42);
  overflow: hidden;
  white-space: nowrap;
}

.obs-sb-side {
  display: flex;
  align-items: center;
  gap: calc(var(--obs-u) * 0.7);
  padding: calc(var(--obs-u) * 0.42) calc(var(--obs-u) * 0.9);
}

.obs-sb-side.team-1 { background: linear-gradient(90deg, rgba(239, 68, 68, 0.24) 0%, transparent 100%); }
.obs-sb-side.team-2 { background: linear-gradient(270deg, rgba(59, 130, 246, 0.24) 0%, transparent 100%); }

.obs-sb-team {
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-size: calc(var(--obs-u) * 1.18);
  font-weight: 800;
  letter-spacing: 0.5px;
  max-width: calc(var(--obs-u) * 9);
  overflow: hidden;
  text-overflow: ellipsis;
}

.obs-sb-team { color: #f8fafc; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85); }
.obs-sb-side.team-1 { border-left: calc(var(--obs-u) * 0.22) solid #ef4444; }
.obs-sb-side.team-2 { border-right: calc(var(--obs-u) * 0.22) solid #3b82f6; }

.obs-sb-meta {
  display: flex;
  align-items: baseline;
  gap: calc(var(--obs-u) * 0.22);
  font-size: calc(var(--obs-u) * 0.66);
  color: #9ca3af;
  font-weight: 700;
}

.obs-sb-meta b {
  font-family: 'Outfit', sans-serif;
  font-size: calc(var(--obs-u) * 0.98);
  color: #e5e7eb;
}

.obs-sb-mid {
  display: flex;
  align-items: center;
  gap: calc(var(--obs-u) * 0.55);
  padding: calc(var(--obs-u) * 0.3) calc(var(--obs-u) * 1.05);
  background: rgba(0, 0, 0, 0.34);
  border-left: 1px solid rgba(255, 255, 255, 0.09);
  border-right: 1px solid rgba(255, 255, 255, 0.09);
}

.obs-sb-kill {
  font-family: 'Outfit', sans-serif;
  font-size: calc(var(--obs-u) * 1.62);
  font-weight: 800;
  min-width: calc(var(--obs-u) * 1.5);
  text-align: center;
}

.obs-sb-kill.team-1 { color: #ef4444; }
.obs-sb-kill.team-2 { color: #60a5fa; }

.obs-sb-vs {
  font-size: calc(var(--obs-u) * 0.56);
  letter-spacing: 1.5px;
  color: #6b7280;
  font-weight: 800;
}

/* ── ③⑦ 좌우 세로 선수 레일 ─────────────────────────────────── */
.obs-rail {
  position: absolute;
  top: calc(var(--obs-edge) + var(--obs-u) * 3.4);   /* 스코어 바 아래에서 시작 */
  width: var(--obs-rail);
  max-height: calc(100% - var(--obs-edge) * 2 - var(--obs-u) * 7.6);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
  pointer-events: auto;
}

.obs-rail::-webkit-scrollbar { width: 0; }
.obs-rail-left  { left: var(--obs-edge); }
.obs-rail-right { right: var(--obs-edge); }

.obs-team-list {
  display: flex;
  flex-direction: column;
  gap: var(--obs-gap);
}

/* 한 선수 = 한 카드. 왼쪽 레일은 초상화가 왼쪽, 오른쪽 레일은 오른쪽에 온다 */
.obs-player-row {
  display: grid;
  grid-template-columns: calc(var(--obs-u) * 3.1) minmax(0, 1fr);
  grid-template-areas:
    "portrait head"
    "portrait hp"
    "skills   skills";
  align-items: center;
  column-gap: calc(var(--obs-u) * 0.5);
  row-gap: calc(var(--obs-u) * 0.26);
  padding: var(--obs-pad);
  background: rgba(12, 20, 34, 0.76);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: calc(var(--obs-u) * 0.6);
  cursor: pointer;
  transition: background 0.15s, box-shadow 0.15s, transform 0.12s;
  pointer-events: auto;
}

.obs-rail-right .obs-player-row {
  grid-template-columns: minmax(0, 1fr) calc(var(--obs-u) * 3.1);
  grid-template-areas:
    "head   portrait"
    "hp     portrait"
    "skills skills";
}

.obs-player-row * { pointer-events: none; }
.obs-player-row:hover { background: rgba(30, 58, 92, 0.9); transform: translateY(-1px); }

.obs-player-row.active-lock {
  background: rgba(6, 62, 82, 0.92);
  box-shadow: inset 0 0 0 2px #22d3ee, 0 0 calc(var(--obs-u) * 1.1) rgba(34, 211, 238, 0.45);
}

.obs-player-row.dead { opacity: 0.42; cursor: not-allowed; }
.obs-player-row.team-1 { border-left: calc(var(--obs-u) * 0.2) solid #ef4444; }
.obs-player-row.team-2 { border-right: calc(var(--obs-u) * 0.2) solid #3b82f6; }
.obs-rail-right .obs-player-row.team-2 { border-left: none; }

/* 초상화 — craftpix 대기 프레임. 사망하면 회색으로 눕는다 */
.obs-portrait {
  grid-area: portrait;
  position: relative;
  width: calc(var(--obs-u) * 3.1);
  height: calc(var(--obs-u) * 3.1);
  border-radius: calc(var(--obs-u) * 0.45);
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.1);
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.obs-portrait img {
  width: 128%;
  height: 128%;
  object-fit: contain;
  image-rendering: auto;
  transform: translateY(6%);
}

.obs-player-row.dead .obs-portrait img { filter: grayscale(1) brightness(0.6); }

.obs-portrait-lv {
  position: absolute;
  left: 0;
  bottom: 0;
  padding: 0 calc(var(--obs-u) * 0.24);
  font-family: 'Outfit', sans-serif;
  font-size: calc(var(--obs-u) * 0.6);
  font-weight: 800;
  color: #111827;
  background: #ffcc00;
  border-radius: 0 calc(var(--obs-u) * 0.3) 0 calc(var(--obs-u) * 0.4);
}

.obs-player-row.dead .obs-portrait-lv { background: #4b5563; color: #d1d5db; }

/* 1~0 단축키 번호 배지 — 포트레이트 우상단 */
.obs-num {
  position: absolute;
  right: 0;
  top: 0;
  min-width: calc(var(--obs-u) * 0.9);
  text-align: center;
  padding: 0 calc(var(--obs-u) * 0.18);
  font-family: 'Outfit', sans-serif;
  font-size: calc(var(--obs-u) * 0.6);
  font-weight: 800;
  color: #e8f0ff;
  background: rgba(15, 23, 42, 0.85);
  border: 1px solid rgba(148, 163, 184, 0.6);
  border-radius: calc(var(--obs-u) * 0.3);
  line-height: 1.5;
}
.obs-num:empty { display: none; }
.obs-player-row.dead .obs-num { opacity: 0.4; }

/* 이름 줄 — 이름 + 목숨 + 킬 */
.obs-card-head {
  grid-area: head;
  display: flex;
  align-items: center;
  gap: calc(var(--obs-u) * 0.34);
  min-width: 0;
}

.obs-rail-right .obs-card-head { flex-direction: row-reverse; }

.obs-player-name {
  font-size: calc(var(--obs-u) * 0.86);
  font-weight: 700;
  color: #f1f5f9;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1 1 auto;
  min-width: 0;
}

.obs-rail-right .obs-player-name { text-align: right; }

.obs-player-lives {
  font-size: calc(var(--obs-u) * 0.58);
  letter-spacing: 0.5px;
  white-space: nowrap;
  flex: none;
}

.obs-player-kd {
  font-size: calc(var(--obs-u) * 0.7);
  font-weight: 800;
  color: #fbbf24;
  white-space: nowrap;
  flex: none;
}

/* HP 바 */
.obs-player-hp-bar {
  grid-area: hp;
  position: relative;
  height: calc(var(--obs-u) * 0.92);
  background: rgba(0, 0, 0, 0.5);
  border-radius: calc(var(--obs-u) * 0.18);
  overflow: hidden;
}

.obs-player-hp-fill {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, #10b981 0%, #34d399 100%);
  transition: width 0.15s ease-out;
}

.obs-player-row.low .obs-player-hp-fill { background: linear-gradient(90deg, #dc2626 0%, #f87171 100%); }

.obs-player-hp-text {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Outfit', sans-serif;
  font-size: calc(var(--obs-u) * 0.56);
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9);
}

/* ⑦ 스킬 쿨다운 — 텍스트 칩이 아니라 인게임 스킬 바처럼 아이콘 + 차오르는 오버레이 */
.obs-player-skills {
  grid-area: skills;
  display: flex;
  gap: calc(var(--obs-u) * 0.26);
  margin-top: calc(var(--obs-u) * 0.1);
}

.obs-skill {
  position: relative;
  flex: 1 1 0;
  height: calc(var(--obs-u) * 1.34);
  border-radius: calc(var(--obs-u) * 0.24);
  border: 1px solid rgba(255, 255, 255, 0.14);
  background-color: rgba(0, 0, 0, 0.38);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Outfit', sans-serif;
  font-size: calc(var(--obs-u) * 0.62);
  font-weight: 800;
  color: #e5e7eb;
  overflow: hidden;
}

/* 남은 쿨타임만큼 아래에서 어둡게 덮는다 — 차오르면 준비 완료 */
.obs-skill-cd {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(2, 6, 20, 0.72);
  transition: height 0.12s linear;
}

.obs-skill-label { position: relative; z-index: 1; }
.obs-skill.ready { border-color: rgba(74, 222, 128, 0.65); color: #86efac; }
.obs-skill.cooling { color: #bae6fd; }
.obs-skill.locked { opacity: 0.4; }

/* ── 좌하단 툴바 ─────────────────────────────────────────────── */
.obs-toolbar {
  position: absolute;
  left: var(--obs-edge);
  bottom: var(--obs-edge);
  display: flex;
  align-items: center;
  gap: calc(var(--obs-u) * 0.5);
  padding: 0;
  pointer-events: none;
  flex-wrap: wrap;
  max-width: calc(100% - var(--obs-edge) * 2 - var(--obs-u) * 20);
}

.obs-mode-btn {
  pointer-events: auto;
  cursor: pointer;
  border: 1px solid rgba(122, 96, 48, 0.5);
  border-radius: calc(var(--obs-u) * 0.5);
  background: rgba(253, 246, 225, 0.9);
  color: #3f7d23;
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-size: calc(var(--obs-u) * 0.82);
  padding: calc(var(--obs-u) * 0.3) calc(var(--obs-u) * 0.75);
  white-space: nowrap;
}

.obs-mode-btn:hover { background: #f4fbea; }
.obs-mode-btn.active { background: #4c8a2e; color: #fffef6; border-color: #3a6b22; }

.obs-toolbar-hint {
  font-size: calc(var(--obs-u) * 0.66);
  color: #cbd5e1;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
  white-space: nowrap;
}

/* ── ④⑤ TAB 상세 전적표 ─────────────────────────────────────── */
.obs-sheet {
  position: absolute;
  left: 50%;
  bottom: calc(var(--obs-u) * 2.4);
  top: auto;
  transform: translateX(-50%);
  width: min(calc(var(--obs-u) * 62), calc(100% - var(--obs-rail) * 2 - var(--obs-edge) * 4));
  max-height: calc(100% - var(--obs-edge) * 2 - var(--obs-u) * 12);
  overflow-y: auto;
  overscroll-behavior: contain;
  pointer-events: auto;
  background: rgba(10, 16, 28, 0.94);
  border: 1px solid rgba(122, 96, 48, 0.5);
  border-radius: calc(var(--obs-u) * 0.8);
  box-shadow: 0 calc(var(--obs-u) * 1.2) calc(var(--obs-u) * 3) rgba(0, 0, 0, 0.6);
  padding: calc(var(--obs-u) * 0.85);
}

.obs-sheet.hidden { display: none; }

.obs-sheet-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: calc(var(--obs-u) * 0.7);
}

.obs-sheet-col { display: flex; flex-direction: column; gap: calc(var(--obs-u) * 0.3); min-width: 0; }

.obs-sheet-head {
  padding-bottom: calc(var(--obs-u) * 0.3);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.obs-sheet-tag {
  font-family: 'Do Hyeon', 'Noto Sans KR', sans-serif;
  font-size: calc(var(--obs-u) * 1.02);
  font-weight: 800;
}

.obs-sheet-col.team-1 .obs-sheet-tag { color: #fca5a5; }
.obs-sheet-col.team-2 .obs-sheet-tag { color: #93c5fd; }

.obs-sheet-list { display: flex; flex-direction: column; gap: calc(var(--obs-u) * 0.26); }

.obs-sheet-row {
  display: grid;
  grid-template-columns: calc(var(--obs-u) * 1.9) minmax(0, 1fr) auto;
  grid-template-areas:
    "por name kd"
    "por gear xp";
  align-items: center;
  column-gap: calc(var(--obs-u) * 0.42);
  row-gap: calc(var(--obs-u) * 0.16);
  padding: calc(var(--obs-u) * 0.34);
  background: rgba(255, 255, 255, 0.04);
  border-radius: calc(var(--obs-u) * 0.34);
}

.obs-sheet-row.dead { opacity: 0.45; }
.obs-sheet-row.team-1 { border-left: calc(var(--obs-u) * 0.16) solid #ef4444; }
.obs-sheet-row.team-2 { border-left: calc(var(--obs-u) * 0.16) solid #3b82f6; }

.obs-sheet-por {
  grid-area: por;
  width: calc(var(--obs-u) * 1.9);
  height: calc(var(--obs-u) * 1.9);
  border-radius: calc(var(--obs-u) * 0.28);
  background: rgba(0, 0, 0, 0.4);
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.obs-sheet-por img { width: 130%; height: 130%; object-fit: contain; }

.obs-sheet-name {
  grid-area: name;
  font-size: calc(var(--obs-u) * 0.8);
  font-weight: 700;
  color: #f1f5f9;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.obs-sheet-kd {
  grid-area: kd;
  font-family: 'Outfit', sans-serif;
  font-size: calc(var(--obs-u) * 0.76);
  font-weight: 800;
  white-space: nowrap;
  text-align: right;
}

.obs-sheet-kd .sk-k { color: #fbbf24; }
.obs-sheet-kd .sk-s { color: #6b7280; margin: 0 calc(var(--obs-u) * 0.14); }
.obs-sheet-kd .sk-d { color: #9ca3af; }

/* ④ 보유 아이템 대응 — 장비/무기 강화 현황 */
.obs-sheet-gear {
  grid-area: gear;
  display: flex;
  gap: calc(var(--obs-u) * 0.18);
  flex-wrap: nowrap;
}

.obs-gear-chip {
  display: flex;
  align-items: center;
  gap: calc(var(--obs-u) * 0.1);
  padding: 0 calc(var(--obs-u) * 0.22);
  height: calc(var(--obs-u) * 0.98);
  border-radius: calc(var(--obs-u) * 0.2);
  background: rgba(0, 0, 0, 0.36);
  border: 1px solid rgba(255, 255, 255, 0.1);
  font-family: 'Outfit', sans-serif;
  font-size: calc(var(--obs-u) * 0.56);
  font-weight: 800;
  color: #e5e7eb;
  white-space: nowrap;
}

.obs-gear-chip.weapon { background: rgba(240, 180, 40, 0.22); border-color: rgba(240, 180, 40, 0.5); color: #fde68a; }
.obs-gear-chip.zero { opacity: 0.32; }

.obs-sheet-xp {
  grid-area: xp;
  font-family: 'Outfit', sans-serif;
  font-size: calc(var(--obs-u) * 0.6);
  color: #a3a3a3;
  white-space: nowrap;
  text-align: right;
}

.obs-guide {
  font-size: calc(var(--obs-u) * 0.62);
  color: #6b7280;
  text-align: center;
  margin: calc(var(--obs-u) * 0.6) 0 0;
  line-height: 1.35;
}

/* ── 관전 중 다른 HUD 조정 ───────────────────────────────────── */
/* 미니맵은 LoL 처럼 우측 하단으로. 크기는 client.js 가 캔버스 해상도로 맞춘다 */
body.observing #game-ui .top-right-group {
  top: calc(var(--obs-edge) + var(--obs-u) * 3.6);
  right: calc(var(--obs-rail) + var(--obs-edge) * 2);
}

/* 미니맵을 LoL 처럼 우측 하단으로. .top-right-group 이 위치 기준이라
   absolute 로는 그룹 안에서만 움직인다 — 화면 기준으로 빼려면 fixed 여야 한다. */
/* 예전에는 오른쪽 레일을 피하려고 레일 폭만큼 안쪽으로 들여놨는데, 정작 피할 것이
   없었다. 레일은 5:5 정원에서도 미니맵보다 63~206px 위에서 끝나는데 우측 여백만
   158~263px 이 잡히다 보니, 미니맵이 구석에 붙지 않고 중계 화면 한가운데로 떠 보였다.
   그래서 기본값을 진짜 우측 하단 구석으로 되돌린다. */
body.observing #game-ui .minimap-container,
body.observing .minimap-container {
  position: fixed;
  right: var(--obs-edge);
  bottom: var(--obs-edge);
  top: auto;
  z-index: 7;
  padding: calc(var(--obs-u) * 0.4);
  border-radius: calc(var(--obs-u) * 0.7);
}

/* 다만 '넓고 낮은 창'에서는 레일이 미니맵 높이까지 실제로 내려와 겹친다.
   여유 폭이 창 크기에 따라 -90px ~ +285px 로 널뛰어서 세로 미디어쿼리 하나로는
   가를 수 없었다(초광폭에서는 세로 800px 에서도 20px 밖에 남지 않는다).
   그래서 client.js 의 syncObsMinimapDodge() 가 두 사각형을 직접 재서, 정말 겹칠
   때만 이 클래스를 붙여 예전처럼 레일 폭만큼 비켜서게 한다. */
body.observing.obs-map-dodge #game-ui .minimap-container,
body.observing.obs-map-dodge .minimap-container {
  right: calc(var(--obs-rail) + var(--obs-edge) * 2);
}

/* 타이머는 스코어 바에 자리를 내주고 그 아래로 내려간다.
   #game-ui 를 함께 적어야 한다 — 창 크기 연동 HUD 블록의
   `#game-ui .top-center-group` 이 아이디 특이도로 이기기 때문이다. */
body.observing #game-ui .top-center-group { top: calc(var(--obs-edge) + var(--obs-u) * 3.6); }

/* 소리 토글은 우상단 고정이라 오른쪽 레일 첫 카드를 덮었다. 레일 왼쪽으로 비킨다 */
body.observing .sound-toggle {
  right: calc(var(--obs-rail) + var(--obs-edge) * 2);
  top: var(--obs-edge);
}

/* 좁은 화면 — 레일 두 줄이 중앙을 다 먹으면 중계 화면이 아니다.
   1024px 미만에서는 레일을 반투명 오버레이로 좁히고, 900px 미만에서는
   레일을 접고 상세 전적표(TAB)만 남긴다. */
@media (max-width: 1024px) {
  .observer-dock { --obs-rail: clamp(118px, 15vw, 150px); }
  .obs-player-skills { display: none; }
  .obs-toolbar-hint { display: none; }
}

@media (max-width: 900px) {
  .obs-rail { display: none; }
  body.observing .minimap-container { right: var(--obs-edge); }
  body.observing #game-ui .top-right-group { right: var(--obs-edge); }
  .obs-sheet { width: calc(100% - var(--obs-edge) * 2); }
  body.observing .sound-toggle { right: var(--obs-edge); }
}

/* 세로가 아주 낮으면 스코어 바의 부가 수치를 접는다 */
@media (max-height: 520px) {
  .obs-sb-meta { display: none; }
  /* 폰 가로에서 상세 전적표가 화면을 다 덮지 않게 행을 납작하게 */
  .obs-sheet { padding: calc(var(--obs-u) * 0.5); }
  .obs-sheet-row { padding: calc(var(--obs-u) * 0.22); }
  .obs-sheet-xp { display: none; }
  .obs-guide { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════
   14차: 폰 가로 화면 HUD 재배치 — 플레이 영역 확보
   ----------------------------------------------------------------------
   실측(784x265 CSS): HUD 가 화면의 32%, 그중 좌하단 스택 하나가 155x238 로
   세로의 90%를 차지했다. 게다가 스틱이 뜨는 아래 절반 한복판에 앉아 있었다.
   대책은 두 가지다.
   ① 아래 절반을 완전히 비운다 — 좌하단 스택을 좌상단 얇은 띠로 옮긴다.
   ② 플레이 중 안 보는 것부터 줄인다. 접속 통계는 지우고, 장비 강화 현황은
      3x2 격자에서 한 줄 칩으로, 아군 상태는 세로 목록에서 가로 칩으로.
      내 이름·킬 수는 내가 이미 아는 정보라 화면에서 뺀다.
   ══════════════════════════════════════════════════════════════════════ */

/* 터치 기기이면 화면이 커도 이 레이아웃을 쓴다. 예전에는 (max-height: 560px) 로 묶여
   있어, 펼친 폴더블처럼 세로가 긴 터치 기기에서는 하나도 걸리지 않았다. 그 결과
   좌하단 체력 패널이 이동 스틱 자리에 그대로 남아 조작을 가렸다.
   아래 규칙은 전부 body.touch-device 로 한정되어 있어 데스크톱에는 영향이 없다. */

  /* ── ② 지운다: 접속 통계는 폰에서 볼 일이 없다 ── */
  body.touch-device .stats-panel { display: none; }

  /* ── ① 좌하단 스택 → 좌상단 얇은 띠 ──
     스틱은 화면 아래 어디서나 뜨므로, 아래 절반에 패널이 있으면 안 된다.
     선택자에 #game-ui 를 붙인 것은 멋이 아니라 필요다 — 같은 파일의
     `#game-ui .hud-panel { padding: 11px 13px }` 같은 규칙이 아이디 특이도로
     이겨서, 클래스만으로 쓴 여백 축소가 전혀 먹지 않았다. */
  body.touch-device #game-ui .hud-left-bottom {
    top: max(4px, env(safe-area-inset-top));
    bottom: auto;
    left: max(4px, env(safe-area-inset-left));
    width: min(46vw, 286px);
    justify-content: flex-start;
    transform: none;
    gap: 3px;
  }

  /* 내 상태 — 한 줄 프로필 + HP + 얇은 XP 띠 + 장비 한 줄 */
  body.touch-device #game-ui .hud-panel { padding: 4px 6px; border-radius: 9px; border-width: 1px; }
  body.touch-device #game-ui .char-panel { gap: 3px; }
  body.touch-device #game-ui .player-profile { gap: 6px; }
  body.touch-device #game-ui .player-names { display: none; }   /* 내 이름·킬은 내가 안다 */
  body.touch-device #game-ui .level-badge { font-size: 0.66rem; padding: 2px 5px; border-radius: 4px; box-shadow: none; }
  body.touch-device #game-ui .lives-display {
    font-size: 0.8rem; letter-spacing: 0; padding: 1px 5px; border-radius: 6px; filter: none;
  }

  body.touch-device #game-ui .bar-container { height: 13px; border-radius: 4px; }
  body.touch-device #game-ui .bar-text { font-size: 0.56rem; }
  /* XP 는 '얼마나 찼나'만 알면 된다 — 숫자를 빼고 띠만 남긴다 */
  body.touch-device #game-ui .xp-container { height: 5px; }
  body.touch-device #game-ui .xp-container .bar-text { display: none; }

  /* 장비 강화 현황 — 레벨업 카드를 고를 때나 보는 정보다.
     3x2 격자(아이콘 위 · 레벨 아래)를 아이콘과 레벨이 나란한 한 줄 칩으로 */
  body.touch-device #game-ui .gear-status h4 { display: none; }
  body.touch-device #game-ui .gear-grid { display: flex; gap: 3px; flex-wrap: nowrap; }
  body.touch-device #game-ui .gear-slot {
    flex: 1 1 0;
    min-width: 0;
    padding: 2px 1px;
    font-size: 0.62rem;
    border-radius: 5px;
    flex-direction: row;
    gap: 2px;
    white-space: nowrap;
    overflow: hidden;
  }
  body.touch-device #game-ui .gear-slot .gear-lvl { font-size: 0.55rem; font-weight: 700; }
  /* 주무기 칸은 '원거리 Lv 1' 처럼 글자가 길어 다른 칸을 밀어낸다 */
  body.touch-device #game-ui .gear-slot.weapon-slot { flex: 1.9 1 0; }

  /* 아군 상태 — 세로 목록이 아니라 가로 칩. 이름과 남은 체력만 읽히면 된다 */
  body.touch-device #game-ui .team-status-panel { max-height: none; overflow: visible; }
  body.touch-device #game-ui .team-status-panel h4 { display: none; }
  body.touch-device #game-ui .team-members-container { flex-direction: row; flex-wrap: nowrap; gap: 3px; }
  body.touch-device #game-ui .team-member-row {
    flex: 1 1 0;
    min-width: 0;
    padding: 2px 4px;
    gap: 2px;
    border-left-width: 2px;
    border-radius: 5px;
  }
  body.touch-device #game-ui .team-member-info { font-size: 0.56rem; }
  body.touch-device #game-ui .team-member-name { max-width: none; }
  body.touch-device #game-ui .team-member-hp { display: none; }   /* 막대 길이로 충분하다 */
  body.touch-device #game-ui .team-member-hp-bar-bg { height: 4px; }

  /* ── 레벨업 바 — 하단 중앙의 큰 덩어리를 납작하게 ──
     'LEVEL UP' 글자와 1·2·3 단축키 배지는 터치에서 아무 의미가 없다. */
  body.touch-device #game-ui .upgrade-bar,
  body.touch-device .upgrade-bar {
    transform: translateX(-50%) scale(0.82);
    transform-origin: bottom center;
    bottom: max(4px, env(safe-area-inset-bottom));
    padding: 5px 8px;
    gap: 6px;
  }
  body.touch-device .upgrade-bar-label { display: none; }
  body.touch-device .mini-hotkey { display: none; }
  body.touch-device .upgrade-mini-card { padding: 4px 8px; }
  body.touch-device .upgrade-bar-gate { font-size: 0.66rem; padding: 2px 6px; }

  /* ── 스킬 버튼 — 세로 3칸이 화면 높이의 68%를 먹고 있었다 ──
     터치에는 키보드가 없으니 'Space·Q·E' 키 표시와 '대시·미각성' 이름표는
     읽을 이유가 없다. 아이콘과 쿨타임 숫자만 남기면 칸 높이가 크게 준다.
     탭 타깃 56px 하한은 그대로 지킨다. */
  body.touch-device #game-ui .skill-num,
  body.touch-device #game-ui .skill-name { display: none; }
  body.touch-device #game-ui .skill-slot { padding: 6px; }
  body.touch-device #game-ui .skill-icon { font-size: 1.5rem; }
  body.touch-device #game-ui .skill-bar { padding: 5px; gap: 6px; }

  /* 은신 표시도 띠처럼 얇게 */
  body.touch-device .stealth-indicator { font-size: 0.66rem; padding: 3px 10px; }

/* 장비 강화 현황을 아주 낮은 화면에서 아예 감추는 규칙을 뒀다가 걷어냈다.
   한 줄 칩으로 줄이고 나면 24px 밖에 안 쓰는데, 감추면 '내가 뭘 올렸는지'를
   확인할 방법이 사라진다. 줄이는 것으로 충분하다. */
@media (max-height: 300px) {
  body.touch-device #game-ui .team-member-name { font-size: 0.52rem; }
  body.touch-device #game-ui .gear-slot { font-size: 0.56rem; padding: 1px; }
  body.touch-device #game-ui .gear-slot .gear-lvl { font-size: 0.5rem; }
}

/* ══════════════════════════════════════════════════════════════════════
   14차: 창 크기 연동 인게임 HUD — 창을 줄이면 HUD 도 함께 줄어든다
   ----------------------------------------------------------------------
   전체화면에서는 알맞던 HUD 가 창을 줄이면 그대로 남아 화면을 뒤덮었다.
   실측(684x545): 좌측 패널 하나가 250x503 으로 세로의 92%, 화면의 34%.
   여기에 우상단 미니맵 21%, 스킬 바 7%가 겹쳐 플레이 영역이 거의 없었다.
   원인은 패널 여백·글자·막대 높이가 전부 고정 px 이었다는 것이다.
   대책은 기준 단위 --hud-u 하나를 만들어 모든 치수를 여기에 거는 것이다.
   가로와 세로 중 더 빡빡한 쪽을 따르고, 상한을 지금 값에 맞췄기 때문에
   큰 화면에서는 기존 모습이 그대로 유지된다.
   ══════════════════════════════════════════════════════════════════════ */

#game-ui {
  /* 상한 16px = 지금의 기본 여백(hud-panel padding 16px)과 같다 */
  --hud-u: clamp(9px, min(0.83vw, 1.6vh), 16px);
  --hud-edge: clamp(6px, 1.2vw, 20px);
}

/* ── 좌하단 스택 (아군 상태 + 캐릭터 패널) ───────────────────── */
#game-ui .hud-left-bottom {
  left: var(--hud-edge);
  bottom: var(--hud-edge);
  width: calc(var(--hud-u) * 20);      /* 16px 일 때 320px = 기존 값 */
  gap: calc(var(--hud-u) * 0.75);
}

#game-ui .hud-panel {
  padding: var(--hud-u);
  border-radius: calc(var(--hud-u) * 1);
}

#game-ui .char-panel { gap: calc(var(--hud-u) * 0.75); }

/* 접속 통계 — 좌상단 */
#game-ui .stats-panel { top: var(--hud-edge); left: var(--hud-edge); }
#game-ui .stat-row { font-size: calc(var(--hud-u) * 0.92); gap: calc(var(--hud-u) * 0.5); }
#game-ui .stat-dot { width: calc(var(--hud-u) * 0.5); height: calc(var(--hud-u) * 0.5); }

/* 아군 상태 */
#game-ui .team-status-panel h4 { font-size: calc(var(--hud-u) * 0.9); margin-bottom: calc(var(--hud-u) * 0.5); }
#game-ui .team-members-container { gap: calc(var(--hud-u) * 0.4); }
#game-ui .team-member-row { padding: calc(var(--hud-u) * 0.34) calc(var(--hud-u) * 0.6); gap: calc(var(--hud-u) * 0.22); }
#game-ui .team-member-info { font-size: calc(var(--hud-u) * 0.82); }
#game-ui .team-member-name { max-width: calc(var(--hud-u) * 8.5); }
#game-ui .team-member-hp-bar-bg { height: calc(var(--hud-u) * 0.36); }

/* 내 캐릭터 */
#game-ui .player-profile { gap: calc(var(--hud-u) * 0.6); }
#game-ui .level-badge { font-size: calc(var(--hud-u) * 0.82); padding: calc(var(--hud-u) * 0.2) calc(var(--hud-u) * 0.45); }
#game-ui .char-name { font-size: calc(var(--hud-u) * 1.0); }
#game-ui .kills-badge { font-size: calc(var(--hud-u) * 0.68); }
#game-ui .lives-display {
  font-size: calc(var(--hud-u) * 1.05);
  letter-spacing: 0;
  padding: calc(var(--hud-u) * 0.18) calc(var(--hud-u) * 0.5);
  border-radius: calc(var(--hud-u) * 0.6);
}
#game-ui .bar-container { height: calc(var(--hud-u) * 1.25); border-radius: calc(var(--hud-u) * 0.36); }
#game-ui .bar-text { font-size: calc(var(--hud-u) * 0.78); }

/* 장비 강화 현황 — 3x2 격자를 유지하되 칸을 단위에 건다 */
#game-ui .gear-status h4 { font-size: calc(var(--hud-u) * 0.76); margin-bottom: calc(var(--hud-u) * 0.4); }
#game-ui .gear-grid { gap: calc(var(--hud-u) * 0.34); }
#game-ui .gear-slot {
  padding: calc(var(--hud-u) * 0.34) calc(var(--hud-u) * 0.2);
  font-size: calc(var(--hud-u) * 0.9);
  border-radius: calc(var(--hud-u) * 0.5);
  gap: calc(var(--hud-u) * 0.1);
}
#game-ui .gear-slot .gear-lvl { font-size: calc(var(--hud-u) * 0.66); }

/* ── 우상단 (미니맵·경고 배너·킬로그) ────────────────────────── */
/* 소리 버튼이 우상단에 고정돼 있으므로 그 높이만큼 아래에서 시작한다 */
#game-ui .top-right-group {
  /* 소리 버튼(위 12px + 지름)의 바로 아래에서 시작한다 — 버튼과 같은 식으로
     계산해야 창 크기가 바뀌어도 둘이 겹치지 않는다 */
  top: calc(16px + clamp(26px, 3.4vh, 38px));
  right: var(--hud-edge);
  gap: calc(var(--hud-u) * 0.7);
}
#game-ui .minimap-container { padding: calc(var(--hud-u) * 0.4); border-radius: calc(var(--hud-u) * 0.9); }
#game-ui .danger-banner {
  width: calc(var(--hud-u) * 13);
  padding: calc(var(--hud-u) * 0.42) calc(var(--hud-u) * 0.7);
  font-size: calc(var(--hud-u) * 0.68);
  border-radius: calc(var(--hud-u) * 0.5);
}
#game-ui #fps-meter { font-size: calc(var(--hud-u) * 0.72); padding: calc(var(--hud-u) * 0.14) calc(var(--hud-u) * 0.55); }
#game-ui .kill-item { font-size: calc(var(--hud-u) * 0.8); padding: calc(var(--hud-u) * 0.34) calc(var(--hud-u) * 0.6); }

/* ── 상단 중앙 타이머 ────────────────────────────────────────── */
#game-ui .top-center-group { top: var(--hud-edge); }
#game-ui .timer-display {
  padding: calc(var(--hud-u) * 0.45) calc(var(--hud-u) * 1.15);
  font-size: calc(var(--hud-u) * 1.28);
  border-radius: calc(var(--hud-u) * 0.7);
}

/* ── 하단 스킬 바 ────────────────────────────────────────────── */
#game-ui .bottom-center-hud { bottom: var(--hud-edge); gap: calc(var(--hud-u) * 1.1); }
#game-ui .skill-bar { padding: calc(var(--hud-u) * 0.55); gap: calc(var(--hud-u) * 0.65); border-radius: calc(var(--hud-u) * 0.9); }
#game-ui .skill-slot {
  width: calc(var(--hud-u) * 4.5);     /* 16px 일 때 72px = 기존 값 */
  height: calc(var(--hud-u) * 4.5);
  border-radius: calc(var(--hud-u) * 0.75);
}
#game-ui .skill-icon { font-size: calc(var(--hud-u) * 1.5); margin-top: calc(var(--hud-u) * 0.25); }
#game-ui .skill-num { font-size: calc(var(--hud-u) * 0.64); }
#game-ui .skill-slot .skill-name { font-size: calc(var(--hud-u) * 0.62); }
#game-ui .skill-cooldown-text { font-size: calc(var(--hud-u) * 0.86); }

/* ── 레벨업 바 ───────────────────────────────────────────────── */
#game-ui .upgrade-bar {
  bottom: calc(var(--hud-edge) + var(--hud-u) * 5.8);   /* 스킬 바 위 */
  padding: calc(var(--hud-u) * 0.6) calc(var(--hud-u) * 1);
  gap: calc(var(--hud-u) * 0.5);
  border-radius: calc(var(--hud-u) * 1);
}
#game-ui .upgrade-bar-label { font-size: calc(var(--hud-u) * 0.95); }
#game-ui .upgrade-mini-card { padding: calc(var(--hud-u) * 0.4) calc(var(--hud-u) * 0.65); border-radius: calc(var(--hud-u) * 0.75); }
#game-ui .upgrade-mini-card .mini-icon { font-size: calc(var(--hud-u) * 1.35); }
#game-ui .upgrade-mini-card .mini-name { font-size: calc(var(--hud-u) * 0.86); }
#game-ui .upgrade-mini-card .mini-lvl { font-size: calc(var(--hud-u) * 0.76); }
#game-ui .mini-hotkey { font-size: calc(var(--hud-u) * 0.8); min-width: calc(var(--hud-u) * 1.4); }
#game-ui .upgrade-bar-gate { font-size: calc(var(--hud-u) * 0.84); }

#game-ui .stealth-indicator { font-size: calc(var(--hud-u) * 0.86); padding: calc(var(--hud-u) * 0.4) calc(var(--hud-u) * 0.9); }
#game-ui .buff-bar { font-size: calc(var(--hud-u) * 0.82); }

/* ── 창이 작아지면 순서대로 덜어낸다 ─────────────────────────
   단위를 줄이는 것만으로는 한계가 있다. 플레이 중 볼 이유가 적은 것부터
   지워야 남은 공간이 실제로 넓어진다. */

/* 1단계 — 접속 통계와 장비 현황 제목은 정보 밀도가 낮다 */
@media (max-width: 1100px), (max-height: 720px) {
  #game-ui .stats-panel { display: none; }
  #game-ui .gear-status h4 { display: none; }
  #game-ui .kills-badge { display: none; }
}

/* 2단계 — 아군 이름 옆 체력 숫자와 XP 숫자는 막대 길이로 읽힌다 */
@media (max-width: 900px), (max-height: 620px) {
  #game-ui .team-member-hp { display: none; }
  #game-ui .xp-container { height: calc(var(--hud-u) * 0.5); }
  #game-ui .xp-container .bar-text { display: none; }
  #game-ui .gear-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  #game-ui .gear-slot { flex-direction: row; padding: calc(var(--hud-u) * 0.22) calc(var(--hud-u) * 0.14); }
  #game-ui .gear-slot .gear-lvl { font-size: calc(var(--hud-u) * 0.58); }
  #game-ui .team-status-panel h4 { display: none; }
}

/* 3단계 — 아주 좁으면 장비 현황과 킬로그를 접는다 */
@media (max-width: 760px), (max-height: 520px) {
  /* 장비 현황은 감추지 않는다 — 2단계에서 이미 한 줄로 눌렀고,
     감추면 '내가 뭘 올렸는지' 확인할 방법이 사라진다 */
  #game-ui .kill-feed { display: none; }
  #game-ui .skill-slot .skill-name { display: none; }
}

/* 시작 화면 바닥글의 빌드 표식 — 작고 옅게 */
.build-tag { opacity: 0.55; font-size: 0.7rem; }

/* 🧪 테스트 모드 타격감 조절 패널 */
.hitfeel-panel {
  position: fixed; right: 16px; top: 300px; z-index: 120;
  background: rgba(20, 24, 18, 0.82); color: #f3ecd2; border: 1px solid rgba(250, 204, 21, 0.5);
  border-radius: 10px; padding: 8px 10px; font-size: 0.72rem; pointer-events: auto;
}
.hitfeel-panel .hf-title { font-weight: 900; margin-bottom: 6px; color: #fde68a; }
.hitfeel-panel .hf-row { display: flex; align-items: center; gap: 4px; margin: 3px 0; }
.hitfeel-panel .hf-label { width: 58px; opacity: 0.85; }
.hitfeel-panel .hf-btn { border: 1px solid rgba(255,255,255,0.25); background: rgba(255,255,255,0.06); color: #f3ecd2; border-radius: 6px; padding: 2px 6px; font-size: 0.7rem; cursor: pointer; }
.hitfeel-panel .hf-btn.on { background: #d97706; border-color: #fbbf24; color: #fff; font-weight: 800; }
.hitfeel-panel .hf-sep { margin-top: 8px; padding-top: 7px; border-top: 1px solid rgba(250, 204, 21, 0.28); }
.hitfeel-panel .hf-sep .hf-label { width: auto; flex: 1; }
.hitfeel-panel .hf-toggle { min-width: 42px; text-align: center; font-weight: 800; }
.hitfeel-panel .hf-toggle.on { background: #16a34a; border-color: #4ade80; }

/* 낮은 창에서는 방 항목을 더 납작하게 — 목록 컨테이너가 80px 대로 줄어도 한 항목이 다 보이게 */
@media (max-height: 700px) {
  .room-list-container { min-height: 96px; padding: 6px; gap: 6px; }
  .room-item { padding: 5px 10px; }
  .room-info { gap: 0; }
  .room-item-name { font-size: 0.82rem; }
  .room-item-count { font-size: 0.7rem; line-height: 1.2; }
  .room-item-teams { margin-top: 1px; }
  .team-chip { font-size: 0.62rem; padding: 0 6px; }
}

/* ── 시작 화면 왼쪽 칸 압축 (17차) ──
   튜토리얼·테스트 버튼이 추가되며 닉네임 카드가 길어져, 왼쪽 칸이 스크롤되고 서버 목록이
   화면 밖으로 밀렸다(FHD 에서도 목록 첫 항목이 잘림). 두 보조 버튼을 한 줄에 나란히 두고
   높이를 줄여 서버 목록에 자리를 돌려준다. 테스트 버튼이 숨겨지면 튜토리얼이 한 줄을 다 쓴다. */
.room-action-section { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 8px; }
.room-action-section > #create-room-btn,
.room-action-section > .observer-create-hint { grid-column: 1 / -1; }
.room-action-section > .tutorial-btn,
.room-action-section > .test-mode-btn { width: auto; padding: 8px 6px; font-size: 0.78rem; line-height: 1.2; white-space: nowrap; }
.room-action-section:not(:has(.test-mode-btn:not(.hidden))) > .tutorial-btn { grid-column: 1 / -1; }
.start-stack > .start-col:not(.start-col--rooms) { padding: 14px 16px; gap: 10px; }

/* 🧪 바닥글의 테스트 모드 링크 — 눈에 띄지 않게, 아는 사람만 누른다 */
.footer-copyright .test-mode-link { border: 0; background: none; color: inherit; opacity: 0.35; font: inherit; font-size: 0.7rem; cursor: pointer; padding: 0 2px; pointer-events: auto; }
.footer-copyright .test-mode-link:hover, .footer-copyright .test-mode-link:focus-visible { opacity: 0.9; text-decoration: underline; outline: none; }
.start-box .footer-copyright { pointer-events: auto; }
/* 시작 화면 간격 — 카드 폭과 입력 폭을 맞추고 목록의 최소 높이를 보장한다.
   터치는 아래의 단계형 메뉴를 사용하므로 데스크톱 레이아웃에만 적용한다.
   짧은 창에서는 컬럼을 억지로 압축하지 않고 오버레이 전체가 스크롤된다. */
body:not(.touch-device) #start-screen .start-box {
  max-width: 1160px !important;
  width: min(calc(100% - 32px), 1160px);
  max-height: none;
  padding: 24px;
  gap: 20px;
  overflow: visible;
}
body:not(.touch-device) #start-screen .start-grid {
  grid-template-columns: minmax(0, 1.5fr) minmax(320px, 1fr);
  flex: 0 0 auto;
  gap: 16px;
}
body:not(.touch-device) #start-screen .start-stack {
  gap: 16px;
  overflow: visible;
}
body:not(.touch-device) #start-screen .start-col {
  padding: 18px;
  gap: 12px;
}
body:not(.touch-device) #start-screen .input-group {
  width: 100%;
  max-width: none;
  gap: 12px;
}
/* 발명 모드 토글 · 서버 생성 · 튜토리얼 — 한 줄에 같은 높이로 나란히.
   토글은 '확장 · 스킬 동작 변경' 이 잘리지 않을 폭이 필요해 가장 넓게 둔다 */
body:not(.touch-device) #start-screen .room-action-section {
  grid-template-columns: minmax(0, 1.45fr) minmax(0, 1.2fr) minmax(0, 0.9fr);
  gap: 12px;
  align-items: stretch;
}
body:not(.touch-device) #start-screen #create-room-btn,
body:not(.touch-device) #start-screen .room-action-section > .tutorial-btn {
  grid-column: auto;
  width: 100%;
  min-width: 0;
  min-height: 52px;
  margin: 0;
}
body:not(.touch-device) #start-screen .room-action-section > .invention-mode-toggle { min-height: 52px; }
/* 서버 생성 — 양옆 토글·튜토리얼과 같은 판(2px 테두리·14px 둥근 모서리·평면)을 쓰되,
   주 행동이라 초록으로 채운다. 9-slice 나무 텍스처(.accent-btn)는 여기서만 걷어낸다. */
body:not(.touch-device) #start-screen #create-room-btn {
  border: 2px solid #3f7d1d;
  border-image: none;
  border-radius: 14px;
  background: #56a028;
  box-shadow: none;
  padding: 6px 14px;
  font-size: 1.15rem;
  transition: background-color .18s ease, border-color .18s ease;
}
body:not(.touch-device) #start-screen #create-room-btn:hover:not(:disabled) {
  background: #62b130;
  border-color: #356b18;
  transform: none;
  box-shadow: none;
}
body:not(.touch-device) #start-screen #create-room-btn:active:not(:disabled) { background: #4b8e22; transform: none; box-shadow: none; }
body:not(.touch-device) #start-screen #create-room-btn:focus-visible { outline: 3px solid #f0b428; outline-offset: 2px; }
body:not(.touch-device) #start-screen .room-action-section > .tutorial-btn {
  font-size: 0.9rem;
  white-space: nowrap;
  line-height: 1.3;
  color: #2f6fca !important;
}
.tutorial-btn-sub { display: block; font-size: 0.72rem; font-weight: 600; opacity: 0.75; }
/* QR 참가 흐름은 튜토리얼을 감춘다 — 빈 칸을 남기지 않고 참가 버튼이 남은 폭을 쓴다 */
body:not(.touch-device) #start-screen .room-action-section:has(> .tutorial-btn.hidden) > #create-room-btn { grid-column: 2 / -1; }
body:not(.touch-device) #start-screen .start-col--rooms {
  min-height: 224px;
}
body:not(.touch-device) #start-screen .room-list-container {
  min-height: 140px;
  max-height: 264px;
}
body:not(.touch-device) #start-screen .no-rooms-msg {
  margin: auto 0;
  padding: 20px 8px;
}
body:not(.touch-device) #start-screen .start-col--guide,
body:not(.touch-device) #start-screen .controls-guide {
  max-height: none;
  overflow: visible;
}
body:not(.touch-device) #start-screen .controls-guide ul:last-child { margin-bottom: 0; }
body:not(.touch-device) #start-screen .char-parade { gap: 32px; padding-bottom: 6px; }
body:not(.touch-device) #start-screen .char-parade img { height: 72px; }
body:not(.touch-device) #start-screen .char-parade .parade-monster img { height: 108px; }
.char-parade {
  height: 56px;
  overflow: visible;
  z-index: 1;
  pointer-events: none;
}
.parade-stage {
  position: absolute;
  inset: -64px 0 0;
  overflow: hidden;
}
.parade-actor {
  position: absolute;
  left: 0;
  bottom: 6px;
  display: block;
  visibility: hidden;
}
.parade-actor img { display: block; width: auto; }
.parade-tears { display: none; }
.parade-fleeing .parade-actor:not(.parade-monster) .parade-tears {
  display: block;
  position: absolute;
  left: 49%;
  top: 34%;
  width: 24%;
  height: 30%;
  pointer-events: none;
}
.parade-tears::before, .parade-tears::after {
  content: '';
  position: absolute;
  top: 0;
  width: 5px;
  height: 14px;
  border-radius: 40% 40% 60% 60%;
  background: linear-gradient(#e4fbff, #49c9ff);
  box-shadow: 0 1px 2px #247cba;
  animation: paradeTears .32s linear infinite;
}
.parade-tears::before { left: 0; }
.parade-tears::after { right: 0; animation-delay: -.16s; }
@keyframes paradeTears {
  from { transform: translate(-2px, 0); opacity: 1; }
  to { transform: translate(-8px, 10px); opacity: .25; }
}
.overlay.hidden .parade-tears::before,
.overlay.hidden .parade-tears::after { animation-play-state: paused; }
body:not(.touch-device) #start-screen .footer-copyright { line-height: 1.6; }

@media (max-width: 900px) {
  body:not(.touch-device) #start-screen .start-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 540px), (max-height: 700px) {
  body:not(.touch-device) #start-screen .start-box { padding: 16px; gap: 16px; }
  body:not(.touch-device) #start-screen .start-col { padding: 14px; }
}
/* '스킬 발명 · 공동 연구' 절이 늘어난 만큼, 낮은 창(노트북 900px 대)에서는 가이드 행간을 조여 스크롤을 막는다 */
@media (max-height: 940px) {
  body:not(.touch-device) #start-screen .controls-guide li { font-size: 0.88rem; line-height: 1.42; }
  body:not(.touch-device) #start-screen .controls-guide h3 + ul { margin-bottom: 10px; }
}
@media (max-width: 620px) {
  body:not(.touch-device) #start-screen .room-action-section { grid-template-columns: minmax(0, 1fr); }
}

/* 17차 메모리: 숨겨진 화면(시작·대기실·직업 선택·결과)의 숲 배경(각 1920×1080 ≈ 8MB 디코딩)은
   참조를 끊어 브라우저가 비트맵을 내릴 수 있게 한다. 다시 보일 때는 HTTP 캐시에서 즉시 복원된다. */
.overlay.hidden, .overlay.hidden::before, .overlay.hidden::after { background-image: none !important; }


/* ══════════════════════════════════════════════════════════════════════
   📱 18차: 오른쪽 아래 고정 조준 스틱 + 스킬 원형 배치
   참고: screenshots/ui/mobile_right.png — 조준 스틱 둘레에 대시(왼쪽)·Q(왼쪽 위)·E(위).
   스틱은 평소에도 옅은 베이스가 보인다(어디를 눌러야 하는지 알 수 있게). 베이스를 누르면
   그 중심에, 그 밖의 반화면을 누르면 누른 자리에 스틱이 생긴다(client.js enableTouchControls).
   스틱 중심(--joy-cx/--joy-cy)을 기준으로 베이스와 버튼이 같은 좌표계를 쓴다.
   ══════════════════════════════════════════════════════════════════════ */
body.touch-device {
  --joy-cx: calc(max(12px, env(safe-area-inset-right)) + 72px);    /* 스틱 중심 ← 오른쪽 가장자리 */
  --joy-cy: calc(max(12px, env(safe-area-inset-bottom)) + 64px);   /* 스틱 중심 ← 아래 가장자리 */
}
.touch-stick.home { opacity: 0.42; }
.touch-stick.home .stick-knob { opacity: 0.55; }
#stick-aim-home  { left: auto; top: auto; margin: 0; right: calc(var(--joy-cx) - 52px); bottom: calc(var(--joy-cy) - 52px); }
#stick-move-home { top: auto; margin: 0; left: calc(var(--joy-cx) - 52px); bottom: calc(var(--joy-cy) - 52px); }
/* 관전·탈락 중에는 조작이 없다 — 베이스도 걷는다 */
body.observing #touch-controls, body.eliminated #touch-controls { display: none; }

/* 스킬 버튼 — 스틱 중심을 원점으로 반지름 104px 원호에 배치 (대시 180° · Q 135° · E 90°).
   노브 최대 이동(48px)+노브 반지름(23px)=71px 이 버튼 안쪽 가장자리(104-29=75px)에 닿지 않는다.
   #game-ui 를 붙인 이유: 같은 파일의 #game-ui .skill-slot { width: calc(--hud-u*4.5) } 를 이기려면
   아이디 특이도가 필요하다. */
body.touch-device #game-ui .bottom-center-hud {
  left: auto; top: auto; width: 0; height: 0; gap: 0; transform: none;
  right: var(--joy-cx); bottom: var(--joy-cy);
}
body.touch-device #game-ui .skill-bar {
  position: absolute; left: 0; top: 0; width: 0; height: 0; padding: 0; gap: 0; display: block;
  background: none; border: none; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none;
}
body.touch-device #game-ui .skill-slot {
  position: absolute; width: 58px; height: 58px; min-width: 0; min-height: 0; padding: 0;
  border-radius: 50%; transform: translate(-50%, -50%);
  background: rgba(15, 23, 42, 0.72);
}
body.touch-device #game-ui .skill-slot[data-skill="Space"] { left: -104px; top: 0; }
body.touch-device #game-ui .skill-slot[data-skill="Q"]     { left: -74px;  top: -74px; }
body.touch-device #game-ui .skill-slot[data-skill="E"]     { left: 0;      top: -104px; }
body.touch-device #game-ui .skill-num,
body.touch-device #game-ui .skill-name { display: none; }
body.touch-device #game-ui .skill-icon { font-size: 1.5rem; margin: 0; }
body.touch-device #game-ui .skill-slot.aiming { transform: translate(-50%, -50%) scale(1.08); }

/* 🧪 테스트 모드 타격감 패널 — 폰에서는 오른쪽 아래(엄지 자리)를 덮어 조준 스틱을 막았다.
   쿨타임 초기화 토글만 남겨 상단 타이머 옆으로 보낸다. */
body.touch-device .hitfeel-panel {
  top: 6px; right: auto; left: calc(50% + 96px); padding: 3px 8px; font-size: 0.66rem;
}
body.touch-device .hitfeel-panel .hf-title,
body.touch-device .hitfeel-panel .hf-row:not(.hf-sep) { display: none; }
body.touch-device .hitfeel-panel .hf-sep { margin: 0; padding: 0; border: 0; }

/* ══════════════════════════════════════════════════════════════════════
   📱 터치 시작 화면 — 스크롤 없이 한 화면에 담는다
   폰 가로는 세로 높이가 344~412px 밖에 없다. PC 기준 여백·로고·치비
   퍼레이드를 그대로 두면 닉네임 칸이 화면 밖으로 31~42px 밀리고 조작법
   상자에 내부 스크롤이 생겨, 시작 화면을 훑어야 했다.
   장식을 걷고 배율을 낮춰 한눈에 들어오게 한다.
   전부 body.touch-device 한정이라 PC 에는 영향이 없다.
   파일 끝에 두는 이유: 앞쪽의 .start-box·.logo 규칙을 캐스케이드로 이겨야 한다.
   ══════════════════════════════════════════════════════════════════════ */

/* 조작법은 입력 방식에 맞는 쪽만 보인다.
   선택자에 .controls-guide 를 붙인 것은 필요해서다 — 같은 파일의
   `.controls-guide ul { display: flex }` 가 특이도(0,1,1)로 이겨서,
   클래스만 쓴 display:none(0,1,0)이 PC 에서 전혀 먹지 않았다. */
.controls-guide .ctl-touch { display: none; }
body.touch-device .controls-guide .ctl-pc { display: none; }
body.touch-device .controls-guide .ctl-touch { display: flex; }

body.touch-device #start-screen.overlay { padding: 6px; }
body.touch-device #start-screen .start-box {
  width: min(100%, 1320px);
  max-height: calc(100dvh - 12px);
  padding: 8px 12px 6px;
  gap: 6px;
  border-width: 2px;
}
/* 머리말 — 로고를 줄이고 부제는 한 줄로 붙인다 */
body.touch-device #start-screen .start-header { gap: 8px; }
body.touch-device #start-screen .logo { font-size: clamp(1.1rem, 3.2vw, 1.7rem); margin-bottom: 0; letter-spacing: 2px; }
body.touch-device #start-screen .logo-sub { font-size: 0.62rem; margin: 0; }
/* 장식은 세로 공간을 가장 많이 먹는다 — 가로에서는 뺀다 */
body.touch-device #start-screen .char-parade { display: none; }
body.touch-device #start-screen .footer-copyright { font-size: 0.58rem; margin-top: 2px; letter-spacing: 0; }
/* 본문 — 여백과 글자를 한 단계씩 줄인다 */
/* 가로 화면은 폭이 남는다 — 조작법 칸을 넓히면 긴 문장이 한 줄에 들어가
   줄 수가 줄고, 그만큼 세로가 확보된다 */
body.touch-device #start-screen .start-grid { gap: 8px; grid-template-columns: minmax(0, 1fr) minmax(320px, 46%); }
body.touch-device #start-screen .start-col-title { font-size: 0.78rem; margin-bottom: 4px; }
body.touch-device #start-screen .controls-guide { padding: 8px 10px; border-radius: 10px; overflow: hidden; }
body.touch-device #start-screen .controls-guide h3 { font-size: 0.7rem; margin: 0 0 2px; }
body.touch-device #start-screen .controls-guide h3 + ul { margin-bottom: 4px; }
body.touch-device #start-screen .controls-guide li { font-size: 0.6rem; line-height: 1.28; margin-bottom: 0; }
body.touch-device #start-screen .input-group { gap: 6px; }
body.touch-device #start-screen .input-group input[type="text"] { padding: 8px 10px; }
body.touch-device #start-screen .room-action-section { gap: 6px; }
body.touch-device #start-screen .accent-btn,
body.touch-device #start-screen .secondary-btn { padding: 8px 12px; font-size: 0.8rem; min-height: 40px; }
body.touch-device #start-screen .tutorial-btn { font-size: 0.72rem; min-height: 34px; }

/* 세로가 특히 짧은 폰 가로(≤400px) — 마지막 몇 px 을 저작권 줄과 배율에서 짜낸다 */
@media (max-height: 400px) {
  body.touch-device #start-screen .start-box { padding: 6px 10px 4px; gap: 4px; }
  body.touch-device #start-screen .logo { font-size: 1.05rem; letter-spacing: 1px; }
  body.touch-device #start-screen .logo-sub { font-size: 0.56rem; }
  body.touch-device #start-screen .controls-guide { padding: 6px 8px; }
  body.touch-device #start-screen .controls-guide h3 { font-size: 0.64rem; }
  body.touch-device #start-screen .controls-guide li { font-size: 0.55rem; line-height: 1.2; }
  body.touch-device #start-screen .footer-copyright { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════
   📱 튜토리얼 말풍선 — 캐릭터를 가리지 않게 화면 위쪽으로 붙인다
   말풍선은 화면 중앙에서 205px 위에 놓였고, 짧은 화면에서는
   `@media (max-height: 640px)` 가 top:70px 로 오히려 아래로 내렸다.
   세로가 344~412px 뿐인 폰 가로에서는 그 자리가 곧 화면 한가운데라,
   카메라가 따라다니는 캐릭터를 통째로 덮어 조작이 불가능했다
   (측정: 캐릭터 영역과 7,440~11,520px² 겹침).
   위 가장자리에 얇게 붙이고 배율을 낮춰, 아래로 캐릭터 자리까지
   내려오지 않게 한다. PC 는 겹침이 없으므로 그대로 둔다.
   ══════════════════════════════════════════════════════════════════════ */
body.touch-device .tut-bubble {
  top: max(4px, env(safe-area-inset-top));
  width: min(72vw, 580px);
  padding: 6px 10px 6px;
  gap: 7px;
  font-size: 0.67rem;
  line-height: 1.3;
  border-width: 2px;
  border-radius: 12px;
}
/* 아래를 가리키는 꼬리는 캐릭터 쪽으로 뻗는다 — 위에 붙은 말풍선에는 맞지도 않는다 */
body.touch-device .tut-bubble .tut-tail { display: none; }
body.touch-device .tut-avatar {
  width: 26px; height: 26px; font-size: 0.95rem; border-width: 2px;
}
body.touch-device .tut-title { font-size: 0.58rem; margin-bottom: 1px; }
body.touch-device .tut-progress { margin-top: 4px; font-size: 0.62rem; }
body.touch-device .tut-actions { margin-top: 5px; gap: 8px; }
body.touch-device .tut-next { padding: 5px 12px; font-size: 0.72rem; border-radius: 8px; }
body.touch-device .tut-skip { padding: 2px 6px; font-size: 0.64rem; }

/* ══════════════════════════════════════════════════════════════════════
   📱 모바일·태블릿 가로 전용 시작 화면 — 단계형 흐름
   세로용 한 화면(닉네임 + 서버 목록 + 조작법)을 가로에 다 넣으면 세로가
   344~412px 뿐이라 스크롤이 생기고 손이 닿는 자리도 아니다.
   닉네임 → 메뉴 → 서버 목록 / 가이드 순서로 한 번에 하나만 보여 준다.
   PC 는 아래 요소가 전부 감춰져 기존 한 화면 배치를 그대로 쓴다.
   ══════════════════════════════════════════════════════════════════════ */
.m-menu, .m-back, #m-next { display: none; }

body.touch-device #start-screen .start-grid,
body.touch-device #start-screen .start-stack { display: block; }
/* 단계 전환은 data-mstep 하나로 관리한다 — 켤 것만 아래에서 되살린다 */
body.touch-device #start-screen[data-mstep] .start-col,
body.touch-device #start-screen[data-mstep] .m-menu,
body.touch-device #start-screen[data-mstep] .m-back { display: none; }
/* 생성·튜토리얼 버튼은 메뉴 단계로 옮겼으므로 닉네임 칸에서는 감춘다 */
body.touch-device #start-screen .room-action-section { display: none; }

/* ① 닉네임 */
body.touch-device #start-screen[data-mstep="name"] .start-col:not(.start-col--rooms):not(.start-col--guide) { display: block; }
body.touch-device #start-screen[data-mstep="name"] #m-next { display: block; margin-top: 10px; width: 100%; }
body.touch-device #start-screen[data-mstep="name"] .input-group { max-width: 420px; margin: 0 auto; }

/* ② 메뉴 — 가로 화면이므로 2×2 로 크게 */
body.touch-device #start-screen[data-mstep="menu"] .m-menu { display: grid; }
body.touch-device #start-screen[data-mstep="menu"] .m-back,
body.touch-device #start-screen[data-mstep="rooms"] .m-back,
body.touch-device #start-screen[data-mstep="guide"] .m-back { display: block; }
body.touch-device #start-screen .m-menu {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px; max-width: 620px; margin: 6px auto 0;
}
body.touch-device #start-screen .m-btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 52px; padding: 10px 14px;
  font-family: inherit; font-size: 0.92rem; font-weight: 900; letter-spacing: -0.01em;
  color: #4a3a1c; background: rgba(255, 251, 235, 0.95);
  border: 2px solid rgba(122, 96, 48, 0.45); border-radius: 12px;
  box-shadow: 0 3px 0 rgba(122, 96, 48, 0.35); cursor: pointer;
}
body.touch-device #start-screen .m-btn span { font-size: 1.15rem; }
body.touch-device #start-screen .m-btn:active { transform: translateY(2px); box-shadow: 0 1px 0 rgba(122, 96, 48, 0.35); }
body.touch-device #start-screen .m-btn-primary {
  color: #fff; background: linear-gradient(135deg, #f59e0b, #d97706);
  border-color: #b45309; box-shadow: 0 3px 0 #92400e;
}
body.touch-device #start-screen .m-btn:disabled { opacity: 0.45; }
body.touch-device #start-screen .m-back {
  margin: 0 auto 4px; padding: 6px 14px; min-height: 36px;
  font-family: inherit; font-size: 0.78rem; font-weight: 900; color: #6b5326;
  background: transparent; border: 2px solid rgba(122, 96, 48, 0.35);
  border-radius: 10px; cursor: pointer;
}

/* ③ 서버 목록 — 가로라 폭이 남으므로 1행 3열 */
body.touch-device #start-screen[data-mstep="rooms"] .start-col--rooms { display: block; }
body.touch-device #start-screen[data-mstep="rooms"] #room-list-container {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px;
  align-content: start; overflow-y: auto;
}
body.touch-device #start-screen[data-mstep="rooms"] .no-rooms-msg { grid-column: 1 / -1; }

/* ④ 가이드 — 가로 화면에 맞춰 2단으로 읽는다 */
body.touch-device #start-screen[data-mstep="guide"] .start-col--guide { display: block; }
body.touch-device #start-screen[data-mstep="guide"] .controls-guide {
  columns: 2; column-gap: 20px; padding: 10px 14px; overflow-y: auto;
}
body.touch-device #start-screen[data-mstep="guide"] .controls-guide h3 { break-after: avoid; font-size: 0.78rem; }
body.touch-device #start-screen[data-mstep="guide"] .controls-guide ul { break-inside: avoid; }
body.touch-device #start-screen[data-mstep="guide"] .controls-guide li { font-size: 0.7rem; line-height: 1.4; }

/* ══ 대기실 — 가로에서 두 팀이 한눈에 들어오게 3열을 유지한다 ══
   모바일에서는 폭 기준 미디어 쿼리가 3열을 1열로 쌓아, 팀2와 사이드가
   화면 밖으로 154~431px 밀리고 279~552px 을 스크롤해야 했다. */
body.touch-device #lobby-screen .lobby-grid {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 0.8fr);
  gap: 8px;
}
body.touch-device #lobby-screen .lobby-grid .team-column-1 { grid-column: 1; grid-row: 1; }
body.touch-device #lobby-screen .lobby-grid .team-column-2 { grid-column: 2; grid-row: 1; }
body.touch-device #lobby-screen .lobby-grid .lobby-side { grid-column: 3; grid-row: 1; }
body.touch-device #lobby-screen .lobby-grid .team-column { min-height: 0; }
body.touch-device #lobby-screen .lobby-grid .team-member-card { flex: none; width: 100%; }
/* QR 은 이미 방에 들어온 기기에 필요 없고 세로를 192px 먹는다 — 가로에서는 뺀다 */
body.touch-device #lobby-screen .qr-block { display: none; }
body.touch-device #lobby-screen .lobby-box { --panel-pad: 8px; padding: 8px 12px; gap: 6px; max-height: calc(100dvh - 12px); }
body.touch-device #lobby-screen .lobby-header h2 { font-size: 1rem; }
body.touch-device #lobby-screen .lobby-header p { font-size: 0.72rem; }
body.touch-device #lobby-screen .team-column-header { font-size: 0.76rem; padding: 4px 8px; }
body.touch-device #lobby-screen .side-title { font-size: 0.7rem; }
body.touch-device #lobby-screen .accent-btn,
body.touch-device #lobby-screen .danger-btn,
body.touch-device #lobby-screen .secondary-btn { min-height: 40px; padding: 8px 14px; font-size: 0.82rem; }

/* 대기실 가로 — 남은 세로를 짜낸다. 버튼을 세로로 쌓으면 97px 을 먹는다.
   가로 화면이므로 한 줄로 눕히고, 사이드 블록과 상태 띠도 함께 조인다. */
body.touch-device #lobby-screen .lobby-actions {
  display: flex; flex-direction: row; flex-wrap: wrap;
  align-items: center; justify-content: center; gap: 8px; margin-top: 0;
}
body.touch-device #lobby-screen .waiting-msg { margin: 0; font-size: 0.72rem; }
body.touch-device #lobby-screen .team-start-status { padding: 3px 10px; font-size: 0.72rem; }
body.touch-device #lobby-screen .side-block { padding: 6px 8px; }
body.touch-device #lobby-screen .lobby-bot-section { padding: 6px 8px; }
body.touch-device #lobby-screen .lobby-bot-controls { display: flex; gap: 6px; }
body.touch-device #lobby-screen .lobby-bot-controls .secondary-btn { min-height: 34px; padding: 6px 8px; font-size: 0.72rem; }
body.touch-device #lobby-screen .team-rule { font-size: 0.66rem; }
body.touch-device #lobby-screen .lobby-observer-list { font-size: 0.7rem; }

/* 대기 안내문이 flex-basis:100% 로 한 줄을 통째로 차지해, 버튼이 다음 줄로 밀려
   결국 세로로 쌓였다. 가로에서는 버튼과 같은 줄에 둔다. */
body.touch-device #lobby-screen .lobby-actions .waiting-msg { flex-basis: auto; align-self: center; }
body.touch-device #lobby-screen .lobby-actions .accent-btn,
body.touch-device #lobby-screen .lobby-actions .danger-btn {
  min-width: 0; padding-left: 18px; padding-right: 18px;
}
/* 세로가 특히 짧은 화면(≤400px) — 한 단계 더 조인다 */
@media (max-height: 400px) {
  body.touch-device #lobby-screen .lobby-header h2 { font-size: 0.88rem; }
  body.touch-device #lobby-screen .lobby-header p { font-size: 0.66rem; }
  body.touch-device #lobby-screen .team-start-status { padding: 2px 8px; font-size: 0.66rem; }
  body.touch-device #lobby-screen .side-title { font-size: 0.64rem; }
  body.touch-device #lobby-screen .accent-btn,
  body.touch-device #lobby-screen .danger-btn { min-height: 34px; padding: 6px 14px; font-size: 0.74rem; }
  body.touch-device #lobby-screen .lobby-box { padding: 6px 10px; gap: 4px; }
  body.touch-device #lobby-screen .side-block,
  body.touch-device #lobby-screen .lobby-bot-section { padding: 4px 7px; }
  body.touch-device #lobby-screen .team-column-header { font-size: 0.7rem; padding: 3px 7px; }
  body.touch-device #lobby-screen .lobby-actions { padding-top: 4px; padding-bottom: 6px; margin-top: 2px; }
  body.touch-device #lobby-screen .lobby-grid { gap: 6px; }
}

/* 하단 고정 버튼 바 — 세로 여백이 30px 을 먹는다. 가로에서는 얇게 만든다 */
body.touch-device #lobby-screen .lobby-actions {
  margin-top: 4px; padding-top: 6px; padding-bottom: 8px;
}
body.touch-device #lobby-screen .lobby-side { gap: 6px; }
body.touch-device #lobby-screen .lobby-grid .team-column-list { gap: 5px; }
body.touch-device #lobby-screen .lobby-header { margin-bottom: 0; }

/* ══════════════════════════════════════════════════════════════════════
   19차: 1차 릴리즈 HUD 정리
   ══════════════════════════════════════════════════════════════════════ */

/* ── 버튼 통일 — 9-slice 나무 텍스처를 걷고 토글·보조 버튼과 같은 평면 판으로 ──
   주 행동(.accent-btn) = 초록으로 채움 · 위험 행동(.danger-btn) = 붉은 테두리의 밝은 판.
   모두 2px 테두리 · 14px 모서리. 대기실(게임 시작·방 나가기), 결과 화면(다시하기), 알림 모달이 같이 바뀐다. */
.accent-btn, #start-button, #start-screen .accent-btn {
  border: 2px solid #3f7d1d;
  border-image: none;
  border-radius: 14px;
  background: #56a028;
  box-shadow: none;
  padding: 10px 22px;
  min-height: 48px;
  transition: background-color .18s ease, border-color .18s ease;
}
.accent-btn:hover:not(:disabled), #start-screen .accent-btn:hover:not(:disabled) { background: #62b130; border-color: #356b18; transform: none; box-shadow: none; }
.accent-btn:active:not(:disabled), #start-screen .accent-btn:active:not(:disabled) { background: #4b8e22; transform: none; box-shadow: none; }
.danger-btn {
  border: 2px solid #d9663b;
  border-image: none;
  border-radius: 14px;
  background: #fff4ec;
  color: #b8431a;
  text-shadow: none;
  box-shadow: none;
  padding: 10px 22px;
  min-height: 48px;
  transition: background-color .18s ease, border-color .18s ease;
}
.danger-btn:hover { background: #ffe6d6; border-color: #b8431a; transform: none; box-shadow: none; filter: none; }
.danger-btn:active { background: #ffd9c2; transform: none; box-shadow: none; }
.secondary-btn { border-radius: 14px; }
.victory-actions .accent-btn, .victory-actions .secondary-btn { min-height: 48px; flex: 0 1 220px; margin: 0; }
.lobby-actions { flex-direction: row; flex-wrap: wrap; justify-content: center; }
.lobby-actions .waiting-msg { flex: 1 1 100%; }

/* ── HUD 글자 크기 통일 — 공동 발명연구 패널(제목 18 · 본문 14 · 보조 12)을 기준으로 ──
   단위(--hud-u)는 #game-ui 밖의 패널(공동 발명연구)도 쓰도록 :root 에도 둔다.
   창을 줄이면 같이 줄되, 읽을 수 없는 크기까지는 내려가지 않게 바닥을 둔다. */
/* 단위 상한 16px → 32px(19차): 상한이 FHD 기준에 묶여 있어 QHD·UHD 에서는 HUD 만 작게 남았다.
   FHD 에서는 지금과 같고(15.9px), QHD 는 21px · UHD(100%)는 32px 로 화면과 같은 비율을 유지한다. */
:root {
  --hud-u: clamp(9px, min(0.83vw, 1.6vh), 32px);
  --hud-edge: clamp(6px, 1.2vw, 40px);
  --hud-fs-title: max(13px, calc(var(--hud-u) * 1.125));
  --hud-fs-body: max(11px, calc(var(--hud-u) * 0.875));
  --hud-fs-small: max(10px, calc(var(--hud-u) * 0.75));
}
/* PC 에만 적용한다 — 터치 기기는 HUD 단위가 9px 대라 바닥값이 걸리면 경고 배너가 스킬 버튼을 덮는다 */
body:not(.touch-device) #game-ui .team-status-panel h4 { font-size: var(--hud-fs-title); }
body:not(.touch-device) #game-ui .stat-row, body:not(.touch-device) #game-ui .team-member-info,
body:not(.touch-device) #game-ui .kill-item, body:not(.touch-device) #game-ui .bar-text,
body:not(.touch-device) #game-ui .level-badge, body:not(.touch-device) #game-ui .gear-status h4,
body:not(.touch-device) #game-ui .danger-banner { font-size: var(--hud-fs-body); }
body:not(.touch-device) #game-ui .kills-badge, body:not(.touch-device) #game-ui .gear-slot .gear-lvl,
body:not(.touch-device) #game-ui #fps-meter, body:not(.touch-device) #game-ui .skill-num { font-size: var(--hud-fs-small); }
body:not(.touch-device) #game-ui .danger-banner { width: calc(var(--hud-u) * 16); line-height: 1.45; }
body:not(.touch-device) #game-ui .team-member-name { max-width: calc(var(--hud-u) * 11); }

#game-ui { --hud-u: clamp(9px, min(0.83vw, 1.6vh), 32px); --hud-edge: clamp(6px, 1.2vw, 40px); }
body.observing, .observer-dock { --obs-u: clamp(9.5px, min(0.84vw, 1.72vh), 30px); --obs-rail: clamp(140px, 14vw, 472px); --obs-edge: clamp(6px, 0.7vw, 36px); }

/* ── 접속 통계(전체 연결 · 생존 · 처참한 최후) — 세로 3줄을 가로 한 줄로 ── */
#game-ui .stats-panel { flex-direction: row; align-items: center; gap: calc(var(--hud-u) * 1.1); padding: calc(var(--hud-u) * 0.55) calc(var(--hud-u) * 0.9); }
#game-ui .stat-row { white-space: nowrap; }

/* ── 킬로그 — 색은 팀으로만(아군 초록 · 적군 빨강 · 관전자는 중계 화면의 팀 색), 직업은 이름 앞 아이콘 ── */
.kill-item { justify-content: flex-start; gap: 8px; border-left-color: #94a3b8; }
.kill-item.ally { border-left-color: #22c55e; }
.kill-item.enemy, .kill-item.team-1 { border-left-color: #ef4444; }
.kill-item.team-2 { border-left-color: #3b82f6; }
.kill-item.neutral { border-left-color: #f59e0b; }
.kill-name { display: inline-flex; align-items: center; gap: 4px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kill-name.ally { color: #4ade80; }
.kill-name.enemy, .kill-name.team-1 { color: #f87171; }
.kill-name.team-2 { color: #60a5fa; }
.kill-name.neutral { color: #fbbf24; }
.kill-class { flex: none; }
.kill-sep { flex: none; color: #cbd5e1; font-size: 0.8em; }

/* ── 관전 화면 좌하단 툴바 — 다른 버튼과 같은 평면 판(2px 테두리)으로, 글자는 HUD 본문 크기로 ── */
.obs-mode-btn {
  border: 2px solid rgba(150, 122, 68, 0.45);
  border-radius: calc(var(--hud-u) * 0.8);
  background: #fffdf4;
  font-size: var(--hud-fs-body);
  padding: calc(var(--hud-u) * 0.45) calc(var(--hud-u) * 0.95);
  transition: background-color .18s ease, border-color .18s ease;
}
.obs-mode-btn:hover { background: #f4fbea; border-color: #6cbb45; }
.obs-mode-btn.active { background: #56a028; color: #fffef6; border-color: #3f7d1d; }
.obs-mode-btn:focus-visible { outline: 3px solid #f0b428; outline-offset: 2px; }
.obs-toolbar-hint { font-size: var(--hud-fs-small); }

/* ── 🎬 최종 킬 — 슬로모션·줌인 동안 가장자리를 어둡게 눌러 시선을 가운데로 모은다 ── */
#game-ui.finale::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(ellipse at center, rgba(8, 12, 6, 0) 38%, rgba(8, 12, 6, 0.5) 100%);
  animation: finaleVeil 0.5s ease-out both;
}
@keyframes finaleVeil { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { #game-ui.finale::after { animation: none; } }
