/*
  디자인 메모
  - Legatus 로고 4색(#F9E6A8 #F2A900 #CC6F00 #4D2A00)에서 모든 색을 뽑는다. 밝은 바탕 #FFF9E9는 가장 옅은 색을 흰 쪽으로 옮긴 값.
  - 큰 면(틀, 레일, 채팅·지도 무대)은 밝기와 채도를 가깝게 맞춘다. 진한 색은 단추, 선택 표시, 지도 표시물처럼 작은 곳에만 쓴다.
  - 로고의 45도 판(plate)이 이 화면의 모양 언어다: 선택된 탭 표시, 지도 위 거리표, 지도 가장자리에 붙는 방향표.
  - 게임에서 온 글자(채팅, 좌표, 지도 위 거리)는 Galmuri, 화면 글자는 Noto Sans KR.
  - 흰 글자 단추는 #CC6F00 대신 #A55A00(5.2:1). #F2A900 위에는 흰 글자를 올리지 않는다.
*/

:root {
  color-scheme: light;
  --shell: #faf1d9;
  --rail-top: #f8edd0;
  --rail-bottom: #faf0d8;
  --card: #fff9e9;
  --line: #eadcb2;
  --line-strong: #dcc68c;
  --line-soft: #f2e7c8;
  --ink: #4d2a00;
  --ink-2: #6e4a1c;
  --muted: #80653d;
  --tint: #f9e6a8;
  --saffron: #f2a900;
  --amber: #cc6f00;
  --accent-ink: #a55a00;
  --accent-fill: #a55a00;
  --on-accent: #ffffff;
  --focus: var(--accent-ink);
  --good: #2e7d32;
  --warn: #b7791f;
  --bad: #b3261e;
  /* 채팅·지도 무대: 틀과 거의 같은 밝기 */
  --stage-top: #f8eed3;
  --stage-bottom: #faf1da;
  --motif: rgba(204, 111, 0, .075);
  --map-bg: #ece0bf;
  --scroll: #ddcb9c;
  --scroll-hover: #c4a970;
  /* 채팅 글자: 게임 색을 밝은 바탕에서 읽히게 눌렀다 */
  --chat-ink: #4d2a00;
  --chat-gray: #7a6446;
  --chat-dim: #6e5a3e;
  --chat-party: #0e6b88;      /* 게임 #7DDCFF */
  --chat-notice: #2f7a2f;     /* 게임 #A1E89E */
  --chat-guild: #2c6e49;
  --chat-whisper: #9c2c9c;
  --chat-red: #b03a2e;
  --chat-gold: #9a5a00;
  --chat-shadow: none;
  --plate: rgba(255, 250, 235, .64);
  --plate-hover: rgba(255, 255, 255, .94);
  --ctab: rgba(255, 255, 255, .32);
  --ctab-hover: rgba(255, 255, 255, .6);
  /* 지도 위 판: 어느 테마에서도 지형 위에서 읽히도록 짙은 갈색 판에 밝은 글자 */
  --sign: rgba(43, 24, 0, .86);
  --sign-ink: #fff3d6;
  --sign-accent: #f2a900;
  --pixel: Galmuri11, "Noto Sans KR", monospace;
  --pixel-chat: Galmuri14, Galmuri11, "Noto Sans KR", monospace;
  --pixel-mono: GalmuriMono11, Galmuri11, ui-monospace, monospace;
  --sans: "Noto Sans KR", "Malgun Gothic", system-ui, sans-serif;
  --r-card: 10px;
  --r-ctl: 7px;
  --slant: 7px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --shell: #1c140a;
    --rail-top: #21170c;
    --rail-bottom: #1e150b;
    --card: #281c0e;
    --line: #3d2d18;
    --line-strong: #5a4420;
    --line-soft: #30230f;
    --ink: #f6e8c8;
    --ink-2: #d8c39a;
    --muted: #ae9872;
    --accent-ink: #f5b83a;
    --accent-fill: #f2a900;
    --on-accent: #2b1800;
    --good: #6cc070;
    --warn: #e0a640;
    --bad: #ff7a6b;
    --stage-top: #20160b;
    --stage-bottom: #1c140a;
    --motif: rgba(242, 169, 0, .06);
    --map-bg: #15100a;
    --scroll: #4a3820;
    --scroll-hover: #6e5530;
    --chat-ink: #fff6e3;
    --chat-gray: #b5a688;
    --chat-dim: #c8b997;
    --chat-party: #7ddcff;
    --chat-notice: #a1e89e;
    --chat-guild: #7fe0a6;
    --chat-whisper: #ff7bff;
    --chat-red: #ff6b5b;
    --chat-gold: #ffb733;
    --chat-shadow: 1px 1px 0 rgba(0, 0, 0, .45);
    --plate: rgba(0, 0, 0, .22);
    --plate-hover: rgba(0, 0, 0, .38);
    --ctab: rgba(0, 0, 0, .14);
    --ctab-hover: rgba(0, 0, 0, .28);
  }
}

/* 사용자가 어둡게를 고른 경우. 값은 위 구역과 같아야 한다. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --shell: #1c140a;
  --rail-top: #21170c;
  --rail-bottom: #1e150b;
  --card: #281c0e;
  --line: #3d2d18;
  --line-strong: #5a4420;
  --line-soft: #30230f;
  --ink: #f6e8c8;
  --ink-2: #d8c39a;
  --muted: #ae9872;
  --accent-ink: #f5b83a;
  --accent-fill: #f2a900;
  --on-accent: #2b1800;
  --good: #6cc070;
  --warn: #e0a640;
  --bad: #ff7a6b;
  --stage-top: #20160b;
  --stage-bottom: #1c140a;
  --motif: rgba(242, 169, 0, .06);
  --map-bg: #15100a;
  --scroll: #4a3820;
  --scroll-hover: #6e5530;
  --chat-ink: #fff6e3;
  --chat-gray: #b5a688;
  --chat-dim: #c8b997;
  --chat-party: #7ddcff;
  --chat-notice: #a1e89e;
  --chat-guild: #7fe0a6;
  --chat-whisper: #ff7bff;
  --chat-red: #ff6b5b;
  --chat-gold: #ffb733;
  --chat-shadow: 1px 1px 0 rgba(0, 0, 0, .45);
  --plate: rgba(0, 0, 0, .22);
  --plate-hover: rgba(0, 0, 0, .38);
  --ctab: rgba(0, 0, 0, .14);
  --ctab-hover: rgba(0, 0, 0, .28);
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--shell);
  color: var(--ink);
  font: 14px/1.55 var(--sans);
  /* 한국어는 낱말 중간에서 끊지 않는다. 너무 긴 낱말만 끊는다. */
  word-break: keep-all;
  overflow-wrap: anywhere;
}
button, input { font: inherit; color: inherit; }
button { cursor: pointer; }
code { font-family: ui-monospace, Consolas, monospace; font-size: 12px; color: var(--accent-ink); }
[hidden] { display: none !important; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track, ::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--scroll) content-box; border: 3px solid transparent; border-radius: 999px; }
::-webkit-scrollbar-thumb:hover { background: var(--scroll-hover) content-box; }
/* Chrome은 scrollbar-color가 있으면 위 규칙을 무시하므로 지원 안 하는 브라우저(Firefox)에만 건다 */
@supports not selector(::-webkit-scrollbar) {
  * { scrollbar-width: thin; scrollbar-color: var(--scroll) transparent; }
}

:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.error { color: var(--bad); }
.stage .error { color: var(--chat-red); }

/* ---------- 무대 배경: 로고의 판 세 장이 아주 옅게 깔린다 */

.stage {
  position: relative; isolation: isolate; overflow: hidden;
  background: linear-gradient(170deg, var(--stage-top), var(--stage-bottom));
}
.stage::before {
  content: ""; position: absolute; z-index: -1; right: -8%; bottom: -14%; width: min(78vmin, 760px); aspect-ratio: 1 / .7992;
  background: var(--motif);
  -webkit-mask: url("symbol.svg") center / contain no-repeat;
  mask: url("symbol.svg") center / contain no-repeat;
}

/* ---------- 로고 */

.wordmark { display: inline-flex; align-items: center; gap: 10px; margin: 0; color: var(--ink); }
.mark { width: 30px; height: 30px; flex: none; border-radius: 7px; }
/* 글자는 PNG의 모양만 쓰고 색은 글자색을 따라간다. 어두운 화면에서도 보여야 한다. */
.wordmark-text {
  display: block; width: 110px; height: 13px; background: currentColor;
  -webkit-mask: url("wordmark.png") left center / contain no-repeat;
  mask: url("wordmark.png") left center / contain no-repeat;
}

/* ---------- 로그인 */

.login { min-height: 100%; display: grid; place-items: center; padding: 16px; }
.login-card {
  width: min(400px, 100%); padding: 28px; display: grid; gap: 14px; border-radius: 14px;
  border: 1px solid var(--line); background: var(--card); color: var(--ink); box-shadow: 0 14px 40px rgba(77, 42, 0, .12);
}
.login-card .mark { width: 40px; height: 40px; border-radius: 9px; }
.login-card .wordmark-text { width: 152px; height: 18px; }
.login-card p { margin: 0; color: var(--ink-2); font-size: 13px; }
.field { display: grid; gap: 6px; font-size: 12px; color: var(--ink-2); }
.field input {
  padding: 9px 12px; background: var(--shell); color: var(--ink); border: 1px solid var(--line-strong);
  border-radius: var(--r-ctl); font-size: 15px;
}
.login-card button {
  padding: 11px; border: 0; border-radius: var(--r-ctl); background: var(--accent-fill); color: var(--on-accent); font-weight: 700;
}

/* ---------- 틀 */

.app { height: 100%; display: flex; flex-direction: column; }
.topbar {
  display: flex; align-items: center; gap: 28px; padding: 0 20px; min-height: 56px;
  background: var(--shell); border-bottom: 1px solid var(--line);
}
.tabs { display: flex; gap: 22px; align-self: stretch; }
.tabs button {
  position: relative; border: 0; background: none; padding: 0 4px; color: var(--muted); font-weight: 600; font-size: 14px;
}
.tabs button:hover { color: var(--ink-2); }
.tabs button[aria-selected="true"] { color: var(--ink); }
/* 선택 표시는 로고의 판처럼 45도로 깎인 막대 */
.tabs button[aria-selected="true"]::after {
  content: ""; position: absolute; left: -2px; right: -2px; bottom: -1px; height: 4px;
  background: linear-gradient(90deg, var(--saffron), var(--amber));
  clip-path: polygon(4px 0, 100% 0, calc(100% - 4px) 100%, 0 100%);
}
.status { margin-left: auto; display: flex; align-items: center; gap: 14px; }
.pill { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--ink-2); white-space: nowrap; }
.pill .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); }
.pill.ok .dot { background: var(--good); }
.pill.warn .dot { background: var(--warn); }
.pill.bad .dot { background: var(--bad); }
.icon-button {
  display: inline-flex; align-items: center; justify-content: center; height: 30px; min-width: 30px; padding: 0 7px;
  border: 1px solid var(--line); border-radius: var(--r-ctl); background: var(--card); color: var(--ink-2);
}
.icon-button:hover { border-color: var(--line-strong); color: var(--ink); }
.icon-button svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
/* 누르면 바뀔 쪽을 보여 준다: 밝을 때 달, 어두울 때 해 */
#theme-toggle[data-next="light"] .i-moon, #theme-toggle[data-next="dark"] .i-sun { display: none; }
.link-button { border: 0; background: none; padding: 0; color: var(--muted); font-size: 12px; text-decoration: underline; }
main { flex: 1; min-height: 0; }
.tab { height: 100%; }

/* ---------- 왼쪽 레일 (채팅·지도 공통) */

.chat-layout, .map-layout { display: grid; grid-template-columns: 252px minmax(0, 1fr); min-height: 0; }
.filters, .map-rail {
  background: linear-gradient(180deg, var(--rail-top), var(--rail-bottom)); border-right: 1px solid var(--line);
  padding: 16px; overflow-y: auto; display: flex; flex-direction: column; gap: 10px;
}
.filters h2, .map-rail h2 { margin: 6px 0 0; font-size: 12px; font-weight: 600; color: var(--muted); }
.filter-row { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.chips { display: flex; flex-wrap: wrap; gap: 5px; }
.chip {
  display: inline-flex; align-items: center; gap: 7px; padding: 4px 9px 4px 7px;
  border: 1px solid transparent; border-radius: var(--r-ctl); background: transparent; color: var(--ink-2); font-size: 13px;
}
.chip .swatch {
  width: 10px; height: 10px; flex: none; background: var(--c, var(--muted)); opacity: .35;
  clip-path: polygon(3px 0, 100% 0, calc(100% - 3px) 100%, 0 100%);
}
.chip .n { font: 12px/1 var(--pixel-mono); color: var(--muted); }
.chip[aria-pressed="true"] { background: var(--card); border-color: var(--line); color: var(--ink); font-weight: 600; }
.chip[aria-pressed="true"] .swatch { opacity: 1; }
.chip:hover { border-color: var(--line-strong); }
.options { margin-top: 6px; }
.mix-only { display: contents; }
.tab-note { display: none; margin: 0; font-size: 12px; color: var(--muted); }
.in-tab .mix-only { display: none; }
.in-tab .tab-note { display: block; }
.in-tab .options { margin-top: 0; }
.check { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--ink-2); white-space: nowrap; }
.check input { accent-color: var(--amber); margin: 0; }
.search input {
  width: 100%; padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--r-ctl); background: var(--card); font-size: 13px;
}
.hint { margin: 0; font-size: 11.5px; color: var(--muted); }
.filters .hint { margin-top: auto; }

/* ---------- 채팅 */

.chat-main { display: flex; flex-direction: column; min-height: 0; }
.chat-tabs { display: flex; gap: 2px; padding: 12px 20px 0; flex: none; overflow-x: auto; scrollbar-width: none; }
.chat-tabs::-webkit-scrollbar { display: none; }
.ctab {
  display: inline-flex; align-items: center; gap: 6px; flex: none; border: 0; padding: 8px 12px 7px;
  background: var(--ctab); color: var(--chat-dim); font: 12px/1 var(--pixel); text-shadow: var(--chat-shadow);
}
.ctab:hover { background: var(--ctab-hover); color: var(--chat-ink); }
.ctab[aria-selected="true"] { background: var(--plate); color: var(--chat-ink); box-shadow: inset 0 2px 0 var(--c, var(--amber)); }
.ctab-n:empty { display: none; }
.ctab-n { font: 12px/1 var(--pixel-mono); color: var(--chat-gold); }

.chat-scroll { flex: 1; overflow-y: auto; padding: 0 10px 12px 20px; } /* 오른쪽은 스크롤 막대(10px)만큼 덜어 끝을 맞춘다 */
.messages { list-style: none; margin: 0; padding: 0; }
.msg {
  display: grid; grid-template-columns: 62px 74px 1fr; column-gap: 8px; align-items: baseline;
  padding: 3px 10px; background: var(--plate); color: var(--chat-ink); font: 15px/21px var(--pixel-chat); text-shadow: var(--chat-shadow);
}
.msg:hover { background: var(--plate-hover); }
.msg.fresh { animation: surface .22s ease-out; }
@keyframes surface { from { opacity: 0; transform: translateY(4px); } }
.msg time { font: 12px/21px var(--pixel-mono); color: var(--chat-gray); white-space: nowrap; }
.badge { font: 12px/21px var(--pixel); color: var(--c, var(--chat-gray)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.content { white-space: pre-wrap; word-break: break-word; min-width: 0; }
.content .sender { color: var(--chat-ink); }
.cat-party .content .sender, .cat-party .content .body { color: var(--chat-party); }
.cat-whisper .content { font-style: italic; }
.cat-whisper .sender { color: var(--chat-whisper); }
.cat-notice .content { color: var(--chat-notice); }
.cat-system .content { color: var(--chat-dim); }
.msg.mine { background: rgba(242, 169, 0, .16); box-shadow: inset 3px 0 0 var(--saffron); }

.day { padding: 10px 10px 4px; color: var(--chat-gray); font: 12px/18px var(--pixel); text-shadow: var(--chat-shadow); }
.day::before { content: "── "; }
.day:first-child { padding-top: 0; }

.cat-chat { --c: var(--chat-gold); }
.cat-party { --c: var(--chat-party); }
.cat-guild { --c: var(--chat-guild); }
.cat-whisper { --c: var(--chat-whisper); }
.cat-notice { --c: var(--chat-notice); }
.cat-system { --c: var(--chat-gray); }

.load-older {
  display: block; width: 100%; margin: 0; border: 0; padding: 6px 10px; text-align: left;
  background: var(--plate); color: var(--chat-gray); font: 12px/1.4 var(--pixel);
}
.load-older:hover { color: var(--chat-ink); }
.empty { margin: 24px 0; color: var(--chat-dim); font: 15px/21px var(--pixel-chat); text-shadow: var(--chat-shadow); }
.jump-new {
  position: absolute; left: 20px; bottom: 54px; border: 0; padding: 7px 12px;
  border-radius: 6px; background: var(--accent-fill); color: var(--on-accent); font: 12px/1 var(--pixel);
  box-shadow: 0 2px 0 rgba(0, 0, 0, .3);
}
.readonly-bar {
  margin: 0; padding: 11px 20px 13px; border-top: 1px solid var(--line); font-size: 12px; color: var(--muted);
  background: var(--plate);
}

/* ---------- 지도: 레일 */

.rail-block { display: flex; flex-direction: column; gap: 8px; }
.segmented { display: inline-flex; overflow: hidden; border: 1px solid var(--line); border-radius: var(--r-ctl); background: var(--card); align-self: flex-start; }
.segmented button { border: 0; background: none; padding: 6px 16px; color: var(--ink-2); font-size: 13px; }
.segmented button + button { border-left: 1px solid var(--line); }
.segmented button[aria-pressed="true"] { background: var(--accent-fill); color: var(--on-accent); font-weight: 600; }
.segmented:empty { display: none; }
.layer-list { display: grid; gap: 7px; }
.key { width: 16px; height: 16px; flex: none; image-rendering: pixelated; }
/* 채집물 범례. map.js(paintLegend)가 지도에 있는 아이템마다 한 줄씩 넣는다(실제 아이템 이름과 그림).
   감싸는 상자는 없는 셈 쳐서 줄들이 .layer-list의 다른 줄과 나란히 선다 */
.node-legend { display: contents; }
/* 얻는 아이템을 아직 모르는 채집물 줄: 그 노드들의 분류 아이콘을 나란히 */
.legend-cats { display: inline-flex; gap: 2px; flex: none; }
/* 원(1.4배)이 줄 높이를 밀지 않게 바깥 여백을 줄인다 */
.key-item { display: inline-grid; place-items: center; flex: none; width: 22px; height: 22px; margin: -3px; background: url("map/item_backdrop.png") center / 22px 22px no-repeat; }
.key-item img { width: 16px; height: 16px; image-rendering: pixelated; }
.key-me {
  display: inline-block; background: var(--saffron);
  clip-path: polygon(50% 0, 100% 100%, 50% 74%, 0 100%);
}
.key-area { display: inline-grid; place-items: center; font: 12px/16px var(--pixel); color: var(--ink); }
/* LO가 고른 그림 아이콘(NPC, 퀘스트, 던전 입구, 역참 마차, tools/cut_icons.py가 자른 것). 원본이 80~120px라
   줄일 때 계단이 지지 않게 부드럽게 줄인다. 줄 높이를 밀지 않게 바깥 여백을 줄인다 */
.key-pic { width: 22px; height: 22px; margin: -3px; object-fit: contain; image-rendering: auto; }
.quest-card { padding: 12px; border: 1px solid var(--line); border-radius: var(--r-card); background: var(--card); gap: 4px; }
.quest-card h2 { margin: 0; }
.quest-name { margin: 2px 0 0; font-weight: 700; font-size: 14px; color: var(--ink); }
.quest-step { margin: 0; font-size: 13px; color: var(--ink-2); }
.quest-meta { margin: 4px 0 0; font: 12px/1.5 var(--pixel); color: var(--accent-ink); }
.rail-foot { margin-top: auto; gap: 6px; }
.map-where { margin: 0; font-size: 12.5px; color: var(--ink-2); }

/* ---------- 지도: 무대 */

.map-stage { position: relative; min-height: 0; overflow: hidden; background: var(--map-bg); }
.map { position: absolute; inset: 0; background: var(--map-bg); }
.leaflet-container { font: 12px/1.4 var(--sans); background: var(--map-bg); outline: 0; }
/* 1칸 = 1픽셀 그림을 확대할 때 흐리지 않게 */
.leaflet-tile { image-rendering: pixelated; }
.leaflet-container .leaflet-control-attribution { display: none; }

/* 지도 위 표시물 */
/* 채집물은 게임(GatherMap NodeIcons)과 같게 그린다.
   얻는 아이템을 모르는 종류: 분류 아이콘. 상태는 _remembered, _gone 그림이 이미 나타내므로 더 흐리게 하지 않는다. */
.lg-node { width: 18px; height: 18px; image-rendering: pixelated; }
/* 아는 종류: 아이콘의 1.4배 크기의 어두운 원 위에 아이템 그림. */
.lg-item { display: grid; place-items: center; width: 26px; height: 26px; background: url("map/item_backdrop.png") center / 25px 25px no-repeat; }
.lg-item img { width: 18px; height: 18px; image-rendering: pixelated; }
/* 기억: 게임 틴트 0x99FFFFFF, 원과 그림을 함께 불투명도 60%로 */
.lg-item.remembered { opacity: .6; }
/* 비어 있음: 게임 틴트 0x80606060. 그림은 0.376배로 어둡게 하고 원은 흐리게만, 둘 다 불투명도 50% */
.lg-item.gone { opacity: .5; }
.lg-item.gone img { filter: brightness(.376); }
/* 서버에 그림이 없어 분류 아이콘으로 바꾼 것. 상태는 그 아이콘 그림이 나타낸다 */
.lg-item.fallback, .key-item.fallback { background: none; opacity: 1; }
.lg-item.fallback img, .key-item.fallback img { filter: none; }
.lg-me { position: relative; width: 26px; height: 26px; }
.lg-me .ring {
  position: absolute; inset: -6px; border-radius: 50%; border: 2px solid var(--saffron); opacity: 0;
  animation: ping 2.4s ease-out infinite;
}
.lg-me svg { position: absolute; inset: 0; width: 26px; height: 26px; overflow: visible; filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, .55)); }
.lg-me .arrow { fill: var(--saffron); stroke: #2b1800; stroke-width: 1.6; stroke-linejoin: round; }
.lg-me.stale .arrow { fill: #b9a77e; }
.lg-me.stale .ring { display: none; }
@keyframes ping { 0% { transform: scale(.5); opacity: .8; } 80%, 100% { transform: scale(1.5); opacity: 0; } }
.lg-quest { display: block; width: 26px; height: 26px; object-fit: contain; filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, .55)); }

/* 판: 로고의 45도 평행사변형. 거리표와 가장자리 방향표에 쓴다 */
.plate {
  display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 calc(var(--slant) + 7px);
  background: var(--sign); color: var(--sign-ink); font: 12px/22px var(--pixel); white-space: nowrap;
  clip-path: polygon(var(--slant) 0, 100% 0, calc(100% - var(--slant)) 100%, 0 100%);
}
.plate b { font-weight: 400; color: var(--sign-accent); }
.lg-label { position: absolute; left: 50%; top: 100%; margin-top: 4px; transform: translateX(-50%); pointer-events: none; }

.edge-pins { position: absolute; inset: 0; pointer-events: none; z-index: 650; }
.edge-pin {
  position: absolute; pointer-events: auto; border: 0; padding: 0 calc(var(--slant) + 8px) 0 calc(var(--slant) + 4px);
  transform: translate(-50%, -50%); cursor: pointer;
}
.edge-pin .dir { display: inline-block; width: 10px; height: 10px; background: var(--sign-accent); clip-path: polygon(0 0, 100% 50%, 0 100%, 28% 50%); }
.edge-pin:hover { --sign: rgba(77, 42, 0, .95); }
.edge-pin:focus-visible { outline-offset: 3px; }

.map-tools { position: absolute; right: 14px; top: 14px; z-index: 700; display: flex; gap: 8px; align-items: flex-start; }
.zoom { display: flex; flex-direction: column; }
.map-button {
  display: inline-flex; align-items: center; gap: 6px; height: 32px; min-width: 32px; justify-content: center; padding: 0 10px;
  border: 1px solid var(--line-strong); background: var(--card); color: var(--ink); font-size: 13px; border-radius: var(--r-ctl);
  box-shadow: 0 2px 8px rgba(43, 24, 0, .18);
}
.zoom .map-button { font-size: 17px; line-height: 1; padding: 0; }
.zoom .map-button:first-child { border-radius: var(--r-ctl) var(--r-ctl) 0 0; }
.zoom .map-button + .map-button { border-top: 0; border-radius: 0 0 var(--r-ctl) var(--r-ctl); }
.map-button svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.map-button[aria-pressed="true"] { background: var(--accent-fill); color: var(--on-accent); border-color: var(--accent-fill); }
.map-button:disabled { opacity: .5; cursor: default; }

.readout { position: absolute; left: 14px; bottom: 14px; z-index: 700; margin: 0; }
.readout:empty { display: none; }

/* 3D를 골랐는데 아직 3D 그림이 없을 때 위에 한 줄 */
.map-notice {
  position: absolute; left: 14px; top: 14px; right: 200px; z-index: 700; max-width: 520px;
  padding: 7px 12px; background: var(--sign); color: var(--sign-ink); font-size: 12.5px; line-height: 1.5;
  border-left: 3px solid var(--sign-accent);
}
.map-notice[hidden] { display: none; }

/* 지역 이름표: Wynncraft 지도처럼 땅 위에 크게, 게임 글꼴로. 크기 0인 표시물 한가운데에 놓는다 */
.lg-area {
  position: absolute; left: 0; top: 0; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; white-space: nowrap; cursor: default;
  color: #fff3d6; text-align: center;
  text-shadow: 0 0 2px #2b1800, 0 0 2px #2b1800, 1px 1px 0 #2b1800, -1px 1px 0 #2b1800, 1px -1px 0 #2b1800, -1px -1px 0 #2b1800;
}
.lg-area .name { font: 18px/1.2 var(--pixel); letter-spacing: .02em; }
.lg-area .lv { font: 12px/1.3 var(--pixel); color: var(--sign-accent); }
.map.far .lg-area .name { font-size: 14px; }
/* 멀리서는 채집물이 섬마다 수십 개라 작게 줄여 분포만 보이게 한다 */
.map.far .lg-item, .map.far .lg-node { transform: scale(.5); }
.map.far .lg-area .lv { display: none; }
/* 가까이 보면 땅을 가리지 않게 흐리게 */
.map.near .lg-area { opacity: .55; }

/* NPC: 스킨 얼굴, 얼굴을 모르면 NPC 그림. 이름은 가까이 볼 때만 */
.lg-npc { position: relative; width: 14px; height: 14px; }
.lg-npc .tag, .lg-dungeon .tag, .lg-carriage .tag {
  position: absolute; left: 50%; bottom: 100%; margin-bottom: 4px; transform: translateX(-50%);
  height: 20px; padding: 0 calc(var(--slant) + 6px); background: var(--sign); color: var(--sign-ink);
  font: 11px/20px var(--pixel); white-space: nowrap; pointer-events: none;
  clip-path: polygon(var(--slant) 0, 100% 0, calc(100% - var(--slant)) 100%, 0 100%);
}
.lg-npc .tag { display: none; }
.map.near .lg-npc .tag { display: block; }
.map.far .lg-npc { display: none; }
/* 얼굴: 스킨 8x8을 키운 그림. 짙은 갈색 테두리 + 사프란 한 줄로 지형 위에서 떠 보이게 */
.lg-npc.face { width: 22px; height: 22px; }
.lg-npc.face img {
  display: block; width: 22px; height: 22px; image-rendering: pixelated;
  border: 2px solid #2b1800; outline: 1.5px solid var(--saffron); box-shadow: 0 2px 4px rgba(0, 0, 0, .55);
  box-sizing: border-box; background: #2b1800;
}
.map.near .lg-npc.face img { transform: scale(1.3); }
/* 얼굴을 모르는 NPC: 범례와 같은 NPC 그림 */
.lg-npc.figure { width: 18px; height: 22px; }
.lg-npc.figure img { display: block; width: 18px; height: 22px; object-fit: contain; filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, .55)); }
.map.near .lg-npc.figure img { transform: scale(1.3); }
.lg-npc.face .tag { margin-bottom: 6px; }
.map.near .lg-npc.face .tag { margin-bottom: 10px; }
/* 붙어 있는 NPC 이름표는 map.js(layoutNpcTags)가 자리를 옮긴다. 위로 멀리 올린 이름표는 이 선으로 얼굴과 잇는다 */
.lg-npc .leader { position: absolute; width: 2px; margin-left: -1px; background: #2b1800; pointer-events: none; }
/* 옮긴 이름표가 이웃 얼굴 밑에 깔리지 않게 */
.lg-npc .tag { z-index: 1; }

/* 던전 입구: 해골 돌문 그림. 이름과 레벨은 늘 보인다 */
.lg-dungeon { position: relative; width: 30px; height: 30px; }
.lg-dungeon .gate { display: block; width: 30px; height: 30px; object-fit: contain; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .6)); }
.lg-dungeon .tag b { font-weight: 400; color: var(--sign-accent); }
.map.far .lg-dungeon .tag { display: none; }

/* 역참 마차: 마을·사냥터 사이 순간이동. 이름은 던전처럼 늘 보이고, 멀리서는 그림만 */
.lg-carriage { position: relative; width: 32px; height: 28px; }
.lg-carriage img { display: block; width: 32px; height: 28px; object-fit: contain; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .6)); }
.map.far .lg-carriage .tag { display: none; }
.map.near .lg-carriage img, .map.near .lg-dungeon .gate { transform: scale(1.3); transform-origin: 50% 90%; }
.map.near .lg-carriage .tag, .map.near .lg-dungeon .tag { margin-bottom: 10px; }

.map-empty {
  position: absolute; inset: 0; z-index: 800; display: grid; place-content: center; gap: 6px; padding: 24px; text-align: center;
  background: var(--map-bg); color: var(--ink-2); font-size: 13px;
}
.map-empty p { margin: 0; max-width: 360px; }
.map-empty-title { font-weight: 700; font-size: 15px; color: var(--ink); }

.tooltip {
  position: fixed; z-index: 1000; pointer-events: none; padding: 6px 10px; max-width: 280px;
  border-radius: 6px; background: rgba(43, 24, 0, .95); color: #fff3d6; font: 12px/18px var(--sans);
}
.tooltip b { display: block; font-weight: 600; color: var(--saffron); }

/* ---------- 좁은 화면 */

@media (max-width: 760px) {
  .topbar { flex-wrap: wrap; gap: 4px 16px; padding: 8px 14px 0; }
  .topbar .wordmark { gap: 8px; }
  .topbar .mark { width: 24px; height: 24px; border-radius: 6px; }
  .topbar .wordmark-text { width: 86px; height: 10px; }
  .status { gap: 10px; }
  .tabs { order: 3; width: 100%; height: 38px; }

  .chat-layout, .map-layout { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .filters, .map-rail { min-width: 0; border-right: 0; border-bottom: 1px solid var(--line); padding: 10px 14px; gap: 8px; overflow: visible; }
  .filters h2, .filters .hint { display: none; }
  .chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin: 0 -14px; padding: 0 14px; }
  .chips::-webkit-scrollbar { display: none; }
  .chip { flex: none; }
  .options { margin-top: 0; }

  .map-rail { gap: 8px; }
  .map-rail h2, .rail-foot .hint { display: none; }
  .map-rail .rail-block { min-width: 0; }
  /* 표시 목록은 한 줄로 두고 가로로 밀어 본다. 화면 전체가 옆으로 밀리지 않게 칸 안에서만 */
  .layer-list { display: flex; gap: 14px; overflow-x: auto; scrollbar-width: none; margin: 0 -14px; padding: 2px 14px; }
  .layer-list::-webkit-scrollbar { display: none; }
  .layer-list .check { flex: none; }
  .quest-card { width: 100%; padding: 8px 10px; }
  .rail-foot { margin-top: 0; width: 100%; }

  .chat-tabs { padding: 8px 10px 0; }
  .chat-scroll { padding: 0 10px 8px; }
  .msg { display: block; padding: 4px 8px; }
  .msg time, .msg .badge { margin-right: 8px; }
  .readonly-bar { padding: 8px 12px 10px; }
  .jump-new { left: 10px; bottom: 50px; }
  .map-tools { right: 10px; top: 10px; }
  .readout { left: 10px; bottom: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .msg.fresh { animation: none; }
  .lg-me .ring { animation: none; opacity: 0; }
}
