/* 리셋 · 레이아웃 · 플레이 화면 HUD.
   index.html이 screens.css보다 먼저 읽으므로, 원래 <style> 안에 있던
   순서(= 캐스케이드)가 그대로 유지된다. 미디어 쿼리 두 개도 여기에 있다
   — 둘 다 .app/.mainCol/.stage/canvas/.joystick 같은 이 파일의 선택자만
   덮어쓴다. */

:root {
  color-scheme: dark;
  --bg: #111318;
  --panel: #1c222b;
  --panel-2: #252d37;
  --text: #eef3f7;
  --muted: #9ba8b6;
  --accent: #f2c14e;
  --danger: #e85d5d;
  --ok: #5fd08a;
  --wall: #657180;
  --floor: #2b3340;
  --room: #353f4d;
}

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

html, body {
  height: 100%;
  overscroll-behavior: none;
}

body {
  margin: 0;
  height: 100dvh;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  font-family: "Segoe UI", "Malgun Gothic", system-ui, sans-serif;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  touch-action: none;
}

.app {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100dvh;
  overflow: hidden;
}

.mainCol {
  display: flex;
  flex-direction: column;
  min-height: 0;
  height: 100%;
}

.stage {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  background:
    linear-gradient(90deg, rgba(255,255,255,0.025) 1px, transparent 1px),
    linear-gradient(rgba(255,255,255,0.025) 1px, transparent 1px),
    #151922;
  background-size: 48px 48px;
}

canvas {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none;
  cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><g fill="none" stroke="black" stroke-width="4" stroke-linecap="round"><line x1="16" y1="1" x2="16" y2="12"/><line x1="16" y1="20" x2="16" y2="31"/><line x1="1" y1="16" x2="12" y2="16"/><line x1="20" y1="16" x2="31" y2="16"/><circle cx="16" cy="16" r="5"/></g><g fill="none" stroke="%2339ff14" stroke-width="2" stroke-linecap="round"><line x1="16" y1="2" x2="16" y2="11"/><line x1="16" y1="21" x2="16" y2="30"/><line x1="2" y1="16" x2="11" y2="16"/><line x1="21" y1="16" x2="30" y2="16"/><circle cx="16" cy="16" r="4"/></g></svg>') 16 16, crosshair;
}

.chip {
  min-width: 0;
  padding: 4px 7px;
  border: 1px solid rgba(255,255,255,0.12);
  background: rgba(255,255,255,0.055);
  border-radius: 7px;
}

.chip b {
  display: block;
  font-size: 9px;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 2px;
}

.chip span {
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
}

/* 활성화된 버프를 필드 왼쪽 위에 겹쳐 보여주는 패널. 남은 시간이 줄어드는
   게이지와 함께 표시해서 언제 끊기는지 한눈에 알 수 있게 한다. */
.buffZone {
  position: absolute;
  top: 8px;
  left: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  pointer-events: none;
  z-index: 3;
}

.buffZone:empty {
  display: none;
}

/* 게스트 지연 표시. 필드 오른쪽 위에 겹쳐 둔다 — 버프 패널(왼쪽 위)과
   반대쪽이라 둘이 겹치지 않고, 조작 영역도 가리지 않는다. */
.netStatTag {
  position: absolute;
  top: 8px;
  right: 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px 8px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(12, 16, 24, 0.72);
  pointer-events: none;
  z-index: 3;
  font-size: 10px;
  line-height: 1.25;
}

.netStatTag span {
  display: flex;
  gap: 6px;
  justify-content: space-between;
}

.netStatTag b {
  color: var(--muted);
  font-weight: 600;
}

.netStatTag i {
  font-style: normal;
  font-weight: 700;
  color: #7fe0a8;
}

/* 노랑/빨강은 "회선이 문제다"를 눈에 띄게 하려는 것이다. 임계값의 근거는
   js/ui.js의 NET_PING_WARN_MS 주석에 있다. */
.netStatTag i.warn { color: #ffd166; }
.netStatTag i.bad { color: #ff7a6a; }

.buffChip {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px 4px 6px;
  border-radius: 8px;
  border: 1px solid var(--buffColor);
  background: rgba(12, 16, 24, 0.72);
  box-shadow: 0 2px 8px rgba(0,0,0,0.35);
  min-width: 116px;
}

.buffChip.expiring {
  animation: buffBlink 0.6s steps(2, end) infinite;
}

@keyframes buffBlink {
  50% { opacity: 0.42; }
}

.buffChip > .buffDot {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--buffColor);
  box-shadow: 0 0 6px var(--buffColor);
}

.buffChip > .buffInfo {
  flex: 1 1 auto;
  min-width: 0;
}

.buffChip .buffName {
  display: block;
  font-size: 10px;
  font-weight: 700;
  color: #eef2f7;
  white-space: nowrap;
}

/* 남은 시간은 숫자 없이 게이지 길이로만 나타낸다. 초 표시를 뺀 만큼
   게이지를 두껍게 잡아 한눈에 읽히게 한다. */
.buffChip .buffBar {
  /* span 이라 display를 주지 않으면 인라인이 되어 height가 통째로 무시된다.
     예전에는 옆의 초 표시가 남아 있어 이 결함이 드러나지 않았다. */
  display: block;
  margin-top: 4px;
  height: 5px;
  border-radius: 3px;
  overflow: hidden;
  background: rgba(255,255,255,0.16);
}

.buffChip .buffBar > i {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: var(--buffColor);
  box-shadow: 0 0 5px var(--buffColor);
}

.bar {
  width: 100%;
  height: 5px;
  overflow: hidden;
  background: rgba(255,255,255,0.14);
  border-radius: 999px;
  margin-top: 3px;
}

.bar > i {
  display: block;
  height: 100%;
  width: 100%;
  background: linear-gradient(90deg, #0f7a44, #b6f36a);
}

.bar.ammo > i {
  background: linear-gradient(90deg, #8a4a06, #ffd970);
}

.bar.ammo.infinite > i {
  background: linear-gradient(90deg, #10688f, #b8ecff);
}

/* --- 하단 컨트롤 독: 조이스틱 + 상태창을 화면 한쪽(아래)으로 통합해
   세로로 긴 화면비를 실제 플레이 화면(캔버스)에서 조금 완화한다 --- */
.controlDock {
  position: relative;
  z-index: 5;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px max(9px, env(safe-area-inset-right)) max(9px, env(safe-area-inset-bottom)) max(9px, env(safe-area-inset-left));
  background: #12161d;
  border-top: 1px solid rgba(255,255,255,0.1);
  touch-action: none;
}

.joystick {
  position: relative;
  flex: 0 0 auto;
  width: 90px;
  height: 90px;
  border-radius: 50%;
  background: rgba(255,255,255,0.07);
  border: 2px solid rgba(255,255,255,0.22);
  touch-action: none;
}

.joystick-thumb {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 40px;
  height: 40px;
  margin-left: -20px;
  margin-top: -20px;
  border-radius: 50%;
  background: rgba(242, 193, 78, 0.85);
  border: 2px solid rgba(255,255,255,0.5);
  box-shadow: 0 4px 10px rgba(0,0,0,0.3);
  pointer-events: none;
}

.joystick.active {
  background: rgba(255,255,255,0.1);
  border-color: rgba(242, 193, 78, 0.55);
}

.joystick.active .joystick-thumb {
  background: rgba(242, 193, 78, 1);
}

.statusZone {
  flex: 1 1 auto;
  min-width: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5px;
}

.menuToggle {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: 50%;
  background: rgba(255,255,255,0.07);
  border: 1px solid rgba(255,255,255,0.18);
  color: var(--text);
  font-size: 15px;
  line-height: 1;
  display: grid;
  place-items: center;
  touch-action: manipulation;
}

aside {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 6;
  width: min(270px, 78vw);
  height: 100%;
  padding: 16px 14px;
  padding-top: max(20px, env(safe-area-inset-top));
  padding-right: max(14px, env(safe-area-inset-right));
  padding-bottom: max(16px, env(safe-area-inset-bottom));
  border-left: 1px solid rgba(255,255,255,0.1);
  background: rgba(17, 21, 28, 0.98);
  overflow-y: auto;
  transform: translateX(100%);
  transition: transform 0.22s ease;
  touch-action: pan-y;
}

aside.open {
  transform: translateX(0);
}

h1 {
  margin: 0 0 4px;
  font-size: 18px;
  letter-spacing: 0;
}

.mapNameTag {
  display: inline-block;
  margin-bottom: 14px;
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(242, 193, 78, 0.14);
  border: 1px solid rgba(242, 193, 78, 0.4);
  color: var(--accent);
  font-size: 11px;
  font-weight: 700;
}

.panel {
  border: 1px solid rgba(255,255,255,0.1);
  background: var(--panel);
  border-radius: 8px;
  padding: 12px;
  margin-bottom: 12px;
}

.panel h2 {
  margin: 0 0 10px;
  font-size: 14px;
  color: #dce7f3;
}

/* 축소한 순위표를 담는 상자. 축소(transform)는 그림만 줄이고 자식들의
   레이아웃 높이는 그대로 남기므로, 이 상자가 실제 차지할 높이를 잡고
   넘치는 레이아웃을 잘라 준다. 없으면 옆 패널에 헛스크롤이 생긴다.
   (자를 위험은 없다 — 상자 높이를 축소 뒤 그림 높이에 정확히 맞춘다.) */
.leaderboardFit {
  overflow: hidden;
}

/* 순위표는 12명(팀전이면 팀 + 팀원)이 항상 다 보여야 한다. 줄을 한 줄로
   좁혀 두고, 그래도 창에 안 들어가면 fitLeaderboard()가 통째로 줄인다.
   설정창(.start-card)과 같은 방식이고, 이유도 같다 — 브라우저 확대를 하면
   CSS 픽셀 기준 창 높이가 줄어 아래쪽 줄이 잘린다. */
.leaderboard {
  display: grid;
  gap: 4px;
  transform-origin: top left;
}

.rank {
  display: grid;
  grid-template-columns: 24px 1fr 38px;
  align-items: center;
  gap: 8px;
  min-height: 28px;
  padding: 5px 7px;
  background: var(--panel-2);
  border-radius: 7px;
  font-size: 13px;
}

.rank .dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid rgba(255,255,255,0.55);
}

/* 경기 중 순위표만 좁은 줄을 쓴다. 경기 종료 화면(#messageRanking)은
   자리가 넉넉하므로 위의 기본 .rank 그대로 둔다. */
.leaderboard .rank {
  grid-template-columns: 18px 1fr auto 34px;
  gap: 6px;
  min-height: 0;
  padding: 3px 6px;
  font-size: 12.5px;
}

/* 팀 줄은 팀원 이름이 아래로 붙으므로 킬/데스 칸이 없다. */
.leaderboard .rank.teamRow {
  grid-template-columns: 18px 1fr 34px;
}

.leaderboard .rank .dot {
  width: 11px;
  height: 11px;
  border-width: 2px;
  margin-right: 2px;
}

.leaderboard .kd {
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}

.leaderboard .rank small {
  font-size: 10.5px;
  line-height: 1.35;
  margin-top: 0;
}

.rank.me {
  outline: 2px solid var(--accent);
}

.rank small {
  display: block;
  color: var(--muted);
  font-weight: 500;
  font-size: 11px;
  margin-top: 2px;
}

button {
  height: 44px;
  padding: 0 16px;
  border: 0;
  border-radius: 7px;
  background: var(--accent);
  color: #211a09;
  font-weight: 800;
  cursor: pointer;
  touch-action: manipulation;
}

.fireHint {
  position: absolute;
  right: max(12px, env(safe-area-inset-right));
  bottom: 10px;
  z-index: 3;
  padding: 6px 10px;
  border-radius: 8px;
  background: rgba(25,31,40,0.6);
  border: 1px solid rgba(255,255,255,0.12);
  color: var(--muted);
  font-size: 11px;
  pointer-events: none;
  opacity: 0.85;
  max-width: 128px;
  text-align: right;
}

.fireHint.hide {
  display: none;
}

.rotateHint {
  position: absolute;
  top: max(10px, env(safe-area-inset-top));
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(25,31,40,0.88);
  border: 1px solid rgba(255,255,255,0.14);
  color: var(--muted);
  font-size: 11px;
  display: none;
  touch-action: manipulation;
}

.rotateHint.show {
  display: block;
}

.hide {
  display: none !important;
}

/* 전체화면 토글. 상태창(controlDock) 안에 흐름대로 놓인다 — 필드 위에 뜨지
   않아야 경기를 가리지 않는다.

   z-index로 시작 화면·결과창(8) 위로 올리려 해 봤지만 안 된다. .controlDock이
   이미 `position: relative; z-index: 5`라 쌓임 맥락(stacking context)을 만들고,
   그 안의 z-index는 아무리 키워도 5 안에 갇힌다. 독 자체를 올리면 조이스틱과
   상태 칩까지 설정창 위로 떠오르므로 그럴 수도 없다.
   그래서 설정 화면·결과창이 떠 있는 동안에는 이 버튼이 덮인다. 그때는 Esc로
   나간다(안드로이드는 뒤로가기 제스처, iOS는 전체화면 자체가 없다). 정작
   필요한 경기 중에는 늘 눌린다. */
.fullscreenBtn {
  flex: 0 0 auto;
  /* 아래 button 규칙이 height 44px을 준다. 그건 손가락으로 누르는 큰
     버튼(시작·재시작)에 맞춘 값이라, 상태창에 늘 붙어 있는 이것에는 크다. */
  height: 32px;
  padding: 0 11px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(12, 16, 24, 0.72);
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  /* 한글은 글자 사이에서 줄이 바뀐다. 좁은 독에서 "전체화면"이 두 줄로
     접히지 않게 막는다. */
  white-space: nowrap;
  cursor: pointer;
  touch-action: manipulation;
}

.fullscreenBtn:hover {
  color: var(--text);
  border-color: rgba(255, 255, 255, 0.32);
}

/* --- 데스크톱(마우스/키보드) 화면: 상태창을 항상 펼쳐 보여주고
   모바일 전용 조이스틱은 숨긴다 --- */
@media (min-width: 880px) and (hover: hover) and (pointer: fine) {
  .app {
    flex-direction: row;
  }

  .mainCol {
    flex: 1 1 auto;
    min-width: 0;
  }

  .joystick {
    display: none;
  }

  .menuToggle {
    display: none;
  }

  .fireHint {
    display: none;
  }

  aside {
    position: static;
    flex: 0 0 300px;
    width: 300px;
    height: 100%;
    transform: none;
    transition: none;
  }

  /* 세로 독에서는 칩들이 위에서부터 쌓이고 남는 자리는 비어 있다. 전체화면
     버튼을 그 맨 아래로 내려 상태 칩과 섞이지 않게 한다. */
  .fullscreenBtn {
    margin-top: auto;
    width: 100%;
  }

  /* 데스크톱에서는 창이 넓을수록 플레이 화면(캔버스)의 가로가 세로에
     비해 지나치게 길어지므로, 최대 가로세로비를 두어 좌우로 여백을
     두고 그 안에 화면을 중앙 정렬한다. */
  .stage {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  /* 필드 가로 비율을 7:5까지 낮춘다(기존 8:5). 스크립트의
     PC_VIEW_WIDTH/HEIGHT와 반드시 같은 비율이어야 레터박스가 생기지 않는다. */
  canvas {
    width: auto;
    height: 100%;
    max-width: 100%;
    aspect-ratio: 7 / 5;
  }

  /* 가로 비율을 줄이면 좌우에 여백이 남는다. 하단 가로 바였던 상태창을
     그 여백 쪽 세로 독으로 옮기면, 캔버스가 화면 세로를 온전히 쓸 수 있어
     같은 창에서도 필드가 더 크게 보인다.
     row-reverse: DOM 순서(stage → dock)를 그대로 두고 독만 왼쪽에 둔다
     (오른쪽에는 이미 상세 정보 패널이 있으므로 좌우로 나눠 배치). */
  .mainCol {
    flex-direction: row-reverse;
  }

  .controlDock {
    flex: 0 0 auto;
    flex-direction: column;
    justify-content: flex-start;
    width: 180px;
    height: 100%;
    gap: 8px;
    padding: 12px 10px;
    border-top: 0;
    border-right: 1px solid rgba(255,255,255,0.1);
  }

  /* 세로 독에서는 칩이 남는 높이만큼 늘어나지 않도록 내용 높이로 고정하고
     위쪽부터 쌓는다. */
  .statusZone {
    flex: 0 0 auto;
    width: 100%;
    grid-template-columns: 1fr;
    align-content: start;
  }
}

/* --- 모바일(터치) 가로모드: 조이스틱 + 상태창을 화면 하단 전체가 아닌
   왼쪽 세로 독으로 몰아서, 필드(캔버스)가 화면 가로 전체를 다 차지해
   지나치게 넓은 가로 비율이 되지 않고 1:1에 좀 더 가까워지도록 한다 --- */
@media (orientation: landscape) and (pointer: coarse) {
  .mainCol {
    flex-direction: row-reverse;
  }

  .controlDock {
    flex: 0 0 auto;
    /* column-reverse: DOM 순서(조이스틱→상태창→메뉴버튼)를 그대로 두되
       시각적으로는 뒤집어서, 엄지가 닿기 편한 화면 왼쪽 아래에 조이스틱이
       오도록 한다(메뉴 버튼은 자연스럽게 위쪽 구석으로). */
    flex-direction: column-reverse;
    justify-content: flex-start;
    width: 172px;
    height: 100%;
    overflow-y: auto;
    gap: 10px;
    padding: max(10px, env(safe-area-inset-top)) 9px max(10px, env(safe-area-inset-bottom)) max(9px, env(safe-area-inset-left));
    border-top: 0;
    border-right: 1px solid rgba(255,255,255,0.1);
  }

  .joystick {
    align-self: center;
    width: 76px;
    height: 76px;
  }

  .joystick-thumb {
    width: 34px;
    height: 34px;
    margin-left: -17px;
    margin-top: -17px;
  }

  .statusZone {
    width: 100%;
  }

  .menuToggle {
    align-self: center;
  }
}
