/* UWO 함대 배치 시뮬레이터 — 양피지 테마 */
:root {
  --bg: #f4efe6;
  --text: #2d2417;
  --muted: #6d604e;
  --card-bg: #fffdf9;
  --card-border: #d9c6aa;
  --line: #e3d5bf;
  --shadow: 0 12px 28px rgba(67, 42, 18, .10);
  --shadow-sm: 0 2px 6px rgba(67, 42, 18, .08);
  --radius-lg: 10px;
  --radius-md: 8px;
  --radius-sm: 4px;

  --accent: #8a6a3a;
  --accent-soft: #efe3cd;
  --accent-text: #6b4f26;

  /* 유형색 — 항해사 유형(모험/교역/전투) */
  --adventure: #5e88c7;
  --adventure-soft: #c9daf8;
  --trade: #5c9d64;
  --trade-soft: #d9ead3;
  --combat: #c56a6a;
  --combat-soft: #f4cccc;

  /* 등급색 — 초상화 배경·등급 배지.
     각 등급마다 배경(bg) / 테두리(line) / 글자(ink) 세 톤을 같은 계열로 맞춘다. */
  --grade-sp: #ffe599;  --grade-sp-line: #d9ad33;  --grade-sp-ink: #6b4c07;
  --grade-s:  #fff2cc;  --grade-s-line:  #e0c56a;  --grade-s-ink:  #7a5f14;
  --grade-a:  #d0e0e3;  --grade-a-line:  #8fb3ba;  --grade-a-ink:  #2f5c63;
  --grade-b:  #fce5cd;  --grade-b-line:  #e3b183;  --grade-b-ink:  #7a4f1e;
  --grade-c:  #c9daf8;  --grade-c-line:  #96b6e6;  --grade-c-ink:  #2f4f83;

  --ok: #3f7a46;
  --warn-bg: #fdf0d8;
  --warn-line: #d9b169;
  --danger: #b4524a;

  /* 제독(S+) 강조색 */
  --admiral: #ffe599;
  --admiral-line: #d8ab2e;
  --admiral-text: #6b4c07;

  --topbar-h: 96px;
  --mobile-tabs-h: 0px;
}

* { box-sizing: border-box; }

/* display 를 지정한 요소(.modal 등)가 브라우저 기본 [hidden] 규칙을 이겨
   투명한 채로 화면을 덮는 것을 막는다. */
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Malgun Gothic', system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}
body { display: flex; flex-direction: column; overflow: hidden; }

h1, h2, h3, h4, h5 { margin: 0; font-weight: 700; }
ul { margin: 0; padding: 0; list-style: none; }
p { margin: 0; }

/* ---------- 상단 바 ---------- */
.topbar {
  flex: none;
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 8px 14px;
  background: linear-gradient(180deg, #fffdf8, #f6efe2);
  border-bottom: 1px solid var(--card-border);
  box-shadow: var(--shadow-sm);
  z-index: 20;
}
.brand { display: flex; align-items: baseline; gap: 8px; }
/* .brand 는 baseline 정렬이라(이름 ↔ 버전 표기를 맞추려고) 아이콘만 가운데로 뺀다 */
.brand-icon { width: 18px; height: 18px; align-self: center; flex: none; margin-right: -2px; }
.brand h1 { font-size: 17px; letter-spacing: -.2px; }
.ver { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.credit { font-size: 11px; color: var(--muted); opacity: .8; }

/* 배치가 늘어도 상단 바 크기는 그대로여야 한다 — 탭 줄은 5개쯤에서 멈추고 ◀ ▶ 로 넘긴다 */
/* 가로 간격은 아이콘 버튼 사이(4px)와 같게, 줄 간격은 좁은 화면용으로 넉넉히 */
.plan-bar { display: flex; align-items: center; gap: 10px 4px; flex-wrap: nowrap; flex: 1 1 auto; min-width: 0; }
/* 탭 줄부터 프리셋까지 한 덩어리로 오른쪽 끝에 붙인다 (왼쪽 여백은 제목이 쓴다) */
.plan-strip { display: flex; align-items: center; gap: 4px; min-width: 0; flex: 0 1 auto; margin-left: auto; }
.plan-tabs {
  flex: 0 1 auto; min-width: 0; max-width: 460px;   /* 기본 이름 기준 5개 남짓 */
  display: flex; gap: 4px;
  overflow-x: auto; scrollbar-width: none;          /* 넘김은 ◀ ▶ 로 하므로 막대는 감춘다 */
}
.plan-tabs::-webkit-scrollbar { display: none; }
.strip-nav {
  flex: none;
  width: 20px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--card-border); border-radius: var(--radius-sm);
  background: var(--card-bg); color: var(--muted);
  font: inherit; font-size: 9px; line-height: 1; cursor: pointer;
}
.strip-nav:hover:not(:disabled) { border-color: var(--accent); color: var(--accent-text); background: #fff; }
.strip-nav:disabled { opacity: .3; cursor: default; }
.plan-tab {
  flex: none;
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 10px;
  border: 1px solid var(--card-border); border-radius: var(--radius-md);
  background: var(--card-bg); color: var(--muted);
  font: inherit; font-size: 12px; cursor: pointer;
  white-space: nowrap;
}
.plan-tab:hover { border-color: var(--accent); color: var(--text); }
.plan-tab.is-active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-text); font-weight: 700; }
/* 이름이 길어도 탭 폭은 일정하게 (전체 이름은 title 로 보인다) */
.plan-tab { max-width: 128px; }
.plan-tab .plan-nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-tab .plan-n {
  min-width: 18px; padding: 0 4px; border-radius: 9px;
  background: rgba(0,0,0,.07); font-size: 10px; text-align: center;
  font-variant-numeric: tabular-nums;
}
/* 조작 버튼 묶음은 탭 줄 바로 옆에 (오른쪽 정렬은 .plan-strip 의 margin-left:auto 가 맡는다) */
.plan-actions { display: flex; gap: 4px; flex: none; }
/* 프리셋 — 배치 전체를 다루는 기능이라 나머지 버튼과 살짝 떼어 둔다 (4px + 10px) */
.preset-btn { flex: none; margin-left: 10px; }

.btn {
  padding: 6px 11px;
  border: 1px solid var(--card-border); border-radius: var(--radius-md);
  background: var(--card-bg); color: var(--text);
  font: inherit; font-size: 12px; cursor: pointer;
}
.btn:hover { border-color: var(--accent); background: #fff; }
.btn.sm { padding: 5px 9px; font-size: 11.5px; }
.btn.primary { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-text); font-weight: 600; }
.btn.danger:hover { border-color: var(--danger); color: var(--danger); }
/* 아이콘만 있는 버튼 — 글자 버튼과 높이를 맞추고 좌우 여백만 줄인다 */
.btn.ico {
  min-width: 34px;                     /* 이모지·기호 폭이 달라도 버튼 크기는 같게 */
  padding-left: 7px; padding-right: 7px; font-size: 13px; line-height: 1.25;
}
.btn.ico.glyph { font-size: 15px; }   /* 이모지가 아닌 기호(⧉)는 조금 크게 */

/* 기호는 글자라 베이스라인에 얹히는데, 폰트 안에서 그려지는 높이가 기호마다 달라
   버튼 한가운데와 어긋난다(+ 는 1.6px 아래로 치우쳐 보였다).
   line-height 를 줄여도 베이스라인과 줄 중심이 같이 움직여 해결되지 않으므로,
   Pretendard 15px 기준으로 잰 값만큼 기호만 위아래로 밀어 준다. */
.btn.ico .ico-g,
.reset-btn .ico-g { display: block; transform: translateY(var(--g-nudge, 0)); }
/* 아래 값은 실제로 그려지는 픽셀(잉크)의 중심을 재서 버튼 한가운데에 맞춘 것 */
#plan-add    { --g-nudge: -1.2px;  }
#plan-rename { --g-nudge: -0.35px; }
#plan-dup    { --g-nudge:  1.15px; }
#plan-reset  { --g-nudge: -0.6px;  }
#plan-delete { --g-nudge: -0.2px;  }
/* 팔레트 머리줄 버튼은 글자 크기·줄높이가 달라 반대로 위쪽으로 치우쳐 있었다 */
#filter-reset { --g-nudge: 1.8px; }
#own-mode     { --g-nudge: 2px;   }
.icon-btn {
  width: 26px; height: 26px; flex: none;
  border: 1px solid var(--card-border); border-radius: var(--radius-sm);
  background: var(--card-bg); color: var(--muted);
  font-size: 15px; line-height: 1; cursor: pointer;
}
.icon-btn:hover { border-color: var(--danger); color: var(--danger); }

.data-note {
  flex: none; margin: 0; padding: 6px 14px;
  background: var(--warn-bg); border-bottom: 1px solid var(--warn-line);
  font-size: 12px; color: var(--accent-text);
}

/* ---------- 로딩 ---------- */
.loading { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; color: var(--muted); }
.spinner {
  width: 28px; height: 28px; border-radius: 50%;
  border: 3px solid var(--accent-soft); border-top-color: var(--accent);
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- 3분할 ---------- */
.work {
  flex: 1; min-height: 0;
  display: grid;
  grid-template-columns: 288px minmax(0, 1fr) 360px;
  gap: 1px;
  background: var(--card-border);
}
.pane { min-height: 0; display: flex; flex-direction: column; background: var(--bg); overflow: hidden; }
.pane-head {
  flex: none;
  display: flex; align-items: baseline; gap: 8px;
  padding: 9px 12px 7px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, #fbf7ef, #f4efe6);
}
.pane-head h2 { font-size: 13px; letter-spacing: .3px; }
/* ⚠ 한 줄로 못 박는다. 조건을 하나 담으면 글이 길어져 두 줄로 접히고, 제목줄이 17px 자라
   목록 전체가 밀려 올라간다 — 방금 보던 칩을 놓친다. 길면 …로 자르고 전체는 title 로 본다. */
.pane-count {
  font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums;
  min-width: 0;
  /* 늘 두 줄이다 — 아랫줄(조건 수)이 비어도 자리를 지켜야 제목줄 높이가 안 변한다.
     각 줄은 넘치면 …로 자른다(전체는 title 로 본다). */
  display: flex; flex-direction: column; line-height: 15px;
}
.pc-main, .pc-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pc-sub { min-height: 15px; opacity: .85; }
/* 수 표시가 두 줄이 되었으므로 제목과 가운데를 맞춘다 (다른 칸은 baseline 그대로).
   ⚠ 위아래 여백을 줄여 «두 줄이어도 제목줄 높이는 그대로» 둔다 —
     한 줄일 때가 9+7+23=39px 였고, 지금은 5+4+30=39px 로 같다.
     제목줄이 자라면 그만큼 목록이 짧아진다. */
.pane-palette .pane-head { align-items: center; padding-top: 5px; padding-bottom: 4px; }

/* 제목줄 오른쪽 끝 버튼 묶음 (초기화 ↺ · 보유 설정 ⚙) */
.head-actions {
  margin-left: auto; flex: none; align-self: center;   /* pane-head 는 baseline 정렬이라 따로 맞춘다 */
  display: flex; gap: 4px;
}
.reset-btn {
  flex: none;
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--card-border); border-radius: var(--radius-sm);
  background: var(--card-bg); color: var(--muted);
  font: inherit; font-size: 13px; line-height: 1; cursor: pointer;
}
.reset-btn:hover { border-color: var(--accent); color: var(--accent-text); background: #fff; }
.reset-btn.is-active { border-color: var(--accent); color: var(--accent-text); font-weight: 700; }

/* ---------- 팔레트 ---------- */
.search-row { flex: none; display: flex; gap: 5px; padding: 8px 10px 6px; }
.search-row input {
  flex: 1; min-width: 0;
  padding: 6px 9px;
  border: 1px solid var(--card-border); border-radius: var(--radius-md);
  background: var(--card-bg); color: var(--text); font: inherit; font-size: 12.5px;
}
.search-row input:focus { outline: 2px solid var(--accent-soft); outline-offset: -1px; border-color: var(--accent); }
/* 「LV2만」 — 검색 중에만 나타나므로 입력칸 옆에서 줄바꿈 없이 붙어 있게 한다 */
.search-row .lv2-chip { flex: none; white-space: nowrap; }
.search-row .lv2-chip.is-on {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
/* 입력칸 안의 × 는 브라우저 기본 「검색어만 지우기」. 초기화(↺)와 역할이 달라 그대로 둔다. */

.filters { flex: none; padding: 0 10px 8px; display: flex; flex-direction: column; gap: 6px; }
.chip-rows { display: flex; flex-direction: column; gap: 4px; }
.chip-row { display: flex; gap: 4px; flex-wrap: wrap; }
/* 아래 드롭다운과 같은 라운드 스퀘어 */
.chip {
  padding: 4px 10px;
  border: 1px solid var(--card-border); border-radius: var(--radius-md);
  background: var(--card-bg); color: var(--muted);
  font: inherit; font-size: 11.5px; cursor: pointer;
}
.chip:hover { border-color: var(--accent); }
.chip.is-on { font-weight: 700; }

/* 등급·유형 칩은 늘 그 색을 입고 있어 한눈에 구분된다.
   고르지 않은 칩은 흐리게, 고른 칩은 진하게 + 안쪽 테두리로 표시. */
/* [data-tint] 는 효과·기술 목록의 계열 칩이다. 유형 칩과 «같은 규칙에 태워» 둔다 —
   색값을 두 군데 적으면 한쪽만 고쳐져 같은 말이 다른 색이 된다. */
#filter-grade .chip, #filter-type .chip, .chip[data-tint] { opacity: .5; }
#filter-grade .chip.is-on, #filter-type .chip.is-on, .chip[data-tint].is-on {
  opacity: 1; box-shadow: inset 0 0 0 1px currentColor;
}

#filter-grade .chip {
  background: var(--grade-bg); border-color: var(--grade-line); color: var(--grade-ink);
}
#filter-grade .chip[data-value="S+"] { --grade-bg: var(--grade-sp); --grade-line: var(--grade-sp-line); --grade-ink: var(--grade-sp-ink); }
#filter-grade .chip[data-value="S"]  { --grade-bg: var(--grade-s);  --grade-line: var(--grade-s-line);  --grade-ink: var(--grade-s-ink); }
#filter-grade .chip[data-value="A"]  { --grade-bg: var(--grade-a);  --grade-line: var(--grade-a-line);  --grade-ink: var(--grade-a-ink); }
#filter-grade .chip[data-value="B"]  { --grade-bg: var(--grade-b);  --grade-line: var(--grade-b-line);  --grade-ink: var(--grade-b-ink); }
#filter-grade .chip[data-value="C"]  { --grade-bg: var(--grade-c);  --grade-line: var(--grade-c-line);  --grade-ink: var(--grade-c-ink); }

#filter-type .chip, .chip[data-tint] { background: var(--type-bg); border-color: var(--type-line); color: var(--type-ink); }
#filter-type .chip[data-value="모험"], .chip[data-tint="모험"] { --type-bg: var(--adventure-soft); --type-line: #a9bddf; --type-ink: #355b95; }
#filter-type .chip[data-value="교역"], .chip[data-tint="교역"] { --type-bg: var(--trade-soft);     --type-line: #a9c8a3; --type-ink: #37693d; }
#filter-type .chip[data-value="전투"], .chip[data-tint="전투"] { --type-bg: var(--combat-soft);    --type-line: #deb0b0; --type-ink: #8c4343; }
/* 계열이 없는 칩(기술·효과)은 강조색(갈색)을 입는다 — 색만 다르고 방식은 위와 같다 */
.chip[data-tint="강조"] { --type-bg: var(--accent-soft); --type-line: var(--accent); --type-ink: var(--accent-text); }
.select-row { display: flex; gap: 5px; }
.select-row select {
  flex: 1; min-width: 0;
  padding: 5px 7px;
  border: 1px solid var(--card-border); border-radius: var(--radius-md);
  background: var(--card-bg); color: var(--text); font: inherit; font-size: 12px;
}
.check { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--muted); cursor: pointer; }

.palette-list {
  flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding: 4px 8px 10px;
  display: flex; flex-direction: column; gap: 3px;
}
.pane-foot { flex: none; padding: 6px 10px 8px; border-top: 1px solid var(--line); }

/* 항해사 카드 짜임 — 초상화 | 이름·정보 | 뱃지
   위쪽 정렬이라 검색 칩이 붙어 카드가 길어져도 초상화는 제자리에 남는다
   (가운데 정렬이면 카드가 커질수록 초상화가 아래로 밀린다). */
.mate-card {
  flex: none;
  display: flex; align-items: flex-start; gap: 8px;
  padding: 5px 6px;
  border: 1px solid var(--card-border);
  border-radius: var(--radius-md);
  background: var(--card-bg);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7);
  cursor: grab; touch-action: pan-y;
  user-select: none; -webkit-user-select: none;
}
.mate-card:hover { border-color: var(--accent-line, var(--accent)); filter: brightness(1.03); }
.mate-card.is-placed { opacity: .55; }
.mate-card.is-selected { outline: 2px solid var(--accent); outline-offset: 1px; }

/* 카드 배경 = 항해사 유형색 */
.mate-card.m-모험 { background: var(--adventure-soft); border-color: #a9bddf; }
.mate-card.m-교역 { background: var(--trade-soft);     border-color: #a9c8a3; }
.mate-card.m-전투 { background: var(--combat-soft);    border-color: #deb0b0; }
.mate-card.m-모험:hover { border-color: #7a9ad0; }
.mate-card.m-교역:hover { border-color: #86ab7f; }
.mate-card.m-전투:hover { border-color: #cd9494; }

/* 초상화 테두리 = 등급색 */
.portrait-frame {
  flex: none; padding: 2px; border-radius: var(--radius-sm);
  background: var(--grade-bg, #efe2b3);
  /* 테두리는 등급색과 같은 계열의 진한 톤. C등급처럼 카드 배경과 같은 색이어도 윤곽이 남는다. */
  box-shadow: inset 0 0 0 1px var(--grade-line, rgba(45, 36, 23, .18));
}


/* 배경을 비워 프레임의 등급색이 그대로 비치게 한다.
   초상화 PNG 의 투명한 부분(인물 주변)도 등급색으로 채워진다. */
.mate-portrait {
  position: relative; width: 32px; height: 32px;
  border-radius: 3px; overflow: hidden;
  background: transparent;
}
.mate-portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* 초상화를 끝내 못 받았을 때 이름 첫 글자로 대신한다 (빈 칸으로 두지 않는다) */
.mate-portrait.no-portrait::before, .slot-portrait.no-portrait::before {
  content: attr(data-initial);
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 700; color: var(--text); opacity: .45;
}
.slot-portrait { position: relative; }

/* 배치 뱃지 — 「배치」 위, 위치(1-2) 아래 두 줄.
   카드는 위쪽 정렬이라 검색 칩이 붙어도 뱃지가 움직이지 않는다.
   위여백 6px = 기본 카드(콘텐츠 36px) 기준 세로 가운데 위치. */
.mate-badge {
  flex: none; align-self: flex-start; margin-top: 6px;
  display: flex; flex-direction: column; align-items: center;
  padding: 1px 4px; border-radius: 3px;
  font-weight: 700; color: #fff; line-height: 1.15;
}
.mate-badge b { font-size: 8.5px; font-weight: 700; opacity: .85; }
/* 가장 긴 위치 표기(1-선장 = 29.8px)에 맞춰 폭을 고정 — 위치가 바뀌어도 뱃지가 들썩이지 않게 */
.mate-badge i {
  min-width: 30px; text-align: center;
  font-size: 10px; font-style: normal; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.mate-badge.placed { background: var(--ok); }
.mate-badge.dup { background: var(--danger); }

.mate-info { min-width: 0; flex: 1; }
.mate-name { display: flex; align-items: center; gap: 4px; font-size: 12.5px; font-weight: 600; min-width: 0; }
.mate-name-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* gap 대신 가운데 점으로 구분하므로 간격을 줄인다 */
.mate-sub { display: flex; gap: 4px; align-items: center; font-size: 10.5px; color: var(--muted); min-width: 0; }
.mate-job { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sub-dot { flex: none; opacity: .5; }

/* 검색으로 걸린 효과·기술 — 한 행에 칩 하나, 접힌 개수는 마지막 칩 옆에 */
.mate-hits { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; margin-top: 3px; min-width: 0; }
.hit-row { display: flex; align-items: center; gap: 4px; max-width: 100%; min-width: 0; }
.hit-chip {
  min-width: 0; padding: 0 4px; border-radius: 3px;
  font-size: 9.5px; line-height: 14px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hit-chip b { margin-left: 3px; font-variant-numeric: tabular-nums; }
.hit-chip.is-effect { background: rgba(255,255,255,.75); color: var(--accent-text); }
.hit-chip.is-skill  { background: rgba(45,36,23,.10);   color: var(--text); }
/* 접힌 칩은 감춰 두고, 「+N」 을 누르면 드러낸다 */
.hit-row.is-extra { display: none; }
.mate-hits.is-open .hit-row.is-extra { display: flex; }
.hit-more {
  flex: none; padding: 0 4px; border-radius: 3px;
  border: 1px solid var(--card-border); background: rgba(255, 255, 255, .6);
  font: inherit; font-size: 9.5px; line-height: 13px; color: var(--muted);
  cursor: pointer;
}
.hit-more:hover { border-color: var(--accent); color: var(--accent-text); }
.mate-stat { flex: none; white-space: nowrap; }
/* 이름 앞 등급 라벨 — 초상화 배경과 같은 등급색을 쓴다 */
.mate-grade {
  flex: none; padding: 0 4px; border-radius: 3px;
  font-size: 9.5px; font-weight: 700;
  line-height: 16px;                  /* 이름 글자(12.5px)의 실제 높이와 같게 */
  /* 글꼴의 위/아래 여백이 비대칭이라 상자를 가운데 정렬해도 글자가 0.38px 어긋난다.
     align-items:center 는 여백을 포함해 가운데를 잡으므로, 아래쪽에 0.75px 을 주면
     배지가 그 절반만큼 올라가 이름 글자와 정확히 맞는다. */
  margin-bottom: .75px;
  background: var(--grade-bg, #efe2b3);
  color: var(--grade-ink, #4a3a17);
  box-shadow: inset 0 0 0 1px var(--grade-line, transparent);
}

/* 등급 한 벌 — 이 클래스를 단 요소는 배경·테두리·글자색을 함께 물려받는다 */
.g-Sp { --grade-bg: var(--grade-sp); --grade-line: var(--grade-sp-line); --grade-ink: var(--grade-sp-ink); }
.g-S  { --grade-bg: var(--grade-s);  --grade-line: var(--grade-s-line);  --grade-ink: var(--grade-s-ink); }
.g-A  { --grade-bg: var(--grade-a);  --grade-line: var(--grade-a-line);  --grade-ink: var(--grade-a-ink); }
.g-B  { --grade-bg: var(--grade-b);  --grade-line: var(--grade-b-line);  --grade-ink: var(--grade-b-ink); }
.g-C  { --grade-bg: var(--grade-c);  --grade-line: var(--grade-c-line);  --grade-ink: var(--grade-c-ink); }

/* 팔레트 카드에는 유형 칩이 없다(배경색이 대신함). 슬롯·요약에서만 쓴다. */
.slot-type { padding: 0 4px; border-radius: 3px; font-size: 10px; font-weight: 700; flex: none; }
.t-모험 { background: var(--adventure-soft); color: #355b95; }
.t-교역 { background: var(--trade-soft); color: #37693d; }
.t-전투 { background: var(--combat-soft); color: #8c4343; }

/* ---------- 배치판 ---------- */
/* 높이를 고정해 선택/미선택 전환 때 아래 배치판이 밀리지 않게 한다 */
.selection-bar {
  flex: none; display: flex; align-items: center; gap: 8px;
  min-height: 31px;
  padding: 6px 12px;
  background: var(--accent-soft); border-bottom: 1px solid var(--accent);
  font-size: 12px; color: var(--accent-text);
}
.selection-bar.is-empty {
  background: #f7f2e8; border-bottom-color: var(--line); color: var(--muted);
}
.selection-bar b { color: var(--accent-text); }
/* 자리는 유지하고 보이기만 감춘다 */
.is-invisible { visibility: hidden; }
.board { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 10px 12px 20px; display: flex; flex-direction: column; gap: 10px; }

/* 세로 flex + overflow-y 스크롤 컨테이너의 자식은 flex:none 이어야 한다.
   기본값(flex-shrink:1)이면 내용이 넘칠 때 카드가 눌려 잘린다. */
.ship { flex: none; border: 1px solid var(--card-border); border-radius: var(--radius-lg); background: var(--card-bg); box-shadow: var(--shadow-sm); overflow: hidden; }
.ship.is-empty { opacity: .78; }
.ship.candidates { border-style: dashed; background: #fbf8f2; }
.ship-head {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px;
  background: linear-gradient(180deg, #f8f2e6, #f2ebdd);
  border-bottom: 1px solid var(--line);
}
.ship-head h3 { font-size: 12.5px; }
.ship-count { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.ship-note { font-size: 11px; color: var(--muted); margin-left: auto; }
.ship-clear {
  margin-left: auto; padding: 2px 8px;
  border: 1px solid var(--card-border); border-radius: var(--radius-sm);
  background: var(--card-bg); color: var(--muted); font: inherit; font-size: 11px; cursor: pointer;
}
.ship-clear:hover:not(:disabled) { border-color: var(--danger); color: var(--danger); }
.ship-clear:disabled { opacity: .4; cursor: default; }

.ship-slots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(158px, 1fr));
  gap: 5px; padding: 7px;
}
.slot {
  position: relative;
  min-height: 52px;
  border: 1px dashed var(--card-border); border-radius: var(--radius-md);
  background: #fdfaf4;
  padding: 3px 5px 4px;
  touch-action: pan-y;
  transition: border-color .12s, background .12s;
}
/* 채워진 슬롯 배경 = 항해사 유형색 (팔레트 카드와 같은 규칙) */
.slot.is-filled { border-style: solid; background: var(--card-bg); cursor: grab; }
.slot.is-filled.m-모험 { background: var(--adventure-soft); border-color: #a9bddf; }
.slot.is-filled.m-교역 { background: var(--trade-soft);     border-color: #a9c8a3; }
.slot.is-filled.m-전투 { background: var(--combat-soft);    border-color: #deb0b0; }



.slot.is-selected { outline: 2px solid var(--accent); outline-offset: 1px; }
/* 상태 표시는 유형색보다 우선 */
.slot.is-filled.is-dup { border-color: var(--danger); background: #fdf3f2; }
.slot.is-droptarget, .slot.is-filled.is-droptarget { border-color: var(--accent); background: #fffaf0; }
.slot.is-drophover, .slot.is-filled.is-drophover { border-color: var(--accent); background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent); }
.slot.is-dragsource { opacity: .35; }
.slot-label { display: block; font-size: 9.5px; color: var(--muted); letter-spacing: .2px; }
.slot-body { display: flex; align-items: center; gap: 6px; min-height: 32px; }
.slot-empty { font-size: 11px; color: #b6a78f; }
.slot-portrait { width: 28px; height: 28px; border-radius: 3px; overflow: hidden; background: transparent; }
.slot-portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }
.slot-text { min-width: 0; flex: 1; }
.slot-name { display: flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600; min-width: 0; }
.slot-name-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.slot-sub { display: flex; gap: 4px; align-items: center; font-size: 10px; color: var(--muted); min-width: 0; }
.slot-job { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.slot-grade {
  padding: 0 3px; border-radius: 3px; flex: none;
  font-size: 9.5px; font-weight: 700;
  background: var(--grade-bg, rgba(45,36,23,.1));
  color: var(--grade-ink, var(--muted));
  box-shadow: inset 0 0 0 1px var(--grade-line, transparent);
}
.slot.is-filled:has(.slot-grade.g-Sp) { border-color: var(--grade-sp-line); }
.slot-stat { flex: none; white-space: nowrap; }
.slot-dup { display: block; font-size: 9.5px; color: var(--danger); font-weight: 700; }
.slot-clear {
  position: absolute; top: 2px; right: 2px;
  width: 17px; height: 17px;
  border: none; border-radius: 3px;
  background: transparent; color: #bfae94;
  font-size: 13px; line-height: 1; cursor: pointer; padding: 0;
}
.slot:hover .slot-clear { background: rgba(180, 82, 74, .1); color: var(--danger); }

/* 드래그 고스트 */
.ghost-card {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 8px 4px 4px;
  border: 1px solid var(--accent); border-radius: var(--radius-md);
  background: #fff; box-shadow: var(--shadow);
  font-size: 12px; font-weight: 600;
  opacity: .95; transform: rotate(-1.5deg);
}
.ghost-card img { width: 26px; height: 26px; border-radius: 3px; object-fit: cover; }
body.is-dragging { cursor: grabbing; }
body.is-dragging * { cursor: grabbing !important; }
.palette-list.is-droptarget { box-shadow: inset 0 0 0 2px var(--accent-soft); }
.palette-list.is-drophover { box-shadow: inset 0 0 0 2px var(--danger); background: #fdf5f4; }

/* ---------- 요약 ---------- */
.summary-tabs { flex: none; display: flex; gap: 3px; padding: 6px 10px; border-bottom: 1px solid var(--line); }
.summary-tabs button {
  flex: 1;
  padding: 5px 6px;
  border: 1px solid var(--card-border); border-radius: var(--radius-md);
  background: var(--card-bg); color: var(--muted); font: inherit; font-size: 12px; cursor: pointer;
}
.summary-tabs button.is-active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-text); font-weight: 700; }
.summary-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 8px 10px 24px; display: flex; flex-direction: column; gap: 10px; }

.sum-ship, .sum-block { flex: none; border: 1px solid var(--card-border); border-radius: var(--radius-md); background: var(--card-bg); padding: 7px 9px 9px; }
/* 선박 카드는 <details> — 제목줄을 눌러 접고 편다 */
.sum-ship > summary {
  display: flex; align-items: baseline; gap: 6px;
  cursor: pointer; list-style: none; user-select: none;
}
.sum-ship > summary::-webkit-details-marker { display: none; }   /* 기본 삼각형 제거 */
.sum-ship > summary::before {
  content: '▾'; flex: none;
  font-size: 9px; color: var(--muted); line-height: 1;
  transform: translateY(-1px);
  transition: transform .12s ease;
}
.sum-ship:not([open]) > summary::before { transform: translateY(-1px) rotate(-90deg); }
.sum-ship > summary:hover h4 { color: var(--accent-text); }
.sum-ship[open] > summary { margin-bottom: 5px; }
/* 접었을 때만 보이는 한 줄 요약 */
.fold-hint { margin-left: auto; font-size: 10.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.sum-ship[open] .fold-hint { display: none; }
.sum-ship h4, .sum-block h4 { font-size: 12.5px; }
.sum-block h4 { margin-bottom: 6px; }
.sum-block h4 em, .sum-ship h4 em { font-style: normal; font-size: 11px; color: var(--muted); font-weight: 400; }
.sum-ship h5 { font-size: 11px; color: var(--muted); margin-bottom: 3px; letter-spacing: .2px; }
.sum-ship h5 em { font-style: normal; }
.sum-cols { display: grid; grid-template-columns: 1fr; gap: 8px; }

.roster { display: flex; flex-wrap: wrap; gap: 3px; margin-bottom: 6px; }
.roster-chip { padding: 1px 5px; border-radius: 3px; font-size: 10.5px; }

.eff-list li {
  display: flex; align-items: baseline; gap: 5px;
  padding: 1.5px 0;
  border-bottom: 1px solid #f3ece0;
  font-size: 11.5px;
}
.eff-list li:last-child { border-bottom: none; }
.eff-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lv {
  flex: none; min-width: 17px; padding: 0 3px;
  border-radius: 3px; background: var(--accent-soft); color: var(--accent-text);
  font-size: 10px; font-weight: 700; text-align: center; font-variant-numeric: tabular-nums;
}
.lv.over { background: #f6ddb6; color: #8a5b12; }
.val { flex: none; font-size: 11px; color: var(--accent-text); font-weight: 600; font-variant-numeric: tabular-nums; }
.val.unknown { color: #b3a48d; font-weight: 400; }

.table-scroll { overflow-x: auto; }
.trade-table { width: 100%; border-collapse: collapse; font-size: 11.5px; }
.trade-table th, .trade-table td { padding: 3px 5px; border-bottom: 1px solid #f0e8da; text-align: left; white-space: nowrap; }
.trade-table thead th { font-size: 10.5px; color: var(--muted); font-weight: 600; border-bottom: 1px solid var(--card-border); }
.trade-table tbody th { font-weight: 600; }
/* 수치 칸: 고정폭 상자를 칸 가운데에 두고, 그 안에서 숫자를 오른쪽으로 붙인다.
   → 칸 전체로는 가운데지만 11.5 / 9.4 / 9 의 오른쪽 끝이 서로 맞는다. */
.trade-table thead th:not(:first-child) { text-align: center; }
.trade-table .num { text-align: center; position: relative; }
.trade-table .num .n {
  display: inline-block; min-width: 4.4ch;
  text-align: right; font-variant-numeric: tabular-nums;
}
/* 「상한」 배지는 숫자 상자 밖(칸 오른쪽 끝)에 띄워 가운데 정렬을 흐트러뜨리지 않는다.
   배지가 있는 표에서만 오른쪽 여백을 잡아 숫자와 겹치지 않게 한다(머리글도 같이 밀어 중심을 맞춘다). */
.trade-table .num .capped { position: absolute; right: 3px; top: 50%; transform: translateY(-50%); margin: 0; }
.trade-table.has-cap thead th:not(:first-child),
.trade-table.has-cap .num { padding-right: 27px; }
.trade-table .num.zero { color: #c3b7a2; }
.trade-table .num.is-capped { color: #8a5b12; }
.capped { margin-left: 3px; padding: 0 3px; border-radius: 3px; background: #f6ddb6; color: #8a5b12; font-size: 9px; font-weight: 700; }

.lang-list li { display: flex; align-items: baseline; gap: 6px; padding: 1.5px 0; border-bottom: 1px solid #f3ece0; font-size: 11.5px; }
.lang-list li:last-child { border-bottom: none; }
.lang-name { flex: 1; }
.lang-count { font-size: 10.5px; color: var(--muted); }

.empty-note { font-size: 11.5px; color: var(--muted); padding: 3px 0; }
.hint { font-size: 11px; color: var(--muted); line-height: 1.45; }
.warn {
  padding: 6px 9px; border: 1px solid var(--warn-line); border-radius: var(--radius-md);
  background: var(--warn-bg); font-size: 11.5px; color: #8a5b12;
}

/* ---------- 모달 ---------- */
.modal { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; padding: 16px; background: rgba(45, 36, 23, .42); }
.modal-box {
  width: 100%; max-width: 620px; max-height: 88vh; max-height: 88dvh;
  display: flex; flex-direction: column;
  border: 1px solid var(--card-border); border-radius: var(--radius-lg);
  background: var(--card-bg); box-shadow: var(--shadow); overflow: hidden;
}
.modal-head { flex: none; display: flex; align-items: center; gap: 8px; padding: 9px 12px; border-bottom: 1px solid var(--line); background: linear-gradient(180deg, #f8f2e6, #f2ebdd); }
.modal-head h3 { flex: 1; font-size: 14px; }
.modal-body { flex: 1; min-height: 0; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 9px; }
.modal-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.io-label { font-size: 11.5px; color: var(--muted); }
.io-text {
  width: 100%; min-height: 120px; resize: vertical;
  padding: 7px; border: 1px solid var(--card-border); border-radius: var(--radius-md);
  background: #fdfaf4; color: var(--text);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 11px;
}
.io-status { font-size: 11.5px; min-height: 16px; }
.import-box { border-top: 1px solid var(--line); padding-top: 9px; display: flex; flex-direction: column; gap: 7px; }
.import-box h4 { font-size: 12.5px; color: var(--accent-text); }
.owned-count { color: var(--muted); font-size: 11px; }
.io-status.ok { color: var(--ok); }
.io-status.bad { color: var(--danger); }
label.btn { display: inline-flex; align-items: center; }

.mate-detail { display: flex; flex-direction: column; gap: 10px; }
.md-head { display: flex; gap: 12px; align-items: flex-start; }
/* 상세 모달 초상화 — 팔레트 카드와 같이 등급색을 배경으로 (투명 PNG 뒤로 비침) */
.md-portrait-frame { flex: none; padding: 3px; border-radius: var(--radius-md); }
.md-portrait { display: block; width: 92px; height: 92px; border-radius: var(--radius-sm); object-fit: cover; background: transparent; }
.md-line { font-size: 12px; margin-bottom: 2px; }
.md-line.muted { color: var(--muted); font-size: 11.5px; }
.md-line .down { color: var(--danger); }
.md-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; }
.md-cols h5 { font-size: 11.5px; color: var(--muted); margin-bottom: 3px; }
/* 오른쪽 칸에 상자가 둘(기술 · 제독 명령) 쌓인다 */
.md-col-stack { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.eff-list.detail li { font-size: 11px; gap: 4px; }
.slot-tag { flex: none; min-width: 52px; font-size: 9.5px; color: var(--muted); }
.cmd-list li { padding: 4px 0; border-bottom: 1px solid #f3ece0; font-size: 11.5px; }
/* 상자 안에서는 마지막 줄 밑줄이 테두리와 겹쳐 지저분해진다 */
.cmd-list li:last-child { border-bottom: none; padding-bottom: 0; }
.cmd-cost { font-size: 10.5px; color: var(--muted); }
/* 계열 아이콘 — 같은 크기면 글자보다 작아 보여 조금 키운다 */
.cmd-type { font-size: 12px; vertical-align: -0.5px; }
/* 명령 이름 계열색 — 뱃지(.t-*)와 달리 배경 없이 글자색만 */
.cmd-name.c-모험 { color: #1155cc; }
.cmd-name.c-교역 { color: #38761d; }
.cmd-name.c-전투 { color: #990000; }
.cmd-desc { font-size: 11px; color: var(--muted); line-height: 1.4; }
/* 스탯 — 라벨(계열색) 위, 값 아래.
   4열이라 한 행이 곧 한 계열(모험 / 교역 / 전투)이 된다. */
/* 스탯 · 효과 · 기술 · 제독 명령 — 같은 상자로 묶어 섹션을 눈으로 구분한다 */
.stat-box,
.detail-box { border: 1px solid var(--line); border-radius: var(--radius-md); padding: 9px 10px; background: #fffdf9; }
.stat-box h5,
.detail-box h5 { margin-bottom: 7px; }
.stat-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 5px 6px; }
.stat-cell { display: flex; flex-direction: column; align-items: stretch; gap: 3px; min-width: 0; }
.stat-key {
  padding: 1px 4px; border-radius: 3px;
  font-size: 10.5px; font-weight: 700; text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.stat-num {
  padding: 3px 4px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--card-bg);
  font-size: 12.5px; font-weight: 600; text-align: center;
  font-variant-numeric: tabular-nums;
}

/* ---------- 모바일 탭 ---------- */
.mobile-tabs { display: none; }

/* ---------- 반응형 ---------- */
@media (max-width: 1280px) {
  .work { grid-template-columns: 250px minmax(0, 1fr) 310px; }
}
@media (max-width: 1024px) {
  .work { grid-template-columns: 232px minmax(0, 1fr); }
  .pane-summary { display: none; }
  body[data-pane="summary"] .work { grid-template-columns: 232px minmax(0, 1fr); }
  body[data-pane="summary"] .pane-board { display: none; }
  body[data-pane="summary"] .pane-summary { display: flex; }
  .mobile-tabs { display: flex; }
  .mobile-tabs button:first-child { display: none; }
}
@media (max-width: 720px) {
  :root { --mobile-tabs-h: 46px; }
  .topbar { padding: 6px 10px; gap: 8px; }
  .brand h1 { font-size: 15px; }
  .brand-icon { width: 16px; height: 16px; }
  /* 좁은 화면에서는 탭 줄과 버튼 줄을 2줄로 (배치 수와 무관하게 항상 2줄) */
  .plan-bar { flex-wrap: wrap; }
  .plan-strip { flex: 1 1 100%; }
  .plan-tabs { flex: 1 1 0; max-width: none; }
  /* 둘째 줄은 왼쪽 조작 버튼 · 오른쪽 프리셋으로 나눠 쓴다 (한쪽만 몰리면 허전하다) */
  .plan-actions { margin-left: 0; }
  .preset-btn { margin-left: auto; }
  .plan-actions .btn { font-size: 11px; padding: 4px 7px; }
  /* 아이콘은 좁은 화면에서도 알아볼 크기를 유지한다 */
  .plan-actions .btn.ico { font-size: 12.5px; padding-left: 6px; padding-right: 6px; }
  .plan-actions .btn.ico.glyph { font-size: 14px; }

  .work { grid-template-columns: minmax(0, 1fr); }
  .pane-palette, .pane-board, .pane-summary { display: none; }
  body[data-pane="palette"] .pane-palette { display: flex; }
  body[data-pane="board"] .pane-board { display: flex; }
  body[data-pane="summary"] .pane-summary { display: flex; }

  .mobile-tabs {
    display: flex; flex: none;
    border-top: 1px solid var(--card-border);
    background: linear-gradient(180deg, #f8f2e6, #f2ebdd);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .mobile-tabs button {
    flex: 1; padding: 11px 4px;
    border: none; background: transparent; color: var(--muted);
    font: inherit; font-size: 12.5px; cursor: pointer;
  }
  .mobile-tabs button.is-active { color: var(--accent-text); font-weight: 700; box-shadow: inset 0 -2px 0 var(--accent); }
  .mobile-tabs button:first-child { display: block; }

  .ship-slots { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .md-cols { grid-template-columns: 1fr; }
}
@media (min-width: 1500px) {
  .sum-cols { grid-template-columns: 1fr 1fr; }
}

/* 터치 기기: hover 로만 보이던 것을 항상 보이게 */
@media (hover: none) {
  .slot-clear { color: #cbbda3; }
  .slot:hover .slot-clear { background: transparent; }
}

/* ---------- 보유 항해사 설정 모드 ---------- */
/* 그리드 폭은 그대로 두고, 팔레트만 토글 폭(34px + 여백)만큼 넘쳐 나와
   가운데 배치판 위를 덮는다. 어느 섹션도 크기가 변하지 않아 레이아웃이 흔들리지 않는다. */
.work.is-ownmode .pane-palette {
  width: calc(100% + 42px);
  justify-self: start;          /* 칸 왼쪽에 붙이고 오른쪽으로 넘치게 */
  position: relative;
  z-index: 5;
  box-shadow: 5px 0 16px rgba(67, 42, 18, .20);   /* 위에 떠 있는 느낌 */
}
.work.is-ownmode .pane-foot { display: none; }

/* 한 열로 쌓이는 좁은 화면에는 넘칠 자리가 없다 — 원래 폭 그대로 둔다. */
@media (max-width: 720px) {
  .work.is-ownmode .pane-palette { width: 100%; box-shadow: none; }
}

.own-bar {
  flex: none; display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 7px 10px;
  background: var(--accent-soft); border-bottom: 1px solid var(--accent);
}

/* 고른 항해사 알림 — 좁은 화면에서만 (넓은 화면은 배치판의 선택 막대가 이미 보인다).
   위쪽 720px 미디어 블록보다 이 규칙이 뒤에 있어 거기서 켜면 덮여버린다 → 전용 블록을 바로 아래에 둔다. */
.pick-bar { display: none; }
.pick-text { font-size: 12.5px; color: var(--accent-text); margin-right: auto; min-width: 0;
             overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.only-narrow { display: none; }

@media (max-width: 720px) {
  .pick-bar {
    flex: none; display: flex; align-items: center; gap: 8px;
    padding: 7px 10px;
    background: var(--accent-soft); border-top: 1px solid var(--accent);
  }
  .only-narrow { display: inline; }
  .only-wide { display: none; }
}
.own-count { font-size: 12px; font-weight: 700; color: var(--accent-text); margin-right: auto; }

/* 보유 설정 카드 — 오른쪽 끝에 토글 */
.mate-card.is-ownrow { cursor: pointer; }
.mate-card.is-ownrow:not(.is-owned) { opacity: .62; }
.mate-card.is-ownrow.is-owned { box-shadow: inset 0 0 0 1px var(--accent); }

/* 보유 설정용 토글 스위치 — 카드가 길어져도 첫 줄 높이에 맞춰 둔다 */
.toggle-switch { position: relative; flex: none; width: 34px; height: 19px; align-self: flex-start; margin-top: 8px; }
.toggle-switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.toggle-slider {
  position: absolute; inset: 0; pointer-events: none;
  background: #cfc4b0; border-radius: 19px;
  transition: background .15s ease;
}
.toggle-slider::before {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 15px; height: 15px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.25);
  transition: transform .15s ease;
}
.toggle-switch input:checked + .toggle-slider { background: var(--ok); }
.toggle-switch input:checked + .toggle-slider::before { transform: translateX(15px); }
.toggle-switch input:focus-visible + .toggle-slider { outline: 2px solid var(--accent); outline-offset: 1px; }

.reset-btn[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-text); }

/* ---------- 배치 모달 (RS 프리셋 화면과 같은 짜임) ---------- */
.plan-list { display: flex; flex-direction: column; gap: 5px; }
.plan-empty { padding: 14px; text-align: center; color: var(--muted); font-size: 12px; }
.plan-item {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 9px;
  border: 1px solid var(--card-border); border-radius: var(--radius-md);
  background: var(--card-bg);
}
.plan-item.is-active { border-color: var(--accent); background: #fffaf0; }
.plan-reorder { display: flex; flex-direction: column; gap: 2px; flex: none; }
.reorder-btn {
  width: 18px; height: 14px; padding: 0;
  border: 1px solid var(--card-border); border-radius: 3px;
  background: var(--card-bg); color: var(--muted);
  font: inherit; font-size: 8px; line-height: 1; cursor: pointer;
}
.reorder-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent-text); }
.reorder-btn:disabled { opacity: .3; cursor: default; }
.plan-item-info { flex: 1; min-width: 0; }
.plan-item-name {
  display: flex; align-items: center; gap: 5px;
  font-size: 12.5px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.plan-active-badge {
  flex: none; padding: 0 4px; border-radius: 3px;
  background: var(--accent-soft); color: var(--accent-text);
  font-size: 9.5px; font-weight: 700;
}
.plan-item-meta { font-size: 10.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.plan-item-actions { display: flex; gap: 3px; flex: none; flex-wrap: wrap; justify-content: flex-end; }

.plan-status { min-height: 16px; font-size: 11.5px; }
.plan-status.is-ok { color: var(--ok); }
.plan-status.is-error { color: var(--danger); }
.plan-note {
  padding: 8px 10px; border: 1px solid var(--warn-line); border-radius: var(--radius-md);
  background: var(--warn-bg); color: var(--accent-text); font-size: 11px; line-height: 1.5;
}

@media (max-width: 560px) {
  .plan-item { flex-wrap: wrap; }
  .plan-item-actions { width: 100%; justify-content: flex-start; }
}

/* ---------- 효과·기술 목록 ----------
   이름을 몰라도 고를 수 있는 입구. 항목을 누르면 검색어가 되어 항해사 목록으로 넘어간다.
   목록은 팔레트와 같은 자리를 쓰므로(둘 중 하나만 보인다) 스크롤 규칙도 같게 맞춘다. */
.pal-modes { flex: none; display: flex; gap: 4px; padding: 6px 10px 0; }
.pal-mode {
  flex: 1; padding: 5px 8px;
  border: 1px solid var(--card-border); border-radius: var(--radius-md);
  background: var(--card-bg); color: var(--muted);
  font: inherit; font-size: 12px; cursor: pointer;
}
.pal-mode:hover { border-color: var(--accent); }
.pal-mode.is-on {
  background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 700;
}

.ability-bar { flex: none; display: flex; flex-direction: column; gap: 5px; padding: 8px 10px 6px; }
.ability-bar input {
  padding: 6px 9px;
  border: 1px solid var(--card-border); border-radius: var(--radius-md);
  background: var(--card-bg); color: var(--text); font: inherit; font-size: 12.5px;
}
.ability-bar input:focus { outline: 2px solid var(--accent-soft); outline-offset: -1px; border-color: var(--accent); }

.ability-list {
  flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  /* ⚠ 위쪽 여백은 0 이어야 한다. 붙어 있는 머리줄은 이 여백 «아래» 에 서므로,
     여백이 있으면 그 틈으로 뒤에 지나가는 칩이 비친다(2px 이어도 눈에 띈다). */
  padding: 0 8px 10px;
}
/* ⚠ 묶음 사이를 «바깥 여백» 으로 띄우면 안 된다. 붙어 있는(sticky) 머리줄은 제 묶음
   안에서만 붙어 있으므로, 여백만큼은 «맨 위에 머리줄이 없는» 구간이 생긴다.
   그 사이 칩이 올라왔다가 다음 머리줄이 툭 나타나 위치가 흔들려 보였다.
   여백을 묶음 «안쪽»(.ab-items 아래)으로 옮겨 묶음끼리 맞닿게 한다 — 넘겨받기가 이어진다. */
.ab-group + .ab-group { margin-top: 0; }
/* 분류 이름은 스크롤해도 남는다 — 500종을 훑는 동안 「지금 어느 분류인지」 를 잃지 않게 */
.ab-group-head {
  position: sticky; top: 0; z-index: 1;
  /* ⚠ 배경은 «목록과 같은 색» 이어야 한다. 예전엔 var(--panel, #fff) 이었는데 FS 에는
     --panel 이 없어 흰색으로 떨어졌고, 베이지 목록 위에 흰 띠가 떠 보였다.
     ⚠ 좌우로 목록 안쪽 여백(8px)만큼 넓힌다 — 안 그러면 뒤로 지나가는 칩이 옆으로 새어 나온다. */
  /* ⚠ 아래쪽 «마진» 을 주면 안 된다. 붙어 있는(sticky) 요소는 «마진 박스» 기준으로
     묶음 안에 갇히므로, 마진만큼 묶음 바닥보다 «먼저» 밀려 나간다.
     그 사이 맨 위에 머리줄이 없어 칩이 비치고, 다음 머리줄이 툭 나타나 흔들려 보였다.
     간격은 아래 .ab-items 의 padding-top 이 맡는다. */
  margin: 0 -8px;
  padding: 0 8px;
  background: var(--bg);
  box-shadow: 0 1px 0 var(--line);      /* 밑줄 한 겹 — 칩이 「뒤로」 지나간다는 것이 보이게 */
  display: flex; align-items: center; gap: 4px;
}
/* 제목 전체가 접기 단추다 — 글자만 누르게 하면 과녁이 너무 좁다 */
.ab-group-btn {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; gap: 6px;
  /* ⚠ 높이는 «정수» 여야 한다. 11.5px × 1.5 = 17.25px 라 머리줄이 25.25px 이 됐는데,
     붙어 있는(sticky) 요소가 소수 높이를 가지면 스크롤 위치마다 반올림이 달라져
     글자가 1px 씩 떨린다. line-height 를 못 박아 16 + 4 + 4 = 24px 로 맞춘다. */
  padding: 4px 2px;
  border: 0; background: none; color: var(--muted);
  font: inherit; font-size: 11.5px; font-weight: 700; text-align: left; cursor: pointer;
  line-height: 16px;    /* ⚠ font: inherit «뒤» 여야 한다 — 축약형이 line-height 를 되돌린다 */
}
.ab-group-btn:hover { color: var(--accent-text); }
.ab-group-nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ab-group-n {
  flex: none;
  font-weight: 400; font-size: 10.5px; line-height: 16px; color: var(--muted); opacity: .8;
}
/* ▾ / ▸ — 접힘 여부를 글자 하나로. 폭을 고정해 제목 첫 글자가 흔들리지 않게 한다 */
.ab-caret { flex: none; width: 9px; font-size: 9px; line-height: 16px; opacity: .7; }
.ab-caret::before { content: '▾'; }
.ab-group.is-collapsed .ab-caret::before { content: '▸'; }
.ab-group.is-collapsed .ab-items { display: none; }

/* 목록 아래 줄 — 조건을 담기 전에는 안내, 담은 뒤에는 결과로 건너가는 문 */
/* 두 바닥 줄(항해사 / 기술·효과)의 높이를 맞춘다 — 모드를 오갈 때 어긋나면 눈에 띈다.
   기본 줄높이(1.5 × 11px = 16.5)면 두 줄이 47px 이라 3px 튄다. 15px 로 못 박아 44px. */
#mate-foot {
  /* 기술·효과 쪽 바닥(.ability-foot)과 «정확히» 같은 44px. 두 줄 30 + 위아래 7+7.
     기본 줄높이(1.5)로 두면 33 + 14 = 47 이라 모드를 오갈 때 1~3px 씩 튄다. */
  height: 44px; line-height: 15px; padding-top: 7px; padding-bottom: 7px;
}
.ability-foot {
  display: flex; align-items: center; gap: 8px;
  /* 좌우 여백을 줄여 안내문에 폭을 더 준다 — Pretendard 가 없는 환경(맑은 고딕 폴백)에서는
     글자가 넓어져 한 줄에 안 들어가고, 두 줄이 되면 아래 min-height 를 넘어 바닥이 자란다. */
  padding-left: 8px; padding-right: 8px;
  /* ⚠ 설명 ↔ 버튼이 바뀌어도 바닥 줄 높이가 변하면 안 된다. 조건을 하나 담는 순간
     목록이 13px 솟아올라 방금 보던 칩을 놓친다. 높은 쪽(버튼)에 맞춰 고정한다.
     44 = 위아래 여백 14 + 버튼 29.25 (box-sizing: border-box). */
  min-height: 44px;
}
.ability-foot .hint { margin: 0; }
.ability-go { flex: 1 1 auto; text-align: center; }

.ab-items { display: flex; flex-wrap: wrap; gap: 3px; padding: 4px 0 10px; }
.ab-item {
  display: inline-flex; align-items: center; gap: 5px;
  max-width: 100%; padding: 4px 8px;
  border: 1px solid var(--card-border); border-radius: var(--radius-md);
  background: var(--card-bg); color: var(--text);
  font: inherit; font-size: 11.5px; cursor: pointer; text-align: left;
}
/* 계열색 — 항해사 카드(.mate-card.m-모험 …)와 같은 톤·같은 이름표를 쓴다.
   고른 칩(.is-on)은 강조색이 이겨야 하므로 :not(.is-on) 으로 비켜 준다. */
.ab-item.m-모험:not(.is-on) { background: var(--adventure-soft); border-color: #a9bddf; }
.ab-item.m-교역:not(.is-on) { background: var(--trade-soft);     border-color: #a9c8a3; }
.ab-item.m-전투:not(.is-on) { background: var(--combat-soft);    border-color: #deb0b0; }
/* 기술은 분류로 칠한다 — 전부 scope 가 combat 이라 계열색으로는 다 같은 분홍이 된다.
   포격·충파·백병·지원 색값은 abilities.js 의 SKILL_TINT 와 짝이다. */
.ab-item.k-포격:not(.is-on) { background: #d9ead3; border-color: #a9c8a3; }
.ab-item.k-충파:not(.is-on) { background: #c9daf8; border-color: #a9bddf; }
.ab-item.k-백병:not(.is-on) { background: #f4cccc; border-color: #deb0b0; }
.ab-item.k-지원:not(.is-on) { background: #d9d2e9; border-color: #b8aed4; }   /* 회복 */
.ab-item.k-강화:not(.is-on) { background: #fff2cc; border-color: #e0c56a; }   /* 올린다 — 밝게 */
.ab-item.k-약화:not(.is-on) { background: var(--grade-a); border-color: var(--grade-a-line); }  /* A등급 청록 */
.ab-item:hover { border-color: var(--accent); }
.ab-item.is-on {
  background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 700;
}
.ab-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 상세 모달에서 태생·직업 이름에 올리면 효과가 뜬다.
   밑줄은 넣지 않는다 — 이름 자체가 이미 굵거나 색이 있어 줄까지 그으면 시끄럽다.
   커서만 바꿔 「올려 볼 것이 있다」 를 알린다. */
.md-line b[title], .md-line .down[title], .md-job[title] { cursor: help; }

/* 직업·태생의 직접 수치 — 효과 목록과 «다르게» 보여야 한다.
   레벨이 없으므로 LV 배지 자리에 출처(직업/태생) 이름표를 둔다. */
.src-badge {
  flex: none; min-width: 26px; padding: 0 4px; border-radius: var(--radius-sm);
  font-size: 9.5px; font-weight: 700; line-height: 16px; text-align: center;
}
.src-badge.s-job   { background: var(--accent-soft); color: var(--accent-text); }
.src-badge.s-birth { background: var(--grade-a);     color: var(--grade-a-ink); }
.eff-list.direct .val { font-variant-numeric: tabular-nums; }

/* 공통 할증(직업 「판매 가격 할증률」) — 품목을 안 가리므로 표의 «행» 이 아니라 표 위 한 줄이다.
   예전에는 이 값이 20품목 전부를 표에 올려, 0.5% 만 든 19행이 정작 볼 것을 밀어냈다. */
.common-sell {
  display: flex; align-items: center; gap: 5px;
  margin: 0 0 5px; padding: 3px 5px;
  border-radius: var(--radius-sm); background: var(--accent-soft);
  font-size: 11.5px;
}
.common-sell .eff-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.common-sell .val { flex: none; font-weight: 700; font-variant-numeric: tabular-nums; }
/* 선박 칸 아래에 한 줄로 — 위 두 칸(효과·기술)과 나란히 두면 셋이 좁아진다 */
.sum-direct { margin-top: 8px; }
.sum-direct h5 { margin: 0 0 4px; }

/* 3차 초월 배지 — 「3차 초월」 을 따로 묶으면 41종이 제 성격 묶음에 한 번, 거기 또 한 번
   나와 목록이 두 배로 길어진다. 묶음 대신 이름 옆에 두 글자만 붙인다.
   ⚠ 배지는 .ab-name 의 «형제» 다(안에 넣으면 말줄임에 같이 잘린다). 칩이 inline-flex 이므로
   flex: none 으로 폭을 지킨다.
   금색은 「특별한 것」에 쓰는 색이다 — 화면마다 색이 갈리면 눈이 다시 배워야 한다. */
.ab-badge {
  flex: none; margin-right: 1px; padding: 0 4px;
  border-radius: var(--radius-sm);
  background: linear-gradient(160deg, #ffeaa8 0%, #f2c64f 55%, #d7a11d 100%);
  box-shadow: inset 0 0 0 1px #b8860b;
  font-style: normal; font-size: 9.5px; font-weight: 800; line-height: 1.6;
  color: #5b4108; vertical-align: 1px;
}
/* 고른 칩 위에서도 금색은 그대로 둔다 — 강조색에 묻히면 3차인지 알 수 없어진다 */
.ab-item.is-on .ab-badge { box-shadow: inset 0 0 0 1px #b8860b, 0 0 0 1px rgba(255, 255, 255, .5); }
/* 보유자 수 — 0 명인 항목은 애초에 목록에 없다(골라도 빈 목록만 나온다) */
.ab-count { flex: none; font-size: 10.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.ab-item.is-on .ab-count { color: #fff; opacity: .85; }
/* LV2 보유자 수 — 「12·3」 처럼 붙는다. 전체 중 몇이 LV2 인지 한눈에 보이면 고를 때 도움이 된다 */
.ab-lv2 { font-style: normal; }
.ab-lv2::before { content: '·'; margin: 0 1px; opacity: .6; }
/* 값표(data.js)에 이름이 없는 항목 — 고를 수는 있지만 수치가 안 나온다.
   숨기지 않는다: 46명이 가진 「행동 봉쇄」 처럼 실제로 쓰이는 것이 섞여 있어,
   감추면 오히려 「왜 이 스킬이 목록에 없지」 가 된다. 표시만 흐리게 두고 툴팁으로 알린다. */
.ab-item.is-unknown { border-style: dashed; opacity: .75; }
.ab-item.is-unknown.is-on { opacity: 1; }

/* ---------- 순위표 모달 ---------- */
.rank-tabs { display: flex; gap: 4px; flex-wrap: wrap; }
.rank-tab {
  padding: 5px 11px;
  border: 1px solid var(--card-border); border-radius: var(--radius-md);
  background: var(--card-bg); color: var(--muted);
  font: inherit; font-size: 12px; cursor: pointer; white-space: nowrap;
}
.rank-tab:hover { border-color: var(--accent); color: var(--text); }
.rank-tab.is-on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent-text); font-weight: 700; }

/* 스크롤은 .modal-body 하나만 — 안에 또 스크롤 상자를 두면 머리글 고정이 그 상자에 붙어
   화면에서는 영영 안 붙는다(스티키는 «가장 가까운 스크롤 조상» 을 기준으로 삼는다). */
.rank-table { width: 100%; border-collapse: collapse; font-size: 12px; table-layout: fixed; }
.rank-table th, .rank-table td { padding: 3px 6px; border-bottom: 1px solid #f0e8da; white-space: nowrap; text-align: left; }
.rank-table thead th {
  /* 스티키 기준은 .modal-body 의 «내용 상자» 라 padding(12px)만큼 내려붙는다.
     그만큼 끌어올려야 그 틈으로 행이 비쳐 지나가지 않는다. */
  /* 머리 영역(.rank-head) 바로 아래에 붙는다 — 높이는 JS 가 재서 넣는다(칩 줄이 접히면 달라짐) */
  position: sticky; top: var(--rank-head-h, 76px); z-index: 1;
  padding-top: 6px;
  background: var(--card-bg); box-shadow: inset 0 -1px 0 var(--card-border);
  font-size: 10.5px; color: var(--muted); font-weight: 600;
}
.rank-table thead th:nth-child(n+4) { text-align: center; }
.rank-table tbody tr { cursor: pointer; }
.rank-table .rk { width: 3.4em; text-align: right; font-variant-numeric: tabular-nums; color: var(--muted); }
.rank-table .nm { width: auto; max-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* table-layout: fixed 는 첫 행(머리글)의 폭만 본다 — 이름 칸만 폭을 비워 남는 자리를 받게 한다 */
.rank-table th:nth-child(1) { width: 3.6em; }   /* 순위 */
.rank-table th:nth-child(2) { width: 34px; }    /* 초상화 */
.rank-table th:nth-child(3) { width: 3.4em; }   /* 등급 */
/* 실측한 내용 폭에 맞춘다 — 합 30px · 보정값 49px · 특화도 57px(+순위 숫자) */
.rank-table th:nth-child(5) { width: 4.2em; }   /* 합 */
.rank-table th:nth-child(6) { width: 6.4em; }   /* 보정값 — 972(12) */
.rank-table th:nth-child(7) { width: 7.4em; }   /* 특화도 — 50.94%(102) 로 가장 넓다 */

/* 계열색 — 팔레트 카드(.mate-card.m-모험 …)와 같은 톤. 어느 계열인지 목록에서 바로 읽힌다 */
.rank-table tbody tr.m-모험 { background: var(--adventure-soft); }
.rank-table tbody tr.m-교역 { background: var(--trade-soft); }
.rank-table tbody tr.m-전투 { background: var(--combat-soft); }
/* 호버는 배경 대신 테두리로 — 배경을 덮으면 계열색이 사라진다 */
.rank-table tbody tr:not(.is-placed):hover td { box-shadow: inset 0 -1px 0 var(--accent), inset 0 1px 0 var(--accent); }

/* 이미 배치된 항해사 — 목록에는 남기되 고를 수 없다(같은 사람을 두 칸에 넣는 실수 방지) */
.rank-table tbody tr.is-placed { cursor: default; opacity: .5; }
.rank-table tbody tr.is-placed .nm { text-decoration: line-through; text-decoration-color: rgba(45, 36, 23, .35); }
.rk-placed {
  margin-left: 5px; font-style: normal; font-size: 10px; font-weight: 600;
  color: var(--accent-text); text-decoration: none;
  font-variant-numeric: tabular-nums;
}

/* 탭·필터 묶음 — 표 머리글과 함께 위에 붙는다.
   .modal-body 는 padding 12px 이라 top:-12px 로 끌어올려야 모달 맨 위에 닿는다. */
/* 순위표 모달은 위·아래 줄이 «고정» 이라 본문의 패딩·간격을 각 줄이 직접 갖는다.
   본문 padding(12px)과 flex gap(9px)이 남아 있으면, 스크롤 첫 21px 동안 고정 줄이
   그만큼 위로 밀려 「윗부분 높이가 흔들리는」 것처럼 보인다. */
.modal-box.is-rank .modal-body { padding-top: 0; padding-bottom: 0; gap: 0; }

.rank-head {
  position: sticky; top: 0; z-index: 3;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 0 8px;
  background: var(--card-bg);
}
/* 계열 칩 + 보유 토글 — 왼쪽 정렬. 폭이 모자라면 탭 아래 줄로 자연히 내려간다 */
.rank-filters { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* 등급 배지는 칸 가운데로 — 왼쪽 정렬이면 이름 열과 사이가 들쭉날쭉해 보인다 */
.rank-table td:nth-child(3) { text-align: center; }
.rank-table th:nth-child(3) { text-align: center; }

.rank-table .pt { padding: 2px 4px; }
.rank-table .pt .portrait-frame { display: inline-block; }
/* 표에서는 조금 작게 — URL(=w96)은 그대로라 팔레트와 캐시를 공유한다 */
.rank-table .mate-portrait { width: 24px; height: 24px; }
.rank-table .mate-portrait.no-portrait::before { font-size: 11px; }
.rank-table .num { text-align: center; }
/* 숫자는 고정폭 상자 안에서 오른쪽 정렬 — 자릿수가 달라도 오른쪽 끝이 맞는다 */
.rank-table .num .n { display: inline-block; min-width: 4.6ch; text-align: right; font-variant-numeric: tabular-nums; }
/* 그 값만으로 매긴 순위 — 작게 덧붙인다.
   («(102)» 처럼 자릿수가 달라도 숫자의 오른쪽 끝이 흔들리지 않도록 두 상자 모두 폭을 잡는다) */
.rank-table .num i {
  display: inline-block; min-width: 4.6ch; text-align: right;
  margin-left: 3px; font-style: normal; font-size: 9.5px; color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.rank-table td:nth-child(5) .n { min-width: 4.4ch; }   /* 합 — 모험은 1178 처럼 네 자리가 나온다 */
.rank-table td:nth-child(6) .n { min-width: 4.4ch; }   /* 보정값 — 1178 */
.rank-table td:nth-child(7) .n { min-width: 6.2ch; }   /* 특화도 — 50.94% */

@media (max-width: 720px) {
  /* 375px 에서는 고정 폭 숫자 열이 자리를 다 먹어 이름이 세 글자로 잘린다.
     「합」은 보정값의 재료일 뿐이라(이름 칸 툴팁에 그대로 있다) 좁은 화면에서만 접는다. */
  .rank-table th:nth-child(5), .rank-table td:nth-child(5) { display: none; }
  /* 등급 글자도 접는다 — 초상화 테두리·배경이 이미 등급색이라 뜻이 사라지지는 않는다 */
  .rank-table th:nth-child(3), .rank-table td:nth-child(3) { display: none; }
  .rank-table th:nth-child(6) { width: 5.8em; }
  .rank-table th:nth-child(7) { width: 6.8em; }
  .rank-table th, .rank-table td { padding: 3px 4px; }
}

/* 화면에는 안 보이되 스크린 리더에는 읽히는 라벨 (초상화 열 머리글 등) */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* 순위표 모달은 표가 필요한 만큼만 — 기본 620px 이면 이름 열만 129px 남는다 */
.modal-box.is-rank { max-width: 500px; }   /* 가장 긴 이름(148px)과 「50.94%(102)」까지 안 잘리는 최소 폭 */

/* 정렬 옆 「순위표」 — 드롭다운과 높이를 맞춘다. 순위 정렬이 아닐 때는 꺼진 채로 남는다
   (숨기면 줄이 들썩이고, 그런 기능이 있다는 것도 모르게 된다) */
.select-row .rank-detail { flex: none; padding: 5px 9px; }
.btn:disabled { opacity: .4; cursor: default; }
.btn:disabled:hover { border-color: var(--card-border); background: var(--card-bg); }

/* 순위 정렬일 때 카드에 붙는 순위 번호 */
.mate-rank {
  flex: none; min-width: 20px; padding: 0 4px; margin-right: 3px;
  border-radius: 3px; background: rgba(0, 0, 0, .07);
  font-size: 10px; line-height: 15px; text-align: center; color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* 순위표 안내 — 640행을 내려가도 바닥에 남는다 (.modal-body 의 padding 12px 만큼 내려붙인다) */
.rank-foot {
  position: sticky; bottom: 0; z-index: 3;
  margin-top: auto;
  padding: 7px 0 12px;
  background: var(--card-bg);
  box-shadow: inset 0 1px 0 var(--line);
}

/* 효과 이름의 계열색 — 스탯 라벨(.t-모험 …)과 «같은 잉크색» 을 쓴다.
   배경까지 칠하면 목록이 알록달록해져 글자색만 바꾼다. */
.eff-name.s-모험 { color: #355b95; }
.eff-name.s-교역 { color: #37693d; }
.eff-name.s-전투 { color: #8c4343; }

/* 주소로 넘겨받다 실패했을 때 — 안내 줄을 경고색으로 */
.data-note.is-error { background: #fbe4e0; border-bottom-color: var(--danger); color: #8c3b33; }
