/*
 * RNG ARENA 디자인 토큰 — 팔레트 A(다크 슬레이트 + 틸 + 크림).
 * 다크 슬레이트 바탕(#10141C·#1A212B), 크림 포인트(#E0CFA2), 틸 글로우(#4FB3A5).
 * 픽셀아트 관례대로 바탕은 저채도 5단, 강조는 크림 1계열로 묶는다. 채도 높은 금색과
 * 진한 청색을 함께 쓰던 템플릿 조합에서 벗어나는 것이 이 팔레트의 목적이다.
 * 색·보더·패널·버튼은 전부 이 블록을 정본으로 삼는다.
 */
:root {
  /*
   * 색 채널 — 알파를 달고 쓰는 색은 여기 공백 구분 RGB 하나만 정본으로 둔다.
   * 규칙 본문은 `rgb(var(--c-deep) / 0.949)`로 파생해 쓴다(hex 재기입 금지).
   */
  --c-deep: 16 20 28;
  --c-scrim: 10 13 19;
  --c-panel: 26 33 43;
  --c-panel-soft: 36 46 58;
  --c-panel-mid: 42 53 66;
  --c-slot: 21 27 36;
  --c-gold: 224 207 162;
  --c-gold-bright: 246 236 208;
  --c-gold-warm: 246 238 214;
  --c-info: 108 198 216;
  --c-owned: 79 179 165;
  --c-epic: 176 146 216;
  --c-legendary: 234 201 122;
  --c-black: 0 0 0;
  --c-white: 255 255 255;

  /* 바탕 */
  --bg-deep: rgb(var(--c-deep));
  --bg-void: rgb(var(--c-scrim));
  --bg-panel: rgb(var(--c-panel));
  --bg-panel-soft: rgb(var(--c-panel-soft));
  --bg-panel-mid: rgb(var(--c-panel-mid));
  --bg-slot: rgb(var(--c-slot));
  --bg-slot-raised: #212a36;
  --bg-scrim: rgb(var(--c-scrim) / 0.851);
  --bg-chip: #30363d;
  --bg-blackout: #050606;
  --bg-gold-deep: #1d2420;

  /* 크림 포인트 — 글로우만 틸로 준다(고채도 금색 발광을 쓰지 않는다). */
  --gold: rgb(var(--c-gold));
  --gold-bright: rgb(var(--c-gold-bright));
  --gold-deep: #8a7a50;
  --gold-line: rgb(var(--c-gold) / 0.349);
  --gold-line-strong: rgb(var(--c-gold) / 0.702);
  --gold-glow: rgb(var(--c-owned) / 0.18);

  /* 텍스트 */
  --ink: #ede6d6;
  --ink-soft: #b3c2cb;
  --ink-dim: #8496a3;
  --ink-on-gold: #141a12;

  /* 상태색 — 제한적으로만 사용한다. */
  --ok: #6fcfa5;
  --ok-deep: #41a87b;
  --info: rgb(var(--c-info));
  --info-deep: #419eb1;
  --danger: #e2685e;
  --danger-line: #5e3a38;
  --danger-bg: #3a2422;
  --danger-bg-deep: #241618;
  --danger-ink: #f3cfc9;
  --owned: rgb(var(--c-owned));

  /* 등급색 */
  --grade-common: #9fadb9;
  --grade-uncommon: #84cd90;
  --grade-rare: #63b5d2;
  --grade-epic: rgb(var(--c-epic));
  --grade-legendary: rgb(var(--c-legendary));

  /* 장비 등급 5단계 — 노멀·레어·에픽·유니크·레전드 */
  --grade-normal: var(--grade-common);
  --grade-unique: var(--owned);
  --grade-legend: var(--grade-legendary);

  /* 에픽 배너 — 승급 연출이 쓰는 보라 계열 파생색 */
  --epic-bg: #362d43;
  --epic-bg-deep: #1f1927;
  --epic-ink: #d0bee8;

  /* 패널·보더 */
  --line-card: #2f3b49;
  --line-quiet: #2b3644;
  --line-mid: #38434f;
  --line-bright: #47586a;
  --line-info: #3f5666;
  --radius-panel: 0.9rem;
  --radius-card: 0.65rem;
  --radius-slot: 0.5rem;
  --border-panel: 1px solid var(--gold-line);
  --border-card: 1px solid var(--line-card);
  --border-soft: 1px solid var(--line-quiet);
  --shadow-panel: 0 1.5rem 4.5rem rgb(var(--c-black) / 0.867), 0 0 2rem var(--gold-glow);
  --shadow-card: 0 0.35rem 1rem rgb(var(--c-black) / 0.467);

  /* 버튼 */
  --btn-gold: linear-gradient(180deg, var(--gold-bright), var(--gold) 55%, var(--gold-deep));
  --btn-navy: linear-gradient(180deg, var(--bg-panel-soft), var(--bg-panel));
  --btn-disabled-bg: #222a34;
  --btn-disabled-ink: #6d7a86;
  --line-disabled: var(--line-mid);
  --tap-min: 2.75rem;

  /*
   * 밀도 — 오버레이 여백·행 간격·폰트 단계를 여기서만 조절한다.
   * 표면(HUD)은 건드리지 않고 오버레이 안쪽 정보 밀도만 올린다.
   * 터치 표면은 --tap-min이 따로 지키므로 여백을 줄여도 조작성은 유지된다.
   */
  --pad-panel: 0.6rem 0.85rem;
  --pad-body: 0.7rem 0.85rem;
  --gap-panel: 0.7rem;
  --gap-card: 0.35rem;
  --gap-row: 0.25rem;

  /* 폰트 스케일 5단계 — 과대 헤더를 없애고 단계를 고정한다. */
  --fs-title: 1.1rem;
  --fs-section: 0.86rem;
  --fs-body: 0.78rem;
  --fs-meta: 0.72rem;
  --fs-micro: 0.66rem;

  /*
   * 오버레이 크기 — 표면과 같은 --hud-unit 스케일에서 파생하는 5단계 폭·2단계 높이.
   * 값은 "뷰포트 비례 상한", "절대 상한", "여백·노치를 뺀 실측" 셋 중 가장 작은 쪽이라
   * 어떤 화면에서도 패널이 밖으로 나가지 않고, 좁고 짧은 뷰포트에서는 저절로 전체 화면에
   * 가까워진다. 높이는 100dvh 기준이라 모바일 주소창이 펴져도 헤더·푸터가 잘리지 않는다.
   *
   * 절대 상한(rem)이 따로 있는 이유 — 오버레이 안쪽 정보 밀도(--fs-*·--pad-*)는 표면
   * 스케일과 분리돼 고정이다. 표면이 커진다고 패널까지 같이 부풀면 글자 크기는 그대로인 채
   * 여백만 늘어 화면 점유만 커진다. 표면은 자라고 오버레이는 오늘 크기에서 멈춘다.
   */
  --overlay-pad: clamp(0.4rem, 2.2vmin, 1.1rem);
  --overlay-gutter-x: calc(var(--overlay-pad) * 2 + env(safe-area-inset-left, 0px) + env(safe-area-inset-right, 0px));
  --overlay-gutter-y: calc(var(--overlay-pad) * 2 + env(safe-area-inset-top, 0px) + env(safe-area-inset-bottom, 0px));
  --overlay-w-xl: min(calc(var(--hud-unit) * 56), 58rem, calc(100vw - var(--overlay-gutter-x)));
  --overlay-w-lg: min(calc(var(--hud-unit) * 45), 46rem, calc(100vw - var(--overlay-gutter-x)));
  --overlay-w-md: min(calc(var(--hud-unit) * 35), 36rem, calc(100vw - var(--overlay-gutter-x)));
  --overlay-w-sm: min(calc(var(--hud-unit) * 29), 30rem, calc(100vw - var(--overlay-gutter-x)));
  --overlay-w-xs: min(calc(var(--hud-unit) * 24), 24.5rem, calc(100vw - var(--overlay-gutter-x)));
  --popover-w: min(calc(var(--hud-unit) * 20), 20.5rem, calc(100vw - var(--overlay-gutter-x)));
  --overlay-h: min(calc(var(--hud-unit) * 42), 43rem, calc(100dvh - var(--overlay-gutter-y)));
  --overlay-h-sm: min(calc(var(--hud-unit) * 35), 36rem, calc(100dvh - var(--overlay-gutter-y)));
  /* 오버레이 안쪽 목록의 높이 상한 — 짧은 화면(가로 모드)에서는 dvh 쪽이 이긴다. */
  --overlay-list-h: min(24rem, 46dvh);
  --overlay-list-h-lg: min(26rem, 50dvh);

  /*
   * 표면(HUD) 유동 스케일 — 고정 브레이크포인트 패치 대신 뷰포트에 비례해 자란다.
   * 기준을 vmin으로 잡아 세로·가로 어느 쪽이 짧아도 같은 비율로 줄어든다(가로 모드 안전).
   * 터치 표면(--tap-min)만은 이 스케일과 무관하게 44px를 지킨다.
   *
   * 기울기 1.41vmin은 "손가락/시야 거리에 맞는 크기"에서 역산한 값이다 —
   * 최소변 390px에서 12.86px(모바일 현행 유지), 900px에서 20.05px, 1080px에서 22.59px,
   * 1440px에서 27.66px. 옛 상한 1.02rem은 최소변 1024px에서 이미 걸려 768×1024·1440×900·
   * 1920×1080이 전부 같은 크기였다(큰 화면일수록 표면이 상대적으로 더 작아 보였다).
   * 새 상한 1.75rem은 최소변 1468px부터만 걸리는 폭주 방지선이라 실사용 구간을 묶지 않는다.
   */
  --hud-unit: clamp(0.74rem, 0.46rem + 1.41vmin, 1.75rem);
  --hud-gap: calc(var(--hud-unit) * 0.36);
  --hud-gap-tight: calc(var(--hud-unit) * 0.22);
  --hud-radius: calc(var(--hud-unit) * 0.42);

  /* 가장자리 여백 — 노치·홈 인디케이터(safe-area)를 그대로 더한다. */
  --hud-edge: calc(var(--hud-unit) * 0.62);
  --hud-edge-left: calc(var(--hud-edge) + env(safe-area-inset-left, 0px));
  --hud-edge-right: calc(var(--hud-edge) + env(safe-area-inset-right, 0px));
  --hud-edge-top: calc(var(--hud-edge) + env(safe-area-inset-top, 0px));
  --hud-edge-bottom: calc(var(--hud-edge) + env(safe-area-inset-bottom, 0px));

  /* 표면 글자·아이콘 — 오버레이 밀도(--fs-*)와 분리해 따로 자란다. */
  --hud-fs: var(--hud-unit);
  --hud-fs-sm: max(0.68rem, calc(var(--hud-unit) * 0.86));
  --hud-fs-xs: max(0.62rem, calc(var(--hud-unit) * 0.76));
  --hud-icon: clamp(1rem, calc(var(--hud-unit) * 1.55), 2.75rem);
  --hud-portrait: clamp(1.5rem, calc(var(--hud-unit) * 1.85), 4rem);
  /* 미니맵은 배수를 따로 키운다 — 데스크톱에서 "작아서 안 보인다"가 나오던 자리다. */
  --hud-minimap: clamp(2.2rem, calc(var(--hud-unit) * 4), 7.5rem);

  /*
   * 아이콘 리프트 — 카드(테두리+배경) 없이 아이콘 자체를 버튼으로 세우는 대비 수단.
   * 밝은 크림 림 두 겹이 어두운 지형 위에서 실루엣을 살리고, 어두운 그림자 한 겹이
   * 밝은 지형(모래·눈) 위에서 살린다. 무거운 포스트프로세싱(블룸·backdrop-filter)은 아니다.
   */
  /*
   * 아이콘 아트가 다크 슬레이트 선화라 어두운 지형(물·바위) 위에서는 실루엣이 통째로
   * 묻힌다(1440×900 실측). 그래서 밝기를 먼저 올려 몸통을 지형에서 떼고, 크림 림 두 겹을
   * 겹쳐 1~2px 스티커 외곽선을 만든 뒤, 마지막 어두운 그림자로 밝은 지형과도 분리한다.
   */
  --hud-icon-lift:
    brightness(1.28)
    drop-shadow(0 0 1px rgb(var(--c-gold-bright) / 0.95))
    drop-shadow(0 0 2px rgb(var(--c-gold-bright) / 0.75))
    drop-shadow(0 2px 4px rgb(var(--c-black) / 0.9));
  --hud-icon-lift-strong:
    brightness(1.4)
    drop-shadow(0 0 1px rgb(var(--c-gold-bright) / 1))
    drop-shadow(0 0 3px rgb(var(--c-gold) / 0.9))
    drop-shadow(0 2px 4px rgb(var(--c-black) / 0.9));
  --hud-icon-lift-flare:
    brightness(1.55)
    drop-shadow(0 0 1px rgb(var(--c-gold-bright) / 1))
    drop-shadow(0 0 6px rgb(var(--c-gold) / 0.95))
    drop-shadow(0 2px 4px rgb(var(--c-black) / 0.9));
  /* 아이콘 뒤 경계 없는 방사형 스크림 — 각진 카드가 아니라 지형을 눌러 주는 그늘이다. */
  --hud-icon-scrim: radial-gradient(closest-side, rgb(var(--c-scrim) / 0.5), rgb(var(--c-scrim) / 0));

  /*
   * 가장자리 앵커가 비우고 지나가는 띠 — 상단바 줄과 파티 초상 줄이 실제로 먹는 높이다.
   * 우측 퀵 레일·미니 피드는 이 두 띠 사이에만 서서 어떤 뷰포트에서도 겹치지 않는다.
   * 초상이 --tap-min보다 커지는 큰 화면에서는 초상 쪽이 띠 높이를 정한다.
   */
  --hud-bottom-zone: calc(max(var(--tap-min), var(--hud-portrait)) + var(--hud-unit) * 1.6 + env(safe-area-inset-bottom, 0px));

  /*
   * 오버레이 스택 4층 — "누가 누구 위에 열리는가"의 의미 단위다.
   * 옛 계약은 백드롭이 전부 z-index 30이라 층을 DOM 선언 순서가 정했고, 편성 위에 연
   * 영웅 상세·픽커가 부모 뒤로 깔렸다(전체 화면 전환 뒤에는 통째로 가려진다).
   * 층 판단의 정본은 여기 하나이고, 배선은 계산된 z-index를 읽어 포커스 스택을 맞춘다.
   */
  --z-overlay-base: 30;     /* 진입점(퀵 레일·☰ 메뉴)에서 직접 여는 오버레이 */
  --z-overlay-popover: 31;  /* 영웅 상세 — 편성 위에 뜨고 자기 위에 픽커를 연다 */
  --z-overlay-picker: 32;   /* 부모 오버레이가 연 선택·상세 팝업 */
  --z-overlay-confirm: 33;  /* 확인 다이얼로그 — 언제나 최상위 */
}

html, body {
  margin: 0;
  height: 100%;
  /* 모바일 주소창 개폐로 표면 앵커가 잘리지 않게 작은 뷰포트 높이를 바닥으로 깐다. */
  min-height: 100svh;
  overflow: hidden;
  background: var(--bg-deep);
  color: var(--ink);
  font-family: 'Pretendard', 'Apple SD Gothic Neo', system-ui, sans-serif;
}

/* 패널 모서리 장식 — 레퍼런스의 금속 프레임 코너를 순수 CSS로 표현한다. */
.panel-frame {
  position: relative;
}

.panel-frame::before,
.panel-frame::after {
  content: '';
  position: absolute;
  width: 1.15rem;
  height: 1.15rem;
  pointer-events: none;
  border: 2px solid var(--gold-line-strong);
}

.panel-frame::before {
  top: 0.35rem;
  left: 0.35rem;
  border-right: 0;
  border-bottom: 0;
  border-top-left-radius: 0.35rem;
}

.panel-frame::after {
  right: 0.35rem;
  bottom: 0.35rem;
  border-left: 0;
  border-top: 0;
  border-bottom-right-radius: 0.35rem;
}

#game-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  cursor: pointer;
  /*
   * 백버퍼는 devicePixelRatio 상한(2) 때문에 물리 픽셀보다 작을 수 있다.
   * 그 마지막 확대까지 니어리스트로 묶어야 픽셀 경계가 산다 — auto로 두면
   * 브라우저가 이중선형으로 늘려서 고DPR 모바일에서만 번져 보인다.
   */
  image-rendering: pixelated;
}

#game-canvas[hidden] {
  display: none;
}

#game-canvas.hero-selected {
  cursor: zoom-out;
}

#hud {
  position: fixed;
  inset: 0;
  /* 주소창이 접혔다 펴져도 표면 하단 앵커가 화면 밖으로 밀리지 않는다. */
  height: 100dvh;
  pointer-events: none;
}

/*
 * 표면 앵커의 기준 상자 — 모달이 열리면 이 상자만 통째로 inert가 된다.
 * 두 행 격자로 두어 상단바가 몇 줄로 접히든 "상단바 아래 남은 띠"가 실측으로 잡힌다.
 * (예전에는 토큰으로 상단바 높이를 어림했는데, 노치가 있는 가로 모드처럼 상단바가
 *  두 줄로 접히면 어림값이 모자라 우측 퀵 레일과 겹치는 회귀가 실측으로 잡혔다.)
 * 바닥 앵커(파티 초상)는 격자 배치를 받지 않아 예전처럼 상자 전체를 기준으로 붙는다.
 */
#hud-surface {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr);
}

/*
 * 상단 HUD — ref-main-hud: 좌측 스테이지 칩, 중앙 킬 진행 바, 우측 골드와 조작 열.
 * 일일 보상은 topbar 아래로 흐르게 두어 줄바꿈 높이와 무관하게 겹치지 않는다.
 */
#hud-top {
  grid-row: 1;
  display: grid;
  justify-items: center;
}

#topbar {
  width: 100%;
  box-sizing: border-box;
  display: flex;
  /*
   * 좌·우 열은 자리가 모자랄 때만 스스로 줄바꿈한다 — 폭 기준 패치 없이
   * 어느 뷰포트에서든 잘리지 않고 두 줄로 접힌다.
   */
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--hud-gap);
  padding:
    var(--hud-edge-top)
    var(--hud-edge-right)
    calc(var(--hud-unit) * 1.4)
    var(--hud-edge-left);
  background: linear-gradient(rgb(var(--c-scrim) / 0.8) 0%, rgb(var(--c-scrim) / 0.4) 55%, rgb(var(--c-black) / 0) 100%);
  font-size: var(--hud-fs);
  font-weight: 700;
  text-shadow: 0 1px 3px rgb(var(--c-black));
}

.topbar-left,
.topbar-right {
  display: flex;
  align-items: center;
  gap: var(--hud-gap);
  flex: 1 1 auto;
  min-width: 0;
}

.topbar-right {
  flex-wrap: wrap;
  justify-content: flex-end;
}

.hud-brand {
  display: grid;
  margin: 0;
  padding: calc(var(--hud-unit) * 0.28) calc(var(--hud-unit) * 0.55);
  border: 1px solid var(--gold-line);
  border-radius: var(--hud-radius);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.851), rgb(var(--c-deep) / 0.851));
  color: var(--gold-bright);
  font-size: calc(var(--hud-fs-xs) * 0.86);
  font-weight: 900;
  letter-spacing: 0.18em;
  line-height: 1.15;
  text-align: center;
}

/* 좁은 화면에서는 지표 텍스트가 우측 버튼 열을 침범하지 않고 줄어든다. */
#topbar span {
  white-space: nowrap;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

#topbar .hud-brand span { overflow: visible; }

#stage { flex: 0 0 auto; }

/*
 * 미니맵 버튼 — 캔버스 하나와 스테이지 한 줄만 띄운다. 타이틀 카드 배경·테두리는
 * 두지 않는다(표면 정리 계약). 누르면 지도 오버레이가 열린다(진입점 하나 계약).
 */
#stage {
  display: grid;
  justify-items: center;
  gap: var(--hud-gap-tight);
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  padding: 0;
  pointer-events: auto;
  border: 0;
  background: none;
  color: var(--gold-bright);
  font: inherit;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
}

/* 저해상 캔버스를 확대해 쓴다 — 3D 픽셀 룩과 같은 니어리스트 계단을 남긴다. */
#minimap-canvas {
  display: block;
  width: var(--hud-minimap);
  height: var(--hud-minimap);
  border: 1px solid var(--gold-line);
  border-radius: calc(var(--hud-radius) * 0.7);
  background: var(--bg-void);
  image-rendering: pixelated;
}

.minimap-stage {
  color: var(--gold-bright);
  font-size: var(--hud-fs-xs);
  font-weight: 800;
  line-height: 1.05;
  /* 카드가 사라진 자리에서도 밝은 지형 위에서 읽히게 얇은 그림자만 남긴다. */
  text-shadow: 0 1px 2px rgb(var(--c-scrim) / 0.8);
}

/* 최전선에서 사냥 중이면 스테이지 글씨가 금색 강조로 바뀐다. */
#stage.is-frontier .minimap-stage { color: var(--gold); }

#stage:hover #minimap-canvas,
#stage:focus-visible #minimap-canvas { border-color: var(--gold); }

#stage:hover,
#stage:focus-visible {
  outline: 2px solid var(--gold-line-strong);
  outline-offset: 2px;
}

.topbar-purse {
  display: grid;
  justify-items: end;
  gap: var(--hud-gap-tight);
  min-width: 0;
  padding: calc(var(--hud-unit) * 0.28) calc(var(--hud-unit) * 0.7);
  border: 1px solid var(--gold-line-strong);
  border-radius: var(--hud-radius);
  background: linear-gradient(180deg, rgb(var(--c-panel-mid) / 0.8), rgb(var(--c-deep) / 0.8));
}

#gold { color: var(--gold-bright); font-weight: 900; }

/* 초당 수입은 표면에서 빼고 성장 화면 헤더에서만 읽는다. */
.growth-gold-rate { color: var(--ok); font-size: 0.74rem; font-weight: 600; }

.ui-icon {
  display: inline-grid;
  flex: 0 0 auto;
  place-items: center;
  width: 1.35rem;
  height: 1.35rem;
  overflow: hidden;
  line-height: 1;
}

.ui-icon img,
.ui-icon-fallback {
  grid-area: 1 / 1;
}

.ui-icon img {
  display: none;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ui-icon.is-loaded img { display: block; }
.ui-icon.is-loaded .ui-icon-fallback { display: none; }

.hud-menu-icon {
  width: var(--hud-icon);
  height: var(--hud-icon);
  /* 카드가 없으니 실루엣 자체가 대비를 든다 — 밝은 림 두 겹 + 어두운 그림자 한 겹. */
  filter: var(--hud-icon-lift);
}

.close-icon {
  width: 1.25rem;
  height: 1.25rem;
  margin: auto;
}

.button-ui-icon,
.title-settings-icon {
  width: 1.45rem;
  height: 1.45rem;
}

/*
 * ☰ 단일 메뉴 버튼 — 표면에 남는 유일한 관리 진입점이고, 수령 가능 항목은
 * 통합 배지 하나로만 알린다(개별 버튼·배지를 표면에 늘어놓지 않는다).
 * 카드(테두리+그라디언트 배경)는 두르지 않는다 — 아이콘 자체가 버튼이고, 지형과의
 * 대비는 아이콘 리프트(다중 drop-shadow) + 경계 없는 방사형 스크림이 만든다.
 */
.hud-menu-button {
  position: relative;
  display: grid;
  place-items: center;
  min-height: var(--tap-min);
  min-width: var(--tap-min);
  padding: 0;
  pointer-events: auto;
  border: 0;
  border-radius: var(--hud-radius);
  background: none;
  color: var(--gold-bright);
  font: inherit;
  font-size: var(--hud-fs);
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  text-shadow: none;
}

.hud-menu-button::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--hud-icon-scrim);
  pointer-events: none;
}

.hud-menu-button:hover,
.hud-menu-button:focus-visible {
  color: var(--gold-bright);
  outline: 2px solid var(--gold-line-strong);
  outline-offset: 2px;
}

.hud-menu-button:hover .hud-menu-icon,
.hud-menu-button:focus-visible .hud-menu-icon { filter: var(--hud-icon-lift-strong); }

/* 수령 가능 강조 — 테두리가 없으므로 아이콘 자체가 금색으로 더 밝게 뜬다. */
.hud-menu-button.has-claimable .hud-menu-icon { filter: var(--hud-icon-lift-strong); }

.hud-menu-badge {
  position: absolute;
  top: -0.35rem;
  right: -0.35rem;
  min-width: 1.15rem;
  padding: 0 0.25rem;
  border-radius: 999px;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font-size: 0.7rem;
  font-weight: 900;
  line-height: 1.2rem;
  text-align: center;
}

.hud-menu-badge[hidden] { display: none; }

/*
 * 상단바 칩 버튼 — 스테이지 칩과 ☰ 메뉴 사이의 공통 형태.
 * 보스 게이트와 일일 보상이 같은 밀도(--fs-meta·--tap-min)를 쓴다.
 */
.hud-chip-button {
  position: relative;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--hud-gap-tight);
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  padding: calc(var(--hud-unit) * 0.28) calc(var(--hud-unit) * 0.55);
  pointer-events: auto;
  border: 1px solid var(--gold-line);
  border-radius: 999px;
  background: rgb(var(--c-panel) / 0.8);
  color: var(--gold-bright);
  font: inherit;
  font-size: var(--hud-fs-sm);
  font-weight: 800;
  white-space: nowrap;
  cursor: pointer;
}

.hud-chip-button:hover:not(:disabled),
.hud-chip-button:focus-visible {
  border-color: var(--gold);
  outline: 2px solid var(--gold-line-strong);
  outline-offset: 2px;
}

/* 수령 가능·도전 가능은 점 배지 하나로만 알린다(색·크기 강조는 쓰지 않는다). */
.hud-chip-badge {
  position: absolute;
  top: 0.15rem;
  right: 0.15rem;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 999px;
  background: var(--gold-bright);
  box-shadow: 0 0 0.35rem var(--gold);
}

.hud-chip-badge[hidden] { display: none; }

/*
 * 일일 보상 — 아이콘 하나뿐이라 카드 껍데기를 두르지 않는다. 표면 규칙은 하나다:
 * 글자를 든 칩(보스·골드)은 카드를 유지하고, 아이콘만 있는 버튼은 아이콘 자체가 버튼이다.
 */
#daily-reward {
  padding: 0;
  border: 0;
  background: none;
}

#daily-reward::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--hud-icon-scrim);
  pointer-events: none;
}

#daily-reward .button-ui-icon { filter: var(--hud-icon-lift); }

#daily-reward[hidden] {
  display: none;
}

/* 수령 가능 발광도 카드 테두리가 아니라 아이콘 자체가 든다. */
#daily-reward.is-claimable .button-ui-icon {
  filter: var(--hud-icon-lift-strong);
  animation: hud-chip-ready-pulse 1.8s ease-in-out infinite;
}

@keyframes hud-chip-ready-pulse {
  0%, 100% { filter: var(--hud-icon-lift-strong); }
  50% { filter: var(--hud-icon-lift-flare); }
}

html[data-reduced-motion="true"] #daily-reward.is-claimable .button-ui-icon {
  animation: none;
  filter: var(--hud-icon-lift-strong);
}

#daily-reward.claimed {
  color: var(--btn-disabled-ink);
  cursor: default;
}

#daily-reward.claimed .button-ui-icon {
  filter: var(--hud-icon-lift);
  opacity: 0.45;
}

/* 튜토리얼 목표 한 줄 — 표면에 얇게 얹히고 절대 스크롤을 만들지 않는다. */
#tutorial-hint {
  z-index: 3;
  display: inline-flex;
  align-items: center;
  /* 한 줄 계약 — 길이가 넘쳐도 줄바꿈 대신 잘라 낸다(표면 무스크롤). */
  white-space: nowrap;
  overflow: hidden;
  gap: var(--hud-gap);
  max-width: calc(100% - var(--hud-edge-left) - var(--hud-edge-right));
  margin-top: var(--hud-gap);
  padding: calc(var(--hud-unit) * 0.28) calc(var(--hud-unit) * 0.55);
  pointer-events: auto;
  border: 1px solid var(--gold-line);
  border-radius: 999px;
  background: var(--bg-scrim);
  color: var(--ink-soft);
  font-size: var(--hud-fs-sm);
  font-weight: 700;
  line-height: 1.2;
}

#tutorial-hint[hidden] { display: none; }

.tutorial-hint-step {
  flex: none;
  color: var(--gold);
  font-weight: 900;
}

.tutorial-hint-text {
  overflow: hidden;
  text-overflow: ellipsis;
}

.tutorial-hint-claim {
  flex: none;
  /*
   * 실기기 실측에서 22.4px짜리 표면으로 잡혔다(iPhone 17 Pro). 겉 크기를 44px로 키우면
   * 가로 모드(874×292)에서 힌트 줄이 두꺼워져 미니 피드와 겹치므로(실측 67×20),
   * 채팅 ⋯과 같은 방식으로 겉 크기는 두고 히트 영역만 44px로 넓힌다.
   */
  position: relative;
  padding: 0.2rem 0.55rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: 999px;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-size: 0.74rem;
  font-weight: 900;
  cursor: pointer;
}

.tutorial-hint-claim::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  width: 100%;
  height: 100%;
}

.tutorial-hint-claim[hidden] { display: none; }

.tutorial-hint-claim:hover,
.tutorial-hint-claim:focus-visible {
  border-color: var(--gold-bright);
  outline: 2px solid var(--gold-line-strong);
  outline-offset: 2px;
}

.tutorial-hint-claim:disabled {
  border-color: var(--line-disabled);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay-base);
  display: grid;
  place-items: center;
  /* 여백은 뷰포트 비례 + 노치 인셋 — 패널 크기 토큰이 이 값을 그대로 빼고 계산한다. */
  padding:
    calc(var(--overlay-pad) + env(safe-area-inset-top, 0px))
    calc(var(--overlay-pad) + env(safe-area-inset-right, 0px))
    calc(var(--overlay-pad) + env(safe-area-inset-bottom, 0px))
    calc(var(--overlay-pad) + env(safe-area-inset-left, 0px));
  pointer-events: auto;
  background: var(--bg-scrim);
  backdrop-filter: blur(0.35rem);
}

.modal-backdrop[hidden] {
  display: none;
}

/*
 * 오버레이 진입·퇴장 전환 — 이름 목록이 아니라 `.modal-backdrop`과 그 자식 패널
 * 구조에 건다. 새 오버레이는 아무 데도 이름을 올리지 않고 같은 전환을 받는다.
 *
 * 진입은 채우기(both) 없이 한 번만 돈다 — 배경으로 접힌 오버레이(`[inert]`,
 * opacity 0)를 애니메이션 채우기가 도로 켜 버리면 스크림이 두 겹으로 겹친다.
 * 퇴장은 반대로 채워야 한다. 닫히는 껍데기는 배선이 inert로 접어 두므로,
 * 채우지 않으면 `[inert]`의 opacity 0이 먼저 먹어 퇴장이 보이지 않는다.
 */
.modal-backdrop:not([hidden]):not([inert]) {
  animation: overlay-enter 180ms ease-out;
}

.modal-backdrop:not([hidden]):not([inert]) > * {
  animation: overlay-enter-panel 180ms cubic-bezier(0.2, 0.8, 0.3, 1);
}

/* 퇴장 중에는 `hidden`이 이미 켜져 있다 — display만 잠깐 되살려 전환을 끝까지 보여 준다. */
.modal-backdrop[hidden][data-closing] {
  display: grid;
}

.modal-backdrop[data-closing] {
  pointer-events: none;
  animation: overlay-exit 140ms ease-in both;
}

.modal-backdrop[data-closing] > * {
  animation: overlay-exit-panel 140ms ease-in both;
}

@keyframes overlay-enter {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes overlay-enter-panel {
  from {
    opacity: 0;
    transform: translateY(calc(var(--hud-unit) * 0.7)) scale(0.98);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes overlay-exit {
  from { opacity: 1; }
  to { opacity: 0; }
}

@keyframes overlay-exit-panel {
  from {
    opacity: 1;
    transform: none;
  }
  to {
    opacity: 0;
    transform: translateY(calc(var(--hud-unit) * 0.35)) scale(0.99);
  }
}

/* 감소된 모션에서는 전환 없이 그 자리에서 나타나고 사라진다. */
html[data-reduced-motion="true"] .modal-backdrop,
html[data-reduced-motion="true"] .modal-backdrop > * {
  animation: none;
}

/* 오버레이 스택 층 */
/*
 * 층은 백드롭 id가 아니라 **패널 클래스**(= 의미 단위 역할)로 배정한다. 이름 목록을 늘어놓으면
 * 새 오버레이가 목록에 오르지 않아 조용히 바닥 층에 남는다 — 전체 화면 계약(§4.4)과 같은 이유다.
 * 같은 꼴의 패널을 쓰는 새 오버레이는 아무 데도 이름을 올리지 않고 맞는 층에 들어간다.
 */
.modal-backdrop:has(> .hero-popover-panel) {
  z-index: var(--z-overlay-popover);
}

.modal-backdrop:has(> .picker-panel),
.modal-backdrop:has(> .equipment-detail-panel) {
  z-index: var(--z-overlay-picker);
}

.modal-backdrop:has(> .promotion-panel) {
  z-index: var(--z-overlay-confirm);
}

/*
 * 배경 오버레이는 통째로 접는다 — 스크림(0.851)이 두 겹으로 겹치면 0.978까지 어두워지고
 * backdrop-filter 블러도 두 번 돌아간다. inert는 배선(syncHudInert)이 맨 위 한 겹만 남기고
 * 전부 붙이므로, 시각 스택·포커스 스택·스크림이 한 판단에서 함께 나온다.
 */
.modal-backdrop[inert] {
  opacity: 0;
  pointer-events: none;
}
/* 오버레이 스택 층 끝 */

/*
 * 공통 오버레이 패널 — 모든 화면이 같은 슬레이트 프레임과 크림 테두리를 쓴다.
 * 모서리 장식은 .panel-frame과 같은 형태를 각 패널에 직접 그린다.
 */
.achievements-panel,
.prestige-panel,
.promotion-panel,
.settings-panel,
.hiring-panel,
.party-panel,
.equipment-panel,
.arena-panel,
.tower-panel,
.shop-panel,
.quests-panel,
.collection-panel,
.chat-panel,
.map-panel,
.menu-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  /*
   * clip은 hidden과 달리 스크롤 컨테이너를 만들지 않는다 — 패널 자신은 절대 스크롤하지
   * 않고(머리말·푸터가 밀려 나가지 않는다) 스크롤은 본문 하나만 맡는다.
   * hidden이던 시절, 짧은 화면에서 본문이 넘치면 패널이 통째로 75px쯤 밀려 머리말이
   * 화면 밖으로 나가는 회귀가 실측으로 잡혔다(도감·844×390).
   */
  overflow: clip;
  border: 1px solid var(--gold-line-strong);
  border-radius: var(--radius-panel);
  background:
    linear-gradient(180deg, rgb(var(--c-panel) / 0.969), rgb(var(--c-deep) / 0.98));
  box-shadow: var(--shadow-panel);
}

.achievements-panel::before,
.prestige-panel::before,
.promotion-panel::before,
.settings-panel::before,
.hiring-panel::before,
.party-panel::before,
.equipment-panel::before,
.arena-panel::before,
.tower-panel::before,
.shop-panel::before,
.quests-panel::before,
.collection-panel::before,
.chat-panel::before,
.chat-panel::after,
.map-panel::before,
.map-panel::after,
.achievements-panel::after,
.prestige-panel::after,
.promotion-panel::after,
.settings-panel::after,
.hiring-panel::after,
.party-panel::after,
.equipment-panel::after,
.arena-panel::after,
.tower-panel::after,
.shop-panel::after,
.quests-panel::after,
.collection-panel::after,
.menu-panel::before,
.menu-panel::after {
  content: '';
  position: absolute;
  z-index: 1;
  width: 1.15rem;
  height: 1.15rem;
  pointer-events: none;
  border: 2px solid var(--gold-line-strong);
}

.achievements-panel::before,
.prestige-panel::before,
.promotion-panel::before,
.settings-panel::before,
.hiring-panel::before,
.party-panel::before,
.equipment-panel::before,
.arena-panel::before,
.tower-panel::before,
.shop-panel::before,
.quests-panel::before,
.collection-panel::before,
.chat-panel::before,
.map-panel::before,
.menu-panel::before {
  top: 0.35rem;
  left: 0.35rem;
  border-right: 0;
  border-bottom: 0;
  border-top-left-radius: 0.35rem;
}

.achievements-panel::after,
.prestige-panel::after,
.promotion-panel::after,
.settings-panel::after,
.hiring-panel::after,
.party-panel::after,
.equipment-panel::after,
.arena-panel::after,
.tower-panel::after,
.shop-panel::after,
.quests-panel::after,
.collection-panel::after,
.menu-panel::after {
  right: 0.35rem;
  bottom: 0.35rem;
  border-left: 0;
  border-top: 0;
  border-bottom-right-radius: 0.35rem;
}

.achievements-panel,
.prestige-panel,
.promotion-panel,
.settings-panel {
  width: var(--overlay-w-md);
  max-height: var(--overlay-h);
}

.promotion-panel {
  width: var(--overlay-w-sm);
}

.settings-panel {
  width: var(--overlay-w-xs);
}

/* 목록형 오버레이 3층 그리드 — header 고정 / main 세로 1축 스크롤 / footer 고정.
 * 정본: docs/design/mobile-menu-ux-v1.md §3. 데스크톱 카드 폭·높이는 그대로 둔다. */
.equipment-panel,
.collection-panel,
.achievements-panel,
.shop-panel,
.arena-panel,
.tower-panel,
.map-panel,
.quests-panel {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
}

/* 상단 보조 문구가 있는 화면은 그 줄까지 고정 행으로 센다. */
.shop-panel {
  grid-template-rows: auto auto minmax(0, 1fr) auto;
}

/* 하단 고정 푸터 — 상태 문구와 주 액션을 엄지 존에 붙인다. */
.panel-footer {
  display: flex;
  align-items: center;
  gap: var(--gap-panel);
  padding: var(--pad-panel);
  padding-bottom: calc(var(--overlay-pad) + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--gold-line);
  background: linear-gradient(0deg, rgb(var(--c-panel-mid) / 0.502), rgb(var(--c-black) / 0));
}

.panel-footer .hiring-status {
  flex: 1;
  min-width: 0;
  margin: 0;
  padding: 0;
}

.panel-footer button {
  min-height: var(--tap-min);
  flex: 0 0 auto;
}

.panel-footer-action {
  font-weight: 800;
}

.achievements-header,
.prestige-header,
.promotion-header,
.settings-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--pad-panel);
  border-bottom: 1px solid var(--gold-line);
  background: linear-gradient(180deg, rgb(var(--c-panel-mid) / 0.502), rgb(var(--c-black) / 0));
}

.promotion-header p,
.promotion-header h2 {
  margin: 0;
}

.promotion-header p {
  color: var(--gold);
  font-size: var(--fs-micro);
  font-weight: 800;
  letter-spacing: 0.12em;
}

.promotion-body {
  display: grid;
  gap: var(--gap-panel);
  padding: var(--pad-body);
}

.promotion-body p {
  margin: 0;
}

.promotion-body label {
  color: var(--ink-soft);
  font-size: 0.85rem;
  font-weight: 700;
}

#promotion-warning {
  color: var(--gold-bright);
  font-size: 0.84rem;
  line-height: 1.5;
}

#promotion-error {
  min-height: 1.3em;
  color: var(--danger);
  font-size: 0.84rem;
}


.achievements-header p,
.achievements-header h2,
.prestige-header p,
.prestige-header h2,
.settings-header h2 {
  margin: 0;
}

.achievements-header p,
.prestige-header p {
  color: var(--gold);
  font-size: var(--fs-micro);
  font-weight: 800;
  letter-spacing: 0.12em;
}

.achievements-header h2,
.prestige-header h2,
.settings-header h2 {
  color: var(--gold-bright);
  font-size: var(--fs-title);
  letter-spacing: 0.02em;
  text-shadow: 0 2px 4px rgb(var(--c-black) / 0.667);
}

/* 모든 오버레이의 닫기 버튼은 같은 금색 사각 프레임을 쓴다. */
#achievements-close,
#prestige-close,
#settings-close,
#hiring-close,
#party-close,
#equipment-close,
#arena-close,
#shop-close,
#promotion-close,
#hero-popover-close,
#slot-picker-close,
#equip-picker-close,
#growth-close,
#collection-close,
#tower-close,
#chat-close,
#menu-close,
#quests-close,
#map-close,
#equipment-detail-close {
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  border: 1px solid var(--gold-line);
  border-radius: 0.5rem;
  background: var(--btn-navy);
  color: var(--gold-bright);
  font: inherit;
  font-size: var(--fs-title);
  line-height: 1;
  cursor: pointer;
}

#achievements-close:hover,
#achievements-close:focus-visible,
#prestige-close:hover,
#prestige-close:focus-visible,
#settings-close:hover,
#settings-close:focus-visible,
#hiring-close:hover,
#hiring-close:focus-visible,
#party-close:hover,
#party-close:focus-visible,
#equipment-close:hover,
#equipment-close:focus-visible,
#arena-close:hover,
#arena-close:focus-visible,
#shop-close:hover,
#shop-close:focus-visible,
#promotion-close:hover,
#promotion-close:focus-visible,
#hero-popover-close:hover,
#hero-popover-close:focus-visible,
#slot-picker-close:hover,
#slot-picker-close:focus-visible,
#equip-picker-close:hover,
#equip-picker-close:focus-visible,
#equipment-detail-close:hover,
#equipment-detail-close:focus-visible,
#growth-close:hover,
#growth-close:focus-visible,
#collection-close:hover,
#collection-close:focus-visible,
#tower-close:hover,
#tower-close:focus-visible,
#chat-close:hover,
#chat-close:focus-visible,
#menu-close:hover,
#menu-close:focus-visible,
#quests-close:hover,
#quests-close:focus-visible,
#map-close:hover,
#map-close:focus-visible {
  border-color: var(--gold);
  outline: 2px solid var(--gold-line-strong);
  outline-offset: 2px;
}

.settings-body {
  display: grid;
  gap: var(--gap-panel);
  padding: var(--pad-body);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* 뮤트 목록은 로컬 전용 표시 필터다 — 길어지면 목록만 안에서 스크롤한다. */
.settings-mutes {
  display: grid;
  gap: 0.5rem;
  padding: 0.85rem 0 0;
  border-top: 1px solid var(--gold-line);
}

.settings-mute-title {
  margin: 0;
  color: var(--gold-bright);
  font-size: 0.85rem;
  font-weight: 800;
}

.settings-mute-list {
  display: grid;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
  max-height: 11rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  list-style: none;
}

.settings-mute-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.3rem 0.5rem;
  border: var(--border-soft);
  border-radius: var(--radius-slot);
  background: var(--bg-slot);
  font-size: 0.82rem;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.settings-mute-row button {
  flex: 0 0 auto;
  min-height: var(--tap-min);
  padding: 0 0.6rem;
  font-size: 0.78rem;
}

.settings-mute-row button:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 1px;
}

.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 2.75rem;
  font-weight: 800;
}

/*
 * display: flex가 UA의 [hidden] display:none을 이기므로 명시 가드를 둔다 —
 * 알림·Google 연동처럼 기능이 없을 때 숨기는 줄이 빈 버튼으로 렌더됐다.
 */
.settings-row[hidden] {
  display: none;
}

#settings-music,
#settings-sfx,
#settings-push,
#settings-google {
  min-width: 4.5rem;
  min-height: var(--tap-min);
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.55rem;
  background: linear-gradient(180deg, var(--bg-gold-deep), var(--bg-panel-mid));
  color: var(--gold-bright);
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}

#settings-music[aria-pressed="false"],
#settings-sfx[aria-pressed="false"],
#settings-push[aria-pressed="false"] {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
}

#settings-push:disabled { cursor: default; opacity: 0.7; }

/* Google 연동 버튼 — 연동 완료·진행 중에는 잠긴 상태로 남는다. */
#settings-google {
  min-width: 8.5rem;
}

#settings-google:disabled { cursor: default; opacity: 0.7; }

#settings-google:focus-visible,
#title-google:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

/* 알림 안내 한 줄 — 거부 상태를 알릴 뿐 오류처럼 보이지 않게 둔다. */
.settings-note {
  margin: 0;
  color: var(--ink-dim);
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1.4;
}

.settings-note[hidden] { display: none; }

/* 설정 하단 법적 문서 링크 — 새 탭으로 열려 게임 세션을 끊지 않는다. */
.settings-legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  padding: 0.85rem 0 0;
  border-top: 1px solid var(--gold-line);
  color: var(--ink-dim);
  font-size: 0.78rem;
  font-weight: 600;
}

.settings-legal a {
  /* 문장 속 링크가 아니라 단독 이동 표면이라 44px 계약을 지킨다(실기기 실측 16px). */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  color: var(--ink-soft);
  text-decoration: none;
}

.settings-legal a:hover,
.settings-legal a:focus-visible {
  color: var(--gold-bright);
  text-decoration: underline;
}

#settings-music:focus-visible,
#settings-sfx:focus-visible,
#settings-push:focus-visible,
.settings-motion-options label:has(input:focus-visible) {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

.settings-motion {
  margin: 0;
  padding: 0.85rem 0 0;
  border: 0;
  border-top: 1px solid var(--gold-line);
}

.settings-motion legend {
  padding: 0 0.25rem 0 0;
  color: var(--ink);
  font-weight: 800;
}

.settings-motion-options {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.45rem;
  margin-top: 0.7rem;
}

.settings-motion-options label {
  min-height: var(--tap-min);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  border: 1px solid var(--line-mid);
  border-radius: 0.55rem;
  background: var(--bg-slot);
  color: var(--ink-soft);
  cursor: pointer;
}

.settings-motion-options label:has(input:checked) {
  border-color: var(--gold-line-strong);
  background: linear-gradient(180deg, var(--bg-gold-deep), var(--bg-panel-mid));
  color: var(--gold-bright);
}

.achievement-list {
  display: grid;
  gap: 0.6rem;
  padding: 0.85rem;
  min-height: 0;
  overflow-y: auto;
}

.achievement-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 1rem;
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--line-card);
  border-radius: var(--radius-card);
  background: var(--bg-slot);
}

.achievement-item.achieved {
  border-color: var(--gold-line-strong);
  background: linear-gradient(180deg, var(--bg-panel-mid), var(--bg-slot));
}

.achievement-item.claimed {
  opacity: 0.68;
}

/* 업적 요약·구획 — 무엇을 향해 가는지 먼저 읽히게 한다. */
.achievement-summary {
  margin: 0;
  color: var(--gold-bright);
  font-size: var(--fs-body);
  font-weight: 800;
}

.achievement-section {
  display: grid;
  gap: var(--gap-card);
}

.achievement-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--gap-card);
  padding-bottom: 0.15rem;
  border-bottom: 1px solid var(--line-quiet);
}

.achievement-section-head h3 {
  margin: 0;
  font-size: var(--fs-section);
}

.achievement-section-count {
  color: var(--ink-soft);
  font-size: var(--fs-meta);
  font-weight: 800;
}

.achievement-section.complete .achievement-section-count {
  color: var(--ok);
}

.achievement-copy h4,
.achievement-copy p {
  margin: 0;
}

.achievement-copy h4 {
  font-size: var(--fs-section);
}

/* 진행바 — 폭은 배선이 넘긴 비율뿐이고, 옆의 문구가 같은 값을 글로도 말한다. */
.achievement-bar {
  display: block;
  height: 0.35rem;
  margin-top: 0.35rem;
  overflow: hidden;
  border-radius: 0.2rem;
  background: var(--bg-slot-raised);
}

.achievement-bar-fill {
  display: block;
  width: var(--achievement-progress, 0%);
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--info), var(--gold));
}

.achievement-item.achieved .achievement-bar-fill {
  background: var(--btn-gold);
}

.achievement-copy p {
  margin-top: 0.15rem;
  color: var(--ink-soft);
  font-size: 0.86rem;
}

.achievement-progress {
  display: inline-block;
  margin-top: 0.35rem;
  color: var(--info);
  font-size: 0.8rem;
  font-weight: 700;
}

.achievement-reward {
  display: grid;
  justify-items: end;
  gap: 0.35rem;
  color: var(--gold-bright);
  font-size: 0.82rem;
  font-weight: 800;
}

.achievement-reward button {
  min-width: 5.2rem;
  min-height: var(--tap-min);
  padding: 0.4rem 0.65rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.45rem;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}

.achievement-reward button:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

.achievement-reward button:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

/* 좌측 파티 초상 카드 — ref-main-hud의 가장자리 배치와 체력 바 */
/* 파티는 왼쪽 가장자리에 세로로 쌓여 중앙 전투를 가리지 않는다. */
#party-panel {
  position: absolute;
  left: var(--hud-edge-left);
  bottom: var(--hud-edge-bottom);
  display: grid;
  justify-items: start;
  gap: var(--hud-gap);
  width: max-content;
  max-width: calc(100% - var(--hud-edge-left) - var(--hud-edge-right));
  pointer-events: auto;
}

/*
 * 초상 배치 — 좌하단 고정 1행 격자. 출전 상한이 5명(서버 MAX_PARTY v20)이라 5열 한 줄로
 * 전부 들어가고, 가로·세로 어느 쪽도 스크롤하지 않는다(표면 무스크롤 계약).
 * 순서는 왼쪽에서 오른쪽으로 흐르고 데스크톱·모바일이 같은 배치를 쓴다.
 */
#party-cards {
  display: grid;
  grid-template-columns: repeat(5, max-content);
  grid-template-rows: auto;
  gap: var(--hud-gap-tight);
  min-height: 0;
}

/*
 * 초상 스트립 — 초상화와 세로 체력 바만 남긴 최소 표시다. 이름·레벨 전체 표기는
 * 팝오버로 넘기고, 여기서는 낭독용 aria-label만 이름을 들고 있다.
 * 테두리는 대표 스킬 쿨다운 게이지다(표시 전용, 전투 값과 무관하다).
 */
.hero-portrait {
  position: relative;
  display: grid;
  grid-template-columns: auto auto;
  align-items: center;
  justify-content: center;
  gap: var(--hud-gap-tight);
  /* 초상을 줄여도 조작 표면은 최소 터치 크기(44×44)를 지킨다. */
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  padding: calc(var(--hud-unit) * 0.14);
  border: 1px solid var(--grade-color, var(--grade-common));
  border-radius: var(--hud-radius);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.933), rgb(var(--c-deep) / 0.949));
  box-shadow: var(--shadow-card);
  color: var(--ink-soft);
  font: inherit;
  line-height: 1;
  cursor: pointer;
}

/* 테두리 게이지 — conic-gradient 링을 마스크로 잘라 얇은 띠만 남긴다. */
.hero-portrait-gauge {
  position: absolute;
  inset: -1px;
  padding: 2px;
  border-radius: inherit;
  pointer-events: none;
  background: conic-gradient(
    from 0deg,
    var(--gold-bright) var(--skill-angle, 0deg),
    rgb(var(--c-white) / 0.078) var(--skill-angle, 0deg)
  );
  -webkit-mask: linear-gradient(rgb(var(--c-black)) 0 0) content-box, linear-gradient(rgb(var(--c-black)) 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(rgb(var(--c-black)) 0 0) content-box, linear-gradient(rgb(var(--c-black)) 0 0);
  mask-composite: exclude;
}

.hero-portrait.is-skill-ready .hero-portrait-gauge {
  background: conic-gradient(from 0deg, var(--gold-bright), var(--gold) 50%, var(--gold-bright));
}

/* 준비 완료는 금색 발광 한 번으로만 알린다. */
@keyframes hero-skill-ready-pulse {
  0% { box-shadow: 0 0 0 0 rgb(var(--c-gold-bright) / 0); }
  35% { box-shadow: 0 0 0.55rem 0.1rem rgb(var(--c-gold-bright) / 0.8); }
  100% { box-shadow: 0 0 0 0 rgb(var(--c-gold-bright) / 0); }
}

.hero-portrait.is-skill-pulse {
  animation: hero-skill-ready-pulse 520ms ease-out 1;
}

html[data-reduced-motion="true"] .hero-portrait.is-skill-pulse {
  animation: none;
}

/* 레벨 배지는 초상 안쪽 모서리에 얹는다 — 스트립 밖으로 삐져나가지 않게 한다. */
/*
 * 등급 배지 — 테두리 등급색과 같은 정보를 글자로도 낸다(등급색 단독 신호 금지 계약).
 * 절대 배치라 초상 격자 폭을 늘리지 않는다 = 표면 무스크롤 계약을 건드리지 않는다.
 */
.hero-portrait-grade {
  position: absolute;
  right: calc(var(--hud-unit) * 0.06);
  top: calc(var(--hud-unit) * 0.06);
  padding: 0 calc(var(--hud-unit) * 0.12);
  border: 1px solid var(--grade-color, var(--grade-common));
  border-radius: 999px;
  background: rgb(var(--c-scrim) / 0.933);
  color: var(--ink);
  font-size: calc(var(--hud-fs-xs) * 0.74);
  font-weight: 800;
  line-height: 1.5;
  white-space: nowrap;
}

.hero-portrait-level {
  position: absolute;
  left: calc(var(--hud-unit) * 0.1);
  bottom: calc(var(--hud-unit) * 0.1);
  min-width: calc(var(--hud-fs-xs) * 1.5);
  padding: 0 calc(var(--hud-unit) * 0.14);
  border: 1px solid var(--gold-line);
  border-radius: 999px;
  background: rgb(var(--c-scrim) / 0.933);
  color: var(--ink-dim);
  font-size: calc(var(--hud-fs-xs) * 0.86);
  font-weight: 800;
  line-height: calc(var(--hud-fs-xs) * 1.5);
  text-align: center;
}

.hero-portrait .hero-icon {
  width: var(--hud-portrait);
  height: var(--hud-portrait);
  border-radius: calc(var(--hud-radius) * 0.8);
}

.hero-portrait:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

.hero-portrait:disabled {
  cursor: default;
  opacity: 0.6;
}

.hero-portrait.is-down {
  opacity: 0.55;
  filter: saturate(0.4);
}

/*
 * 영웅 상세 — 가운데 영웅 정보, 주위 5부위 장비 고리, 확장 스탯 12종, 강화·승급.
 * 표면 무스크롤 계약을 지키려 패널 높이를 묶고 본문만 안에서 스크롤한다.
 */
.hero-popover-panel {
  display: flex;
  flex-direction: column;
  /* 패널 자신은 스크롤하지 않는다(clip) — 스크롤은 본문 한 겹만 맡는다. */
  overflow: clip;
  width: var(--overlay-w-md);
  max-height: var(--overlay-h);
  border: 1px solid var(--gold-line-strong);
  border-radius: var(--radius-panel);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.973), rgb(var(--c-deep) / 0.984));
  box-shadow: var(--shadow-panel);
}

.hero-popover-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: 0.5rem;
  padding: var(--pad-panel);
  border-bottom: 1px solid var(--gold-line);
  background: linear-gradient(180deg, rgb(var(--c-panel-mid) / 0.502), rgb(var(--c-black) / 0));
}

.hero-detail-body {
  display: grid;
  gap: var(--gap-panel);
  padding: var(--pad-body);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/*
 * 장비 고리 — 3×3 격자에서 가운데가 영웅이고 머리(위)·무기(좌)·상의(우)·
 * 장갑(좌하)·신발(우하)이 둘러싼다. 좁은 화면에서도 같은 배치를 쓴다.
 */
.hero-detail-slots {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-areas:
    ".      head   ."
    "weapon core   chest"
    "gloves .      boots";
  gap: var(--gap-card);
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
  align-items: center;
  justify-items: center;
}

.hero-detail-slots > li[data-slot="weapon"] { grid-area: weapon; }
.hero-detail-slots > li[data-slot="head"] { grid-area: head; }
.hero-detail-slots > li[data-slot="chest"] { grid-area: chest; }
.hero-detail-slots > li[data-slot="gloves"] { grid-area: gloves; }
.hero-detail-slots > li[data-slot="boots"] { grid-area: boots; }

.hero-detail-core {
  grid-area: core;
  display: grid;
  justify-items: center;
  gap: 0.2rem;
  text-align: center;
}

.hero-detail-portrait {
  width: 3.6rem;
  height: 3.6rem;
  object-fit: cover;
  border: 2px solid var(--gold-line-strong);
  border-radius: 0.6rem;
  background: var(--bg-slot);
}

/* 부위 슬롯 버튼 — 아이콘 위, 티어·등급 한 줄. 빈 슬롯은 실루엣만 남는다. */
.hero-detail-slot {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 0.15rem;
  width: 100%;
  /* 장비 고리는 3열 격자라 좁은 화면에서 칸 폭이 44px 아래로 눌린다(390px에서 34px 실측). */
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  padding: 0.3rem 0.2rem;
  border: 2px solid var(--card-grade, var(--line-card));
  border-radius: var(--radius-slot);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.933), rgb(var(--c-deep) / 0.949));
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-micro);
  font-weight: 700;
  text-align: center;
  cursor: pointer;
}

.hero-detail-slot.grade-normal { --card-grade: var(--grade-normal); }
.hero-detail-slot.grade-rare { --card-grade: var(--grade-rare); }
.hero-detail-slot.grade-epic { --card-grade: var(--grade-epic); }
.hero-detail-slot.grade-unique { --card-grade: var(--grade-unique); }
.hero-detail-slot.grade-legend { --card-grade: var(--grade-legend); }

/* 빈 슬롯 실루엣 — 점선 테두리와 흐린 아이콘으로 "여기 넣을 수 있다"만 말한다. */
.hero-detail-slot.is-empty {
  border-style: dashed;
  border-color: var(--line-disabled);
  background: rgb(var(--c-scrim) / 0.4);
  color: var(--ink-dim);
}

.hero-detail-slot.is-empty .hero-detail-slot-icon { opacity: 0.35; }

.hero-detail-slot:hover,
.hero-detail-slot:focus-visible {
  border-color: var(--gold);
  outline: 2px solid var(--gold-line-strong);
  outline-offset: 2px;
}

.hero-detail-slot-icon {
  width: 1.9rem;
  height: 1.9rem;
  object-fit: contain;
}

.hero-detail-slot-name {
  max-width: 100%;
  overflow: hidden;
  color: var(--ink-soft);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 확장 스탯 12종 — 2열 이름·값 표. 상한에 닿은 줄만 금색으로 알린다. */
.hero-detail-sheet {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.15rem var(--gap-card);
  margin: 0;
  padding: 0;
  list-style: none;
}

.hero-detail-sheet > li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.35rem;
  padding: 0.15rem 0.3rem;
  border-bottom: 1px solid rgb(var(--c-white) / 0.059);
  color: var(--ink-dim);
  font-size: var(--fs-meta);
}

.hero-detail-sheet .stat-value {
  color: var(--ink-soft);
  font-weight: 800;
}

.hero-detail-sheet > li.is-capped .stat-value {
  color: var(--gold-bright);
}

#hero-detail-reduction {
  margin: 0;
  color: var(--info);
  font-size: var(--fs-meta);
}

.hero-popover-identity h2 {
  margin: 0;
  font-size: var(--fs-section);
}

.hero-popover-identity p {
  margin: 0.15rem 0 0;
  color: var(--ink-dim);
  font-size: 0.76rem;
}

.hero-popover-stats {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.8rem;
}

.hero-popover-actions {
  display: grid;
  gap: var(--gap-card);
}

.hero-popover-actions button {
  width: 100%;
  min-height: var(--tap-min);
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.45rem;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-weight: 800;
  font-size: 0.82rem;
  /* 승급 조건처럼 긴 문구가 "필\n요"로 끊기지 않게 단어 단위로만 줄바꿈한다. */
  word-break: keep-all;
  cursor: pointer;
}

.hero-popover-actions button.secondary {
  border-color: var(--line-bright);
  background: var(--btn-navy);
  color: var(--ink-soft);
}

.hero-popover-actions button:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.hero-popover-skill-box h3 {
  margin: 0 0 0.25rem;
  color: var(--ink-dim);
  font-size: 0.74rem;
}

#hero-popover-skills {
  display: grid;
  gap: 0.2rem;
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--ink-soft);
  font-size: var(--fs-meta);
}

.hero-popover-actions {
  grid-auto-flow: column;
}

.hero-icon {
  width: 2rem;
  height: 2rem;
  flex: 0 0 auto;
  object-fit: cover;
  border: 1px solid var(--gold-line);
  border-radius: 0.5rem;
  background: var(--bg-slot);
  box-shadow: 0 0.2rem 0.6rem rgb(var(--c-black) / 0.533);
}

/* 체력 바는 초상 옆에 세로로 서서 자리를 거의 쓰지 않는다. */
.hero-hp {
  display: flex;
  align-items: flex-end;
  width: calc(var(--hud-unit) * 0.26);
  height: var(--hud-portrait);
  overflow: hidden;
  border: 1px solid var(--bg-void);
  border-radius: 999px;
  background: var(--bg-void);
}

.hero-hp-fill {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(0deg, var(--ok-deep), var(--ok));
  transition: height 120ms linear;
}


#prestige-entry {
  display: grid;
  gap: 0.4rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, rgb(var(--c-panel-mid) / 0.933), rgb(var(--c-deep) / 0.949));
  box-shadow: var(--shadow-card);
}

#prestige-entry strong {
  color: var(--gold-bright);
}

#prestige-lock-reason {
  margin: 0.15rem 0 0;
  color: var(--ink-dim);
  font-size: 0.78rem;
}

/* 환생은 메뉴 항목 중 유일한 금색 강조다 — 사이클을 끝내는 행동이라서다. */
#prestige-open {
  min-height: var(--tap-min);
  border-color: var(--gold-line-strong);
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font-weight: 900;
}

#prestige-open:hover,
#prestige-open:focus-visible {
  color: var(--ink-on-gold);
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

#prestige-open:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.prestige-body {
  /* 절대 위치 자손을 본문 스크롤 영역에 가둔다 — 위 .collection-body와 같은 이유. */
  position: relative;
  padding: var(--pad-body);
  overflow-y: auto;
}

/* ref-prestige: PP 획득량이 중앙 최우선 정보, 초기화/유지는 색으로 갈린다. */
.prestige-gain {
  margin: 0;
  padding: 0.8rem 1rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, rgb(var(--c-panel-mid) / 0.902), rgb(var(--c-deep) / 0.941));
  color: var(--gold-bright);
  font-size: clamp(1.3rem, 4vw, 1.9rem);
  font-weight: 900;
  text-align: center;
  /* 큰 헤드라인이 "얻습니 다."처럼 어중간하게 끊기지 않게 단어 단위로 줄바꿈한다. */
  word-break: keep-all;
  text-shadow: 0 2px 6px rgb(var(--c-black) / 0.667);
}

.prestige-multipliers {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.65rem;
  margin: 0.85rem 0;
}

.prestige-multipliers div {
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-card);
  background: var(--bg-slot);
}

.prestige-multipliers dt {
  color: var(--ink-dim);
  font-size: 0.78rem;
}

.prestige-multipliers dd {
  margin: 0.25rem 0 0;
  color: var(--gold-bright);
  font-weight: 900;
  /* 공격·첼력 비교는 스탯별 줄(\n)로 나뉜다 — 값 중간 줄꺾임 방지. */
  white-space: pre-line;
}

.prestige-contract {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.65rem;
}

.prestige-contract section {
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--line-card);
  border-radius: var(--radius-card);
  background: var(--bg-slot);
}

/* 초기화는 위험색, 유지는 청색 — 두 열을 색으로 분리한다. */
.prestige-contract section:first-child { border-color: var(--danger-line); }
.prestige-contract section:first-child h3 { color: var(--danger); }
.prestige-contract section:last-child { border-color: var(--line-info); }
.prestige-contract section:last-child h3 { color: var(--info); }

.prestige-contract h3 {
  margin: 0;
  font-size: var(--fs-section);
}

.prestige-contract ul {
  margin: 0.45rem 0 0;
  padding-left: 1.15rem;
  color: var(--ink-soft);
  font-size: 0.86rem;
  line-height: 1.55;
}

.prestige-error {
  min-height: 1.4em;
  margin: 0.65rem 0 0;
  color: var(--danger);
  font-size: 0.86rem;
}

/* 취소와 확정은 충분히 벌리고, 확정만 금색으로 강조한다. */
.prestige-actions {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
  padding: var(--pad-body);
  border-top: 1px solid var(--gold-line);
}

.promotion-actions {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
  padding: var(--pad-body);
  border-top: 1px solid var(--gold-line);
}

.promotion-actions button {
  flex: 1 1 auto;
  min-width: 7rem;
  min-height: var(--tap-min);
  padding: 0.55rem 0.8rem;
  border: 1px solid var(--line-bright);
  border-radius: 0.55rem;
  background: var(--btn-navy);
  color: var(--ink-soft);
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}

#promotion-confirm,
#google-conflict-confirm {
  border-color: var(--gold-line-strong);
  background: var(--btn-gold);
  color: var(--ink-on-gold);
}

.promotion-actions button:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

.promotion-actions button:disabled,
#promotion-close:disabled {
  opacity: 0.55;
  cursor: wait;
}

.prestige-actions button {
  flex: 1 1 auto;
  min-width: 7rem;
  min-height: var(--tap-min);
  padding: 0.55rem 0.8rem;
  border: 1px solid var(--line-bright);
  border-radius: 0.55rem;
  background: var(--btn-navy);
  color: var(--ink-soft);
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}

#prestige-confirm {
  border-color: var(--gold-line-strong);
  background: var(--btn-gold);
  color: var(--ink-on-gold);
}

.prestige-actions button:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

.prestige-actions button:disabled,
#prestige-close:disabled {
  opacity: 0.55;
  cursor: wait;
}

#prestige-fade {
  position: fixed;
  inset: 0;
  z-index: 25;
  pointer-events: none;
  background:
    radial-gradient(circle at 35% 60%, rgb(var(--c-legendary) / 0.333), transparent 25%),
    var(--bg-blackout);
  opacity: 0;
  transition: opacity 420ms ease-in;
}

#prestige-fade.is-active {
  opacity: 0.92;
}

#prestige-fade.is-clearing {
  opacity: 0;
  transition-duration: 650ms;
}

#prestige-fade[hidden] {
  display: none;
}

/* 토스트는 하단 스킬 열 위로 띄워 중앙 전투와 스킬 상태를 가리지 않는다. */
#toast {
  position: absolute;
  bottom: 6.2rem;
  left: 50%;
  transform: translateX(-50%);
  padding: 0.5rem 1rem;
  border: 1px solid var(--gold-line);
  border-radius: 0.55rem;
  background: rgb(var(--c-scrim) / 0.902);
  color: var(--ink);
  font-weight: 700;
}

#result-banner {
  position: absolute;
  z-index: 26;
  top: 50%;
  left: 50%;
  min-width: min(75vw, 24rem);
  padding: 1rem 2rem;
  transform: translate(-50%, -50%);
  border: 2px solid currentColor;
  border-radius: 1rem;
  background: rgb(var(--c-deep) / 0.902);
  box-shadow: 0 0 2rem currentColor;
  font-size: clamp(2rem, 7vw, 4.5rem);
  font-weight: 900;
  letter-spacing: 0.04em;
  text-align: center;
  text-shadow: 0 3px 8px rgb(var(--c-black));
  animation: result-pop 1s ease-out both;
}

#result-banner.victory {
  color: var(--gold-bright);
}

#result-banner.defeat {
  color: var(--danger);
}

#result-banner.prestige {
  color: var(--gold-bright);
  font-size: clamp(1.1rem, 3vw, 2rem);
  line-height: 1.35;
  animation-duration: 4s;
}

#result-banner[hidden] {
  display: none;
}

@keyframes result-pop {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.72);
  }
  16%, 72% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
  100% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(1.04);
  }
}

#boot {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  background: var(--bg-deep);
  font-size: 1.1rem;
  color: var(--ink-dim);
}

#title {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  /* 하단 여백은 절대 배치된 법적 문서 링크 자리다 — 중앙 정렬 내용이 그 위를 덮지 않게 둔다. */
  padding: 1rem 1rem 3.25rem;
  box-sizing: border-box;
  background:
    radial-gradient(circle at 50% 48%, rgb(var(--c-deep) / 0.2), rgb(var(--c-deep) / 0.667) 72%, rgb(var(--c-deep) / 0.902));
}

#title-logo {
  width: min(32rem, 76vw, 65vh);
  /* 버튼(전투 시작·설정·Google)과 하단 링크까지 스크롤 없이 들어가도록 로고를 먼저 줄인다. */
  max-height: 42vh;
  object-fit: contain;
  height: auto;
  display: block;
  filter: drop-shadow(0 0.8rem 1.8rem rgb(var(--c-black) / 0.733));
}

#offline-banner {
  width: max-content;
  max-width: min(32rem, calc(100vw - 2rem));
  box-sizing: border-box;
  padding: 0.75rem 1.2rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, rgb(var(--c-panel-mid) / 0.933), rgb(var(--c-deep) / 0.949));
  box-shadow: 0 0.65rem 1.8rem rgb(var(--c-black) / 0.6);
  color: var(--gold-bright);
  font-weight: 700;
  text-align: center;
}

#title-cta,
#title-settings-open,
#boot-retry {
  min-height: var(--tap-min);
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.65rem;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-weight: 900;
  cursor: pointer;
}

#title-cta {
  width: min(20rem, 84vw);
  padding: 0.75rem 1.2rem;
  box-shadow: 0 0.65rem 1.8rem rgb(var(--c-black) / 0.6), 0 0 1.2rem var(--gold-glow);
  font-size: 1.05rem;
}

#title-google {
  min-height: var(--tap-min);
  padding: 0.5rem 1.1rem;
  border: 1px solid var(--gold-line);
  border-radius: 0.65rem;
  background: var(--btn-navy);
  color: var(--gold-bright);
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}

#title-google:disabled {
  cursor: default;
  opacity: 0.7;
}

#title-settings-open {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-width: 7rem;
  padding: 0.55rem 1rem;
  border-color: var(--gold-line);
  background: var(--btn-navy);
  color: var(--ink-soft);
  font-weight: 800;
}

#boot-retry {
  padding: 0.6rem 1.2rem;
}

/* 법적 문서 링크 — 타이틀 중앙 정렬을 흔들지 않도록 하단에 고정한다. */
.title-legal {
  position: absolute;
  bottom: max(0.75rem, env(safe-area-inset-bottom, 0));
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 0.9rem;
  font-size: 0.72rem;
}

.title-legal a {
  color: var(--ink-dim);
  text-decoration: none;
}

.title-legal a:hover,
.title-legal a:focus-visible {
  color: var(--gold-bright);
  text-decoration: underline;
}

#title-cta:hover,
#title-cta:focus-visible,
#title-settings-open:hover,
#title-settings-open:focus-visible,
#boot-retry:hover,
#boot-retry:focus-visible {
  outline: 3px solid var(--gold-bright);
  outline-offset: 3px;
}

#title-cta:disabled,
#boot-retry:disabled {
  opacity: 0.65;
  cursor: wait;
}

#title[hidden],
#title-google[hidden],
#boot[hidden],
#offline-banner[hidden],
#boot-retry[hidden] {
  display: none;
}

@media (max-width: 760px) {
  /*
   * 표면 크기·간격은 전부 유동 토큰이 잡는다 — 여기 남는 것은 좁은 화면에서
   * 자리를 아예 비우는 판단(브랜드 접기)과 오버레이 열 수 재배치뿐이다.
   */
  #topbar { padding-bottom: calc(var(--hud-unit) * 0.8); }

  .hud-brand { display: none; }

  /* 390px에서도 메뉴 항목은 네 칸 그리드를 유지할 만큼 좁혀 준다. */
  .menu-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.3rem;
  }

  .menu-item {
    min-height: var(--tap-min);
    padding: 0.4rem 0.15rem;
    font-size: var(--fs-micro);
  }

  .menu-item-icon { width: 1.5rem; height: 1.5rem; font-size: 1.05rem; }

  .menu-body { padding: var(--pad-body); }

  /* 좁은 화면에서는 머리말 부제를 접고 환생 배수 줄만 남긴다. */
  .menu-panel .hiring-header > div:first-child p { display: none; }
  .menu-panel #prestige-status { font-size: 0.72rem; }

  #title-logo {
    width: min(20rem, 72vw);
  }

  #offline-banner {
    max-width: calc(100vw - 2rem);
  }

  .achievement-item {
    grid-template-columns: 1fr;
    gap: 0.55rem;
  }

  .achievement-reward {
    grid-template-columns: 1fr auto;
    align-items: center;
    justify-items: start;
  }

  /*
   * 5열 한 줄이 390px 뷰포트에 온전히 들어가도록 초상 사이만 더 붙인다.
   * 초상·체력 바 크기는 유동 토큰(--hud-portrait)이 이미 뷰포트에 맞춰 줄여 놓는다.
   */
  #party-cards { gap: calc(var(--hud-unit) * 0.16); }

  .prestige-multipliers,
  .prestige-contract {
    grid-template-columns: 1fr;
  }

  .prestige-actions,
  .promotion-actions {
    gap: 0.6rem;
  }
}

html[data-reduced-motion="true"] #result-banner {
  animation-duration: 180ms;
}

html[data-reduced-motion="true"] #result-banner.prestige {
  animation-duration: 400ms;
}

html[data-reduced-motion="true"] #prestige-fade,
html[data-reduced-motion="true"] #prestige-fade.is-clearing {
  transition-duration: 120ms;
}

/* 고용소(아레나 캠프) 오버레이 — 후보·갱신만 남아 한 폭 좁게 선다. */
.hiring-panel {
  width: var(--overlay-w-lg);
  max-height: var(--overlay-h);
}

/* 편성 오버레이 — 영웅 슬롯 격자와 보유 영웅이 사는 자리다. */
.party-panel {
  width: var(--overlay-w-xl);
  max-height: var(--overlay-h);
}

.party-body {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gap-panel);
  padding: var(--pad-body);
  overflow-y: auto;
}

/* 모든 오버레이가 공유하는 헤더 — 금색 제목과 우측 지표 열 */
/*
 * 오버레이 공통 머리말 — 제목 열·지표 열·닫기 버튼 한 줄.
 * 좁은 패널에서 지표 문자열(골드·개수)이 길어져도 헤더가 패널 폭을 넘지 않도록
 * 두 열 모두 줄어들 수 있게 두고(min-width: 0), 넘치는 글자는 말줄임으로 자른다.
 */
.hiring-header {
  display: flex;
  align-items: center;
  gap: clamp(0.4rem, 2vmin, 1rem);
  min-width: 0;
  padding: var(--pad-panel);
  border-bottom: 1px solid var(--gold-line);
  background: linear-gradient(180deg, rgb(var(--c-panel-mid) / 0.502), rgb(var(--c-black) / 0));
}

.hiring-header p,
.hiring-header h2 {
  margin: 0;
}

/*
 * 머리말 부제와 제목을 한 줄에 붙여 헤더에서 한 줄을 걷어낸다.
 * DOM 순서(부제 → 제목)는 그대로 두고 order로 제목을 앞세워 낭독 순서를 지킨다.
 */
.hiring-header > div:first-child,
.achievements-header > div:first-child,
.prestige-header > div:first-child,
.promotion-header > div:first-child {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.4rem;
  min-width: 0;
}

/* 제목 열은 남는 자리를 먹고, 지표·제목 글자는 넘치면 말줄임으로 잘린다. */
.hiring-header > div:first-child {
  flex: 1 1 auto;
}

.hiring-header > div:first-child > h2,
.hiring-header-meta > * {
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.hiring-header > div:first-child > p,
.achievements-header > div:first-child > p,
.prestige-header > div:first-child > p,
.promotion-header > div:first-child > p {
  order: 2;
}

.hiring-header p {
  color: var(--gold);
  font-size: var(--fs-micro);
  font-weight: 800;
  letter-spacing: 0.12em;
}

.hiring-header h2 {
  color: var(--gold-bright);
  font-size: var(--fs-title);
  letter-spacing: 0.02em;
  text-shadow: 0 2px 4px rgb(var(--c-black) / 0.667);
}

.hiring-header-meta {
  margin-left: auto;
  display: grid;
  justify-items: end;
  gap: 0.1rem;
  flex: 0 1 auto;
  min-width: 0;
  font-size: var(--fs-meta);
}

#hiring-gold { color: var(--gold-bright); font-weight: 800; }
#hiring-pity { color: var(--ink-dim); }

/* 천장 진행은 무료 갱신 타이머와 분리된 자체 게이지로 읽힌다. */
.pity-gauge {
  display: block;
  width: 8rem;
  height: 0.4rem;
  overflow: hidden;
  border: 1px solid var(--gold-line);
  border-radius: 999px;
  background: var(--bg-void);
}

.pity-gauge > span {
  display: block;
  width: 0%;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--info-deep), var(--info));
}

/* ref-hiring-camp: 후보 6칸을 한 폭으로 고정하고 보유 영웅을 그 아래에 둔다. */
.hiring-body {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gap-panel);
  padding: var(--pad-body);
  overflow: auto;
}

/* 섹션 제목 — 레퍼런스의 좌우 마름모 구분선 */
.hiring-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-bottom: 0.6rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--gold-line);
}

.hiring-section-head h3 {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  /* 제목이 칩에 밀려 "인벤토/리"처럼 중간에서 끊기지 않게 축소를 거부한다 —
   * 대신 우측 칩 무리가 다음 줄로 접힌다(.equipment-filters는 flex-wrap). */
  flex-shrink: 0;
  word-break: keep-all;
  margin: 0;
  color: var(--gold-bright);
  font-size: var(--fs-section);
}

.hiring-section-head h3::before {
  content: '◆';
  color: var(--gold);
  font-size: 0.6rem;
}

.hiring-section-head p {
  margin: 0;
  color: var(--ink-dim);
  font-size: 0.85rem;
}

.hiring-refresh {
  display: flex;
  gap: 0.4rem;
}

.hiring-refresh button {
  min-height: var(--tap-min);
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--gold-line);
  border-radius: 0.5rem;
  background: var(--btn-navy);
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 700;
  cursor: pointer;
}

.hiring-refresh button:hover:not(:disabled),
.hiring-refresh button:focus-visible {
  border-color: var(--gold);
  color: var(--gold-bright);
}

.hiring-refresh button:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.hiring-candidates,
.hiring-roster-list {
  list-style: none;
  display: grid;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
}

/* 후보 그리드는 3×2로 고정한다 — 서버 후보 수는 6칸이다. */
.hiring-candidates {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.hiring-roster-list {
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}

/*
 * 등급은 카드 테두리 전체로 표현한다(ref-hiring-camp).
 * 2열 배치로 스탯·롤을 나란히 놓아 카드 줄 수를 한 줄 줄인다 —
 * 제목·스킬·행동만 두 칸을 걸치고 나머지 수치는 자동 배치로 좌우에 채운다.
 */
.hiring-card {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gap-card);
  padding: 0.5rem 0.6rem;
  border: 2px solid var(--card-grade, var(--grade-common));
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.941), rgb(var(--c-deep) / 0.961));
  box-shadow: inset 0 0 1.2rem rgb(var(--c-black) / 0.4);
}

.hiring-card.grade-uncommon { --card-grade: var(--grade-uncommon); }
.hiring-card.grade-rare { --card-grade: var(--grade-rare); }
.hiring-card.grade-epic { --card-grade: var(--grade-epic); }
.hiring-card.grade-legendary {
  --card-grade: var(--grade-legendary);
  box-shadow: inset 0 0 1.2rem rgb(var(--c-black) / 0.4), 0 0 1rem rgb(var(--c-legendary) / 0.2);
}

/*
 * 고용 결과 리빌 — 뒤집힌 카드가 열리며 등급색 테두리와 등급명을 함께 연다.
 * 색은 보조 신호이고 등급명 텍스트가 언제나 함께 실린다(등급색 단독 신호 금지).
 */
.hire-reveal {
  display: grid;
  justify-items: center;
  gap: var(--gap-row);
  margin-top: var(--gap-panel);
  padding: 0.55rem 0.7rem;
  border: 2px solid var(--card-grade, var(--grade-common));
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.941), rgb(var(--c-deep) / 0.961));
  text-align: center;
}

.hire-reveal[hidden] { display: none; }

.hire-reveal.grade-uncommon { --card-grade: var(--grade-uncommon); }
.hire-reveal.grade-rare { --card-grade: var(--grade-rare); }
.hire-reveal.grade-epic { --card-grade: var(--grade-epic); }
.hire-reveal.grade-legendary { --card-grade: var(--grade-legendary); }

.hire-reveal.is-celebrated {
  box-shadow: 0 0 1.2rem rgb(var(--c-legendary) / 0.28);
}

/* 카드가 뒤집혀 열린다 — 길이는 배선이 --reveal-flip으로 넘긴다(0이면 즉시 표시). */
.hire-reveal.is-open {
  animation: hire-reveal-flip var(--reveal-flip, 520ms) cubic-bezier(0.2, 0.8, 0.3, 1) both;
}

@keyframes hire-reveal-flip {
  0% { opacity: 0; transform: perspective(40rem) rotateY(90deg) scale(0.94); }
  60% { opacity: 1; transform: perspective(40rem) rotateY(-8deg) scale(1.02); }
  100% { opacity: 1; transform: none; }
}

.hire-reveal-grade {
  padding: 0.05rem 0.4rem;
  border: 1px solid var(--card-grade, var(--grade-common));
  border-radius: var(--radius-slot);
  color: var(--card-grade, var(--grade-common));
  font-size: var(--fs-micro);
  font-weight: 800;
  letter-spacing: 0.06em;
}

.hire-reveal-name {
  color: var(--ink);
  font-size: var(--fs-section);
}

.hire-reveal-meta {
  color: var(--ink-soft);
  font-size: var(--fs-meta);
}

html[data-reduced-motion="true"] .hire-reveal.is-open {
  animation: none;
}

.hiring-card.in-party {
  background: linear-gradient(180deg, rgb(var(--c-panel-mid) / 0.941), rgb(var(--c-slot) / 0.961));
}

.hiring-card-title {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-wrap: wrap;
}

.hiring-job-icon {
  width: 2.3rem;
  height: 2.3rem;
  flex: 0 0 auto;
  object-fit: cover;
  border: 1px solid var(--card-grade, var(--gold-line));
  border-radius: 0.5rem;
  background: var(--bg-slot);
}

.hiring-card-title .name { font-weight: 800; font-size: var(--fs-body); }
.hiring-card-title .job { color: var(--ink-soft); font-size: var(--fs-meta); }

.hiring-grade {
  margin-left: auto;
  font-size: var(--fs-micro);
  font-weight: 800;
  letter-spacing: 0.06em;
}

.hiring-card .roll,
.hiring-card .skills,
.hiring-card .stats {
  margin: 0;
  color: var(--ink-dim);
  font-size: var(--fs-meta);
  /* 스탯·롤 문자열이 "공\n격"처럼 단어 중간에서 끊기지 않게 한다. */
  word-break: keep-all;
}

.hiring-card .stats { color: var(--ink-soft); }

/*
 * 후보 카드는 스탯(왼쪽)·롤(오른쪽)이 항상 같은 줄에 오므로 롤을 우측 정렬한다.
 * 보유 목록 카드는 Lv./출전 줄이 하나 더 붙어 자동 배치가 밀리므로 정렬을 건드리지 않는다.
 */
.hiring-candidates .hiring-card .roll { text-align: right; }

/* 스킬 목록과 행동 열은 카드 폭 전체를 쓴다. */
.hiring-card .skills {
  grid-column: 1 / -1;
}

.hiring-card-actions {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.1rem;
}

/* 고용은 크림 채움, 나머지 행동은 슬레이트 — 화면당 강조를 하나로 묶는다. */
.hiring-card-actions button {
  flex: 1 1 auto;
  /* 폭까지 44px 터치 표면 — 모자라면 줄바꿈으로 넘긴다(320px 폭에서 43px로 눌렸다). */
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  padding: 0.35rem 0.55rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.45rem;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-weight: 800;
  font-size: 0.82rem;
  cursor: pointer;
}

.hiring-card-actions button.secondary {
  border-color: var(--line-bright);
  background: var(--btn-navy);
  color: var(--ink-soft);
}

.hiring-card-actions button.danger {
  border-color: var(--danger-line);
  background: linear-gradient(180deg, var(--danger-bg), var(--danger-bg-deep));
  color: var(--danger-ink);
}

.hiring-card-actions button:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.hiring-card-actions button:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

.hiring-status {
  margin: 0;
  padding: 0 1.15rem 1rem;
  min-height: 1.2rem;
  color: var(--gold-bright);
  font-size: 0.85rem;
}

.hiring-empty {
  color: var(--ink-dim);
  font-size: 0.85rem;
}

/* 장비 오버레이 — 인벤토리 100칸과 3부위 장착 */
.equipment-panel {
  width: var(--overlay-w-xl);
  max-height: var(--overlay-h);
}

#equipment-gold { color: var(--gold-bright); font-weight: 800; }
#equipment-count { color: var(--ink-dim); }

/* ref-equipment: 왼쪽 탐색(인벤토리) → 오른쪽 상세·행동 */
.equipment-body {
  /* 절대 위치 자손을 본문 스크롤 영역에 가둔다 — 위 .collection-body와 같은 이유. */
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 21rem);
  gap: var(--gap-panel);
  padding: var(--pad-body);
  min-height: 0;
  overflow: auto;
}

.equipment-inventory { order: -1; min-width: 0; }

#equipment-hero-select,
#promotion-material {
  /*
   * iOS WebKit은 기본 모양(menulist)의 select에 height/min-height를 무시한다 — 실기기
   * 실측에서 27.6px로 잡혔다(iPhone 17 Pro/iOS 26.5). appearance를 벗겨야 44px 계약이
   * 실제로 선다. 화살표는 네이티브가 사라지므로 토큰 색 삼각형으로 직접 그린다.
   */
  appearance: none;
  max-width: 12rem;
  min-height: var(--tap-min);
  padding: 0.3rem 1.5rem 0.3rem 0.45rem;
  border: 1px solid var(--gold-line);
  border-radius: 0.5rem;
  background-color: var(--bg-slot);
  background-image:
    linear-gradient(45deg, transparent 50%, rgb(var(--c-gold) / 0.85) 50%),
    linear-gradient(135deg, rgb(var(--c-gold) / 0.85) 50%, transparent 50%);
  background-position: right 0.85rem center, right 0.5rem center;
  background-size: 0.35rem 0.35rem;
  background-repeat: no-repeat;
  color: var(--ink);
  font: inherit;
  font-size: 0.82rem;
}

#promotion-material { max-width: none; min-height: var(--tap-min); }

.equipment-slots {
  list-style: none;
  display: grid;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
}

.equipment-slot {
  display: grid;
  gap: var(--gap-row);
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--card-grade, var(--line-card));
  border-left: 4px solid var(--card-grade, var(--line-bright));
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.902), rgb(var(--c-deep) / 0.941));
}

.equipment-slot.grade-normal { --card-grade: var(--grade-normal); }
.equipment-slot.grade-rare { --card-grade: var(--grade-rare); }
.equipment-slot.grade-epic { --card-grade: var(--grade-epic); }
.equipment-slot.grade-unique { --card-grade: var(--grade-unique); }
.equipment-slot.grade-legend { --card-grade: var(--grade-legend); }

.equipment-slot .slot-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4rem;
  font-size: 0.85rem;
  font-weight: 700;
}

.equipment-slot .slot-name {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--ink-dim);
  font-weight: 600;
  font-size: 0.78rem;
}

.equipment-icon {
  width: 2.1rem;
  height: 2.1rem;
  flex: 0 0 auto;
  object-fit: cover;
  border: 1px solid var(--gold-line);
  border-radius: 0.4rem;
  background: var(--bg-slot);
  vertical-align: middle;
}
.equipment-slot p {
  margin: 0;
  color: var(--ink-dim);
  font-size: 0.76rem;
}

.equipment-slot button {
  justify-self: start;
  min-height: var(--tap-min);
  margin-top: 0.15rem;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--line-bright);
  border-radius: 0.4rem;
  background: var(--btn-navy);
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.76rem;
  font-weight: 700;
  cursor: pointer;
}

.equipment-slot button:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.equipment-slot-actions {
  display: flex;
  gap: 0.35rem;
  flex-wrap: wrap;
}

/* 강화는 화면의 최우선 행동 — 금색은 여기에만 쓴다. */
.equipment-slot button.enhance {
  border-color: var(--gold-line-strong);
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font-weight: 800;
}

.equipment-slot button.enhance:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
}

.equipment-hero-stats {
  margin: 0.6rem 0 0;
  color: var(--info);
  font-size: 0.82rem;
}

.equipment-set-bonus {
  margin: 0.55rem 0 0;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink-dim);
}

.equipment-set-bonus.complete {
  text-shadow: 0 0 8px currentColor;
}

.equipment-synthesis {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  margin: 0.4rem 0 0.5rem;
}

.equipment-synthesis button {
  align-items: center;
  gap: 0.35rem;
  min-height: var(--tap-min);
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--line-bright);
  border-radius: 0.4rem;
  background: var(--btn-navy);
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
}

#equipment-synthesis-toggle { display: inline-flex; }

.equipment-synthesis button[aria-pressed='true'] {
  border-color: var(--grade-epic);
  background: linear-gradient(180deg, var(--epic-bg), var(--epic-bg-deep));
  color: var(--epic-ink);
}

.equipment-synthesis button:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.equipment-synthesis-hint {
  margin: 0;
  color: var(--ink-dim);
  font-size: 0.74rem;
}

.equipment-synthesis-hint[hidden] {
  display: none;
}

.equipment-cell.synthesis-selected button {
  outline: 2px solid var(--grade-epic);
  outline-offset: -2px;
  box-shadow: 0 0 10px rgb(var(--c-epic) / 0.4);
}

.equipment-detail[hidden] {
  display: none;
}

/* 선택 장비 상세 — 현재값 → 다음값 비교와 행동 우선순위 */
.equipment-detail {
  margin-top: 0.6rem;
  display: grid;
  gap: 0.3rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, rgb(var(--c-panel-mid) / 0.902), rgb(var(--c-deep) / 0.941));
}

.equipment-detail h4 {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0;
  color: var(--gold-bright);
  font-size: var(--fs-section);
}

.equipment-detail p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.78rem;
}

.equipment-detail-actions {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.25rem;
}

.equipment-detail-actions button {
  flex: 1 1 auto;
  min-height: var(--tap-min);
  border: 1px solid var(--line-bright);
  border-radius: 0.45rem;
  background: var(--btn-navy);
  color: var(--ink-soft);
  font: inherit;
  font-weight: 800;
  font-size: 0.82rem;
  cursor: pointer;
}

.equipment-detail-actions button.danger {
  border-color: var(--danger-line);
  background: linear-gradient(180deg, var(--danger-bg), var(--danger-bg-deep));
  color: var(--danger-ink);
}

.equipment-detail-actions button:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.equipment-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.equipment-filters button {
  min-height: var(--tap-min);
  padding: 0.3rem 0.65rem;
  border: 1px solid var(--line-mid);
  border-radius: 0.5rem;
  background: var(--bg-slot);
  color: var(--ink-dim);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
}

.equipment-filters button[aria-pressed="true"] {
  border-color: var(--gold-line-strong);
  background: linear-gradient(180deg, var(--bg-gold-deep), var(--bg-panel-mid));
  color: var(--gold-bright);
}

/* 5열 슬롯 그리드 — 아이콘 중심의 정사각 칸 */
.equipment-grid {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0.3rem;
  margin: 0;
  padding: 0.15rem;
  max-height: var(--overlay-list-h);
  overflow: auto;
}

.equipment-cell {
  min-height: 5.1rem;
  border: 1px dashed var(--line-quiet);
  border-radius: var(--radius-slot);
  background: rgb(var(--c-scrim) / 0.4);
}

.equipment-cell button {
  display: grid;
  justify-items: center;
  gap: 0.15rem;
  width: 100%;
  height: 100%;
  min-height: 5.1rem;
  padding: 0.3rem 0.25rem;
  border: 2px solid var(--card-grade, var(--grade-common));
  border-radius: var(--radius-slot);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.933), rgb(var(--c-deep) / 0.949));
  color: var(--ink);
  font: inherit;
  text-align: center;
  cursor: pointer;
}

.equipment-cell button.grade-normal { --card-grade: var(--grade-normal); }
.equipment-cell button.grade-rare { --card-grade: var(--grade-rare); }
.equipment-cell button.grade-epic { --card-grade: var(--grade-epic); }
.equipment-cell button.grade-unique { --card-grade: var(--grade-unique); }
.equipment-cell button.grade-legend { --card-grade: var(--grade-legend); }

.equipment-cell button[aria-pressed="true"] {
  box-shadow: 0 0 0 2px var(--gold) inset;
}

.equipment-cell button:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

.equipment-cell .cell-name {
  display: grid;
  justify-items: center;
  gap: 0.15rem;
  max-width: 100%;
  overflow: hidden;
  font-size: var(--fs-micro);
  font-weight: 700;
  text-overflow: ellipsis;
}

.equipment-cell .equipment-icon {
  width: 2.1rem;
  height: 2.1rem;
}

.equipment-cell .cell-stat {
  color: var(--ink-soft);
  font-size: var(--fs-micro);
}

.equipment-cell .cell-sub {
  color: var(--ink-dim);
  font-size: 0.62rem;
}

.equipment-cell.equipped button {
  box-shadow: 0 0 0 2px var(--owned) inset;
}

.equipment-empty {
  grid-column: 1 / -1;
  color: var(--ink-dim);
  font-size: 0.85rem;
}

/* 파티 카드 등급 테두리 — 고용소 카드와 같은 색 규칙 */
.hero-portrait.grade-common { --grade-color: var(--grade-common); }
.hero-portrait.grade-uncommon { --grade-color: var(--grade-uncommon); }
.hero-portrait.grade-rare { --grade-color: var(--grade-rare); }
.hero-portrait.grade-epic { --grade-color: var(--grade-epic); }
.hero-portrait.grade-legendary { --grade-color: var(--grade-legendary); }

/*
 * 보스 게이트 — 상단바 스테이지 칩 오른쪽의 컴팩트 칩.
 * 킬 진행은 칩 테두리가 차오르는 것으로만 읽고, 가득 차면 발광으로 알린다.
 */
#boss-challenge {
  position: relative;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: var(--hud-gap-tight);
  /* 폭도 뷰포트에 비례한다 — 좁은 화면에서는 저절로 줄고 넓은 화면에서만 길어진다. */
  max-width: clamp(6rem, 24vmin, 10rem);
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  padding: calc(var(--hud-unit) * 0.28) calc(var(--hud-unit) * 0.55);
  pointer-events: auto;
  border: 2px solid var(--line-mid);
  border-radius: 999px;
  background: linear-gradient(180deg, rgb(var(--c-panel-soft) / 0.949), rgb(var(--c-deep) / 0.949));
  color: var(--gold-bright);
  font: inherit;
  font-size: var(--hud-fs-sm);
  font-weight: 800;
  letter-spacing: 0.02em;
  text-shadow: 0 2px 4px rgb(var(--c-black) / 0.667);
  cursor: pointer;
}

/* 킬 진행은 버튼 테두리가 차오르는 것으로만 읽힌다(서버 killCount의 시각 표현). */
#boss-challenge::before {
  content: '';
  position: absolute;
  inset: -2px;
  padding: 3px;
  border-radius: inherit;
  pointer-events: none;
  background: conic-gradient(
    from 0deg,
    var(--boss-accent, var(--gold)) var(--boss-angle, 0deg),
    rgb(var(--c-white) / 0.122) var(--boss-angle, 0deg)
  );
  -webkit-mask: linear-gradient(rgb(var(--c-black)) 0 0) content-box, linear-gradient(rgb(var(--c-black)) 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(rgb(var(--c-black)) 0 0) content-box, linear-gradient(rgb(var(--c-black)) 0 0);
  mask-composite: exclude;
}

/* 게이지가 가득 차면 금색 발광으로 도전 가능을 알린다. */
#boss-challenge.is-ready {
  box-shadow: 0 0 0.9rem 0.1rem rgb(var(--c-gold-bright) / 0.4);
}

#boss-challenge.is-ready::before {
  background: conic-gradient(from 0deg, var(--gold-bright), var(--gold) 50%, var(--gold-bright));
  animation: boss-gate-ready-pulse 1.6s ease-in-out infinite;
}

@keyframes boss-gate-ready-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.65; }
}

html[data-reduced-motion="true"] #boss-challenge.is-ready::before {
  animation: none;
}

#boss-challenge[hidden] {
  display: none;
}

#boss-challenge:hover,
#boss-challenge:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 3px;
}

#boss-challenge:disabled {
  border-color: var(--line-mid);
  color: var(--ink-dim);
  box-shadow: none;
  cursor: default;
}

/* 최전선이 아니면 도전이 아니라 이동 안내다 — 금색 강조를 걷어낸다. */
#boss-challenge.is-away {
  border-color: var(--gold-line);
  color: var(--ink-soft);
  box-shadow: none;
}

#boss-challenge.boss-grand {
  box-shadow: 0 0 1.1rem 0.1rem rgb(var(--c-legendary) / 0.333);
}

/*
 * 파티 = 영웅 슬롯 10칸. 5×2 격자로 표면 초상 스트립과 같은 순서를 보여 준다.
 * 빈 칸은 점선 + 로 남아 "여기 배치"만 말한다.
 */
.party-slot-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--gap-card);
  margin: 0;
  padding: 0;
  list-style: none;
}

.party-slot {
  position: relative;
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 0.15rem;
  width: 100%;
  min-height: var(--tap-min);
  padding: 0.3rem 0.2rem;
  border: 2px solid var(--card-grade, var(--line-card));
  border-radius: var(--radius-slot);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.933), rgb(var(--c-deep) / 0.949));
  color: var(--ink);
  font: inherit;
  font-size: var(--fs-micro);
  font-weight: 700;
  text-align: center;
  cursor: pointer;
}

.party-slot.grade-common { --card-grade: var(--grade-common); }
.party-slot.grade-uncommon { --card-grade: var(--grade-uncommon); }
.party-slot.grade-rare { --card-grade: var(--grade-rare); }
.party-slot.grade-epic { --card-grade: var(--grade-epic); }
.party-slot.grade-legendary { --card-grade: var(--grade-legendary); }

.party-slot.is-empty {
  border-style: dashed;
  border-color: var(--line-disabled);
  background: rgb(var(--c-scrim) / 0.4);
  color: var(--ink-dim);
  font-size: var(--fs-section);
  font-weight: 900;
}

.party-slot:hover:not(:disabled),
.party-slot:focus-visible {
  border-color: var(--gold);
  outline: 2px solid var(--gold-line-strong);
  outline-offset: 2px;
}

.party-slot:disabled { cursor: default; }

.party-slot-icon {
  width: 1.9rem;
  height: 1.9rem;
  object-fit: cover;
  border-radius: 0.3rem;
  background: var(--bg-slot);
}

.party-slot-name {
  max-width: 100%;
  overflow: hidden;
  color: var(--ink-soft);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 등급명 배지 — 슬롯 테두리 등급색과 같은 정보를 우상단에 글자로도 낸다. */
.party-slot-grade {
  position: absolute;
  top: 0.1rem;
  right: 0.2rem;
  color: var(--ink-soft);
  font-size: 0.58rem;
  font-weight: 800;
  white-space: nowrap;
}

/* 슬롯 번호는 좌상단 작은 배지로만 읽힌다. */
.party-slot-index {
  position: absolute;
  top: 0.1rem;
  left: 0.2rem;
  color: var(--ink-dim);
  font-size: 0.58rem;
  font-weight: 900;
}

#party-slots-summary {
  margin: 0;
  color: var(--ink-dim);
  font-size: var(--fs-meta);
}

.synergy-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--hud-gap-tight);
  list-style: none;
  margin: 0 0 var(--hud-gap-tight);
  padding: 0;
}

.synergy-chip,
.synergy-tag {
  margin: 0;
  padding: 0.12rem 0.38rem;
  border: 1px solid var(--gold-line);
  border-radius: calc(var(--hud-radius) * 0.6);
  background: var(--bg-panel-soft);
  color: var(--ink-dim);
  font-size: var(--hud-fs-xs);
  line-height: 1.2;
}

.synergy-chip.is-active,
.synergy-tag {
  color: var(--ink);
  border-color: var(--gold-line-strong);
}

.hero-tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--hud-gap-tight);
  margin: 0 0 var(--hud-gap-tight);
}

.hire-synergy-hint {
  margin: 0;
  color: var(--owned);
  font-size: var(--hud-fs-xs);
}

/*
 * 배치·장착 후보 목록 팝업 — 영웅 슬롯과 장비 슬롯이 같은 형태를 공유한다.
 * 목록만 안에서 스크롤하고 표면은 건드리지 않는다.
 */
.picker-panel {
  display: flex;
  flex-direction: column;
  /* 패널 자신은 스크롤하지 않는다(clip) — 스크롤은 본문 한 겹만 맡는다. */
  overflow: clip;
  width: var(--overlay-w-sm);
  max-height: var(--overlay-h-sm);
  border: 1px solid var(--gold-line-strong);
  border-radius: var(--radius-panel);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.969), rgb(var(--c-deep) / 0.98));
  box-shadow: var(--shadow-panel);
}

.picker-list {
  display: grid;
  gap: var(--gap-card);
  margin: 0;
  padding: var(--pad-body);
  list-style: none;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.picker-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--gap-card);
  padding: 0.35rem 0.45rem;
  border: 1px solid var(--card-grade, var(--border-card));
  border-left: 3px solid var(--card-grade, var(--line-bright));
  border-radius: var(--radius-card);
  background: var(--bg-slot);
}

.picker-row.grade-common { --card-grade: var(--grade-common); }
.picker-row.grade-uncommon { --card-grade: var(--grade-uncommon); }
.picker-row.grade-rare { --card-grade: var(--grade-rare); }
.picker-row.grade-epic { --card-grade: var(--grade-epic); }
.picker-row.grade-legendary { --card-grade: var(--grade-legendary); }
.picker-row.grade-normal { --card-grade: var(--grade-normal); }
.picker-row.grade-unique { --card-grade: var(--grade-unique); }
.picker-row.grade-legend { --card-grade: var(--grade-legend); }

.picker-row.is-current { background: linear-gradient(180deg, rgb(var(--c-panel-mid) / 0.941), rgb(var(--c-slot) / 0.961)); }

.picker-row-icon {
  width: 2rem;
  height: 2rem;
  object-fit: cover;
  border: 1px solid var(--card-grade, var(--gold-line));
  border-radius: 0.35rem;
  background: var(--bg-slot);
}

.picker-row-copy {
  display: grid;
  gap: 0.05rem;
  min-width: 0;
}

.picker-row-name {
  overflow: hidden;
  font-size: var(--fs-body);
  font-weight: 800;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.picker-row-meta {
  color: var(--ink-dim);
  font-size: var(--fs-meta);
}

/* 목록 안의 실행 버튼 — 화면당 금색 강조는 이 열 하나로 묶는다. */
.picker-row button {
  /* 폭까지 44px 터치 표면 — "배치" 두 글자가 41px로 눌리던 자리다. */
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.45rem;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-size: var(--fs-meta);
  font-weight: 800;
  white-space: nowrap;
  cursor: pointer;
}

.picker-row button.secondary {
  border-color: var(--line-bright);
  background: var(--btn-navy);
  color: var(--ink-soft);
}

.picker-row button:disabled {
  border-color: var(--line-disabled);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.picker-row button:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

.picker-empty {
  color: var(--ink-dim);
  font-size: var(--fs-body);
  text-align: center;
}

/*
 * 장비 상세 팝업 — 인벤토리 칸과 영웅 상세 슬롯이 같은 팝업을 공유한다.
 * 티어·등급색은 머리말이, 증감은 비교 줄이 맡는다.
 */
.equipment-detail-panel {
  display: flex;
  flex-direction: column;
  /* 패널 자신은 스크롤하지 않는다(clip) — 스크롤은 본문 한 겹만 맡는다. */
  overflow: clip;
  width: var(--overlay-w-xs);
  max-height: var(--overlay-h-sm);
  border: 1px solid var(--gold-line-strong);
  border-radius: var(--radius-panel);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.969), rgb(var(--c-deep) / 0.98));
  box-shadow: var(--shadow-panel);
}

.equipment-detail-body {
  display: grid;
  gap: var(--gap-card);
  padding: var(--pad-body);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.equipment-detail-main {
  margin: 0;
  color: var(--gold-bright);
  font-size: var(--fs-body);
  font-weight: 800;
}

.equipment-detail-subs {
  display: grid;
  gap: 0.1rem;
  margin: 0;
  padding: 0;
  list-style: none;
  color: var(--ink-soft);
  font-size: var(--fs-meta);
}

.equipment-detail-compare-box h3 {
  margin: 0 0 0.2rem;
  color: var(--ink-dim);
  font-size: var(--fs-meta);
}

.equipment-detail-compare-box[hidden] { display: none; }

.equipment-detail-compare {
  display: grid;
  gap: 0.1rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-meta);
}

.equipment-detail-compare > li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.35rem;
  color: var(--ink-dim);
}

/* 증감은 부호(+/-)가 정본이고 색은 보조다 — 올라가면 청록, 내려가면 붉은색. */
.equipment-detail-compare .delta-up { color: var(--ok); font-weight: 800; }
.equipment-detail-compare .delta-down { color: var(--danger); font-weight: 800; }

.equipment-detail-popup-actions {
  display: grid;
  grid-auto-flow: column;
  gap: var(--gap-card);
}

.equipment-detail-popup-actions button {
  min-height: var(--tap-min);
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--line-bright);
  border-radius: 0.45rem;
  background: var(--btn-navy);
  color: var(--ink-soft);
  font: inherit;
  font-size: var(--fs-meta);
  font-weight: 800;
  cursor: pointer;
}

/* 강화만 금색 — 화면당 최우선 행동 하나 규칙을 지킨다. */
.equipment-detail-popup-actions button.enhance {
  border-color: var(--gold-line-strong);
  background: var(--btn-gold);
  color: var(--ink-on-gold);
}

.equipment-detail-popup-actions button.danger {
  border-color: var(--danger-line);
  background: linear-gradient(180deg, var(--danger-bg), var(--danger-bg-deep));
  color: var(--danger-ink);
}

.equipment-detail-popup-actions button:disabled {
  border-color: var(--line-disabled);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.equipment-detail-popup-actions button:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

/*
 * 우측 퀵 아이콘 레일 — 자주 쓰는 진입점 4개만 세로로 세운다.
 * 표면 요소라 스크롤을 만들지 않고, 상단바(보스 칩)와 하단(파티 격자) 사이에 선다.
 */
.quick-rail {
  position: absolute;
  right: var(--hud-edge-right);
  /*
   * 격자 2행(상단바 아래 남은 띠) 안에 선다 — 상단바가 한 줄이든 두 줄이든 실측 높이를
   * 그대로 피하고, 아래로는 파티 초상 띠를 비운다. 가운데 정렬이라 가로 모드처럼
   * 높이가 짧아도 위아래 어느 쪽과도 겹치지 않는다.
   */
  grid-row: 2;
  top: 0;
  bottom: var(--hud-bottom-zone);
  display: grid;
  align-content: center;
  justify-items: end;
  gap: var(--hud-gap);
  pointer-events: auto;
}

.quick-rail[hidden] { display: none; }

/*
 * 아이콘 자체가 버튼이다 — 카드 껍데기(테두리+그라디언트)를 두르지 않는다.
 * 히트 영역은 카드가 아니라 버튼 상자의 --tap-min이 지키므로 44×44는 그대로 남는다.
 */
.quick-rail-button {
  position: relative;
  display: grid;
  place-items: center;
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  padding: 0;
  border: 0;
  border-radius: var(--hud-radius);
  background: none;
  color: var(--gold-bright);
  font: inherit;
  font-size: var(--hud-fs-xs);
  font-weight: 700;
  cursor: pointer;
}

/* 경계 없는 방사형 그늘 — 밝은 지형에서도 아이콘 밑이 눌려 실루엣이 산다. */
.quick-rail-button::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--hud-icon-scrim);
  pointer-events: none;
}

.quick-rail-button:hover,
.quick-rail-button:focus-visible {
  color: var(--gold-bright);
  outline: 2px solid var(--gold-line-strong);
  outline-offset: 2px;
}

/* 카드가 없으니 비활성은 아이콘 자체가 흐려지는 것으로 읽힌다. */
.quick-rail-button:disabled {
  opacity: 0.45;
  cursor: default;
}

.quick-rail-button:hover .quick-rail-icon,
.quick-rail-button:focus-visible .quick-rail-icon { filter: var(--hud-icon-lift-strong); }

.quick-rail-icon {
  width: var(--hud-icon);
  height: var(--hud-icon);
  font-size: var(--hud-fs);
  line-height: 1;
  filter: var(--hud-icon-lift);
}

/* 알림은 점 배지 하나로만 — 색·크기 강조는 쓰지 않는다. */
.quick-rail-badge {
  position: absolute;
  top: 0.1rem;
  right: 0.1rem;
  min-width: 0.95rem;
  padding: 0 0.15rem;
  border-radius: 999px;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font-size: 0.58rem;
  font-weight: 900;
  line-height: 0.95rem;
  text-align: center;
}

.quick-rail-badge[hidden] { display: none; }

/*
 * 성장 오버레이 — 탭 하나에 레벨업·승급·특성·환생 진입을 모은다.
 * 목록만 안에서 스크롤하고 표면은 건드리지 않는다.
 */
.growth-panel {
  display: flex;
  flex-direction: column;
  /* 패널 자신은 스크롤하지 않는다(clip) — 스크롤은 본문 한 겹만 맡는다. */
  overflow: clip;
  width: var(--overlay-w-md);
  max-height: var(--overlay-h);
  border: 1px solid var(--gold-line-strong);
  border-radius: var(--radius-panel);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.969), rgb(var(--c-deep) / 0.98));
  box-shadow: var(--shadow-panel);
}

.growth-tabs {
  display: grid;
  grid-auto-flow: column;
  gap: var(--gap-card);
  padding: var(--pad-body);
  border-bottom: 1px solid var(--gold-line);
}

.growth-tabs button {
  min-height: var(--tap-min);
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--gold-line);
  border-radius: 0.45rem;
  background: var(--btn-navy);
  color: var(--ink-dim);
  font: inherit;
  font-size: var(--fs-meta);
  font-weight: 800;
  cursor: pointer;
}

/* 고른 탭만 금색 테두리로 읽힌다(탭 하나만 강조). */
.growth-tabs button[aria-selected="true"] {
  border-color: var(--gold-line-strong);
  background: linear-gradient(180deg, var(--bg-gold-deep), var(--bg-panel-mid));
  color: var(--gold-bright);
}

.growth-tabs button:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

.growth-body {
  display: grid;
  padding: var(--pad-body);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.growth-tabpanel {
  display: grid;
  gap: var(--gap-card);
  align-content: start;
}

.growth-tabpanel[hidden] { display: none; }

.growth-summary {
  margin: 0;
  color: var(--gold-bright);
  font-size: var(--fs-body);
  font-weight: 800;
}

.growth-note {
  margin: 0;
  color: var(--danger);
  font-size: var(--fs-meta);
}

.growth-hint {
  margin: 0;
  color: var(--ink-dim);
  font-size: var(--fs-micro);
}

/* 탭당 최우선 행동 하나만 금색이다. */
.growth-action {
  justify-self: start;
  min-height: var(--tap-min);
  padding: 0.3rem 0.9rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.45rem;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-size: var(--fs-meta);
  font-weight: 800;
  cursor: pointer;
}

.growth-action:disabled {
  border-color: var(--line-disabled);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.growth-action:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

/* 아레나(비동기 PvP) 오버레이 */
.arena-panel {
  width: var(--overlay-w-xl);
  max-height: var(--overlay-h);
}

#arena-rating { color: var(--gold-bright); font-weight: 800; }
#arena-daily { color: var(--ink-dim); }

.arena-body {
  display: grid;
  grid-template-columns: 1.1fr 1fr 1fr;
  gap: var(--gap-panel);
  padding: var(--pad-body);
  min-height: 0;
  overflow: auto;
}

.arena-defense-summary {
  margin: 0 0 0.6rem;
  color: var(--ink-dim);
  font-size: 0.85rem;
}

.arena-defense-list,
.arena-candidates,
.arena-ranking-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.6rem;
}

/* ref-pvp-arena: 도전 상대 카드는 같은 정보 순서를 반복한다. */
.arena-candidate {
  display: grid;
  gap: 0.3rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--line-info);
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.933), rgb(var(--c-deep) / 0.949));
}

.arena-candidate-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  font-weight: 800;
}

.arena-candidate-rating { color: var(--gold-bright); font-size: 0.85rem; }

.arena-candidate p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.8rem;
}

.arena-candidate button {
  min-height: var(--tap-min);
  margin-top: 0.35rem;
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.55rem;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}

.arena-candidate button:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.arena-candidate button:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

.arena-rank-row {
  display: grid;
  grid-template-columns: 3rem 1fr auto;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--line-card);
  border-radius: var(--radius-slot);
  background: var(--bg-slot);
  font-size: 0.85rem;
}

/* 현재 플레이어 행만 금색으로 강조한다. */
.arena-rank-row.me {
  border-color: var(--gold-line-strong);
  background: linear-gradient(180deg, var(--bg-gold-deep), var(--bg-panel-mid));
}

.arena-rank { color: var(--ink-dim); }
.arena-rank-rating { color: var(--gold-bright); font-weight: 800; }

.arena-rank-record {
  grid-column: 1 / -1;
  color: var(--ink-dim);
  font-size: 0.75rem;
}

#arena-my-rank { margin: 0; color: var(--ink-dim); font-size: 0.8rem; }

#arena-defense-save,
#arena-refresh {
  min-height: var(--tap-min);
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--gold-line);
  border-radius: 0.5rem;
  background: var(--btn-navy);
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 700;
  cursor: pointer;
}

#arena-defense-save:hover,
#arena-defense-save:focus-visible,
#arena-refresh:hover,
#arena-refresh:focus-visible {
  border-color: var(--gold);
  color: var(--gold-bright);
}

#arena-defense-save:disabled,
#arena-refresh:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.arena-replay {
  position: absolute;
  z-index: 27;
  left: 50%;
  bottom: 8%;
  display: grid;
  justify-items: center;
  gap: 0.4rem;
  padding: 0.9rem 1.4rem;
  transform: translateX(-50%);
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-panel);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.949), rgb(var(--c-deep) / 0.969));
  box-shadow: var(--shadow-panel);
  text-align: center;
}

.arena-replay[data-tone="win"] { border-color: var(--gold-line-strong); }
.arena-replay[data-tone="loss"] { border-color: var(--danger-line); }

.arena-replay-title {
  margin: 0;
  color: var(--gold-bright);
  font-size: var(--fs-section);
  font-weight: 800;
}

.arena-replay-detail {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.85rem;
}

.arena-replay button {
  min-height: var(--tap-min);
  margin-top: 0.3rem;
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--gold-line);
  border-radius: 0.55rem;
  background: var(--btn-navy);
  color: var(--ink-soft);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

.arena-replay[hidden] { display: none; }

/* O3 무한 타워 오버레이 — 층 목록·랭킹만 오버레이 안에서 스크롤한다. */
.tower-panel {
  width: var(--overlay-w-xl);
  max-height: var(--overlay-h);
}

#tower-current { color: var(--gold-bright); font-weight: 800; }
#tower-best,
#tower-attempts,
#tower-countdown { color: var(--ink-dim); }

.tower-body {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--gap-panel);
  padding: var(--pad-body);
  min-height: 0;
  overflow: hidden;
}

.tower-body > section {
  display: grid;
  grid-template-rows: auto auto 1fr;
  min-height: 0;
}

.tower-next {
  margin: 0 0 0.5rem;
  color: var(--ink-soft);
  font-size: 0.85rem;
}

/*
 * 도전 패널은 내용이 한 줄뿐이라 공유 규칙의 1fr 행이 카드를 빈 공간으로
 * 늘였다 — 내용 높이로 접고, 남는 세로는 전투력 게이지가 채운다.
 */
.tower-challenge-panel {
  align-self: start;
  grid-template-rows: none;
  align-content: start;
}

.tower-power-track {
  margin: 0 0 0.35rem;
}

#tower-power { margin: 0; color: var(--ink-dim); font-size: 0.8rem; }

#tower-challenge {
  min-height: var(--tap-min);
  align-self: start;
  padding: 0.55rem 0.9rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.55rem;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}

#tower-challenge:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

#tower-challenge:focus-visible,
#tower-reward-claim:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

.tower-reward {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-top: 0.7rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, var(--bg-gold-deep), var(--bg-panel-mid));
}

.tower-reward[hidden] { display: none; }

.tower-reward-copy { display: grid; gap: 0.15rem; }
.tower-reward-copy strong { color: var(--gold-bright); }
.tower-reward-copy span { color: var(--ink-soft); font-size: 0.8rem; }

#tower-reward-claim {
  min-height: var(--tap-min);
  padding: 0.35rem 0.8rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.5rem;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}

#tower-reward-claim:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.tower-floors {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.4rem;
  align-content: start;
  min-height: 0;
  overflow-y: auto;
}

.tower-floor-row {
  display: grid;
  grid-template-columns: 4rem 1fr auto;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--line-card);
  border-radius: var(--radius-slot);
  background: var(--bg-slot);
  font-size: 0.85rem;
}

.tower-floor-row .tower-floor { color: var(--ink-soft); font-weight: 800; }
.tower-floor-row .tower-floor-power { color: var(--ink-dim); font-size: 0.78rem; }
.tower-floor-row .tower-floor-reward {
  grid-column: 1 / -1;
  color: var(--gold);
  font-size: 0.75rem;
}

.tower-floor-row[data-state="cleared"] { border-color: var(--line-info); color: var(--owned); }
.tower-floor-row[data-state="current"] {
  border-color: var(--gold-line-strong);
  background: linear-gradient(180deg, var(--bg-gold-deep), var(--bg-panel-mid));
}
.tower-floor-row[data-state="attempted"] { border-color: var(--danger-line); }
.tower-floor-row[data-state="locked"] { color: var(--ink-dim); }

.tower-ranking-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.5rem;
  align-content: start;
  min-height: 0;
  overflow-y: auto;
}

#tower-my-rank { margin: 0; color: var(--ink-dim); font-size: 0.8rem; }

/* 코스메틱 상점 오버레이 */
.shop-panel {
  width: var(--overlay-w-xl);
  max-height: var(--overlay-h);
}

#shop-gold { color: var(--gold-bright); font-weight: 800; }
#shop-slots { color: var(--ink-dim); }

/* 비 P2W 문구는 구매 영역과 같은 폭에서 상시 노출한다. */
.shop-no-p2w {
  margin: 0.6rem 1.15rem 0;
  padding: 0.5rem 0.8rem;
  border: 1px solid var(--line-info);
  border-radius: var(--radius-slot);
  background: var(--bg-slot);
  color: var(--owned);
  font-size: 0.82rem;
  font-weight: 700;
  text-align: center;
}

.shop-body {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--gap-panel);
  padding: var(--pad-body);
  min-height: 0;
  overflow: auto;
}

.shop-categories {
  display: grid;
  gap: 0.9rem;
}

.shop-category h4 {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 0.45rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--gold-line);
  font-size: var(--fs-section);
  color: var(--gold-bright);
}

/* 상품은 6칸 격자 — 의상·무기 스킨·배너·이모트를 같은 카드 형태로 반복한다. */
.shop-items {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  /* 칸 최소 폭이 열 수를 정한다 — 폭 브레이크포인트 없이 3→2→1로 자연히 접힌다. */
  grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr));
  gap: 0.5rem;
}

.shop-item {
  display: grid;
  justify-items: center;
  align-content: start;
  gap: 0.3rem;
  padding: 0.6rem 0.55rem;
  border: 1px solid var(--line-card);
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.933), rgb(var(--c-deep) / 0.949));
  font-size: 0.82rem;
  text-align: center;
}

/* 보유·장착 중은 청록으로 — 금색은 구매 행동에만 남긴다. */
.shop-item.owned { border-color: var(--owned); }
.shop-item.equipped {
  border-color: var(--owned);
  box-shadow: 0 0 0 1px var(--owned) inset;
}
.shop-item.owned .shop-state,
.shop-item.equipped .shop-state { color: var(--owned); font-weight: 700; }

/* 카테고리 머리말 — 보유 수를 숫자로 먼저 읽힌다(색은 보조). */
.shop-category-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--gap-card);
}

.shop-category-owned {
  color: var(--ink-soft);
  font-size: var(--fs-meta);
  font-weight: 800;
}

.shop-category-owned.complete { color: var(--owned); }

/*
 * 프리뷰 — 사기 전에 무엇인지 보이게 슬롯별로 모양을 달리 그린다.
 * 색은 배선이 씬 팔레트에서 풀어 넣은 --preview-color 하나뿐이다.
 */
.shop-swatch {
  position: relative;
  width: 2.4rem;
  height: 2.4rem;
  overflow: hidden;
  border-radius: var(--radius-slot);
  border: 1px solid var(--gold-line);
  background: var(--bg-chip);
}

/* 궤적 — 색이 옅어지며 흐르는 꼬리. */
.shop-swatch.preview-trail {
  background:
    linear-gradient(
      115deg,
      transparent 12%,
      var(--preview-color, var(--bg-chip)) 48%,
      transparent 88%
    ),
    var(--bg-slot);
}

/* 무기 발광 — 가운데 세로 날에 빛이 앉는다. */
.shop-swatch.preview-glow {
  background: var(--bg-slot);
}

.shop-swatch.preview-glow::after {
  content: '';
  position: absolute;
  top: 15%;
  bottom: 15%;
  left: 50%;
  width: 0.32rem;
  transform: translateX(-50%);
  border-radius: 0.16rem;
  background: var(--preview-color, var(--ink-dim));
  box-shadow: 0 0 0.5rem var(--preview-color, transparent);
}

/* 캠프 깃발 — 아래가 갈라진 페넌트. */
.shop-swatch.preview-banner {
  background: var(--bg-slot);
}

.shop-swatch.preview-banner::after {
  content: '';
  position: absolute;
  top: 12%;
  left: 25%;
  width: 50%;
  height: 66%;
  background: var(--preview-color, var(--ink-dim));
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 74%, 0 100%);
}

.shop-swatch.preview-swatch {
  background: var(--preview-color, var(--bg-chip));
}

.shop-price { color: var(--gold-bright); font-weight: 800; }
.shop-state { color: var(--ink-dim); font-size: 0.75rem; }

.shop-item button {
  width: 100%;
  min-height: var(--tap-min);
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.5rem;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 800;
  cursor: pointer;
}

.shop-item button:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.shop-item button:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

.shop-roster-hint {
  margin: 0 0 0.6rem;
  color: var(--ink-dim);
  font-size: 0.82rem;
}

#shop-roster-limit { margin: 0; color: var(--ink-dim); font-size: 0.82rem; }

#shop-roster-buy {
  width: 100%;
  min-height: var(--tap-min);
  padding: 0.55rem 0.8rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.55rem;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}

#shop-roster-buy:disabled {
  border-color: var(--line-mid);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

/*
 * 좁은 화면 재배치 — 크기는 유동 토큰이 잡으므로 여기서는 앵커 위치와 열 수만 만진다.
 * 기본 규칙 뒤에 두어 재배치가 실제로 적용된다.
 */
@media (max-width: 760px) {
  /*
   * 좁은 화면에서는 레일을 파티 초상 띠 한 칸 위로 더 띄운다 — 세로 가운데가 아니라
   * 엄지가 닿는 아래쪽에 모이고, 좌하단 격자와의 여유도 함께 벌어진다.
   */
  .quick-rail {
    top: auto;
    bottom: calc(var(--hud-bottom-zone) + var(--hud-gap));
  }

  /* 성장 탭은 4개라 좁은 화면에서 2열로 접는다. */
  .growth-tabs {
    grid-auto-flow: row;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* 390px에서도 영웅 슬롯 5열은 유지하고(초상 스트립 순서와 같게) 스탯만 1열로 접는다. */
  .hero-detail-sheet { grid-template-columns: 1fr; }

  .party-slot,
  .hero-detail-slot { padding: 0.25rem 0.15rem; }

  .party-slot-icon,
  .hero-detail-slot-icon { width: 1.6rem; height: 1.6rem; }

  .equipment-detail-popup-actions { grid-auto-flow: row; }
}

/* R1 도파민 — 일일 퀘스트·도감·환생 상점. 색은 전부 공통 토큰만 쓴다. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* HUD 요약 배지 — 수령 가능한 보상이 있을 때만 금색으로 튄다. */
#quest-open.has-claimable {
  border-color: var(--gold);
  background: var(--btn-gold);
  color: var(--ink-on-gold);
}

#quest-open[hidden] { display: none; }

/*
 * 메뉴 오버레이 — 표면에서 걷어낸 진입점을 아이콘 그리드 한 판으로 모은다.
 * 항목별 수령 가능 여부는 점 배지로만 알리고 색·크기 강조는 쓰지 않는다.
 */
.menu-panel {
  width: var(--overlay-w-sm);
  max-height: var(--overlay-h-sm);
}

.menu-body {
  display: grid;
  gap: var(--gap-panel);
  padding: var(--pad-body);
  /* 전체 화면에서는 패널 높이를 채워야 바닥 정렬이 먹는다(카드 높이에서는 콘텐츠만큼만). */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

/* 환생 진입 카드는 본문 밖 패널 막내다 — 본문이 스크롤필요 만큼 길어져도 항상 보인다. */
#prestige-entry {
  margin: 0 0.85rem 0.7rem;
}

.menu-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.menu-item {
  position: relative;
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 0.15rem;
  min-height: var(--tap-min);
  padding: 0.45rem 0.35rem;
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-card);
  background: var(--btn-navy);
  color: var(--ink-soft);
  font: inherit;
  font-size: var(--fs-meta);
  font-weight: 700;
  text-align: center;
  cursor: pointer;
}

.menu-item:hover,
.menu-item:focus-visible {
  border-color: var(--gold);
  color: var(--gold-bright);
  outline: 2px solid var(--gold-line-strong);
  outline-offset: 2px;
}

.menu-item:disabled {
  border-color: var(--line-disabled);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.menu-item[hidden] { display: none; }

.menu-item-icon {
  width: 1.75rem;
  height: 1.75rem;
  font-size: 1.15rem;
  line-height: 1;
}
.menu-item-label { line-height: 1.2; }

.menu-item-badge {
  position: absolute;
  top: 0.3rem;
  right: 0.3rem;
  min-width: 1.05rem;
  padding: 0 0.2rem;
  border-radius: 999px;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font-size: 0.66rem;
  font-weight: 900;
  line-height: 1.1rem;
  text-align: center;
}

.menu-item-badge[hidden] { display: none; }

/* 잠긴 항목 — disabled 대신 aria-disabled라 포커스·낭독은 살고 조작만 막힌다. */
.menu-item[data-locked="true"] {
  border-color: var(--line-disabled);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.menu-item[data-locked="true"] .menu-item-icon { opacity: 0.4; }

.menu-item[data-locked="true"]:hover,
.menu-item[data-locked="true"]:focus-visible {
  border-color: var(--line-disabled);
  color: var(--btn-disabled-ink);
}

/* 자물쇠 수치는 한 줄로 고정한다 — 줄바꿈이 칸 높이를 두 배로 만들었다. */
.menu-item-lock {
  color: var(--ink-dim);
  font-size: var(--fs-micro);
  font-weight: 700;
  line-height: 1.1;
  white-space: nowrap;
}

.menu-item-lock[hidden] { display: none; }

/* 해금 순간 한 번만 번쩍인다(반복 없음). */
@keyframes menu-unlock-flash {
  0% { border-color: var(--gold-bright); box-shadow: 0 0 0 0 var(--gold-glow); }
  40% { border-color: var(--gold-bright); box-shadow: 0 0 0.9rem 0.15rem var(--gold-glow); }
  100% { border-color: var(--gold-line); box-shadow: none; }
}

.menu-item.just-unlocked {
  animation: menu-unlock-flash 900ms ease-out 1;
}

html[data-reduced-motion="true"] .menu-item.just-unlocked {
  animation: none;
  border-color: var(--gold);
}

#mute-toggle.muted { color: var(--ink-dim); border-color: var(--line-disabled); }

#prestige-status {
  color: var(--ink-soft);
  font-weight: 600;
}

.quests-panel {
  width: var(--overlay-w-md);
  max-height: var(--overlay-h-sm);
}

.collection-panel {
  width: var(--overlay-w-xl);
  max-height: var(--overlay-h);
}

#quests-summary { color: var(--gold-bright); font-weight: 800; }
#quests-reset { color: var(--ink-dim); }
#collection-summary { color: var(--ink-soft); }

/*
 * 지도 헤더의 사냥 위치 요약은 좁으면 말줄임 대신 두 줄로 접는다 —
 * "청람 해안 · 스테이지 60 · …"처럼 중간이 끊기는 것보다 줄바꿈이 낫다.
 */
.hiring-header-meta > #map-summary {
  white-space: normal;
  word-break: keep-all;
  text-align: right;
}

.quests-body,
.collection-body {
  /*
   * 본문이 절대 위치 자손의 컨테이닝 블록을 겸한다 — 그래야 그 상자가 본문의 스크롤
   * 영역에 갇히고 패널의 레이아웃 오버플로로 새지 않는다(패널은 스크롤하지 않는다).
   */
  position: relative;
  display: grid;
  gap: var(--gap-panel);
  padding: var(--pad-body);
  min-height: 0;
  overflow: auto;
}

.collection-body {
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
}

/* 퀘스트 목록과 아래 카드는 위로 붙인다 — stretch는 카드 안에 빈 공백을 만든다. */
.quests-body {
  align-content: start;
}

/* 진행 바는 퀘스트·도감·특전이 같은 형태를 공유한다. */
.reward-track,
.collection-track {
  display: block;
  width: 100%;
  height: 0.45rem;
  overflow: hidden;
  border: 1px solid var(--gold-line);
  border-radius: 999px;
  background: var(--bg-slot);
}

.reward-fill,
.collection-track > span {
  display: block;
  width: 0%;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--gold-deep), var(--gold-bright));
  transition: width 200ms ease-out;
}

.quest-list,
.collection-milestones {
  list-style: none;
  display: grid;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
}

/* 한 줄에 진행과 수령을 함께 둬 5종이 스크롤 없이 들어온다. */
.quest-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.15rem 0.8rem;
  /* 5개 퀘스트와 전체 완료 보상 카드가 데스크톱 본문 한 화면에 들어오게 압축한다. */
  padding: 0.4rem 0.7rem;
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, var(--bg-panel), var(--bg-deep));
}

.quest-row > .quest-row-head,
.quest-row > .reward-track,
.quest-row > .quest-progress {
  grid-column: 1;
}

.quest-row > button {
  grid-column: 2;
  grid-row: 1 / span 3;
  min-width: 5.5rem;
  white-space: nowrap;
}

.quest-name,
.collection-milestone-copy strong {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.quest-row.ready {
  border-color: var(--gold-line-strong);
  box-shadow: 0 0 0.8rem var(--gold-glow);
}

.quest-row.claimed { opacity: 0.65; }

.quest-row-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
}

.quest-name { font-weight: 800; }
.quest-reward { color: var(--gold-bright); font-weight: 800; font-size: 0.86rem; }

.quest-progress {
  margin: 0;
  color: var(--ink-dim);
  font-size: 0.78rem;
}

.quest-row button,
.collection-milestone button,
#quest-bonus-claim {
  min-height: var(--tap-min);
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.5rem;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-weight: 800;
  font-size: 0.82rem;
  cursor: pointer;
}

.quest-row button:disabled,
.collection-milestone button:disabled,
#quest-bonus-claim:disabled {
  border-color: var(--btn-disabled-bg);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.quest-row button:focus-visible,
.collection-milestone button:focus-visible,
#quest-bonus-claim:focus-visible,
.prestige-node button:focus-visible,
.prestige-tree-respec button:focus-visible,
.prestige-respec-confirm-actions button:focus-visible,
.collection-tabs button:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

/* 전체 완료 보너스는 목록과 분리해 한 덩어리로 보여 준다. */
.quest-bonus {
  display: grid;
  gap: 0.35rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, var(--bg-panel-soft), var(--bg-deep));
}

#quest-bonus-reward {
  margin: 0;
  color: var(--gold-bright);
  font-weight: 800;
}

.quest-bonus-hint {
  margin: 0;
  color: var(--ink-dim);
  font-size: 0.8rem;
}

#quest-bonus-claim.ready {
  box-shadow: 0 0 0.9rem var(--gold-glow);
}

/* 도감 — 분류 탭, 수집 그리드, 구간 보상 */
.collection-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.collection-tabs button {
  min-height: var(--tap-min);
  padding: 0.3rem 0.65rem;
  border: 1px solid var(--border-soft-color, var(--gold-line));
  border-radius: 0.5rem;
  background: var(--bg-slot);
  color: var(--ink-dim);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
}

.collection-tabs button[aria-pressed="true"] {
  border-color: var(--gold-line-strong);
  background: linear-gradient(180deg, var(--bg-panel-soft), var(--bg-panel));
  color: var(--gold-bright);
}

.collection-progress {
  margin: 0 0 0.35rem;
  color: var(--ink-soft);
  font-size: 0.85rem;
  font-weight: 700;
}

.collection-grid {
  list-style: none;
  display: grid;
  /* 칸이 지나치게 커지지 않도록 상한을 둔다 — 분류마다 열 수만 바뀐다.
   * 열 수는 6칸으로 묶어 두어 좁은 화면에서도 가로 스크롤이 생기지 않는다. */
  grid-template-columns: repeat(min(var(--collection-columns, 6), 6), minmax(2.2rem, 4rem));
  justify-content: center;
  gap: 0.35rem;
  margin: 0.7rem 0 0;
  padding: 0.15rem;
  max-height: var(--overlay-list-h-lg);
  overflow: auto;
}

/* 미수집 칸도 같은 크기로 남겨 진행 감각을 준다(실루엣). */
.collection-cell {
  display: grid;
  /* 아이콘이 남는 높이를 다 쓰고 라벨 행은 늘 잘리지 않게 둘로 나눈다 —
   * 좁은 칸에서 aspect-ratio 정사각형만 믿으면 라벨이 반쪽 잘려 나갔다. */
  grid-template-rows: minmax(0, 1fr) auto;
  justify-items: center;
  align-content: center;
  gap: 0.15rem;
  /*
   * 칸이 자기 .sr-only(position: absolute)의 컨테이닝 블록이 된다.
   * 위치 지정 조상이 없으면 그 절대 위치 상자가 .collection-panel 기준으로 잡혀
   * 격자·본문의 클리핑을 우회하고 스크롤하지 않은 격자 전체 높이를 패널의 레이아웃
   * 오버플로로 얹었다(844×390 도감에서 75px 실측 — overlay-scroll-containment 회귀).
   */
  position: relative;
  aspect-ratio: 1;
  padding: 0.2rem;
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-slot);
  background: linear-gradient(180deg, var(--bg-panel), var(--bg-deep));
  overflow: hidden;
}

.collection-cell.locked {
  border-style: dashed;
  border-color: var(--btn-disabled-bg);
  background: var(--bg-slot);
  color: var(--btn-disabled-ink);
}

.collection-cell.found {
  border-color: var(--gold-line-strong);
}

.collection-cell.grade-uncommon { border-color: var(--grade-uncommon); }
.collection-cell.grade-rare { border-color: var(--grade-rare); }
.collection-cell.grade-epic { border-color: var(--grade-epic); }
.collection-cell.grade-legendary { border-color: var(--grade-legendary); }
.collection-cell.locked.grade-uncommon,
.collection-cell.locked.grade-rare,
.collection-cell.locked.grade-epic,
.collection-cell.locked.grade-legendary { border-color: var(--btn-disabled-bg); }

.collection-cell.tier-family.found { box-shadow: 0 0 0 1px var(--info) inset; }
.collection-cell.tier-grand.found { box-shadow: 0 0 0 1px var(--gold) inset; }

.collection-icon {
  /* 높이 기준으로 줄인다 — 칸이 작을수록 아이콘이 먼저 줄어 라벨 자리를 남긴다. */
  width: auto;
  height: 100%;
  max-width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 0.35rem;
}

.collection-mark {
  font-size: 0.9rem;
  font-weight: 900;
  line-height: 1;
}

.collection-cell.found .collection-mark { color: var(--gold-bright); }

.collection-cell-label {
  max-width: 100%;
  overflow: hidden;
  color: var(--ink-dim);
  font-size: 0.56rem;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.collection-milestone {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-card);
  background: var(--bg-slot);
}

.collection-milestone.ready { border-color: var(--gold-line-strong); }
.collection-milestone.claimed { opacity: 0.65; }

.collection-milestone-copy {
  display: grid;
  gap: 0.15rem;
  min-width: 0;
}

.collection-milestone-reward {
  color: var(--gold-bright);
  font-size: 0.78rem;
  font-weight: 700;
}

.collection-empty {
  color: var(--ink-dim);
  font-size: 0.85rem;
  list-style: none;
}

/* O3 환생 특성 트리 — 환생 오버레이 안의 3분기 세로 트리 */
.prestige-tree {
  margin-top: 0.7rem;
  padding: var(--pad-body);
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-card);
  background: var(--bg-slot);
}

#prestige-tree-points {
  margin: 0;
  color: var(--gold-bright);
  font-size: 0.82rem;
  font-weight: 800;
}

.prestige-tree-respec {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0.5rem 0 0.15rem;
}

.prestige-tree-note {
  margin: 0;
  color: var(--ink-dim);
  font-size: 0.76rem;
}

.prestige-respec-confirm {
  display: grid;
  gap: 0.45rem;
  margin: 0.35rem 0 0.15rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: var(--radius-card);
  background: var(--bg-panel);
}

.prestige-respec-confirm p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.78rem;
}

.prestige-respec-confirm-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.45rem;
}

.prestige-tree-branches {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(12rem, 100%), 1fr));
  gap: 0.55rem;
  margin-top: 0.55rem;
}

.prestige-branch {
  display: grid;
  gap: var(--gap-card);
  align-content: start;
  padding: 0.45rem 0.5rem;
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, var(--bg-panel), var(--bg-deep));
}

.prestige-branch-head h4 {
  margin: 0;
  color: var(--gold-bright);
  font-size: 0.84rem;
}

.prestige-branch-head p {
  margin: 0.15rem 0 0;
  color: var(--ink-dim);
  font-size: 0.72rem;
}

/* 분기별 노드는 길어질 수 있어 목록만 내부 스크롤한다(표면 무스크롤 계약). */
.prestige-branch-nodes {
  list-style: none;
  display: grid;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
  max-height: 12rem;
  overflow-y: auto;
}

.prestige-node {
  display: grid;
  gap: var(--gap-row);
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-card);
  background: var(--bg-slot);
}

.prestige-node.max { border-color: var(--gold-line-strong); }
.prestige-node.locked { opacity: 0.7; }

.prestige-node-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4rem;
}

.prestige-node-name { font-weight: 800; font-size: var(--fs-body); }
.prestige-node-level { color: var(--ink-dim); font-size: var(--fs-meta); }

.prestige-node-effect {
  margin: 0;
  color: var(--ink-soft);
  font-size: var(--fs-meta);
}

.prestige-node-lock {
  margin: 0;
  color: var(--ink-dim);
  font-size: var(--fs-micro);
}

.prestige-node button,
.prestige-tree-respec button,
.prestige-respec-confirm-actions button {
  /* 짧은 라벨('취소')도 44×44 터치 표면을 지킨다 — 폭까지 최소를 건다. */
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.45rem;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-weight: 800;
  font-size: 0.76rem;
  cursor: pointer;
}

#prestige-respec-cancel {
  border-color: var(--gold-line);
  background: transparent;
  color: var(--ink-soft);
}

.prestige-node button:disabled,
.prestige-tree-respec button:disabled,
.prestige-respec-confirm-actions button:disabled {
  border-color: var(--btn-disabled-bg);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.prestige-tree-status {
  min-height: 1.2em;
  margin: 0.5rem 0 0;
  color: var(--gold-bright);
  font-size: 0.8rem;
}

/* R2 전투 쥬스 — 화면 플래시·오프라인 복귀 카드·골드 롤링. 색은 공통 토큰만 쓴다. */
#screen-flash {
  position: fixed;
  inset: 0;
  z-index: 24;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(
    circle at 50% 55%,
    color-mix(in srgb, var(--flash-color, var(--gold)) 45%, transparent),
    transparent 62%
  );
}

#screen-flash[hidden] { display: none; }

#screen-flash.is-active {
  animation: screen-flash-pop var(--flash-duration, 420ms) ease-out both;
}

#screen-flash::after {
  content: attr(data-flash-glyph) " " attr(data-flash-label);
  position: absolute;
  top: calc(var(--hud-edge-top) + var(--hud-unit));
  left: 50%;
  padding: calc(var(--hud-unit) * 0.36) calc(var(--hud-unit) * 0.72);
  transform: translateX(-50%);
  border: 2px solid var(--flash-color, var(--gold));
  border-radius: var(--radius-slot);
  background: var(--bg-panel);
  color: var(--ink);
  font-size: calc(var(--hud-unit) * 0.86);
  font-weight: 900;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

#screen-flash.flash-level-up {
  --flash-color: var(--gold-bright);
}

#screen-flash.flash-promotion {
  --flash-color: var(--grade-epic);
}

#screen-flash.flash-synthesis {
  --flash-color: var(--info);
}

#screen-flash.flash-legendary {
  --flash-color: var(--grade-legendary);
}

#screen-flash.flash-boss-defeat {
  --flash-color: var(--danger);
}

#screen-flash.flash-epic-drop {
  --flash-color: var(--grade-epic);
}

@keyframes screen-flash-pop {
  0% { opacity: 0; }
  22% { opacity: 0.5; }
  100% { opacity: 0; }
}

/* 감소된 모션에서는 번쩍임 대신 아주 옅은 신호만 남긴다. */
html[data-reduced-motion="true"] #screen-flash.is-active {
  animation-duration: 120ms;
  animation-timing-function: linear;
}

html[data-reduced-motion="true"] #screen-flash {
  background: radial-gradient(
    circle at 50% 55%,
    color-mix(in srgb, var(--flash-color, var(--gold)) 18%, transparent),
    transparent 62%
  );
}

/* 골드 카운트 롤링 — 늘어나는 동안만 살짝 밝아진다. */
#gold.is-rolling {
  color: var(--gold-bright);
  text-shadow: 0 0 0.6rem var(--gold-glow);
}

/* 처치로 골드가 들어온 순간 — 카운터가 한 번 튄다(값은 원장이 정한다). */
#gold.is-kill-gain {
  color: var(--gold-bright);
  animation: gold-kill-gain 260ms ease-out;
}

@keyframes gold-kill-gain {
  0% { transform: scale(1); }
  35% { transform: scale(1.14); }
  100% { transform: scale(1); }
}

html[data-reduced-motion="true"] #gold.is-kill-gain {
  animation: none;
}

html[data-reduced-motion="true"] #gold.is-rolling {
  text-shadow: none;
}

/* 오프라인 복귀 보상 카드 — 타이틀의 단일 status 영역을 그대로 쓴다. */
#offline-banner {
  display: grid;
  gap: 0.55rem;
  text-align: left;
}

.offline-headline {
  margin: 0;
  color: var(--gold-bright);
  font-size: var(--fs-section);
  font-weight: 900;
  text-align: center;
}

.offline-rows {
  list-style: none;
  display: grid;
  gap: 0.3rem;
  margin: 0;
  padding: 0;
}

.offline-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.2rem;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-slot);
  background: var(--bg-slot);
  font-size: 0.86rem;
}

.offline-row-label { color: var(--ink-soft); font-weight: 700; }
.offline-row-value { color: var(--gold-bright); font-weight: 800; }

.offline-cap-note {
  margin: 0;
  color: var(--ink-dim);
  font-size: 0.74rem;
  font-weight: 600;
  text-align: center;
}

/* 카드 등장은 짧게 — 감소된 모션에서는 즉시 표시한다. */
#offline-banner:not([hidden]) {
  animation: offline-card-in 320ms ease-out both;
}

@keyframes offline-card-in {
  0% { opacity: 0; transform: translateY(0.5rem); }
  100% { opacity: 1; transform: none; }
}

html[data-reduced-motion="true"] #offline-banner:not([hidden]) {
  animation-duration: 1ms;
}

/* R3 보스 고유 기믹 — 발동 경고 배너. 색은 계열 변수로 받아 토큰만 쓴다. */
#boss-warning {
  position: absolute;
  z-index: 26;
  top: 22%;
  left: 50%;
  max-width: min(28rem, calc(100vw - 2rem));
  padding: 0.6rem 1.4rem;
  transform: translateX(-50%);
  pointer-events: none;
  border: 1px solid var(--mechanic-color, var(--gold));
  border-radius: 0.7rem;
  background: linear-gradient(180deg, var(--bg-panel), var(--bg-deep));
  box-shadow: 0 0.6rem 1.6rem rgb(var(--c-black) / 0.6), 0 0 1.2rem var(--gold-glow);
  color: var(--mechanic-color, var(--gold-bright));
  font-weight: 900;
  letter-spacing: 0.02em;
  text-align: center;
  text-shadow: 0 2px 5px rgb(var(--c-black) / 0.667);
  animation: boss-warning-in 320ms ease-out both;
}

#boss-warning[hidden] { display: none; }

@keyframes boss-warning-in {
  0% { opacity: 0; transform: translateX(-50%) translateY(-0.6rem) scale(0.94); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}

/* 감소된 모션에서는 문구만 남기고 등장 움직임을 없앤다. */
html[data-reduced-motion="true"] #boss-warning {
  animation-duration: 1ms;
}

/* 보스 컷인 — 지역 전용 보스 이름·칭호를 진입 순간에 한 번 세운다(표시 전용).
   보스 경고 배너보다 위(z 27)에 서고, 포인터·탭 순서는 잡지 않는다. */
#boss-cutin {
  /* 좌우 인셋으로 폭을 잡는다 — :root 전역 box-sizing이 없어 width:100%+패딩은 넘친다. */
  position: absolute;
  z-index: 27;
  top: 38%;
  right: 0;
  left: 0;
  display: grid;
  box-sizing: border-box;
  justify-items: center;
  gap: calc(var(--hud-unit) * 0.2);
  padding: calc(var(--hud-unit) * 0.7) calc(var(--hud-unit) * 0.6);
  pointer-events: none;
  border-top: 1px solid var(--boss-tier-color, var(--gold));
  border-bottom: 1px solid var(--boss-tier-color, var(--gold));
  background: linear-gradient(
    90deg,
    rgb(var(--c-deep) / 0) 0%,
    rgb(var(--c-deep) / 0.88) 18%,
    rgb(var(--c-deep) / 0.92) 50%,
    rgb(var(--c-deep) / 0.88) 82%,
    rgb(var(--c-deep) / 0) 100%
  );
  text-align: center;
  text-shadow: 0 2px 6px rgb(var(--c-black) / 0.7);
}

#boss-cutin[hidden] { display: none; }

#boss-cutin p { margin: 0; }

#boss-cutin-region {
  color: var(--ink-dim);
  font-size: calc(var(--hud-unit) * 0.62);
  letter-spacing: 0.16em;
}

#boss-cutin-name {
  color: var(--ink);
  font-size: calc(var(--hud-unit) * 1.5);
  font-weight: 900;
  line-height: 1.1;
  letter-spacing: 0.04em;
}

#boss-cutin-title {
  color: var(--boss-tier-color, var(--gold-bright));
  font-size: calc(var(--hud-unit) * 0.72);
  letter-spacing: 0.1em;
}

#boss-cutin-tier {
  padding: 0 calc(var(--hud-unit) * 0.4);
  border: 1px solid var(--boss-tier-color, var(--gold));
  border-radius: 999px;
  color: var(--boss-tier-color, var(--gold-bright));
  font-size: calc(var(--hud-unit) * 0.56);
  font-weight: 700;
  letter-spacing: 0.14em;
}

/* 이름은 옆에서 밀려 들어오고 띠는 가로로 열린다 — 진입 데(2.2초) 안에서 끝난다. */
#boss-cutin.is-active {
  animation: boss-cutin-band var(--boss-cutin-duration, 2000ms) ease-out both;
}

#boss-cutin.is-active #boss-cutin-name {
  animation: boss-cutin-name var(--boss-cutin-duration, 2000ms) ease-out both;
}

@keyframes boss-cutin-band {
  0% { opacity: 0; transform: scaleX(0.2); }
  12% { opacity: 1; transform: scaleX(1); }
  82% { opacity: 1; transform: scaleX(1); }
  100% { opacity: 0; transform: scaleX(1); }
}

@keyframes boss-cutin-name {
  0% { opacity: 0; transform: translateX(-8%); letter-spacing: 0.3em; }
  18% { opacity: 1; transform: translateX(0); letter-spacing: 0.04em; }
  100% { opacity: 1; transform: translateX(0); letter-spacing: 0.04em; }
}

/* 모션 최소화 — 이름·칭호는 그대로 두고 움직임만 없앤다(정보는 남는다). */
html[data-reduced-motion="true"] #boss-cutin.is-active,
#boss-cutin.is-reduced.is-active,
html[data-reduced-motion="true"] #boss-cutin.is-active #boss-cutin-name,
#boss-cutin.is-reduced.is-active #boss-cutin-name {
  animation: none;
  opacity: 1;
  transform: none;
}

/* R4 시즌·이벤트 — 아레나 시즌 영역과 골드 러시 배너. 공통 토큰만 쓴다. */
#arena-season-countdown { color: var(--ink-dim); }

/* 시즌은 세 열 위에 한 줄로 걸쳐 다른 열 높이를 밀지 않는다. */
.arena-season {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-content: start;
  align-items: center;
  gap: 0.5rem 1rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, var(--bg-panel), var(--bg-deep));
}

.arena-season > .hiring-section-head {
  grid-column: 1 / -1;
  margin-bottom: 0;
}

.arena-season[hidden] { display: none; }

#arena-season-tier {
  margin: 0;
  color: var(--season-tier-color, var(--gold-bright));
  font-size: 0.82rem;
  font-weight: 800;
}

.arena-season-last {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.8rem;
}

/* 시즌 보상 카드 — 수령 가능할 때만 금색으로 튄다. */
.arena-season-reward {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.7rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-card);
  background: var(--bg-slot);
}

.arena-season-reward[hidden] { display: none; }

.arena-season-reward.ready {
  border-color: var(--gold-line-strong);
  box-shadow: 0 0 0.8rem var(--gold-glow);
}

.arena-season-reward.claimed { opacity: 0.65; }

.arena-season-reward-copy {
  display: grid;
  gap: 0.15rem;
  min-width: 0;
}

.arena-season-reward-copy strong {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

#arena-season-reward-value {
  color: var(--gold-bright);
  font-size: 0.78rem;
  font-weight: 700;
}

#arena-season-claim {
  min-height: var(--tap-min);
  min-width: 5.5rem;
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--gold-line-strong);
  border-radius: 0.5rem;
  background: var(--btn-gold);
  color: var(--ink-on-gold);
  font: inherit;
  font-weight: 800;
  font-size: 0.82rem;
  white-space: nowrap;
  cursor: pointer;
}

#arena-season-claim:disabled {
  border-color: var(--btn-disabled-bg);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

#arena-season-claim:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

/* 골드 러시 HUD 배너 — 상단 중앙, 전투를 가리지 않는 얇은 띠. */
#gold-rush-banner {
  position: absolute;
  z-index: 25;
  top: 12%;
  left: 50%;
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  max-width: min(24rem, calc(100vw - 2rem));
  padding: 0.45rem 1.1rem;
  transform: translateX(-50%);
  pointer-events: none;
  border: 1px solid var(--gold-line-strong);
  border-radius: 999px;
  background: linear-gradient(180deg, var(--bg-panel), var(--bg-deep));
  box-shadow: 0 0.5rem 1.4rem rgb(var(--c-black) / 0.6), 0 0 1.2rem var(--gold-glow);
  color: var(--gold-bright);
  font-weight: 900;
  text-shadow: 0 2px 5px rgb(var(--c-black) / 0.667);
  animation: gold-rush-pulse 2.4s ease-in-out infinite;
}

#gold-rush-banner[hidden] { display: none; }

.gold-rush-remaining {
  color: var(--ink-soft);
  font-size: 0.78rem;
  font-weight: 700;
}

@keyframes gold-rush-pulse {
  0%, 100% { box-shadow: 0 0.5rem 1.4rem rgb(var(--c-black) / 0.6), 0 0 1.2rem var(--gold-glow); }
  50% { box-shadow: 0 0.5rem 1.4rem rgb(var(--c-black) / 0.6), 0 0 2rem var(--gold-line-strong); }
}

/* 감소된 모션에서는 문구만 남기고 맥동을 멈춘다. */
html[data-reduced-motion="true"] #gold-rush-banner {
  animation: none;
}

/*
 * 글로벌 채팅 + 획득 피드.
 * 채팅 오버레이는 내부에서만 스크롤하고, 표면 미니 피드는 고정 높이로 떠 있다가 사라진다.
 */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.chat-panel {
  width: var(--overlay-w-sm);
  max-height: var(--overlay-h-sm);
}

#chat-connection {
  color: var(--ink-dim);
  font-size: 0.82rem;
  font-weight: 700;
}

#chat-connection[data-state="online"] { color: var(--ok); }
#chat-connection[data-state="offline"] { color: var(--danger); }

/* 로그만 스크롤한다 — 표면과 패널 프레임은 스크롤하지 않는다. */
.chat-log {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin: 0;
  padding: 0.9rem 1.15rem;
  /*
   * 12rem 고정 하한이던 시절, 짧은 화면(가로 모드 874×292 실측)에서 로그가 줄지 않아
   * 패널이 118px 넘쳤고 clip에 잘려 입력창과 보내기 버튼이 통째로 사라졌다.
   * 기본 크기는 12rem으로 두되 줄어들 수 있게 flex-basis로 바꾼다.
   */
  flex: 1 1 12rem;
  min-height: 0;
  max-height: min(52vh, 26rem);
  overflow-y: auto;
  list-style: none;
  overscroll-behavior: contain;
}

.chat-empty {
  margin: auto;
  color: var(--ink-dim);
  font-size: 0.85rem;
  text-align: center;
}

.chat-line {
  display: flex;
  gap: 0.45rem;
  align-items: baseline;
  font-size: 0.88rem;
  line-height: 1.45;
  overflow-wrap: anywhere;
}

.chat-line .chat-time {
  flex: 0 0 auto;
  color: var(--ink-dim);
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
}

.chat-line .chat-name {
  flex: 0 0 auto;
  color: var(--gold-bright);
  font-weight: 800;
}

.chat-line .chat-text {
  color: var(--ink);
}

.chat-system {
  padding: 0.15rem 0.4rem;
  border-left: 2px solid var(--info);
  background: rgb(var(--c-info) / 0.078);
}

.chat-system .chat-name { color: var(--info); }
.chat-system .chat-text { color: var(--ink-soft); }

.chat-form {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  padding: 0 1.15rem 0.35rem;
}

#chat-send {
  flex: 0 0 auto;
  min-height: var(--tap-min);
  padding: 0 0.9rem;
  border: 1px solid var(--gold-line);
  border-radius: var(--radius-slot);
  background: var(--btn-navy);
  color: var(--gold-bright);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

#chat-send:hover,
#chat-send:focus-visible {
  border-color: var(--gold);
}

#chat-send:disabled {
  border-color: var(--line-disabled);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.chat-form input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: var(--tap-min);
  padding: 0 0.7rem;
  border: var(--border-soft);
  border-radius: var(--radius-slot);
  background: var(--bg-slot);
  color: var(--ink);
  font: inherit;
}

.chat-form input:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 1px;
}

.chat-count {
  flex: 0 0 auto;
  color: var(--ink-dim);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}

/* 메시지 옆 ⋯ — 신고·뮤트 시트를 여는 유일한 포인터 진입점(길게 누르기·우클릭과 동치).
   메시지 줄 높이(밀도)가 우선이라 겉 크기는 1.5rem으로 두고, 히트 영역만 ::after로
   --tap-min까지 넓힌다. */
.chat-menu-button {
  position: relative;
  flex: 0 0 auto;
  margin-left: auto;
  padding: 0 0.3rem;
  min-width: 1.5rem;
  min-height: 1.5rem;
  border: 0;
  border-radius: var(--radius-slot);
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  line-height: 1;
  cursor: pointer;
}

/* 보이지 않는 확장 히트 영역 — 겉 크기를 키우지 않고 44px 터치 표면만 만든다. */
.chat-menu-button::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  width: 100%;
  height: 100%;
}

.chat-menu-button:hover,
.chat-menu-button:focus-visible {
  color: var(--gold-bright);
  background: rgb(var(--c-gold-warm) / 0.067);
}

.chat-menu-button:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 1px;
}

/* 패널 안에 떠서 로그 위에 겹친다 — 표면 레이아웃을 밀지 않는다. */
.chat-context {
  position: absolute;
  z-index: 3;
  right: 1.15rem;
  bottom: 4.4rem;
  display: grid;
  gap: 0.5rem;
  padding: 0.7rem 0.8rem;
  width: min(16rem, calc(100% - 2.3rem));
  border: 1px solid var(--gold-line-strong);
  border-radius: var(--radius-panel);
  background: rgb(var(--c-deep) / 0.98);
  box-shadow: var(--shadow-panel);
}

.chat-context[hidden] { display: none; }

.chat-context-title {
  margin: 0;
  color: var(--gold-bright);
  font-size: 0.82rem;
  font-weight: 800;
  overflow-wrap: anywhere;
}

.chat-context-select {
  min-height: var(--tap-min);
  padding: 0 0.5rem;
  border: var(--border-soft);
  border-radius: var(--radius-slot);
  background: var(--bg-slot);
  color: var(--ink);
  font: inherit;
}

.chat-context-actions {
  display: flex;
  gap: 0.4rem;
}

.chat-context-actions button {
  flex: 1 1 0;
  min-height: var(--tap-min);
  font-size: 0.8rem;
}

.chat-context-select:focus-visible,
.chat-context-actions button:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 1px;
}

/* 로그 한 줄(획득 피드) — 채팅 안과 미니 피드가 같은 형태를 쓴다. */
.feed-line {
  display: flex;
  gap: 0.45rem;
  align-items: baseline;
  color: var(--ink-soft);
  font-size: 0.85rem;
  line-height: 1.45;
  overflow-wrap: anywhere;
}

.feed-line .feed-text { color: inherit; }

.chat-log .feed-line {
  padding-left: 0.4rem;
  border-left: 2px solid currentColor;
}

/* 표면 미니 피드 — 고정 높이, 스크롤 없음, 클릭은 아래 전투 화면으로 통과시킨다. */
#mini-feed {
  position: absolute;
  z-index: 24;
  /* 파티 초상 띠 바로 위에 눕는다 — 띠 높이가 유동이라 겹칠 여지가 없다. */
  bottom: calc(var(--hud-bottom-zone) + var(--hud-gap));
  left: var(--hud-edge-left);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--hud-gap-tight);
  width: min(22rem, 46vw);
  height: clamp(2.6rem, 14svh, 5.6rem);
  overflow: hidden;
  pointer-events: none;
}

#mini-feed .feed-line {
  padding: calc(var(--hud-unit) * 0.1) calc(var(--hud-unit) * 0.42);
  border-radius: var(--hud-radius);
  background: rgb(var(--c-scrim) / 0.651);
  font-size: var(--hud-fs-sm);
  font-weight: 700;
  text-shadow: 0 2px 5px rgb(var(--c-black) / 0.667);
  animation: mini-feed-in 220ms ease-out both;
}

#mini-feed .feed-line[data-fading="true"] {
  opacity: 0.35;
  transition: opacity 400ms ease-in;
}

@keyframes mini-feed-in {
  from { opacity: 0; transform: translateY(0.4rem); }
  to { opacity: 1; transform: none; }
}

/* 모션 최소화에서는 미니 피드가 움직이지 않고 그대로 떴다 사라진다. */
html[data-reduced-motion="true"] #mini-feed .feed-line {
  animation: none;
  transition: none;
}

/* 새 채팅은 수령 배지와 구분되는 작은 점으로만 알린다. */
#menu-open.has-chat-unread::after {
  content: '';
  position: absolute;
  right: 0.35rem;
  bottom: 0.35rem;
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 999px;
  background: var(--info);
  box-shadow: 0 0 0.4rem var(--info);
}

/* 티어 배지 — 등급색 테두리 안에 T1~T10을 작게 얹는다. */
.tier-badge {
  flex: 0 0 auto;
  padding: 0 0.3rem;
  border: 1px solid currentColor;
  border-radius: 0.35rem;
  color: var(--card-grade, var(--grade-normal));
  font-size: 0.68rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
}

.equipment-cell .cell-name .tier-badge {
  margin-right: 0.15rem;
}

/* 합성 선택 진행도 — 재료 10칸을 채우는 동안 남은 수를 같이 보여 준다. */
#equipment-synthesis-auto {
  min-height: var(--tap-min);
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--gold-line);
  border-radius: 0.5rem;
  background: var(--btn-navy);
  color: var(--ink);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

#equipment-synthesis-auto:disabled {
  border-color: var(--line-disabled);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

/*
 * 월드맵 — 지역 10 노드와 선택 지역의 스테이지 20칸.
 * 패널 안쪽만 스크롤하고 표면은 그대로 둔다. 지역색은 --region-color로 받는다.
 */
.map-panel {
  width: var(--overlay-w-lg);
  max-height: var(--overlay-h);
}

#map-summary {
  color: var(--ink-soft);
  font-weight: 700;
}

.map-body {
  display: grid;
  gap: var(--gap-panel);
  padding: var(--pad-body);
  min-height: 0;
  overflow-y: auto;
  /* 늘어지면(align-content: stretch) 지역·스테이지 칸 사이가 빈 밴드로 찢어진다 — 위로 붙인다. */
  align-content: start;
}

.map-region-detail {
  margin: 0;
  color: var(--ink-dim);
  font-size: 0.82rem;
}

/* 지역 노드는 폭 패치 없이 칸 최소 폭만으로 열 수를 정한다(390px에서도 두 열). */
.region-nodes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(7rem, 100%), 1fr));
  gap: 0.5rem;
}

.region-node {
  display: grid;
  gap: 0.15rem;
  min-height: var(--tap-min);
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--region-color, var(--gold-line));
  border-left: 4px solid var(--region-color, var(--gold));
  border-radius: var(--radius-card);
  background: linear-gradient(180deg, rgb(var(--c-panel) / 0.902), rgb(var(--c-deep) / 0.941));
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.region-node .region-name {
  color: var(--region-color, var(--ink));
  font-weight: 800;
  font-size: 0.9rem;
}

.region-node .region-meta {
  color: var(--ink-dim);
  font-size: 0.74rem;
  font-variant-numeric: tabular-nums;
}

.region-node.is-locked {
  border-color: var(--line-disabled);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.region-node.is-locked .region-name { color: var(--btn-disabled-ink); }

.region-node.is-current,
.region-node[aria-pressed="true"] {
  box-shadow: 0 0 0 2px var(--gold) inset;
}

.region-stages {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(3.1rem, 1fr));
  gap: 0.35rem;
}

.stage-cell {
  min-height: var(--tap-min);
  padding: 0.3rem;
  border: 1px solid var(--line-disabled);
  border-radius: var(--radius-slot);
  background: var(--bg-slot);
  color: var(--ink-soft);
  font: inherit;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.stage-cell.is-locked {
  border-color: var(--line-disabled);
  background: var(--btn-disabled-bg);
  color: var(--btn-disabled-ink);
  cursor: default;
}

.stage-cell.is-boss {
  border-color: var(--gold-line);
  color: var(--gold-bright);
}

.stage-cell.is-boss-grand {
  border-color: var(--gold-line-strong);
  box-shadow: 0 0 0.5rem var(--gold-glow) inset;
}

.stage-cell.is-frontier {
  border-color: var(--info);
  color: var(--info);
}

.stage-cell.is-current {
  border-color: var(--gold);
  background: var(--btn-navy);
  color: var(--gold-bright);
  box-shadow: 0 0 0 2px var(--gold) inset;
}

.stage-cell:disabled { cursor: default; }

/* 효과음 볼륨 슬라이더 — 설정 줄 토큰을 그대로 쓰고 트랙·썸만 금색으로 맞춘다. */
#settings-sfx-volume {
  flex: 1 1 auto;
  max-width: 12rem;
  min-height: var(--tap-min);
  accent-color: var(--gold);
  background: transparent;
  cursor: pointer;
}

#settings-sfx-volume:disabled {
  cursor: not-allowed;
  opacity: 0.45;
}

#settings-sfx-volume:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

/*
 * 오버레이 내부 구조 전환 — 뷰포트가 아니라 "패널 자신의 폭"으로 판단한다.
 * 패널 폭은 이미 --overlay-w-* 토큰이 뷰포트 비례로 정하므로, 여기서 다시 뷰포트
 * 브레이크포인트를 늘어놓을 이유가 없다. 이 컨테이너 질의 두 벌이 예전
 * 1100/1000/900/620/480px 다섯 곳의 폭 패치를 전부 대신한다.
 */
.hiring-panel,
.equipment-panel,
.arena-panel,
.tower-panel,
.shop-panel,
.prestige-panel,
.collection-panel {
  container-type: inline-size;
  container-name: overlay;
}

/* 3단 배치(아레나·타워)는 더 일찍 접힌다 — 칸마다 목록이 들어 있기 때문이다. */
@container overlay (max-width: 56rem) {
  .arena-body,
  .tower-body {
    grid-template-columns: 1fr;
  }

  /*
   * 3단이 접히면 본문 한 겹만 스크롤한다 — 칸마다 있던 안쪽 목록 스크롤을 본문에 넘긴다.
   * 넓을 때는 반대로 각 칸이 자기 목록을 스크롤하고(.tower-body는 overflow: hidden)
   * 머리말·푸터가 고정된다. 좁아질수록 스크롤이 한 겹 줄어드는 방향이라
   * 48rem 규칙(도감·장비·환생)·560px 전체 화면 규칙과 같다.
   */
  .tower-body {
    overflow-y: auto;
    /* 늘어지면 도전 칸과 층 칸 사이가 빈 밴드로 찢어진다 — 위로 붙인다. */
    align-content: start;
  }

  /*
   * 1단으로 접히면 칸 높이는 내용이 정한다. 3단 전용으로 걸어 둔 min-height: 0
   * (안쪽 목록 스크롤용)이 그대로면 스크롤 그리드의 auto 트랙이 내용 대신
   * min-content로 눌려, visible로 풀린 층 목록(322px)이 아래 랭킹 칸 위로 새어
   * 겹쳐 그어졌다(844×390 실측 — 칸 83px·목록 50px로 압축). min-height를 auto로
   * 돌려 두 단계(본문>칸, 칸>목록) 모두 내용 높이를 보장하고, 1fr 행도 접는다
   * (넓을 때 .tower-challenge-panel이 하던 모양).
   */
  .tower-body > section {
    grid-template-rows: none;
    align-content: start;
    min-height: auto;
  }

  .tower-floors,
  .tower-ranking-list {
    min-height: auto;
    max-height: none;
    /* overflow-y만 visible로 두면 overflow-x: auto와 만나 다시 auto로 계산된다. */
    overflow: visible;
  }
}

/* 2단 배치(장비·상점·도감)와 카드 격자는 패널이 좁아지는 만큼만 접힌다. */
@container overlay (max-width: 44rem) {
  .equipment-body,
  .shop-body,
  .collection-body {
    grid-template-columns: 1fr;
  }

  /* 후보·인벤토리 칸 수는 칸 최소 폭이 정한다 — 3→2→1 폭 패치가 사라진다. */
  .hiring-candidates {
    grid-template-columns: repeat(auto-fit, minmax(min(9.5rem, 100%), 1fr));
  }

  .equipment-grid {
    grid-template-columns: repeat(auto-fill, minmax(min(4.4rem, 100%), 1fr));
  }

  /*
   * 헤더 요약은 수집 현황 칩이 같은 값을 그대로 들고 있다 — 좁은 패널에서는
   * nowrap+ellipsis 계약(.hiring-header-meta)이 숫자 중간을 "···"로 잘라
   * 보스 총계가 깨져 보이므로, 붙는 지점부터는 칩에 맡기고 숨긴다.
   */
  #collection-summary {
    display: none;
  }
}

/*
 * 좁은 패널에서는 본문 한 겹만 스크롤한다 — 안쪽 목록이 자기 스크롤을 본문에 넘긴다.
 * 계약상 오버레이 내부 목록의 내부 스크롤은 허용이지만, 패널이 좁아지면 본문 스크롤과
 * 두 겹으로 겹쳐 조작을 방해한다(844×390에서 도감·장비·환생 세 곳 모두 두 겹 실측).
 * 판단 기준은 뷰포트가 아니라 패널 폭이다 — 도감·장비 패널은 44.9rem, 환생 패널은
 * 28.1rem으로 줄어드는 지점이라 48rem 하나로 세 곳이 함께 걸린다.
 * 560px 전체 화면 규칙이 같은 취지로 하는 일을, 여기서는 패널 폭 기준으로 한다.
 */
@container overlay (max-width: 48rem) {
  .collection-grid,
  .equipment-grid,
  .prestige-branch-nodes {
    max-height: none;
    /* overflow-y만 visible로 두면 overflow-x: auto와 만나 다시 auto로 계산된다. */
    overflow: visible;
  }
}

/*
 * 좁은 화면 전체 화면 계약 — docs/design/mobile-menu-ux-v1.md §3, responsive-ui-v1.md §4.2.
 *
 * (1) 대상: MODAL_IDS 오버레이 **전부**. 목록형 8종만 걸던 옛 규칙을 걷어내고
 *     `.modal-backdrop`과 그 자식 패널 하나로 잡는다 — 셀렉터에 이름을 21개 늘어놓지
 *     않으므로, 새 오버레이도 같은 마크업(백드롭 > 패널)만 쓰면 자동으로 이 계약을 탄다.
 * (2) 판정 축: 폭·높이 둘 다. 옛 규칙은 폭 560px 하나여서 가로 모드 폰(844×390)이
 *     카드로 남았는데, 그쪽이 오히려 더 좁다(본문 높이 304px). 어느 한 축이라도
 *     560px 이하면 카드를 그만두고 화면을 다 쓴다.
 * (3) 확인 다이얼로그·픽커처럼 본문이 짧은 오버레이는 전체 화면이 되면 아래가 텅 빈다.
 *     전체 화면은 유지하되 본문은 위로 붙이고 마지막 줄(푸터·상태)을 바닥에 못 박아
 *     주 액션을 엄지 존에 둔다 — 빈 자리는 본문과 액션 사이로 간다.
 */
@media (max-width: 560px), (max-height: 560px) {
  .modal-backdrop {
    padding: 0;
    place-items: stretch;
  }

  .modal-backdrop > * {
    /*
     * 세이프 에어리어는 패널이 네 방향 모두 먹는다 — 헤더는 상단 인셋 아래,
     * 푸터는 하단 인셋 위로 밀린다. 가로 모드 노치는 좌·우로 오므로 네 방향이 다 필요하다.
     * :root에 전역 box-sizing이 없어 여기서 border-box를 직접 건다(안 그러면 100dvh를 넘친다).
     */
    box-sizing: border-box;
    width: 100vw;
    max-width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    padding:
      env(safe-area-inset-top, 0px)
      env(safe-area-inset-right, 0px)
      env(safe-area-inset-bottom, 0px)
      env(safe-area-inset-left, 0px);
    border: 0;
    border-radius: 0;
  }

  /* 전체 화면에서는 모서리 장식이 화면 모서리와 겹쳐 지저분해진다. */
  .modal-backdrop > *::before,
  .modal-backdrop > *::after {
    display: none;
  }

  /* 마지막 줄(푸터·상태 문구)을 바닥에 붙인다 — 위 (3). */
  .modal-backdrop > * > footer:last-child,
  .modal-backdrop > * > .hiring-status:last-child {
    margin-top: auto;
  }

  /* 하단 인셋은 패널이 이미 먹었다 — 푸터가 또 먹으면 두 번 들어간다. */
  .panel-footer {
    padding-bottom: 0.6rem;
  }

  /* 확인 다이얼로그 본문도 넘치면 스스로 스크롤한다(패널은 clip이라 그냥 잘린다). */
  .promotion-body {
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  /* 세로 1축 원칙 — 안쪽 목록 스크롤을 풀어 본문 스크롤 하나로 합친다.
   * 전체 화면에서는 본문이 이미 화면 높이를 다 쓰므로 이중 스크롤이 조작을 방해한다. */
  .tower-floors,
  .tower-ranking-list,
  .equipment-grid,
  .collection-grid,
  .prestige-branch-nodes,
  .settings-mute-list {
    max-height: none;
    /* overflow-y만 visible로 두면 overflow-x: auto와 만나 다시 auto로 계산된다. */
    overflow: visible;
  }

  /* 로그는 화면 높이를 다 쓴다 — 26rem 상한이 남으면 입력창 아래가 빈다. */
  .chat-log {
    max-height: none;
  }

  /*
   * 메뉴 항목 상하 패딩만 접는다 — 가로 모드(본문 ~236px)에서 4행 격자+환생 카드가
   * 한 화면에 들어오게 한다. 패딩을 그대로 두면 격자가 17px 넘쳐 마지막 행이
   * 환생 카드에 가려진 채 초기 화면에 잘려 나왔다(844×390 실측). 최소 터치 44px은 유지.
   */
  .menu-item {
    padding-block: 0.2rem;
  }
}
