/* 관측소 — 틀. 상단 바, 지도 위에 떠 있는 것들, 오른쪽 판(레일), 입력창, 좁은 화면의 탭 바, 로그인.
   화면별 부품(대화·단지·찜·지역·그래프)은 css/*.css, 토큰과 낱개는 base.css.

   배치.
   - 넓은 화면(1101px~): 지도가 바닥 전체. 오른쪽에 흰 판 하나가 16px 띄워 떠 있다(반지름 22, 옅은 그림자).
     지표 칩·범례·시간줄·지도 단추는 판을 피해 지도 위에 떠 있다. 판 왼쪽 가장자리를 끌어 폭을 바꾼다.
   - 태블릿(761~1100px): 지도 위, 판 아래로 쌓는다. 판은 떠 있지 않다.
   - 좁은 화면(~760px): 탭 바 앱. 지도·지역·단지·찜·AI 다섯 칸. 판은 화면을 다 쓰고, 손잡이는 없다.
     지도를 눌렀을 때만 아래에 미리보기 카드가 떠서, 누르면 다 펼친다. */

:root {
  --rail-w: var(--panel-w); /* app.js 가 끌어서 바꾸는 값 */
  --panel-inset: 16px; /* 판이 화면 가장자리에서 떨어진 거리 — app.js 도 읽는다 */
  --gutter: var(--s-16); /* 판 안 좌우 여백 — 머리·몸통·지역·대화가 모두 이 값(좁은 화면 12px) */
  --map-right: calc(
    var(--rail-w) + var(--panel-inset) * 2
  ); /* 지도 위 물건이 피해야 할 오른쪽 폭 */
  --glass: rgba(255, 255, 255, 0.92);
}

/* ══ 상단 바 ═══════════════════════════════════════════════════════════════ */
.topbar {
  position: relative;
  z-index: 5;
  flex: 0 0 var(--top-h);
  display: flex;
  align-items: center;
  gap: var(--s-16);
  height: var(--top-h);
  padding: 0 var(--s-24);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.brand {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--fs-15);
  font-weight: 500;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.brand-mark {
  flex: none;
  width: 28px;
  height: 28px;
  color: var(--green);
}
.status {
  flex: none;
  margin-left: auto;
  font-size: var(--fs-12);
  color: var(--ink-3);
  white-space: nowrap;
}
.signout {
  flex: none;
  height: 36px;
  padding: 0 var(--s-4);
  border: 0;
  background: none;
  color: var(--ink-2);
  font-size: var(--fs-13);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 4px;
  transition:
    color var(--dur),
    text-decoration-color var(--dur);
}
.signout:hover {
  color: var(--ink);
  text-decoration-color: currentColor;
}

/* 찾기 — 돌빛 알약. 초점이면 흰 바탕에 먹 선 */
.search {
  position: relative;
  flex: 1 1 auto;
  min-width: 160px;
  max-width: 520px;
  margin: 0 auto;
}
.search-ic {
  position: absolute;
  left: 16px;
  top: 50%;
  width: 15px;
  height: 15px;
  margin-top: -7.5px;
  color: var(--ink-3);
  pointer-events: none;
}
.search input {
  width: 100%;
  height: 40px;
  padding: 0 44px 0 42px;
  border: 1px solid transparent;
  border-radius: var(--r-16);
  background: var(--stone);
}
.search input:hover {
  border-color: transparent;
  background: var(--stone-2);
}
.search input:focus {
  background: var(--surface);
  border-color: var(--ink);
}
.search-kbd {
  position: absolute;
  right: 14px;
  top: 50%;
  height: 20px;
  min-width: 20px;
  margin-top: -10px;
  padding: 0 6px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-4);
  background: var(--surface);
  font: 500 11px/18px var(--mono);
  color: var(--ink-3);
  text-align: center;
  pointer-events: none;
}
.search:focus-within .search-kbd {
  display: none;
}
/* 찾기 결과 — 떠 있는 판. 내 조건의 후보 지역 찾기도 같은 것을 쓴다 */
.search-pop {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 30;
  max-height: min(60vh, 440px);
  overflow-y: auto;
  padding: var(--s-6);
  border-radius: var(--r-16);
  background: var(--surface);
  box-shadow: var(--sh-pop);
}
.search-pop [role='option'] {
  display: flex;
  align-items: baseline;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  border: 0;
  border-radius: var(--r-8);
  background: none;
  font-size: var(--fs-14);
  text-align: left;
}
.search-pop [role='option'] b {
  font-weight: 500;
  white-space: nowrap;
}
.search-pop [role='option'] span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-12);
  color: var(--ink-3);
}
.search-pop [role='option']:hover,
.search-pop [role='option']:focus-visible {
  background: var(--stone);
  outline: none;
}
.search-none {
  padding: 10px 12px;
  font-size: var(--fs-13);
  color: var(--ink-3);
}

/* ── 내 조건 — 상단바의 칩. 누르면 아래로 창이 내려온다 ─────────────────── */
.me {
  position: relative;
  flex: 0 1 auto;
  min-width: 0;
}
.me-btn {
  display: flex;
  align-items: center;
  gap: var(--s-8);
  max-width: 340px;
  height: 36px;
  padding: 0 14px 0 12px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  background: var(--surface);
  font-size: var(--fs-13);
  text-align: left;
  transition: border-color var(--dur);
}
.me-btn:hover,
.me-btn[aria-expanded='true'] {
  border-color: var(--ink);
}
.me-ic {
  flex: none;
  width: 15px;
  height: 15px;
  color: var(--ink-2);
}
.me-k {
  flex: none;
  font-weight: 500;
}
.me-v {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink-3);
}
.me.is-set .me-v {
  color: var(--ink);
  font-weight: 500;
}
.me.is-set .me-v::before {
  content: '';
  display: inline-block;
  width: 1px;
  height: 11px;
  margin-right: var(--s-8);
  vertical-align: -1px;
  background: var(--line-2);
}
.me-form {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  z-index: 40;
  width: 420px;
  max-height: calc(100dvh - var(--top-h) - 20px);
  overflow-y: auto;
  overscroll-behavior: contain;
  display: grid;
  gap: var(--s-16);
  padding: var(--s-24) var(--s-24) var(--s-20);
  border-radius: var(--r-16);
  background: var(--surface);
  box-shadow: var(--sh-pop);
}
.me-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.me-head b {
  font-size: var(--fs-20);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -0.02em;
}
.me-head span {
  font-size: var(--fs-13);
  color: var(--ink-3);
}
.me-form label,
.me-lab {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  font-size: var(--fs-13);
  font-weight: 500;
  color: var(--ink-2);
}
.me-form label small,
.me-lab small,
.me-form legend small {
  margin-left: 6px;
  font-size: var(--fs-12);
  font-weight: 400;
  color: var(--ink-3);
}
.me-form fieldset {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}
.me-form legend {
  margin-bottom: var(--s-6);
  padding: 0;
  font-size: var(--fs-13);
  font-weight: 500;
  color: var(--ink-2);
}
.me-form input,
.me-form select {
  width: 100%;
}
.me-regions {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
}
.me-region-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-6);
  font-size: var(--fs-13);
  color: var(--ink-3);
}
.me-region-chips:empty {
  display: none;
}
.me-region-add {
  position: relative;
}
.me-area-row {
  display: flex;
  align-items: center;
  gap: var(--s-8);
}
.me-area-row input {
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
}
.me-area-sep,
.me-area-unit {
  flex: none;
  color: var(--ink-3);
}
.me-area-py {
  flex: none;
  margin-left: auto;
  font-size: var(--fs-12);
  color: var(--ink-3);
}
.me-area-presets {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-6);
  margin-top: var(--s-8);
}
.me-area-presets button {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink-2);
  font-size: var(--fs-13);
  font-weight: 500;
  transition:
    border-color var(--dur),
    background var(--dur),
    color var(--dur);
}
.me-area-presets button small {
  font-size: var(--fs-11);
  font-weight: 400;
  color: var(--ink-3);
}
.me-area-presets button:hover {
  border-color: var(--ink);
  color: var(--ink);
}
.me-area-presets button.is-on {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.me-area-presets button.is-on small {
  color: rgba(255, 255, 255, 0.7);
}
.me-units {
  gap: var(--s-6);
}
/* 땅·건물 세부 — <details>. 요약 줄은 꺾쇠 하나, 켠 조건 수는 먹 배지(옛 .finder-more 와 같은 모양) */
.me-land > summary {
  display: inline-flex;
  align-items: center;
  gap: var(--s-6);
  list-style: none;
  padding: var(--s-4) 0;
  font-size: var(--fs-13);
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  user-select: none;
}
.me-land > summary::-webkit-details-marker {
  display: none;
}
.me-land > summary::after {
  content: '';
  width: 6px;
  height: 6px;
  margin: 0 0 3px 2px;
  border-right: 1.5px solid var(--ink-3);
  border-bottom: 1.5px solid var(--ink-3);
  transform: rotate(45deg);
  transition: transform var(--dur);
}
.me-land[open] > summary::after {
  transform: rotate(-135deg);
  margin-bottom: -2px;
}
.me-land > summary span {
  display: inline-block;
  min-width: 18px;
  padding: 0 5px;
  border-radius: var(--r-pill);
  background: var(--primary);
  color: var(--on-primary);
  font-family: var(--mono);
  font-size: var(--fs-11);
  line-height: 18px;
  text-align: center;
  white-space: nowrap;
}
.me-land > summary span:empty {
  display: none;
}
.me-land-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-6) 10px;
  margin-top: var(--s-8);
}
/* .me-form label 이 세로 쌓기라 base 의 .field·.check 가 깨진다 — 여기서는 가로로 되돌린다 */
.me-land-grid .field {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--s-8);
  min-width: 0;
  font-weight: 400;
}
.me-land-grid .field select {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.me-land-grid .check {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--s-8);
  min-height: 40px;
  font-weight: 400;
  color: var(--ink);
  line-height: 1.4;
}
.me-land-grid .check input {
  flex: none;
  width: 16px;
}
.me-land > .me-note-line {
  margin-top: var(--s-8);
  font-size: var(--fs-12);
  color: var(--ink-3);
}
.me-confirm {
  font-size: var(--fs-12);
}
.me-unit {
  position: relative;
  display: block;
}
.me-unit input {
  padding-right: 68px;
  text-align: right;
}
.me-unit i {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  font-style: normal;
  font-size: var(--fs-12);
  color: var(--ink-3);
  pointer-events: none;
}
.me-check {
  flex-direction: row !important;
  align-items: center;
  gap: var(--s-8) !important;
  min-height: 28px;
  font-weight: 400 !important;
  color: var(--ink) !important;
}
.me-check input {
  width: 16px;
  height: 16px;
}
.me-check.me-confirm {
  color: var(--ink-3) !important;
}
.me-sync {
  font-size: var(--fs-12);
  color: var(--ink-3);
}
.me-actions {
  display: flex;
  gap: var(--s-8);
  padding-top: var(--s-4);
}
.me-actions .btn-send {
  flex: 1;
}

/* ══ 무대 — 지도가 바닥, 판이 떠 있다 ══════════════════════════════════════ */
.stage {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
}
.map-pane {
  position: absolute;
  inset: 0;
  background: var(--stone-3);
}
#map {
  position: absolute;
  inset: 0;
}

/* 지도 위에 떠 있는 것들의 재질 — 흰 유리 */
.pills,
.legend,
.timeline,
.maplibregl-ctrl-group {
  background: var(--glass);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  box-shadow: var(--sh-float);
}

/* ── 지도 위 첫 줄 — 칠할 값 칩 + 더보기 ────────────────────────────────── */
.map-top {
  position: absolute;
  z-index: 3;
  top: var(--s-16);
  left: var(--s-16);
  right: var(--map-right);
  display: flex;
  align-items: flex-start;
  gap: var(--s-8);
  pointer-events: none;
}
.map-top > * {
  pointer-events: auto;
}
.pills {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  border-radius: var(--r-16);
}
.pill,
.layers-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--r-8);
  background: none;
  color: var(--ink-2);
  font-size: var(--fs-13);
  font-weight: 500;
  white-space: nowrap;
  transition:
    background var(--dur),
    color var(--dur);
}
.pill:hover,
.layers-btn:hover,
.layers-btn[aria-expanded='true'] {
  background: var(--stone);
  color: var(--ink);
}
.pill.is-on,
.layers-btn.is-on {
  background: var(--primary);
  color: #fff;
}
.layers {
  position: relative;
  flex: none;
}
.layers-v::after {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  margin: 0 0 3px 7px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  opacity: 0.7;
}
/* 더보기 — 칠할 값·단지 점 색·겹쳐보기 스위치. 넓은 판 */
#layers-pop {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  width: 480px;
  max-height: calc(100dvh - var(--top-h) - 90px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--s-16);
  border-radius: var(--r-16);
  background: var(--surface);
  box-shadow: var(--sh-pop);
}
#layers-pop .field {
  width: 100%;
}
#layers-pop .field select {
  flex: 1;
  width: 100%;
}
#layers-pop .toggle-clean {
  min-height: auto;
  padding: 10px 12px;
  margin-bottom: var(--s-4);
  border-radius: var(--r-8);
  background: var(--stone);
  white-space: normal;
}
.toggle-clean span {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.toggle-clean b {
  font-size: var(--fs-13);
  font-weight: 500;
  color: var(--ink);
}
.toggle-clean small {
  font-size: var(--fs-12);
  color: var(--ink-3);
}
.layers-h {
  margin: var(--s-12) 0 2px;
  padding: 10px 2px 0;
  border-top: 1px solid var(--line-soft);
  font-size: var(--fs-12);
  font-weight: 500;
  color: var(--ink-3);
}
.layers-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 var(--s-4);
}
#layers-pop .toggle {
  width: 100%;
  min-height: 36px;
  padding: 0 10px;
  justify-content: flex-start;
  white-space: normal;
}

/* ── 범례 — 지도 왼쪽 아래, 시간줄 위 ───────────────────────────────────── */
.legend {
  position: absolute;
  z-index: 2;
  left: var(--s-16);
  bottom: calc(var(--timeline-h) + 24px);
  max-width: 340px;
  max-height: calc(100% - var(--timeline-h) - 120px);
  overflow-y: auto;
  padding: 12px 14px;
  border-radius: var(--r-16);
  font-size: var(--fs-12);
}
body.no-timeline .legend {
  bottom: var(--s-16);
  max-height: calc(100% - 120px);
}
.legend-head {
  display: flex;
  align-items: center;
  gap: var(--s-6);
  margin-bottom: 6px;
}
.legend-title {
  font-size: var(--fs-13);
  font-weight: 500;
  white-space: nowrap;
}
.legend-asof {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--ink-3);
  white-space: nowrap;
}
.legend-asof:empty {
  display: none;
}
.legend-more {
  margin-left: auto;
  height: 22px;
  padding: 0 9px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  background: none;
  color: var(--ink-2);
  font-size: var(--fs-11);
  font-weight: 500;
  white-space: nowrap;
}
.legend-more:hover,
.legend-more[aria-expanded='true'] {
  border-color: var(--ink);
  color: var(--ink);
}
.legend-more:not([hidden]) + .legend-why {
  margin-left: 0;
}
.legend-why {
  margin-left: auto;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 1px solid var(--line-2);
  border-radius: 50%;
  background: none;
  color: var(--ink-3);
  font: 500 11px/18px var(--mono);
  transition:
    background var(--dur),
    color var(--dur),
    border-color var(--dur);
}
.legend-why:hover,
.legend.is-open .legend-why {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.legend-ramp {
  display: flex;
  align-items: center;
  gap: var(--s-8);
  min-width: 170px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--ink-3);
}
.legend-ramp .ramp {
  flex: 1;
  height: 6px;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--fall-map), var(--stone), var(--rise-map));
  box-shadow: inset 0 0 0 1px rgba(23, 23, 28, 0.06);
}
/* 수준 지표 — 돌빛에서 깊은 초록으로(map.js SEQ_STOPS 와 같은 다섯 색, 감마 0.85 를 자리로) */
.legend.is-seq .legend-ramp .ramp,
.legend-dots.is-seq .dots-ramp {
  background: linear-gradient(
    90deg,
    var(--map-seq-0) 0%,
    var(--map-seq-1) 20%,
    var(--map-seq-2) 44%,
    var(--map-seq-3) 71%,
    var(--map-seq-4) 100%
  );
}
.legend-hint {
  display: none;
  max-width: 276px;
  margin: 8px 0 0;
  line-height: 1.5;
  color: var(--ink-2);
}
.legend.is-open .legend-hint {
  display: block;
}
.legend.is-min .legend-rel,
.legend.is-min .legend-arrow {
  display: none;
}
.legend.no-fill .legend-ramp,
.legend.no-fill .legend-why,
.legend.no-fill .legend-asof,
.legend.no-fill .legend-hint {
  display: none;
}
.legend.no-fill .legend-head {
  margin-bottom: 0;
}
.legend-rel,
.legend-arrow {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--line-soft);
  color: var(--ink-2);
}
.legend-rel-row,
.legend-arrow {
  display: flex;
  align-items: center;
  gap: var(--s-8);
  min-height: 20px;
  line-height: 1.4;
}
.legend-rel-row + .legend-rel-row {
  margin-top: 4px;
}
.legend-rel-row.dim {
  color: var(--ink-3);
}
.legend-rel svg,
.legend-arrow svg {
  flex: none;
}
.legend-rel svg line,
.legend-arrow svg line {
  stroke: var(--ink-3);
  stroke-width: 1.5;
}
.legend-arrow.mig svg line {
  stroke: var(--teal);
  stroke-width: 2.5;
}
.legend-arrow.mig svg path {
  fill: var(--teal);
}
.vw-sw {
  flex: none;
  width: 14px;
  height: 14px;
  border-radius: var(--r-4);
  opacity: 0.75;
}
.vw-sw-ramp {
  background: linear-gradient(90deg, var(--fall-map), var(--stone), var(--rise-map));
}
.vw-note {
  margin-left: 4px;
}
.dots-ramp {
  flex: none;
  width: 44px;
  height: 8px;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--fall-map), var(--stone), var(--rise-map));
}
.legend-dots.is-budget .dots-ramp {
  background: linear-gradient(90deg, var(--green), var(--coral), var(--rise));
}
.density-ramp {
  flex: none;
  width: 44px;
  height: 8px;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--stone), var(--coral), var(--coral-ink));
}
.density-kind {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.density-kind select {
  height: 26px;
  padding: 0 22px 0 8px;
  font-size: var(--fs-12);
  background-position: right 6px center;
}
.school-keys {
  gap: 10px;
}
.school-keys i {
  display: inline-block;
  width: 9px;
  height: 9px;
  margin-right: 4px;
  border-radius: 50%;
  vertical-align: -1px;
}
.terrain-scale {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin-bottom: 4px;
  font-size: var(--fs-11);
}
.terrain-scale span {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.terrain-scale i {
  width: 14px;
  height: 10px;
  border-radius: 2px;
}
.terrain-note {
  margin: 4px 0 0;
  font-size: var(--fs-11);
  color: var(--ink-3);
}

/* ── 시간줄 — 지도 아래, 판을 피해서 ─────────────────────────────────────── */
.timeline {
  position: absolute;
  z-index: 2;
  left: var(--s-16);
  right: var(--map-right);
  bottom: var(--s-16);
  padding: 8px 18px 12px;
  border-radius: var(--r-22);
}
/* 정책 눈금 — 넓은 투명 손잡이, 올리면 진해진다. 말풍선은 눈금 위에 */
.spark .pmark {
  cursor: pointer;
}
.spark .pmark rect {
  fill: transparent;
}
.spark .pmark:hover line {
  stroke: var(--ink);
  opacity: 1;
}
.timeline-tip {
  position: absolute;
  bottom: calc(100% - 4px);
  z-index: 3;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: max-content;
  max-width: min(360px, 80vw);
  padding: 10px 12px;
  border-radius: var(--r-16);
  background: var(--surface);
  box-shadow: var(--sh-pop);
  font-size: var(--fs-12);
  line-height: 1.45;
  color: var(--ink);
  pointer-events: none;
}
.timeline-tip b {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--ink-3);
}
.timeline-tip span {
  white-space: normal;
}
/* 시간줄 이름표 — 뒤의 선이 무엇이고 아래 눈금이 무엇인지 */
.timeline-key {
  display: flex;
  justify-content: space-between;
  gap: var(--s-12);
  margin: 2px 0 -2px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.02em;
  color: var(--ink-3);
  pointer-events: none;
}
.tk-line::before,
.tk-mark::before {
  content: '';
  display: inline-block;
  vertical-align: middle;
  margin-right: 6px;
}
.tk-line::before {
  width: 14px;
  height: 0;
  border-top: 1.5px solid var(--ink-2);
}
.tk-mark::before {
  width: 0;
  height: 9px;
  border-left: 2px solid var(--rise);
}
.tk-mark em {
  margin-left: 6px;
  font-style: normal;
  color: var(--ink-4);
}
.spark {
  display: block;
  width: 100%;
  height: 40px;
  margin-bottom: -6px;
}
.spark .area {
  fill: rgba(23, 23, 28, 0.05);
}
.spark .line {
  fill: none;
  stroke: var(--ink-2);
  stroke-width: 1.3;
}
.spark .cursor {
  stroke: var(--ink);
  stroke-width: 1.5;
}
.timeline-row {
  display: flex;
  align-items: center;
  gap: 14px;
}
.timeline-ym {
  min-width: 64px;
  font-family: var(--mono);
  font-size: var(--fs-13);
  font-weight: 500;
  letter-spacing: 0.02em;
}
#time-slider {
  flex: 1;
  appearance: none;
  height: 3px;
  margin: 0;
  border-radius: var(--r-pill);
  background: var(--line-2);
}
#time-slider::-webkit-slider-thumb {
  appearance: none;
  width: 18px;
  height: 18px;
  border: 3px solid #fff;
  border-radius: 50%;
  background: var(--primary);
  box-shadow: 0 1px 4px rgba(23, 23, 28, 0.25);
  cursor: pointer;
}
#time-slider::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border: 3px solid #fff;
  border-radius: 50%;
  background: var(--primary);
  box-shadow: 0 1px 4px rgba(23, 23, 28, 0.25);
  cursor: pointer;
}
.play {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  transition:
    background var(--dur),
    transform 0.1s;
}
.play:hover {
  background: var(--primary-hover);
}
.play:active {
  transform: scale(0.96);
}
.play svg {
  width: 12px;
  height: 12px;
  fill: currentColor;
}
.play .ic-pause,
.play.is-playing .ic-play {
  display: none;
}
.play.is-playing .ic-pause {
  display: block;
}

/* ── MapLibre 손질 ──────────────────────────────────────────────────────── */
.maplibregl-ctrl-group {
  border: 0 !important;
  border-radius: var(--r-16) !important;
  overflow: hidden;
}
.maplibregl-ctrl-group button {
  width: 36px !important;
  height: 36px !important;
  background-color: transparent !important;
}
.maplibregl-ctrl-group button + button {
  border-top: 1px solid var(--line) !important;
}
.maplibregl-ctrl-group button:hover {
  background-color: var(--stone) !important;
}
.maplibregl-ctrl-top-right {
  top: var(--s-16) !important;
  right: var(--map-right) !important;
}
.maplibregl-ctrl-bottom-right,
.maplibregl-ctrl-bottom-left {
  bottom: calc(var(--timeline-h) + 16px) !important;
}
body.no-timeline .maplibregl-ctrl-bottom-right,
body.no-timeline .maplibregl-ctrl-bottom-left {
  bottom: 10px !important;
}
.maplibregl-ctrl-bottom-right {
  right: var(--map-right) !important;
}
.maplibregl-ctrl-bottom-left {
  left: 300px !important;
}
.maplibregl-ctrl-attrib {
  font-size: 10px !important;
  background: rgba(255, 255, 255, 0.7) !important;
}
.maplibregl-ctrl-attrib a {
  color: var(--ink-3) !important;
}
.maplibregl-popup-content {
  padding: 10px 14px !important;
  border-radius: var(--r-16) !important;
  box-shadow: var(--sh-pop) !important;
  font-family: var(--font);
  font-size: var(--fs-12);
  line-height: 1.5;
  color: var(--ink);
}
.maplibregl-popup-content strong {
  font-weight: 500;
}
/* 점에 마우스를 올리면 뜨는 한 장 */
.maplibregl-popup.hc-pop .maplibregl-popup-content {
  min-width: 240px;
  padding: 12px 14px;
  border-radius: var(--r-16);
}
.maplibregl-popup.hc-pop .maplibregl-popup-tip {
  border-top-color: #fff;
}
.hc-top {
  display: flex;
  align-items: center;
  gap: 6px;
}
.hc-nm {
  font-size: var(--fs-14);
  font-weight: 500;
}
.hc-mark {
  background: none;
  border: 1px solid var(--line-2);
  color: var(--ink-3);
}
.hc-price {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-top: 4px;
}
.hc-price b {
  font-size: var(--fs-20);
  font-weight: 500;
  letter-spacing: -0.02em;
}
.hc-price span,
.hc-out,
.hc-facts,
.hc-memo {
  margin-top: 3px;
  font-size: var(--fs-12);
  color: var(--ink-3);
}
.hc-memo {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px dashed var(--line);
  color: var(--ink-2);
}
.hc-chart {
  margin-top: 6px;
}

/* ── 답을 기다리는 동안의 알림 — 초록 알약, 지도 위 아래 가운데 ───────────── */
.ai-progress {
  position: fixed;
  z-index: 45;
  left: calc((100% - var(--map-right)) / 2);
  bottom: calc(var(--timeline-h) + 32px);
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: var(--s-8);
  max-width: calc(100vw - 32px);
  padding: 10px 18px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--green);
  color: #fff;
  font-size: var(--fs-13);
  font-weight: 500;
  white-space: nowrap;
  box-shadow: 0 8px 24px -8px rgba(0, 60, 51, 0.5);
}
body.no-timeline .ai-progress {
  bottom: 28px;
}
.ai-progress .pulse {
  background: #fff;
}
.ai-progress.is-new {
  background: var(--blue);
}
.ai-progress.is-new .pulse {
  animation: none;
}
.ai-fab,
.m-dock,
.sheet-close,
.sheet-expand,
.sheet-title {
  display: none;
}

/* ══ 판 — 오른쪽에 떠 있는 흰 판 ════════════════════════════════════════════ */
.rail {
  container: rail / inline-size; /* 판 폭에 따라 큰 수치 글자 크기가 따라온다(chat.css) */
  position: absolute;
  top: var(--panel-inset);
  right: var(--panel-inset);
  bottom: var(--panel-inset);
  z-index: 3;
  display: flex;
  flex-direction: column;
  width: var(--rail-w);
  min-width: 0;
  border-radius: var(--r-22);
  background: var(--surface);
  box-shadow: var(--sh-panel);
  overflow: hidden;
}
/* 폭 손잡이 — 판 왼쪽 가장자리. 올리면 짧은 막대가 보인다 */
.rail-grip {
  position: absolute;
  top: var(--panel-inset);
  bottom: var(--panel-inset);
  right: calc(var(--rail-w) + var(--panel-inset) - 6px);
  z-index: 4;
  width: 12px;
  cursor: col-resize;
  touch-action: none;
}
.rail-grip::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 4px;
  height: 40px;
  margin: -20px 0 0 -2px;
  border-radius: var(--r-pill);
  background: var(--primary);
  opacity: 0;
  transition: opacity var(--dur);
}
.rail-grip:hover::after,
.rail-grip:focus-visible::after,
body.is-resizing .rail-grip::after {
  opacity: 1;
}
.rail-grip:focus-visible {
  outline: none;
}
body.is-resizing {
  cursor: col-resize;
  user-select: none;
}
body.is-resizing .maplibregl-canvas {
  pointer-events: none;
}

/* 판 머리 — 밑줄 탭 */
.sheet-bar {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--s-6);
  padding: 0 var(--s-12) 0 var(--gutter); /* 탭 글자가 판 여백 선에 맞게 */
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}
.rail-tabs {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: stretch;
  gap: 2px;
}
.rail-tab {
  position: relative;
  flex: none;
  height: 52px;
  padding: 0 10px;
  border: 0;
  border-radius: var(--r-4);
  background: none;
  color: var(--ink-3);
  font-size: var(--fs-14);
  white-space: nowrap;
  transition: color var(--dur);
}
.rail-tab::after {
  content: '';
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: -1px;
  height: 2px;
  background: var(--primary);
  opacity: 0;
  transform: scaleX(0.6);
  transition:
    opacity var(--dur),
    transform var(--dur) var(--ease);
}
.rail-tab:hover {
  color: var(--ink);
}
.rail-tab.is-on {
  color: var(--ink);
  font-weight: 500;
}
.rail-tab.is-on::after {
  opacity: 1;
  transform: none;
}
.rail-tab[data-panel='thread'].is-on {
  color: var(--green);
}
.rail-tab[data-panel='thread'].is-on::after {
  background: var(--green);
}
.rail-tab:focus-visible {
  outline-offset: -4px;
}
/* AI 탭의 점 — 만드는 중이면 숨쉬고, 새 답이 있으면 파랑 */
.rail-tab[data-panel='thread'].is-busy::before,
.rail-tab[data-panel='thread'].has-new::before {
  content: '';
  position: absolute;
  top: 14px;
  right: 2px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 2px var(--surface);
}
.rail-tab[data-panel='thread'].is-busy::before {
  animation: pulse 1.2s ease-in-out infinite;
}
.rail-tab[data-panel='thread'].has-new::before {
  background: var(--blue);
  animation: none;
}
.tab-n {
  margin-left: 5px;
  vertical-align: 1px;
}
/* 더보기 — 탭 줄 끝의 점 셋. 관계 그래프처럼 가끔 쓰는 판이 산다 */
.rail-more {
  position: relative;
  flex: none;
  display: flex;
  align-items: center;
}
.rail-more-btn {
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: none;
  color: var(--ink-3);
  font-size: var(--fs-14);
  letter-spacing: 0.06em;
  transition:
    background var(--dur),
    color var(--dur);
}
.rail-more-btn:hover,
.rail-more-btn.is-on {
  background: var(--stone);
  color: var(--ink);
}
.rail-more-pop {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 5;
  min-width: 148px;
  padding: var(--s-4);
  border-radius: var(--r-16);
  background: var(--surface);
  box-shadow: var(--sh-pop);
}
.rail-more-pop .rail-tab {
  width: 100%;
  height: 36px;
  border-radius: var(--r-8);
  text-align: left;
}
.rail-more-pop .rail-tab::after {
  display: none;
}
.rail-more-pop .rail-tab.is-on {
  background: var(--stone);
}
/* 판 펼치기 — 화면을 다 쓴다. 안의 글줄은 1120px 에서 멈춰 가운데 온다 */
body.rail-wide .rail {
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: auto;
  border-radius: 0;
  box-shadow: none;
}
body.rail-wide .rail-grip {
  display: none;
}
body.rail-wide .thread,
body.rail-wide .place,
body.rail-wide .panel-head,
body.rail-wide .panel-body,
body.rail-wide .composer,
body.rail-wide .quick,
body.rail-wide .graph-form,
body.rail-wide .sheet-bar {
  padding-inline: max(var(--s-20), calc((100% - 1120px) / 2));
}
body.rail-wide .thread-bar {
  margin-inline: calc(-1 * max(var(--s-20), calc((100% - 1120px) / 2)));
  padding-inline: max(14px, calc((100% - 1120px) / 2));
}
body.rail-wide .rt-scroll,
body.rail-wide .cmp-scroll {
  margin-inline: 0;
}
.rail-expand,
.rail-hide {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: none;
  color: var(--ink-3);
  transition:
    background var(--dur),
    color var(--dur);
}
.rail-hide:hover,
.rail-expand:hover {
  background: var(--stone);
  color: var(--ink);
}
.rail-expand .ic-shrink,
body.rail-wide .rail-expand .ic-grow {
  display: none;
}
body.rail-wide .rail-expand .ic-shrink {
  display: block;
}
/* 판 접기 — 지도만 크게. 떠 있는 초록 단추가 대신 AI 로 간다 */
body.rail-hidden .rail,
body.rail-hidden .rail-grip {
  display: none;
}
body.rail-hidden {
  --map-right: var(--s-16);
}
body.rail-hidden .ai-fab {
  display: inline-flex;
  align-items: center;
  position: fixed;
  right: 18px;
  bottom: calc(22px + env(safe-area-inset-bottom));
  z-index: 40;
  height: 48px;
  padding: 0 22px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--green);
  color: #fff;
  font-size: var(--fs-15);
  font-weight: 500;
  white-space: nowrap;
  box-shadow: 0 12px 32px -8px rgba(0, 60, 51, 0.45);
}
body.rail-hidden .ai-fab:hover {
  background: var(--green-hover);
}
body.rail-hidden .ai-progress {
  left: 50%;
}

/* 판 안의 탭 내용 — 굴러가는 몸통 하나씩 */
.panel {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.panel-head {
  flex: none;
  padding: var(--s-16) var(--gutter) var(--s-12);
}
/* 찜 판 머리 — 세그먼트와 AI 묻기 단추가 한 줄 */
.saved-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-8);
  flex-wrap: wrap;
}
.saved-acts {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--s-8);
  margin-left: auto;
}
.saved-head .panel-note:empty {
  display: none;
}
.saved-head .panel-note {
  flex-basis: 100%;
  margin: 6px 0 0;
}
/* 입력창 옆 아이콘 단추(프리셋) — 넓은 화면에서는 숨긴다 */
.composer-ic {
  display: none;
  flex: none;
  width: 46px;
  height: 46px;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink-2);
}
.composer-ic[aria-expanded='true'] {
  background: var(--stone);
  color: var(--ink);
}
.panel-note {
  margin: 0 0 10px;
  font-size: var(--fs-13);
  line-height: 1.55;
  color: var(--ink-2);
}
.panel-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* 좌우 여백은 --gutter — 찜 비교표처럼 넓은 것이 더 보이게(2026-09-25 사용자) */
  padding: 0 var(--gutter) var(--s-20);
}
/* 탭을 바꾸면 내용이 스르르 — 갑자기 바뀌지 않게. 움직임을 줄인 사람에게는 base 가 끈다 */
.panel:not([hidden]),
.thread:not([hidden]) {
  animation: panel-in 0.2s var(--ease);
}
@keyframes panel-in {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
/* 찜 판은 바닥에 붙는 AI 묻기 줄이 있다 — 아래 여백이 있으면 줄이 그만큼 떠 보인다. 여백은 목록이 스스로 갖는다 */
#saved-body {
  padding-bottom: 0;
}
#saved-body > .memo-list,
#saved-body > .panel-empty,
#saved-body > .empty {
  margin-bottom: var(--s-20);
}
.place {
  overflow-y: auto;
  overscroll-behavior: contain;
}
.thread {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: var(--s-16);
  padding: var(--gutter);
}
/* 대화 기록 줄 — 굴려도 위에 붙어 있다 */
.thread-bar {
  position: sticky; /* 대화 목록(.chat-list)은 이 줄을 기준으로 뜬다 */
  top: calc(-1 * var(--gutter));
  z-index: 4;
  display: flex;
  align-items: center;
  gap: var(--s-6);
  margin: calc(-1 * var(--gutter)) calc(-1 * var(--gutter)) 0;
  padding: var(--s-8) var(--gutter);
  background: var(--glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line-soft);
}
.thread-bar-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink-2);
  font-size: var(--fs-13);
  font-weight: 500;
}
/* 답 오면 알림 — 켜지면 먹, 못 켜는 기기(사파리 탭)는 흐리게 */
.push-btn.is-on {
  color: var(--on-primary);
  background: var(--primary);
  border-color: var(--primary);
}
.push-btn:disabled {
  opacity: 0.45;
  cursor: default;
}

.thread-bar-btn:hover,
.thread-bar-btn[aria-expanded='true'] {
  background: var(--stone);
  border-color: transparent;
  color: var(--ink);
}
.thread-bar-title {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-12);
  color: var(--ink-3);
  text-align: center;
}

/* 고른 지역에 맞춘 질문 칩 줄 — 입력창 위 */
.quick {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-6);
  padding: 10px var(--s-16);
  border-top: 1px solid var(--line);
  background: var(--surface);
}
.quick::-webkit-scrollbar {
  display: none;
}
.quick-k {
  flex: none;
  padding: 0 2px;
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--green);
}
.quick .chip {
  flex: none;
  min-height: 32px;
  padding: 5px 12px;
  font-size: var(--fs-13);
}
/* ── 입력창 — 판 맨 아래. 돌빛 알약 칸과 초록 묻기뿐(웹·방식은 확인 창에서) ── */
.composer {
  flex: none;
  display: flex;
  gap: var(--s-8);
  padding: var(--s-12) var(--s-16) var(--s-16);
  border-top: 1px solid var(--line);
  background: var(--surface);
}
.composer input {
  flex: 1;
  min-width: 0;
  height: 44px;
  padding: 0 16px;
  border: 1px solid transparent;
  border-radius: var(--r-16);
  background: var(--stone);
}
.composer input:hover {
  border-color: transparent;
}
.composer input:focus {
  background: var(--surface);
  border-color: var(--ink);
}
.composer .btn-send {
  height: 44px;
  padding: 0 22px;
  background: var(--green);
  border-color: var(--green);
}
.composer .btn-send:hover,
.composer .btn-send:active {
  background: var(--green-hover);
  border-color: var(--green-hover);
}
/* ══ 창 — 단지·통계·방법. 틀만 여기, 속은 각 파일 ═══════════════════════════ */
.modal {
  width: min(1120px, 94vw);
  max-height: 88vh;
}
.modal-close {
  position: absolute;
  top: 18px;
  right: 18px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--stone);
  color: var(--ink);
  transition:
    background var(--dur),
    color var(--dur);
}
.modal-close:hover {
  background: var(--primary);
  color: #fff;
}
.modal-close svg {
  width: 14px;
  height: 14px;
}
.modal-body {
  max-height: 88vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 36px 40px 40px;
}
/* 굴려 내려가면 위에 붙는 작은 머리 — 흰 유리, 이름 하나. 닫기 단추가 그 오른쪽에 앉는다 */
.modal-mini {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  height: 56px;
  padding: 0 72px 0 40px;
  background: var(--glass);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-15);
  font-weight: 500;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition:
    opacity var(--dur),
    transform var(--dur) var(--ease);
}
.modal.is-scrolled .modal-mini {
  opacity: 1;
  transform: none;
}
.modal.is-scrolled .modal-close {
  top: 10px;
}

/* ══ 로그인 — 초록 판 위 흰 카드 하나 ══════════════════════════════════════ */
body.login-page {
  display: block;
  overflow: auto;
  background: var(--green);
}
.login {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: calc(40px + env(safe-area-inset-top)) 16px calc(40px + env(safe-area-inset-bottom));
}
.login-deco {
  display: none;
}
.login-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-20);
  margin: 0 0 28px;
  font-size: clamp(32px, 5vw, 44px);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.03em;
  color: #fff;
  text-align: center;
}
.login-brand .brand-mark {
  width: 56px;
  height: 56px;
  color: #fff;
}
/* 초록 판 위라 뒤집는다 — 흰 판에 초록 집, 문은 희게 */
.login-brand .brand-mark .mark-house {
  fill: var(--green);
}
.login-brand .brand-mark .mark-door {
  fill: #fff;
}
.login-panel {
  width: min(400px, 100%);
}
.login-card {
  padding: 28px;
  border-radius: var(--r-22);
  background: var(--surface);
  box-shadow: 0 24px 64px -24px rgba(0, 0, 0, 0.45);
}
.lf {
  display: flex;
  flex-direction: column;
  gap: var(--s-6);
  margin-bottom: var(--s-16);
  font-size: var(--fs-13);
  font-weight: 500;
  color: var(--ink-2);
}
.lf input {
  width: 100%;
  height: 46px;
  padding: 0 16px;
  font-size: 16px;
}
.login-submit {
  width: 100%;
  height: 48px;
  margin-top: var(--s-8);
  font-size: var(--fs-15);
}
.login-error {
  margin: 0 0 var(--s-12);
  padding: 10px 14px;
  border-radius: var(--r-8);
  background: var(--coral-wash);
  color: var(--coral-ink);
  font-size: var(--fs-13);
}
@keyframes login-shake {
  0%,
  100% {
    transform: translateX(0);
  }
  20% {
    transform: translateX(-6px);
  }
  40% {
    transform: translateX(5px);
  }
  60% {
    transform: translateX(-3px);
  }
  80% {
    transform: translateX(2px);
  }
}
.is-shaking {
  animation: login-shake 0.32s ease;
}
.login-foot {
  margin: var(--s-20) 0 0;
  font-size: var(--fs-13);
  color: rgba(255, 255, 255, 0.6);
  text-align: center;
}

/* ══ 터치 기기 — 페이지는 확대되지 않는다(지도만). 좁은 화면 규칙을 태블릿까지 넓힌 것 ═══ */
@media (pointer: coarse) {
  html,
  body {
    touch-action: pan-x pan-y;
  }
}

/* ══ 태블릿(761~1100) — 판을 오른쪽에 붙여 나란히. 떠 있지 않고 가장자리에 닿는다 ═══
   전에는 지도 위·판 아래로 쌓아 둘 다 반쪽이었다(2026-09-25 사용자: "태블릿 사이즈에서 엉망").
   판 폭은 화면의 42%(360~460px), 나머지가 지도. 손잡이는 없고 펼치기(rail-wide)는 그대로 된다. */
@media (max-width: 1360px) {
  .brand-sub {
    display: none;
  }
}
@media (max-width: 1180px) {
  .status {
    display: none;
  }
}
@media (min-width: 761px) and (max-width: 1100px) {
  :root {
    --rail-mid: clamp(360px, 42vw, 460px);
    --panel-inset: 0px;
    /* app.js 가 인라인으로 --rail-w 를 써도 여기서는 판 폭이 정해져 있다 */
    --map-right: calc(var(--rail-mid) + var(--s-12));
  }
  .rail {
    top: 0;
    right: 0;
    bottom: 0;
    border-radius: 0;
    box-shadow: none;
    border-left: 1px solid var(--line);
  }
  /* 펼치기(rail-wide)는 화면을 다 써야 하므로 폭 고정은 접힌 판에만 — !important 가 펼치기의 width:auto 를 이기면 판이 같은 폭으로 왼쪽에 붙는다(2026-09-26) */
  body:not(.rail-wide) .rail {
    width: var(--rail-mid) !important;
  }
  body.rail-wide .rail {
    border-left: 0;
  }
  .rail-grip {
    display: none;
  }
  .topbar {
    padding: 0 var(--s-16);
    gap: var(--s-12);
  }
  .search {
    max-width: none;
  }
  .legend {
    max-width: 240px;
  }
  .timeline {
    left: var(--s-12);
    bottom: var(--s-12);
    padding: 6px 14px 10px;
  }
  .ai-progress {
    left: calc((100vw - var(--rail-mid)) / 2);
  }
}
/* 태블릿 세로(≤900) — 상단 바가 비좁다: 로그아웃 글자를 숨기고 조건 요약을 짧게, 시간줄 설명은 접는다 */
@media (max-width: 900px) and (min-width: 761px) {
  .signout {
    display: none;
  }
  .me-v {
    max-width: 150px;
  }
  .timeline-key {
    display: none;
  }
}

/* ══ 좁은 화면 — 탭 바 앱 ══════════════════════════════════════════════════ */
@media (max-width: 760px) {
  :root {
    --timeline-h: 44px;
    --gutter: var(--s-12);
  }
  html,
  body {
    height: 100dvh;
    position: fixed;
    inset: 0;
    width: 100%;
    overflow: hidden;
    touch-action: pan-x pan-y; /* 페이지는 확대되지 않는다. 지도 캔버스는 MapLibre 가 따로 */
  }
  input,
  select,
  textarea {
    font-size: 16px; /* iOS 가 초점에서 확대하지 않게 */
  }

  .topbar {
    flex: 0 0 calc(var(--top-h-m) + env(safe-area-inset-top));
    height: calc(var(--top-h-m) + env(safe-area-inset-top));
    padding: env(safe-area-inset-top) var(--s-12) 0;
    gap: 10px;
  }
  .brand {
    gap: 0;
  }
  .brand span,
  .brand-sub,
  .status,
  .signout {
    display: none;
  }
  .search {
    min-width: 0;
  }
  .search input {
    font-size: 16px;
    border-radius: var(--r-16);
  }
  .search-kbd {
    display: none;
  }
  .search-pop {
    position: fixed;
    top: calc(var(--top-h-m) + env(safe-area-inset-top) + 6px);
    left: 10px;
    right: 10px;
  }
  .me-btn {
    width: 40px;
    height: 40px;
    padding: 0;
    justify-content: center;
  }
  .me-k,
  .me-v {
    display: none;
  }
  .me.is-set .me-btn {
    background: var(--primary);
    border-color: var(--primary);
  }
  .me.is-set .me-ic {
    color: #fff;
  }
  /* 내 조건 — 화면을 다 쓰는 판. 저장 줄은 아래에 붙어 있다 */
  .me-form {
    position: fixed;
    top: calc(var(--top-h-m) + env(safe-area-inset-top));
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    max-height: none;
    padding: var(--s-20) var(--s-16) calc(24px + env(safe-area-inset-bottom));
    border-radius: 0;
    border-top: 1px solid var(--line);
    box-shadow: none;
  }
  .me-actions {
    position: sticky;
    bottom: calc(-24px - env(safe-area-inset-bottom));
    margin: 0 calc(-1 * var(--s-16)) calc(-24px - env(safe-area-inset-bottom));
    padding: var(--s-12) var(--s-16) calc(16px + env(safe-area-inset-bottom));
    background: var(--glass);
    border-top: 1px solid var(--line);
  }
  .me-actions .btn {
    height: 46px;
    font-size: var(--fs-15);
  }
  body:has(#me-form:not([hidden])) .m-dock,
  body:has(#layers-pop:not([hidden])) .m-dock {
    display: none;
  }

  .stage {
    display: block;
  }
  .map-pane {
    position: absolute;
    inset: 0;
  }
  .rail {
    display: none;
  }
  :root {
    --map-right: 10px;
  }

  /* 지표 칩 띠 — 상단바 아래 붙어 있다 */
  .map-top {
    top: 0;
    left: 0;
    right: 0;
    padding: 8px 10px;
    gap: 0;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    background: var(--glass);
    border-bottom: 1px solid var(--line);
  }
  .map-top::-webkit-scrollbar {
    display: none;
  }
  .pills {
    flex: none;
    padding: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  /* 더보기 — 칩 띠는 남기고 그 아래를 다 쓴다. 더보기를 다시 눌러 닫는다 */
  #layers-pop {
    position: fixed;
    top: calc(var(--top-h-m) + env(safe-area-inset-top) + 51px);
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    max-height: none;
    padding: var(--s-16) var(--s-16) calc(24px + env(safe-area-inset-bottom));
    border-radius: 0;
    border-top: 1px solid var(--line);
    box-shadow: none;
    z-index: 60;
  }
  #layers-pop .toggle {
    min-height: 46px;
    font-size: var(--fs-14);
  }
  #layers-pop .field {
    height: 44px;
  }
  .layers-grid {
    grid-template-columns: 1fr;
  }

  /* 범례 — 띠로 한 줄을 다 쓰지 않고, 칩 띠 아래 왼쪽에 작은 알약으로 떠 있다. 칠한 값만 말한다 */
  .legend,
  body.no-timeline .legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    top: 61px;
    left: 10px;
    right: auto;
    bottom: auto;
    max-width: calc(100% - 20px);
    max-height: none;
    padding: 5px 10px 5px 12px;
    border-radius: var(--r-pill);
    font-size: var(--fs-11);
  }
  .legend-head {
    margin: 0;
  }
  .legend-title {
    font-size: var(--fs-11);
  }
  .legend-asof,
  .legend-why,
  .legend-more,
  .legend-hint,
  .legend-arrow,
  .legend-rel {
    display: none;
  }
  .legend.no-fill {
    display: none;
  }
  .legend-ramp {
    flex: 0 1 auto;
    min-width: 0;
    gap: 6px;
    font-size: 10.5px;
  }
  .legend-ramp .ramp {
    width: 56px;
    min-width: 40px;
    height: 5px;
  }
  /* 지형·점포 밀도는 한 줄 남긴다 — 무엇인지 모르면 얼룩이다 */
  .legend-terrain:not([hidden]),
  .legend-density:not([hidden]) {
    display: flex;
    flex: 1 0 100%;
    flex-wrap: wrap;
    align-items: center;
    gap: 2px 10px;
    margin: 0;
    padding-top: 4px;
    border-top: 1px solid var(--line-soft);
  }
  .legend-terrain .terrain-scale {
    margin: 0;
    font-size: 10.5px;
  }
  .legend-terrain .legend-rel-row:last-of-type,
  .legend-terrain .terrain-note,
  .legend-terrain .wide-only,
  .legend-density .terrain-note {
    display: none;
  }
  .legend-terrain.is-wide .terrain-note {
    display: block;
    margin: 0;
  }
  .legend-terrain.is-wide .terrain-scale,
  .legend-terrain.is-wide .legend-rel-row {
    display: none;
  }

  /* 시간줄 — 한 줄만. 흐름 선과 이름표는 넓은 화면의 것 */
  .timeline {
    left: 10px;
    right: 10px;
    bottom: calc(var(--dock-h) + 10px);
    padding: 6px 8px 6px 14px;
    border-radius: var(--r-pill);
  }
  .spark,
  .timeline-key {
    display: none;
  }
  .timeline-row {
    gap: 10px;
  }
  .timeline-ym {
    min-width: 56px;
    font-size: var(--fs-12);
  }
  #time-slider::-webkit-slider-thumb {
    width: 22px;
    height: 22px;
  }
  #time-slider::-moz-range-thumb {
    width: 22px;
    height: 22px;
  }
  .play {
    width: 32px;
    height: 32px;
  }
  body.sheet-peek .timeline {
    display: none;
  }

  .maplibregl-ctrl-top-right {
    top: calc(var(--top-h-m) + env(safe-area-inset-top) + 96px) !important;
    right: 12px !important;
  }
  .maplibregl-ctrl-group button {
    width: 40px !important;
    height: 40px !important;
  }
  .maplibregl-ctrl-bottom-right,
  body.no-timeline .maplibregl-ctrl-bottom-right {
    right: 10px !important;
    bottom: calc(var(--dock-h) + 2px) !important;
  }
  .maplibregl-ctrl-bottom-left {
    left: 0 !important;
    bottom: calc(var(--dock-h) + var(--timeline-h) - 6px) !important;
  }
  body.no-timeline .maplibregl-ctrl-bottom-left {
    bottom: calc(var(--dock-h) + 2px) !important;
  }

  /* ── 탭 바 — 흰 유리, 위에 가는 선, 다섯 칸 ────────────────────────────── */
  .ai-fab {
    display: none !important;
  }
  .m-dock {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 55;
    display: flex;
    align-items: stretch;
    height: var(--dock-h);
    padding: 0 6px env(safe-area-inset-bottom);
    border-top: 1px solid var(--line);
    background: var(--glass);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
  }
  .dock-btn {
    position: relative;
    flex: 1 1 0;
    min-width: 0;
    height: 60px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: 0;
    border: 0;
    border-radius: var(--r-8);
    background: none;
    color: var(--ink-3);
    font-size: 10.5px;
    font-weight: 500;
    transition: color var(--dur);
  }
  .dock-btn svg {
    width: 24px;
    height: 24px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  .dock-btn:active,
  .dock-btn.is-on {
    color: var(--ink);
  }
  .dock-btn.is-on svg {
    stroke-width: 1.9;
  }
  .dock-n {
    position: absolute;
    top: 6px;
    left: calc(50% + 4px);
    height: 17px;
    line-height: 17px;
    font-size: 10.5px;
    box-shadow: 0 0 0 2px var(--surface);
  }
  /* AI 칸 — 켜지면 초록 */
  .dock-ai svg {
    fill: currentColor;
    stroke: none;
  }
  .dock-ai:active,
  .dock-ai.is-on {
    color: var(--green);
  }
  .dock-ai.is-busy::after,
  .dock-ai.has-new::after {
    content: '';
    position: absolute;
    top: 8px;
    left: calc(50% + 8px);
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--green);
    box-shadow: 0 0 0 2px var(--surface);
  }
  .dock-ai.is-busy::after {
    animation: pulse 1.2s ease-in-out infinite;
  }
  .dock-ai.has-new::after {
    background: var(--blue);
  }
  .ai-progress {
    left: 50%;
    bottom: calc(var(--dock-h) + var(--timeline-h) + 16px);
  }
  body.no-timeline .ai-progress,
  body.ai-open .ai-progress {
    bottom: calc(var(--dock-h) + 12px);
  }

  /* ── 판 — 화면을 다 쓴다. 위는 상단바 자리부터, 아래는 탭 바 위까지 ────── */
  body.ai-open .rail {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: var(--dock-h);
    z-index: 50;
    display: flex;
    width: auto;
    border-radius: 0;
    box-shadow: none;
  }
  body.ai-open .sheet-bar {
    gap: 10px;
    min-height: calc(var(--top-h-m) + env(safe-area-inset-top));
    padding: env(safe-area-inset-top) var(--s-12) 0 var(--s-20);
  }
  body.ai-open .rail-tabs,
  body.ai-open .rail-hide,
  body.ai-open .rail-expand {
    display: none; /* 탭 줄은 아래 탭 바가 대신한다 */
  }
  .sheet-title {
    display: block;
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--fs-20);
    font-weight: 500;
    letter-spacing: -0.02em;
  }
  .sheet-close,
  .sheet-expand {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 36px;
    padding: 0;
    border: 0;
    border-radius: var(--r-pill);
    background: var(--stone);
    color: var(--ink);
    font-size: var(--fs-13);
    font-weight: 500;
  }
  .sheet-close {
    width: 36px;
  }
  .sheet-close svg {
    width: 14px;
    height: 14px;
  }
  .sheet-expand {
    display: none;
    gap: 6px;
    padding: 0 14px 0 12px;
    background: var(--primary);
    color: #fff;
  }
  .sheet-expand svg {
    width: 14px;
    height: 14px;
  }

  /* ── 미리보기 카드 — 지도를 눌렀을 때. 아래에 떠 있고, 누르면 다 펼친다 ── */
  body.sheet-peek .rail {
    top: auto;
    left: 10px;
    right: 10px;
    bottom: calc(var(--dock-h) + 10px);
    max-height: var(--peek-h);
    border-radius: var(--r-22);
    box-shadow: var(--sh-pop);
    animation: peek-in 0.26s var(--ease);
  }
  @keyframes peek-in {
    from {
      opacity: 0;
      transform: translateY(16px);
    }
    to {
      opacity: 1;
      transform: none;
    }
  }
  body.sheet-peek .sheet-bar {
    min-height: 56px;
    padding: 0 var(--s-12) 0 var(--s-20);
    border-bottom: 0;
  }
  body.sheet-peek .sheet-title {
    font-size: var(--fs-15);
    color: var(--ink-3);
  }
  body.sheet-peek .sheet-expand {
    display: inline-flex;
  }
  body.sheet-peek .composer,
  body.sheet-peek .quick,
  body.sheet-peek .thread-bar,
  body.sheet-peek .place-bar {
    display: none;
  }
  /* 미리보기 안은 굴리지 않는다 — 누르면 펼쳐진다. 아래는 흰 안개 */
  body.sheet-peek .panel-body,
  body.sheet-peek .place,
  body.sheet-peek .thread {
    overflow: hidden;
    pointer-events: none;
  }
  body.sheet-peek .rail::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 56px;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0), #fff);
    pointer-events: none;
  }

  .thread {
    gap: 14px;
    padding: var(--gutter);
  }
  /* 판 이름·닫기 줄은 없앤다 — 탭 바가 이미 어느 판인지 말한다(2026-09-25 "상단바 왜 필요"). 미리보기에서만 남긴다 */
  body.ai-open:not(.sheet-peek) .sheet-bar {
    display: none;
  }
  /* 입력창은 AI 판에서만 — 다른 판에서는 표 끝을 가렸다 */
  body.ai-open:not([data-panel='thread']) .composer {
    display: none;
  }
  /* 대화 머리줄: 글자 없이 아이콘만, 새 대화는 목록 안으로, 프리셋은 입력창 옆으로 */
  .thread-bar {
    top: calc(-1 * var(--gutter));
    margin: calc(-1 * var(--gutter)) calc(-1 * var(--gutter)) 0;
    padding: 6px var(--gutter);
    gap: var(--s-4);
  }
  .thread-bar .tb-txt,
  .thread-bar #chat-new,
  .thread-bar #preset-btn,
  .push-btn > span {
    display: none;
  }
  .thread-bar-btn {
    width: 36px;
    height: 36px;
    padding: 0;
    justify-content: center;
  }
  .thread-bar-btn svg {
    width: 16px;
    height: 16px;
  }
  .thread-bar-title {
    flex: 1 1 auto;
  }
  .composer-ic {
    display: inline-flex;
  }
  .panel-head {
    padding: 10px var(--gutter) 8px;
  }
  .saved-head .seg-btn {
    padding: 5px 12px;
  }
  .panel-body {
    padding: 0 var(--gutter) var(--s-16);
  }
  .quick {
    flex-wrap: nowrap;
    padding: 8px 12px;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent);
    mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent);
  }
  .quick::after {
    content: '';
    flex: 0 0 14px;
  }
  .composer {
    padding: 10px 12px 12px;
    gap: 6px;
  }
  .composer input,
  .composer .btn-send {
    height: 46px;
  }
  .btn,
  .chip {
    min-height: 40px;
  }
  .toggle {
    min-height: 40px;
  }

  /* 창은 화면을 다 쓴다 — 아래에서 올라온다 */
  .modal {
    width: 100vw;
    max-width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    border-radius: 0;
    box-shadow: none;
  }
  .modal[open] {
    animation: modal-up 0.28s var(--ease);
  }
  @keyframes modal-up {
    from {
      transform: translateY(24px);
      opacity: 0;
    }
    to {
      transform: none;
      opacity: 1;
    }
  }
  .modal-body {
    max-height: 100dvh;
    padding: calc(64px + env(safe-area-inset-top)) 18px calc(32px + env(safe-area-inset-bottom));
  }
  .modal-close {
    top: calc(12px + env(safe-area-inset-top));
    right: 14px;
    width: 40px;
    height: 40px;
  }
  .modal-mini {
    height: calc(56px + env(safe-area-inset-top));
    padding: env(safe-area-inset-top) 64px 0 18px;
    font-size: var(--fs-17);
  }
  .modal.is-scrolled .modal-close {
    top: calc(8px + env(safe-area-inset-top));
  }
}

@media (max-width: 380px) {
  .brand-mark {
    width: 24px;
    height: 24px;
  }
}
