* { margin: 0; padding: 0; box-sizing: border-box; }

/* ── 테마 (docs/테마-설계.md) ─────────────
   기본(속성 없음) = 베이직: 역사지도 종이톤 베이지. data-theme은 head의
   인라인 스크립트가 localStorage에서 읽어 첫 페인트 전에 찍는다 —
   main.js(모듈, 지연 실행)에서 하면 테마 깜빡임(FOUC)이 보인다.
   대부분의 색이 --accent·--ink·--bg의 color-mix 파생이라
   테마는 기둥 변수 몇 개만 갈아 끼우면 전체가 따라온다.
   2026-07-30 재정의: 흰색=순백 · 베이직=종이 베이지(기본) · 검은색=다크 청록. */
:root {
  --bg: #e8e0cf;               /* 종이 베이지 — 역사지도 종이색(LAND_LIGHT)과 동일 */
  --accent: #a97a35;           /* 어두운 앰버 — 밝은 바탕 대비 */
  --ink: #2b2a24;
  --ink-dim: color-mix(in srgb, var(--ink) 62%, transparent);
  --line: color-mix(in srgb, var(--accent) 42%, transparent);
  --surface: rgba(246, 238, 221, 0.93);
  --halo: rgba(246, 238, 221, 0.75);  /* 지도 위 텍스트 그림자 (브랜드 등) */
  /* UI 표면(패널·팝업·알약)의 그림자 색. 밝은 테마에 다크용 진한 검정을 쓰면
     얼룩처럼 번져 보인다 — 테마마다 따로 준다 (지도 위 마커는 제외). */
  --sh: rgba(74, 60, 34, 0.16);
  --rail-w: 52px;              /* 좌·우 세로 아이콘 레일 너비 */
  --nav-h: 48px;               /* 최상단 네비게이션 바 높이 */
  --brail-h: 36px;             /* 최하단 가로 바 높이 */
  --panel-w: 264px;            /* 우측 패널(설정·지도상세·연대표상세) 폭 */
  /* 지도 출처 표기(MapLibre attribution) 한 줄 높이.
     라이선스상 가릴 수 없으므로 바닥에 붙는 컨트롤이 이만큼 비켜선다.
     접혀 있을 때(ⓘ)도 오른쪽 끝에 24px을 차지해 축척 바와 부딪힌다. */
  --attrib-h: 24px;
}
/* 하단이 차지하는 총 높이 = 바 + (열려 있다면) 연대표.
   바닥에 붙는 것들(레일·패널·축척 바·범례·저작권)은 전부 이 하나만 본다.
   body에 두는 이유: --brail-h를 덮는 규칙(map-focus)이 body에 있어서,
   :root에 두면 계산이 html에서 먼저 굳어 버려 따라오지 않는다. */
body { --btm-h: var(--brail-h); }
body.tl-open { --btm-h: calc(var(--brail-h) + var(--tl-h)); }
:root[data-theme="light"] {
  --bg: #fdfdfb;               /* 순백 — 중성, 온기 최소 */
  --ink: #24241f;
  --line: color-mix(in srgb, var(--accent) 30%, transparent);
  --surface: rgba(255, 255, 255, 0.92);
  --halo: rgba(255, 255, 255, 0.8);
  --sh: rgba(40, 40, 34, 0.14);
}
:root[data-theme="black"] {
  --bg: #0d1618;               /* 다크 청록 + 밝은 앰버 — 이 앱의 원래 얼굴 */
  --accent: #d69a4e;
  --ink: #f4f1ea;
  --line: color-mix(in srgb, var(--accent) 28%, transparent);
  --surface: rgba(14, 22, 24, 0.86);
  --halo: rgba(0, 0, 0, 0.7);
  --sh: rgba(0, 0, 0, 0.45);
}

html, body { height: 100%; }

body {
  font-family: "Noto Sans KR", -apple-system, BlinkMacSystemFont, sans-serif;
  background: var(--bg);
  color: var(--ink);
  overflow: hidden;
}

#map { position: fixed; top: var(--nav-h); left: 0; right: 0; bottom: 0; }

/* MapLibre 컨트롤 톤 맞추기 */
.maplibregl-ctrl-attrib { font-family: "IBM Plex Mono", monospace; font-size: 10px; }
.maplibregl-ctrl-group { background: var(--surface); border: 1px solid var(--line); }
.maplibregl-ctrl-group button { background: transparent; }

/* ── 최상단 네비게이션 ─────────────────
   서비스명 + 대메뉴(지도·연대표, 앞으로 매거진 등). 좌·우 레일과 패널이
   모두 이 바 아래에서 시작한다(--nav-h). */
.topnav {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--nav-h);
  z-index: 20;                 /* 연대표 패널(14)보다 위 — 항상 접근 가능 */
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 0 16px;
  background: var(--surface);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.topnav-menu { display: flex; align-items: center; gap: 4px; }
.nav-item {
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 500;
  padding: 6px 13px;
  transition: all 0.15s ease;
}
.nav-item:hover { color: var(--ink); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.nav-item.is-active {
  color: var(--ink);
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 18%, transparent);
}

.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  flex: 0 0 auto;
}
.brand-mark { color: var(--accent); font-size: 20px; line-height: 1; }
.brand-name {
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.02em;
}

/* ── 컨트롤 패널 ─────────────────────── */
.panel {
  position: fixed;
  top: var(--nav-h);
  right: var(--rail-w);        /* 세로 레일 왼쪽에 붙는다 */
  bottom: var(--btm-h);        /* 하단 바(+연대표) 위에서 끝난다 */
  z-index: 12;
  width: var(--panel-w);
  background: var(--surface);
  backdrop-filter: blur(10px);
  border-left: 1px solid var(--line);
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow-y: auto;
  box-shadow: -8px 0 40px var(--sh);
  transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 접힐 때는 레일 너비까지 더 밀어야 화면 밖으로 완전히 나간다 */
.panel.is-collapsed { transform: translateX(calc(100% + var(--rail-w))); }

/* ── 패널 폭 조절 손잡이 (패널 왼쪽 가장자리) ──
   연대표 높이 손잡이(.tl-resize)를 90° 돌린 것. 패널이 열려 있을 때만 나타나고,
   폭이 바뀌면 패널 가장자리를 따라 함께 움직인다. */
.panel-resize {
  position: fixed;
  top: var(--nav-h);
  bottom: var(--btm-h);
  right: calc(var(--rail-w) + var(--panel-w) - 5px);
  width: 10px;
  z-index: 13;                 /* 패널(12) 위 — 가장자리에서 바로 잡힌다 */
  cursor: ew-resize;
  touch-action: none;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
body.rail-open .panel-resize { opacity: 1; pointer-events: auto; }
/* 손잡이 자체는 세로 두 줄. 패널 세로 가운데에 걸터앉는다. */
.panel-grip {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  gap: 2.5px;
  padding: 13px 2.5px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--line);
  transition: border-color 0.15s ease;
}
.panel-grip i {
  display: block;
  width: 1.5px; height: 22px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--ink) 32%, transparent);
  transition: background 0.15s ease;
}
.panel-resize:hover .panel-grip,
.panel-resize:active .panel-grip { border-color: var(--accent); }
.panel-resize:hover .panel-grip i,
.panel-resize:active .panel-grip i { background: var(--accent); }
/* 끄는 동안에는 패널이 손가락을 뒤따라야 한다 — 폭에 붙은 전환 효과를 끈다 */
body.panel-rz .panel,
body.panel-rz .panel-resize { transition: none; }
body.panel-rz { cursor: ew-resize; user-select: none; }

/* 패널 헤더 (제목 + 닫기) */
.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 4px;
}
.panel-head-title { font-size: 13px; font-weight: 700; letter-spacing: 0.02em; }
.panel-close {
  width: 26px; height: 26px;
  border: 1px solid var(--line); border-radius: 6px;
  background: transparent; color: var(--ink-dim);
  cursor: pointer; font-size: 12px; line-height: 1;
  transition: all 0.15s ease;
}
.panel-close:hover { color: var(--ink); border-color: var(--accent); }

/* ── 우측 세로 아이콘 레일 ───────────────── */
/* 화면 오른쪽 끝에 고정. 패널이 열리고 닫혀도 항상 같은 자리에 있다. */
.rail {
  position: fixed;
  top: var(--nav-h); right: 0; bottom: var(--btm-h);
  z-index: 13;                 /* 패널(12)보다 위 */
  width: var(--rail-w);
  background: var(--surface);
  backdrop-filter: blur(10px);
  border-left: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 14px 0;
  box-shadow: -8px 0 40px var(--sh);
  transition: box-shadow 0.2s ease;
}
/* 패널이 열리면 레일과 패널은 이어진 한 면이다 — 레일 그림자가 패널 위로
   떨어지면 둘 사이에 얼룩진 띠가 생긴다. 경계는 border-left 한 줄로 충분. */
body.rail-open .rail:not(.rail-left) { box-shadow: none; }
body.lrail-open .rail-left { box-shadow: none; }

/* 좌측 레일 — 같은 컴포넌트를 방향만 뒤집어 쓴다. 공간 레이어가 첫 항목이고,
   앞으로 늘어날 좌측 패널(주제·인물·사건)이 여기에 쌓인다. */
.rail-left {
  right: auto;
  left: 0;
  border-left: none;
  border-right: 1px solid var(--line);
  box-shadow: 8px 0 40px var(--sh);
}
.rail-btn {
  width: 40px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 7px 0;
  border: 1px solid transparent;
  border-radius: 9px;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  font-family: inherit;
  transition: all 0.15s ease;
}

/* 검색 뒤로 가기는 폰 전용 — 넓은 화면은 바깥을 누르면 닫힌다 */
.search-back { display: none; }
@media (max-width: 620px) { .search-back { display: block; } }

/* 팝오버 닫기 — 폰에서 팝오버가 화면을 거의 다 덮으면 여는 버튼이 뒤에
   숨어 돌아갈 길이 없어진다(2026-08-03 제보: 지도유형에 닫힘 버튼이 없다). */
.pop-close {
  position: absolute; top: 10px; right: 10px; z-index: 2;
  width: 30px; height: 30px; line-height: 1;
  font-size: 13px; color: var(--ink);
  background: color-mix(in srgb, var(--bg) 70%, transparent);
  border: 1px solid var(--line); border-radius: 8px; cursor: pointer;
}
.pop-close:hover { border-color: var(--accent); }
.basemap-pop { position: fixed; }

/* 설정은 상단바 가장 오른쪽 — .rail-btn(세로 레일용) **뒤에** 두어야 이긴다.
   앞에 두었더니 flex-direction:column이 그대로 남아 버튼이 세로로 섰다
   (2026-08-03 제보: 위치가 비뚤어짐). */
.topnav-settings {
  margin-left: auto;
  flex-direction: row; align-items: center; gap: 6px;
  width: auto; height: 32px; padding: 0 11px;
  border-radius: 999px;
}
.topnav-settings .rail-ico { font-size: 14px; }
.topnav-settings .rail-txt { font-size: 12px; }
/* 좁은 화면 전용 버튼 — 넓은 화면에서는 숨는다 (모바일 미디어 쿼리가 켠다).
   **.rail-btn 뒤에 와야 한다** — 앞에 두면 같은 순위에서 뒤의 display:flex가
   이겨, 데스크톱에 '상세' 버튼이 하나 더 보인다. */
.rail-btn-narrow { display: none; }
.rail-btn:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--ink); }
.rail-btn.is-active {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  border-color: var(--line);
  color: var(--accent);
}
.rail-ico { font-size: 17px; line-height: 1; }
/* '지도상세'·'연대표상세'는 52px 레일에 한 줄로 안 들어간다 — 두 줄로 접는다 */
.rail-txt { font-size: 9px; letter-spacing: 0.02em; text-align: center; line-height: 1.3; }

/* ── 상세 설명 패널 ───────────────────────── */
.detail-panel { gap: 0; }
.detail-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 14px;
  overflow-y: auto;
  padding-top: 4px;
}
/* 안내문 (아직 아무것도 안 눌렀을 때 / 결과 없을 때) */
.detail-empty {
  font-size: 11.5px;
  line-height: 1.65;
  color: var(--ink-dim);
  padding: 10px 2px;
}
.detail-empty b { color: var(--ink); font-weight: 500; }

/* ── 연대표 상세 (시간축 쪽 상세) ─────────── */
/* 지도상세와 같은 패널 자리를 쓰므로 여백·글자 크기를 맞춘다.
   다른 점은 색 — 트랙 색을 그대로 물려받아 연대표의 띠와 이어 준다. */
.tld-where {
  display: flex; align-items: center; flex-wrap: wrap; gap: 7px;
  font-size: 11px; color: var(--ink-dim);
}
.tld-dot {
  flex: 0 0 auto;
  width: 9px; height: 9px; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--ink) 25%, transparent);
}
.tld-where-txt { color: var(--ink); font-weight: 700; }
.tld-kind {
  padding: 2px 8px;
  border: 1px solid var(--line); border-radius: 999px;
  font-size: 9.5px; color: var(--ink-dim);
}
.tld-span {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  font-family: "IBM Plex Mono", monospace;
}
.tld-span-main { font-size: 15px; color: var(--accent); }
.tld-span-sub { font-size: 10.5px; color: var(--ink-dim); }
.tld-link-btn {
  align-self: flex-start;
  padding: 7px 12px;
  border: 1px solid var(--line); border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  color: var(--ink); cursor: pointer;
  font-family: inherit; font-size: 11px;
  transition: all 0.15s ease;
}
.tld-link-btn:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 18%, transparent); }
.tld-foot { font-size: 10px; line-height: 1.6; color: var(--ink-dim); opacity: 0.75; }
/* 두 축의 머리글 (역사 / 땅과 자연) — 성격이 다른 두 글을 갈라 준다.
   제목만큼 무겁지 않게, 앞의 짧은 선으로 구획만 표시한다. */
.tld-axis {
  display: flex; align-items: center; gap: 7px;
  /* 부모(.detail-body)의 gap이 14px이라 머리글이 제 카드에서 떨어져 보인다.
     아래쪽만 당겨 머리글이 자기 카드에 붙게 한다. */
  margin: 2px 0 -8px;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.04em;
  color: var(--ink-dim);
}
.tld-axis::before {
  content: ''; flex: 0 0 auto;
  width: 12px; height: 1px; background: var(--accent); opacity: 0.6;
}

/* 대표작 목록 — 곡·작품은 연대표에 그리지 않고 여기서만 편다
   (주제별 연대표 가이드 §4.2). 카드(.info-card)로 감싸지 않는 이유는
   여러 개가 줄줄이 오기 때문이다 — 카드를 겹치면 여백이 두 배로 쌓인다.
   연도를 왼쪽에 세로로 정렬해 눈이 시간 순서를 먼저 훑게 한다. */
.tld-works { display: flex; flex-direction: column; gap: 9px; margin: 0; padding: 0; list-style: none; }
.tld-work {
  padding-left: 9px;
  border-left: 2px solid color-mix(in srgb, var(--accent) 35%, transparent);
}
.tld-work-head { display: flex; align-items: baseline; gap: 7px; }
.tld-work-year {
  flex: 0 0 auto;
  font-size: 10.5px; font-variant-numeric: tabular-nums;
  color: var(--ink-dim); opacity: 0.85;
}
.tld-work-name { font-size: 12px; font-weight: 700; color: var(--ink); }
.tld-work-desc {
  margin: 3px 0 0;
  font-size: 11.5px; line-height: 1.55; color: var(--ink-dim);
}

/* 현재 보고 있는 단위 (대륙 > 국가) */
.detail-crumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 5px;
  font-size: 10.5px;
  color: var(--ink-dim);
  padding-bottom: 2px;
}
.detail-crumb button {
  border: none; background: none; padding: 0;
  color: var(--accent); cursor: pointer;
  font-family: inherit; font-size: 10.5px;
  text-decoration: underline; text-underline-offset: 2px;
}
/* 하위 권역 체크 칩 (유럽 → 동유럽·서유럽·… 여러 개 함께 체크 가능) */
.dt-chips { display: flex; flex-wrap: wrap; gap: 6px; padding-bottom: 4px; }
.dt-chip-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px;
  border: 1px solid var(--line); border-radius: 999px;
  background: transparent; color: var(--ink-dim);
  cursor: pointer; font-family: inherit; font-size: 10.5px;
  transition: all 0.15s ease;
}
.dt-chip-btn:hover {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-color: var(--accent); color: var(--ink);
}
.dt-chip-btn.is-selected {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  border-color: var(--accent); color: var(--ink);
}
.dt-chip-btn .dt-cb { width: 12px; height: 12px; font-size: 9px; }

/* 주제 묶음 — 뎁스 1(주제) > 뎁스 2(분류) > 뎁스 3(지형)을 글자 크기로 구분 */
.dt-group { display: flex; flex-direction: column; gap: 3px; }
/* 체크박스 — 선택(지도 강조 중)이면 채워지고 ✓ 가 표시된다.
   행 전체가 버튼이라 체크박스든 글자든 어디를 눌러도 토글된다. */
.dt-cb {
  flex: 0 0 auto;
  width: 13px; height: 13px;
  border: 1.5px solid color-mix(in srgb, var(--ink) 35%, transparent);
  border-radius: 3.5px;
  display: inline-flex; align-items: center; justify-content: center;
  align-self: center;
  font-size: 9.5px; line-height: 1; color: #1a1208;
  transition: all 0.15s ease;
}
.is-selected > .dt-cb {
  background: var(--accent);
  border-color: var(--accent);
}
.is-selected > .dt-cb::after { content: '✓'; font-weight: 700; }
.dt-head-name { flex: 1; }
/* 뎁스 1: 주제 제목 (자연환경 …) — 누르면 주제 전체 강조, 재클릭 해제 */
.dt-group-head {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 7px;
  border: 1px solid transparent; border-radius: 7px;
  background: transparent; text-align: left;
  font-family: inherit; font-size: 13px; font-weight: 700; color: var(--ink);
  cursor: pointer;
  transition: all 0.15s ease;
}
.dt-group-head:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); border-color: var(--line); }
.dt-group-head.is-selected {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  border-color: var(--accent);
  color: var(--accent);
}
/* 뎁스 2: 분류 제목 (신기 습곡 산지·주요 강·반도 …) — 누르면 분류 전체 강조 */
.dt-sub-head {
  display: flex; align-items: center; gap: 7px;
  margin-left: 8px;
  padding: 4px 7px;
  border: 1px solid transparent; border-radius: 7px;
  background: transparent; text-align: left;
  font-family: inherit; font-size: 11.5px; font-weight: 600; color: var(--ink-dim);
  cursor: pointer;
  transition: all 0.15s ease;
}
.dt-sub-head:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); border-color: var(--line); color: var(--ink); }
.dt-sub-head.is-selected {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  border-color: var(--accent);
  color: var(--ink);
}
.dt-sub-name { flex: 1; }
.dt-group-count {
  font-family: "IBM Plex Mono", monospace;
  font-size: 9.5px; color: var(--ink-dim);
}
/* 뎁스 3: 개별 지형 행 — 누르면 그 지형 강조, 재클릭 해제 */
.dt-item {
  display: flex; align-items: baseline; gap: 7px;
  margin-left: 22px;
  padding: 3px 7px;
  border: 1px solid transparent; border-radius: 7px;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer; text-align: left;
  font-family: inherit;
  transition: all 0.15s ease;
}
.dt-item:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); color: var(--ink); border-color: var(--line); }
/* 클릭된(지도에 강조 중인) 항목 */
.dt-item.is-selected {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  border-color: var(--accent);
  color: var(--ink);
}
.dt-item.is-selected .dt-name { font-weight: 700; }
.dt-chip {
  flex: 0 0 auto; width: 8px; height: 8px;
  border-radius: 2px; align-self: center;
}
.dt-name { flex: 1; font-size: 10.5px; }

/* ── 좌측 공간 레이어 메뉴 ─────────────── */
/* 좌측 패널 — 우측 패널과 같은 형식. 레일에 딱 붙고 위아래로 꽉 찬다
   (예전에는 지도 위에 뜬 둥근 카드라 우측과 조작감이 달랐다). */
.lpanel {
  position: fixed;
  top: var(--nav-h);
  left: var(--rail-w);         /* 좌측 레일에 붙는다 */
  bottom: var(--btm-h);        /* 하단 바(+연대표) 위에서 끝난다 */
  z-index: 12;
  width: auto;                 /* 뎁스2가 열리면 오른쪽으로 넓어진다 */
  max-width: calc(100vw - var(--rail-w));
  background: var(--surface);
  backdrop-filter: blur(10px);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 8px 0 40px var(--sh);
  transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}
.lpanel.is-collapsed { transform: translateX(calc(-100% - var(--rail-w))); pointer-events: none; }

.lpanel-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px 8px;
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 14%, transparent);
}
/* '전체' 토글은 제목 바로 옆에 붙인다. 뎁스2가 열려 패널이 넓어져도
   제목에서 멀어지지 않도록, 남는 공간은 오른쪽(닫기 버튼 앞)이 흡수한다. */
.lpanel-head .panel-head-title { flex: 0 0 auto; }
/* 제목 = 닫기 버튼. 좌측 레일의 '레이어' 버튼으로도 여닫을 수 있다. */
.lpanel-title-btn {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 2px 6px 2px 0;
  border: none;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  font-family: inherit;
  transition: color 0.15s ease;
}
.lpanel-title-btn:hover { color: var(--accent); }
.lpanel-head-right { display: flex; align-items: center; gap: 6px; flex: 1; }
.lpanel-head-right #lpanel-all { flex: 0 0 auto; }
.lpanel-head-right .panel-close { margin-left: auto; }

/* 뎁스1(주제 목록) + 뎁스2(레이어 상세) 가로 배치 */
.lpanel-cols {
  flex: 1;
  display: flex;
  min-height: 0;
}
.lp1 {
  flex: 0 0 auto;
  width: 248px;   /* 이름 + 스위치 + 개수 + 화살표가 줄임표 없이 들어가는 폭 */
  overflow-y: auto;
  padding: 6px;
  display: flex;
  flex-direction: column;
  /* 간격은 .sec-kids / .sec-row 가 각자 관리한다 (대분류마다 다른 여백) */
  gap: 0;
}

/* 뎁스1 대분류 헤더 (1. 자연레이어 / 2. 인문레이어)
   뎁스2 아코디언(.lg-head)과 같은 어휘를 쓴다 — › 셰브런이 열리면 90도 회전,
   배경 없음, 같은 padding·글자 크기, 개수는 공용 .lg-count 알약. */
.sec-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 10px 11px;
  /* .topic-row 와 같은 1px 투명 테두리 — 없으면 안쪽 내용이 1px 어긋난다 */
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: background 0.14s ease;
}
.sec-row:hover { background: color-mix(in srgb, var(--accent) 8%, transparent); }
/* 두 번째 대분류 위에 구분선 — 섹션 경계를 눈으로 끊어 준다
   (기본 .sec-row 의 투명 border 를 윗변만 덮어쓴다) */
.sec-row + .sec-row,
.sec-kids + .sec-row {
  margin-top: 4px;
  border-top-color: color-mix(in srgb, var(--accent) 14%, transparent);
  padding-top: 12px;
}
.sec-caret {
  flex: 0 0 auto;
  width: 11px;              /* 글리프 폭에 좌우되지 않는 고정 슬롯 */
  text-align: center;
  color: var(--accent);
  font-size: 11px;
  line-height: 1;
  transition: transform 0.18s ease;
}
.sec-row.is-open .sec-caret { transform: rotate(90deg); }
/* 뎁스 글자 크기 단계: 패널 제목 13 > 대분류 12.5 > 주제 11.5 > 레이어 11 */
.sec-name {
  flex: 1;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.01em;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 대분류 전체 켜기/끄기 스위치 — 주제 행 스위치와 동일 규칙 */
.sec-sw { cursor: pointer; }
.sec-sw:hover { border-color: var(--accent); }
.sec-sw.is-on { background: color-mix(in srgb, var(--accent) 45%, transparent); border-color: var(--accent); }
.sec-sw.is-on .layer-knob { transform: translateX(12px); background: var(--accent); }

/* 하위 주제 묶음 — 닫히면 완전히 숨긴다 */
.sec-kids {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0 0 6px;
}
.sec-kids.is-closed { display: none; }

/* 뎁스1 주제 행 */
.topic-row {
  display: flex;
  align-items: center;
  gap: 7px;
  width: 100%;
  padding: 10px;
  border: 1px solid transparent;
  border-radius: 9px;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: all 0.15s ease;
}
.topic-row:hover { background: color-mix(in srgb, var(--accent) 9%, transparent); color: var(--ink); }
.topic-row.is-active {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-color: var(--line);
  color: var(--ink);
}
.topic-text { flex: 1; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.topic-name {
  font-size: 12.5px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 하위 주제 — 크기 격차에 더해 들여쓰기로 위계를 준다.
   왼쪽 여백 28px = .sec-row padding(11) + 셰브런(11) + gap(6) 이라
   주제 이름이 대분류 이름과 같은 세로선에서 시작한다. */
.topic-row.is-child { padding-left: 28px; }
/* ── 뎁스1 세로 정렬 ──────────────────────
   대분류 행과 하위 주제 행이 오른쪽 구조를 똑같이 갖도록 맞춘다:
   같은 padding-right, 고정 폭 스위치·알약, 그리고 화살표 자리(11px)를
   대분류도 빈 칸으로 예약한다(.sec-row::after). 그래야 이름 길이와
   상관없이 세 요소가 항상 같은 세로선에 놓인다. */
.sec-row,
.topic-row.is-child { padding-right: 10px; gap: 6px; }
.sec-row .layer-sw,
.topic-row.is-child .layer-sw { flex: 0 0 auto; }
.sec-row .lg-count,
.topic-row.is-child .lg-count {
  flex: 0 0 auto;
  width: 40px;
  text-align: center;
  padding-left: 0;
  padding-right: 0;
}
.topic-row.is-child .topic-arrow { flex: 0 0 auto; width: 11px; text-align: right; }
/* 대분류에는 › 가 없으므로 같은 폭의 빈 칸을 만들어 준다 */
.sec-row::after { content: ""; flex: 0 0 auto; width: 11px; }
/* 주제(뎁스2)는 대분류(12.5px)보다 한 단계 작게 — 위계를 크기로도 구분 */
.topic-row.is-child .topic-name { font-size: 11.5px; font-weight: 500; }
.topic-row.is-child.is-active .topic-name { font-weight: 700; }
.topic-hint { font-size: 9.5px; opacity: 0.6; line-height: 1.3; }
.topic-arrow { flex: 0 0 auto; color: var(--accent); font-size: 14px; line-height: 1; }
/* 하위 행의 › 는 '뎁스2 열기' 표시. 대분류 셰브런과 헷갈리지 않도록
   선택된 행에서만 또렷해지고 평소에는 흐리게 둔다. */
.topic-row.is-child .topic-arrow { opacity: 0.35; transition: opacity 0.15s ease; }
.topic-row.is-child:hover .topic-arrow,
.topic-row.is-child.is-active .topic-arrow { opacity: 1; }

/* 뎁스1 주제 행의 전체 켜기/끄기 스위치 */
.topic-sw { cursor: pointer; }
.topic-sw:hover { border-color: var(--accent); }
.topic-sw.is-on {
  background: color-mix(in srgb, var(--accent) 45%, transparent);
  border-color: var(--accent);
}
.topic-sw.is-on .layer-knob {
  transform: translateX(12px);
  background: var(--accent);
}

/* 뎁스2 패널 — 주제 선택 시에만 보임 */
.lp2 {
  display: none;
  flex: 0 0 auto;
  width: 300px;
  border-left: 1px solid color-mix(in srgb, var(--accent) 14%, transparent);
  flex-direction: column;
  min-height: 0;
}
.lp2.is-open { display: flex; }
.lp2-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px 4px;
}
.lp2-title { font-size: 13px; font-weight: 700; }
.lp2-hint {
  font-size: 10px;
  color: var(--ink-dim);
  opacity: 0.85;
  line-height: 1.4;
  padding: 0 12px 4px;
}
.lp2-head-right { display: flex; align-items: center; gap: 8px; }
.lp2-back { font-size: 17px; line-height: 0.9; padding-bottom: 3px; }

/* 주제 전체 켜기/끄기 토글 */
.lp2-all {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  font-family: inherit;
  transition: all 0.15s ease;
}
.lp2-all:hover { color: var(--ink); border-color: var(--accent); }
.lp2-all-label { font-size: 10.5px; font-weight: 500; }
.lp2-all.is-on { color: var(--ink); }
.lp2-all.is-on .layer-sw {
  background: color-mix(in srgb, var(--accent) 45%, transparent);
  border-color: var(--accent);
}
.lp2-all.is-on .layer-knob {
  transform: translateX(12px);
  background: var(--accent);
}
.lp2-alpha {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 12px 5px;
}
.lp2-width { padding-bottom: 9px; border-bottom: 1px solid color-mix(in srgb, var(--accent) 12%, transparent); }
.lp2-alpha-label { width: 38px; }
.lp2-alpha-label { flex: 0 0 auto; font-size: 10.5px; color: var(--ink-dim); }
.lp2-body {
  flex: 1;
  overflow-y: auto;
  padding: 2px 10px 12px;
}

/* 열기 버튼 (메뉴가 닫혀 있을 때 좌상단) */
.lpt-icon { color: var(--accent); font-size: 14px; line-height: 1; }

/* 아코디언 그룹 */
.lg {
  margin-top: 8px;
  border: 1px solid color-mix(in srgb, var(--accent) 16%, transparent);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.02);
  overflow: hidden;
}
.lg-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 10px 11px;
  border: none;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: background 0.14s ease;
}
.lg-head:hover { background: color-mix(in srgb, var(--accent) 8%, transparent); }
.lg-chevron {
  flex: 0 0 auto;
  color: var(--accent);
  font-size: 11px;
  line-height: 1;
  transition: transform 0.18s ease;
}
.lg.is-open .lg-chevron { transform: rotate(90deg); }
/* 뎁스3 그룹 제목 — 주제(11.5)와 레이어(11) 사이 단계 */
.lg-title { flex: 1; font-size: 11.5px; font-weight: 700; letter-spacing: 0.01em; }
.lg-count {
  flex: 0 0 auto;
  font-family: "IBM Plex Mono", monospace;
  font-size: 9.5px;
  color: var(--ink-dim);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px 8px;
}
/* 개수가 0/11 ↔ 11/11로 바뀌어도 폭이 변하지 않게 고정 — 옆 스위치가 밀리지 않는다
   (대분류·주제 행은 아래에서 이미 40px로 고정) */
.lg-head .lg-count {
  width: 40px;
  text-align: center;
  padding-left: 0;
  padding-right: 0;
}
.lg-count.is-active { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 55%, transparent); }

/* 그룹 헤더의 전체 켜기/끄기 스위치 */
.group-sw { cursor: pointer; }
.group-sw:hover { border-color: var(--accent); }
.group-sw.is-on {
  background: color-mix(in srgb, var(--accent) 45%, transparent);
  border-color: var(--accent);
}
.group-sw.is-on .layer-knob {
  transform: translateX(12px);
  background: var(--accent);
}

.lg-body { display: none; padding: 0 7px 8px; }
.lg.is-open .lg-body { display: block; }
.lg-hint {
  font-size: 10px;
  color: var(--ink-dim);
  opacity: 0.8;
  padding: 2px 4px 7px;
  line-height: 1.4;
}

/* 레이어 색상 칩 — 지도 위 표현색과 짝을 맞춘다 */
.layer-chip {
  flex: 0 0 auto;
  width: 11px;
  height: 11px;
  border-radius: 3px;
  border: 1px solid var(--sh);
  background: rgba(255, 255, 255, 0.2);
}

/* 선명도 슬라이더 공통 (뎁스2 헤더·배경 옅게에서 사용) */
.alpha-range {
  flex: 1;
  -webkit-appearance: none;
  appearance: none;
  height: 3px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 18%, transparent);
  outline: none;
  cursor: pointer;
}
.alpha-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--accent);
  border: none;
}
.alpha-range::-moz-range-thumb {
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--accent);
  border: none;
}
.alpha-val {
  flex: 0 0 auto;
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  color: var(--ink-dim);
  width: 32px;
  text-align: right;
}

/* 배경 옅게 슬라이더 (우측 패널, 지형 지도 전용) */
.wash-row {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 7px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 7px;
}
.wash-label {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1.25;
}
.wash-label small { font-size: 9px; color: var(--ink-dim); font-weight: 400; }
.wash-row .alpha-range { flex: 1; }
.wash-row input[type="range"] {
  flex: 1;
  -webkit-appearance: none;
  appearance: none;
  height: 3px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 18%, transparent);
  outline: none;
  cursor: pointer;
}
.wash-row input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--accent);
  border: none;
}
.wash-row input[type="range"]::-moz-range-thumb {
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--accent);
  border: none;
}
.wash-val {
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  color: var(--ink-dim);
  width: 30px;
  text-align: right;
}

/* 지형 클릭 팝업 */
/* 팝업이 지도 구석에 뜨면 닫기 ×가 떠 있는 버튼(레일·검색 등) 밑에 깔려
   못 누른다(2026-08-04, 폰 좌상단 '레이어' 버튼이 덮음 — mobile-touch가
   잡음). z-index로는 못 푼다 — #map이 fixed라 자체 쌓임 맥락이어서 팝업이
   그 안에 갇힌다. 대신 nv-focus가 겹친 버튼에 이 클래스를 붙여 비켜 준다.
   팝업은 지도 이동·닫기로 곧 사라지므로 닫힐 때 바로 복원된다. */
.is-yield { opacity: 0.25; pointer-events: none; }
.nv-popup .maplibregl-popup-content {
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 9px;
  padding: 9px 12px;
  box-shadow: 0 8px 28px var(--sh);
  backdrop-filter: blur(8px);
}
.nv-popup .maplibregl-popup-tip { border-top-color: var(--surface); border-bottom-color: var(--surface); }
/* 닫기 버튼 — 기본값은 글자만 덩그러니 놓인 작은 ×라 지도 위에서 잘 안 보인다.
   앱의 다른 닫기(.panel-close)와 같은 생김새로 맞춘다. 제목과 겹치지 않도록
   내용의 오른쪽 여백도 그만큼 준다. */
.nv-popup .maplibregl-popup-content { padding-right: 34px; }
.nv-popup .maplibregl-popup-close-button {
  top: 5px; right: 5px;
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  color: var(--ink-dim);
  font-size: 14px; line-height: 1;
  padding: 0;
}
.nv-popup .maplibregl-popup-close-button:hover {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--ink);
}

/* "그 해의 세계"에서 나라 위에 마우스를 올렸을 때 뜨는 이름표.
   지도 위 이름표는 자리가 모자라면 지워지므로(충돌 회피), 색만 남은 나라가
   무엇인지 알 수 있는 길은 이것뿐이다. 클릭 팝업보다 가볍게 둔다. */
.year-tip .maplibregl-popup-content {
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 5px 9px;
  font-size: 12px;
  box-shadow: 0 4px 16px var(--sh);
  backdrop-filter: blur(6px);
  pointer-events: none;
}
.year-tip .maplibregl-popup-tip { display: none; }
.year-tip-sub { display: block; margin-top: 2px; font-size: 10.5px; color: var(--ink-dim); }
.nvp-name { font-size: 13px; font-weight: 700; letter-spacing: 0.01em; }
.nvp-cat {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 3px;
  font-size: 10.5px;
  color: var(--ink-dim);
}
.nvp-dot {
  width: 8px; height: 8px;
  border-radius: 2px;
  border: 1px solid rgba(0, 0, 0, 0.35);
}

/* 검색 */
/* 검색 버튼 — 제자리 버튼 왼쪽에 나란히. 누르면 아래로 검색창이 펼쳐진다. */
.search-btn {
  position: fixed;
  top: calc(var(--nav-h) + 14px);
  right: calc(var(--panel-w) + 72px + var(--rail-w));   /* 지도 모양 버튼 right + 54 */
  z-index: 13;
  width: 44px; height: 44px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--surface);
  backdrop-filter: blur(10px);
  color: var(--ink-dim);
  cursor: pointer;
  box-shadow: 0 6px 20px var(--sh);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: right 0.28s cubic-bezier(0.4, 0, 0.2, 1),
              border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.search-btn.is-panel-closed { right: calc(72px + var(--rail-w)); }
.search-btn:hover, .search-btn.is-open {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}

/* 검색창 팝오버 — 검색 버튼 아래로 펼쳐진다 */
.search-pop {
  position: fixed;
  top: calc(var(--nav-h) + 66px);
  right: calc(var(--panel-w) + 18px + var(--rail-w));
  /* 연대표 패널(14)보다 위 — 방금 사용자가 연 임시 팝오버이고, 결과가 길면
     연대표 위로 내려온다. 13이던 동안은 아래쪽 결과가 연대표의 높이 조절
     손잡이(.tl-resize)에 가려 눌리지 않았다. */
  z-index: 15;
  width: 300px;
  background: var(--surface);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px;
  box-shadow: 0 10px 40px var(--sh);
  transition: right 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}
.search-pop.is-panel-closed { right: calc(18px + var(--rail-w)); }
.search-pop.is-hidden { display: none; }

/* ── 지도 모양 (투영 · 지도유형) ─────────
   구글 지도의 '레이어' 버튼과 같은 자리·같은 방식. 상단 묶음의 오른쪽 끝이다 —
   가장 자주 쓰는 지도 조작이라 손이 먼저 닿는 자리를 준다. */
.basemap-btn {
  position: fixed;
  top: calc(var(--nav-h) + 14px);
  right: calc(var(--panel-w) + 18px + var(--rail-w));   /* 레일 + 패널 폭(조절 가능) + 여백(18) */
  z-index: 13;
  width: 44px; height: 44px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--surface);
  backdrop-filter: blur(10px);
  color: var(--ink-dim);
  cursor: pointer;
  box-shadow: 0 6px 20px var(--sh);
  display: flex; align-items: center; justify-content: center;
  transition: right 0.28s cubic-bezier(0.4, 0, 0.2, 1),
              border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.basemap-btn.is-panel-closed { right: calc(18px + var(--rail-w)); }
.basemap-btn:hover, .basemap-btn.is-open {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}

.basemap-pop {
  position: fixed;
  top: calc(var(--nav-h) + 66px);
  right: calc(var(--panel-w) + 18px + var(--rail-w));
  z-index: 13;
  width: 268px;
  /* 화면이 낮으면(노트북 + 연대표) 팝업이 하단 바를 넘어간다 — 넘치면 스크롤 */
  max-height: calc(100vh - var(--nav-h) - var(--btm-h) - 78px);
  overflow-y: auto;
  background: var(--surface);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 4px 12px 10px;
  box-shadow: 0 10px 40px var(--sh);
  transition: right 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}
.basemap-pop.is-panel-closed { right: calc(18px + var(--rail-w)); }
.basemap-pop.is-hidden { display: none; }
/* 패널 안에 있을 때의 규칙(.group)을 그대로 쓰되, 팝업이라 사이만 갈라 준다 */
.basemap-pop .group { padding: 10px 0; }
.basemap-pop .group + .group { border-top: 1px solid var(--line); }

.search { display: flex; flex-direction: column; gap: 6px; position: relative; }
.search-input {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: rgba(0, 0, 0, 0.25);
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
  outline: none;
  transition: border-color 0.15s ease;
}
.search-input::placeholder { color: color-mix(in srgb, var(--ink) 40%, transparent); }
.search-input:focus { border-color: var(--accent); }
/* 결과가 길어지면 여기서 스크롤한다 — 높이를 안 막으면 목록이 팝오버 밖으로
   흘러 축척 바·연대표에 겹치고, 맨 아래 **출처 표시가 화면 밖으로 밀린다.**
   출처는 지오코딩 사용 정책이 요구하는 것이라 늘 보여야 한다. */
.search-results {
  display: flex; flex-direction: column; gap: 3px;
  max-height: min(52vh, 420px);
  overflow-y: auto;
  overscroll-behavior: contain;   /* 끝까지 굴려도 뒤 지도가 따라 움직이지 않게 */
}
.search-item {
  padding: 7px 9px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 12px;
  line-height: 1.4;
  color: var(--ink-dim);
  transition: all 0.12s ease;
}
.search-item:hover { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--ink); }
.search-item .si-name { color: var(--ink); font-weight: 500; }
.search-item .si-ctx { font-size: 10px; opacity: 0.6; }
.search-empty { padding: 4px 2px; font-size: 11px; color: var(--ink-dim); }
/* 안내 줄 — "엔터로 더 넓게" · "찾는 중". 결과가 아니라 안내라서 누를 수 없다.
   바깥 지명은 엔터에서만 찾으므로(지오코딩 정책) 그 사실을 여기서 알린다. */
.search-note {
  padding: 5px 2px 2px;
  font-size: 10px; color: var(--ink-dim); opacity: 0.75;
}
/* 출처 — Nominatim/OSM 사용 정책이 요구하는 기여자 표시 */
.search-attrib {
  margin-top: 4px; padding: 4px 2px 0;
  border-top: 1px solid color-mix(in srgb, var(--accent) 14%, transparent);
  font-size: 9px; color: var(--ink-dim); opacity: 0.7;
}
.search-attrib a { color: inherit; }
/* 최근 검색 머리줄 */
.search-recent-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 2px 2px 0;
  font-size: 10px; color: var(--ink-dim);
}
.search-recent-head button {
  border: none; background: none; padding: 2px 4px;
  color: var(--accent); cursor: pointer;
  font-family: inherit; font-size: 10px;
}
.search-recent-head button:hover { text-decoration: underline; }

.group { display: flex; flex-direction: column; gap: 9px; }

/* 섹션 제목(검색·언어·투영·지도유형) — 옵션보다 뚜렷하게 큰 위계 */
.group-title {
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--ink);
}

/* 지도·자료 출처 — 지도 위 ⓘ 대신 설정 맨 아래(2026-08-06). 본문보다 낮은
   위계라 작고 옅게, 링크만 라이선스 확인이 되도록 살려 둔다. */
.src-list {
  margin: 0; padding: 0 0 0 2px;
  list-style: none;
  font-size: 11.5px; line-height: 1.7;
  color: var(--ink-dim);
}
.src-list a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

/* 세그먼트(투영·언어) */
.seg { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.seg-3 { grid-template-columns: 1fr 1fr 1fr; }
.seg-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 10px 4px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  transition: all 0.16s ease;
}
.seg-btn:hover { border-color: color-mix(in srgb, var(--accent) 55%, transparent); color: var(--ink); }
.seg-btn.is-active {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border-color: var(--accent);
  color: var(--ink);
}
.seg-label { font-size: 11.5px; font-weight: 500; }
.seg-sub { font-family: "IBM Plex Mono", monospace; font-size: 8px; letter-spacing: 0.14em; opacity: 0.7; }
.seg + .seg { margin-top: 6px; }
/* 세그먼트 아래 한 줄 설명 — 왜 이런 선택지가 있는지 짧게 알려 준다 */
.group-note {
  margin: 6px 2px 0;
  font-size: 10.5px;
  line-height: 1.5;
  color: var(--ink-dim);
}

/* 스택(지도유형) */
.stack { display: flex; flex-direction: column; gap: 6px; }
.opt {
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: left;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  transition: all 0.16s ease;
}
.opt:hover { border-color: color-mix(in srgb, var(--accent) 55%, transparent); color: var(--ink); }
.opt.is-active {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border-color: var(--accent);
  color: var(--ink);
}
.opt-label { font-size: 12px; font-weight: 500; }
.opt-desc { font-size: 10.5px; opacity: 0.72; line-height: 1.35; }


/* ── 겹쳐보기 레이어 ─────────────────── */
.group-hint {
  margin-top: -4px;
  margin-bottom: 2px;
  font-size: 10px;
  color: var(--ink-dim);
  opacity: 0.75;
}
/* 한 줄 행이 되면서 항목 사이 간격도 줄였다 — 4px는 두 줄짜리 행을
   떼어 놓으려던 값이라, 한 줄에서는 성기게만 보인다. */
.layer-list { display: flex; flex-direction: column; gap: 1px; }

.layer-row {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 5px 9px;
  border: 1px solid transparent;
  border-radius: 7px;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: all 0.16s ease;
}
.layer-row:hover { background: color-mix(in srgb, var(--accent) 9%, transparent); color: var(--ink); }
.layer-row.is-on { color: var(--ink); }

/* 토글 스위치 */
.layer-sw {
  flex: 0 0 auto;
  position: relative;
  width: 28px;
  height: 16px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid var(--line);
  transition: background 0.18s ease, border-color 0.18s ease;
}
.layer-knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 55%, transparent);
  transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1), background 0.18s ease;
}
.layer-row.is-on .layer-sw {
  background: color-mix(in srgb, var(--accent) 45%, transparent);
  border-color: var(--accent);
}
.layer-row.is-on .layer-knob {
  transform: translateX(12px);
  background: var(--accent);
}

.layer-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
/* 뎁스4 개별 레이어 — 가장 작은 단계.
   행은 이름 한 줄이다(2026-08-05 요청) — 설명은 ⓘ 카드로 갔다. 이름이 길면
   줄바꿈 대신 말줄임: 두 줄이 되면 한 줄로 만든 뜻이 없어진다. */
.layer-name {
  font-size: 11px; font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* 넓은 버튼(전체 보기) */
.wide-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 100%;
  padding: 11px;
  border: 1px solid var(--accent);
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--ink);
  cursor: pointer;
  transition: all 0.16s ease;
}
.wide-btn:hover { background: color-mix(in srgb, var(--accent) 24%, transparent); }
.wide-btn span:first-child { font-size: 13px; font-weight: 500; }
.wide-sub { font-family: "IBM Plex Mono", monospace; font-size: 8px; letter-spacing: 0.16em; opacity: 0.7; }

/* ── 나침반 ──────────────────────────── */
/* 상단 묶음의 **맨 왼쪽** 자리다. 기준 방위 그대로면 숨기 때문에,
   오른쪽 끝에 두면 지도를 돌릴 때마다 옆 버튼들이 통째로 밀린다. */
.compass {
  position: fixed;
  top: calc(var(--nav-h) + 14px);
  /* 패널 왼쪽에 위치 — 패널이 열려 있어도 가려지지 않는다.
     패널이 닫히면 .is-panel-closed 가 붙어 오른쪽 끝으로 이동한다. */
  right: calc(var(--panel-w) + 180px + var(--rail-w));   /* 전체화면 버튼 right + 54 */
  z-index: 13;          /* 패널(12)보다 위 */
  width: 44px; height: 44px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--surface);
  backdrop-filter: blur(10px);
  cursor: pointer;
  box-shadow: 0 6px 20px var(--sh);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: right 0.28s cubic-bezier(0.4, 0, 0.2, 1),
              border-color 0.15s ease, background 0.15s ease,
              opacity 0.2s ease, transform 0.2s ease;
}
/* 패널이 닫히면 레일 왼쪽으로 이동 */
.compass.is-panel-closed { right: calc(180px + var(--rail-w)); }
.compass:hover { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); }
/* 북쪽(기준 방위) 그대로일 때는 숨는다 — 알려 줄 것이 없는데 자리만 차지한다.
   display:none 이 아니라 투명하게 두는 것은 나타날 때 스르르 보이게 하려는 것.
   pointer-events를 끊어야 안 보이는 버튼이 클릭을 가로채지 않는다. */
.compass.is-hidden {
  opacity: 0;
  transform: scale(0.8);
  pointer-events: none;
}

/* 바늘: N(빨강)·S(회색) 두 삼각형. 지도 bearing에 따라 회전 */
.compass-needle {
  position: absolute;
  width: 0; height: 0;
  transition: transform 0.2s ease;
}
.cn-n, .cn-s {
  position: absolute;
  left: -4.5px;
  width: 0; height: 0;
  border-left: 4.5px solid transparent;
  border-right: 4.5px solid transparent;
}
/* 버튼 44px → 중심 y=22. 바늘 끝은 중심에서 (9+1)=10px 이므로 위에서 12px 지점.
   N 라벨은 2px~9.5px 를 차지하므로 2.5px 여유가 남는다. */
.cn-n { bottom: 1px; border-bottom: 9px solid #d0503a; }  /* 북쪽: 붉은 바늘 */
.cn-s { top: 1px; border-top: 9px solid color-mix(in srgb, var(--ink) 55%, transparent); } /* 남쪽 */
.compass-n {
  position: absolute;
  top: 2px;
  line-height: 1;
  font-family: "IBM Plex Mono", monospace;
  font-size: 7.5px;
  font-weight: 700;
  color: var(--ink-dim);
  pointer-events: none;
}

/* ── 제자리 버튼 ─────────────────────── */
/* 축척 바 바로 왼쪽 — 자리를 잡는 것은 감싸는 .mapctl-bottom 이다.
   (2026-07-31 이전에는 우측 상단 나침반 옆에 홀로 떠 있었다) */
.home-btn {
  flex: 0 0 auto;
  width: 40px; height: 40px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--surface);
  backdrop-filter: blur(10px);
  color: var(--ink-dim);
  cursor: pointer;
  box-shadow: 0 6px 20px var(--sh);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.home-btn:hover {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}

/* 현위치 마커 — 지도 위 파란 점. 흰 테두리 + 은은한 펄스로
   지도 앱들의 표준 GPS 표시와 같은 어휘를 쓴다 */
.geo-dot {
  width: 14px; height: 14px;
  border-radius: 50%;
  background: #3b82f6;
  border: 2.5px solid #fff;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.45);   /* 지도 위 마커 — 테마 무관 */
  position: relative;
}
.geo-dot::after {
  content: "";
  position: absolute;
  inset: -2.5px;              /* 테두리 포함한 원 크기에서 시작 */
  border-radius: 50%;
  background: rgba(59, 130, 246, 0.35);
  animation: geo-pulse 2.4s ease-out infinite;
  pointer-events: none;
}
@keyframes geo-pulse {
  0%   { transform: scale(1);   opacity: 0.9; }
  70%  { transform: scale(2.6); opacity: 0; }
  100% { transform: scale(2.6); opacity: 0; }
}

/* ── 범례 (식생·문화권) ───────────────── */
.legend {
  position: fixed;
  right: 18px;
  /* 축척 바와 같은 이유로 출처 표기 줄을 비켜선다 */
  bottom: calc(var(--btm-h) + var(--attrib-h) + 10px);
  z-index: 11;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 260px;
  pointer-events: none;
}
.legend.is-hidden { display: none; }
.lg-box {
  background: var(--surface);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 9px 11px;
  box-shadow: 0 6px 24px var(--sh);
}
.lg-box-title { font-size: 11px; font-weight: 700; margin-bottom: 6px; }
.lg-items { display: flex; flex-direction: column; gap: 3px; }
.lg-item { display: flex; align-items: center; gap: 6px; }
.lg-item .lg-chip {
  flex: 0 0 auto;
  width: 11px; height: 11px;
  border-radius: 2px;
  border: 1px solid rgba(0, 0, 0, 0.35);
}
.lg-label { font-size: 10px; color: var(--ink-dim); line-height: 1.3; }
.lg-note {
  margin-top: 6px;
  font-size: 8.5px;
  color: var(--ink-dim);
  opacity: 0.65;
  line-height: 1.35;
}

/* ── 우측 하단 지도 조작 묶음 (제자리 + 축척 바) ─────────────────── */
/* 가로 위치는 이 상자 하나가 잡는다 — 안의 버튼들은 흐름대로 놓인다.
   패널이 열리면 왼쪽으로 비켜난다. */
.mapctl-bottom {
  position: fixed;
  /* 출처 표기 줄 위에 놓는다. 한때 같은 줄에 두고 "접힌 ⓘ는 오른쪽 끝이라
     가로로 안 겹친다"고 봤지만, 축척 바의 오른쪽 끝이 ⓘ와 16px 겹쳤고
     ⓘ를 펼치면 749px 띠가 제자리 버튼까지 파고들었다. 출처는 가릴 수 없으니
     이쪽이 비켜선다 (--attrib-h). */
  bottom: calc(var(--btm-h) + var(--attrib-h) + 10px);
  right: calc(var(--panel-w) + 18px + var(--rail-w));   /* 레일 + 패널 폭(조절 가능) + 여백(18) */
  z-index: 13;          /* 패널(12)보다 위 */
  display: flex;
  align-items: center;
  gap: 10px;
  transition: right 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 패널이 닫히면 레일 왼쪽으로 이동 */
.mapctl-bottom.is-panel-closed { right: calc(18px + var(--rail-w)); }

/* [−] 슬라이더 [+] 로 확대·축소하고, 오른쪽 눈금은 그 길이가
   현재 화면에서 실제 몇 km인지 보여준다. */
.zoombar {
  display: flex;
  align-items: center;
  gap: 9px;
  background: var(--surface);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 7px 12px;
  box-shadow: 0 6px 20px var(--sh);
}
.zoom-range { width: 110px; flex: 0 0 auto; }
.zoombar-btn {
  flex: 0 0 auto;
  width: 20px; height: 20px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  font-size: 13px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  transition: all 0.15s ease;
}
.zoombar-btn:hover { color: var(--ink); border-color: var(--accent); }
.zoombar-scale {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  min-width: 76px;
}
.zoombar-rule {
  height: 5px;
  border: 1px solid color-mix(in srgb, var(--ink) 55%, transparent);
  border-top: none;    /* ⊔ 모양 눈금 */
}
.zoombar-label {
  font-family: "IBM Plex Mono", monospace;
  font-size: 9px;
  color: var(--ink-dim);
  line-height: 1;
}

/* ── 지도 전체 화면 버튼 ─────────────────
   좌·우·하단 패널을 한 번에 접는다. 패널이 아니라 지도 컨트롤이므로
   전체 화면 중에도 화면에 남아 돌아올 길이 항상 보인다. */
.mapfull-btn {
  position: fixed;
  top: calc(var(--nav-h) + 14px);
  right: calc(var(--panel-w) + 126px + var(--rail-w));   /* 검색 버튼 right + 54 */
  z-index: 13;
  width: 44px; height: 44px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--surface);
  backdrop-filter: blur(10px);
  color: var(--ink-dim);
  cursor: pointer;
  box-shadow: 0 6px 20px var(--sh);
  display: flex; align-items: center; justify-content: center;
  transition: right 0.28s cubic-bezier(0.4, 0, 0.2, 1), color 0.15s ease, border-color 0.15s ease;
}
.mapfull-btn:hover { color: var(--ink); border-color: var(--accent); }
.mapfull-btn.is-panel-closed { right: calc(126px + var(--rail-w)); }
/* 전체 화면 아이콘 — 지도와 연대표가 같은 아이콘을 쓴다.
   켜져 있으면 "되돌리기(축소)"를 뜻하도록 안쪽 화살표로 바뀐다. */
.fs-in { display: none; }
.is-active .fs-out, .is-on .fs-out { display: none; }
.is-active .fs-in, .is-on .fs-in { display: block; }
.mapfull-btn.is-active { color: var(--accent); border-color: var(--accent); }

/* 연대표 헤더의 전체 화면 버튼 — 헤더 높이에 맞춘 작은 아이콘 버튼 */
.fs-btn {
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 24px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  transition: all 0.15s ease;
}
.fs-btn:hover { color: var(--ink); border-color: var(--accent); }
.fs-btn.is-on { color: var(--accent); border-color: var(--accent); }

/* 지도 전체 화면 — 좌·우 레일과 하단 바를 감추고, 그 두께를 0으로 만들어
   지도 컨트롤들이 화면 끝까지 붙게 한다 (calc가 --rail-w·--btm-h를 참조한다). */
body.map-focus { --rail-w: 0px; --brail-h: 0px; }
body.map-focus .rail,
body.map-focus .brail { display: none; }

/* ── 데이터 출처 배지 ─────────────────── */
/* 하단 바의 오른쪽 끝에 산다 — 지도 위에 뜬 알약이 아니라 상태 표시줄의 한 칸.
   (바가 생기기 전에는 화면 좌하단에 떠 있었다.) */
.source-badge {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 7px;
  padding-right: 4px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 10.5px;
  color: var(--ink-dim);
  white-space: nowrap;
  pointer-events: none;
}
.source-dot { color: var(--accent); font-size: 8px; }

/* ── 로딩 ───────────────────────────── */
.loading {
  position: fixed;
  bottom: calc(var(--btm-h) + 12px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  font-family: "IBM Plex Mono", monospace;
  font-size: 12px;
  color: var(--ink-dim);
  background: var(--surface);
  border: 1px solid var(--line);
  padding: 7px 16px;
  border-radius: 20px;
  transition: opacity 0.4s ease;
}
.loading.is-hidden { opacity: 0; pointer-events: none; }

/* ── 태블릿 ─────────────────────────── */
@media (max-width: 900px) {
  /* 지도 버튼 줄은 --panel-w에서 자리를 내므로 폭만 줄이면 전부 따라온다 */
  :root { --panel-w: 240px; }
  .lp1 { width: 232px; }   /* 데스크톱(248)보다 살짝 좁게 — 이름 줄임 없는 하한 */
  .lp2 { width: 260px; }
  .legend { max-width: 210px; }
  .lg-label { font-size: 9.5px; }
}

/* ── 모바일 ─────────────────────────── */
/* 좁은 화면에서는 패널을 하단 시트로 바꾼다. 사이드 패널은 지도를 거의
   다 가려버리기 때문. 시트는 화면 아래에서 올라오고 최대 높이를 제한한다. */
@media (max-width: 620px) {
  :root { --nav-h: 44px; }
  .topnav { gap: 12px; padding: 0 12px; }
  .nav-item { padding: 5px 10px; font-size: 12px; }
  /* '한국지도'까지 메뉴가 넷이라 브랜드 글자까지는 안 들어간다(390px 실측
     ~410px 필요). 로고 마크만 남긴다 — 이름은 넓은 화면이 보여 준다. */
  .brand-name { display: none; }

  /* 세로 레일 → 우상단 가로 아이콘 바. 하단 시트와 겹치지 않는다. */
  .rail {
    top: calc(var(--nav-h) + 10px); right: 14px; bottom: auto;
    width: auto;
    flex-direction: row;
    gap: 6px;
    padding: 5px;
    border: 1px solid var(--line);
    border-radius: 10px;
  }
  .rail-btn { width: 42px; }

  /* 하단 시트에는 좌우 폭이라는 게 없다 — 폭 손잡이를 감춘다 */
  .panel-resize { display: none; }

  .panel {
    top: auto;
    left: 0;
    right: 0;
    bottom: var(--brail-h);   /* 하단 바 위에서 올라온다 */
    width: 100%;
    max-height: 68vh;
    border-left: none;
    border-top: 1px solid var(--line);
    border-radius: 14px 14px 0 0;
    padding: 12px 14px calc(14px + env(safe-area-inset-bottom));
    box-shadow: 0 -8px 40px var(--sh);
    /* 아래에서 위로 슬라이드 */
    transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
  }
  .panel.is-collapsed { transform: translateY(calc(100% + var(--brail-h))); }

  /* ── 연대표상세 시트 — 연대표 **위로 겹쳐** 올라온다 (2026-08-01) ──
     폰은 세로가 844px뿐인데 지도·연대표·상세가 모두 아래쪽을 원한다. 자리를
     나누면 셋 다 못 쓸 만큼 작아지므로 겹치되 처음에는 조금만 올린다.
     그전에는 좁은 화면에서 아무것도 열지 않아, 항목을 눌러도 반응이 없었다. */
  .panel.is-sheet {
    z-index: 16;                 /* 연대표 패널(14)·검색 팝오버(15)보다 위 */
    bottom: 0;                   /* 하단 바까지 덮는다 — 시트를 보는 동안은 이게 주인공 */
    max-height: 84vh;
    /* 기본은 이름·연도가 보이는 낮은 높이. 끄는 동안에는 --sheet-drag가 얹힌다. */
    height: calc(132px + var(--sheet-drag, 0px));
    transform: none;
    transition: height 0.26s cubic-bezier(0.4, 0, 0.2, 1);
  }
  /* 끄는 중에는 손가락을 따라와야 하므로 전환을 끈다 */
  .panel.is-sheet[style*="--sheet-drag"] { transition: none; }
  /* 펼쳐도 **글 길이에 맞춘다.** 72vh로 고정하면 짧은 설명 아래로 빈 화면이
     길게 남아, 뒤의 지도·연대표를 이유 없이 가린다. 긴 글은 84vh에서 멈추고
     그때부터 본문이 스크롤된다. */
  .panel.is-sheet.is-sheet-full {
    height: auto;
    max-height: calc(84vh + var(--sheet-drag, 0px));
  }

  /* peek에서는 본문이 잘리므로 스크롤을 막는다 — 조금 보이는 글을 억지로
     굴리게 두면 "다 봤다"고 오해한다. 펼쳤을 때만 굴러간다. */
  .panel.is-sheet .detail-body { overflow: hidden; }
  .panel.is-sheet.is-sheet-full .detail-body { overflow-y: auto; }

  /* 손잡이를 크게 — 끄는 과녁이자 눌러서 펴는 과녁이다 */
  .panel.is-sheet .panel-head {
    padding-top: 14px;
    cursor: grab;
    touch-action: none;          /* 세로 끌기가 페이지 스크롤로 새지 않게 */
  }
  .panel.is-sheet .panel-head::before { width: 48px; height: 5px; }

  /* 시트 상단에 잡아당기는 손잡이 표시 */
  .panel-head { position: relative; padding-top: 8px; }
  /* 잡아당기는 손잡이 — 34×3에 28% 농도는 있는지도 모를 만큼 옅었다.
     지도 앱들처럼 또렷하게 둔다(2026-08-03 요청). */
  .panel-head::before {
    content: "";
    position: absolute;
    top: 1px; left: 50%;
    transform: translateX(-50%);
    width: 44px; height: 5px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--ink) 45%, transparent);
  }

  /* 지도 버튼들은 항상 우상단 고정 (패널이 아래로 내려갔으므로).
     레일이 가로 바로 바뀌어 위쪽에 있으므로 그 아래로 내린다.
     나침반은 여기서도 맨 왼쪽 — 숨었다 나타나도 옆이 밀리지 않는다.

     **줄 사이 간격은 레일 높이에서 계산한다.** 예전에는 72px이라는 어림수를
     썼는데, 레일이 실제로는 71px(위 여백 54 + 높이 71 = 125)이라 아래 줄과
     9px 겹쳤다 — 설정/지도상세 바 위로 검색·지도유형 버튼이 올라탔다.
     --rail-drop 하나만 고치면 두 줄이 함께 움직인다. */
  /* 폰에서는 지도 버튼을 **크게** 한다 — 44px은 손가락 최소치일 뿐이고,
     지도 위에 떠 있는 버튼은 걸어가면서도 눌러야 한다. 52px.

     그리고 **전부 한 줄에 모은다.** 레일(설정·상세)이 윗줄, 동그란 버튼이
     아랫줄로 두 줄을 이루면 우상단 구석이 통째로 지도를 덮는다.
     레일을 같은 줄의 왼쪽에 세워 [설정][상세] [검색][지도유형] 한 줄로.
     --attrib-h는 아래 묶음(제자리·나침반)이 출처 ⓘ 위로 물러서게 한다. */
  /* 지도 버튼 지름 — 52px은 지구본 위에서 너무 컸다(2026-08-03 제보).
     손끝 과녁으로 40px이면 충분하다. */
  :root { --rail-drop: calc(var(--nav-h) + 8px); --mbtn: 40px; --attrib-h: 34px; }

  /* 지도 위에 뜬 버튼은 **반투명**이다 — 지명을 가리는 검은 원 두 개가
     지구본 위에서 너무 도드라졌다(2026-08-03 제보). */
  .basemap-btn, .search-btn, .compass, .home-btn {
    background: color-mix(in srgb, var(--surface) 72%, transparent);
    backdrop-filter: blur(8px);
  }

  .basemap-btn, .search-btn, .mapfull-btn, .compass, .home-btn {
    width: var(--mbtn); height: var(--mbtn);
    font-size: 17px;
  }
  .basemap-btn { top: var(--rail-drop); right: 14px; }
  .basemap-btn.is-panel-closed { right: 14px; }
  .search-btn { top: var(--rail-drop); right: calc(14px + var(--mbtn) + 6px); }
  .search-btn.is-panel-closed { right: calc(14px + var(--mbtn) + 6px); }
  /* 팝오버는 그 줄 **아래**에서 열린다 */
  /* 검색창은 작게 — 지도 앱들처럼 한 줄이면 된다(2026-08-03 요청).
     뒤로 가기(‹)를 왼쪽에 두어 돌아갈 길을 만든다. */
  /* 첫 줄(뒤로 가기 + 입력칸)만 가로로 세운다. 결과 목록은 그 아래 줄이므로
     wrap을 허용하고 결과가 한 줄을 통째로 쓰게 한다. */
  /* 기본은 세로(column)라 방향까지 되돌려야 한 줄이 된다 */
  .search { flex-direction: row; align-items: center; gap: 6px; flex-wrap: wrap; }
  .search-results { flex: 1 0 100%; }
  .search-back {
    flex: none; width: 30px; height: 34px; padding: 0;
    font: inherit; font-size: 19px; line-height: 1; color: var(--ink);
    background: transparent; border: none; cursor: pointer;
  }
  /* flex 줄 안에서 남는 폭을 차지한다 — width:100%로 두면 뒤로 가기와
     같은 줄에 못 앉아 두 줄이 된다. */
  .search-input { flex: 1; min-width: 0; width: auto; height: 36px; font-size: 14px; padding: 0 10px; }
  .search-pop { padding: 8px 10px; }

  .search-pop, .basemap-pop {
    top: var(--nav-h); left: 14px; right: 14px; width: auto;
    /* 회차를 읽는 중에는 지도 띠 안에서 끝나야 한다. 화면 끝까지 늘어나면
       본문 위로 443px 흘러내렸다(2026-08-03 제보). 넘치면 안에서 굴린다. */
    max-height: calc(100vh - var(--nav-h) - var(--btm-h) - 20px);
    overflow-y: auto;
  }
  body.content-open:not(.content-full) .search-pop,
  body.content-open:not(.content-full) .basemap-pop {
    max-height: calc(var(--cv-strip) + var(--rail-drop));
  }
  .search-pop.is-panel-closed, .basemap-pop.is-panel-closed { right: 14px; }

  /* 우측 레일 — 폰에서는 '지도 상세'·'연대표 상세'를 **하나로 합친다.**
     버튼 셋이 가로를 다 먹어 산만하고, 어차피 지도를 누르면 지도 상세가
     연대표를 누르면 연대표 상세가 스스로 열린다. 남는 버튼은 "방금 보던
     것을 다시 열기"만 하면 되므로 하나면 충분하다. */
  /* 폰 레일에는 **설정 하나만** 남긴다.
     상세는 버튼이 필요 없다 — 지도를 누르면 지도 상세가, 연대표를 누르면
     연대표 상세가 스스로 열린다(panel-detail의 setRail('detail'),
     main의 openSheet()). 버튼은 "방금 보던 것을 다시 열기"일 뿐이라,
     좁은 화면에서 그 편의 하나를 위해 자리를 내줄 값어치가 없다. */
  #rail-detail, #rail-tldetail, #rail-anydetail { display: none; }

  /* 설정마저 상단바로 옮긴 뒤(2026-08-03) 폰 **우측** 레일에는 아무것도
     안 남았다. 그런데 상자는 그대로 그려져 검색 버튼 왼쪽에 10px짜리 빈
     막대가 섰다(제보 사진의 왼쪽 동그라미). 빈 레일은 감춘다.
     **좌측은 겨냥하면 안 된다** — #lrail도 class가 "rail rail-left"라
     한때 .rail 전체를 감췄더니 폰에서 '레이어' 버튼이 통째로 사라졌다
     (2026-08-04 제보). */
  .rail:not(.rail-left) { display: none; }

  /* 회차 시간 띠는 폰에서 감춘다(2026-08-03 요청).
     57px을 쓰면서 점은 9px이라 손끝으로 겨냥하기 어렵고, 연도는 본문이
     이미 말한다("1220년에 프랑스에서는…"). 넓은 화면에서는 남는 폭에
     들어가므로 그대로 둔다. */
  .cv-strip-tl { display: none; }

  /* 상단바의 설정은 아이콘만 남긴다 — 폰에서는 '설정' 두 글자가 메뉴를
     밀어낸다(2026-08-03 요청).
     글자를 지우면 가로가 남아 켜짐 표시(둥근 사각)가 아이콘에서 비켜난다 —
     정사각 원으로 만들어 아이콘 한가운데에 맞춘다(제보: 원의 중심이 어긋남). */
  .topnav-settings {
    width: 38px; height: 38px; padding: 0;
    justify-content: center; border-radius: 50%;
  }
  .topnav-settings .rail-txt { display: none; }

  /* 레일을 동그란 버튼들과 **같은 줄**에 세운다. 오른쪽부터
     지도유형(14) · 검색(74) 이 서고, 레일은 그 왼쪽에 붙는다.
     높이도 버튼과 맞춰야 한 줄로 읽힌다. */
  .rail {
    top: var(--rail-drop);
    right: calc(14px + var(--mbtn) * 2 + 16px);
    height: var(--mbtn);
    align-items: center;
    border-radius: 999px;      /* 동그란 이웃과 같은 말투 */
    padding: 0 4px;
  }
  .rail-btn { width: 46px; height: 44px; }
  /* 설정만은 정사각 원 — 위 규칙이 46×44로 만들면 켜짐 표시가 타원이 된다 */
  .topnav-settings { width: 40px; height: 40px; }

  /* 연대표가 화면을 통째로 쓰는 동안(전체 화면)에는 **지도 버튼을 감춘다.**
     이들은 지도 위에 떠 있는 조작 도구인데, 폰에서는 지도가 안 보이는데도
     연대표 머리(칩 줄) 위에 그대로 남아 칩을 가렸다 — 실측으로 레이어·설정·
     검색·지도유형 넷 모두 tl-head를 덮고 있었다.
     '연대표'를 다시 눌러 지도로 돌아오면 그대로 되살아난다. */
  body.tl-maxed .rail-left,
  body.tl-maxed .rail,
  body.tl-maxed .search-btn,
  body.tl-maxed .basemap-btn,
  body.tl-maxed .mapctl-bottom,
  body.tl-maxed .compass { display: none; }

  /* 좌측 레일도 가로 바로 — 네비 바로 아래 좌상단.
     top은 어림수가 아니라 --rail-drop — 우상단 동그란 버튼(검색·지도유형)과
     같은 줄에 서야 한다. +10px 어림수로 두었더니 2px 어긋나 있었다. */
  .rail-left {
    top: var(--rail-drop); left: 14px; right: auto; bottom: auto;
    border-right: none;
    border: 1px solid var(--line);
  }
  .brand-name { font-size: 13px; }
  /* ⛶ 전체 화면 버튼은 폰에서 **빼낸다.** 상단 네비의 '지도'가 똑같은 일을
     한다(둘 다 setMapFocus를 토글). 좁은 화면에서 같은 기능을 두 번 두면
     그만큼 지도가 가려진다. 기능이 사라지는 것은 아니다. */
  .mapfull-btn { display: none; }

  /* 나침반을 **위로 올린다**(2026-08-03 요청). 아래 오른쪽에서는 제자리
     버튼과 붙어 무엇이 무엇인지 헷갈렸다 — 검색·지도유형과 한 줄로 세운다.
     (전에는 '지도를 돌려야 나타나므로 윗줄이 밀린다'고 아래에 두었는데,
     실제로는 아래에서 제자리와 헷갈리는 쪽이 더 잦았다.) */
  .compass, .compass.is-panel-closed {
    top: var(--rail-drop); bottom: auto;
    right: calc(14px + var(--mbtn) * 2 + 12px);   /* 검색 왼쪽 */
    width: var(--mbtn); height: var(--mbtn);
  }

  /* 좁은 화면에서는 출처만 짧게 — 바 안에서 연대표 버튼을 밀지 않도록 */
  /* 'AWS 지형' 같은 출처 배지는 폰에서 감춘다. 지금 어느 타일을 쓰는지
     알려 주는 **진단용 표시**라 일상 사용에는 쓸모가 없는데, 좁은 하단 바에서
     자리만 차지한다. 라이선스 표기 의무는 지도 위 ⓘ가 이미 지고 있다.
     넓은 화면에서는 그대로 둔다 — 자리도 넉넉하고, 지도유형을 바꿔 가며
     무엇이 걸렸는지 확인할 때 쓸모가 있다. */
  .source-badge { display: none; }

  /* 축척 바는 좁은 화면에서 숨긴다 — 핀치 줌이 있고, 하단 시트와 겹친다.
     제자리 버튼은 남긴다 — 길을 잃었을 때 돌아올 유일한 길이라 더 필요하다. */
  .zoombar { display: none; }
  .mapctl-bottom { right: 14px; }
  .mapctl-bottom.is-panel-closed { right: 14px; }

  /* 출처 ⓘ는 제자리 버튼 **바로 아래에 딱 붙어**(간격 0) 두 겹처럼 보였다.
     라이선스상 가릴 수 없는 표시라 없앨 수는 없으니, 오른쪽 끝으로 밀어
     버튼 아래가 아니라 화면 모서리에 두고 사이를 띄운다. */
  .maplibregl-ctrl-bottom-right { right: 4px; bottom: 2px; }

  /* 펼친 출처가 **닫히지 않던 문제**. MapLibre의 compact 토글은 터치에서
     두 번째 탭이 먹지 않아, 한 번 펼치면 404×64 띠가 지도를 덮은 채 남았다.
     펼쳤을 때 ⓘ 자리에 닫기 과녁을 만들어 준다 — 아이콘은 그대로 두고
     그 위를 덮는 투명한 버튼처럼 동작하게 한다. */
  .maplibregl-ctrl-attrib.maplibregl-compact-show {
    max-width: calc(100vw - 28px);
    padding-right: 30px;         /* ⓘ 자리를 비워 둔다 */
  }
  .maplibregl-ctrl-attrib.maplibregl-compact-show .maplibregl-ctrl-attrib-button {
    width: 30px; height: 30px;
    top: 50%; transform: translateY(-50%);
    right: 0;
  }

  /* 터치 타겟 확보 */
  .layer-row { padding: 10px 9px; }
  .opt { padding: 11px; }
  .seg-btn { padding: 12px 4px; }
  .search-input { padding: 11px; font-size: 16px; } /* 16px 미만이면 iOS가 확대함 */
  .search-item { padding: 9px; }

  /* 좌측 레이어 메뉴도 하단 시트로 전환 */
  .lpanel {
    top: auto;
    left: 0;   /* 하단 시트 — 레일 오프셋·측면 테두리 무시 */
    border-right: none;
    box-shadow: 0 -8px 40px var(--sh);
    right: 0;
    bottom: var(--brail-h);   /* 하단 바 위에서 올라온다 */
    width: 100%;
    max-width: 100%;
    max-height: 70vh;
    border: none;
    border-top: 1px solid var(--line);
    border-radius: 14px 14px 0 0;
    box-shadow: 0 -8px 40px var(--sh);
  }
  .lpanel.is-collapsed { transform: translateY(calc(100% + var(--brail-h))); opacity: 0; }
  .lpanel-head { position: relative; padding-top: 16px; }
  .lpanel-head::before {
    content: "";
    position: absolute;
    top: 6px; left: 50%;
    transform: translateX(-50%);
    width: 34px; height: 3px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--ink) 28%, transparent);
  }
  /* 모바일: 주제를 고르면 뎁스2가 뎁스1을 대신한다 (✕로 목록 복귀) */
  .lpanel.has-topic .lp1 { display: none; }
  .lp1 { width: 100%; }
  .lp2 { width: 100%; border-left: none; }
  .lp2-body { padding-bottom: calc(14px + env(safe-area-inset-bottom)); }
  
  /* 범례는 하단 시트에 가리지 않도록 상단 우측으로 */
  .legend {
    top: calc(var(--nav-h) + 104px);
    bottom: auto;
    right: 14px;
    max-width: 150px;
  }
  .lg-box { padding: 7px 9px; }
  .lg-label { font-size: 9px; }
}

/* 가로 모드(낮은 높이)에서는 시트가 화면을 다 덮지 않도록 */
@media (max-width: 900px) and (max-height: 480px) {
  .panel { max-height: 82vh; }
}

/* ── 설명 카드 (국가·권역·지형이 무엇인지) ───────────── */
.info-card {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  padding: 11px 12px 10px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.info-card.is-loading { min-height: 46px; opacity: 0.5; }
.info-card.is-empty { background: transparent; }

/* 설명 사진 (위키백과 썸네일).
   여기 적은 16:10은 **받아오기 전의 빈 칸 크기**다. 사진이 도착하면
   panel-info.js의 fitCardImage()가 실제 비율로 바꿔 끼운다 — 어떤 비율이든
   잘리지 않는다(예전에는 잘라 담아 인물 초상의 얼굴이 날아갔다).
   비워 두지 않고 자리를 먼저 잡는 이유는 카드가 두 번 흔들리지 않게 하려는 것. */
.info-img {
  width: 100%;
  aspect-ratio: 16 / 10;
  /* 세로로 긴 사진이 카드를 다 차지하지 않게 막되, 상한을 패널 폭에 매단다 —
     폭을 넓히는 건 사진을 크게 보려는 것이니 상한만 그대로면 넓혀도 그대로다.
     기본 폭(264px)에서는 지금까지와 똑같은 210px이다. */
  max-height: max(210px, calc(var(--panel-w) * 0.6));
  object-fit: contain;    /* max-height에 걸렸을 때만 일한다 */
  border-radius: 6px;
  background: var(--line);
}

/* 국기·깃발·문장 — 지도 상세의 나라도, 연대표 상세의 옛 나라도 같은 규칙.
   단색 도형이라 사진 크기(16:10 꽉 채우기)로 키우면 패널이 국기 배너가 되고
   비율을 잘라 담으면 다른 나라 국기가 되어 버린다. 작게, contain으로 둔다. */
.info-img.is-flag {
  width: auto;
  height: 34px;
  aspect-ratio: auto;
  object-fit: contain;
  align-self: flex-start;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: transparent;
}

.info-text {
  font-size: 11.5px;
  line-height: 1.72;
  color: var(--ink);
  /* 기본은 5줄까지만 — 아래 자연환경 목록을 밀어내지 않게 한다 */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 5;
  line-clamp: 5;
  overflow: hidden;
}
.info-card.is-empty .info-text { color: var(--ink-dim); font-size: 11px; }
.info-card.is-open .info-text {
  -webkit-line-clamp: unset;
  line-clamp: unset;
  overflow: visible;
}
.info-more {
  align-self: flex-start;
  border: none; background: none; padding: 0;
  color: var(--accent); cursor: pointer;
  font-family: inherit; font-size: 10.5px;
  text-decoration: underline; text-underline-offset: 2px;
}
.info-src { font-size: 9.5px; color: var(--ink-dim); }
.info-src a { color: var(--ink-dim); text-underline-offset: 2px; }
.info-src a:hover { color: var(--accent); }

/* 레이어 항목 — 토글 행 + 설명(ⓘ) 버튼 + 펼쳐지는 설명 카드 */
.layer-item { position: relative; }
.layer-item .layer-row { padding-right: 28px; }
.layer-info-btn {
  position: absolute;
  top: 6px;
  right: 5px;
  width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  border: none; border-radius: 50%;
  background: transparent;
  color: var(--ink-dim);
  opacity: 0.45;
  cursor: pointer;
  font-family: inherit; font-size: 12px; line-height: 1;
  transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.layer-info-btn:hover { opacity: 1; color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); }
.layer-item.is-info-open .layer-info-btn { opacity: 1; color: var(--accent); }
.layer-info-host:not(:empty) { padding: 2px 4px 6px 8px; }
/* 좌측 패널은 폭이 좁아 본문 패널보다 한 단계 작게 */
.layer-info-host .info-card { padding: 9px 10px 8px; gap: 6px; }
.layer-info-host .info-text { font-size: 11px; line-height: 1.68; -webkit-line-clamp: 4; line-clamp: 4; }
/* 레이어 설명은 개념 설명(자체 작성)이라 사진이 거의 없고, 자리도 좁다 */
.layer-info-host .info-img { display: none; }

/* 지도 팝업 안의 설명 — 기본은 접혀 있다 (팝업이 지도를 가리지 않게) */
.nvp-info-btn {
  align-self: flex-start;
  margin-top: 2px;
  border: none; background: none; padding: 0;
  color: var(--accent); cursor: pointer;
  font-family: inherit; font-size: 10.5px;
  text-decoration: underline; text-underline-offset: 2px;
}
.nvp-info-host:not(:empty) { margin-top: 6px; }
.nvp-info-host .info-card {
  border-color: rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.05);
  padding: 8px 9px;
  gap: 5px;
}
.nvp-info-host .info-text { font-size: 10.5px; line-height: 1.65; -webkit-line-clamp: 6; line-clamp: 6; }
/* 팝업은 지도를 가리므로 사진을 더 납작하게 (빈 칸 비율 + 세로 사진 상한) */
.nvp-info-host .info-img { aspect-ratio: 16 / 9; max-height: 140px; border-radius: 4px; }

/* 지도 팝업 설명 — 폰에서는 지도를 절반 넘게 덮었다(2026-08-03 요청).
   두 줄만 보이고 '더 보기'로 펴게 한다. */
@media (max-width: 620px) {
  /* 지도 팝업 자체를 줄인다 — 폭 제한이 없어 사진 크기만큼 벌어졌다
     (2026-08-03 제보: 설명창이 너무 크다). */
  .nv-popup .maplibregl-popup-content { max-width: 240px; padding: 7px 10px; }
  .nv-popup .maplibregl-popup-content { padding-right: 30px; }
  .nvp-name { font-size: 12px; }
  .nvp-info-host .info-img { max-height: 76px; }
  .nvp-info-host .info-card { padding: 6px 7px 5px; gap: 4px; }
  .nvp-info-host .info-src { font-size: 8.5px; }
  .nvp-info-host .info-text {
    font-size: 11.5px; line-height: 1.5;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .nvp-info-host .info-card.is-open .info-text {
    -webkit-line-clamp: unset; overflow: visible;
  }
  .nvp-info-host .info-more { display: block; font-size: 11px; }
}

/* ── 하단 연대표 패널 ─────────────────── */
/* 시간축(연대표) × 공간축(지도). 열리면 --tl-h(실제 높이)가 잡히고,
   하단 UI(축척 바·범례·출처 배지)와 좌우 패널이 그만큼 위로 비켜난다. */
/* 라벨 열 너비 — 손잡이(14) + 이름 + 접기 버튼(13)이 다 들어가야 한다.
   76px일 때 '아메리카'가 한 글자씩 세로로 쪼개졌다. */
:root { --tl-h: 0px; --tl-label-w: 86px; }

.tlpanel {
  position: fixed;
  left: 0; right: 0;
  bottom: var(--brail-h);      /* 하단 바에 딱 붙는다 (좌측 패널이 좌측 레일에 붙듯) */
  max-height: calc(100vh - var(--nav-h) - var(--brail-h));
  z-index: 14;                 /* 레일(13)·패널(12)보다 위 — 전폭을 쓴다 */
  display: flex;
  flex-direction: column;
  background: var(--surface);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--line);
  box-shadow: 0 -8px 40px var(--sh);
  user-select: none;
  transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 접힐 때는 바 두께까지 더 밀어야 화면 밖으로 완전히 나간다 (우측 패널과 같은 문법) */
.tlpanel.is-collapsed { transform: translateY(calc(100% + var(--brail-h))); pointer-events: none; }

/* 전체 화면이어도 우측 레일 자리는 비워 둔다 — 연대표에서 항목을 누르면
   설명이 연대표상세(우측)에 열리는데, 레일과 패널이 연대표 뒤로 숨으면
   눌러도 아무 일이 없는 것처럼 보인다. 네비를 남겨 두는 것과 같은 이유. */
.tlpanel.is-max { right: var(--rail-w); }
/* 패널까지 열려 있으면 그 폭만큼 더 물러선다 — 안 그러면 패널이 연대표 헤더의
   오른쪽 버튼들(전체 시대·전체 화면·닫기)을 덮어 누를 수 없다. */
body.rail-open .tlpanel.is-max { right: calc(var(--rail-w) + var(--panel-w)); }
/* 이때 우측 레일·패널은 연대표를 피해 오르지 않는다(--btm-h를 안 본다) —
   그러면 연대표 높이(=화면 전체)만큼 밀려 높이가 0이 되어 버린다. */
body.tl-maxed .rail:not(.rail-left),
body.tl-maxed .panel-resize,
body.tl-maxed .panel { z-index: 15; bottom: var(--brail-h); }

.tl-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 10px 5px 12px;
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 14%, transparent);
}
.tl-title-btn {
  display: flex; align-items: center; gap: 7px;
  background: none; border: 0; padding: 0;
  color: var(--ink); cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 700;
}
.tlt-icon { color: var(--accent); }
.tl-hint {
  flex: 1;
  font-size: 10px; color: var(--ink-dim); opacity: 0.75;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tl-head-right { display: flex; align-items: center; gap: 6px; }

.tl-main { display: flex; flex-direction: column; }

/* 눈금 줄 — 왼쪽 모서리는 트랙 라벨 열과 폭을 맞춘다 */
.tl-axisrow {
  display: flex;
  height: 24px;
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 14%, transparent);
}
.tl-corner {
  flex: 0 0 var(--tl-label-w);        /* 트랙 이름 열과 폭을 맞춘다 */
  border-right: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
}
.tl-axis {
  position: relative; flex: 1; overflow: hidden;
  font-family: "IBM Plex Mono", monospace;
}
.tl-tick {
  position: absolute; top: 6px;
  transform: translateX(4px);
  font-size: 9.5px; color: var(--ink-dim);
  white-space: nowrap; pointer-events: none;
}
.tl-tick.is-zero { color: var(--accent); }

/* 트랙 영역 — 세로만 스크롤, 가로는 시간축 팬(드래그)으로 움직인다 */
.tl-scroll {
  display: flex;
  overflow-y: auto; overflow-x: hidden;
  max-height: 36vh;
}
.tl-labels {
  position: relative;
  flex: 0 0 var(--tl-label-w);
  border-right: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
}
/* 시대 줄 — 각 연대표의 **첫 줄**이자 그 연대표의 이름표다. 왼쪽 라벨 칸에
   연대표 이름(`기본 연대표 ▾`)이 서고, 같은 줄 오른쪽에 신석기·청동기·…가
   깔린다. 이름만을 위한 줄을 따로 두지 않는다 — 한 줄을 이름에 쓰면 트랙이
   쓸 수 있는 세로(화면 36%)가 연대표마다 그만큼 깎인다.
   2026-07-31 이전에는 좌측 26px 세로쓰기 띠(.tl-setcol)였다. */
.tl-track-label {
  position: absolute; left: 0; right: 0;
  display: flex; align-items: center; justify-content: center;
  padding-left: 14px;          /* 왼쪽 손잡이 자리 */
  padding-right: 13px;         /* 오른쪽 접기 버튼 자리 */
  text-align: center;
  font-size: 11px; font-weight: 700; color: var(--ink-dim);
  word-break: keep-all;        /* '아메리카'를 한 글자씩 끊지 않는다 */
  border-left: 3px solid var(--c);
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 12%, transparent);
  background: color-mix(in srgb, var(--c) 7%, transparent);
}
.tl-track-label.is-hit {
  color: var(--ink);
  background: color-mix(in srgb, var(--c) 24%, transparent);
}
/* 접을 수 있는 트랙은 칸 전체가 과녁이다 — 화살표는 15px인데 펼친 트랙은
   1000px이 넘어, 그 작은 과녁까지 커서를 옮기는 것 자체가 일이다. */
/* `display: flex`가 hidden 속성의 기본 display:none을 이긴다 — 이 줄이 없으면
   연대표를 접었을 때 숨긴 트랙 라벨 11개가 시대 줄 위에 그대로 겹쳐 그려진다. */
.tl-track-label[hidden] { display: none; }
/* 시대 줄 라벨 = 연대표 이름표. 손잡이가 없으니 왼쪽 여백을 줄인다.
   **글자는 아래 트랙(11px)보다 커야 한다** — 이 줄이 트랙들의 머리(깊이 1)인데
   자식보다 작으면 위아래 관계가 뒤집혀 읽힌다. 한때 10px이었던 것은 두 줄로
   접혀도 29px에 욱여넣으려던 것인데, 이제 줄 높이가 이름에 맞춰 늘어난다
   (panel-timeline labelMinH) — 글자를 줄여 맞출 이유가 사라졌다. */
.tl-track-label.is-ages {
  padding-left: 6px;
  font-size: 12px; font-weight: 800; line-height: 1.2;
  color: var(--accent);
  border-top: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  background: color-mix(in srgb, var(--accent) 11%, transparent);
}
.tl-track-label.is-ages:hover { background: color-mix(in srgb, var(--accent) 19%, transparent); }
/* 연대표가 여럿일 때 묶음의 시작을 눈에 띄게 — 시간축 쪽에도 같은 선을 긋는다 */
.tl-row.is-ages { border-top: 1px solid color-mix(in srgb, var(--accent) 30%, transparent); }
.tl-track-label.can-fold { cursor: pointer; }
.tl-track-label.can-fold:hover { background: color-mix(in srgb, var(--c) 16%, transparent); }
.tl-track-label.can-fold:hover .tl-track-fold { opacity: 1; }
/* 배지는 이름 옆이 아니라 아래에 둔다 — 옆에 두면 좁은 라벨 열에서 이름이
   밀려 세로로 쪼개진다 (76px일 때 '아메리카'가 네 줄이 됐다). */
.tl-label-in { display: inline-flex; flex-direction: column; align-items: center; gap: 2px; }
/* 트랙이 길어지면(펼친 아프리카는 1000px이 넘는다) 가운데 정렬로는 이름이 화면
   밖으로 내려간다. 그때만 위에 붙인다 — 부모가 stretch면 sticky가 먹지 않으므로
   .is-tall일 때 align-items를 flex-start로 바꾸는 것이 조건이다. */
.tl-track-label.is-tall { align-items: flex-start; }
.tl-track-label.is-tall .tl-label-in { position: sticky; top: 5px; padding-top: 5px; }

/* 접힌 트랙 — 큰 흐름(rank 1)만 남았다는 것을 아주 옅은 사선으로 말한다.
   완전히 비우지 않는 이유는 설계 문서 §9: 트랙이 사라지면 그 시대에 그곳이
   비어 있었다는 뜻으로 읽힌다. */
.tl-row.is-folded {
  background-image: repeating-linear-gradient(135deg,
    color-mix(in srgb, var(--ink) 3.5%, transparent) 0 1px,
    transparent 1px 7px);
}
/* 접혀서 가려진 항목 수 — 숫자뿐이라 번역이 필요 없다 (.lg-count의 축소판) */
.tl-fold-badge {
  padding: 0 3px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--c) 40%, transparent);
  font-size: 9px; font-weight: 700; letter-spacing: 0;
  color: var(--ink);
  white-space: nowrap;
}
.tl-fold-badge[hidden] { display: none; }

/* 접기 버튼 — 왼쪽이 순서 손잡이, 오른쪽이 접기. 접을 것이 있을 때만 나온다
   (전체 보기에서는 어차피 rank 1뿐이라 눌러도 아무 일이 없다). */
.tl-track-fold {
  position: absolute;
  right: 0; top: 0; bottom: 0;
  width: 15px;
  display: flex; align-items: center; justify-content: center;
  padding: 0; border: 0; background: none;
  cursor: pointer;
  touch-action: none;
  opacity: 0.5;
  transition: opacity 0.15s ease;
}
.tl-track-label.is-tall .tl-track-fold { align-items: flex-start; padding-top: 8px; }
.tl-track-fold[hidden] { display: none; }
.tl-track-label:hover .tl-track-fold { opacity: 1; }
.tl-fold-caret {
  width: 0; height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid var(--ink);
  transition: transform 0.15s ease;
}
/* 접히면 ▾가 ▸로 눕는다 (레이어 패널 .lg-chevron과 같은 문법) */
.tl-track-label.is-folded .tl-fold-caret { transform: rotate(-90deg); }

/* 트랙 순서 손잡이 — 잡고 위아래로 끌면 그 연대표 안에서 자리가 바뀐다.
   무엇을 위에 둘지는 사람마다 다르다(한국사 중심 / 유럽사 중심 …). */
.tl-track-handle {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  cursor: grab;
  touch-action: none;          /* 터치로 끌 때 세로 스크롤로 새지 않게 */
  opacity: 0.45;
  transition: opacity 0.15s ease;
}
.tl-track-handle i {
  display: block;
  width: 9px; height: 1.5px;
  border-radius: 2px;
  background: var(--ink);
}
.tl-track-label:hover .tl-track-handle { opacity: 0.9; }
.tl-track-handle:active { cursor: grabbing; }
/* 끄는 동안: 잡힌 줄은 떠 보이고, 커서는 화면 어디서나 grabbing */
.tl-track-label.is-dragging {
  background: color-mix(in srgb, var(--c) 34%, transparent);
  box-shadow: 0 2px 10px var(--sh);
  color: var(--ink);
  z-index: 2;
}
body.tl-reordering { cursor: grabbing; }
body.tl-reordering .tl-track-handle { opacity: 0.9; }
/* 순서 되돌리기 — 순서를 바꾼 뒤에만 헤더에 나타난다 (hidden 속성으로 제어) */
.tl-order-reset { font-size: 14px; line-height: 1; }
.tl-order-reset[hidden] { display: none; }

.tl-viewport { position: relative; flex: 1; overflow: hidden; touch-action: none; }
.tl-grid { position: absolute; inset: 0; pointer-events: none; }
.tl-gridline { position: absolute; top: 0; bottom: 0; width: 1px; background: color-mix(in srgb, var(--ink) 5%, transparent); }
.tl-gridline.is-zero { background: color-mix(in srgb, var(--accent) 35%, transparent); }   /* BC·AD 경계 */
.tl-row {
  position: absolute; left: 0; right: 0;
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 12%, transparent);
  pointer-events: none;
}
.tl-row.is-hit { background: color-mix(in srgb, var(--accent) 7%, transparent); }

/* 항목 띠 — 트랙 색(--c)을 이어받아 왕조·시대를 구분한다 */
.tl-item {
  position: absolute;
  height: 18px;
  display: flex; align-items: center;
  padding: 0 6px;
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--c) 55%, transparent);
  border-radius: 4px;
  background: color-mix(in srgb, var(--c) 16%, color-mix(in srgb, var(--bg) 55%, transparent));
  color: var(--ink); cursor: pointer;
  font-family: inherit; font-size: 10.5px; line-height: 1;
  white-space: nowrap;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.tl-item.is-rank1 { background: color-mix(in srgb, var(--c) 30%, color-mix(in srgb, var(--bg) 50%, transparent)); font-weight: 700; }
.tl-item:hover { border-color: var(--c); background: color-mix(in srgb, var(--c) 45%, color-mix(in srgb, var(--bg) 40%, transparent)); z-index: 2; }
.tl-item.is-active {
  border-color: var(--ink);
  box-shadow: 0 0 0 1px var(--c), 0 0 10px color-mix(in srgb, var(--c) 60%, transparent);
  z-index: 3;
}
.tl-item.is-hit { border-color: var(--c); }
.tl-item.is-tiny { padding: 0; }
.tl-item.is-tiny .tl-item-label { display: none; }   /* 너무 좁으면 이름은 툴팁으로 */
.tl-item-label { overflow: hidden; text-overflow: ellipsis; }
/* 세로선이 가리키는 해에 없던 항목 — 지우지 않고 흐리게만 둔다.
   지워 버리면 "그 해에 무엇이 없었는가"(직전에 망하고 직후에 서는 나라들)를
   읽을 수 없다. 흐리게 두면 그 해의 앞뒤가 같은 화면에 남는다. */
.tl-item.is-offyear { opacity: 0.28; }
.tl-item.is-offyear:hover { opacity: 0.85; }

/* ── 세로선 (그 해의 지도) ─────────────────
   연대표를 가로지르는 한 줄. 이 선이 선 자리가 곧 지도가 그린 해다. */
.tl-year-btn .tly-icon { font-size: 9px; line-height: 1; opacity: 0.75; }
.tl-year-btn.is-on {
  color: var(--ink);
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
}
.tl-year-btn.is-on .tly-icon { opacity: 1; color: var(--accent); }
.tl-year-btn:disabled { opacity: 0.4; cursor: default; }
.tl-year-btn:disabled:hover { color: var(--ink-dim); border-color: var(--line); }

/* ── 정보 밀도 (간단·기본·상세) ─────────────
   축척은 그대로 두고 한 줄에 담기는 양만 바꾼다. 셋이 한 벌이라는 것이
   보여야 하므로 낱개 버튼이 아니라 붙은 한 덩어리로 그린다. */
.tl-density {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: 7px;
  flex: none;                /* 헤더가 좁아져도 눌리지 않는다 */
}
/* overflow: hidden으로 모서리를 자르지 않는다 — 폰에서 과녁을 44px로 넓히는
   ::after까지 함께 잘려 22px가 됐다(2026-08-02 실측). 양 끝 버튼에 직접
   둥근 모서리를 줘서 같은 모양을 낸다. */
.tl-density-btn:first-child { border-radius: 6px 0 0 6px; }
.tl-density-btn:last-child { border-radius: 0 6px 6px 0; }
.tl-density-btn {
  padding: 4px 8px;
  border: 0;
  border-left: 1px solid var(--line);
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 10.5px;
  font-weight: 500;
  line-height: 1.5;
  cursor: pointer;
  white-space: nowrap;
}
.tl-density-btn:first-child { border-left: 0; }
.tl-density-btn:hover { color: var(--ink); background: var(--hover); }
.tl-density-btn.is-on {
  color: var(--ink);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
}

.tl-play {
  position: absolute; top: 0; bottom: 0;
  width: 2px; margin-left: -1px;
  background: var(--accent);
  box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 70%, transparent);
  z-index: 4;                  /* 항목 띠(is-active = 3)보다 위 */
  cursor: ew-resize;
  touch-action: none;
}
/* 잡을 자리는 선보다 넓어야 한다 — 2px짜리 선을 정확히 겨냥하게 하면
   끌 수 있다는 걸 알아도 못 끈다. 보이지 않는 12px 띠를 양옆에 둔다. */
.tl-play::before {
  content: ''; position: absolute; top: 0; bottom: 0; left: -6px; right: -6px;
}

.tl-play-grip {
  position: absolute; top: 0; bottom: 0;
  transform: translateX(-50%);
  display: flex; align-items: center;
  padding: 0 7px;
  background: var(--accent);
  color: var(--bg);
  border-radius: 4px;
  font-family: "IBM Plex Mono", monospace;
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.02em;
  white-space: nowrap;
  cursor: ew-resize;
  touch-action: none;
  z-index: 5;
  box-shadow: 0 1px 6px var(--sh);
}
.tl-play-grip[hidden] { display: none; }
.tl-play[hidden] { display: none; }

/* ── 하단 가로 바 ─────────────────────── */
/* 좌·우 세로 레일과 같은 부재를 눕힌 것. 시간축의 상시 진입점이라
   연대표가 닫혀 있어도 항상 자리를 지킨다 (예전에는 하단 중앙에 뜬
   알약 버튼이었다 — 지도 위에 떠 있어 어디가 앱의 끝인지 모호했다).
   바 전체가 하나의 큰 버튼이다 — 36px 띠 안에서 71px짜리 버튼을 겨냥하게
   하는 대신, 어디를 눌러도 연대표가 나온다. */
.brail {
  cursor: pointer;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  height: var(--brail-h);
  z-index: 13;                 /* 세로 레일과 같은 층 */
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 10px;
  background: var(--surface);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--line);
  box-shadow: 0 -8px 40px var(--sh);
  transition: box-shadow 0.2s ease;
}
/* 연대표가 열리면 바와 패널은 이어진 한 면 — 그림자는 패널 쪽이 진다
   (좌·우 레일과 패널 사이에서 얼룩진 띠를 지웠던 것과 같은 이유) */
body.tl-open .brail { box-shadow: none; }

/* 하단 바의 연대표 열기 버튼.
   **테두리와 바탕을 준다** — 예전에는 둘 다 transparent라 그냥 글자로 보여
   누를 수 있는 줄 모르고 지나쳤다(2026-08-01 사용자 지적). 이 앱에서 연대표로
   들어가는 가장 큰 문이라 눌러 보이는 것이 중요하다. */
.brail-btn {
  display: flex; align-items: center; gap: 6px;
  height: 28px;
  padding: 0 13px;
  border: 1px solid color-mix(in srgb, var(--accent) 42%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--ink);
  cursor: pointer;
  font-family: inherit; font-size: 11.5px; font-weight: 700;
  letter-spacing: 0.02em;
  transition: all 0.15s ease;
}
/* 바 어디에 올려도 버튼이 켜진다 — "이 띠 전체가 눌린다"를 눈으로 알려 준다 */
.brail:hover .brail-btn,
.brail-btn:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--ink); }
.brail:hover .brail-btn.is-active { background: color-mix(in srgb, var(--accent) 24%, transparent); color: var(--accent); }
.brail-btn.is-active {
  background: color-mix(in srgb, var(--accent) 18%, transparent);
  border-color: var(--line);
  color: var(--accent);
}
.brail-ico { font-size: 14px; line-height: 1; }
.brail-hint {
  font-size: 10px; color: var(--ink-dim); opacity: 0.75;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 연대표가 열리면 같은 안내가 패널 헤더에 있다 — 바에서는 접는다 */
body.tl-open .brail-hint { display: none; }

/* 연대표 항목 팝업의 설명 줄 (nv-popup 안) */
.nvp-desc {
  margin-top: 5px;
  max-width: 260px;
  font-size: 11px; line-height: 1.6;
  color: var(--ink-dim);
  white-space: normal;
}

/* 연대표 클릭 지점 마커 — 지도 위 호박색 점 */
/* 연대표에서 고른 항목의 중심지. 영토 도형이 없는 항목(부여·선비·금·인물)에서는
   이 점이 지도에 남는 유일한 표시라, 트랙 색을 그대로 물려받아 연대표의 어느
   줄에서 온 것인지 알 수 있게 한다 (--c는 focusTimelineItem이 넣는다). */
/* 연대표에서 고른 항목의 지도 표시 — 점 하나와 이름 한 줄.
   가로로 눕혀 점이 좌표에 오고 이름이 그 오른쪽에 붙는다. */
/* 이름표는 흐름에서 빼서 점 오른쪽에 띄운다. **좌표에 맞춰지는 것은 이 요소의
   가운데**이므로(MapLibre 마커 기본 anchor), 이름을 같은 줄에 세워 두면 글자
   길이의 절반만큼 점이 왼쪽으로 밀린다 — 이름을 붙인 뒤 이븐 루시드가 코르도바가
   아니라 대서양 한복판에 찍혔다. 요소의 크기를 점 하나로 고정해야 좌표가 맞는다. */
.tl-map-mark {
  position: relative;
  box-sizing: border-box;
  width: 18px; height: 18px;
  pointer-events: none;         /* 지도 클릭을 가로채지 않는다 */
  white-space: nowrap;
}
.tl-map-dot {
  display: block;               /* 인라인으로 두면 width가 먹지 않아 점이 찌그러진다 */
  box-sizing: border-box;
  width: 100%; height: 100%;
  border-radius: 50%;
  background: var(--c, var(--accent));
  border: 2px solid #fff;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--c, var(--accent)) 25%, transparent), 0 2px 10px rgba(0, 0, 0, 0.5);   /* 지도 위 마커 — 테마 무관 */
}
/* 배경(밝은 역사 지도 / 어두운 위성)이 무엇이든 읽혀야 하므로 글자에 테두리를
   둘러 띄운다. 테두리 색은 흰색이 아니라 트랙 색(--c) — 지도의 이름표와 연대표의
   띠가 같은 색이면 어느 줄에서 온 항목인지 지도만 봐도 알 수 있다.
   흐림(blur) 대신 여덟 방향으로 찍어 윤곽선을 만든다 — 흐리면 색이 옅어져
   트랙을 구분하지 못한다. */
.tl-map-name {
  position: absolute;                       /* 흐름 밖 — 점의 좌표를 밀지 않는다 */
  left: 20px; top: 50%; transform: translateY(-50%);
  font-size: 16px; font-weight: 800; letter-spacing: -0.01em;
  color: #000;
  text-shadow:
    -2px 0 var(--c, #fff), 2px 0 var(--c, #fff), 0 -2px var(--c, #fff), 0 2px var(--c, #fff),
    -1.4px -1.4px var(--c, #fff), 1.4px -1.4px var(--c, #fff),
    -1.4px 1.4px var(--c, #fff), 1.4px 1.4px var(--c, #fff),
    /* 트랙 색이 밝은 지도에 묻히지 않게 같은 색을 한 겹 더 번지게 깐다 */
    0 0 8px color-mix(in srgb, var(--c, #fff) 70%, transparent);
}

/* 지도 저작권 표기는 하단 바(+연대표) 바로 위에 얹는다 — 가릴 수 없다.
   나머지 하단 요소는 각자 규칙에서 --btm-h를 더해 이미 비켜나 있다. */
.maplibregl-ctrl-bottom-right,
.maplibregl-ctrl-bottom-left { bottom: var(--btm-h); }

@media (max-width: 620px) {
  .tl-hint, .brail-hint { display: none; }
  .tl-scroll { max-height: 30vh; }
  /* 좁은 화면에서는 레일이 상단 가로 바이고 패널은 하단 시트라, 전체 화면에서
     오른쪽을 비워 둘 이유가 없다 (비우면 빈 띠만 남는다) */
  .tlpanel.is-max,
  body.rail-open .tlpanel.is-max { right: 0; }
  /* 이름 열을 조금 넓힌다 — 58px에서는 깊이 1(연대표 이름)을 9px까지 줄여야
     들어갔는데, 그러면 자식인 트랙 이름(11px)보다 작아져 **위아래 관계가
     거꾸로 읽힌다.** 데스크톱에서 이미 같은 이유로 고친 문제다(연대표 설계 §3).
     여기서는 열을 넓혀 글자를 줄이지 않는 쪽을 택한다. */
  :root { --tl-label-w: 68px; }
  /* 깊이별 글자 크기: 깊이 1(연대표 이름) > 깊이 2(트랙 이름).
     좁은 화면이라 데스크톱(12/11)보다 한 단계씩 작지만 **순서는 지킨다.** */
  .tl-track-label { font-size: 10px; }
  .tl-track-label.is-ages { font-size: 11.5px; padding-left: 4px; }
  /* 라벨 열이 좁으면 손잡이 12 + 접기 12를 빼고 이름 자리가 얼마 안 남는다.
     두 띠를 좁히고 배지는 숫자 대신 점 하나로 낮춘다. */
  .tl-track-label { padding-left: 11px; padding-right: 12px; }
  .tl-track-handle { width: 12px; }
  .tl-track-handle i { width: 7px; }
  .tl-track-fold { width: 12px; }
  .tl-fold-badge { font-size: 0; padding: 0; width: 5px; height: 5px; align-self: center; }
  /* 헤더에 버튼이 더 들어갈 자리가 없다 — '그 해의 지도'는 아이콘만 남긴다.
     기능 자체는 그대로다(누르면 세로선이 서고 지도가 그 해로 바뀐다). */
  .tl-year-btn .lp2-all-label { display: none; }
  .tl-year-btn { padding: 4px 6px; }

  /* 헤더가 가로로 넘쳐 오른쪽 버튼들이 화면 밖에 있었다 (2026-08-02 실측:
     tl-head 663px > 390px, tl-head-right가 x=436 — 연대표가 다섯이 되면서
     칩 줄만 377px이다). 정보 밀도를 넣기 전부터 있던 문제다.
     **칩 줄만 가로로 스크롤시키고 오른쪽 버튼들은 제자리에 못 박는다.**
     칩은 원래 여러 개가 이어지는 목록이라 스크롤이 자연스럽지만, 버튼은
     화면 밖에 있으면 있는 줄도 모른다. */
  .tl-sets {
    overflow-x: auto;
    flex-wrap: nowrap;
    scrollbar-width: none;         /* 줄 하나짜리 띠에 막대까지 뜨면 지저분하다 */
    min-width: 0;                  /* flex 자식이 내용만큼 버티지 않게 */
  }
  .tl-sets::-webkit-scrollbar { display: none; }
  .tl-set-chip { flex: none; }
  .tl-head-right { flex: none; margin-left: auto; }

  /* 정보 밀도 — 폰에서는 헤더가 이미 넘쳐 가로로 밀린다(실측 682px > 390px).
     글자 대신 **막대 세 개의 굵기**로 뜻을 보인다: 간단은 한 줄, 기본은
     두 줄, 상세는 세 줄. 언어를 타지 않아 ko·en·es가 같은 폭을 쓴다
     (한 글자로 줄이는 방법은 'Simple'·'Detallado'에서 무너진다).
     뜻은 title·aria-label에 그대로 남아 읽어 주는 기기는 잃는 것이 없다.
     세로 과녁은 아래 ::after 규칙이 44px로 넓힌다. */
  .tl-density-btn { padding: 5px 8px; }
  /* 막대는 box-shadow로 그리므로 높이를 만들지 않는다 — 셋을 담을 10px을
     직접 준다. 안 그러면 span이 2px로 접혀 둘째·셋째 줄이 잘린다. */
  .tl-density-btn > span { font-size: 0; display: block; width: 13px; height: 10px; }
  .tl-density-btn > span::before {
    content: '';
    display: block;
    height: 2px;
    border-radius: 1px;
    background: currentColor;
    box-shadow: 0 4px 0 currentColor;    /* 둘째 줄 */
    width: 100%;
  }
  /* 간단 = 한 줄만 (둘째 줄 그림자를 지운다) */
  .tl-density-btn[data-density="simple"] > span::before { box-shadow: none; }
  /* 상세 = 셋째 줄까지 */
  .tl-density-btn[data-density="detail"] > span::before {
    box-shadow: 0 4px 0 currentColor, 0 8px 0 currentColor;
  }

  /* ── 터치 과녁 넓히기 (2026-08-01) ────────────────────────
     손가락 끝은 약 44px이다(Apple HIG). 실측해 보니 44px 미만이 81개였고
     최악은 레이어 스위치 28×16px — 정확히 누르기 어렵다.

     **보이는 크기는 그대로 두고 눌리는 자리만 넓힌다.** 요소 자체를 키우면
     좁은 화면에서 줄바꿈이 나고 설계된 간격이 무너진다. ::after로 투명한
     사각형을 덧씌워 과녁만 키운다 — 화면에는 아무 변화가 없다. */
  /* **이미 자리를 잡은 요소(position: absolute·fixed)는 건드리지 않는다.**
     여기에 넣었다가 두 번 망가뜨렸다:
       .layer-info-btn — absolute가 덮여 오른쪽 끝의 ⓘ가 왼쪽으로 (x=347→13)
       .compass·.home-btn — fixed가 덮여 right:176px이 왼쪽 이동으로 바뀌어
         화면 밖(x=-176)에 그려졌다. 지도를 돌려야 나타나는 버튼이라
         한동안 눈에 안 띄었다.
     ::after는 부모가 static이든 fixed든 똑같이 얹히므로 position을 바꿀
     이유가 애초에 없다. 이미 자리 잡은 것은 그대로 두고 과녁만 씌운다. */
  .layer-sw, .accent-dot, .panel-close,
  .tl-track-fold, .fs-btn, .tl-year-btn,
  .nav-item, .tl-set-chip, .tl-density-btn {
    position: relative;
  }
  /* 지도 팝업의 닫기 — 이미 absolute라 position은 건드리지 않고 과녁만 넓힌다 */
  .nv-popup .maplibregl-popup-close-button::after {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 44px; height: 44px;
  }
  .layer-sw::after, .layer-info-btn::after, .accent-dot::after,
  .panel-close::after, .tl-track-fold::after, .fs-btn::after,
  .tl-year-btn::after, .compass::after, .home-btn::after,
  .nav-item::after, .tl-set-chip::after, .tl-density-btn::after {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: max(100%, 44px);
    height: max(100%, 44px);
    /* 그리지 않는다 — 오직 포인터를 받기 위한 것 */
    background: none;
  }
  /* 스위치 안의 손잡이(::before)가 과녁에 가려 안 보이면 안 된다 */
  .layer-sw::before { z-index: 1; }

  /* 접기 화살표는 라벨 열 오른쪽 끝에 붙어 있다. 과녁을 좌우로 넓히면
     이름 위를 덮으므로 **세로로만** 넓힌다 (라벨 칸 전체가 이미 접기
     과녁이라 가로는 넓힐 이유도 없다 — 연대표 설계 §3). */
  .tl-track-fold::after { width: 100%; }

  /* 정보 밀도 셋은 서로 붙어 있다 — 가로로 넓히면 이웃의 과녁을 덮어
     '간단'을 누르려다 '기본'이 눌린다. 세로로만 넓힌다. */
  .tl-density-btn::after { width: 100%; }

  /* 레이어 한 줄이 이 앱에서 가장 많이 누르는 곳이다(레이어 13개 × 스위치).
     줄을 손가락 크기로 높인다 — 과녁만 넓혀 봐야 부모 줄이 낮으면 잘린다.
     **min-height가 아니라 padding으로 높인다.** min-height를 주면 .layer-row가
     flex 안에서 늘어나면서 설명(ⓘ)의 기준 상자가 바뀌어, 오른쪽 끝에 있던
     ⓘ가 왼쪽으로 밀려났다(실측 x=347 → 13). padding은 그 기준을 건드리지 않는다. */
     행이 이름 한 줄이 되면서(2026-08-05) 글자 높이가 두 줄→한 줄로 줄어
     같은 9px 패딩으로는 과녁이 36px까지 내려왔다(mobile-touch 실측).
     11px로 올려 38px을 되찾는다 — 촘촘하게 보이는 이득은 넓은 화면에서
     취하고, 폰에서는 손가락이 먼저다. */
  .layer-row { padding-top: 11px; padding-bottom: 11px; }
  /* 넓은 화면에서 줄인 항목 간격(1px)은 폰에서 줄끼리 붙어 보이게 한다.
     간격은 과녁의 위아래 경계이기도 해서, 이 값이 곧 손가락 여유가 된다. */
  .layer-list { gap: 3px; }

  /* 설명(ⓘ)은 **크기를 건드리지 않는다.** 과녁만 넓힌다(::after, 위 규칙).
     세로로 키우면 같은 줄의 켜기 스위치와 과녁을 다투고, 위치를 옮기면
     제자리를 잃는다 — 실제로 손대 봤다가 왼쪽 끝으로 밀려났다.
     지금도 27px이라 44px에는 못 미치지만, 스위치(38px)와 서로 침범하지
     않는 것을 확인했다. 둘을 다 키우려면 줄 구조 자체를 바꿔야 한다. */
}

/* 연대표 켜고 끄기 칩 (헤더) — 기본 연대표 / 철학의 역사 / … */
.tl-sets { display: flex; align-items: center; gap: 5px; }
.tl-set-chip {
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-dim); cursor: pointer;
  font-family: inherit; font-size: 10.5px;
  padding: 3px 10px;
  white-space: nowrap;
  transition: all 0.15s ease;
}
.tl-set-chip:hover { border-color: var(--accent); color: var(--ink); }
.tl-set-chip.is-on {
  color: var(--ink);
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

/* 항목 유형 구분 — 사조·시대는 굵고 진한 띠, 인물은 그 위에 얹히는 얇은 알약.
   2026-07-31에 뒤집었다. 그전에는 era가 8~14%로 일반 항목(16%)보다 **옅어서**
   사조와 인물이 구분되지 않았다 — 철학 연대표를 전체 보기로 띄우면 시대 띠와
   인물이 같은 크기·같은 농도로 섞여 "지금 보는 것이 어느 시대인가"가 읽히지
   않았다. era는 그 트랙의 배경이지 인물과 자리를 다투는 항목이 아니다.
   ([주제별 연대표 가이드 §4.2](../docs/주제별-연대표-작성-가이드.md)) */
.tl-item.is-era {
  height: 20px;                       /* 인물(14px)보다 두껍게. LANE_H(21px)를 넘기지 않는다 */
  /* 레인 좌표(r.top)는 레인의 위 모서리다 — 높이가 유형마다 다르므로 기본
     18px과의 차이만큼 끌어올려 레인 한가운데에 세운다. 안 하면 굵은 띠와
     얇은 알약이 같은 레인에서 위아래로 어긋나 보인다. */
  margin-top: -1px;
  border-style: solid;
  border-color: color-mix(in srgb, var(--c) 85%, transparent);
  background: color-mix(in srgb, var(--c) 42%, color-mix(in srgb, var(--bg) 30%, transparent));
  font-weight: 700;
  letter-spacing: 0.01em;
  z-index: 0;                         /* 인물 알약이 위에 얹히도록 */
}
.tl-item.is-era.is-rank1 {
  background: color-mix(in srgb, var(--c) 58%, color-mix(in srgb, var(--bg) 22%, transparent));
}
.tl-item.is-era:hover {
  background: color-mix(in srgb, var(--c) 70%, color-mix(in srgb, var(--bg) 15%, transparent));
}
/* 인물은 era 위에 얹히는 얇은 알약 — 배경 띠와 겹쳐도 글자가 읽히도록
   불투명에 가깝게 두고 테두리를 또렷하게 한다. */
.tl-item.is-person {
  height: 14px;
  margin-top: 2px;                    /* 위 주석과 같은 이유 — 레인 한가운데로 */
  border-radius: 9px;
  font-size: 10px;
  background: color-mix(in srgb, var(--bg) 88%, var(--c));
  border-color: color-mix(in srgb, var(--c) 75%, transparent);
  z-index: 1;
}
.tl-item.is-person.is-rank1 { font-weight: 700; }
.tl-item.is-person:hover { background: color-mix(in srgb, var(--c) 40%, var(--bg)); }

/* 건축물은 존속 기간 막대가 아니라 대표 준공·개장 연도의 한 점이다. 버튼은
   20×18px 과녁이지만 눈에 보이는 것은 가운데 8px 사각형뿐이라, 클릭하기 쉽다고
   시간이 길어 보이지 않는다. 같은 해·가까운 해의 버튼 충돌은 panel-timeline의
   점 항목 레인 계산이 이 20px 폭을 함께 반영한다. */
.tl-item.is-building {
  height: 18px;
  padding: 0;
  justify-content: center;
  overflow: visible;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  z-index: 2;
}
.tl-item.is-building::before {
  content: '';
  display: block;
  width: 8px; height: 8px;
  box-sizing: border-box;
  border: 1.5px solid color-mix(in srgb, var(--c) 85%, var(--ink));
  border-radius: 1px;
  background: color-mix(in srgb, var(--c) 72%, var(--bg));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--bg) 75%, transparent);
  transition: transform 0.12s ease, background 0.12s ease, box-shadow 0.12s ease;
}
.tl-item.is-building .tl-item-label { display: none; }
.tl-item.is-building:hover,
.tl-item.is-building.is-active { background: transparent; border: 0; box-shadow: none; }
.tl-item.is-building:hover::before { transform: scale(1.35); background: var(--c); }
.tl-item.is-building.is-active::before {
  transform: scale(1.35);
  background: var(--c);
  box-shadow: 0 0 0 2px var(--ink), 0 0 9px color-mix(in srgb, var(--c) 75%, transparent);
}
.tl-item.is-building:focus-visible { outline: 1px solid var(--ink); outline-offset: -1px; }

/* ── 키 컬러(액센트) — 테마와 독립 선택 ───────
   파생색(경계선·호버·칩)이 전부 --accent의 color-mix라 변수 하나면 된다.
   기본 앰버는 속성 없음. 검은색(다크) 테마에서는 밝은 변형을 쓴다. */
:root[data-accent="yellow"] { --accent: #97832a; }
:root[data-accent="blue"]   { --accent: #3f6fa3; }
:root[data-accent="green"]  { --accent: #41784b; }
:root[data-accent="violet"] { --accent: #7a58a3; }
:root[data-accent="teal"]   { --accent: #2f7c80; }
:root[data-theme="black"][data-accent="yellow"] { --accent: #ddc84f; }
:root[data-theme="black"][data-accent="blue"]   { --accent: #6fa8d9; }
:root[data-theme="black"][data-accent="green"]  { --accent: #71b87e; }
:root[data-theme="black"][data-accent="violet"] { --accent: #a98fd8; }
:root[data-theme="black"][data-accent="teal"]   { --accent: #62b8bb; }
:root[data-accent="red"]   { --accent: #a84438; }
:root[data-theme="black"][data-accent="red"]   { --accent: #d96b5c; }
/* 검은색 액센트 = 무채색(모노) — 다크 테마에서는 밝은 잉크색이어야 보인다 */
:root[data-accent="black"] { --accent: #3a372f; }
:root[data-theme="black"][data-accent="black"] { --accent: #c9c5bc; }

.accent-row { display: flex; gap: 8px; padding-top: 8px; }
.accent-dot {
  width: 20px; height: 20px;
  border-radius: 50%;
  border: 2px solid transparent;
  padding: 0; cursor: pointer;
  transition: transform 0.12s ease, border-color 0.12s ease;
}
.accent-dot:hover { transform: scale(1.15); }
.accent-dot.is-active { border-color: var(--ink); box-shadow: 0 0 0 2px var(--surface); }
.accent-dot[data-accent="amber"]  { background: #c8944a; }
.accent-dot[data-accent="yellow"] { background: #cdb43e; }
.accent-dot[data-accent="blue"]   { background: #5b8fc4; }
.accent-dot[data-accent="green"]  { background: #5aa068; }
.accent-dot[data-accent="violet"] { background: #9678c0; }
.accent-dot[data-accent="teal"]   { background: #4aa0a4; }
.accent-dot[data-accent="red"]    { background: #c25a4d; }
.accent-dot[data-accent="black"]  { background: #33302a; box-shadow: inset 0 0 0 1.5px rgba(140, 140, 140, 0.55); }

/* ── 연대표 높이 조절 핸들 (패널 상단 가장자리) ── */
.tl-resize {
  position: absolute;
  top: -5px; left: 0; right: 0;
  height: 10px;
  cursor: ns-resize;
  z-index: 3;
  touch-action: none;
}
/* 가운데 손잡이 — 두 줄. 마우스를 올려야 나타나던 한 줄은 "끌 수 있다"를
   숨긴 것과 같았다. 늘 보이게 두고, 잡으면 액센트로 물든다.
   윗선 위에 걸터앉아 지도 쪽으로 조금 올라와 있다 — 헤더의 버튼·문구를 가리지
   않으면서(가운데 56px뿐) 손으로 잡을 면적은 밴드(10px)보다 넓어진다. */
.tl-grip {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  gap: 2.5px;
  padding: 2.5px 13px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--line);
  transition: border-color 0.15s ease;
}
.tl-grip i {
  display: block;
  width: 22px; height: 1.5px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--ink) 32%, transparent);
  transition: background 0.15s ease;
}
.tl-resize:hover .tl-grip,
.tl-resize:active .tl-grip { border-color: var(--accent); }
.tl-resize:hover .tl-grip i,
.tl-resize:active .tl-grip i { background: var(--accent); }

/* ── 편집형 회차 읽기 화면 (파일럿) ─────────────────
   글 옆에 지도가 있으면 이해가 깊어지는가를 재는 화면이다. 그래서 지도를
   덮지 않고 **왼쪽을 비운 채** 오른쪽에만 선다 — 지도가 계속 보여야 본문과
   지도를 오가는 동작 자체를 관찰할 수 있다.
   기존 우측 패널(.panel)과 겹치지 않도록 레일 안쪽까지만 차지한다. */
/* 지도와 글이 나눠 갖는 자리 — 사용자가 손잡이로 정한다(panel-content.js).
   --cv-w: 넓은 화면의 읽기 폭 · --cv-strip: 폰에서 남길 지도 띠 높이 */
:root { --cv-w: min(46vw, 520px); --cv-strip: 88px; }

.content-view {
  position: fixed;
  top: var(--nav-h); right: 0; bottom: var(--btm-h);
  width: var(--cv-w);
  z-index: 15;                  /* 연대표 전체화면(14)보다 위, 네비(20)보다 아래 */
  display: flex; flex-direction: column;
  /* 다른 패널은 반투명(--surface)이지만 여기는 **불투명**이다. 저쪽은 잠깐
     보는 카드라 뒤가 비쳐도 되지만, 이 화면은 몇 분을 읽는 자리다. 지도의
     지명과 본문 글자가 겹치면 글이 읽히지 않는다 (2026-08-02 실측). */
  background: var(--bg);
  border-left: 1px solid var(--line);
  box-shadow: -8px 0 24px var(--sh);
  overflow: hidden;
}
.content-view[hidden] { display: none; }

/* 카탈로그는 고르는 화면이라 지도가 할 일이 없다 — 화면을 다 쓴다.
   지도는 회차에 들어가야 나온다 (2026-08-02 요청). 크기 손잡이도 이때는
   나눌 것이 없으니 숨긴다. */
body.content-full .content-view {
  top: var(--nav-h); left: 0; right: 0; width: auto;
  border-left: none;
}
body.content-full .cv-resize { display: none; }

/*
 * ── 좌/우 배치 (2026-08-03 요청) ───────────────────────────
 * 글을 왼쪽에 두고 싶은 사람이 있다. 지도는 자연히 반대편으로 간다.
 * 기본은 오른쪽(위 규칙), 왼쪽일 때만 여기서 뒤집는다.
 */
/* :not(.content-full) — 목록으로 돌아가면 좌/우 구분이 없다. 이 조건이
   없으면 왼쪽에 고정된 채 폭만 --cv-w로 남아 옆에 지도가 비쳤다
   (2026-08-03 제보: 뒤로 갔는데 지도가 안 사라짐). */
body.cv-left:not(.content-full) .content-view {
  left: 0; right: auto;
  border-left: none; border-right: 1px solid var(--line);
  box-shadow: 8px 0 24px var(--sh);
}
body.cv-left:not(.content-full) .cv-resize { left: auto; right: -5px; }

/* 연대표가 지도 폭만큼만 눕게 된 뒤로는(아래) 글 아래가 비어 지도가 비쳤다.
   연대표가 그 자리를 안 쓰므로 글이 바닥까지 내려간다 (2026-08-03).
   폰도 같다 — 하단 바(36px)가 본문 아래에 띠로 남아 절 제목을 잘랐다.
   연대표는 하단 바 대신 상단 메뉴의 '연대표'로 연다. */
body.content-open .content-view { bottom: 0; }
/* 회차를 읽는 동안에는 하단 바를 감춘다 — 남겨 두면 그 36px만큼 글이 잘린다 */
body.content-open:not(.content-full) #brail { display: none; }

/*
 * ── 연대표는 지도 폭만큼만 (2026-08-03 요청) ────────────────
 * 회차를 읽는 동안 연대표가 화면을 가로지르면 본문 아래로 파고든다.
 * 글이 차지한 쪽을 비워 두고 지도 위에만 눕는다.
 */
body.content-open:not(.content-full) #tlpanel { right: var(--cv-w); }
body.content-open:not(.content-full).cv-left #tlpanel { right: 0; left: var(--cv-w); }
/* 하단 바(연대표 열기 단추가 있는 줄)도 같이 물러난다 */
body.content-open:not(.content-full) #brail { right: var(--cv-w); }
body.content-open:not(.content-full).cv-left #brail { right: 0; left: var(--cv-w); }

/*
 * ── 지도 조작 아이콘 (2026-08-03 요청) ──────────────────────
 * 회차를 읽는 동안에도 전체보기·검색·지도유형·제자리가 보여야 한다. 이들은
 * 모두 화면 오른쪽 끝에 붙어 있어 읽기 화면(z15)에 통째로 가려졌다 —
 * **지도가 있는 쪽 안으로** 들여놓는다.
 * 크기도 44px에서 36px로 줄인다. 다른 메뉴 아이콘과 같은 크기다.
 */
/* --cv-w는 **넓은 화면 전용**이다(폰은 위아래로 나뉜다). 폰까지 걸리면
   버튼이 지도 한복판으로 밀려난다(2026-08-03 제보: 위치가 중간으로 와 있음). */
@media (min-width: 621px) {
body.content-open:not(.content-full) .basemap-btn,
body.content-open:not(.content-full) .basemap-btn.is-panel-closed { right: calc(var(--cv-w) + 14px); }
body.content-open:not(.content-full) .search-btn,
body.content-open:not(.content-full) .search-btn.is-panel-closed { right: calc(var(--cv-w) + 60px); }
body.content-open:not(.content-full) .compass,
body.content-open:not(.content-full) .compass.is-panel-closed { right: calc(var(--cv-w) + 106px); }
body.content-open:not(.content-full) .mapctl-bottom,
body.content-open:not(.content-full) .mapctl-bottom.is-panel-closed { right: calc(var(--cv-w) + 14px); }
}

/* 글이 왼쪽이면 아이콘은 화면 오른쪽으로 되돌아간다 — 그쪽이 지도다.
   다만 화면 끝에는 우측 레일(상세 버튼)이 서 있다. --rail-w만큼 비켜서지
   않으면 레일 아이콘이 위를 덮어 눌리지 않는다(2026-08-03 제보). */
@media (min-width: 621px) {
body.content-open:not(.content-full).cv-left .basemap-btn,
body.content-open:not(.content-full).cv-left .basemap-btn.is-panel-closed { right: calc(var(--rail-w) + 14px); }
body.content-open:not(.content-full).cv-left .search-btn,
body.content-open:not(.content-full).cv-left .search-btn.is-panel-closed { right: calc(var(--rail-w) + 60px); }
body.content-open:not(.content-full).cv-left .compass,
body.content-open:not(.content-full).cv-left .compass.is-panel-closed { right: calc(var(--rail-w) + 106px); }
body.content-open:not(.content-full).cv-left .mapctl-bottom,
body.content-open:not(.content-full).cv-left .mapctl-bottom.is-panel-closed { right: calc(var(--rail-w) + 14px); }
body.content-open:not(.content-full).cv-left .basemap-pop,
body.content-open:not(.content-full).cv-left .search-pop { right: calc(var(--rail-w) + 14px); }
}

/* 버튼만 옮기고 팝오버를 두고 왔더니, 좌측 배치에서 메뉴가 버튼과 떨어진
   자리(x=1102)에 열려 읽기 화면 아래로 들어갔다(2026-08-03 제보).
   팝오버도 같이 옮기고, 읽기 화면(15)보다 위에 띄운다. */
/* 폰에서는 회차가 위아래로 나뉘어 --cv-w가 없다. 이 규칙이 걸리면 팝오버가
   왼쪽 끝(x=14)으로 튀어 본문 위로 443px 흘러내렸다(2026-08-03 제보). */
@media (min-width: 621px) {
body.content-open:not(.content-full) .basemap-pop,
body.content-open:not(.content-full) .search-pop { right: calc(var(--cv-w) + 14px); z-index: 16; }
}
body.content-open:not(.content-full).cv-left .basemap-pop,
body.content-open:not(.content-full).cv-left .search-pop { right: 14px; z-index: 16; }

/* 크기 — 읽는 화면에서는 지도 조작이 주인공이 아니다 */
body.content-open:not(.content-full) .basemap-btn,
body.content-open:not(.content-full) .search-btn,
body.content-open:not(.content-full) .compass { width: 36px; height: 36px; }
body.content-open:not(.content-full) .home-btn { width: 34px; height: 34px; }
body.content-open:not(.content-full) .zoombar { transform: scale(0.88); transform-origin: right center; }

/* 크기 손잡이 — 연대표 높이(.tl-resize)와 같은 문법. 넓은 화면에서는 왼쪽
   가장자리를 가로로, 폰에서는 위 가장자리를 세로로 끈다. */
.cv-resize {
  position: absolute;
  top: 0; bottom: 0; left: -5px; width: 10px;
  cursor: ew-resize; z-index: 4; touch-action: none;
}
.cv-grip {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  display: flex; gap: 2.5px;
  padding: 13px 2.5px;
  border-radius: 999px;
  background: var(--surface); border: 1px solid var(--line);
  transition: border-color 0.15s ease;
}
.cv-grip i {
  display: block; width: 1.5px; height: 22px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--ink) 32%, transparent);
  transition: background 0.15s ease;
}
.cv-resize:hover .cv-grip, .cv-resize:active .cv-grip { border-color: var(--accent); }
body.cv-rz { cursor: ew-resize; user-select: none; }
body.cv-rz .cv-grip { border-color: var(--accent); }

.cv-bar {
  flex: none; display: flex; align-items: center;
  gap: 8px; padding: 6px 12px;
  border-bottom: 1px solid var(--line);
}
.cv-back, .cv-close, .cv-side {
  font: inherit; color: var(--ink); background: transparent;
  border: 1px solid var(--line); border-radius: 999px;
  padding: 6px 12px; cursor: pointer; min-height: 32px;
}
.cv-back:hover, .cv-close:hover, .cv-side:hover { border-color: var(--accent); }
/* 좌/우 배치 전환 — 폰에서는 위아래로 나뉘어 뒤집을 것이 없다 */
.cv-side { font-size: 13px; color: var(--ink-dim); }
.cv-side:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 620px) { .cv-side { display: none; } }
.cv-back:focus-visible, .cv-close:focus-visible,
.cv-toc-b:focus-visible, .cv-chip:focus-visible,
.cv-ep-open:focus-visible, .cv-switch:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

/* 제목은 막대 안에 들어간다 — 뒤로·제목·배치 전환이 한 줄이다(2026-08-03).
   따로 머리글 블록을 두면 본문이 시작되기 전에 세 줄을 쓴다. */
.cv-head { flex: none; padding: 12px 16px 4px; }
.cv-title {
  flex: 1; min-width: 0;
  margin: 0; font-size: 15.5px; line-height: 1.3; color: var(--ink);
  font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cv-q { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-dim); }

/* 회차의 뒤로 가기는 화살표뿐이라 정사각으로 줄인다. 시리즈 목록의
   '← 목록'은 글자가 있으므로 이 규칙을 받지 않는다 — 폭을 묶으면 두 줄로
   접힌다(2026-08-03). */
.cv-bar .cv-title + .cv-side,
body.content-open:not(.content-full) .cv-bar > .cv-back:first-child {
  flex: none;
}
.cv-bar:has(.cv-title) .cv-back {
  flex: none; width: 30px; min-height: 30px; padding: 0;
  font-size: 15px; line-height: 1; white-space: nowrap;
}
.cv-bar .cv-side { flex: none; padding: 4px 9px; min-height: 28px; font-size: 12px; }

.cv-toc {
  flex: none; display: flex; flex-wrap: wrap; gap: 6px;
  padding: 10px 16px; border-bottom: 1px solid var(--line);
}
.cv-toc-b {
  font: inherit; font-size: 12px; color: var(--ink-dim);
  background: transparent; border: 1px solid var(--line); border-radius: 999px;
  padding: 5px 10px; cursor: pointer;
}
.cv-toc-b:hover { color: var(--ink); border-color: var(--accent); }

.cv-body { flex: 1; overflow-y: auto; padding: 8px 16px 24px; }

/* 선택된 절 — 색만으로 구분하지 않는다. 왼쪽 굵은 선과 배경을 함께 쓴다. */
.cv-sec {
  padding: 12px; margin: 8px 0; cursor: pointer;
  border-left: 3px solid transparent; border-radius: 6px;
}
.cv-sec:hover { background: color-mix(in srgb, var(--accent) 6%, transparent); }
.cv-sec.is-on {
  border-left-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 11%, transparent);
}
.cv-sec-h { margin: 0 0 6px; font-size: 14px; color: var(--ink); }
.cv-sec-b { margin: 0 0 8px; font-size: 13px; line-height: 1.65; color: var(--ink); }

/* 문장 속 누를 수 있는 문구 (§3.2).
   링크와 작은 태그의 **중간**으로 보이게 한다 — 알약으로 만들면 문장이
   끊기고, 맨 글자로 두면 누를 수 있는 줄 모른다. 그래서 옅은 배경과 얇은
   밑줄만 준다. 문장 안에 있으므로 줄바꿈을 따라 접혀야 한다(inline). */
.cv-cue {
  color: var(--ink);
  background: color-mix(in srgb, var(--accent) 11%, transparent);
  /* 밑줄은 border가 아니라 text-decoration으로 긋는다 — border-bottom은 상자
     아래에 한 줄만 그어져, 두 줄로 접힌 문구의 첫 줄에는 밑줄이 안 남는다. */
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 55%, transparent);
  text-underline-offset: 3px;
  border-radius: 3px;
  padding: 0 2px; cursor: pointer;
  /* span이라 낱말 단위로 접힌다. button은 브라우저가 inline-block으로 못박아
     긴 문구가 줄 끝에서 통째로 넘어갔다(2026-08-03). */
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
.cv-cue:hover { background: color-mix(in srgb, var(--accent) 22%, transparent); }
.cv-cue:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* 켜진 문구는 지도·연대표 강조와 같은 색을 쓴다 — 셋이 한 곳을 가리킨다는
   것을 색으로 잇는다 (§3.2). */
.cv-cue.is-on {
  background: var(--accent); color: var(--bg);
  text-decoration-color: var(--accent); font-weight: 600;
}

/* 절 아래 칩(.cv-chips/.cv-chip)은 없앴다 — 본문의 낱말이 같은 항목을
   가리키므로 같은 것을 두 번 늘어놓는 셈이었다 (2026-08-03). */

/*
 * 낱말을 누르면 열리던 사진 카드를 **본문 옆에 상시** 둔다(2026-08-03 요청).
 * 갑자기 튀어나오면 읽던 글이 밀려 자리를 잃었다. 절 안에서 오른쪽에 작게
 * 띄우고 글이 그 옆을 흐르게 한다 — 넓은 화면에서만. 폰은 폭이 없어 아래에
 * 그대로 쌓는다.
 */
.cv-info { margin: 8px 0 0; }
.cv-info:empty { display: none; }

/*
 * 폰에서는 사진이 읽는 자리를 통째로 먹었다(2026-08-03 제보: 글이 아예 안
 * 보임). 넓은 화면과 같은 뜻으로 — 글 옆에 작게 — 두되 크기만 줄인다.
 * 폰은 문단 폭이 좁아 42%를 넘기면 남는 글줄이 토막 난다.
 */
@media (max-width: 620px) {
  .cv-info {
    float: right; width: 42%; max-width: 150px;
    margin: 2px 0 8px 10px;
  }
  .cv-info .info-card { padding: 6px 7px 5px; gap: 4px; }
  .cv-info .info-img { max-height: 92px; }
  .cv-info .info-text {
    font-size: 10.5px; line-height: 1.45;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .cv-info.is-tight .info-text,
  .cv-info.is-tight .info-more { display: none; }
  .cv-info .info-src { font-size: 8.5px; }
  .cv-sec::after { content: ''; display: block; clear: both; }
  /* 확대하면 폭을 다 쓴다 — 사진을 제대로 볼 유일한 길이다 */
  .cv-info.is-big { float: none; width: auto; max-width: none; margin: 8px 0; }
  .cv-info.is-big .info-img { max-height: 220px; }
  .cv-info.is-big .info-text { -webkit-line-clamp: none; font-size: 12px; }
  .cv-zoom { display: block; width: 24px; height: 24px; font-size: 12px; }
}
@media (min-width: 621px) { .cv-info .info-img { max-height: 240px; } }

@media (min-width: 621px) {
  .cv-info {
    /* 글보다 먼저 오므로(panel-content.js) 뒤따르는 문단이 이 옆을 흐른다.
       36%는 남은 폭에 우리말 한 줄이 20자쯤 들어가는 선이다 — 더 넓히면
       글줄이 토막 나고, 더 좁히면 사진을 알아보기 어렵다. */
    float: right; width: 36%; max-width: 210px;
    margin: 2px 0 10px 14px;
  }
  .cv-info .info-card { padding: 8px 9px 7px; gap: 5px; }
  /* 짧은 문단 옆에서 사진이 혼자 길면 그만큼 왼쪽이 빈다. 세로를 묶어
     글이 끝나기 전에 사진도 끝나게 한다 — 크게 보려면 ⤢가 있다. */
  .cv-info .info-img { max-height: 118px; }
  .cv-info .info-text {
    font-size: 11.5px; line-height: 1.5;
    /* 옆에 붙은 카드는 짧게 — 길면 글보다 사진 설명이 길어진다.
       확대 버튼을 누르면 전문이 나온다. */
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
  }
  /* 문단이 짧은 절에서는 설명을 아예 접는다. 사진만으로도 무엇인지 알아보고,
     자세히 보려면 ⤢가 있다 — 글 옆이 비는 것보다 낫다(2026-08-03 제보). */
  .cv-info.is-tight .info-text,
  .cv-info.is-tight .info-more { display: none; }
  .cv-info .info-src { font-size: 9px; }
  /* 절이 끝나면 띄움을 푼다 — 다음 절 제목이 사진 옆으로 파고들지 않게 */
  .cv-sec::after { content: ''; display: block; clear: both; }
  /* 확대 — 누르면 카드가 절 폭을 다 쓴다. 사진과 글을 크게 보고 싶을 때. */
  .cv-info.is-big { float: none; width: auto; max-width: none; margin: 10px 0; }
  .cv-info.is-big .info-img { max-height: 320px; }
  .cv-info.is-big .info-text { -webkit-line-clamp: none; font-size: 12.5px; }
}
/*
 * ── 회차 시간 띠 (2026-08-03 요청) ──────────────────────────
 * 연대표가 지도 폭만큼 짧아지면 721항목·5트랙은 라벨이 전부 잘린다.
 * 이 회차의 지점만 시간순 점으로 찍고 지금 읽는 곳을 크게 표시한다 —
 * 포기할 것을 포기해야 남는 것이 읽힌다.
 */
.cv-strip-tl { padding: 10px 16px 8px; border-bottom: 1px solid var(--line); }
.cv-strip-line {
  position: relative; height: 18px;
  /* 가운데 가로줄 — 점들이 이 위에 앉는다 */
  background: linear-gradient(var(--line), var(--line)) center / 100% 1px no-repeat;
}
.cv-strip-dot {
  position: absolute; top: 50%;
  width: 9px; height: 9px; padding: 0;
  transform: translate(-50%, -50%);
  border-radius: 50%; cursor: pointer;
  background: color-mix(in srgb, var(--accent) 45%, var(--bg));
  border: 1px solid color-mix(in srgb, var(--accent) 60%, transparent);
  transition: transform 0.15s ease, background 0.15s ease;
}
.cv-strip-dot:hover { transform: translate(-50%, -50%) scale(1.35); }
.cv-strip-dot:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* 지금 읽는 지점 — 이 띠가 답하는 유일한 질문이다 */
.cv-strip-dot.is-on {
  width: 15px; height: 15px;
  background: var(--accent); border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
.cv-strip-ends {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-top: 5px; font-size: 10.5px; color: var(--ink-dim);
}
.cv-strip-now {
  flex: 1; text-align: center; font-weight: 600;
  color: var(--accent); font-size: 11px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding: 0 8px;
}

.cv-zoom {
  position: absolute; right: 6px; top: 6px; z-index: 2;
  width: 26px; height: 26px; line-height: 1;
  font-size: 13px; color: var(--ink);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  border: 1px solid var(--line); border-radius: 6px;
  cursor: pointer; display: none;
}
@media (min-width: 621px) { .cv-zoom { display: block; } }
.cv-zoom:hover { border-color: var(--accent); }
.cv-info { position: relative; }

/* ── 카탈로그 — 고르는 화면 ─────────────────────────
   제목만 줄줄이 세운 표는 '제작 현황판'으로 읽힌다. 고르려면 무엇에 관한
   글인지(한 줄), 어떤 느낌인지(사진·색), 지금 읽을 수 있는지가 보여야 한다. */
.cv-catalog { flex: 1; overflow-y: auto; padding: 16px 16px 28px; }
.cv-cat-h { margin: 0 0 4px; font-size: 20px; letter-spacing: -0.01em; color: var(--ink); }
.cv-cat-guide { margin: 0 0 18px; font-size: 12.5px; line-height: 1.55; color: var(--ink-dim); }

/* 한 줄에 여러 개를 늘어놓는다 — 한 줄에 하나면 넓은 화면에서 폭이 남고,
   훑어보려면 자꾸 굴려 내려야 한다.
   **칸 수를 화면 폭마다 못박지 않는다.** auto-fill이 남는 폭을 보고 알아서
   접는다 — 폰 2개, 태블릿 3개, 넓은 화면 4개가 저절로 나온다.
   좁은 칸에서 카드가 어떻게 줄어드는지는 아래 @container 규칙에 있다. */
/* **칸 수를 직접 정한다.** auto-fill에 맡겼더니 1440px에서 7칸이 되고 표지가
   132px로 줄어 사진을 키운 뜻이 사라졌다. 남는 폭은 칸을 늘리는 데 쓰지 않고
   칸 하나를 넓히는 데 쓴다 — 사진이 커야 무엇을 찍었는지 알아본다. */
.cv-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* stretch — 한 줄의 카드가 같은 높이로 선다. start로 두면 소개 한 줄이
     두 줄이 된 카드만 길어져 아래 끝이 어긋난다(2026-08-03 제보). */
  align-items: stretch;
}
.cv-card { display: flex; flex-direction: column; }
.cv-card-body { flex: 1; display: flex; flex-direction: column; }
/* 편 수는 늘 카드 맨 아래에 붙는다 — 소개 줄 수가 달라도 밑선이 맞는다 */
.cv-count { margin-top: auto; }
@media (min-width: 700px)  { .cv-grid { gap: 16px; grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .cv-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* 카드 하나 = 시리즈 하나. 표지가 위, 본문이 아래로 쌓인다 — 옆에 붙은
   96px 조각은 무엇을 찍은 사진인지 알아보기 어려웠다. */
.cv-card {
  --tone: var(--accent);
  margin: 0; padding: 0;
  background: var(--bg);
  border: 1px solid var(--line); border-radius: 14px;
  overflow: hidden;
}
/* 표지 — 카드 폭을 꽉 채우는 띠. 사진이 오면 덮이고, 없으면 색과 기호가
   그대로 표지가 된다. 높이는 칸 폭을 따라간다 — min-height를 두었더니 좁은
   칸에서 그 값에 눌려 어느 폭에서나 132px로 납작해졌다(2026-08-03). */
.cv-cover {
  position: relative;
  /* max-height를 두면 좁은 칸에서 상자가 4:3보다 납작해져 세로로 긴 사진이
     위아래로 잘렸다(2026-08-03 제보: 샤르트르 첨탑이 날아감). 비율만 고정하고
     높이는 폭을 따라가게 둔다. */
  aspect-ratio: 4 / 3;
  background:
    radial-gradient(120% 90% at 20% 0%, color-mix(in srgb, #fff 26%, transparent), transparent 60%),
    linear-gradient(150deg,
      color-mix(in srgb, var(--tone) 92%, transparent),
      color-mix(in srgb, var(--tone) 52%, transparent));
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.cv-cover-ini {
  font-size: 58px; font-weight: 700; line-height: 1;
  color: color-mix(in srgb, #fff 88%, transparent);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.28);
}
.cv-cover-img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity 0.35s ease;
}
.cv-cover.has-img .cv-cover-img { opacity: 1; }
/* 세로로 긴 사진은 잘라 담지 않고 통째로 보여 준다 — 남는 자리는 시리즈 색 */
.cv-cover.is-tall .cv-cover-img { object-fit: contain; }
/* 사진이 오면 기호는 물러난다 — 지우지 않고 옅게 남겨 사진 위 장식이 된다 */
.cv-cover.has-img .cv-cover-ini { opacity: 0.16; }

/* 제목을 사진 위에 얹는다. 사진이 밝아도 읽히도록 아래쪽에 어두운 층을 깐다. */
.cv-cover-cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  /* 사진 <img>는 이 자막보다 **나중에** 붙는다(불러온 뒤 덧댄다). 둘 다 자리를
     잡은 요소라 그대로 두면 사진이 자막을 덮는다 — 층을 올려 못 덮게 한다. */
  z-index: 1;
  padding: 22px 14px 11px;
  background: linear-gradient(to top,
    rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0.38) 52%, transparent);
}
.cv-field {
  display: block; font-size: 11px; font-weight: 700;
  color: rgba(255, 255, 255, 0.82); letter-spacing: 0.06em;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
.cv-card-h {
  margin: 2px 0 0; font-size: 18px; font-weight: 700;
  color: #fff; line-height: 1.3; letter-spacing: -0.01em;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.55);
}

.cv-card-body { padding: 12px 14px 10px; }
.cv-hook { margin: 0 0 10px; font-size: 13px; line-height: 1.6; color: var(--ink-dim); }

/* 시리즈 카드 아래 한 줄 — 회차 제목을 늘어놓는 대신 몇 편인지만 말한다 */
.cv-count { margin: 0; font-size: 12px; font-weight: 600; color: var(--tone); }

/* 눌러서 시리즈로 들어가는 카드 */
.cv-card.is-open { cursor: pointer; transition: border-color 0.15s, transform 0.15s; }
.cv-card.is-open:hover { border-color: var(--tone); transform: translateY(-2px); }
.cv-card.is-open:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* 읽을 것이 없는 시리즈 — 눌러도 '데이터 필요'만 나오므로 잠근다.
   지우지 않는 이유는 무엇을 만들 계획인지가 그 자체로 정보이기 때문이다. */
/* 흐리게는 하되 **무엇을 찍은 사진인지는 남긴다**. 0.55 + grayscale 0.65는
   일곱 장을 한 덩어리로 만들어, 목록 아래쪽이 주제 없는 회색 띠로 보였다
   (2026-08-05 제보: 이미지들이 비슷한 느낌이다). 잠긴 표시는 글자 쪽이
   맡고 사진은 색을 지킨다. */
.cv-card.is-locked { opacity: 0.82; }
.cv-card.is-locked .cv-cover-img { filter: grayscale(0.25) saturate(0.9); }
.cv-card.is-locked .cv-count { color: var(--ink-dim); font-weight: 500; }

/* ── 2단: 시리즈 안의 회차 목록 ─────────────────────────── */
.cv-series-field {
  display: block; font-size: 11px; font-weight: 700;
  color: var(--tone); letter-spacing: 0.06em; margin: 0 0 2px;
}
/*
 * 회차를 한 줄씩 세우면 넓은 화면에서 폭이 통째로 빈다 — 1440px에서 제목과
 * '읽기'가 1000px 넘게 떨어져 한 줄로 안 읽혔다(2026-08-03 요청).
 * 1단과 같은 격자에 담고, 칸 안에서 사진 위·글 아래로 쌓는다.
 */
.cv-series .cv-eps {
  margin-top: 18px;
  display: grid; gap: 16px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 1100px) { .cv-series .cv-eps { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.cv-series .cv-ep {
  border-top: none;
  border: 1px solid var(--line); border-radius: 12px;
  overflow: hidden; background: var(--bg);
}
.cv-series .cv-ep-row {
  display: block; padding: 0; min-height: 0;
  width: 100%; text-align: left;
}
/* 아래 여백은 뒤에 오는 것(상태 알약·사유 메모)이 만들어 준다. 그런데 읽을
   수 있는 회차는 둘 다 없어서 제목이 카드 밑변에 붙었다 — 술의 역사처럼 세
   편이 모두 공개된 시리즈에서는 세 칸이 전부 그랬다(2026-08-05 제보).
   제목 자신이 아래 여백을 갖고, 뒤에 무엇이 오면 그때 걷는다. */
/* 아래 여백은 상태 알약이 만들어 준다. 그런데 다 된 회차에는 알약이 없어
   ('준비 중'만 표시한다 — 2026-08-05) 제목이 카드 밑변에 붙는다.
   :last-child로는 못 잡는다: 뒤에 빈 .cv-ep-gap이 늘 따라온다(격자에서는
   display:none이지만 DOM 형제로는 남는다). 알약이 붙는 칸만 여백을 걷는다. */
.cv-series .cv-ep-title {
  display: block; padding: 11px 13px;
  font-size: 15px; line-height: 1.35;
}
.cv-series .cv-ep:not(.is-live) .cv-ep-title { padding-bottom: 0; }
.cv-series .cv-ep-gap { display: none; }   /* 격자에서는 밀어낼 것이 없다 */
.cv-series .cv-ep-tag { display: inline-block; margin: 7px 13px 11px; }
/* 읽을 수 있는 칸은 카드째 과녁 — 넓은 화면에서 누르기 쉽다 */
.cv-series button.cv-ep-row:hover { border-color: var(--tone); }
.cv-series .cv-ep.is-live { border-color: color-mix(in srgb, var(--tone) 45%, var(--line)); }

/* 회차 줄의 작은 사진. 1단은 사진으로 고르는데 2단만 글줄이면 두 단이 서로
   다른 물건처럼 보인다 — 다만 여기서는 제목을 훑는 것이 먼저라 표지처럼
   크게 깔지 않는다. 사진이 없으면 시리즈 색이 그대로 남는다. */
.cv-ep-thumb {
  /* 64×48은 너무 작아 화면이 비어 보였다(2026-08-03 요청). 격자 칸에서는
     칸 폭을 다 쓴다 — 사진이 커야 무엇을 찍었는지 알아본다. */
  width: 100%; aspect-ratio: 16 / 10;
  border-radius: 0; overflow: hidden; position: relative;
  background: linear-gradient(150deg,
    color-mix(in srgb, var(--tone) 55%, transparent),
    color-mix(in srgb, var(--tone) 22%, transparent));
}
.cv-ep-thumb img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity 0.3s ease;
}
.cv-ep-thumb.has-img img { opacity: 1; }
/* 아직 못 만드는 회차는 사진도 물러난다 — 읽을 수 있는 줄이 먼저 보여야 한다 */
.cv-ep:not(.is-live) .cv-ep-thumb { opacity: 0.6; }
.cv-ep:not(.is-live) .cv-ep-thumb img { filter: grayscale(0.5); }
/* 사유 메모는 사진 폭만큼 들여 제목 줄과 맞춘다 (사진 폭 + gap 14px) */
.cv-series .cv-ep-note { padding: 0 13px 11px; }

.cv-eps { list-style: none; margin: 0; padding: 0; }
.cv-ep { border-top: 1px dashed var(--line); }
.cv-ep:first-child { border-top: none; }
/* 읽을 수 있는 글은 줄 전체가 과녁 — 제목 글자만 누르게 하면 폰에서 어렵다 */
.cv-ep-row {
  display: flex; align-items: center; gap: 8px; width: 100%;
  font: inherit; text-align: left;
  background: transparent; border: none;
  padding: 8px 0; min-height: 40px;
}
button.cv-ep-row { cursor: pointer; }
button.cv-ep-row:hover .cv-ep-title { color: var(--tone); }
button.cv-ep-row:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
.cv-ep-title { flex: 1; min-width: 0; font-size: 13px; color: var(--ink-dim); line-height: 1.4; }
.cv-ep.is-live .cv-ep-title { color: var(--ink); font-weight: 600; }
.cv-ep-tag {
  flex: none; font-size: 10px; white-space: nowrap;
  border: 1px solid var(--line); border-radius: 999px;
  padding: 2px 8px; color: var(--ink-dim);
}
.cv-ep.is-live .cv-ep-tag {
  background: var(--tone); border-color: var(--tone);
  color: #fff; font-weight: 700;
}
/* 왜 아직 못 만드는지 — 고르는 데는 방해라 작게 둔다 */
.cv-ep-note {
  display: block; font-size: 11px; line-height: 1.45;
  color: color-mix(in srgb, var(--ink) 42%, transparent);
  padding: 0 0 8px;
}

/* 좁은 칸(폰 2단)에서는 카드를 줄인다. 같은 내용을 그대로 욱여넣으면
   "증류 기술의 세계 / 확산", "1200~1500 / 년 세계 건축"처럼 말이 끊긴다.
   컨테이너 질의라 화면이 아니라 **칸 폭**을 본다 — 폰이든 좁은 패널이든
   같은 규칙이 걸린다. */
.cv-card { container-type: inline-size; }
@container (max-width: 230px) {
  .cv-card-h { font-size: 15px; line-height: 1.28; }
  .cv-field { font-size: 10px; letter-spacing: 0.04em; }
  .cv-cover-cap { padding: 18px 10px 8px; }
  .cv-card-body { padding: 10px 10px 8px; }
  /* 소개 한 줄은 **남긴다.** 회차 목록이 2단으로 빠진 뒤로는 이 줄이 카드에
     남은 유일한 설명이라, 접으면 제목만 덩그러니 남는다(2026-08-03).
     대신 석 줄에서 끊어 카드 높이가 들쭉날쭉해지지 않게 한다. */
  .cv-hook {
    font-size: 12px; line-height: 1.5;
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .cv-count { font-size: 11px; }
  .cv-ep-note { display: none; }
  .cv-ep-title { font-size: 12px; }
  .cv-ep-row { gap: 5px; padding: 7px 0; min-height: 36px; }
  .cv-ep-tag { font-size: 9px; padding: 2px 6px; }
}

/* 모바일 전환 버튼 — 넓은 화면에서는 필요 없다(둘이 함께 보인다) */
.cv-switch { display: none; }
/* 지도 보기 조종 줄도 폰 전용 — 넓은 화면은 본문과 지도가 함께 보여 필요 없다 */
.cv-mapnav { display: none; }
/* 목차 펴기 단추도 폰 전용 — 넓은 화면에서는 목차가 접히지 않으니 누를 것이 없다 */
.cv-toc-toggle { display: none; }

@media (max-width: 620px) {
  /* 폰에서는 좌우로 좁게 나누지 않는다. 전체 폭을 쓰고 명시적 버튼으로 오간다
     (2026-08-02 §5: "모바일의 명시적 본문 보기·지도 보기 전환").

     **레일 아래에서 시작한다.** 폰에서 레일은 세로 기둥이 아니라 네비 바로
     아래의 가로 바이고, 설정·검색·지도유형 버튼이 거기 있다. 회차를 네비
     바로 아래(--nav-h)부터 깔면 그 버튼들을 통째로 덮어 **설정을 열 수 없다**
     (2026-08-02 실측: rail-settings가 y=58에 그대로 있는데 .cv-bar가 위를
     덮어 hit-test에서 잡히지 않았다). 연대표 전체화면은 지도가 안 보이니
     감추는 것이 맞지만(위 body.tl-maxed), 회차는 지도를 옆에 두고 읽는
     화면이라 지도 조작 버튼이 살아 있어야 한다. */
  .content-view {
    width: 100%; border-left: none;
    /* 레일(설정·검색) 아래에서 시작하되, **지도가 실제로 보일 띠**를 남긴다.
       레일 아래 10px만 남겼더니 지도가 있으나 마나였다 — 항목을 골라도
       마커가 레일 뒤나 패널 뒤에 깔려 "지도가 안 보인다"가 됐다
       (2026-08-02 제보). 기본 88px이면 마커와 그 주변 지명이 한 줄 들어오고,
       그 뒤로는 **손잡이를 끌어 사용자가 정한다**(--cv-strip). */
    top: calc(var(--rail-drop) + var(--mbtn) + var(--cv-strip));
  }
  /* 폰에서는 위아래로 나뉘므로 손잡이도 가로 띠가 된다 */
  .cv-resize {
    top: -6px; bottom: auto; left: 0; right: 0;
    width: auto; height: 14px; cursor: ns-resize;
  }
  .cv-grip { flex-direction: column; padding: 2.5px 15px; }
  .cv-grip i { width: 26px; height: 1.5px; }
  body.cv-rz { cursor: ns-resize; }
  /* 지도 보기에서는 패널이 사라지므로 손잡이도 숨긴다 */
  body.content-map .cv-resize { display: none; }
  /* 읽을 자리를 늘린다. 폰 844px에서 머리·목차·바가 294px을 먹어 본문에
     342px(화면의 41%)밖에 안 남았다 — 두 문단이면 끝이라 계속 스크롤해야
     했다 (2026-08-02 실측). 회차 제목은 이미 카탈로그에서 보고 들어온
     것이므로 여기서 크게 반복할 이유가 없다. */
  .cv-bar { padding: 5px 12px; }
  .cv-back, .cv-close { padding: 5px 10px; min-height: 30px; font-size: 13px; }
  .cv-head { padding: 8px 14px 2px; }
  .cv-title { font-size: 16px; margin-bottom: 3px; }
  .cv-q { font-size: 12px; }
  .cv-body { padding: 4px 14px 16px; }
  .cv-sec { padding: 10px; margin: 5px 0; }

  /* 목차는 접어 둔다. 다섯 줄이 155px을 차지했는데, 그중 넷은 지금 읽지 않을
     절이다. details로 두어 필요한 사람만 편다 — 없애지 않는 이유는 목차가
     '이 글이 어디로 가는지'를 보여 주는 유일한 자리이기 때문이다. */
  .cv-toc {
    display: block; padding: 6px 14px;
    max-height: 34px; overflow: hidden;
    position: relative;
  }
  .cv-toc.is-open { max-height: none; }
  .cv-toc-b { font-size: 11px; padding: 4px 8px; margin: 0 4px 4px 0; }
  .cv-toc-toggle {
    display: block;
    position: absolute; right: 10px; top: 4px;
    font: inherit; font-size: 11px; color: var(--ink-dim);
    background: var(--bg); border: 1px solid var(--line); border-radius: 999px;
    padding: 3px 9px; cursor: pointer; min-height: 26px;
  }

  /* 지도 보기 조종 줄 — 지금 어디를 보는지, 앞뒤로 어떻게 가는지.
     이것이 없을 때는 지도만 남아 지점을 옮기려면 본문으로 돌아가야 했다. */
  .cv-mapnav {
    display: none;
    flex: none; align-items: center; gap: 8px;
    margin: 0 12px 8px; padding: 6px 8px;
    background: var(--bg); border: 1px solid var(--line); border-radius: 999px;
    box-shadow: 0 2px 10px var(--sh);
  }
  body.content-map .cv-mapnav { display: flex; pointer-events: auto; }
  .cv-now {
    flex: 1; text-align: center; font-size: 13px; font-weight: 600;
    color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .cv-step {
    flex: none; width: 44px; height: 44px;   /* 터치 과녁 */
    font: inherit; font-size: 20px; line-height: 1;
    color: var(--ink); background: transparent;
    border: none; border-radius: 999px; cursor: pointer;
  }
  .cv-step:disabled { opacity: 0.3; cursor: default; }
  .cv-step:not(:disabled):hover { background: color-mix(in srgb, var(--accent) 14%, transparent); }

  .cv-switch {
    display: block; flex: none; width: calc(100% - 24px); margin: 0 12px 12px;
    font: inherit; font-size: 14px; font-weight: 600;
    color: var(--bg); background: var(--accent);
    border: none; border-radius: 8px; padding: 12px; cursor: pointer;
    min-height: 44px;              /* 터치 과녁 */
  }
  /* '지도 보기'를 누르면 본문을 접어 지도가 드러난다. 화면을 닫지는 않는다 —
     선택한 절과 항목이 그대로 남아야 돌아왔을 때 이어 읽을 수 있다. */
  body.content-map .cv-body,
  body.content-map .cv-toc,
  body.content-map .cv-head { display: none; }
  body.content-map .content-view {
    top: auto; bottom: var(--btm-h); height: auto;
    background: transparent; box-shadow: none; border: none; pointer-events: none;
  }
  body.content-map .cv-bar { display: none; }
  body.content-map .cv-switch { pointer-events: auto; }
}

/* ── 회차 경로 안내표 — 글 끝의 참고사항 ──────────────────────────────
   지도 위에 띄웠다가 옮겼다(2026-08-05 제보: 지도를 가린다). 추정임을 밝히는
   일은 급히 알릴 경고가 아니라 읽고 나서 확인할 참고사항이라, 글 맨 아래가
   제자리다. 지도는 지도대로 온전히 보이고 이 문장은 사라지지 않는다. */
.cv-note {
  margin: 26px 0 4px;
  padding: 10px 12px;
  font-size: 12.5px; line-height: 1.6;
  color: var(--ink-dim);
  background: color-mix(in srgb, var(--tone, #c2410c) 7%, transparent);
  border-left: 3px solid color-mix(in srgb, var(--tone, #c2410c) 55%, transparent);
  border-radius: 0 6px 6px 0;
}
.cv-note b { color: var(--ink); font-weight: 700; }
