/* 모달 — 공통 껍데기(js/modal.js). 카드 자체는 .panel 의 유리 재질을 그대로 쓴다. */

/* dialog 를 뷰포트 전체로 깐다. 배경 클릭 판정(event.target === dialog)이 성립하는 조건이고,
   카드 세로 가운데 정렬도 여기서 끝난다. 네이티브 dialog 의 기본 여백·테두리·배경을 모두
   지워야 하는데, 특히 max-width/max-height 기본값(calc(100% - 6px - 2em))을 안 지우면
   폭 좁은 화면에서 카드가 어긋난다. */
.modal-host {
  position: fixed;
  inset: 0;
  width: 100%;
  max-width: 100%;
  height: 100%;
  max-height: 100%;
  margin: 0;
  padding: 20px;
  border: 0;
  background: transparent;
  overflow: auto;
  display: grid;
  place-items: center;
}
.modal-host::backdrop {
  background: rgba(6, 5, 12, 0.62);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

/* place: 'side' — 참여 관리처럼 뒤 화면을 계속 참조해야 하는 모달. 카드를 우하단에 붙이고
   스크림에서 blur 를 뺀다. blur 를 남기면 12px 본문이 무너져 정원 n/100 을 읽을 수 없고,
   그러면 비중앙 배치를 할 이유 자체가 사라진다. 아래 값에서 뒤 본문 대비가 약 4.8:1 남는다. */
.modal-host-side {
  place-items: end;
  backdrop-filter: none;
}
.modal-host-side::backdrop {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background: linear-gradient(180deg,
    rgba(7, 6, 14, 0.30) 0%, rgba(7, 6, 14, 0.48) 24%, rgba(7, 6, 14, 0.52) 100%);
}

.modal {
  width: 100%;
  /* 유리 위에 유리를 겹치면 뒤 명단이 비쳐 글자가 읽히지 않는다. 모달만 불투명 면을 쓴다. */
  background: var(--panel-solid);
  box-shadow: var(--shadow);
  display: grid;
  /* 머리·본문·바닥 3행. 본문만 늘어나고 줄어들어야 스크롤이 본문 안에서 생긴다. */
  grid-template-rows: auto minmax(0, 1fr) auto;
  max-height: calc(100vh - 40px);
  animation: modal-in 180ms cubic-bezier(0.2, 0.7, 0.3, 1);
}
.modal-sm { max-width: 380px; }
.modal-md { max-width: 540px; }
.modal-lg { max-width: 900px; }

@keyframes modal-in {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
}

/* 저장 중. 컨트롤은 js 가 disabled 로 잠그고, 여기서는 그 상태가 눈에 보이게만 한다. */
.modal.is-busy { cursor: progress; }

.modal-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 20px 20px 14px;
  border-bottom: 1px solid var(--edge-soft);
}
.modal-titles { flex: 1; min-width: 0; }
.modal-title { font-size: 16px; }
.modal-sub { margin: 4px 0 0; color: var(--sub); font-size: 12.5px; }

.modal-x {
  flex: none;
  width: 30px;
  height: 30px;
  margin: -4px -4px 0 0;
  border: 1px solid transparent;
  border-radius: var(--radius-slot);
  background: transparent;
  color: var(--sub);
  font-size: 18px;
  line-height: 1;
  transition: color 160ms ease, background 160ms ease;
}
.modal-x:hover { background: rgba(255, 255, 255, 0.06); color: var(--ink); }

.modal-body { padding: 16px 20px; overflow: auto; }
.modal-body > :first-child { margin-top: 0; }
.modal-body > :last-child { margin-bottom: 0; }

.modal-foot {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 14px 20px 18px;
  border-top: 1px solid var(--edge-soft);
}

/* 모달 안의 실패 안내. 색은 .login-error 와 같은 값을 쓴다 — 같은 뜻의 줄이 화면마다
   다른 붉은색이면 사용자가 둘을 다른 상태로 읽는다. --panel-solid 대비 8.44:1. */
.modal-error { margin: 0; color: #F5A6A6; font-size: 12.5px; }

.pin-fields { display: grid; gap: 14px; }

/* 되돌릴 수 없는 동작. 액센트를 쓰지 않고 테두리 한 겹으로만 구분한다 — 스펙 9절의
   글로우 허용 지점 다섯 곳에 버튼은 없다. */
.btn-danger {
  border-color: rgba(245, 166, 166, 0.45);
  background: rgba(245, 166, 166, 0.09);
  color: #F5A6A6;                    /* --panel-solid(#15131F) 대비 8.44:1 */
}
.btn-danger:hover { background: rgba(245, 166, 166, 0.16); }

@media (max-width: 720px) {
  /* 모바일에서는 바닥에 붙는 시트. 엄지로 닿는 자리에 버튼이 온다. */
  .modal-host { padding: 0; place-items: end stretch; }
  .modal {
    max-width: none;
    max-height: 88vh;
    border-radius: var(--radius-panel) var(--radius-panel) 0 0;
    animation-name: sheet-in;
  }
  .modal-foot { padding-bottom: max(18px, env(safe-area-inset-bottom)); }
}
@keyframes sheet-in {
  from { transform: translateY(16px); }
}

/* ── 참여 관리·캐릭터 교체(js/modal-participate.js).
   카드·스크림·바닥 테두리는 위 껍데기가 이미 맡는다 — 여기에는 본문 격자만 둔다.
   .pm-list 에 max-height 를 걸지 않는 이유: 스크롤은 .modal-body 한 곳에서만 생겨야 한다. */

/* place: 'side' 가 존재하는 이유는 뒤 컬럼의 정원 n/100 을 읽으면서 조작하기 위해서다.
   그런데 캐릭터가 12개만 돼도 카드가 695px 로 자라 위쪽 .col-cap(y≈185~205) 을 덮는다 —
   덮는 순간 비중앙 배치의 근거가 통째로 사라지므로, 컬럼 헤더 줄을 비워 두고 본문이 먼저
   스크롤되게 카드 높이를 자른다. 720px 이하는 하단 시트라 해당 없다. */
@media (min-width: 721px) {
  .modal-host-side .modal { max-height: calc(100vh - 250px); }
}

/* 이 한 문장이 앱 전체의 상호작용을 설명한다. 가장 흐린 글씨로 두지 않는다. */
.pm-hint {
  margin: 0 0 12px;
  padding: 9px 12px;
  border-left: 2px solid rgba(107, 227, 245, 0.5);
  border-radius: 0 8px 8px 0;
  background: rgba(255, 255, 255, 0.03);
  color: var(--sub);
  font-size: 12.5px;
}

.pm-list, .pm-picks { list-style: none; margin: 0; padding: 0; }
.pm-list { border-top: 1px solid var(--edge-soft); }
.pm-picks { display: grid; gap: 2px; }

/* 참여 행과 교체 후보 행이 같은 6열 격자를 쓴다 — 전투력·아이템레벨이 두 화면에서 같은
   자리에 와야 지금 자리의 캐릭터와 눈으로 비교된다. 첫 열은 체크박스(18px)와 역할 글자를
   함께 담는다. */
.pm-row label, .pm-pick {
  position: relative;
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) 76px 44px 62px 54px;
  column-gap: 10px;
  align-items: center;
  width: 100%;
  padding: 9px 8px;
  border: 0;
  border-radius: 9px;
  background: none;
  text-align: left;
  cursor: pointer;
}
.pm-row label:hover, .pm-pick:hover { background: rgba(255, 255, 255, 0.035); }
.pm-row.is-on label { background: rgba(255, 255, 255, 0.055); }
.pm-row.is-locked label { cursor: default; }
.pm-row.is-locked .pm-name, .pm-row.is-locked .pm-box { opacity: 0.45; }

/* 커스텀 체크박스 — 네이티브 input 은 접근성을 위해 남기고 시각만 대체한다 */
.pm-check { position: absolute; width: 18px; height: 18px; margin: 0; opacity: 0; }
.pm-box {
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(255, 255, 255, 0.24);
  border-radius: 6px;
  font-size: 12px;
  line-height: 1;
  color: transparent;
  transition: background 140ms ease, border-color 140ms ease;
}
.pm-row.is-on .pm-box {
  border-color: rgba(107, 227, 245, 0.6);
  background: rgba(107, 227, 245, 0.14);
  color: var(--ether);
  box-shadow: 0 0 10px -2px rgba(107, 227, 245, 0.7);
}
.pm-check:focus-visible + .pm-box { outline: 2px solid var(--ether); outline-offset: 2px; }

/* 직업 — 색 단독 인코딩 금지(스펙 9절)라 앞 글자를 함께 둔다. 색은 app.css 의 --cls-* 이고,
   그 값들은 지면(#0B0A14) 기준으로 골랐다. 모달 카드는 --panel-solid(#15131F)로 한 단 밝아
   대비가 조금 내려가지만 가장 빡빡한 정령성도 5.3:1 로 AA 를 넘는다. */
.pm-mark { font-size: 12px; font-weight: 600; letter-spacing: 0.02em; color: var(--cls, var(--cls-etc)); }

.pm-name {
  min-width: 0;
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pm-row:not(.is-on) .pm-name { color: var(--quiet); font-weight: 500; }
.pm-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 6px;
  border: 1px solid rgba(166, 107, 245, 0.4);
  border-radius: 5px;
  color: var(--amethyst);
  font-size: 12px;
  font-weight: 500;
  vertical-align: 1px;
}
.pm-class { font-size: 12.5px; color: var(--sub); }
.pm-lv { font-size: 12px; color: var(--sub); }
.pm-num { text-align: right; font-size: 12.5px; font-weight: 500; letter-spacing: -0.02em; }
.pm-num.pm-il { font-weight: 400; color: var(--sub); }
.pm-none, .pm-note { margin: 12px 0 0; color: var(--sub); font-size: 12.5px; }
.pm-note { color: var(--amethyst); }

/* .modal-foot 은 flex-end 다. 사용량은 왼쪽 끝에 남겨 두고 버튼만 오른쪽으로 몬다. */
.pm-usage { margin: 0 auto 0 0; align-self: center; color: var(--sub); font-size: 12.5px; }
.pm-usage b { font-weight: 500; color: var(--ink); }
.pm-delta { color: var(--ether); font-weight: 500; }

@media (max-width: 720px) {
  /* 좁은 폭에서는 직업을 이름 아래로 접고 숫자 두 열만 유지한다 */
  .pm-row label, .pm-pick {
    grid-template-columns: 22px minmax(0, 1fr) 62px 54px;
    row-gap: 1px;
  }
  .pm-box, .pm-mark { grid-row: 1 / span 2; }
  .pm-name { grid-column: 2; grid-row: 1; }
  .pm-class { grid-column: 2; grid-row: 2; }
  .pm-lv { display: none; }
  .pm-num { grid-column: 3; grid-row: 1; }
  .pm-num.pm-il { grid-column: 4; grid-row: 1; }
}
