/* ==========================================================================
   ZZAPS 지도 화면 전용 스타일
   --------------------------------------------------------------------------
   소유       : 지도 전담 세션
   적용 범위  : /map (body.map-page) 한 곳
   로드 방식  : map/index.blade.php 의 @push('head') 에서만 link

   규칙
     - 모든 선택자를 .map-page 하위로 스코프한다.
     - 공통 app.css 를 수정하지 않고, 지도에서만 덮어써야 하는 것만 여기서 처리한다.
     - 전역 요소 선택자·body·html·.shell 을 재정의하지 않는다.
     - 색은 공통 테마 변수를 읽기만 한다.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. 지도 기본 컨트롤 정리

   Leaflet 이 기본으로 그리는 +/- 확대축소 버튼과 화면 하단 긴 저작자 문구를
   지도 화면에서만 감춘다. 저작자 표시는 지우는 것이 아니라 "지도 출처" 시트로
   옮겨 유지한다 (OSM·행정구역 데이터 모두 표시 의무가 있다).
   -------------------------------------------------------------------------- */
.map-page .leaflet-control-zoom,
.map-page .leaflet-control-attribution { display: none !important; }

/* 남은 컨트롤 컨테이너가 터치를 먹지 않게 */
.map-page .leaflet-control-container .leaflet-bottom { pointer-events: none; }

/* --------------------------------------------------------------------------
   2. 지도 영역 — 헤더 아래부터 하단 내비 위까지 정확히 채운다
   -------------------------------------------------------------------------- */
.map-page .mapwrap {
    position: relative;
    /* 100dvh 는 모바일 주소창 접힘까지 반영한다. safe-area 는 하단 내비 쪽에서 이미 더해진다. */
    height: calc(100dvh - var(--header-h, 56px) - var(--tabbar-total, 62px));
    min-height: 320px;
    overflow: hidden;

    /*
     * 지도 내부 층을 이 상자 안에 가둔다.
     *
     * Leaflet 은 pane 마다 z-index 400~700 을 직접 준다(tile 400 · marker 600 · popup 700).
     * 여기에 지도 자체 UI(토스트 540 · 바텀시트 550 · 출처 700)까지 얹혀 있는데,
     * 예전에는 이 상자가 position:relative 이면서 z-index 가 auto 라 스태킹 컨텍스트를
     * 만들지 않았다. 그래서 저 400~700 이 전부 "루트" 로 올라가 전역 모달(.sheet z-index 200)과
     * 같은 층에서 경쟁했고, 지도 타일이 글쓰기 시트를 덮어 시트가 열려도 보이지 않았다.
     *
     * isolation:isolate 는 크기·위치를 바꾸지 않고 스태킹 컨텍스트만 만든다.
     * 이걸 걸면 내부 400~700 은 이 상자 안에서만 유효해지고,
     * 바깥에서 지도는 z-index:auto 인 블록 하나로만 보인다.
     * (숫자를 크게 올리는 방식이 아니라 층 자체를 가둬 원인을 없앤다)
     */
    isolation: isolate;
}

/* 시트가 숨겨지면 지도가 즉시 전체 높이를 쓴다 (별도 계산 없이 시트만 화면 밖으로) */
.map-page .mapcanvas { position: absolute; inset: 0; }

/* --------------------------------------------------------------------------
   3. 상단 거래유형 필터 (팝니다 / 삽니다)
   -------------------------------------------------------------------------- */
.map-page .zz-map-dealbar {
    position: absolute;
    top: 10px; left: 10px;
    z-index: 500;
    display: inline-flex;
    gap: 0;
    padding: 3px;
    border-radius: var(--r-pill);
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: 0 2px 10px rgba(0, 0, 0, .35);
    overflow: visible;
}

.map-page .zz-map-deal {
    appearance: none;
    border: 0;
    background: transparent;
    color: var(--text-muted);
    font-size: 13.5px;
    font-weight: 700;
    height: 34px;
    padding: 0 16px;
    border-radius: var(--r-pill);
    cursor: pointer;
    white-space: nowrap;
}

/* 활성 상태가 한눈에 구분되게 채운다 */
.map-page .zz-map-deal[aria-pressed="true"] {
    background: var(--primary);
    color: #fff;
}
.map-page .zz-map-deal[aria-pressed="true"][data-val="buy"] { background: var(--buy); }

/* --------------------------------------------------------------------------
   4. 지도 출처 버튼 + 시트
   -------------------------------------------------------------------------- */
.map-page .zz-map-info {
    position: absolute;
    top: 10px; right: 10px;
    z-index: 500;
    width: 32px; height: 32px;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: var(--surface);
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 700;
    font-style: italic;
    cursor: pointer;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .35);
}
.map-page .zz-map-info:hover { color: var(--text); border-color: var(--border-strong); }

.map-page .zz-map-credit {
    position: absolute;
    inset: 0;
    z-index: 700;
    display: flex;
    align-items: flex-end;
}
.map-page .zz-map-credit[hidden] { display: none; }

.map-page .zz-map-credit-back {
    position: absolute;
    inset: 0;
    border: 0;
    background: rgba(0, 0, 0, .5);
    cursor: pointer;
}

.map-page .zz-map-credit-panel {
    position: relative;
    width: 100%;
    background: var(--surface);
    border-top: 1px solid var(--border);
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    padding: 20px 16px calc(16px + env(safe-area-inset-bottom, 0px));
}

.map-page .zz-map-credit-title { font-size: 16px; margin: 0 0 14px; color: var(--text); }

.map-page .zz-map-credit-list { margin: 0 0 16px; }
.map-page .zz-map-credit-list dt {
    font-size: 12px;
    color: var(--text-dim);
    margin-top: 10px;
}
.map-page .zz-map-credit-list dd {
    margin: 3px 0 0;
    font-size: 13.5px;
    color: var(--text-muted);
    overflow-wrap: anywhere;
}
.map-page .zz-map-credit-list dd a { color: var(--info); text-decoration: underline; }

/* --------------------------------------------------------------------------
   5. + 글쓰기 — 지도에서는 원형 "+" 만

   공통 .fab 은 "＋ 글쓰기" 알약형이다. 지도에서만 글자를 감추고 원형으로 만든다.
   위치는 시트 상태에 따라 JS 가 --zz-map-fab-lift 변수로 올려준다.
   -------------------------------------------------------------------------- */
.map-page .fab {
    width: 48px;
    height: 48px;
    padding: 0;
    border-radius: 50%;
    justify-content: center;
    gap: 0;
    right: calc(var(--zz-gutter, 0px) + 16px);
    /* 하단 내비 위 + 시트가 열린 만큼 추가로 들어올린다 */
    bottom: calc(var(--tabbar-total, 62px) + 16px + var(--zz-map-fab-lift, 0px));
    transition: bottom .18s ease;

    /*
     * 예전에는 560 이었다. 지도 바텀시트(550)를 넘기려던 값인데,
     * 이제 지도 내부는 .mapwrap 안에 갇혀 있어 그렇게 높일 이유가 없다.
     * 오히려 560 이면 글쓰기 모달(200)보다 위라 모달을 열어도 + 버튼이 그 위에 떠 있었다.
     * 공통값(75)으로 되돌려 "지도 < FAB·하단내비 < 모달" 순서를 지킨다.
     */
    z-index: 75;
}

/* 알약형에 들어 있던 "글쓰기" 글자만 감춘다 (아이콘은 남긴다) */
.map-page .fab > span,
.map-page .fab-label { display: none; }

/* --------------------------------------------------------------------------
   6. 바텀시트 — transform 으로 직접 움직인다

   translate3d 로만 위치를 바꾸고, 드래그 중에는 transition 을 끈다.
   퍼센트가 아니라 px(--zz-sheet-y)로 다뤄야 손가락과 정확히 붙는다.
   -------------------------------------------------------------------------- */
.map-page .mapsheet {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    z-index: 550;
    display: flex;
    flex-direction: column;
    height: var(--zz-sheet-h, 78%);
    background: var(--surface);
    border-top: 1px solid var(--border-strong);
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    box-shadow: 0 -6px 24px rgba(0, 0, 0, .38);
    /* 초기값은 완전히 숨김. 실제 위치는 JS 가 --zz-sheet-y 로 준다. */
    transform: translate3d(0, var(--zz-sheet-y, 100%), 0);
    transition: transform .26s cubic-bezier(.32, .72, 0, 1);
    will-change: transform;
    touch-action: none;
}

/* 드래그 중에는 애니메이션을 끄고 손가락을 그대로 따라간다 */
.map-page .mapsheet.is-dragging { transition: none; }

/* 완전히 숨겨졌을 때는 포인터를 먹지 않게 (지도 전체를 쓰게) */
.map-page .mapsheet.is-hidden { pointer-events: none; }
.map-page .mapsheet.is-hidden .mapsheet-body { visibility: hidden; }

.map-page .mapsheet-head {
    flex: 0 0 auto;
    padding: 8px 16px 10px;
    cursor: grab;
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
}
.map-page .mapsheet-head:active { cursor: grabbing; }

.map-page .mapsheet-grip {
    width: 36px; height: 4px;
    margin: 0 auto 10px;
    background: var(--surface-4);
    border-radius: var(--r-pill);
}

.map-page .mapsheet-title {
    font-size: 14px;
    font-weight: 700;
    margin: 0;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 6px;
}

.map-page .mapsheet-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding: 0 16px calc(16px + env(safe-area-inset-bottom, 0px));
}

/* --------------------------------------------------------------------------
   7. 매물 없음 토스트 (큰 빈 시트 대신)
   -------------------------------------------------------------------------- */
.map-page .zz-map-toast {
    position: absolute;
    left: 50%;
    bottom: calc(var(--tabbar-total, 62px) + 24px);
    transform: translateX(-50%);
    z-index: 540;
    max-width: 82%;
    padding: 9px 16px;
    border-radius: var(--r-pill);
    background: rgba(0, 0, 0, .8);
    color: #fff;
    font-size: 13px;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity .18s;
}
.map-page .zz-map-toast.is-on { opacity: 1; }

/* --------------------------------------------------------------------------
   8. 모션 최소화 설정 존중
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .map-page .mapsheet { transition: none; }
    .map-page .fab { transition: none; }
}

/* --------------------------------------------------------------------------
   9. 행정구역 집계 마커 — 지도에 올라가는 유일한 요소

   "지역 이름 + 매물 수" 하나뿐이다. 가격·썸네일·개별 상품 핀은 어떤 축척에서도
   지도에 올라가지 않는다 (그런 요소를 만들지 않는다).

   iconSize 를 주지 않으므로 Leaflet 은 마커 div 를 좌표 지점에 그대로 놓는다.
   그래서 안쪽 알약을 translate(-50%,-50%) 로 직접 가운데 맞춘다.
   -------------------------------------------------------------------------- */
.map-page .zz-rmark-icon {
    width: 0 !important;
    height: 0 !important;
    margin: 0 !important;
    background: none;
    border: 0;
}

/* --- 흰색 카드 : 지역 이름(첫 줄) + 판매·구매 숫자(둘째 줄) --- */
.map-page .zz-rmark {
    position: absolute;
    left: 0; top: 0;
    /* 꼬리가 좌표 지점을 가리키도록 카드 아래쪽 끝을 기준으로 올린다 */
    transform: translate(-50%, calc(-100% - 7px));

    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;

    /* 손가락으로 누를 수 있는 최소 크기 */
    min-height: 38px;
    padding: 5px 10px 6px;

    background: #fff;
    border: 0;
    border-radius: 10px;
    /* 약한 그림자 (지도 위에서 떠 보이되 튀지 않게) */
    box-shadow: 0 2px 6px rgba(0, 0, 0, .28);

    white-space: nowrap;
    cursor: pointer;
    transition: transform .14s, box-shadow .14s;
}

/* 아래 작은 꼬리 */
.map-page .zz-rmark::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: -5px;
    width: 10px; height: 10px;
    transform: translateX(-50%) rotate(45deg);
    background: #fff;
    border-radius: 2px;
    box-shadow: 2px 2px 4px rgba(0, 0, 0, .16);
}

.map-page .zz-rmark-name {
    font-size: 12px;
    font-weight: 700;
    line-height: 1.25;
    /* 흰 카드 위에 올라가므로 공통 다크 토큰 대신 고정 먹색을 쓴다 */
    color: #1f2024;
}

/* 판매·구매 두 숫자를 한 줄에 */
.map-page .zz-rmark-nums {
    display: flex;
    align-items: center;
    gap: 8px;
    line-height: 1.2;
}

.map-page .zz-rmark-n {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 12px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

/* 색만 봐도 구분되게 : 점 + 숫자를 같은 색으로 */
.map-page .zz-rmark-n::before {
    content: '';
    width: 6px; height: 6px;
    border-radius: 50%;
    background: currentColor;
}

.map-page .zz-rmark-n--sell { color: #E5484D; }   /* 판매 : 빨강 */
.map-page .zz-rmark-n--buy  { color: #2F6FEA; }   /* 구매 : 파랑 */

/* 한쪽이 0이면 숫자를 흐리게 (없다는 것을 색으로도 알린다) */
.map-page .zz-rmark-n.is-zero { color: #b9bcc4; }

/*
 * 겹치는 자리에서는 이름을 빼고 합계만 남긴 작은 원형으로 줄인다.
 * 지역을 감추지 않으면서 화면을 정리하는 방법이다.
 */
.map-page .zz-rmark--compact {
    min-height: 32px;
    width: 32px;
    padding: 0;
    justify-content: center;
    border-radius: 50%;
}
.map-page .zz-rmark--compact .zz-rmark-total {
    font-size: 12px;
    font-weight: 800;
    color: #1f2024;
    font-variant-numeric: tabular-nums;
}

/* 동 단위는 최종 선택 단위라 살짝 더 크게 둔다 */
.map-page .zz-rmark--dong { padding: 6px 11px 7px; }

/* 사용자가 고른 동 */
.map-page .zz-rmark.is-selected {
    box-shadow: 0 0 0 2px #E5484D, 0 3px 10px rgba(0, 0, 0, .32);
    transform: translate(-50%, calc(-100% - 7px)) scale(1.06);
}

/* 좁은 화면에서는 글자만 한 단계 줄인다 (구조는 그대로) */
@media (max-width: 360px) {
    .map-page .zz-rmark { padding: 4px 8px 5px; min-height: 34px; }
    .map-page .zz-rmark-name { font-size: 11px; }
    .map-page .zz-rmark-n { font-size: 11px; }
    .map-page .zz-rmark-n::before { width: 5px; height: 5px; }
}

@media (prefers-reduced-motion: reduce) {
    .map-page .zz-rmark { transition: none; }
}

/* ==========================================================================
   시트 안 판매 / 구매 선택

   지도 상단에 있던 팝니다·삽니다 필터를 여기로 옮겼다.
   마커가 두 숫자를 함께 보여주므로 지도 전체를 한쪽으로 거르지 않고,
   동을 고른 뒤 목록에서만 갈라 본다.
   색은 마커와 같다 (판매 빨강 · 구매 파랑).
   ========================================================================== */

.map-page .zz-sheet-tabs {
    display: flex;
    gap: 6px;
    margin-top: 10px;
}

/* 카테고리 대분류 / 소분류 — 판매·구매 탭 바로 아래 한 줄 */
.map-page .zz-sheet-cats {
    display: flex;
    gap: 6px;
    margin-top: 8px;
}

.map-page .zz-sheet-cat {
    flex: 1;
    min-width: 0;
    min-height: 34px;
    padding: 0 10px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    color: var(--text);
    font-family: inherit;
    /* 16px 미만이면 iOS 가 선택 시 화면을 확대한다 */
    font-size: 16px;
}
.map-page .zz-sheet-cat:disabled { color: var(--text-dim); }

.map-page .zz-sheet-tab {
    display: inline-flex;
    align-items: center;
    gap: 5px;

    min-height: 34px;
    padding: 0 12px;

    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    color: var(--text-muted);

    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}

.map-page .zz-sheet-tab b {
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

.map-page .zz-sheet-tab:hover { color: var(--text); border-color: var(--border-strong); }

/* 선택 상태 : 마커와 같은 색으로 물들인다 */
.map-page .zz-sheet-tab.is-on {
    background: var(--surface-4);
    border-color: var(--border-strong);
    color: var(--text);
}
.map-page .zz-sheet-tab--sell.is-on {
    background: rgba(229, 72, 77, .16);
    border-color: rgba(229, 72, 77, .45);
    color: #ff8b8e;
}
.map-page .zz-sheet-tab--buy.is-on {
    background: rgba(47, 111, 234, .16);
    border-color: rgba(47, 111, 234, .45);
    color: #8fb4ff;
}

/* 선택하지 않았을 때도 숫자 앞의 색으로 어느 쪽인지 알린다 */
.map-page .zz-sheet-tab--sell b { color: #E5484D; }
.map-page .zz-sheet-tab--buy b { color: #5b8cf0; }
.map-page .zz-sheet-tab--sell.is-on b,
.map-page .zz-sheet-tab--buy.is-on b { color: inherit; }

@media (max-width: 360px) {
    .map-page .zz-sheet-tab { padding: 0 10px; font-size: 12px; }
}


/* ==========================================================================
   전국 거래 버튼
   --------------------------------------------------------------------------
   + 글쓰기 FAB 바로 위. 같은 오른쪽 여백(--zz-gutter + 16px)과 같은 정렬선을 쓰고,
   시트가 열리면 FAB 와 똑같이 --zz-map-fab-lift 만큼 함께 올라간다.

   시각적 우선순위는 + 보다 낮게 둔다 — 알약형 작은 글자 버튼이고 배경도 옅다.
   z-index 는 FAB 와 같은 75. 지도(mapwrap 안 400~700)보다 위,
   바텀시트(550)와 모달(200)의 바깥 계층이다.
   ========================================================================== */
.map-page .map-nation {
    position: fixed;
    right: calc(var(--zz-gutter, 0px) + 16px);
    /*
     * FAB 바닥(= tabbar + 16 + lift) + FAB 높이 48 + 사이 간격 11
     * 두 버튼 사이가 11px 이 되도록 계산한다. safe-area 는 --tabbar-total 에 이미 들어 있다.
     */
    bottom: calc(var(--tabbar-total, 62px) + 16px + var(--zz-map-fab-lift, 0px) + 48px + 11px);

    display: inline-flex;
    align-items: center;
    gap: 5px;
    /* 터치 최소 높이. 알약이라 좌우 여백을 넉넉히 준다. */
    min-height: 34px;
    padding: 0 12px;

    border: 1px solid var(--border-strong);
    border-radius: 999px;
    background: var(--surface-1, #16161a);
    color: var(--text);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .3);

    transition: bottom .18s ease;
    z-index: 75;
}

.map-page .map-nation b {
    font-weight: 700;
    font-size: 12px;
    color: var(--primary-line, #60a5fa);
}

.map-page .map-nation:active { background: var(--surface-2); }
.map-page .map-nation[hidden] { display: none; }

/* 전국 거래를 보고 있는 동안에는 눌린 상태로 표시한다 */
.map-page .map-nation.is-on {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
}
.map-page .map-nation.is-on b { color: #fff; }

@media (prefers-reduced-motion: reduce) {
    .map-page .map-nation { transition: none; }
}
