:root {
  /* 카카오맵 노선 상세 팔레트 — apk 자산에서 추출한 색 매칭. */
  --blue: #2E7DFC;          /* 카카오 액션 파랑 (주변정류장 칩 / 운행중 텍스트) */
  --blue-dark: #1862D6;
  --blue-soft: #E8F1FF;     /* 액션 칩 옅은 파랑 */
  --teal: #00C7B7;          /* 일반(GENERAL) 등급 배지 청록 */
  --teal-soft: #DFF8F4;
  --seat-blue: #2E7DFC;     /* 좌석(SEAT) 등급 파랑 (composite_15 의 색) */
  --seat-blue-soft: #E8F1FF;
  --text: #1A1A1A;
  --text-2: #3B3F47;
  --muted: #8B9098;
  --line: #E5E8EC;
  --line-soft: #F1F3F5;
  --bg: #ffffff;
  --bg-soft: #f5f7fa;
  --green: #00B679;         /* 카카오 원활 (green segment) */
  --yellow: #F5A524;
  --red: #E63950;
  --night: #5b3fb1;
  --night-soft: #ede7f6;
  --shadow: 0 1px 3px rgba(15, 23, 42, 0.05), 0 1px 2px rgba(15, 23, 42, 0.04);
  --shadow-card: 0 2px 8px rgba(15, 23, 42, 0.06);
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }

html, body { background: var(--bg); }

/* 카카오맵 노선 상세는 사용자 휴대폰 시스템 폰트를 그대로 사용 (One UI 의
   삼성 폰트 / iOS 의 Apple SD Gothic Neo / Roboto 등). Pretendard 같은 별도
   웹폰트 우선 지정 안 함 → 모바일 디바이스의 기본 한글 폰트 자연 적용. */
body {
  font-family: -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo",
               "Samsung Sans", "SamsungOne", "Helvetica Neue",
               "Noto Sans KR", Roboto, "Malgun Gothic", sans-serif;
  color: var(--text);
  min-height: 100dvh;
  font-size: 15px;
  letter-spacing: -0.2px;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

button { font-family: inherit; cursor: pointer; }
a { color: inherit; text-decoration: none; }

#app { min-height: 100dvh; display: flex; flex-direction: column; }

/* ---------- app header (카카오 노선 상세: 좌 뒤로, 우 지도) ---------- */
.app-header {
  display: flex; align-items: center; gap: 2px;
  padding: 0 2px;
  height: 44px;
  background: #fff;
}
.app-header .spacer { flex: 1; }
.app-header .header-title {
  font-size: 16px;
  font-weight: 700;
  color: #2b2f33;
  letter-spacing: -0.2px;
}

.icon-btn {
  width: 40px; height: 40px;
  border: 0; background: transparent;
  border-radius: 50%;
  font-size: 22px; color: #2b2f33;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
}
.icon-btn:active { background: #eef2f5; }
.icon-btn img { display: block; }

/* ---------- HOME ---------- */
.home {
  background: var(--bg-soft);
  min-height: 100dvh;
}

.home-hero {
  background: linear-gradient(135deg, #1976d2 0%, #0d47a1 100%);
  color: #fff;
  padding: 16px 20px 20px;
  position: relative;
}
.home-settings-btn {
  position: absolute;
  top: 14px;
  right: 12px;
  width: 40px;
  height: 40px;
  border: 0;
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s;
}
.home-settings-btn:hover { background: rgba(255, 255, 255, 0.26); }
.home-settings-btn:active { background: rgba(255, 255, 255, 0.32); }
.home-settings-btn svg { display: block; }

/* ---------- SETTINGS PAGE ---------- */
.settings-page {
  background: var(--bg-soft);
  min-height: 100dvh;
}
.settings-page .home-bus-settings {
  margin-top: 16px;
}
.home-title {
  font-size: 28px; font-weight: 800; letter-spacing: 0.06em;
  padding-right: 48px;
}
.home-admin-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 6px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  border-radius: 4px;
  vertical-align: middle;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  cursor: pointer;
}
/* on: 빨간 배지 표시. off: 같은 영역 그대로 두되 보이지 않게 — 레이아웃이
   토글 전후로 동일하고, 같은 위치에서 3초 long-press 로 다시 활성화 가능. */
.home-admin-badge.on {
  color: #fff;
  background: #e63950;
}
.home-admin-badge.off {
  color: transparent;
  background: transparent;
}
.home-sub {
  font-size: 12px; opacity: 0.85; margin-top: 4px;
}

.home-search {
  margin: 12px 16px 0;
  background: #fff;
  border-radius: 14px;
  padding: 12px 14px;
  box-shadow: var(--shadow);
  display: flex; align-items: center; gap: 10px;
}
.home-search input {
  flex: 1; border: 0; outline: 0; font-size: 15px;
  background: transparent;
  color: var(--text);
}
.home-search .ic { color: var(--muted); font-size: 16px; }

.search-results {
  margin: 8px 16px 0;
  background: #fff;
  border-radius: 14px;
  box-shadow: var(--shadow);
  overflow: hidden;
  max-height: 60vh; overflow-y: auto;
}
.search-item {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 12px 14px;
  background: #fff;
  border: 0; border-bottom: 1px solid var(--line-soft);
  text-align: left;
}
.search-item:last-child { border-bottom: 0; }
.search-item:active { background: var(--bg-soft); }
.search-num {
  font-size: 17px; font-weight: 500; color: var(--text);
  letter-spacing: -0.3px;
  flex: 1 1 0; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.search-empty { padding: 16px; text-align: center; color: var(--muted); font-size: 13px; }

.home-section {
  padding: 28px 18px 8px;
  font-size: 12px;
  color: var(--muted);
  font-weight: 600;
  letter-spacing: 0.4px;
}

.map-card {
  margin: 0 16px 8px;
  background: #fff;
  border-radius: 14px;
  padding: 16px 18px;
  display: flex; align-items: center; justify-content: space-between;
  box-shadow: var(--shadow);
  border: 0;
  width: calc(100% - 32px);
  text-align: left;
}
.map-card-name { font-size: 17px; font-weight: 600; }
.map-card-meta { font-size: 12px; color: var(--muted); margin-top: 4px; }
.map-card .chev { color: #c3ccd6; font-size: 24px; }

.home-empty {
  margin: 20px 16px;
  background: #fff;
  border-radius: 14px;
  padding: 24px;
  text-align: center;
  color: var(--muted);
  line-height: 1.6;
  box-shadow: var(--shadow);
}

.home-status {
  padding: 16px 16px 28px;
  font-size: 12px;
  color: var(--muted);
  text-align: center;
}
.home-status .dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: #c3ccd6; vertical-align: middle; margin-right: 6px;
}
.home-status .dot.live { background: var(--green); }

.home-bus-settings {
  margin: 0 16px 16px;
  background: #fff;
  border-radius: 14px;
  border: 1px solid var(--line);
  padding: 12px;
}
.home-bus-settings .title {
  font-size: 14px;
  font-weight: 700;
  margin-bottom: 10px;
}
.home-bus-settings .row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}
.home-bus-settings .row label {
  width: 56px;
  font-size: 12px;
  color: var(--muted);
}
.home-bus-settings .row input,
.home-bus-settings .row select {
  flex: 1;
  min-width: 0;
  border: 1px solid #d8dde5;
  border-radius: 8px;
  padding: 7px 9px;
  font-size: 13px;
}
.home-bus-settings .row .unit {
  color: var(--muted);
  font-size: 12px;
}
.home-bus-settings .row input.lowfloor-check {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 0;
  padding: 0;
  border: 1px solid #d8dde5;
  border-radius: 4px;
  cursor: pointer;
  accent-color: var(--blue);
}
/* 체크박스 row 는 label 폭 고정 (56px) 을 풀어주고 한 줄 nowrap. 안 풀면
   "ANCC 활성화" 같은 긴 라벨이 두 줄로 깨짐. */
.home-bus-settings .row.row-check label {
  width: auto;
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  color: var(--text);
  font-size: 13px;
}
.home-bus-settings .bus-settings-hint {
  margin: 0 16px 12px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
}
.home-bus-settings .save {
  width: 100%;
  border: 0;
  background: #1d5cff;
  color: #fff;
  border-radius: 10px;
  padding: 9px 0;
  font-weight: 700;
}

/* ---------- LINE LIST ---------- */
.list-page { background: var(--bg-soft); min-height: 100dvh; }
.list-title { padding: 4px 20px 14px; }
.list-title .main { font-size: 22px; font-weight: 700; }
.list-title .sub  { font-size: 12px; color: var(--muted); margin-top: 4px; }

.line-group { padding: 0 16px 24px; display: flex; flex-direction: column; gap: 8px; }

/* 메인 노선 목록 카드 — 카카오맵의 노선 검색 결과 / 즐겨찾기 카드 매칭.
   배지 PNG 가 노선번호 좌측에 위치, 카드 자체는 흰 배경 + 미세 그림자. */
.line-card {
  background: #fff;
  border-radius: 14px;
  padding: 14px 16px;
  display: flex; align-items: center; gap: 12px;
  box-shadow: var(--shadow);
  border: 0; text-align: left;
  width: 100%;
}
.line-card:active { background: var(--bg-soft); }
.line-card .badge-png,
.line-card .line-badge {
  align-self: center;
}
.line-card .badge-png {
  transform: translateY(1px);
}
.line-badge {
  flex-shrink: 0;
  min-width: 44px; height: 24px; padding: 0 9px;
  border-radius: 999px;
  font-size: 11px; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
/* 카카오맵 배지 — 일반은 청록, 좌석은 파랑, 간선/마을은 파랑, 심야는 보라.
   apk 의 route_bus_GENERAL_composite (청록) / route_bus_SEAT_composite (파랑) 색
   과 일치시킴. 사진의 "일반" 배지 = 청록. */
.badge-trunk  { background: var(--blue-soft); color: var(--blue); }
.badge-night  { background: var(--night-soft); color: var(--night); }
.badge-local  { background: #e6f4ea; color: #2e7d32; }
.badge-normal { background: var(--teal-soft); color: var(--teal); }
.badge-seat   { background: var(--seat-blue-soft); color: var(--seat-blue); }

/* 카카오 APK 의 h_15_ico_bus_* PNG 배지 (예: "일반"/"좌석"/"마을"). xxxhdpi
   원본은 ~60px 폭, 카카오맵 앱은 15dp(=45px @ xxxhdpi) 높이로 표시. 화면에선
   18px(라인 카드/노선번호 헤더) ~ 20px(상세 hero) 높이로 렌더 → 폭은 auto.
   align-self: flex-start 로 큰 노선번호 옆에서 위쪽 정렬. */
.badge-png {
  display: inline-block;
  height: 16px;
  width: auto;
  flex-shrink: 0;
  vertical-align: middle;
  image-rendering: -webkit-optimize-contrast;
}
.badge-png-lg {
  /* 카카오버스 매칭: "일반" 같은 등급 배지가 노선번호 옆에 자리잡되 너무 크지
     않도록. 노선번호 30px 의 약 절반 (15px) 정도가 카카오 사진 비율.
     margin-top 은 배지가 숫자 한가운데 (=숫자 세로 중심) 와 비슷한 높이에
     걸리도록 — 12px → 8px 로 4px 위로. */
  height: 15px;
  align-self: flex-start;
  margin-top: 9px;
}

.line-num {
  font-size: 17px; font-weight: 500; letter-spacing: -0.3px;
  flex: 1 1 0; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  line-height: 1.15;
}

.line-dir {
  flex-shrink: 0;
  font-size: 10px; color: var(--muted);
  background: var(--line-soft); border-radius: 6px;
  padding: 3px 7px;
  font-weight: 600;
}

/* ---------- ROUTE DETAIL ---------- */
.route-page {
  background: #fff;
  min-height: 100dvh;
}
.route-head { padding: 0 4px 12px; }
.route-head-top {
  display: flex; align-items: center;
}
.route-head-top .icon-btn { width: 40px; flex: none; }
/* spacer 는 좌측 뒤로가기와 우측 지도 사이의 여백. sticky-line(중앙 노선번호)
   이 위에 절대 위치로 떠있고 spacer 가 그 공간 채움. */
.route-head-top .spacer { flex: 1; }
.route-head-top.sticky-top {
  position: sticky;
  top: 0;
  z-index: 10;
  background: #fff;
  height: 44px;
  padding: 0 2px;
  box-sizing: border-box;
  /* align-items: center 이 .icon-btn 같은 형제 요소에 적용되어 데스크탑/모바일
     렌더링 차이가 줄어든다. */
  display: flex;
  align-items: center;
}
.route-head-top .sticky-line {
  /* transform 기반 중앙 정렬 — 부모 flex baseline 이 데스크탑/모바일 다르게
     계산되는 문제 회피. top:50% + translateY 로 정확한 픽셀 센터링. */
  position: absolute;
  left: 42px; right: 42px;
  top: 50%;
  transform: translateY(-50%);
  display: flex; align-items: center; justify-content: center; gap: 6px;
  line-height: 1;
  opacity: 0;
  transition: opacity 0.15s;
  pointer-events: none;
}
.route-head-top .sticky-line .badge-png,
.route-head-top .sticky-line .badge,
.route-head-top .sticky-line .num {
  /* baseline 차이 제거 — img / span 이 한 줄에 자연스럽게 정렬. */
  vertical-align: middle;
  display: inline-flex;
  align-items: center;
  line-height: 1;
}
.route-head-top .sticky-line .badge {
  font-size: 11px; font-weight: 500;
  padding: 3px 9px; border-radius: 999px;
}
.route-head-top .sticky-line .badge-png { height: 14px; }
.route-head-top .sticky-line .num {
  /* 카카오 sticky 헤더 — 얇은 숫자체 + 1px 위로 살짝. */
  font-size: 16px; font-weight: 500; letter-spacing: -0.3px;
  position: relative;
  top: -1px;
}
.route-page.scrolled .route-head-top .sticky-line { opacity: 1; }

.route-head-body { padding: 4px 18px 10px; }
.route-line-row {
  display: flex; align-items: baseline; gap: 10px;
}
.route-line-row .badge {
  font-size: 12px; font-weight: 700;
  padding: 4px 10px; border-radius: 999px;
}
.route-line-row .num {
  font-size: 32px; font-weight: 800; letter-spacing: -1px;
  line-height: 1;
}
.route-line-row .sub {
  font-size: 17px; color: var(--text); font-weight: 600;
}
.route-head-body .where {
  font-size: 13px; color: #333; margin-top: 10px; line-height: 1.5;
}
.route-head-body .when {
  font-size: 11px; color: var(--muted); margin-top: 4px;
}

/* ---------- KAKAO-STYLE ROUTE HERO ---------- */
.route-head.kakao { background: #fff; }
/* 카카오맵 노선 상세 타이틀 블록 (축소된 크기). 사용자 피드백 반영:
   기존이 너무 컸음. 카카오 앱 정확 매칭 위해 폰트/패딩 줄임.
   - "일반" 배지 PNG (18px) 노선번호 위쪽 정렬
   - 노선번호: 30px (사진의 101 매칭, 적절히 큼)
   - 메타 13px / 시간 12px */
.route-hero {
  padding: 4px 18px 6px;
}
.route-hero .line-row {
  display: flex; align-items: baseline; gap: 8px;
  flex-wrap: wrap;
}
.route-hero .line-row .badge {
  /* 텍스트 등급 배지 (asset 없을 때 폴백) — PNG 배지(15px) 와 시각적으로 비슷한
     높이가 되도록 축소. */
  font-size: 10.5px; font-weight: 700;
  padding: 2px 8px; border-radius: 999px;
  flex-shrink: 0;
  line-height: 1.4;
  align-self: flex-start;
  margin-top: 12px;
}
.route-hero .line-row .num-big {
  /* 카카오 "101" 비율 매칭 (사이즈/굵기). */
  font-size: 30px; font-weight: 500; letter-spacing: -0.35px;
  line-height: 1.05;
  color: var(--text);
  font-feature-settings: "tnum" 1;
}
.route-hero .line-row .sub-cat {
  font-size: 16px; color: var(--text); font-weight: 500;
}
.route-hero .where-line {
  font-size: 13px; color: var(--text-2);
  margin-top: 2px;
  line-height: 1.45;
  letter-spacing: -0.2px;
}
.route-hero .time-line {
  font-size: 12px; color: var(--muted);
  margin-top: 1px;
  letter-spacing: -0.2px;
}

/* 카카오맵 노선 상세 액션 행:
   [내 버스] 파란 둥근 칩 (이전 "주변 정류장" 자리)
   [북마크/공유/시간] 회색 원형 버튼 3 개
   사진 매칭: 파란 칩 + 회색 원형 3 개, 우측 정렬은 안 함 (좌측 정렬 후 자연 배치). */
.route-actions {
  display: flex; gap: 6px; align-items: center;
  padding: 6px 16px 8px;
  flex-wrap: nowrap;
}
/* 카카오맵 매칭: 칩 + 동그라미 모두 옅은 파랑 톤 시리즈. 칩 높이를 동그라미
   (36px) 와 동일하게 맞춰서 통일감. */
.pill-action {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--blue-soft); color: var(--blue);
  border: 0; border-radius: 999px;
  padding: 0 14px 0 11px;
  height: 36px;
  font-size: 13px; font-weight: 600;
  white-space: nowrap;
  letter-spacing: -0.2px;
}
/* 카카오맵 매칭: 옅은 파랑 칩이라 버스 아이콘은 진한 파랑 단색.
   CSS mask 로 PNG 알파만 추출 + background-color 파랑. */
.pill-action .ic-bus {
  width: 16px; height: 16px;
  background-color: var(--blue);
  -webkit-mask: url("/static/assets/ico_on_bus.png") no-repeat center/contain;
  mask: url("/static/assets/ico_on_bus.png") no-repeat center/contain;
  flex-shrink: 0;
}
.pill-action .lbl { line-height: 1; }
.pill-action:active { filter: brightness(0.92); }

/* 카카오맵: 북마크/공유/시간 원형 버튼 — 옅은 파랑 배경 + 파란 아이콘. */
.action-circle {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--blue-soft);
  color: var(--blue);
  border: 0;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.action-circle .ico-svg { display: inline-flex; line-height: 0; }
/* 액션 동그라미 안 아이콘 — span + CSS mask + background-color 로 정확한
   카카오 파랑 단색. img + filter 는 hue-rotate 미세 색 시프트로 카카오와
   살짝 다르게 나오던 문제 해결. 3 개 동일 19px 비율 (시계도 동일). */
.action-circle .ico-mask {
  display: block;
  width: 19px; height: 19px;
  background-color: var(--blue);
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: center;
  -webkit-mask-size: contain;
  mask-repeat: no-repeat;
  mask-position: center;
  mask-size: contain;
}
.action-circle .ico-bookmark {
  -webkit-mask-image: url("/static/assets/ic_bookmark2.png");
  mask-image: url("/static/assets/ic_bookmark2.png");
}
.action-circle .ico-share {
  -webkit-mask-image: url("/static/assets/share.png");
  mask-image: url("/static/assets/share.png");
}
.action-circle .ico-time {
  -webkit-mask-image: url("/static/assets/ic_time.png");
  mask-image: url("/static/assets/ic_time.png");
}
.action-circle:active { background: #D7E5FE; }

/* 공용 PNG 아이콘 — 카카오 APK 자산 매칭. width/height 클래스로 사이즈 지정. */
.ico-png {
  display: inline-block;
  vertical-align: middle;
  image-rendering: -webkit-optimize-contrast;
}
.ico-png-16 { width: 16px; height: 16px; }
.ico-png-18 { width: 18px; height: 18px; }
.ico-png-20 { width: 20px; height: 20px; }
.ico-png-22 { width: 22px; height: 22px; }
.ico-png-24 { width: 24px; height: 24px; }

/* PNG 톤변환 — 파랑/검정/흰색. */
.ico-tint-blue {
  filter: brightness(0) saturate(100%) invert(38%) sepia(98%) saturate(2200%)
          hue-rotate(208deg) brightness(101%) contrast(98%);
}
.ico-tint-black {
  filter: brightness(0) saturate(100%);
}
.ico-tint-white {
  filter: brightness(0) invert(1);
}

/* 카카오맵 노선 상세 상태 행:
   좌: "노선정보 ›" 검정 텍스트
   우: "N대 운행중" 파란 텍스트 + 파란 원형 새로고침 (작게) */
.route-substatus {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 16px;
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 44px;
  z-index: 9;
  background: #fff;
}
.route-substatus .left,
.route-substatus .route-info-link {
  font-size: 13px;
  color: var(--text);
  font-weight: 600;
  border: 0;
  background: transparent;
  padding: 0;
  cursor: pointer;
  text-align: left;
  letter-spacing: -0.2px;
}
.route-substatus .left .chev,
.route-substatus .route-info-link .chev {
  color: var(--muted);
  font-weight: 400;
}
.route-substatus .route-info-link:active { opacity: 0.65; }
/* 카카오 사진 매칭:
   - "현재 운행 중인 버스 없음" → 옅은 회색 13px (사진 3)
   - "9대 운행중" → 진한 파랑 #2D77FA 13px (사진 4) */
.route-substatus .right {
  display: flex; align-items: center; gap: 4px;
  font-size: 13px; color: var(--muted);
  letter-spacing: -0.2px;
  transform: translateY(-1px);
}
.route-substatus .right .live {
  display: inline-flex;
  align-items: baseline;
  gap: 0;
  font-weight: 400;
  letter-spacing: -0.2px;
  line-height: 1;
}
.route-substatus .right .live-count {
  color: #111;
  font-weight: 600;
}
.route-substatus .right .live-label {
  color: var(--muted);
  font-weight: 400;
}
/* 카카오 사진 매칭: 텍스트 옆 작은 회전 아이콘 (검정). */
.route-substatus .substatus-refresh {
  width: 26px;
  height: 26px;
  margin-left: 1px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: #1A1A1A;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  cursor: pointer;
}
.route-substatus .substatus-refresh:active { background: #F1F3F5; }
.route-substatus .substatus-refresh svg { display: block; }
.route-substatus .substatus-refresh .substatus-refresh-icon {
  display: block;
  width: 20px; height: 20px;
  transform: translateY(-1px);
  background-color: #1A1A1A;
  -webkit-mask: url("/static/assets/ic_refresh3.png") no-repeat center/contain;
  mask: url("/static/assets/ic_refresh3.png") no-repeat center/contain;
}

/* ---------- ROUTE INFO (Kakao Bus style) ---------- */
.route-info-page {
  background: #fff;
  min-height: 100dvh;
  font-family: "Pretendard", -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Malgun Gothic", sans-serif;
  letter-spacing: -0.02em;
  color: #222;
}
.route-info-header {
  display: flex;
  align-items: center;
  height: 44px;
  padding: 0 2px;
  border-bottom: 1px solid #ededed;
  background: #fff;
  position: sticky;
  top: 0;
  z-index: 10;
}
.route-info-header .icon-btn {
  width: 40px;
  height: 40px;
  font-size: 24px;
  color: #222;
}
.route-info-title {
  flex: 1;
  margin: 0;
  padding-right: 40px;
  text-align: center;
  font-size: 16px;
  font-weight: 600;
  color: #000;
  letter-spacing: -0.03em;
}
.route-info-content {
  padding: 0 0 16px;
}
.route-info-block {
  padding: 16px 16px;
  border-bottom: 1px solid #ededed;
}
.route-info-h {
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: 700;
  color: #000;
  letter-spacing: -0.03em;
}
.route-info-body { margin: 0; }
.route-info-main {
  margin: 0;
  font-size: 13px;
  font-weight: 400;
  line-height: 20px;
  color: #222;
  letter-spacing: -0.02em;
}
.route-info-sub {
  margin: 4px 0 0;
  font-size: 12px;
  font-weight: 400;
  line-height: 17px;
  color: #999;
}
.route-info-time {
  margin: 0;
  font-size: 0;
  line-height: 20px;
  color: #222;
}
.route-info-time .pill-tag {
  display: inline-block;
  margin-right: 5px;
  padding: 2px 5px;
  border-radius: 3px;
  background: #f3f3f3;
  color: #666;
  font-size: 10px;
  font-weight: 500;
  line-height: 13px;
  vertical-align: middle;
  letter-spacing: -0.01em;
}
.route-info-time-text {
  font-size: 13px;
  font-weight: 400;
  line-height: 20px;
  letter-spacing: -0.02em;
  vertical-align: middle;
}
.route-info-major {
  margin: 0;
  font-size: 13px;
  font-weight: 400;
  line-height: 20px;
  color: #222;
  word-break: keep-all;
  letter-spacing: -0.02em;
}
.route-info-empty {
  padding: 48px 20px;
  text-align: center;
  color: #999;
  font-size: 13px;
  line-height: 20px;
}
.route-info-footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 24px 0 40px;
}
.route-info-top {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid #e0e0e0;
  background: #fff;
  color: #bbb;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: none;
}
.route-info-top:active { background: #fafafa; }
.route-info-top svg { display: block; width: 16px; height: 16px; }
.route-info-suggest {
  border: 0;
  background: transparent;
  color: #999;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: -0.02em;
  padding: 2px 6px;
  cursor: pointer;
}
.route-info-suggest:active { color: #777; }

/* ---------- TIMELINE (kakao-bus style — per-stop connectors) ---------- */
.timeline-wrap {
  padding: 4px 0 80px;
  position: relative;
  background: #fff;
}
.timeline {
  position: relative;
  padding: 4px 16px 4px 16px;
  isolation: isolate;
}

.stop {
  position: relative;
  /* 모든 정류장 행은 정확히 같은 높이.
     align-items: stretch 라서 .stop-main 이 풀높이로 깔리고, 그 안에서
     name 은 dot 위, ID 는 dot 중앙 근처에 absolute 배치. */
  height: 77px;
  box-sizing: border-box;
  padding-left: 96px;
  display: flex; align-items: stretch;
  z-index: 1;
}

/* 카카오맵 segment 선 — 4px 굵기. dot 중앙(=row 50%) 에서 만남. */
.stop::before {
  content: "";
  position: absolute;
  left: 68px;
  transform: translateX(-50%);
  top: 0;
  height: 50%;
  width: 4px;
  background: #F5A623;
}
.stop::after {
  content: "";
  position: absolute;
  left: 68px;
  transform: translateX(-50%);
  top: 50%;
  bottom: 0;
  width: 4px;
  background: #F5A623;
}
.stop.first::before { content: none; }
.stop.last::after  { content: none; }

/* 카카오맵 차량교통량 색: 노랑(서행) 기본 / 초록(원활) / 빨강(정체). */
.stop.up-green::before   { background: #1DAA67; }
.stop.down-green::after  { background: #1DAA67; }
.stop.up-red::before     { background: #E63950; }
.stop.down-red::after    { background: #E63950; }
.stop.up-yellow::before  { background: #F5A623; }
.stop.down-yellow::after { background: #F5A623; }

/* 카카오맵 정류장 dot — 흰 배경 + 회색 테두리 + 카카오 ⌄ PNG.
   사용자 피드백: 동그라미 크기 더 줄임 (15 → 13px). */
.stop-dot {
  position: absolute;
  left: 68px; top: 50%;
  transform: translate(-50%, -50%);
  width: 13px; height: 13px;
  background: #fff;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #4A4F58;
  border: 1px solid #A0A6AE;
  z-index: 3;
}
.stop-dot .stop-dot-arrow {
  width: 7px; height: auto;
  display: block;
  image-rendering: -webkit-optimize-contrast;
}
.stop-dot .stop-dot-inner { line-height: 0; display: flex; }
.stop-dot .stop-dot-inner svg { display: block; }

.stop-dot.first,
.stop-dot.last {
  border-color: #A0A6AE;
  background: #fff;
  color: #4A4F58;
  width: 13px; height: 13px;
}
/* 진행 표시는 동그라미가 아닌 동그라미 사이의 선(::before/::after)에만 칠한다.
   정류장 dot는 항상 기본 모양을 유지. */

.stop-main {
  flex: 1; min-width: 0;
  position: relative;
  padding: 0;
}
.stop-main::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 8px;
  height: 1px;
  background: var(--line-soft);
}
.stop.last .stop-main::after { content: none; }

/* turnaround-point: 회차점은 일반 dot 없이 [↻ 회차] 알약만 표시. */
/* 회차 정류장 — 카카오 사진 매칭: 작은 흰 캡슐 + 옅은 회색 외곽선 + 회색
   "회차" 텍스트 + ↪ 아이콘. ic_return.png 통째로 표시하되 사이즈 축소. */
.stop.turnaround-point { height: 81px; }
.stop.turnaround-point .stop-dot { display: none; }
.stop.turnaround-hint { height: 81px; }
.stop.turnaround-hint .stop-dot { display: none; }
.stop.turnaround-point .turn-pill-img {
  position: absolute;
  /* 카카오 사진 매칭: 회차 캡슐의 우측 ↻ 아이콘이 타임라인 노란 선 위에
     걸쳐 보이도록 배치. */
  left: 68px;
  top: 50%;
  transform: translate(calc(-100% + 12px), -50%);
  height: 18px;
  width: auto;
  z-index: 3;
  image-rendering: -webkit-optimize-contrast;
}
.stop.turnaround-hint .turn-pill-img {
  position: absolute;
  left: 68px;
  top: 50%;
  transform: translate(calc(-100% + 12px), -50%);
  height: 18px;
  width: auto;
  z-index: 3;
  image-rendering: -webkit-optimize-contrast;
}
/* 카카오맵 정류장 행 — 이름은 dot 위, ID 는 dot 중앙에 수직 정렬.
   둘 다 absolute 배치라서 행마다 줄 높이가 흔들리지 않음. */
.stop-name {
  position: absolute;
  left: 0; right: 0;
  bottom: calc(50% + 10px);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.2;
  color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  letter-spacing: -0.3px;
}
.stop-line2 {
  position: absolute;
  left: 0; right: 0;
  /* ID 의 맨 위쪽이 dot 중앙보다 4px 위 (이전 2px 에서 추가로 2px 더 올림). */
  top: calc(50% - 4px);
  font-size: 12px;
  line-height: 1.2;
  color: var(--muted);
  letter-spacing: -0.2px;
}
.stop-id {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* bus marker placed by JS, top is dot-aligned.
   We anchor a 0x0 box on the timeline line (which is rendered at left: 68px
   *inside* .stop, and .stop itself is offset by 16px due to .timeline's
   padding-left). Since .bus-on-track is positioned against .timeline's
   padding-box, we add that 16px here: 68 + 16 = 84px. */
.bus-on-track {
  position: absolute;
  left: 84px;
  top: 0;
  width: 0;
  height: 0;
  /* 카카오버스처럼 정류장-단계 사이를 순간이동으로 점프(부드러운 보간 X).
     transition 을 끄면 segmentFraction 의 양자화 단계가 바뀌는 순간 차량
     아이콘이 즉시 다음 위치로 점프한다. */
  z-index: 30;
  pointer-events: none;
}
.bus-label {
  background: #f1f4f7;
  border: 1px solid #e1e6ec;
  border-radius: 10px;
  padding: 4px 10px;
  font-size: 11px;
  color: #333;
  font-weight: 600;
  white-space: nowrap;
  display: flex; flex-direction: column; align-items: center;
  line-height: 1.15;
  box-shadow: 0 1px 3px rgba(0,0,0,.06);
}
.bus-label .lab-id { font-size: 11px; color: var(--blue); font-weight: 700; }
.bus-label .lab-state { font-size: 9px; color: var(--muted); margin-top: 1px; }
.bus-icon-track {
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--blue);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px;
  box-shadow: 0 2px 6px rgba(25,118,210,.4);
  margin-left: -2px;
}

/* Speech bubble — drawn entirely by an inline SVG (.bg) injected via JS.
   We only need positioning + padding (which reserves room for bubble caps
   and tail). The SVG path is generated AFTER the label is measured so it's
   pixel-perfect regardless of text content. */
.bus-label.kakao-like {
  position: absolute;
  top: 0;
  /* Place label so its tail tip aligns just left of the icon. */
  right: 11px;
  transform: translateY(-50%);
  /* No CSS background / border / radius — the SVG handles all of that. */
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  /* Padding: left = inside of left corner, right = inside of right corner
     + tail. Top/bottom give vertical breathing room. */
  padding: 3px 9px 3px 5px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 1px;
  line-height: 1;
  white-space: nowrap;
  font-family: "Apple SD Gothic Neo", "Malgun Gothic", "맑은 고딕",
               -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "Noto Sans KR", sans-serif;
  font-feature-settings: "tnum" 1;
  filter: drop-shadow(0 1px 1.5px rgba(0,0,0,.05));
}
.bus-label.kakao-like .lab-row-top {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  gap: 4px;
  position: relative;
  z-index: 1;
}
.bus-label.kakao-like .lab-row-bot {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  justify-content: center;
  position: relative;
  z-index: 1;
  margin-top: 1px;
}
.bus-label.kakao-like .lab-low {
  color: #6f757d;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: -0.2px;
}
/* The injected SVG fills the label exactly so it draws under the text. */
.bus-label.kakao-like > svg.bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible; /* let the tail extend a hair if needed */
  z-index: 0;
}
.bus-label.kakao-like .lab-id,
.bus-label.kakao-like .lab-state {
  position: relative;
  z-index: 1;
}
.bus-label.kakao-like .lab-id {
  color: #6f757d;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: -0.2px;
}
.bus-label.kakao-like .lab-state {
  margin-top: 0;
  color: #e74837;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: -0.2px;
  white-space: nowrap;
}
.bus-label.kakao-like .lab-inline-low {
  position: relative;
  z-index: 1;
  color: #6f757d;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: -0.2px;
  white-space: nowrap;
}
.bus-label.kakao-like.no-state .lab-state {
  display: none;
}
/* Bus icon — anchored on the 0x0 container, centered horizontally on the
   timeline line and vertically on the JS-provided top. */
.bus-icon-track.kakao-like {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%) scale(1.12);
  width: 18px;
  height: 18px;
  border-radius: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
  margin-left: 0;
}
/* BIS 차량 아이콘 — ARMR 맵은 등급별 색 (주황 일반 / 청록 좌석),
   그 외 맵은 회색 단일 (w_18_ico_bus_symantic_gray_525252). PNG 모두 정사각형. */
.bus-icon-track.kakao-like .ic-bus-img {
  display: block;
  width: 18px;
  height: 18px;
  background-position: center;
  background-repeat: no-repeat;
  background-size: contain;
}
/* ARMR 한정 — 등급별 색 BIS */
.bus-icon-track.kakao-like.armr.normal .ic-bus-img {
  background-image: url("/static/assets/map/ARMR/ARMR_ico_bus_general.png");
}
.bus-icon-track.kakao-like.armr.seat .ic-bus-img {
  background-image: url("/static/assets/map/ARMR/ARMR_ico_bus_Express_City_Bus.png");
}
/* 그 외 맵 — 회색 BIS (등급 무관) */
.bus-icon-track.kakao-like.other-map .ic-bus-img {
  background-image: url("/static/assets/w_18_ico_bus_symantic_gray_525252.png");
}
/* 호환 — 클래스 없이도 기본 회색 */
.bus-icon-track.kakao-like.normal .ic-bus-img,
.bus-icon-track.kakao-like.seat .ic-bus-img {
  background-image: url("/static/assets/w_18_ico_bus_symantic_gray_525252.png");
}
.bus-icon-track.kakao-like.armr.normal .ic-bus-img,
.bus-icon-track.kakao-like.armr.seat .ic-bus-img {
  /* ARMR 분기가 위에서 이미 처리됨 — 위 호환 규칙을 덮어쓰기 위해 명시 */
  background-image: var(--armr-bus-bg);
}
.bus-icon-track.kakao-like.armr.normal .ic-bus-img {
  background-image: url("/static/assets/map/ARMR/ARMR_ico_bus_general.png");
}
.bus-icon-track.kakao-like.armr.seat .ic-bus-img {
  background-image: url("/static/assets/map/ARMR/ARMR_ico_bus_Express_City_Bus.png");
}
/* 직행 / 광역 / 심야 카테고리 (cat.cls === "badge-night") — 맵 무관하게 빨간
   BIS 아이콘. ANCC 493 같은 직행 노선이 ARMR 의 좌석/일반 PNG 대신 빨간색
   PNG 로 표시되도록. specificity 동등하지만 캐스케이드 순서로 .armr.* 와
   .other-map 규칙을 이긴다. */
.bus-icon-track.kakao-like.express .ic-bus-img,
.bus-icon-track.kakao-like.armr.express .ic-bus-img,
.bus-icon-track.kakao-like.other-map.express .ic-bus-img {
  background-image: url("/static/assets/w_18_ico_bus_red_d_92600.png");
}
/* 사용자 차량 종류 (막차 / 2층버스) — 기본 버스 아이콘 대신 합성 PNG 자체를 쓴다.
   PNG 캔버스가 46~48px 로 넓어서 18px contain 으로 축소하면 버스 본체가 작아지고
   중심도 틀어진다. 그래서 PNG 를 조금 더 큰 박스로 렌더하고, 버스 본체 중심이
   타임라인 중앙에 오도록 위/좌표를 따로 보정한다. */
.bus-icon-track.kakao-like.vbody-night .ic-bus-img,
.bus-icon-track.kakao-like.armr.vbody-night .ic-bus-img,
.bus-icon-track.kakao-like.other-map.vbody-night .ic-bus-img,
.bus-icon-track.kakao-like.express.vbody-night .ic-bus-img {
  position: absolute;
  left: 0.5px;
  top: -3px;
  width: 22px;
  height: 22px;
  background-image: url("/static/assets/route_img_bus_night.png");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}
.bus-icon-track.kakao-like.vbody-double .ic-bus-img,
.bus-icon-track.kakao-like.armr.vbody-double .ic-bus-img,
.bus-icon-track.kakao-like.other-map.vbody-double .ic-bus-img,
.bus-icon-track.kakao-like.express.vbody-double .ic-bus-img {
  position: absolute;
  left: 1px;
  top: -3px;
  width: 24px;
  height: 24px;
  background-image: url("/static/assets/route_img_bus_2_f.png");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

.empty-block {
  padding: 60px 24px;
  text-align: center;
  color: var(--muted);
  line-height: 1.6;
}

/* ---------- debug bar + route FAB ---------- */
.debug-bar {
  position: fixed;
  bottom: 16px;
  right: 16px;
  z-index: 50;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
  pointer-events: none;
}
.debug-bar > * { pointer-events: auto; }
body.view-route .route-page { padding-bottom: 96px; }
.debug-toggle {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 0;
  background: #455a64;
  color: #fff;
  font-style: italic;
  font-weight: 700;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
  flex-shrink: 0;
}
/* 카카오맵 우하단 FAB 새로고침 — 작은 흰 원 + 파란 회전 아이콘.
   카카오 비율 (사용자 사진): 아이콘이 원의 약 50% (40px 원 → 20px 아이콘). */
/* 카카오 FAB 새로고침 — 사용자 사진 4 의 비율: 흰 원 약 화면 폭 12%,
   아이콘이 원의 약 48%. */
.route-fab-refresh {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 0;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.13);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  cursor: pointer;
  padding: 0;
}
.route-fab-refresh:active { background: #f5f8fc; }
.route-fab-refresh .fab-refresh-icon {
  display: block;
  width: 21px; height: 21px;
  background-color: var(--blue);
  -webkit-mask: url("/static/assets/ic_refresh3.png") no-repeat center/contain;
  mask: url("/static/assets/ic_refresh3.png") no-repeat center/contain;
}
body:not(.view-route) .route-fab-refresh { display: none !important; }
.debug-content {
  position: absolute;
  bottom: calc(100% + 8px);
  right: 0;
  background: rgba(33,33,33,.92); color: #eceff1;
  padding: 10px 12px; font: 11px/1.4 ui-monospace, Menlo, monospace;
  border-radius: 8px; white-space: pre;
  min-width: 240px; max-width: 80vw;
  box-shadow: 0 4px 14px rgba(0,0,0,.3);
}

/* ---------- OBIS modal (어드민 활성화 / 비번 변경) ---------- */
.obis-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.45);
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.obis-modal-card {
  width: 100%;
  max-width: 320px;
  background: #fff;
  border-radius: 14px;
  padding: 18px 18px 14px;
  box-shadow: 0 12px 28px rgba(15, 23, 42, 0.22);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.obis-modal-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
}
.obis-modal-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.obis-modal-field label {
  font-size: 12px;
  color: var(--muted);
}
.obis-modal-field input[type="password"],
.obis-modal-field input[type="text"] {
  width: 100%;
  border: 1px solid #d8dde5;
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 14px;
  background: #fff;
}
.obis-modal-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 0;
  border-top: 1px solid var(--line-soft);
  margin-top: 4px;
  padding-top: 10px;
}
.obis-modal-row label {
  font-size: 13px;
  color: var(--text);
  font-weight: 600;
}
.obis-modal-row input[type="checkbox"] {
  width: 18px;
  height: 18px;
  cursor: pointer;
  accent-color: var(--blue);
}
.obis-modal-actions {
  display: flex;
  gap: 8px;
  margin-top: 6px;
}
.obis-modal-btn {
  flex: 1;
  border: 0;
  border-radius: 10px;
  padding: 10px 0;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.obis-modal-btn.cancel {
  background: #f1f3f5;
  color: var(--text-2);
}
.obis-modal-btn.confirm {
  background: #1d5cff;
  color: #fff;
}
.admin-settings .save {
  background: #455a64;
}
