/* assets/components.css — 모든 페이지 공유 UI 컴포넌트
   (이전엔 polls.css가 36 페이지에 박혀있었음 — 진짜 폴 카드 외 chrome은 여기로)

   포함:
   - 컨트롤: .controls · .seg · .seg-btn · .seg-wrap · .fade-{left,right}
   - 인트로/loading: .intro · .lede · .loading-overlay · .spin
   - 상태: .is-active · .is-selected · .has-data · .no-data
   - 디테일 패널: .detail-pane · .detail-empty · .detail-hdr
   - viz 레이아웃: .viz · .viz-main · .map-pane · .hex-pane · .view-toggle
   - 범례: .leg-item · .leg-dot · .poll-legend
   - 데이터 라벨: .name · .label · .count · .pct · .value · .latest-label
   - 시간/배너: .time-anchor · .legal-banner

   loading 순서: common.css → components.css → 페이지 전용 css
*/

/* 헤더·.page·푸터 chrome → common.css (전 페이지 공통) */

.intro {
  margin-bottom: 24px;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 16px;
  align-items: end;
}
.intro h1 {
  font-size: clamp(24px, 3.2vw, 38px);
  font-weight: 800;
  letter-spacing: -0.03em;
  margin: 0 0 6px;
  line-height: 1.1;
}
.intro .lede {
  color: var(--ink-soft);
  font-size: 14px;
  line-height: 1.6;
  margin: 0;
  max-width: 660px;
}
.legal-banner {
  grid-column: 1 / -1;
  margin-top: 14px;
  padding: 10px 14px;
  background: var(--ink);
  color: var(--bg);
  border-radius: 2px;
  font-size: 12px;
  display: flex;
  gap: 10px;
  align-items: baseline;
}
.legal-banner strong { font-weight: 700; }
.legal-banner span { opacity: 0.75; }

/* === 컨트롤 === */
.controls {
  display: flex;
  gap: 16px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 16px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--rule);
}
.seg {
  display: inline-flex;
}
/* 가로 스크롤 시 "더 있다" 페이드 — JS(setupSegFades)가 스크롤 위치로 클래스 토글 */
.seg.fade-right {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
          mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
}
.seg.fade-left {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 24px);
          mask-image: linear-gradient(to right, transparent, #000 24px);
}
.seg.fade-left.fade-right {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 24px, #000 calc(100% - 24px), transparent);
          mask-image: linear-gradient(to right, transparent, #000 24px, #000 calc(100% - 24px), transparent);
}
.seg-btn {
  padding: 6px 14px;
  background: transparent;
  border: 1px solid var(--rule-strong);
  border-right: none;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background .12s, color .12s;
}
.seg-btn:first-child { border-radius: 2px 0 0 3px; }
.seg-btn:last-child  { border-radius: 0 3px 3px 0; border-right: 1px solid var(--rule-strong); }
.seg-btn.is-active {
  background: var(--ink);
  color: var(--bg);
  border-color: var(--ink);
}
.seg-btn:hover:not(.is-active) {
  background: var(--bg2);
  color: var(--ink);
}
/* 인코딩 토글 (EncodingToggle) — 아이콘 + 두 가족(1위 | 표 비례) 한 바. */
.enc-toggle { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; justify-content: center; }
.enc-group { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.enc-fam { font-size: 9px; font-weight: 700; letter-spacing: 0.02em; color: var(--ink-mute, #8a93a3); line-height: 1; }
.enc-sep { align-self: stretch; width: 1px; background: var(--rule-strong); margin: 0 1px; }
.enc-toggle .seg-btn { display: inline-flex; align-items: center; gap: 4px; }
.enc-ic { flex-shrink: 0; }
.time-anchor {
  margin-left: auto;
  font-size: 12px;
  color: var(--ink-soft);
  display: flex;
  gap: 6px;
  align-items: baseline;
}
.time-anchor .label {  font-size: 11px; }
.time-anchor .value {
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* === 시각화 레이아웃 (flex) === */
.viz {
  display: flex;
  gap: 18px;
  position: relative;
  min-height: 600px;
}
.map-pane, .hex-pane {
  flex: 1 1 0;
  min-width: 0;
  height: 680px;
  background: var(--bg);
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  position: relative;
  display: block;
}
.map-pane { padding: 0; overflow: hidden; }
.hex-pane { padding: 16px; }

/* viz-main: hex/map pane들을 감싼 wrapper — view-toggle overlay 위치 기준 */
.viz-main {
  flex: 1 1 0;
  min-width: 0;
  position: relative;
}
.viz-main > .map-pane,
.viz-main > .hex-pane { flex: unset; width: 100%; }

/* view 토글 오버레이 — viz-main 우측 상단 (지도/격자 영역 안) */
.view-toggle {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 600;
  background: var(--bg);
  border: 1px solid var(--rule-strong);
}
.view-toggle .seg-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.view-toggle .seg-btn:not(.is-active) { background: var(--bg); }
.view-toggle .seg-btn svg { opacity: 0.85; }
.view-toggle .seg-btn.is-active svg { opacity: 1; }
.detail-pane { flex: 0 0 420px; }

/* 지리 코로플레스 (시도·시군구) — sidoMap/sigunguMap SVG. 폴·아카이브 공용(이전 archive.css). */
/* geo 코로플레스는 hex(.governor-hex-svg·.district-hex-svg, 무제한 채움)와 같은 토글에서 비교되므로
   max-width 캡을 두면 geo만 작아 보임 → 캡 제거해 컨테이너를 동일하게 채움. */
.sido-map-svg, .sigungu-map-svg { width: 100%; height: auto; display: block; margin: 0 auto; }
.sido-map-region { stroke: var(--bg); stroke-width: 0.8; }
.sido-map-region.no-data { fill: var(--bg2); stroke: var(--rule-strong); }
.sigungu-map-region { stroke: var(--bg); stroke-width: 0.4; }
.sigungu-map-region.no-data { fill: var(--bg2); stroke: var(--rule); stroke-width: 0.3; }
.sigungu-map-region.is-selected { stroke: var(--ink); stroke-width: 1.4; paint-order: stroke; }
.district-map-svg { width: 100%; height: auto; display: block; margin: 0 auto; }
.district-hex-svg { width: 100%; height: auto; display: block; }
.district-map-region { stroke: var(--bg); stroke-width: 0.4; }
.district-map-region.no-data { fill: var(--bg2); stroke: var(--rule); stroke-width: 0.3; }
.district-map-region.is-selected { stroke: var(--ink); stroke-width: 1.4; paint-order: stroke; }

.loading-overlay {
  position: absolute; inset: 0;
  background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  z-index: 500;
  font-size: 13px; color: var(--ink-soft);
}
.spin {
  display: inline-block;
  width: 12px; height: 12px;
  margin-right: 10px;
  border: 2px solid var(--ink-soft);
  border-top-color: transparent;
  border-radius: 50%;
  animation: spin .9s linear infinite;
}

/* === 디테일 패널 === */
.detail-pane {
  background: var(--bg);
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
  height: 680px;
  overflow-y: auto;
  padding: 18px 20px 24px;
}
.detail-empty {
  color: var(--ink-mute);
  font-size: 13px;
  line-height: 1.6;
  padding: 24px 8px;
}
.detail-hdr {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 6px;
  padding-bottom: 10px;
  border-bottom: 2px solid var(--ink);
}
.detail-hdr h2 {
  font-size: 22px;
  font-weight: 800;
  margin: 0;
  letter-spacing: -0.02em;
}
.detail-hdr .count {
  font-size: 12px;
  color: var(--ink-mute);
  
}

.latest-label {
  font-size: 11px;
  color: var(--ink-mute);
  
  margin: 14px 0 8px;
}
.poll-card .pc-bar-row .name {
  color: var(--ink);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.poll-card .pc-bar-row .pct {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

/* === Hex grid === */
.hex-pane .hex-cell {
  cursor: pointer;
  transition: opacity .12s;
}
.hex-pane .hex-cell:hover { opacity: 0.85; }
/* 선택 셀 — 흰 테두리 + 글로우 halo. 권역(시도) 다크 경계선과 헷갈리지 않게 확연히 구분. */
.hex-pane .hex-cell.is-selected {
  stroke: var(--bg);
  stroke-width: 4;
  paint-order: stroke;
  filter: drop-shadow(0 0 2px #0a0e1a) drop-shadow(0 0 6px rgba(0, 0, 0, 0.6));
}
/* geo(지도) 선택 폴리곤 — 흰 테두리(setStyle) + 글로우. Leaflet path에 직접 클래스 부여. */
.geo-sel {
  paint-order: stroke;
  filter: drop-shadow(0 0 2px #0a0e1a) drop-shadow(0 0 5px rgba(0, 0, 0, 0.55));
}
.hex-pane .hex-cell.no-data {
  fill: var(--bg2);
  stroke: var(--rule-strong);
  stroke-width: 1;
  cursor: default;
}
.hex-pane .hex-label {
  font-size: 13px;
  font-weight: 700;
  fill: var(--ink);
  text-anchor: middle;
  pointer-events: none;
  letter-spacing: -0.01em;
}
.hex-pane .hex-pct {
  font-size: 11px;
  font-weight: 600;
  fill: var(--ink);
  text-anchor: middle;
  pointer-events: none;
  font-variant-numeric: tabular-nums;
}
.hex-pane .hex-cell.has-data + .hex-label,
.hex-pane .hex-cell.has-data + .hex-label + .hex-pct { fill: var(--bg); }

/* 시도 1위색 hex (Archive.governorHex) — 폴·아카이브 공용 캐논. 폴은 archive.css 미로드라 공용 components.css에. */
.governor-hex-svg { width: 100%; height: auto; }
.gov-hex-cell { stroke: var(--bg); stroke-width: 1.5; }
.gov-hex-cell.no-data { fill: var(--bg2); stroke: var(--rule-strong); }
.gov-hex-cell.is-selected { stroke: var(--ink); stroke-width: 2.4; }
.gov-hex-cell:hover { opacity: 0.9; }
.gov-hex-label { text-anchor: middle; pointer-events: none; }
.gov-hex-label.on-data { fill: var(--bg); }
.gov-hex-label.no-data { fill: var(--ink-soft); }
.gov-hex-name { fill: var(--bg); text-anchor: middle; pointer-events: none; }
.gov-hex-pct { fill: var(--bg); opacity: 0.85; text-anchor: middle; pointer-events: none; }

/* 선거별 렌즈 전환 바 — 같은 선거의 3가지 보기(종합/여론조사vs실제/역대 흐름) 사이 이동. 전 페이지 공용. */
.lens-switcher { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 10px 0 4px; }
.lens-label { font-size: 12px; font-weight: 700; color: var(--ink-mute); margin-right: 2px; }
.lens-chip {
  font-size: 12.5px; font-weight: 600; line-height: 1; padding: 6px 11px;
  border: 1px solid var(--rule-strong); border-radius: 999px;
  color: var(--ink-soft); background: var(--bg2); text-decoration: none; white-space: nowrap;
  transition: background .12s, color .12s, border-color .12s;
}
.lens-chip:hover { color: var(--ink); border-color: var(--ink-soft); background: var(--bg3); }
.lens-chip.is-current { background: var(--ink); color: var(--bg); border-color: var(--ink); cursor: default; }
/* 선거별 디렉터리 3레인 타임라인(.poll-tl-*/.ptc-*) 스타일은 common.css — 대시보드 포함 전 페이지 공용. */

/* === 색 범례 (지도/격자 아래) === */
.poll-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;   /* 당 항목 간 간격 넉넉히 — 한 줄에 몰리면 당명끼리 붙어 보임 */
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--rule);
  font-size: 12.5px;
  color: var(--ink-soft);
}
.poll-legend .leg-item { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; padding-right: 2px; }
.poll-legend .leg-dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }

/* === 정보 아이콘 + 팝오버 ===
   깨알 설명문을 본문에 깔아두지 말고 'i' 눌러서 보게. JS 없이 hover/focus(-within)로.
   .info-i(트리거) > .info-pop(설명) 구조. 데스크톱=아이콘 아래, 모바일=하단 시트. */
.info-i {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 17px; height: 17px; margin-left: 7px;
  border-radius: 50%; border: 1.5px solid var(--ink-mute);
  color: var(--ink-mute);
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 11px; line-height: 1; font-weight: 700; font-style: italic;
  cursor: help; flex: 0 0 auto; vertical-align: middle; user-select: none;
  transition: color .12s, border-color .12s;
}
.info-i:hover, .info-i:focus, .info-i:focus-visible { color: var(--ink); border-color: var(--ink); }
.info-i:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }   /* 키보드 포커스 — hover와 구분되는 또렷한 표시 */
.info-pop {
  display: none;
  position: absolute; top: calc(100% + 9px); left: 0;
  width: min(360px, 78vw); z-index: 30;
  background: var(--bg); border: 1px solid var(--rule-strong); border-radius: 8px;
  padding: 11px 13px; box-shadow: 0 8px 28px var(--shadow);
  font-size: 13px; line-height: 1.6; font-weight: 400; font-style: normal;
  color: var(--ink-soft); text-align: left; white-space: normal; letter-spacing: normal;
}
.info-pop b { color: var(--ink); font-weight: 700; }
.info-pop::before {
  content: ''; position: absolute; bottom: 100%; left: 5px;
  border: 6px solid transparent; border-bottom-color: var(--rule-strong);
}
/* 데스크톱 hover/focus(CSS) + 클릭/터치 토글(nav.js가 .is-open 부여) 둘 다 지원 */
.info-i:hover .info-pop, .info-i:focus .info-pop, .info-i:focus-within .info-pop,
.info-i.is-open .info-pop { display: block; }
@media (max-width: 640px) {
  /* 모바일 — 화면 하단 시트로 고정(아이콘 위치와 무관, 가로 넘침 방지). 바깥 탭·Esc로 닫힘(nav.js). */
  .info-pop { position: fixed; left: 12px; right: 12px; bottom: 14px; top: auto; width: auto; }
  .info-pop::before { display: none; }
  /* 모바일 hover는 없고 :focus-within이 터치서 불안정 → .is-open(JS)일 때만 표시 */
  .info-i:hover .info-pop, .info-i:focus .info-pop, .info-i:focus-within .info-pop { display: none; }
  .info-i.is-open .info-pop { display: block; }
}
@media (max-width: 900px) {
  /* 헤더·.page 반응형 chrome → common.css */
  /* 인트로 */
  .intro { grid-template-columns: 1fr; gap: 8px; }
  .intro h1 { font-size: clamp(20px, 6vw, 28px); }
  .intro .lede { font-size: 13px; }

  /* 컨트롤 segmented — 가로 스크롤 (한 줄 유지) */
  .controls { gap: 10px; }
  .seg {
    overflow-x: auto;
    max-width: 100%;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .seg::-webkit-scrollbar { display: none; }
  .seg-btn { flex-shrink: 0; padding: 6px 10px; font-size: 12px; }
  .time-anchor { margin-left: 0; font-size: 11px; }

  /* viz — column layout (hex/map 위, detail 아래) */
  .viz {
    flex-direction: column;
    min-height: 0;
    gap: 14px;
  }
  .map-pane, .hex-pane {
    width: 100%;
    height: auto;
    aspect-ratio: 1 / 1.05;
    min-height: 360px;
    max-height: 70vh;
  }
  .map-pane { padding: 0; }
  .hex-pane { padding: 8px; }
  .detail-pane {
    flex: none;
    width: 100%;
    height: auto;
    max-height: none;
    padding: 14px 16px 20px;
  }

}
@media (max-width: 480px) {
  .map-pane, .hex-pane { aspect-ratio: 1 / 1.15; min-height: 320px; }
}
.byelection-viz .detail-pane { max-height: 600px; overflow-y: auto; }
.seg-wrap { flex-wrap: wrap; gap: 6px; }

.scatter-wrap {
  border-top: 1px solid var(--rule);
  padding: 8px 0;
  margin: 14px 0 4px;
}
.scatter-wrap svg { display: block; }

@keyframes spin { to { transform: rotate(360deg); } }

/* === Hex outline (시군구·시도 cluster footprint) — 테마 인지 ===
   light: 기존 흰 반투명 유지 (디자인 자료에서 부드러운 footprint).
   dark: 흰 반투명을 10~15%로 약하게 (데이터 hex 강조). */
.sig-outline {
  fill: rgba(255,255,255,0.35);
  stroke: rgba(27,34,55,0.45);
  stroke-width: 1.0;
}
.sig-outline.is-selected {
  fill: rgba(255,255,255,0.7);
  stroke: #0a0e1a;
  stroke-width: 3.5;
}
/* 권역(시도) 굵은 경계선 — 카토그램/시군구 hex 공용(종합·폴·역대). 폴은 archive.css 미로드라 여기로. */
.sido-border { stroke: var(--ink, #0a0e1a); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; stroke-opacity: 0.92; pointer-events: none; }
/* 권역 호버 라이트 강조 — 호버한 칸의 시도만 부각(테두리 진하게 + 셀 살짝 또렷), 나머지 dim 없음. */
.sido-border.sido-hot { stroke-width: 4.6; stroke-opacity: 1; transition: stroke-width .08s; }
.sido-hull { fill: rgba(128,128,128,0.05); stroke: var(--ink-mute, rgba(10,14,26,0.45)); stroke-width: 1.5; }
.sido-hull.sido-hot { stroke: var(--ink, #0a0e1a); stroke-opacity: 0.85; stroke-width: 2.6; fill-opacity: 0.6; }
.hex-cell.sido-hot, g.sido-hot { filter: saturate(1.22) brightness(1.04); }
/* 구 영역 경계선 (격자 — 옛 회차 병합 구 윤곽). sig-outline stroke와 같은 테마 색. */
.gu-outline { stroke: rgba(27,34,55,0.45); fill: none; stroke-linecap: round; }
.gu-outline.is-selected { stroke: #0a0e1a; }
/* 시군구 카토그램 라벨 — 공용(역대/종합/폴). 테마 토큰이라 다크 자동. (이전 history.css→이동) */
.hist-sido-bg-label { fill: var(--ink); opacity: 0.35; }
.hist-sido-edge-label { fill: var(--ink); opacity: 0.55; stroke: var(--bg); stroke-width: 2.5; paint-order: stroke fill; }
.hist-sigungu-label { fill: var(--ink); stroke: var(--bg); stroke-width: 1.6; paint-order: stroke fill; }
.metro-outline {
  fill: rgba(255,255,255,0.45);
  stroke: rgba(27,34,55,0.45);
  stroke-width: 1.2;
}
.council-outline {
  fill: rgba(255,255,255,0.4);
  stroke: rgba(27,34,55,0.35);
  stroke-width: 0.8;
}
.council-outline.no-data {
  fill: rgba(220,224,232,0.5);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .sig-outline {
    fill: rgba(255,255,255,0.10);
    stroke: rgba(255,255,255,0.18);
  }
  :root:not([data-theme="light"]) .sig-outline.is-selected {
    fill: rgba(255,255,255,0.25);
    stroke: var(--ink);
  }
  :root:not([data-theme="light"]) .gu-outline { stroke: rgba(255,255,255,0.20); }
  :root:not([data-theme="light"]) .gu-outline.is-selected { stroke: var(--ink); }
  :root:not([data-theme="light"]) .metro-outline {
    fill: rgba(255,255,255,0.10);
    stroke: rgba(255,255,255,0.18);
  }
  :root:not([data-theme="light"]) .council-outline {
    fill: rgba(255,255,255,0.10);
    stroke: rgba(255,255,255,0.15);
  }
  :root:not([data-theme="light"]) .council-outline.no-data {
    fill: rgba(255,255,255,0.06);
  }
}
[data-theme="dark"] .sig-outline {
  fill: rgba(255,255,255,0.10);
  stroke: rgba(255,255,255,0.18);
}
[data-theme="dark"] .sig-outline.is-selected {
  fill: rgba(255,255,255,0.25);
  stroke: var(--ink);
}
[data-theme="dark"] .gu-outline { stroke: rgba(255,255,255,0.20); }
[data-theme="dark"] .gu-outline.is-selected { stroke: var(--ink); }
[data-theme="dark"] .metro-outline {
  fill: rgba(255,255,255,0.10);
  stroke: rgba(255,255,255,0.18);
}
[data-theme="dark"] .council-outline {
  fill: rgba(255,255,255,0.10);
  stroke: rgba(255,255,255,0.15);
}
[data-theme="dark"] .council-outline.no-data {
  fill: rgba(255,255,255,0.06);
}
