:root {
  color-scheme: light dark;
  --bg: #ffffff;
  --fg: #1a1a1a;
  --muted: #6b7280;
  --border: #e5e7eb;
  --accent: #2563eb;
  --accent-fg: #ffffff;
  --surface: #f9fafb;
  --radius: 8px;
  --page-gutter: 0.5rem;
}

/* 기존 좌우 여백을 화면 크기별로 절반으로 줄인다. */
@media (min-width: 640px) {
  :root {
    --page-gutter: 1.25rem;
  }
}

@media (min-width: 900px) {
  :root {
    --page-gutter: 3rem;
  }
}

@media (min-width: 1280px) {
  :root {
    --page-gutter: 4.5rem;
  }
}

@media (min-width: 1600px) {
  :root {
    --page-gutter: 6rem;
  }
}

/* 다크 모드 팔레트. 기본 신호는 OS 설정(prefers-color-scheme)이고, 사용자가 헤더 토글로
   고르면 <html data-theme>가 그 위를 덮는다(2026-08-05). 두 방향 모두 덮어야 하므로
   light/dark 오버라이드를 각각 둔다 — data-theme="light"가 없으면 OS가 다크인 사용자는
   라이트를 선택해도 다크로 돌아간다. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f1115;
    --fg: #e5e7eb;
    --muted: #9ca3af;
    --border: #2a2e37;
    --accent: #60a5fa;
    --accent-fg: #0f1115;
    --surface: #171a21;
  }
}

:root[data-theme='dark'] {
  color-scheme: dark;
  --bg: #0f1115;
  --fg: #e5e7eb;
  --muted: #9ca3af;
  --border: #2a2e37;
  --accent: #60a5fa;
  --accent-fg: #0f1115;
  --surface: #171a21;
}

:root[data-theme='light'] {
  color-scheme: light;
  --bg: #ffffff;
  --fg: #1a1a1a;
  --muted: #6b7280;
  --border: #e5e7eb;
  --accent: #2563eb;
  --accent-fg: #ffffff;
  --surface: #f9fafb;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  font-family:
    -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
    'Apple SD Gothic Neo', 'Malgun Gothic', sans-serif;
  background: var(--bg);
  color: var(--fg);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--accent);
}

.container {
  max-width: none;
  margin: 0 auto;
  padding: 1rem var(--page-gutter);
}

/* 시각적으로는 숨기되 스크린리더에는 남긴다(접근성 전용 헤딩 등에 사용). */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* 본문 바로가기(2026-08-15 추가): 헤더의 시도 링크(17개)·언어/테마 스위치·검색창을 매번
   다 거치지 않고 본문으로 뛸 수 있게 한다. 평소엔 화면 밖에 있다가 키보드 포커스가 오면
   나타난다 — 마우스 사용자에게는 아무 영향이 없다. */
.skip-link {
  position: absolute;
  top: -3rem;
  left: 0.5rem;
  z-index: 100;
  padding: 0.6rem 1rem;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--accent-fg);
  text-decoration: none;
}

.skip-link:focus {
  top: 0.5rem;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
}

button,
input {
  font: inherit;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--fg);
  cursor: pointer;
  text-decoration: none;
  font-size: 0.9rem;
}

.btn-primary {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: var(--accent);
}

.search-form {
  display: flex;
  gap: 0.5rem;
}

.search-form input[type='text'] {
  flex: 1;
  min-width: 0;
  padding: 0.6rem 0.8rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--fg);
}

/* 전 페이지 헤더 검색창(2026-08-04 요구): 홈을 제외한 모든 페이지 상단에 상시 노출된다. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}

/* 헤더와 본문은 화면 전체 폭을 쓰고 좌우 여백을 맞춘다. */
.site-header-inner {
  max-width: none;
  margin: 0 auto;
  padding: 0.6rem var(--page-gutter);
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  row-gap: 0.4rem;
}

/* 헤더 두 줄 구성(2026-08-05):
     1행  [태극기]  [시도 링크 …………]        [한/EN] [해/달]
     2행                                    [검색창]
   시도 링크는 영어 표기에서 폭이 두 배로 늘어(Gyeongbuk·Gyeongnam…) 검색창과 한 줄에
   둘 수 없다. 스위치는 화면 우측 상단에 고정해야 하므로 1행에 남기고, 자리를 내주는 쪽은
   검색창이다 — order를 마지막으로 두고 flex-basis 100%를 줘 자기 줄을 쓰게 한다.
   시도 링크는 1행에서 남는 폭을 다 쓰고, 모자라면 그 안에서 가로 스크롤된다. */
.site-logo {
  order: 1;
}

/* flex-basis를 0으로 둔다(2026-08-05 재수정). auto(=내용 폭)로 두면 flex-wrap이 "줄이기"보다
   "줄바꿈"을 먼저 택해, 화면이 좁아질 때 시도 링크가 아니라 스위치가 아랫줄로 떨어졌다.
   basis 0 + grow 1이면 링크 줄이 남는 공간만큼만 차지하고 넘치는 부분은 자기 안에서 가로
   스크롤되므로, 1행 구성(로고·링크·스위치)이 폭과 무관하게 유지된다. 링크가 남는 공간을
   다 채우니 스위치는 자연히 오른쪽 끝에 선다. */
.sido-nav {
  order: 2;
  flex: 1 1 0;
}

.lang-switch {
  order: 3;
}

.theme-switch {
  order: 4;
}

/* 노란 버스 아이콘과 이름을 헤더의 한 링크로 묶는다. */
.site-logo {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 0.45rem;
  text-decoration: none;
}

.site-logo img {
  display: block;
  width: 44px;
  height: 44px;
}

.site-logo-name {
  color: var(--fg);
  font-size: 1.05rem;
  font-weight: 800;
  letter-spacing: -0.05em;
  white-space: nowrap;
}

.site-logo-name span {
  color: var(--muted);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0;
}

@media (max-width: 40rem) {
  .site-logo-name { display: none; }
}

/* 시도 링크(2026-08-05, 별도 퀵바에서 헤더로 이동). 17개라 좁은 화면에서는 폭을 넘으므로
   가로 스크롤로 흘린다 — 줄바꿈시키면 헤더가 두 줄이 돼 sticky 헤더가 화면을 과하게 먹는다.
   스크롤바 자체는 숨겨 띠를 깔끔하게 유지한다. min-width:0이 있어야 flex 자식이 내용 크기
   아래로 줄어들어 실제로 스크롤이 생긴다. 왼쪽 여백은 로고와 첫 링크가 붙어 보이지 않게 한다. */
.sido-nav {
  min-width: 0;
  margin-left: 0.5rem;
  overflow-x: auto;
  scrollbar-width: none;
}

.sido-nav::-webkit-scrollbar {
  display: none;
}

.sido-nav ul {
  display: flex;
  gap: 0.7rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.sido-nav li {
  flex-shrink: 0;
}

.sido-nav a {
  color: var(--muted);
  text-decoration: none;
  font-size: 0.9rem;
  white-space: nowrap;
}

.sido-nav a:hover,
.sido-nav a:focus-visible {
  color: var(--accent);
  text-decoration: underline;
}

/* 검색창은 2행 오른쪽 — flex-basis 100%로 자기 줄을 잡고, max-width로 폭을 묶은 뒤
   margin-left:auto로 위 스위치와 오른쪽 끝을 맞춘다. */
.site-header .search-form {
  order: 5;
  flex: 1 1 100%;
  min-width: 0;
  max-width: 26rem;
  margin-left: auto;
}

/* 테마 스위치(2026-08-05). 항상 헤더 오른쪽 끝에 붙는다 — 검색창이 있는 페이지에서는
   검색창이 남는 공간을 다 먹으므로 바로 옆에 좁게 붙이고, 검색창이 없는 홈에서는 자신이
   margin-left:auto로 오른쪽 끝까지 밀린다(안 그러면 시도 링크에 붙어 버린다). */
.theme-switch {
  flex-shrink: 0;
  margin-left: auto;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  line-height: 0;
}

.theme-switch + .theme-switch {
  margin-left: 0.5rem;
}

/* 언어 스위치는 테마 스위치와 같은 트랙을 쓰되 아이콘 대신 글자를 얹는다. 손잡이 위치는
   CSS로 알 수 없어(선택값이 localStorage에 있다) app.ts가 .is-en으로 표시한다.

   글자는 손잡이 중심에 정확히 맞춘다(2026-08-05 수정). 아이콘은 크기가 고정이라 가장자리
   기준(left/right) 배치로 충분했지만, "한"과 "EN"은 글자 폭이 서로 달라 같은 방식으로는
   양쪽이 제각기 치우친다. 그래서 손잡이가 서는 두 지점을 좌표로 계산해 그 위에 가운데를
   포갠다 — 손잡이 중심 = left(0.2rem) + 지름의 절반(0.675rem), EN 쪽은 여기에 이동 거리
   1.65rem을 더한 값이다. */
.lang-switch .ts-ico {
  font-size: 0.68rem;
  font-weight: 700;
  line-height: 1;
  color: var(--muted);
  transform: translate(-50%, -50%);
}

.lang-switch .ts-ico-sun {
  left: 0.875rem;
}

.lang-switch .ts-ico-moon {
  left: 2.525rem;
  right: auto;
}

.lang-switch .ts-ico-sun {
  color: var(--accent-fg);
}

.lang-switch .ts-knob {
  transform: translateX(0);
}

.lang-switch.is-en .ts-knob {
  transform: translateX(1.65rem);
}

.lang-switch.is-en .ts-ico-sun {
  color: var(--muted);
}

.lang-switch.is-en .ts-ico-moon {
  color: var(--accent-fg);
}

.ts-track {
  position: relative;
  display: block;
  width: 3.5rem;
  height: 1.85rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
}

/* 손잡이가 현재 테마 쪽으로 미끄러진다. 기본 위치(왼쪽)는 라이트다. */
.ts-knob {
  position: absolute;
  top: 0.2rem;
  left: 0.2rem;
  width: 1.35rem;
  height: 1.35rem;
  border-radius: 50%;
  background: var(--accent);
  transition: transform 0.18s ease;
}

.ts-ico {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  transition: color 0.18s ease;
}

.ts-ico-sun {
  left: 0.42rem;
}

.ts-ico-moon {
  right: 0.42rem;
}

/* 손잡이 위치·아이콘 대비는 "지금 화면이 어두운가"에 달려 있고, 그 답은 OS 설정과 사용자
   선택(data-theme) 두 군데서 온다 — 네 갈래를 모두 적어야 어느 조합에서도 어긋나지 않는다.
   손잡이 아래에 깔리는 아이콘만 강조색 대비(--accent-fg)를 준다.

   전부 .theme-switch:not(.lang-switch)로 좁힌다(2026-08-05 버그 수정). 처음에는 `.ts-knob`
   처럼 열어 뒀는데, 언어 스위치가 같은 트랙 마크업을 재사용하는 탓에 테마를 바꾸면 언어
   스위치의 손잡이까지 함께 미끄러졌다 — 게다가 `:root[data-theme]` 조합이 `.lang-switch`
   규칙보다 우선순위가 높아 언어 쪽이 밀려났다. */
.theme-switch:not(.lang-switch) .ts-ico-sun {
  color: var(--accent-fg);
}

@media (prefers-color-scheme: dark) {
  .theme-switch:not(.lang-switch) .ts-knob {
    transform: translateX(1.65rem);
  }

  .theme-switch:not(.lang-switch) .ts-ico-sun {
    color: var(--muted);
  }

  .theme-switch:not(.lang-switch) .ts-ico-moon {
    color: var(--accent-fg);
  }
}

:root[data-theme='dark'] .theme-switch:not(.lang-switch) .ts-knob {
  transform: translateX(1.65rem);
}

:root[data-theme='dark'] .theme-switch:not(.lang-switch) .ts-ico-sun {
  color: var(--muted);
}

:root[data-theme='dark'] .theme-switch:not(.lang-switch) .ts-ico-moon {
  color: var(--accent-fg);
}

:root[data-theme='light'] .theme-switch:not(.lang-switch) .ts-knob {
  transform: translateX(0);
}

:root[data-theme='light'] .theme-switch:not(.lang-switch) .ts-ico-sun {
  color: var(--accent-fg);
}

:root[data-theme='light'] .theme-switch:not(.lang-switch) .ts-ico-moon {
  color: var(--muted);
}

@media (prefers-reduced-motion: reduce) {
  .ts-knob,
  .ts-ico {
    transition: none;
  }
}

/* 버튼 안 아이콘(공유·인쇄 등)은 텍스트와 같은 줄에서 가운데를 맞춘다. */
.btn .icon {
  display: block;
  flex-shrink: 0;
}

.search-form-compact input[type='text'] {
  padding: 0.4rem 0.6rem;
  font-size: 0.9rem;
}

.search-form-compact .btn {
  padding: 0.4rem 0.65rem;
  font-size: 0.85rem;
}

.address-row {
  display: grid;
  grid-template-columns: 4.75rem minmax(0, 1fr);
  align-items: start;
  gap: 0.5rem;
  min-width: 0;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--border);
}

.address-row:last-child {
  border-bottom: none;
}

.address-row .row-label-column {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.address-row .row-body {
  position: relative;
  min-width: 0;
  border-radius: 4px;
}

.address-row .row-body:hover,
.address-row .row-body:focus-within {
  background: var(--surface);
}

.address-row .label {
  color: var(--muted);
  font-size: 0.85rem;
  padding-top: 0.2rem;
  white-space: nowrap;
}

/* 영어에서는 라벨이 훨씬 길다("Administrative Dong"·"Road Name Code"). 한국어 기준 폭
   (5.5rem)을 그대로 쓰면 라벨마다 값 시작 위치가 제각각이 된다 — 가장 긴 라벨에 맞춰
   칼럼을 넓혀 값을 한 줄로 세운다. 한국어는 라벨이 짧아 그 폭이 낭비라 갈라 둔다.
   lang 속성은 언어 전환(app.ts setupLangToggle)이 <html>에 심는다. */
html[lang='en'] .address-row {
  grid-template-columns: 11rem minmax(0, 1fr);
}

/* 한글 기본 주소와 영문 상세 카드 모두 가장 긴 Address Line 라벨에 맞춘 동일한 첫 열을 쓴다.
   두 카드의 값 시작선과 오른쪽 컬럼 너비가 정확히 일치한다. */
.detail-main .address-card .address-row,
html[lang='en'] .detail-main .address-card .address-row {
  grid-template-columns: 7.25rem minmax(0, 1fr);
}

.address-row .value {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: 100%;
  min-width: 0;
  white-space: normal;
  overflow-x: visible;
  word-break: keep-all;
  overflow-wrap: anywhere;
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  margin: 0;
  padding: 0.2rem 0.25rem;
  border-radius: 4px;
  text-align: left;
  cursor: pointer;
  min-height: 1.75rem;
}

.address-row .value-text {
  display: block;
  width: 100%;
}

.address-row .value:hover,
.address-row .value:focus-visible {
  background: var(--surface);
}

.address-row .value:hover .value-text,
.address-row .value:focus-visible .value-text {
  text-decoration: underline;
}

.address-row .value:active {
  background: var(--border);
}

/* 검색·다른 건물·우편번호 목록은 두 번째 값 컬럼 하단의 첫 칸에 둔다. 복사 안내와 같은
   기준선에서 한 줄을 이루며, 긴 번역은 복사 안내를 밀지 않고 말줄임한다. */
.address-row .row-link {
  position: absolute;
  left: 0.25rem;
  bottom: 0.2rem;
  z-index: 1;
  max-width: calc(100% - 5.5rem);
  overflow: hidden;
  font-size: 0.68rem;
  color: var(--muted);
  opacity: 0.78;
  text-decoration: none;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.address-row .row-link:hover,
.address-row .row-link:focus-visible {
  color: var(--accent);
  text-decoration: underline;
}

/* 복사 안내는 값 버튼 안쪽 우측 하단에 둔다. 따라서 문구를 직접 눌러도 복사되고 hover의
   회색 배경 역시 값과 안내 문구 전체를 하나의 클릭 영역으로 감싼다. */
.copy-affordance {
  display: block;
  width: 100%;
  margin-top: 0.15rem;
  color: var(--muted);
  font-size: 0.62rem;
  line-height: 1.2;
  opacity: 0.55;
  text-align: right;
  text-decoration: none;
  white-space: nowrap;
}

/* 헤더(검색바)와 본문 사이 간격 축소(2026-08-19 요구): breadcrumb으로 시작하는 페이지
   (상세·지역 목록)는 컨테이너 상단 패딩을 줄여 검색바에 붙인다 — 홈은 자체 규칙이 따로 있다. */
main.container:has(.breadcrumb) {
  padding-top: 0.5rem;
}

/* 왼쪽 들여쓰기(2026-08-19 요구): 페이지 제목의 지역 로고가 고정폭 박스(contain) 안에서
   letterbox되어 시각적으로 안쪽에서 시작하므로, breadcrumb도 살짝 들여 시선 축을 맞춘다. */
.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  padding-left: 0.5rem;
  color: var(--muted);
  font-size: 0.9rem;
}

.breadcrumb a {
  color: var(--muted);
  text-decoration: none;
}

.breadcrumb a:hover {
  text-decoration: underline;
}

.pagination {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
  margin: 1rem 0;
}

.pagination a,
.pagination span {
  padding: 0.35rem 0.6rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  text-decoration: none;
  color: var(--fg);
}

.pagination .current {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: var(--accent);
}

.recent-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.5rem;
}

.recent-chip {
  padding: 0.3rem 0.6rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--fg);
  text-decoration: none;
  font-size: 0.85rem;
}

.recent-title {
  color: var(--muted);
  font-size: 0.85rem;
}

/* 검색창 포커스 드롭다운(2026-08-18): 최근 검색 5건을 입력창 바로 아래 띄운다
   (app.ts setupSearchRecentDropdown이 lazily 만든다 — form은 그때 position:relative가 된다). */
.search-recent-drop {
  position: absolute;
  top: calc(100% + 0.25rem);
  left: 0;
  right: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  padding: 0.3rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  box-shadow: 0 6px 20px rgb(0 0 0 / 0.12);
}

/* 포커스가 풀리면 app.ts가 drop.hidden = true 로 닫는데, 위의 display:flex가 UA의
   [hidden]{display:none}을 이겨서 드롭다운이 그대로 떠 있었다(2026-08-29 실사용 리포트).
   .search-region-filter-list·.qr-overlay와 정확히 같은 함정이다 — author 규칙으로 다시 눌러 준다. */
.search-recent-drop[hidden] {
  display: none;
}

.search-recent-drop a {
  padding: 0.45rem 0.6rem;
  border-radius: 6px;
  color: var(--fg);
  text-decoration: none;
  font-size: 0.9rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.search-recent-drop a:hover,
.search-recent-drop a:focus-visible {
  background: var(--surface);
}

/* 홈의 최근 검색 카드 영역. */
/* 위 여백 0(2026-08-19 요구: 히어로 예시 링크와 최근 검색 사이 빈공간 제거) — 히어로
   쪽 padding-bottom도 함께 0이라 검색 활용법의 자체 여백만 남는다.
   최근 검색이 비어 있으면(클라이언트 렌더 전/기록 없음) 이 래퍼가 높이 0이므로 아래
   "지역별로 찾기" 간격은 홈 전용 section 마진(.container:has(> .hero) > section)이 정한다. */
.home-lists {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 0;
}

/* 최근 검색 카드가 실제로 보일 때만(recent-searches의 hidden이 풀렸을 때) 아래 간격을 준다. */
.home-lists:has(> :not([hidden])) {
  margin-bottom: 0.75rem;
}

/* 홈의 섹션 간격 축소(2026-08-19 요구: 예시 링크와 "지역별로 찾기"를 붙인다). 히어로도
   section이라 전역 margin(1.5rem)을 그대로 받아 사이가 벌어져 있었다 — 히어로 마진을 0으로,
   다음 섹션 위 마진을 최소로 잡는다. */
.container:has(> .hero) > section {
  margin: 0.5rem 0 1rem;
}

.container:has(> .hero) > .hero {
  margin: 0;
}

.home-lists > * {
  flex: 1 1 16rem;
  margin: 0;
}

.toast {
  position: fixed;
  bottom: 1.25rem;
  left: 50%;
  transform: translateX(-50%) translateY(120%);
  background: var(--fg);
  color: var(--bg);
  padding: 0.5rem 1rem;
  border-radius: var(--radius);
  opacity: 0;
  transition:
    transform 0.2s ease,
    opacity 0.2s ease;
  pointer-events: none;
  z-index: 100;
}

.toast.show {
  transform: translateX(-50%) translateY(0);
  opacity: 1;
}

/* 홈 검색창과 사용법은 지역 목록과 같은 가로 폭을 사용한다. */
.hero {
  padding: 0;
}

/* 홈과 가이드도 공통 좌우 여백으로 검색창과 본문을 정렬한다. */
.container:has(> .hero),
.container.guide-page,
.container.page-search:has(+ .guide-page) {
  padding-top: 0.5rem;
}

.hero h1 {
  font-size: 1.5rem;
  margin: 0 0 0.4rem;
}

.hero p {
  color: var(--muted);
  margin: 0 0 1rem;
}

/* 모든 페이지에서 검색창 바로 아래에 사용법을 항상 표시한다. */
.search-tips {
  margin: 0.75rem 0 0.5rem;
  padding: 0.625rem 0.875rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 0.875rem;
  line-height: 1.5;
}

.search-tips-list {
  display: grid;
  gap: 0.375rem 1.5rem;
  margin-top: 0;
}

@media (min-width: 640px) {
  .search-tips-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.search-tip {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.5rem;
  min-width: 0;
}

.search-tip strong {
  color: var(--fg);
}

.search-tip > span {
  color: var(--muted);
}

.search-tip > a {
  flex-basis: 100%;
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: 600;
  text-underline-offset: 0.2em;
}

.hint {
  color: var(--muted);
  padding: 0.75rem 0;
}

.result-count {
  color: var(--muted);
  font-size: 0.9rem;
}

/* 여러 시도에 같은 도로명·번호가 있을 때 검색 결과를 지역별로 좁혀 보는 필터(2026-08-24).
   결과 수 바로 아래에 놓아 카드 목록을 읽기 전에 부산/충북 등 범위를 먼저 고를 수 있게 한다. */
.search-region-filter {
  margin: 0.35rem 0 0.9rem;
}

.search-region-filter h2 {
  margin: 0 0 0.4rem;
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 600;
}

/* 단위 토글(2026-08-25): 제목 줄 오른쪽에서 시·도/시·군·구를 고른다. 칩과 구별되도록
   세그먼트(붙은 두 버튼) 형태를 쓴다. */
.search-region-filter-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.4rem;
}

.search-region-filter-head h2 {
  margin: 0;
}

.region-level-toggle {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 999px;
  overflow: hidden;
}

.region-level-btn {
  padding: 0.2rem 0.7rem;
  border: 0;
  background: var(--bg);
  color: var(--muted);
  font-size: 0.78rem;
  white-space: nowrap;
}

.region-level-btn + .region-level-btn {
  border-left: 1px solid var(--border);
}

.region-level-btn.active {
  background: var(--accent);
  color: var(--accent-fg);
}

.search-region-filter-list {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}

/* 시·도/시·군·구 두 목록 중 토글로 고른 한쪽만 보인다 — 위의 display:flex가 UA의
   [hidden]{display:none}을 이겨버려 숨긴 목록까지 두 줄로 그려졌다(2026-08-25 실사용
   리포트, .qr-overlay와 같은 함정). author 규칙으로 다시 눌러 준다. */
.search-region-filter-list[hidden] {
  display: none;
}

.search-region-filter-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-height: 2.25rem;
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
  color: var(--fg);
  cursor: pointer;
  font: inherit;
  font-size: 0.85rem;
  white-space: nowrap;
}

.search-region-filter-btn:hover,
.search-region-filter-btn:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
}

.search-region-filter-btn.active {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-fg);
}

/* 시군구 로고 PNG는 원본 여백이 넓어 같은 박스에서 시도 SVG보다 작아 보인다(2026-08-25
   리포트) — 박스를 키우되 음수 마진으로 칩 높이는 그대로 둔다. */
.search-region-filter-logo.logo-sigungu {
  width: 30px;
  height: 30px;
  margin: -3px 0;
}

.search-region-filter-logo {
  flex: 0 0 auto;
  width: 1.5rem;
  height: 1.5rem;
  object-fit: contain;
}

.search-region-filter-count {
  min-width: 1.2rem;
  padding: 0 0.25rem;
  border-radius: 999px;
  opacity: 0.72;
  font-size: 0.75rem;
  line-height: 1.35;
  text-align: center;
}

.search-region-filter-btn.active .search-region-filter-count {
  opacity: 0.9;
}

.building-item[data-region-filter-item][hidden] {
  display: none;
}

/* 한 검색어에 여러 주소가 붙어 있을 때(searchMultiAddress) 구간별 카드(2026-08-19). 번호
   배지로 몇 번째 주소인지 한눈에 스캔되게 하고, 카드 테두리로 구간을 뚜렷이 가른다. */
.multi-address-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin: 1rem 0;
}

/* 상세 카드끼리는 데스크톱에서 나란히 대조한다(2026-08-19 목업) — 컬럼 최소폭 24rem이라
   82rem 컨테이너 기준 2~3열이 된다. align-items 기본값(stretch)을 그대로 둬 같은 행의
   카드 높이가 나란히 맞는다(2026-08-19 요구 — 행정동 유무 등으로 행 수가 달라도 통일). */
@media (min-width: 1024px) {
  .multi-address-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr));
  }
}

.multi-address-list section {
  margin: 0;
}

/* 라벨 칸은 "Address Line 1" 같은 영문 라벨이 들어가므로 상세 페이지 카드와 같은 폭을 쓴다. */
.multi-address-card .address-row {
  grid-template-columns: 7.25rem minmax(0, 1fr);
}

/* 카드 빈 영역 클릭으로 상세 이동(app.ts setupCardNavigation) — 눌린다는 힌트만 준다. */
.multi-address-card {
  cursor: pointer;
}

/* 나란히 배치에서 행 높이까지 통일(2026-08-18 요구): flex 균등분배는 카드마다 내용 높이가
   다르면(도로명 2줄 vs 1줄, 영문 3줄 vs 4줄) 같은 순번 행이 어긋난다 — subgrid로 같은 행의
   카드들이 부모 그리드의 행 트랙을 공유하게 해서, 어느 카드의 행이 길어지면 옆 카드의 같은
   행도 함께 늘어난다. span 9 = 머리(1) + 행 8(도로명·지번·영문·Address 1·우편번호·행정동·
   법정동코드·도로명코드 — 행정동은 비어도 렌더해 자식 수를 고정). subgrid 미지원 브라우저는
   선언이 무효가 돼 auto 행으로 폴백한다(높이 통일만 포기). */
@media (min-width: 1024px) {
  .multi-address-card {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: span 9;
  }

  .multi-address-card .address-row {
    align-items: center;
  }
}

/* 체크박스 히트존(2026-08-18): 패딩만큼 클릭 영역이 커지고(라벨이라 누르면 체크 토글),
   음수 마진으로 시각 위치는 그대로 둔다. 멀티 카드 체크박스 자체도 한 단계 키운다. */
.multi-address-heading .select-zone {
  display: inline-flex;
  flex-shrink: 0;
  padding: 0.5rem;
  margin: -0.5rem;
}

.multi-address-heading .select-check {
  width: 1.5rem;
  height: 1.5rem;
}

.multi-address-detail-link {
  margin-left: auto;
  flex-shrink: 0;
  font-size: 0.8rem;
  font-weight: 400;
  text-decoration: none;
}

.multi-address-detail-link:hover,
.multi-address-detail-link:focus-visible {
  text-decoration: underline;
}


.multi-address-heading {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 0.75rem;
  color: var(--fg);
  font-size: 1.05rem;
  word-break: keep-all;
  overflow-wrap: anywhere;
}

.multi-address-count {
  margin-left: auto;
  flex-shrink: 0;
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 400;
}

section {
  margin: 1.5rem 0;
}

section h2 {
  font-size: 1rem;
  color: var(--muted);
  margin: 0 0 0.6rem;
}

/* 긴 지역명 대응(2026-08-05): 최소 트랙 폭을 10rem으로 넓혀 "창원시 마산합포구" 같은
   9자 이름 대부분이 한 줄에 들어가게 하고, min(100%, …)으로 좁은 화면에서 트랙이 컨테이너를
   넘지 않게 한다. */
.sido-list,
.region-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 10rem), 1fr));
  gap: 0.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* keep-all: 줄바꿈이 필요하면 음절 중간("마산합\n포구")이 아니라 공백("창원시\n마산합포구")
   에서 끊는다. overflow-wrap:anywhere: "전남광주통합특별시"처럼 공백 없는 이름이 트랙보다
   길 때의 비상 줄바꿈 — 없으면 keep-all이 넘침(overflow)을 만든다. */
.sido-list li a,
.region-list li a {
  display: block;
  /* 로고를 키운 만큼(64px) 셀 여백은 줄인다(2026-08-05 요구) — 안 그러면 행 높이가 로고와
     여백 양쪽으로 불어나 목록이 화면을 과하게 먹는다. 상하 여백은 로고가 이미 행 높이를
     정하므로 최소만 남긴다. */
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-decoration: none;
  color: var(--fg);
  word-break: keep-all;
  overflow-wrap: anywhere;
}

/* 시도 상징(CI) 병기(2026-08-05): 로고와 이름을 한 행에 놓는다.
   트랙 폭은 화면에 따라 갈라 준다 — 최장 이름 "전남광주통합특별시"(9자)는 로고 24px과
   간격·패딩까지 더하면 약 12rem을 먹는데, 390px 화면에서 12rem 트랙은 2열을 1열로
   무너뜨린다. 그래서 자리가 있는 640px 이상만 12rem으로 넓혀 전부 한 줄에 앉히고,
   그보다 좁으면 10rem(2열)을 유지한 채 이름만 두 줄로 접는다. */
@media (min-width: 640px) {
  .sido-list {
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr));
  }
}

/* 시군구 목록(region-list-logo)도 같은 트랙 규칙을 쓴다 — "창원시 마산합포구"처럼
   시도만큼 긴 이름이 있다. 로고가 없는 읍면동 목록(.region-list 단독)은 10rem 그대로다. */
@media (min-width: 640px) {
  .region-list-logo {
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr));
  }
}

/* balance: 접힐 때 "전남광주통합특별 / 시"처럼 마지막 한 글자만 떨어져 넘친 것처럼
   보이는 것을 막고 두 줄을 고르게 나눈다. */
.sido-list li a span,
.region-list-logo li a span {
  text-wrap: balance;
}

.sido-list li a,
.region-list-logo li a {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* flex:0 0 auto — 긴 이름이 두 줄로 접힐 때 로고가 찌그러지지 않게 한다.
   object-fit:contain — 원본 종횡비가 정사각(충북)부터 가로 워드마크(대구·제주)까지
   제각각이라 정사각 상자 안에 비율을 지켜 맞춘다. */
/* 64px(2026-08-05 요구로 24→36→48→64): 시군구는 CI 심볼이 아니라 깃발이라 도형이 흰 여백
   안에 들어앉아 있어 작게 두면 마크가 뭉갠다 — 상자를 키운 만큼 마크 자체가 커진다.
   행 자체의 패딩을 줄여(아래 .sido-list li a) 상자를 키워도 목록이 두꺼워지지 않게 했다. */
.region-logo {
  flex: 0 0 auto;
  width: 64px;
  height: 64px;
  object-fit: contain;
}

/* 시군구 깃발은 원래 밝거나 어두운 단색 캔버스를 전제로 한 디자인이 섞여 있다. 배경을
   투명화한 뒤에도 흰 글자와 검은 글자가 각 테마에서 사라지지 않도록 현재 글자색으로 아주
   얇은 외곽 대비만 준다. 색상 자체를 뒤집지 않으므로 공식 상징색은 그대로 유지된다. */
.region-logo[src^='/sigungu/'] {
  filter: drop-shadow(0 0 0.75px var(--fg));
}

/* 시군구 목록 행(RegionLinkList)의 로고는 96×64 고정 — 아래 페이지 제목 로고와 별개다.
   한 줄에 여러 개가 나열되므로 제목 로고처럼 키우면 목록이 깨진다. */
.region-list-logo .region-logo {
  width: 96px;
  height: 64px;
}

.sido-heading {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

/* 페이지 제목 로고(시도·시군구·읍면동·건물색인·건물상세 h1 공통, 2026-08-15: 56×56/96×64→
   72×72/108×72로 확대). -wide가 -lg보다 뒤에 와야 한다 — 시군구가 있는 페이지는 두 클래스를
   같이 받는데(-lg가 기본 정사각, -wide가 깃발용 가로 비율), 소스 순서가 반대였을 때는
   -lg가 항상 이겨서 96×64 깃발이 56×56으로 눌리는 버그가 있었다. */
.region-logo-lg {
  width: 72px;
  height: 72px;
}

.region-logo-wide {
  width: 108px;
  height: 72px;
}

/* 로고를 제목 텍스트에 붙인다(2026-08-19 요구): contain letterbox 때문에 좁은 상징(종로구
   종 모양 등)은 고정폭 박스 가운데 떠서 제목과 시각적 간격이 벌어진다 — 페이지 제목 자리
   (상세·시도 heading)에서는 박스 안 오른쪽으로 붙여 제목과의 간격을 flex gap만큼으로 고정한다. */
.detail-heading .region-logo,
.sido-heading .region-logo {
  object-position: right center;
}

.road-chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.road-chip-list .chip {
  display: inline-block;
  padding: 0.3rem 0.6rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--fg);
  text-decoration: none;
  font-size: 0.85rem;
}

.road-chip-list .chip.active {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: var(--accent);
}

/* 읍면동의 수십~수백 개 도로를 초성별로 한 단계 접는다. 상단 자음 줄은 좁은 화면에서
   가로 스크롤되고, 선택한 그룹만 app.ts가 열어 해당 위치로 이동한다. */
.road-initial-nav {
  display: flex;
  gap: 0.35rem;
  overflow-x: auto;
  padding: 0.1rem 0 0.45rem;
  scrollbar-width: none;
}

.road-initial-nav::-webkit-scrollbar {
  display: none;
}

.road-initial-nav a {
  display: grid;
  place-items: center;
  flex: 0 0 2.35rem;
  width: 2.35rem;
  height: 2.35rem;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--fg);
  font-weight: 700;
  text-decoration: none;
}

.road-initial-nav a:hover,
.road-initial-nav a:focus-visible,
.road-initial-nav a[aria-expanded='true'] {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-fg);
}

.road-directory-hint {
  margin: 0 0 0.5rem;
  color: var(--muted);
  font-size: 0.78rem;
}

.road-groups {
  border-top: 1px solid var(--border);
}

.road-group {
  scroll-margin-top: 5rem;
  border-bottom: 1px solid var(--border);
}

.road-group summary {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-height: 3rem;
  padding: 0.55rem 0.15rem;
  cursor: pointer;
  list-style: none;
}

.road-group summary::-webkit-details-marker {
  display: none;
}

.road-group summary::after {
  content: '›';
  flex-shrink: 0;
  color: var(--muted);
  font-size: 1.25rem;
  transform: rotate(90deg);
  transition: transform 0.15s ease;
}

.road-group[open] summary::after {
  transform: rotate(-90deg);
}

.road-group-initial {
  flex: 0 0 2rem;
  color: var(--fg);
  font-size: 1.05rem;
  font-weight: 700;
  text-align: center;
}

.road-group-range {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  color: var(--muted);
  font-size: 0.8rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.road-group-count {
  flex-shrink: 0;
  color: var(--muted);
  font-size: 0.78rem;
}

.road-group .road-chip-list {
  padding: 0.15rem 0.15rem 0.8rem 2.8rem;
}

.building-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* 데스크톱 정보 밀도: 건물 목록(검색 결과·읍면동 목록)을 다열 그리드로 배치한다. */
@media (min-width: 1024px) {
  .building-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 24rem), 1fr));
    gap: 0.6rem 0.75rem;
  }
}

.building-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.building-sido-logo {
  flex: 0 0 auto;
  width: 2rem;
  height: 2rem;
  object-fit: contain;
}

.building-link {
  flex: 1;
  min-width: 0;
  display: block;
  text-decoration: none;
  color: var(--fg);
}

.building-name {
  font-weight: 700;
  margin-bottom: 0.15rem;
}

/* 주소 줄바꿈(2026-08-05 개선): break-all은 아무 데서나 끊어 "창원시 마산합포\n구"처럼
   읽기 나쁘다 — keep-all로 공백에서 먼저 끊고, anywhere로 공백 없는 초장문(영문 등)의
   넘침만 막는다. */
.building-road {
  font-weight: 600;
  word-break: keep-all;
  overflow-wrap: anywhere;
}

.building-jibun {
  color: var(--muted);
  font-size: 0.85rem;
  margin-top: 0.15rem;
  word-break: keep-all;
  overflow-wrap: anywhere;
}

.building-eng {
  color: var(--muted);
  font-size: 0.8rem;
  margin-top: 0.15rem;
  word-break: keep-all;
  overflow-wrap: anywhere;
}

.building-item .copy-btn {
  flex-shrink: 0;
  min-width: 2.75rem;
  min-height: 2.75rem;
}

/* 다중 선택 복사(2026-08-19): 체크박스(목록 행·멀티주소 카드 공용) + 하단 고정 액션 바
   (app.ts가 lazily 만든다). */
.select-check {
  flex-shrink: 0;
  width: 1.15rem;
  height: 1.15rem;
  margin: 0;
  accent-color: var(--accent);
  cursor: pointer;
}

.select-bar {
  position: fixed;
  left: 50%;
  bottom: 4.75rem; /* 고정 푸터 바(4.5rem) 바로 위 */
  transform: translateX(-50%);
  z-index: 30;
  display: flex;
  flex-direction: column; /* 1행 항목 칩, 2행 액션 버튼 */
  align-items: center;
  gap: 0.4rem;
  max-width: calc(100vw - 1rem);
  padding: 0.5rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--bg);
  box-shadow: 0 4px 16px rgb(0 0 0 / 0.14);
}

.select-bar .btn {
  white-space: nowrap;
}

/* 복사할 항목 토글 칩(2026-08-19): 도로명/지번/영문/우편번호 중 무엇을 복사할지 고른다. */
.select-bar-fields {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.35rem;
}

.select-field {
  padding: 0.25rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--fg);
  font-size: 0.78rem;
  cursor: pointer;
}

.select-field.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-fg);
}

.select-bar-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.select-bar-count {
  flex-shrink: 0;
  padding-left: 0.25rem;
  color: var(--fg);
  font-size: 0.85rem;
  font-weight: 600;
  white-space: nowrap;
}

@media (max-width: 40rem) {
  .select-bar {
    bottom: 3.25rem; /* 모바일 푸터 바(3rem) 위 */
    gap: 0.35rem;
    padding: 0.4rem 0.55rem;
  }

  .select-bar .btn {
    padding: 0.4rem 0.55rem;
    font-size: 0.8rem;
  }

  .select-bar-count {
    font-size: 0.78rem;
  }
}

.map-links,
.share-row {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 1rem 0;
}

/* 라벨은 절대 줄바꿈하지 않는다(2026-08-05) — 좁은 칸에서 "Copy / Link", "QR / 저 / 장"처럼
   글자가 쪼개져 버튼 높이가 제각각이 됐다. 버튼 사이는 계속 접히되(flex-wrap) 글자 안에서는
   끊지 않는다. */
.share-row .btn {
  white-space: nowrap;
}

/* 주소 QR 공유(2026-08-04 추가) — 접혀 있는 상태가 기본이라 페이지 초기 무게에 영향이 없다. */
.qr-details {
  margin: 1rem 0;
}

.qr-details summary {
  cursor: pointer;
  color: var(--fg);
  font-weight: 600;
}

/* 상세 페이지 재구성(2026-08-05, 사용자 목업 반영): 좌측 주소 카드 + 우측 사이드(지도 자리·
   QR 카드). 모바일은 단일 컬럼 스택(사이드가 본문 뒤로), 데스크톱(≥1024px)만 2컬럼. */
/* 세로 여백 절반 + 위아래 통일(2026-08-19 요구): breadcrumb↔제목과 제목↔본문 카드 사이
   간격을 같은 값(.5rem)으로 맞춘다 — 카드 쪽은 아래 first-child 마진 0과 합쳐 .5rem이 된다. */
.detail-heading {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0.5rem 0;
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  line-height: 1.3;
  letter-spacing: -0.025em;
  word-break: keep-all;
  overflow-wrap: anywhere;
}


.detail-layout {
  display: grid;
  gap: 0.5rem;
}

.detail-main > section:first-child {
  margin-top: 0;
}

.detail-side {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.detail-side section {
  margin: 0;
}

@media (min-width: 1024px) {
  .detail-layout {
    grid-template-columns: minmax(0, 1fr) 380px;
    gap: 1.75rem;
    align-items: start;
  }

  .detail-side {
    margin-top: 0;
  }
}

/* 목차(2026-08-29). 좁은 화면에서는 헤더 아래 붙는 가로 스크롤 바다 — 세로 사이드바를 놓을
   폭이 없고, 상세 페이지는 모바일에서 스크롤이 가장 길어 이 기능이 가장 필요한 곳이다. */
.detail-toc {
  position: static;
  margin: 0 0 0.5rem;
  padding: 0.35rem 0;
  background: var(--bg);
}

/* 본문 목차가 사라지면 미리 헤더 안에 둔 복사본을 표시한다. 복사본도 같은 flex 줄에 있으므로
   breakpoint마다 달라지는 헤더 패딩을 별도로 계산하지 않아도 로고와 정렬이 맞는다. */
.site-header-inner > .detail-toc {
  order: 2;
  flex: 1 1 0;
  min-width: 0;
  position: static;
  margin: 0;
  padding: 0;
  background: none;
  box-shadow: none;
}

/* 헤더 줄에서는 캡슐을 벗는다 — 로고와 나란히 서면 테두리가 군더더기가 된다. 테두리 폭과
   여백은 그대로 두고 색만 투명하게 해 이동 전·후의 상자 구조는 같은 상태로 유지한다. */
.site-header-inner > .detail-toc ol {
  border-color: transparent;
  background: none;
}

/* 목차가 헤더에 들어가 있는 동안 상단 줄은 통째로 목차에 내준다(2026-08-29 요구).
   건물 상세를 스크롤해 내려가는 중에 시도 링크로 옮겨 가거나 언어·테마를 바꾸는 일은
   사실상 없다 — 셋을 다 감추면 목차가 줄 전체를 넉넉히 쓴다. 로고(홈 링크)만 남긴다. */
.site-header.has-toc .sido-nav,
.site-header.has-toc .lang-switch,
.site-header.has-toc .theme-switch {
  display: none;
}

/* 본문 목차가 화면 위로 사라지면 app.ts가 미리 배치한 헤더 복사본으로 즉시 교체한다. */

/* 본문 위에 있을 때는 항목 묶음을 캡슐 하나로 감싼다(2026-08-29 요구). 글자만 줄지어 두면
   본문과 구분이 안 돼 "그냥 거기 있는" 것처럼 보였다. 내용 폭에만 맞춰(inline-flex) 줄 전체를
   먹지 않게 한다. */
.detail-toc ol {
  display: inline-flex;
  max-width: 100%;
  gap: 0.15rem;
  margin: 0;
  padding: 0.25rem 0.4rem;
  list-style: none;
  overflow-x: auto;
  scrollbar-width: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
}

.detail-toc ol::-webkit-scrollbar {
  display: none;
}

/* 좁은 화면의 가로 바에는 하위 항목을 넣지 않는다 — 한 줄에 들어갈 폭이 없고, 계층은
   넓은 화면의 세로 목록에서만 의미가 있다. */
.detail-toc ol ol {
  display: none;
}

/* 테두리 없이 글자만 둔다(2026-08-29 요구). 알약 칩으로 만들었더니 헤더 줄에서 상자가
   줄줄이 겹쳐 보였다 — 현재 항목은 굵게, 나머지는 회색이라는 대비만으로 충분히 읽힌다. */
.detail-toc a {
  display: block;
  padding: 0.3rem 0.55rem;
  border: 0;
  color: var(--muted);
  text-decoration: none;
  font-size: 0.85rem;
  white-space: nowrap;
}

.detail-toc a:hover,
.detail-toc a:focus-visible {
  color: var(--fg);
}

/* 현재 보고 있는 섹션(app.ts 스크롤 스파이가 단다). 굵게 + 본문색, 나머지는 회색으로 둔다
   — 채운 알약도 써 봤지만 헤더 줄에 들어가면 색 덩어리가 너무 세게 튀었다. */
.detail-toc a.is-active {
  color: var(--fg);
  font-weight: 700;
}

/* QR은 데스크톱(.qr-card)과 모바일(.qr-details) 두 벌이고 1024px에서 갈린다. 목차 항목도
   같은 경계로 갈라야 숨겨진 쪽으로 뛰어 아무 일도 일어나지 않는 링크가 생기지 않는다. */
.toc-wide {
  display: none;
}

@media (min-width: 1024px) {
  .toc-wide {
    display: block;
  }

  .toc-narrow {
    display: none;
  }
}

/* sticky 헤더와 목차 바에 가리지 않도록 앵커 도착 지점을 내려 잡는다. */
#detail,
#english,
#land,
#map,
#qr,
#qr-m,
#nearby {
  scroll-margin-top: 7rem;
}

/* 주소 카드: 행별 label·값(클릭 복사)·복사 버튼 목록을 감싸는 테두리 카드. 행 구분선은
   .address-row의 border-bottom이 이미 그린다. */
.address-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  padding: 0.25rem 1rem;
}

/* 지도 카드. 좌표가 없을 때는 모눈 placeholder, 있으면 지도·로드뷰 전용 iframe을 쓴다. */
.map-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  padding: 0.75rem;
}

.map-placeholder {
  position: relative;
  height: 280px;
  border-radius: var(--radius);
  background-color: var(--surface);
  background-image:
    linear-gradient(var(--border) 1px, transparent 1px),
    linear-gradient(90deg, var(--border) 1px, transparent 1px);
  background-size: 28px 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

/* 자동 로드되는 카카오 1200px 파노라마는 iframe 안에 격리한다. iframe 내부 이미지는 상위
   주소 문서의 LCP 후보가 아니며, 기존 지도(280)+간격(8)+로드뷰(340) 높이를 처음부터
   예약하므로 로드뷰 도착 시 바깥 레이아웃도 움직이지 않는다. */
.map-frame {
  display: block;
  width: 100%;
  height: 628px;
  border: 0;
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}

/* 모바일·태블릿에서 지도를 좌우로 살짝 들여놓는다(2026-09-09). 폭 100%면 지도가 화면
   가로를 꽉 채워서, 세로로 스크롤하려고 손가락을 대는 자리가 전부 지도 위가 된다 — 그
   드래그는 카카오 지도의 팬으로 먹히고 페이지는 내려가지 않는다. 양옆에 여백을 두면
   거기서 시작한 드래그가 평범한 페이지 스크롤이 된다.

   카드 자체의 padding(0.75rem)에 1.5rem을 더해 가장자리에서 2.25rem(36px)이 비므로
   엄지로 짚기에 충분하다. 데스크톱은 사이드 컬럼이 380px로 이미 좁고 휠로 스크롤하니
   그대로 둔다. 높이는 건드리지 않아 예약된 높이(CLS 방지)가 그대로 유지된다. */
@media (max-width: 1023px) {
  .map-frame,
  .map-placeholder {
    width: calc(100% - 3rem);
    margin-inline: auto;
  }
}

@media (min-width: 1024px) {
  .map-placeholder {
    height: 340px;
  }

  .map-frame {
    height: 748px;
  }
}

/* 외부 지도 앱 바로가기(2026-08-05). 아이콘은 각 사 공식 로고라 색을 건드리지 않는다 —
   다크 모드에서도 원본 그대로 둔다(브랜드 가이드라인이 재색칠을 금지한다). */
.map-app img {
  display: block;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

/* 지도 앱 바로가기(2026-08-05). 오른쪽 정렬에 두 줄로 접히니 오히려 산만해서, 셋을 한 줄에
   넣고 남는 폭을 고르게 나누는 쪽으로 바꿨다 — 버튼 글자를 줄이고 줄바꿈을 막으면 사이드
   폭(380px)에 셋이 들어간다. 보조 동작이라 지도보다 작게 보이는 게 맞다. */
.map-card .map-links {
  margin: 0.75rem 0 0;
  gap: 0.35rem;
  flex-wrap: nowrap;
}

.map-app {
  flex: 1 1 0;
  min-width: 0;
  justify-content: center;
  gap: 0.3rem;
  padding: 0.35rem 0.4rem;
  font-size: 0.78rem;
  white-space: nowrap;
}

.map-app img {
  width: 15px;
  height: 15px;
}

/* 부동산 정보 카드(2026-08-25): 영문 상세와 같은 골격(.address-variants > .address-card)
   안에 들어간다 — 테두리·배경은 .address-card가 그리고 여기는 안쪽 여백만 맡는다. */
.land-info {
  padding: 0.75rem 1rem;
}

.land-link {
  width: 100%;
  justify-content: center;
  white-space: nowrap;
}

/* 공시지가·실거래가 행(2026-08-25): /api/land 응답을 app.ts setupLandInfo가 채운다.
   비어 있는 동안은 [hidden]이라 카드 높이에 영향이 없다. */
.land-rows {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin-bottom: 0.6rem;
}

.land-row {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: 0.85rem;
  min-width: 0;
}

.land-row-label {
  flex-shrink: 0;
  min-width: 4rem;
  color: var(--muted);
}

.land-row-value {
  min-width: 0;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}

/* 실거래 행(2026-08-25 디자인 요구): 금액이 주인공 — [계약월 | 금액 굵게 | 면적·층 오른쪽]. */
.land-trades {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.land-trades > .land-row-label {
  flex-shrink: 0;
  min-width: 4rem;
  color: var(--muted);
  font-size: 0.85rem;
}

.trade-rows {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.trade-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: 0.5rem;
  font-variant-numeric: tabular-nums;
}

.trade-ym {
  color: var(--muted);
  font-size: 0.78rem;
}

.trade-price {
  min-width: 0;
  color: var(--fg);
  font-size: 0.9rem;
  font-weight: 650;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.trade-meta {
  color: var(--muted);
  font-size: 0.78rem;
  white-space: nowrap;
}

/* 공시지가 이력 행(2026-08-25): 최신 연도만 굵게, 지난 연도는 흐리게 — 추이만 보이면 된다. */
.trade-row.history .trade-price {
  font-weight: 400;
  font-size: 0.82rem;
  color: var(--muted);
}

/* 토지이음 워드마크는 짙은 글자에 투명 배경이라 다크 모드 버튼 위에서 안 읽힌다 — 로고
   자체는 변형하지 않고 흰 칩을 깔아 준다(라이트 모드에선 흰 배경 위 흰 칩이라 안 보인다). */
.land-link img {
  display: block;
  width: 80px;
  height: 18px;
  flex-shrink: 0;
  padding: 2px 4px;
  box-sizing: content-box;
  background: #fff;
  border-radius: 4px;
}

/* 주변 시설(2026-08-25): 지도 카드 하단 목록 — 지도 iframe이 postMessage로 준 결과를
   app.ts setupNearbyPlaces가 채운다. 채워지기 전에는 [hidden]이라 자리도 차지하지 않는다. */
.nearby {
  margin-top: 0.75rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
}

.nearby-title {
  margin: 0 0 0.35rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--muted);
}

.nearby-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.nearby-list li {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: 0.8rem;
  min-width: 0;
}

.nearby-label {
  flex-shrink: 0;
  min-width: 3.4rem;
  color: var(--muted);
}

.nearby-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--fg);
}

a.nearby-name:hover {
  color: var(--accent);
}

.nearby-dist {
  margin-left: auto;
  flex-shrink: 0;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* QR 확대(2026-08-05). 카드 안 QR을 감싼 버튼은 테두리·배경 없이 그림만 보이게 둔다. */
.qr-zoom {
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  line-height: 0;
}

/* 전체 화면 오버레이. hidden이 그대로 먹도록 display는 여기서 지정하지 않고, 보일 때만
   .is-open으로 flex를 켠다 — 처음부터 display:flex를 걸면 UA의 [hidden]{display:none}을
   이겨버려 페이지 로드 때 QR이 화면을 덮는다. */
.qr-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  padding: 1.5rem;
  background: rgb(0 0 0 / 0.82);
  cursor: zoom-out;
}

.qr-overlay.is-open {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 정사각 QR을 화면 짧은 변에 맞춘다. 흰 받침은 필수다 — 어두운 배경 위에 그대로 두면
   QR 모듈(검정)이 배경과 붙어 스캔이 안 된다. */
.qr-overlay-svg {
  width: min(88vw, 88vh);
  height: min(88vw, 88vh);
  background: #fff;
  border-radius: 12px;
  padding: 1rem;
}

/* QR 카드(2026-08-05 목업 반영): 데스크톱 전용 상시 노출, QR 왼쪽 + 텍스트·버튼 오른쪽 가로
   배치. 모바일은 자기 화면을 자기 폰으로 스캔할 수 없고 세로 공간이 귀해 접힘(details)을
   유지한다. 두 소비자 모두 같은 도형 정의를 use로 참조하므로 중복 비용은 래퍼 몇 줄뿐이다
   ("QR 1회만 인라인" — 스모크의 use 참조 수 기대값 3: 카드+접힘+인쇄). */
.qr-card {
  display: none;
}

@media (min-width: 1024px) {
  .qr-card {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    padding: 1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg);
  }

  /* QR을 감싼 버튼(.qr-zoom)이 카드의 flex 자식이라 위 정렬은 그쪽에 줘야 한다 —
     svg에만 걸면 버튼이 세로로 늘어난 만큼 QR이 가운데로 밀린다. */
  .qr-card .qr-zoom {
    align-self: flex-start;
    flex: 0 0 210px;
    min-width: 0;
  }

  /* 크기는 사이드 폭에서 버튼 자리를 뺀 나머지에 맞춘다(2026-08-05). 고정 280px로 뒀더니
     버튼 칸이 좁아져 라벨이 "Copy / Link"처럼 줄바꿈됐다 — 옆 버튼이 한 줄로 들어가는 것이
     우선이고, QR은 줄어도 눌러서 전체 화면으로 키울 수 있다. */
  .qr-card .qr-svg {
    margin-top: 0;
    width: 210px;
    max-width: 210px;
    height: auto;
    aspect-ratio: 1;
    padding: 0.5rem;
  }

  .qr-card h2 {
    margin: 0 0 0.35rem;
    font-size: 0.95rem;
    color: var(--fg);
  }

  .qr-details {
    display: none;
  }

  /* 첫 버튼의 상단을 QR 상단과 정확히 맞춘다. 공용 .share-row의 위아래 margin은 이 카드에서
     제거하고, 남은 폭은 버튼 컬럼이 전부 사용한다. */
  .qr-card .share-row {
    margin: 0;
    align-content: flex-start;
  }
}

.qr-card-body {
  flex: 1 1 0;
  min-width: 0;
}

.qr-card-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 0.6rem;
}

.qr-caption {
  margin: 0.5rem 0 0;
  color: var(--muted);
  font-size: 0.8rem;
  max-width: 214px; /* 모바일 접힘 뷰: QR 표시 폭(QR_DISPLAY_SIZE 210 + 여유)에 맞춰 줄바꿈 */
}

.qr-card-body .qr-caption {
  margin-top: 0;
  max-width: none; /* 가로 카드에서는 본문 컬럼 폭을 그대로 쓴다 */
}

/* 페이지 맨 아래 요약 문단(2026-09-12). 상세 페이지는 `라벨 | 값` 표라서 사람이 실제로
   검색하는 문장("…의 지번주소는 …") 어휘가 페이지에 하나도 없었다 — 그 문장을 만드는
   자리다. 숨기지 않는 것이 조건이라(숨긴 키워드 텍스트는 스팸 정책 위반이고 가중치도
   깎인다) 흐린 각주 톤으로만 낮춘다. 위 구분선이 본문 끝을 알리는 역할도 겸한다. */
.address-summary {
  margin: 1.5rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.85rem;
  line-height: 1.7;
  word-break: keep-all;
}

/* viewBox 기반 스케일링(2026-08-04 보강, 클리핑 버그 수정): width/height는 항상 고정
   표시 크기([id].astro의 QR_DISPLAY_SIZE)고, 실제 좌표계는 use 참조 대상(.qr-def 안의
   defs 그룹)이 아니라 이 소비자 쪽 viewBox가 유일한 기준이다 — 그래서 max-width:100%로
   더 작은 박스로 눌려도(모바일 폭, 좁은 카드 등) 잘리지 않고 항상 비율대로 축소된다.
   height:auto는 width만 줄었을 때도 종횡비(항상 정사각형)를 유지시킨다.
   (주의: 이 파일은 dev 모드에서 <style>로 그대로 페이지에 인라인되므로, 아래·위 주석에
   qr-code 참조 id를 HTML 속성 형태로 그대로 옮겨 적지 않는다 — 그렇게 적으면 스모크
   테스트의 "정의가 정확히 1번"이라는 카운트 검증이 주석 텍스트까지 세어 버려 오탐한다.) */
/* 흰 받침은 남긴다 — 다크 모드에서 QR 모듈(검정)이 배경에 붙으면 스캔이 안 된다.
   테두리는 뺐다(2026-08-05 요구): 이미 카드 안에 들어 있어 선이 겹쳐 보인다. */
.qr-svg {
  margin-top: 0.75rem;
  display: block;
  max-width: 100%;
  height: auto;
  background: #ffffff;
  padding: 0.75rem;
  border-radius: var(--radius);
}

.qr-svg[hidden],
.qr-overlay-svg[hidden],
.print-qr[hidden],
[data-qr-placeholder][hidden] {
  display: none !important;
}

.qr-generate-placeholder {
  display: grid;
  place-items: center;
  width: 210px;
  height: 210px;
  max-width: 100%;
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--fg);
  font-weight: 600;
}

.qr-save-btn {
  margin-top: 0.5rem;
}

/* QR 도형 정의 컨테이너(2026-08-04 보강, 클리핑 버그 수정): 좌표 데이터(배경 rect + 모듈
   path)만 담은 defs 그룹 원본이 여기 딱 한 벌 있다 — 화면 위젯(.qr-svg)·인쇄 뷰
   (.print-qr) 둘 다 use 참조 엘리먼트로 이 정의를 가리켜 재사용한다("QR 1회만 인라인").
   display:none으로 숨기면 use 참조가 가리키는 원본도 함께 사라지는 SVG의 잘 알려진 제약이
   있어, 대신 항상(화면·인쇄 공통) 0크기 + overflow:hidden으로 시각적으로만 접어 둔다 —
   use 참조 인스턴싱에는 영향이 없다. width/height 속성 자체도 0으로 이미 주므로 여기 CSS
   쪽 0 지정은 이중 안전장치다. */
.qr-def {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* 통합·개명 시도의 옛 이름 병기(2026-08-05) — h1 바로 아래의 보조 설명 줄. */
.former-names {
  margin: -0.5rem 0 1rem;
  color: var(--muted);
  font-size: 0.9rem;
}

/* 가이드 링크 목록(홈·건물 상세·가이드 색인 공용, 2026-09-09). */
.guide-links {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.5rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr));
}

.guide-links li a {
  display: block;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--fg);
  text-decoration: none;
  line-height: 1.5;
}

.guide-links li a:hover {
  border-color: var(--accent, var(--fg));
}

.guide-links li .guide-card {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.guide-card img {
  flex: 0 0 auto;
  width: clamp(4.5rem, 12vw, 7.5rem);
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: 4px;
}

.guide-card-text {
  min-width: 0;
  overflow-wrap: anywhere;
}

.guide-links .guide-desc {
  display: block;
  margin-top: 0.2rem;
  color: var(--muted, #6b7280);
  font-size: 0.85rem;
}

/* 미리보기 표시(2026-09-10). dev에서만 나타나는 예약·초안 라벨과 상단 배너. */
.guide-badge {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  background: #f59e0b;
  color: #1f1300;
  font-size: 0.72rem;
  font-weight: 600;
  vertical-align: middle;
}

.guide-preview-banner {
  margin: 0.5rem 0 0;
  padding: 0.5rem 0.8rem;
  border-radius: var(--radius);
  background: #fef3c7;
  color: #78350f;
  font-size: 0.85rem;
}

.guide-meta {
  margin: 0 0 1.25rem;
  color: var(--muted, #6b7280);
  font-size: 0.85rem;
}

.doc-page h3 {
  margin: 1.4rem 0 0.4rem;
  font-size: 1rem;
}

.doc-page table {
  width: 100%;
  margin: 0.75rem 0 1rem;
  border-collapse: collapse;
  font-size: 0.92rem;
}

.doc-page th,
.doc-page td {
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border);
  text-align: left;
  vertical-align: top;
}

.doc-page th {
  background: var(--surface);
}

.doc-page blockquote {
  margin: 0.75rem 0;
  padding: 0.5rem 0.9rem;
  border-left: 3px solid var(--border);
  color: var(--muted, #6b7280);
}

.doc-page ol {
  padding-left: 1.3rem;
}

.doc-page .table-wrap {
  overflow-x: auto;
}

/* 가이드 본문 사진(2026-09-09). 자체 호스팅(public/guide/img)이고 width/height를 박아 CLS를
   막는다. 캡션에는 Wikimedia Commons 출처·작가·라이선스를 적는다 — CC BY 계열은 표기가
   의무다. 사진은 본문 폭에 맞추고 세로로 너무 길어지지 않게 비율을 제한한다. */
.doc-page figure {
  margin: 1.25rem 0 1.5rem;
}

.doc-page figure img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 28rem;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface);
}

.doc-page figcaption {
  margin-top: 0.4rem;
  color: var(--muted, #6b7280);
  font-size: 0.8rem;
  line-height: 1.5;
}

.doc-page figcaption a {
  color: inherit;
}

.detail-summary {
  margin: 1rem 0;
  padding: 0.6rem 0.8rem;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border);
  font-size: 0.9rem;
  color: var(--muted);
}

/* Address Line 2 래퍼(data-unit-eng-row) 안의 행은 래퍼의 유일한 자식이라 :last-child
   규칙(카드 마지막 행 밑줄 제거)에 잘못 걸린다 — 뒤에 City/Province/ZIP이 더 오는 행이므로
   구분선을 되살린다(2026-08-18). */
[data-unit-eng-row] .address-row:last-child {
  border-bottom: 1px solid var(--border);
}

/* 상세주소(동·호) 입력 + 전체 복사(2026-08-19) — 주소 카드 바로 아래 한 줄. */
.unit-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.75rem 0;
}

.unit-label {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 0.85rem;
}

.unit-input {
  flex: 1;
  min-width: 0;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--fg);
}

.unit-row .btn {
  flex-shrink: 0;
  white-space: nowrap;
}

.address-variants {
  margin: 1.5rem 0;
}

/* 데스크톱 정보 밀도: 건물 상세 주소 항목을 ≥1024px에서 2열로 배치해 1080p
   화면에서 핵심 정보가 스크롤 없이 들어오게 한다. 모바일은 세로 스택 그대로다. */
.detail-grid {
  display: flex;
  flex-direction: column;
}

/* 모바일 세로 스택에서는 그룹(왼쪽 열) 끝에서도 구분선을 유지한다 — 데스크톱
   2열에서는 각 열의 마지막 행이라 구분선이 없어야 한다(.address-row:last-child 기본값). */
.detail-grid > .detail-col:first-child .address-row:last-child {
  border-bottom: 1px solid var(--border);
}

@media (min-width: 1024px) {
  .detail-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 2rem;
    align-items: start;
  }

  .detail-grid > .detail-col:first-child .address-row:last-child {
    border-bottom: none;
  }
}

/* 이 도로의 인접 주소(2026-09-07). 건물번호를 앞세운 조밀한 목록이다 — 사람은 번호로
   훑고, 크롤러는 도로를 따라 옆 건물로 이어 간다. 번호 열은 자릿수가 들쭉날쭉해도 주소가
   같은 x에서 시작하도록 고정폭을 준다. */
.neighbor-card {
  padding: 0.5rem 1rem 0.75rem;
}

.neighbor-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.neighbor-list > li + li {
  border-top: 1px solid var(--border);
}

.neighbor-list a {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.5rem 0;
  color: inherit;
  text-decoration: none;
}

.neighbor-list a:hover .neighbor-address,
.neighbor-list a:focus-visible .neighbor-address {
  text-decoration: underline;
}

.neighbor-address {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.neighbor-jibun {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 0.9rem;
}

.neighbor-name {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 0.85rem;
}

.neighbor-more {
  display: inline-block;
  margin-top: 0.6rem;
  color: var(--muted);
  font-size: 0.9rem;
}

@media (max-width: 480px) {
  .neighbor-list a {
    flex-wrap: wrap;
    gap: 0 0.5rem;
  }

  .neighbor-name {
    flex: 1 0 100%;
  }
}

.address-variants h2 {
  font-size: 1rem;
  margin-bottom: 0.4rem;
}

/* 검색 가능한 주소 변형은 SSR HTML에 그대로 두되 한 단계 접어 모바일 길이를 줄인다. */
.variants-details {
  border: 0;
}

.variants-details > summary {
  padding: 0.75rem 0;
  color: var(--muted);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}

.variants-details[open] > summary {
  color: var(--fg);
}

.variants-details .detail-grid {
  padding-bottom: 0.4rem;
}

/* /api 문서 페이지 */
.api-endpoint {
  margin: 0 0 1.5rem;
  padding: 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.api-endpoint h3 {
  margin: 0 0 0.5rem;
  font-size: 1rem;
}

.api-method {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  margin-right: 0.4rem;
  border-radius: 4px;
  font-size: 0.75rem;
  font-weight: 700;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  background: var(--accent);
  color: var(--accent-fg);
}

.api-endpoint p {
  color: var(--muted);
  margin: 0.4rem 0;
}

pre.code-block {
  margin: 0.5rem 0;
  padding: 0.75rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--bg);
  overflow-x: auto;
  font-size: 0.8rem;
  line-height: 1.5;
}

pre.code-block code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  white-space: pre;
}

.api-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
  margin: 0.5rem 0 1rem;
}

.api-table th,
.api-table td {
  text-align: left;
  padding: 0.4rem 0.6rem;
  border-bottom: 1px solid var(--border);
}

.api-table th {
  color: var(--muted);
  font-weight: 600;
}

/* 푸터는 이제 최하단 고정 바만 담는다(2026-08-05: API 링크 제거). 고정 배치는 .footer-bar가
   가지므로 푸터 자신은 자리를 차지하지 않게 비워 둔다. */
.site-footer {
  margin: 0;
}

/* 모든 화면에서 한 줄로 유지하고, 넘치는 항목은 가로로 스크롤해 확인한다. */
.footer-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10;
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: safe center;
  gap: 0.6rem;
  padding: 0.6rem 1rem calc(0.6rem + env(safe-area-inset-bottom, 0px));
  overflow-x: auto;
  white-space: nowrap;
  background: var(--bg);
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.72rem;
  line-height: 1.15;
  text-align: center;
}

.footer-bar > * {
  flex-shrink: 0;
}

.visit-counter-compact {
  display: none;
  color: var(--muted);
}

/* hidden(=display:none)이 그대로 먹도록 display를 지정하지 않는다 — 지정하면 UA의
   [hidden] 규칙을 이겨버려 JS가 값을 채우기 전에도 빈 텍스트가 보인다. 크기는 문의/메일과
   통일한다(2026-08-15 요구) — 푸터 안에서 항목마다 글자 크기가 다르지 않게. */
.visit-counter,
.data-date {
  color: var(--muted);
  font-size: 0.72rem;
}

/* 고정 바와 가로 스크롤바가 마지막 콘텐츠를 가리지 않도록 여백을 확보한다. */
body {
  padding-bottom: calc(3rem + env(safe-area-inset-bottom, 0px));
}

/* 데이터 기준일(2026-08-05) — 서버가 meta.loaded_at으로 채우므로 JS 없이도 항상 보인다.
   고정된 방문자 카운터 바로 위에 놓이는 문서 흐름상의 마지막 줄이다. */
.data-date {
  margin: 0;
  padding: 0;
  text-align: center;
  color: var(--muted);
  font-size: 0.72rem;
}

/* 택배 송장용 인쇄 뷰(2026-08-04 추가): 화면에서는 항상 숨기고 인쇄할 때만 보여준다. */
.print-only {
  display: none;
}

@media print {
  .site-header,
  .site-footer,
  .breadcrumb,
  .map-links,
  .share-row,
  .qr-details,
  .toast,
  .btn,
  /* 상세 페이지 화면 전용 본문(2026-08-04 보강): 위 개별 셀렉터는 다른 페이지(지역·읍면동
     목록 등)에도 쓰이는 범용 규칙이라 그대로 두고, 이 상세 페이지 전용 래퍼(국문/영문 주소
     2열 그리드·주소 변형 등 — breadcrumb·map-links·share-row·qr-details도 이 안에 있어
     사실상 이중으로 걸리지만 해가 되지 않는다)만 추가로 숨긴다 — 안 그러면 인쇄 결과에
     .print-only 요약과 화면용 본문이 겹쳐 찍힌다. */
  .screen-only {
    display: none !important;
  }

  .print-only {
    display: block;
  }

  .print-road {
    font-size: 1.5rem;
    font-weight: 700;
    margin: 0 0 0.5rem;
  }

  .print-zip {
    font-size: 1.1rem;
    margin: 0 0 0.5rem;
  }

  .print-eng {
    color: #333333;
    margin: 0 0 1rem;
  }

  .print-qr {
    display: block;
  }
}

/* 검색 제출 버튼(2026-08-05): 라벨 대신 돋보기 아이콘이라 정사각에 가깝게 둔다 —
   글자 버튼과 같은 좌우 패딩을 쓰면 아이콘 옆이 휑하다. */
.search-submit {
  padding: 0.5rem 0.65rem;
  line-height: 0;
}

.search-form-compact .search-submit {
  padding: 0.4rem 0.5rem;
}

/* 본문 최상단 검색창(2026-08-05: 헤더 안에서 본문으로 이동). 헤더에 넣었을 때는 영어 표기의
   시도 링크가 폭을 다 먹어 입력창이 짜부라졌다 — 본문으로 내리면 컨테이너 폭을 온전히 쓴다.
   아래 콘텐츠(breadcrumb 등)와의 간격만 주고 컨테이너 자체 여백은 그대로 쓴다. */
.page-search {
  padding-top: 1rem;
  padding-bottom: 0;
}

/* 푸터 연락처(2026-08-05, 2026-08-15 재수정: 2줄 스택이 눈에 너무 넓어 다시 한 줄로 합치고
   글자를 줄였다). 고정 바 안의 다른 항목과 같은 톤으로 두되, 링크임이 보이도록 호버에서만
   강조색으로 바꾼다 — 상시 파란 링크로 두면 카운터·기준일보다 시선을 먼저 끈다. */
.footer-mail {
  color: var(--muted);
  font-size: 0.72rem;
  text-decoration: none;
}

.footer-mail:hover,
.footer-mail:focus-visible {
  color: var(--accent);
  text-decoration: underline;
}

/* 문의 라벨 — 메일 주소 바로 앞, padding-right로만 간격을 준다(gap 대신 요청받은 대로). */
.footer-mail-label {
  color: var(--muted);
  font-size: 0.72rem;
  padding-right: 0.35rem;
}

.footer-contact {
  display: flex;
  align-items: baseline;
}

/* 문의와 데이터 기준일을 한 줄로 묶는다(2026-08-15 요구). */
.footer-secondary {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
}

/* 모바일에서는 기존 축약 방문자 표기를 유지한다. */
@media (max-width: 40rem) {
  .footer-bar {
    padding: 0.6rem 0.5rem calc(0.6rem + env(safe-area-inset-bottom, 0px));
    font-size: 0.62rem;
  }

  .footer-bar .visit-counter {
    display: none !important;
  }

  .footer-bar .visit-counter-compact:not([hidden]) {
    display: inline;
  }

  /* visit-counter-compact는 자기 font-size가 없어 .footer-bar에서 물려받지만, 아래 셋은
     각자 명시적 font-size가 있어 상속으로 안 줄어든다 — 여기서 같이 맞춰준다. */
  .data-date,
  .data-date-label,
  .footer-mail,
  .footer-mail-label {
    font-size: 0.62rem;
  }
}

/* ------------------------------------------------------------------------- *
 * 큰 마우스 커서(2026-08-19 요구): 화면이 목록·카드 위주라 포인터를 잃기 쉽다 — 기본
 * 커서를 38px 화살표(흰 몸통 + 검정 테두리, 라이트/다크 공통 가시성)로 키우고, 클릭 가능
 * 요소에서는 몸통만 강조색으로 바뀐다(2026-08-18 확정). 두 상태 모두 같은 path·같은 검정
 * 테두리·같은 핫스팟이라 실루엣이 완전히 동일하다 — 처음 버전은 파란 변형에 흰 테두리를
 * 써서 밝은 배경에서 테두리가 녹아 커서가 작아 보이는 문제가 있었다.
 * 텍스트 입력(I빔)·QR 확대(zoom-in/out) 커서는 브라우저 기본을 그대로 둔다.
 * url() 커서를 지원하지 않는 환경은 뒤의 폴백 키워드(default/pointer)로 동작한다.
 * ------------------------------------------------------------------------- */
html {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='38' height='38' viewBox='0 0 24 24'%3E%3Cpath d='M5 2v17.2l4.6-4.5 3 6.5 2.7-1.3-3-6.4h6.5z' fill='white' stroke='black' stroke-width='1.3' stroke-linejoin='round'/%3E%3C/svg%3E") 8 3, default;
}

/* 우리 CSS에서 cursor:pointer를 선언한 클래스들을 전부 나열해 뒤에서 덮는다(같은
   특이도면 나중 규칙이 이긴다). 새로 pointer를 쓰는 요소가 생기면 여기에도 추가한다. */
a,
button,
summary,
label,
select,
input[type='checkbox'],
.btn,
.address-row .value,
.recent-chip,
.select-check,
.select-field,
.multi-address-card,
.theme-switch,
.road-group summary,
.qr-details summary {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='38' height='38' viewBox='0 0 24 24'%3E%3Cpath d='M5 2v17.2l4.6-4.5 3 6.5 2.7-1.3-3-6.4h6.5z' fill='%232563eb' stroke='black' stroke-width='1.3' stroke-linejoin='round'/%3E%3C/svg%3E") 8 3, pointer;
}

/* 다크 모드에서는 #2563eb가 어두운 배경에 묻힌다(2026-08-18 피드백) — 사이트의 다크
   강조색(#60a5fa, --accent)으로 몸통만 바꾼다. path·크기·검정 테두리·핫스팟은 라이트와
   동일해 테마가 바뀌어도 실루엣은 그대로다. cursor url은 CSS 변수를 못 쓰므로 테마 삼중
   상태(system dark / 명시 dark / 명시 light)를 규칙 복제로 처리한다 — 명시 light는
   :not 가드로 걸러져 위 기본 규칙이 남는다. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) a,
  :root:not([data-theme='light']) button,
  :root:not([data-theme='light']) summary,
  :root:not([data-theme='light']) label,
  :root:not([data-theme='light']) select,
  :root:not([data-theme='light']) input[type='checkbox'],
  :root:not([data-theme='light']) .btn,
  :root:not([data-theme='light']) .address-row .value,
  :root:not([data-theme='light']) .recent-chip,
  :root:not([data-theme='light']) .select-check,
  :root:not([data-theme='light']) .select-field,
  :root:not([data-theme='light']) .multi-address-card,
  :root:not([data-theme='light']) .theme-switch,
  :root:not([data-theme='light']) .road-group summary,
  :root:not([data-theme='light']) .qr-details summary {
    cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='38' height='38' viewBox='0 0 24 24'%3E%3Cpath d='M5 2v17.2l4.6-4.5 3 6.5 2.7-1.3-3-6.4h6.5z' fill='%2360a5fa' stroke='black' stroke-width='1.3' stroke-linejoin='round'/%3E%3C/svg%3E") 8 3, pointer;
  }
}

:root[data-theme='dark'] a,
:root[data-theme='dark'] button,
:root[data-theme='dark'] summary,
:root[data-theme='dark'] label,
:root[data-theme='dark'] select,
:root[data-theme='dark'] input[type='checkbox'],
:root[data-theme='dark'] .btn,
:root[data-theme='dark'] .address-row .value,
:root[data-theme='dark'] .recent-chip,
:root[data-theme='dark'] .select-check,
:root[data-theme='dark'] .select-field,
:root[data-theme='dark'] .multi-address-card,
:root[data-theme='dark'] .theme-switch,
:root[data-theme='dark'] .road-group summary,
:root[data-theme='dark'] .qr-details summary {
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='38' height='38' viewBox='0 0 24 24'%3E%3Cpath d='M5 2v17.2l4.6-4.5 3 6.5 2.7-1.3-3-6.4h6.5z' fill='%2360a5fa' stroke='black' stroke-width='1.3' stroke-linejoin='round'/%3E%3C/svg%3E") 8 3, pointer;
}

/* 소개·개인정보·가이드도 공통 콘텐츠 폭을 사용한다. */
.doc-page {
  max-width: none;
}

/* 가이드 목록과 글은 주소 검색과 같은 반응형 본문 너비를 쓴다. */
.doc-page.guide-page {
  max-width: none;
}

.guide-layout > article {
  min-width: 0;
}

.guide-page .guide-prose img {
  display: block;
  width: 50%;
  max-width: 100%;
  height: auto;
  margin: 1.25rem auto;
  border-radius: var(--radius);
}

@media (max-width: 40rem) {
  .guide-page .guide-prose img {
    width: 100%;
  }
}

.guide-layout article :is(h2, h3)[id] {
  scroll-margin-top: 8rem;
}

.guide-toc {
  margin: 1rem 0;
  padding: 0.75rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.guide-toc summary {
  cursor: pointer;
  font-weight: 600;
}

.guide-toc ol {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0;
}

.guide-toc a {
  display: block;
  padding: 0.25rem 0;
  color: var(--muted);
  font-size: 0.85rem;
  text-decoration: none;
  overflow-wrap: anywhere;
}

.guide-toc a:hover,
.guide-toc a:focus-visible {
  color: var(--accent);
  text-decoration: underline;
}

.guide-toc-subheading {
  padding-left: 1rem;
}

/* 가이드 목차는 본문 안의 별도 열에 배치해 화면 밖으로 나가지 않게 한다. */
@media (min-width: 1280px) {
  .guide-layout-with-toc {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 14rem;
    gap: 1.5rem;
    align-items: start;
  }

  .guide-layout-with-toc > article {
    grid-column: 1;
    grid-row: 1;
  }

  .guide-toc {
    grid-column: 2;
    grid-row: 1;
    position: sticky;
    top: 8rem;
    max-height: calc(100dvh - 15rem);
    overflow-y: auto;
    margin-top: 0.5rem;
    margin-left: 0;
    width: auto;
    padding: 0.75rem;
  }
}

.doc-page h1 {
  margin: 0.5rem 0 0.25rem;
  font-size: 1.6rem;
}

.doc-page h2 {
  margin: 2rem 0 0.6rem;
  font-size: 1.1rem;
}

.doc-page p,
.doc-page li {
  line-height: 1.7;
}

.doc-page ul {
  padding-left: 1.2rem;
}

.doc-page li {
  margin-bottom: 0.4rem;
}

.doc-page code {
  padding: 0.1rem 0.35rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  font-size: 0.9em;
  word-break: break-all;
}

/* 최종 수정일 등 본문이 아닌 메타 줄. */
.doc-meta {
  color: var(--muted);
  font-size: 0.85rem;
}

/* 소개·개인정보처리방침 링크는 전 페이지 공통인 고정 바에 둔다. */
.footer-links {
  display: flex;
  gap: 0.6rem;
}

.footer-links a {
  color: var(--muted);
  font-size: 0.72rem;
}

@media (max-width: 40rem) {
  .footer-links a {
    font-size: 0.62rem;
  }
}

/* ------------------------------------------------------------------------- *
 * AdSense 디스플레이 슬롯(2026-08-29). 설계 의도는 src/components/AdSlot.astro 참고.
 *
 * 여기서 지키는 것은 두 가지다.
 *  1) 레이아웃이 밀리지 않는다. 광고는 스크립트가 늦게 채우므로 자리를 미리 잡아 두지
 *     않으면 본문이 통째로 아래로 뛴다 — 이 사이트는 CLS 0.773을 낸 이력이 있다
 *     (astro.config.mjs 참고). min-height로 공간을 예약하고 contain:layout으로 슬롯 안의
 *     변화가 바깥 레이아웃 계산에 새지 않게 막는다.
 *  2) 본문을 가리지 않는다. 하단 고정 바(anchor)·전면 광고(vignette)를 쓰지 않고, 넓은
 *     화면에서만 여백으로 빠진다.
 * ------------------------------------------------------------------------- */
.ad-slot {
  display: block;
  margin: 2rem 0;
  min-height: 280px;
  contain: layout;
  text-align: center;
}

/* "광고" 표기는 구글이 허용하는 문구이자 이용자에게 콘텐츠와 광고를 구분해 주는 최소 장치다.
   광고보다 크거나 눈에 띄면 안 되므로 본문 중 가장 작은 글자·흐린 색으로 둔다. */
.ad-slot-label {
  display: block;
  margin-bottom: 0.3rem;
  color: var(--muted);
  font-size: 0.68rem;
  letter-spacing: 0.03em;
  text-align: left;
}

/* 광고도 본문 흐름 안에 두어 넓어진 콘텐츠를 덮지 않게 한다. */

/* 인쇄(택배 송장 등)에는 광고를 내보내지 않는다. */
@media print {
  .ad-slot {
    display: none;
  }
}
/* Bus directory extensions. Shared foundation comes from juso/kr. */
.directory h2{font-size:1.1rem;margin:1.75rem 0 .65rem}.directory h1{font-size:1.5rem;margin:.5rem 0}.directory .hero{padding-top:.25rem}.terminal-list{display:grid;gap:.5rem}.terminal-list>a{display:flex;justify-content:space-between;gap:1rem;padding:.85rem 1rem;border:1px solid var(--border);border-radius:var(--radius);color:var(--fg);text-decoration:none}.terminal-list>a:hover,.sido-list a:hover{border-color:var(--accent)}.terminal-list span,.subtext,.directory-notice,.small-label,.search-tips,.sources{color:var(--muted);font-size:.875rem}.directory-notice{margin:1rem 0}.breadcrumb{font-size:.85rem;color:var(--muted);margin:.75rem 0 1.25rem}.directory table{margin:1rem 0}footer{margin:2rem var(--page-gutter) 0;border-top:1px solid var(--border);padding:1rem 0;color:var(--muted);font-size:.75rem}footer p{margin:.25rem 0}body{padding-bottom:1rem}main{min-width:0}.route-hero{padding-top:.75rem}.route-hero .search{display:flex;align-items:end;gap:.75rem}.search label{flex:1;min-width:0}.search label>span{display:block;color:var(--muted);font-size:.8rem;margin-bottom:.35rem}input,select{border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);color:var(--fg);padding:.6rem .8rem;font:inherit}.search input{width:100%;min-width:0}button{font:inherit;color:var(--fg);border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);padding:.5rem .75rem}.search-button{background:var(--accent);color:var(--accent-fg);border-color:var(--accent);white-space:nowrap;padding:.65rem 1rem}.quick{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-top:.8rem;font-size:.8rem;color:var(--muted)}.quick button{font-size:.8rem}.quick-note{margin-left:auto}.layout{display:grid;grid-template-columns:minmax(0,1fr) 17rem;gap:2rem}.primary{min-width:0}.title-row,.schedule-heading,.section-heading,.toolbar{display:flex;justify-content:space-between;gap:1rem;align-items:center}.title-row h2{font-size:1.7rem;margin:.25rem 0}.title-row p{margin:0}.icon-button{font-size:1.4rem}.stats{display:grid;grid-template-columns:repeat(4,1fr);margin:1.25rem 0;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface)}.stats>div{padding:1rem}.stats>div+div{border-left:1px solid var(--border)}.stats>div>span{display:block;font-size:.8rem;color:var(--muted)}.stats strong{display:block;font-size:1.35rem;margin-top:.25rem;font-variant-numeric:tabular-nums}.stats strong span{font-size:.8rem;margin-left:.2rem}.schedule-heading h3,.section-heading h3{font-size:1.1rem}.schedule-heading h3 span{font-size:.85rem;color:var(--accent)}.schedule-heading button{font-size:.8rem}.toolbar{margin:.5rem 0 1rem}.filters{display:flex;gap:.35rem;flex-wrap:wrap}.filters button{font-size:.85rem}.filters .selected{background:var(--accent);color:var(--accent-fg);border-color:var(--accent)}select{font-size:.8rem}.table-wrap{overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius)}table{width:100%;border-collapse:collapse;font-size:.9rem}th,td{text-align:left;padding:.85rem 1rem;border-bottom:1px solid var(--border);white-space:nowrap}th{font-size:.8rem;font-weight:500;color:var(--muted);background:var(--surface)}tr:last-child td{border-bottom:0}td:first-child{font-weight:600;font-variant-numeric:tabular-nums}.badge{font-size:.8rem;color:var(--accent)}.badge.premium{font-weight:600}.next-day{display:block;font-size:.7rem;color:var(--muted)}.data-note{display:flex;gap:.6rem;background:var(--surface);padding:.75rem 1rem;border-radius:var(--radius);margin-top:1rem;color:var(--muted);font-size:.85rem}.data-note p{margin:0}.data-note small{font-size:.75rem}.sources{margin:.6rem 0}.sources a{margin-left:.5rem}.terminal-section,#guide{margin-top:2rem}.section-heading span{font-size:.8rem;color:var(--muted)}.terminal-grid{display:grid;grid-template-columns:1fr 1fr;gap:.75rem}.terminal-grid article,.booking-card,.aside-card{border:1px solid var(--border);border-radius:var(--radius);padding:1rem}.terminal-tag{font-size:.75rem;color:var(--muted)}.terminal-grid h4{margin:.5rem 0}.terminal-grid p,.terminal-grid a{font-size:.85rem}.terminal-grid p{color:var(--muted)}details{border-bottom:1px solid var(--border);padding:.85rem 0;font-size:.9rem}summary{font-weight:500}details p{color:var(--muted)}aside{padding-top:1.8rem}.booking-card{background:var(--surface)}.booking-card h3{font-size:1.1rem}.booking-card p,.booking-card small{font-size:.8rem;color:var(--muted)}.booking-card>a{display:flex;justify-content:space-between;padding:.65rem .8rem;border:1px solid var(--border);border-radius:var(--radius);text-decoration:none;margin:.5rem 0;font-size:.85rem}.booking-card .booking-primary{background:var(--accent);color:var(--accent-fg);border-color:var(--accent)}.booking-card small{display:block;margin-top:.75rem}.aside-icon{color:var(--accent)}.aside-card{margin-top:1rem}.aside-card h3{font-size:.95rem;margin-top:0}.aside-card>a{display:flex;justify-content:space-between;padding:.65rem 0;text-decoration:none;font-size:.8rem;border-top:1px solid var(--border)}.aside-card small{display:block;color:var(--muted);margin-top:.2rem}.empty{padding:1.5rem 1rem;background:var(--surface);color:var(--muted);font-size:.9rem}.empty[hidden]{display:none}dialog{max-width:calc(100% - 2rem);width:28rem;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);color:var(--fg);padding:1.25rem}dialog::backdrop{background:#0006}.dialog-heading{display:flex;align-items:center;justify-content:space-between}.dialog-heading h3{margin:.25rem 0 1rem}#saved-content button{margin:.3rem 0}#toast{position:fixed;bottom:1.5rem;left:50%;transform:translateX(-50%);background:var(--fg);color:var(--bg);padding:.7rem 1rem;border-radius:var(--radius);opacity:0;pointer-events:none;max-width:calc(100% - 2rem);font-size:.85rem;z-index:50}#toast.visible{opacity:1}:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
@media(max-width:1000px){.layout{grid-template-columns:minmax(0,1fr)}aside{display:grid;grid-template-columns:1fr 1fr;gap:1rem;padding-top:0}.aside-card{margin:0}}
@media(max-width:639px){.route-hero .search{display:grid;grid-template-columns:minmax(0,1fr) 2.7rem;align-items:end}.search label{grid-column:1}.search label:nth-of-type(2){grid-row:2}.search .swap{grid-column:2;grid-row:1/3;align-self:center}.search-button{grid-column:1/3}.quick-note{display:none}.terminal-list>a{flex-direction:column;gap:.25rem}.stats{grid-template-columns:1fr 1fr}.stats>div{padding:.75rem}.stats>div:nth-child(3){border-left:0;border-top:1px solid var(--border)}.stats>div:nth-child(4){border-top:1px solid var(--border)}.toolbar{align-items:start;flex-direction:column;gap:.6rem}.filters button{padding:.4rem .6rem}th,td{padding:.7rem .6rem;font-size:.8rem}.terminal-grid,aside{grid-template-columns:1fr}.title-row h2{font-size:1.45rem}.sources a{display:inline-block}.section-heading{align-items:start;gap:.5rem;flex-direction:column}.section-heading h3{margin-bottom:0}}
.directory-tabs,.directory-pagination{display:flex;align-items:center;flex-wrap:wrap;gap:.6rem;margin:1rem 0}.directory-tabs>a{border:1px solid var(--border);border-radius:var(--radius);padding:.5rem .75rem;text-decoration:none;font-size:.875rem}.directory-tabs>a:hover{border-color:var(--accent)}.directory-pagination{justify-content:space-between;font-size:.85rem;color:var(--muted)}.directory-pagination button:disabled{opacity:.4;cursor:default}.terminal-list>a{overflow-wrap:anywhere}.directory table td{white-space:normal}.directory table td p{max-width:60rem}

/* 참고 시간표는 홈의 .hero 여백 초기화와 분리해 본문과 정렬한다. */
.reference-route .route-hero.container {
  padding: 1rem var(--page-gutter);
}

.reference-route .hero h1 {
  font-size: clamp(1.25rem, 2.5vw, 1.75rem);
  overflow-wrap: anywhere;
}

.reference-route .search {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 2.75rem minmax(0, 1fr) auto;
  gap: .75rem;
  align-items: end;
}

.reference-route .search > label {
  min-width: 0;
  grid-column: auto;
  grid-row: auto;
}

.reference-route .search input,
.reference-route .search button {
  min-height: 2.75rem;
}

.reference-route .search input {
  font-size: 1rem;
}

.reference-route .search .swap,
.reference-route .search-button {
  grid-column: auto;
  grid-row: auto;
}

.reference-route .search .swap {
  width: 2.75rem;
  padding: .5rem;
}

.reference-route .layout {
  grid-template-columns: minmax(0, 1fr) 17rem;
  gap: clamp(1rem, 2vw, 2rem);
}

.reference-route .layout > aside {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  gap: 1rem;
  min-width: 0;
}

.reference-route .aside-card {
  margin: 0;
}

.reference-route .title-row > div,
.reference-route .data-note p,
.reference-route .terminal-grid > article {
  min-width: 0;
  overflow-wrap: anywhere;
}

.reference-route .title-row .icon-button,
.reference-route .data-note > span {
  flex-shrink: 0;
}

.reference-route .schedule-heading {
  flex-wrap: wrap;
  gap: .5rem;
}

.reference-route .table-wrap {
  max-width: 100%;
}

.reference-route .table-wrap table {
  min-width: 32rem;
}

@media (max-width: 1100px) {
  .reference-route .layout {
    grid-template-columns: minmax(0, 1fr);
  }

  .reference-route .layout > aside {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    padding-top: 0;
  }
}

@media (max-width: 759px) {
  .reference-route .search {
    grid-template-columns: minmax(0, 1fr) 2.75rem;
  }

  .reference-route .search > label {
    grid-column: 1;
  }

  .reference-route .search > label:nth-of-type(2) {
    grid-row: 2;
  }

  .reference-route .search .swap {
    grid-column: 2;
    grid-row: 1 / 3;
    align-self: center;
    transform: rotate(90deg);
  }

  .reference-route .search-button {
    grid-column: 1 / -1;
  }

  .reference-route .quick-note {
    display: none;
  }
}

@media (max-width: 639px) {
  .reference-route .layout > aside {
    grid-template-columns: minmax(0, 1fr);
  }

  .reference-route .stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .reference-route .title-row {
    align-items: flex-start;
    gap: .5rem;
  }
}

/* 모든 페이지에 공통으로 보이는 고정 하단 바. */
body { padding-bottom: 4.25rem; }
.site-footer { margin: 0; padding: 0; border: 0; }
.site-footer .footer-bar {
  position: fixed; inset: auto 0 0; z-index: 30;
  display: flex; align-items: center; justify-content: safe center; gap: 1.25rem;
  overflow-x: auto; white-space: nowrap;
  padding: .8rem 1rem calc(.8rem + env(safe-area-inset-bottom, 0px));
  background: var(--bg); border-top: 1px solid var(--border);
  color: var(--muted); font-size: .75rem;
}
.site-footer .footer-bar > * { flex-shrink: 0; }
.site-footer .footer-bar a { color: var(--muted); text-decoration: none; }
.site-footer .footer-bar a:hover { color: var(--accent); }
.site-footer .visitor-count strong { color: var(--fg); font-variant-numeric: tabular-nums; }
@media (max-width: 700px) {
  .site-footer .footer-bar { justify-content: flex-start; gap: .9rem; font-size: .7rem; }
}
