/**
 * Bản đồ — kiểu dáng. Mọi selector đóng khung trong .vvbd.
 * Không 100vw, không calc(50% - 50vw): cột RealHomes lệch trái, tràn viền tính sai.
 */

.vvbd { position: relative; }

.vvbd .vvbd-khung {
  width: 100%;
  height: clamp(320px, 55vh, 560px);
  border-radius: 2px;
  overflow: hidden;
  border: 1px solid rgba(20, 36, 29, .14);
  /* Leaflet đặt z-index nội bộ khá cao; kẹp lại để không đè menu dính của theme. */
  z-index: 0;
}

.vvbd .vvbd-chua-khai {
  padding: 2.5rem 1rem;
  text-align: center;
  color: #7A7A72;
  background: #F4EDE3;
  border-radius: 2px;
  font-size: .9375rem;
}

/* ==========================================================================
   Nhãn tên dự án cạnh ghim
   ==========================================================================
   Du: "nhãn tên dự án thiết kế lại cho đẹp hơn, đừng có nhìn đen đen xấu xấu".

   Bản cũ là khối đặc `#14241D` bo 2px — trên nền bản đồ sáng nó là những vệt
   đen nặng, và khi sáu bảy dự án đứng gần nhau thì bản đồ trông như bị dán
   nhãn giá. Nay lật sang thẻ SÁNG chữ tối: nhẹ đi hẳn, mà chữ lại tương phản
   TỐT HƠN (chữ tối trên nền sáng dễ đọc hơn chữ kem trên nền tối ở cỡ 12px).

   ⚠️ Nhãn tên và nhãn đo giờ CÙNG HỌ SÁNG, nên phải có một dấu hiệu tách
   chúng ra — nếu không là quay lại đúng lời phê "nhìn giống nhãn tên dự án
   quá". Dấu hiệu ấy là ĐƯỜNG VIỀN, và nó mang nghĩa thật:

       viền LIỀN  → một cái TÊN (thứ cố định, đã có thật)
       viền ĐỨT   → một SỐ ĐO (thứ vừa tính ra, đổi theo chỗ khách bấm)

   Cùng quy ước liền/đứt đang dùng cho tuyến hạ tầng, nên khách chỉ phải học
   một lần cho cả bản đồ. */
.vvbd .vvbd-nhan-du-an {
  background: rgba(255, 253, 249, .94);
  color: #14241D;
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: .1px;
  padding: 4px 9px;
  border: 1px solid rgba(20, 36, 29, .12);
  border-radius: 999px;
  white-space: nowrap;
  width: auto !important;
  height: auto !important;
  box-shadow: 0 1px 2px rgba(20, 36, 29, .10), 0 3px 10px rgba(20, 36, 29, .14);
  /* v1.91.0 — NHÃN LÀ ĐỂ ĐỌC, KHÔNG PHẢI ĐỂ BẤM (Du chốt 26/08).
   *
   * Thẻ nhãn nằm pane 650, trên pane ghim 640, và Leaflet KHÔNG tắt
   * pointer-events cho marker `interactive:false` — nó chỉ thôi bắn sự kiện
   * của riêng marker. Nên chỗ nào nhãn phủ lên một chấm là chỗ ấy chấm mất
   * hẳn đường vào: không mở được thẻ dự án, không đặt được làm mốc đo, rê
   * lên không hiện được tên nó. Đúng lời hứa của hướng (c) — "chấm LUÔN
   * CÒN, bấm vào vẫn ra thẻ đầy đủ" — đang sai ở đó.
   *
   * Trên điện thoại nặng hơn: không có rê chuột nên chấm bị nuốt cú chạm là
   * mất hẳn dự án, không đường vòng nào.
   *
   * ⚠️ CHỈ nhãn TÊN DỰ ÁN. Ghim vùng (`.vvbd-ghim-vung`) phải bấm được — nó
   * là cửa drill vào khu vực. Đã soát: không handler nào gắn lên nhãn tên. */
  pointer-events: none;
}

/* Popup — luật hộp (margin/width) DỜI XUỐNG khối v1.59.0 ở cuối tệp. Để lại
   một luật `.vvbd .leaflet-popup-content` ở đây nữa là hai luật cùng bộ chọn
   cho cùng một thuộc tính: người sửa sau đọc trúng cái trên rồi tưởng mình
   đang đổi thứ đang có hiệu lực. */
.vvbd .vvbd-pop-ten { display: block; font-size: 14px; margin-bottom: 4px; color: #14241D; }
.vvbd .vvbd-pop-dong { display: block; font-size: 12.5px; color: #4a4a44; line-height: 1.5; }
.vvbd .vvbd-pop-dong em { color: #7A7A72; font-style: italic; }

/* v1.1.0 — icon tiện ích dạng emoji trên nền tròn trắng, viền màu nhóm */
.vvbd .vvbd-icon-ti span {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  background: #FFFDF9;
  border: 2px solid #7A7A72;
  border-radius: 50%;
  font-size: 16px; line-height: 1;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
}
/* Hình vector (Maki CC0) thay emoji từ v1.28.0. `flex-shrink` giữ hình khỏi
   bị bóp méo khi huy hiệu chật; `display:block` bỏ khoảng trắng dòng chữ mà
   SVG inline mặc định để lại dưới đáy, thứ làm hình lệch lên trên một hai
   pixel — nhìn một cái không thấy, nhìn hai chục cái thì thấy cả hàng lệch. */
.vvbd .vvbd-icon-ti span > svg { display: block; flex: 0 0 auto; }

/* ==========================================================================
   Ga metro — nhãn tên
   ==========================================================================
   Tooltip mặc định của Leaflet có nền trắng, viền, mũi nhọn: 14 cái như thế
   trên một tuyến là 14 hộp thoại chen nhau. Ở đây bỏ hết khung, chỉ còn chữ
   có viền trắng để đọc được trên mọi nền bản đồ.

   Dùng px chứ KHÔNG dùng rem: site đặt html{font-size:62.5%} nên 1rem = 10px,
   mọi rem ở đây sẽ co lại còn 62,5% — đúng bệnh đã phải vá ở villaverde-blocks.
   ========================================================================== */
/* ==========================================================================
   Dấu ngắt cửa hầm (v1.99.0)
   ==========================================================================
   Vạch MỰC vuông góc với hướng tuyến, đánh dấu chỗ tuyến chui xuống đất.
   Mực là hằng số — bản đồ có nhiều tuyến, mỗi tuyến một màu, nên một ký hiệu
   lấy màu từ tuyến sẽ đọc khác nhau ở mỗi tuyến.

   Thẻ ngoài xoay theo HƯỚNG TUYẾN (`goc`); cái vạch nằm vuông góc sẵn ở đây.
   Nhờ vậy `goc` mang đúng một nghĩa và người đặt tay không phải tự cộng 90°.

   Viền trắng hai bên để vạch tách khỏi chính tuyến nó cắt qua — không có nó
   thì vạch mực nằm trên tuyến sẫm màu là mất hút. */
/* Điểm mốc (v1.108.0) — vòng có tâm rỗng, đọc ra ĐÚNG MỘT toạ độ.
   Cố ý KHÔNG giống chấm ga: chấm ga là nội dung của bản đồ, mốc là giàn giáo.
   Trông giống nhau thì lúc xuất ra không ai biết cái nào là cái nào. */
.vvbd .vvbd-diem-moc { background: none; border: 0; }
.vvbd .vvbd-diem-moc i {
  display: block;
  width: 14px;
  height: 14px;
  box-sizing: border-box;
  border: 2px solid #14241D;
  border-radius: 50%;
  background: rgba(255, 255, 255, .85);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .9);
}
/* Chấm tâm — cái mắt cần để biết chỗ CHÍNH XÁC nằm đâu trong vòng. */
.vvbd .vvbd-diem-moc i::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 3px;
  height: 3px;
  margin: -1.5px 0 0 -1.5px;
  border-radius: 50%;
  background: currentColor;
  color: inherit;
}

.vvbd .vvbd-cua-ham {
  background: none;
  border: 0;
}

.vvbd .vvbd-cua-ham i {
  display: block;
  width: 24px;
  height: 24px;
  position: relative;
}

/* 🔴 VẠCH NẰM NGANG, không nằm dọc — Du 27/08: *"cửa hầm phải xoay được
   nha, chứ để thẳng tưng mà đường tuyến nó đâu có thẳng"*.

   Bản trước vẽ vạch DỌC. Mà `goc` mang nghĩa HƯỚNG TUYẾN đo từ phương bắc,
   nên góc 0 nghĩa là tuyến chạy dọc — và một vạch dọc ở góc 0 thì nằm SONG
   SONG với tuyến, đúng thứ ngược lại với ý đồ. Vạch phải nằm ngang ở góc 0
   thì mọi góc sau đó mới vuông góc.

   Kiểm nhanh: góc 90 (tuyến chạy đông–tây) ⇒ xoay vạch ngang 90° ⇒ vạch dọc
   ⇒ vẫn vuông góc. Đúng ở mọi góc. */
.vvbd .vvbd-cua-ham i::before {
  content: '';
  position: absolute;
  left: 1px;
  top: 10px;
  width: 22px;
  height: 4px;
  border-radius: 1px;
  background: #2C2C2A;
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, .95);
}

/* ==========================================================================
   Nhãn ga — VIÊN MÃ (v1.97.0)
   ==========================================================================
   Trước bản này nhãn ga là TÊN ĐẦY ĐỦ, thường trực. Trên tuyến metro 2 nghĩa
   là những chuỗi kiểu `C8 · QL13 – AEON Mall Bình Dương` — 32 ký tự, ~190px —
   nằm ngang khắp bản đồ và đè lên đúng thứ đáng tiền nhất: tên dự án.

   Nay nhãn thường trực chỉ còn MÃ GA trong một viên bo tròn ~32px, tên đầy đủ
   mọc ra bên cạnh khi rê chuột.

   NỀN VIÊN LÀ MÀU TUYẾN, không phải chữ trần: khi bản đồ có hai ba tuyến, một
   chữ `C8` lơ lửng thì không ai biết nó thuộc tuyến nào. Cùng quy ước với MRT
   Singapore, BTS Bangkok, tàu điện Seoul — khách đi tàu ở đâu về cũng đọc
   được ngay, không cần chú giải.

   Màu nền đặt bằng biến `--vvbd-ga-mau` do JS gắn theo màu lớp; khoảng cách
   tới chấm đặt bằng `--vvbd-ga-lech` vì bán kính chấm co theo zoom. */
.vvbd .vvbd-nhan-ga {
  background: none;
  border: 0;
  box-shadow: none;
  padding: 0;
  white-space: nowrap;
  transition: opacity .15s ease;
  display: flex;
  align-items: center;
  gap: 5px;
}

.vvbd .vvbd-nhan-ga::before { display: none; }  /* mũi nhọn của tooltip */

/* Leaflet gắn sẵn `leaflet-tooltip-left/right` khi nó tự lật chiều. Đẩy nhãn
   ra khỏi chấm bằng margin ở ĐÂY chứ không bằng tuỳ chọn `offset` của Leaflet:
   Leaflet cộng offset y như nhau ở cả hai chiều, nên một offset dương đẩy nhãn
   sang phải kể cả khi nó đã lật sang trái — tức nhãn chạy đè lên chấm đúng lúc
   lật. CSS thì tự biết chiều. */
.vvbd .leaflet-tooltip-right.vvbd-nhan-ga { margin-left: var(--vvbd-ga-lech, 12px); }
.vvbd .leaflet-tooltip-left.vvbd-nhan-ga  { margin-left: calc(-1 * var(--vvbd-ga-lech, 12px)); }

.vvbd .vvbd-ga-ma {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 9px;
  background: var(--vvbd-ga-mau, #B08D57);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: .02em;
  /* Viền trắng mảnh tách viên khỏi nền bản đồ đậm (khu công nghiệp, mặt nước)
     mà không cần đổ bóng — bóng trên Safari iOS từng lem thành một vệt xám. */
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, .9);
}

/* Ga ước lượng: viên viền đứt, cùng ngôn ngữ với chấm và với tuyến chưa chốt.
   Ruột nhạt đi để cả cụm đọc ra "chưa chắc" ngay cả khi nét đứt quá nhỏ. */
.vvbd .vvbd-nhan-ga-ul .vvbd-ga-ma {
  background: transparent;
  color: var(--vvbd-ga-mau, #B08D57);
  border: 1.5px dashed var(--vvbd-ga-mau, #B08D57);
  padding: 1px 6px;
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, .9);
}

/* Tên đầy đủ — in ra CÙNG LÚC với viên, chỉ bị giấu. Đổi nội dung tooltip lúc
   rê chuột thì viên phình ra ngay dưới con trỏ, con trỏ rơi ra ngoài, viên co
   lại, rồi lại phình: một cái nhãn tự đuổi con trỏ. */
.vvbd .vvbd-ga-ten {
  display: none;
  padding: 2px 7px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .94);
  color: #2b2b2b;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.3;
}

.vvbd .vvbd-nhan-ga-mo .vvbd-ga-ten { display: inline-block; }

/* Ga CHƯA CÓ MÃ: không có viên, nhãn chỉ hiện khi rê chuột (Leaflet tự mở/đóng
   vì tooltip không permanent). Giữ nguyên kiểu chữ viền trắng đời cũ. */
.vvbd .vvbd-nhan-ga-tron {
  font-size: 11px;
  font-weight: 600;
  line-height: 1.2;
  color: #2b2b2b;
  text-shadow:
    -1px -1px 0 #fff,  1px -1px 0 #fff,
    -1px  1px 0 #fff,  1px  1px 0 #fff,
     0   -1px 0 #fff,  0    1px 0 #fff,
    -1px  0   0 #fff,  1px  0   0 #fff;
}

/* Dòng ghi công nguồn trong popup — nhỏ, mờ, nhưng có mặt.
   ODbL đòi ghi công khi dùng lại hình học, không chỉ khi dùng ảnh nền. */
.vvbd .vvbd-pop-nguon {
  display: block;
  margin-top: 6px;
  font-size: 10px;
  line-height: 1.3;
  color: #8a8a8a;
}

/* ==========================================================================
   Làm nhạt nền tile
   ==========================================================================
   Nền OSM chuẩn (Carto standard) vẽ rất nhiều: đường nhỏ, ranh phường, nhãn
   khu công nghiệp, ao hồ. Đọc bản đồ hành chính thì tốt, nhưng khi mình thả
   tuyến và ghim lên trên thì chúng chìm lẫn vào đám đó.

   VÌ SAO KHÔNG ĐỔI SANG CARTODB POSITRON — kiểu nền tối giản mà mọi hướng dẫn
   đều khuyên: CARTO đã siết điều khoản, tile của họ nay chỉ dành cho khách
   Enterprise và tổ chức phi lợi nhuận được cấp grant. villaverde.vn là site
   bán hàng, tức thương mại — dùng là sai giấy phép. Stamen cũng loại (đã
   chuyển sang Stadia Maps từ 10/2023, phải đăng ký).

   Nên: giữ nguyên tile OSM đang dùng, chỉ hạ tông bằng CSS. Không thêm phụ
   thuộc, không thêm rủi ro pháp lý, không thêm một máy chủ nữa phải trông.

   FILTER CHỈ ÁP CHO LỚP TILE. Overlay (tuyến, ghim, ga, nhãn) nằm ở pane khác
   nên giữ nguyên màu — đó chính là điều mình muốn: nền lùi, dữ liệu của mình
   tiến lên.
   ========================================================================== */
.vvbd .leaflet-tile-pane {
  filter: grayscale(var(--vvbd-nen-xam, .7))
          brightness(var(--vvbd-nen-sang, 1.04))
          contrast(var(--vvbd-nen-tuong-phan, .9));
}

/* ⚠️ MỨC MẶC ĐỊNH ĐÃ NỚI Ở v1.5.0.
   Bản v1.4.0 để .85/1.08/.82 — Du chụp màn hình và nói đúng: nhạt tới mức đó
   thì ĐƯỜNG VÀNH ĐAI 3 trên nền chìm luôn. Đây là hệ quả tôi không lường:
   làm nhạt nền thì làm nhạt CẢ thông tin nằm trên nền, mà Vành đai 3 lại là
   thứ trước đó tôi vẫn nói "OSM vẽ sẵn rồi, khỏi cần vẽ".

   Cách chữa THẬT không nằm ở đây mà ở nút Nạp: tuyến nào quan trọng với dự án
   thì phải là LỚP CỦA MÌNH, không phải chi tiết trên nền — lớp của mình không
   dính filter, lại có viền trắng. Nới mức mặc định chỉ là đỡ gắt phần nào. */

/* Ba mức đặt sẵn — admin chọn, không phải sửa code.
   Giá trị gắn ở phần tử .vvbd nên mỗi bản đồ tự mang mức của nó. */
.vvbd[data-vvbd-nen="goc"] .leaflet-tile-pane { filter: none; }

.vvbd[data-vvbd-nen="rat-nhat"] {
  --vvbd-nen-xam: 1;
  --vvbd-nen-sang: 1.16;
  --vvbd-nen-tuong-phan: .68;
}

/* ==========================================================================
   v1.6.0 — Chú giải có công tắc
   ==========================================================================
   Thay `L.control.layers` mặc định của Leaflet. Layers control chỉ liệt kê
   TÊN lớp; bản đồ của mình có nét liền/nét đứt mang nghĩa khác nhau, nên chỗ
   bật/tắt cũng phải là chỗ GIẢI THÍCH — nếu không, nét đứt là một quy ước
   không ai nói cho khách biết.
   ========================================================================== */
.vvbd .vvbd-chu-giai {
  background: rgba(255, 253, 249, .95);
  border: 1px solid rgba(20, 36, 29, .18);
  border-radius: 2px;
  box-shadow: 0 1px 5px rgba(0, 0, 0, .2);
  font-size: 12px;
  line-height: 1.35;
  max-width: 268px;
  overflow: hidden;
}

.vvbd .vvbd-cg-nut {
  display: block;
  width: 100%;
  border: 0;
  border-bottom: 1px solid rgba(20, 36, 29, .12);
  background: #F4EDE3;
  color: #14241D;
  font: inherit;
  font-weight: 700;
  text-align: left;
  padding: 6px 10px;
  cursor: pointer;
}

/* ⚠️ v1.72.0 — HAI LUẬT `::after` CŨ ĐÃ Ở ĐÂY BỊ XOÁ. ĐÂY LÀ GỐC THẬT CỦA
   LỖI "icon thu gọn bị lỗi" mà Du báo hai lần.

   Chúng khai mũi tên bằng KÝ TỰ:

       .vvbd .vvbd-cg-nut::after          { content: " ▾" }   (0,2,1)
       .vvbd .vvbd-cg-thu .vvbd-cg-nut::after { content: " ▸" }   (0,3,1)

   Tàn dư từ trước v1.59.0. Luật mới ở cuối tệp khai `content:''` + hình vẽ,
   nhưng nó chỉ có độ đặc hiệu (0,2,1). Nên:

     - trạng thái MỞ: hai luật hoà (0,2,1), luật SAU thắng ⇒ `content:''`
       ⇒ chỉ có hình vẽ ⇒ NHÌN BÌNH THƯỜNG;
     - trạng thái GẬP: luật `.vvbd-cg-thu` mạnh hơn (0,3,1) ⇒ `content` là
       ký tự " ▸", mà hình vẽ nền VẪN ĐƯỢC TÔ ⇒ HAI HÌNH CHỒNG LÊN NHAU.

   Đúng câu Du hỏi: "nó là 2 cái icon chồng lên nhau?". Và nó cũng giải
   thích luôn vì sao bản v1.71.0 đổi sang SVG mà vẫn hỏng — em thay cái hình
   thứ nhất trong khi thủ phạm là cái thứ hai vẫn nằm nguyên đó.

   BÀI HỌC (lần thứ TƯ trong module này): hai cơ chế cùng làm một việc thì
   người sửa sau đọc trúng một cái rồi tưởng mình đang đổi thứ đang có hiệu
   lực. Trước đã dính với luật gập CSS (v1.67.0) và với hai luật
   `.leaflet-popup-content` (v1.59.0). Sửa xong phải đi TÌM VÀ XOÁ bản cũ,
   không được để lại "cho chắc". */
/* v1.67.0 — GỠ luật gập bằng CSS. Từ nay JS ghi thẳng style.display kèm
   !important; để lại luật này là hai cơ chế song song cho cùng một việc,
   và người sửa sau không biết cái nào đang có hiệu lực. */

.vvbd .vvbd-cg-than { padding: 5px 9px 7px; max-height: 300px; overflow-y: auto; }

.vvbd .vvbd-cg-dong {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  padding: 3px 0;
  cursor: pointer;
}

.vvbd .vvbd-cg-dong input { margin: 3px 0 0; flex: 0 0 auto; }

/* Mẫu nét: một vệt màu đúng bằng màu tuyến, đứt hay liền y như trên bản đồ.
   Đây là phần khiến chú giải giải thích được, chứ không chỉ liệt kê. */
.vvbd .vvbd-cg-mau {
  flex: 0 0 auto;
  width: 20px;
  height: 4px;
  margin-top: 6px;
  border-radius: 2px;
  background: var(--vvbd-cg-mau, #7A7A72);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .9);
}

.vvbd .vvbd-cg-dut {
  background: repeating-linear-gradient(
    to right,
    var(--vvbd-cg-mau, #7A7A72) 0 5px,
    transparent 5px 9px
  );
  box-shadow: none;
}

/* Nhóm tiện ích hiện bằng chấm tròn, không phải vệt — chúng là điểm, không
   phải tuyến; dùng cùng một mẫu là dạy khách một quy ước sai. */
.vvbd .vvbd-cg-cham {
  width: 10px;
  height: 10px;
  margin: 3px 5px 0;
  border-radius: 50%;
}

.vvbd .vvbd-cg-trong { background: none; box-shadow: none; }

.vvbd .vvbd-cg-chu b { display: block; font-weight: 600; color: #14241D; }
.vvbd .vvbd-cg-chu i {
  display: block;
  font-style: normal;
  font-size: 10.5px;
  color: #7A7A72;
  margin-top: 1px;
}

/* ==========================================================================
   v1.6.0 — Chữ trên bản đồ
   ==========================================================================
   Hai kiểu chữ, hai cơ chế khác nhau:
     .vvbd-chu-doc  — SVG <text> gắn vào <textPath>, chạy dọc đường. Nằm trong
                      overlay SVG nên KHÔNG dính filter làm nhạt nền.
     .vvbd-chu-noi  — divIcon, xoay bằng transform ở span bên trong (xoay ở
                      marker là ghi đè translate3d của Leaflet).
   ========================================================================== */
.vvbd .vvbd-chu-doc {
  font-weight: 700;
  letter-spacing: .2px;
  paint-order: stroke;
  stroke: #ffffff;
  stroke-width: 3px;
  stroke-linejoin: round;
  pointer-events: none;
}

.vvbd .vvbd-chu-noi { width: auto !important; height: auto !important; }

.vvbd .vvbd-chu-noi > span {
  display: inline-block;
  transform-origin: 0 50%;
  white-space: nowrap;
  font-weight: 700;
  line-height: 1.15;
  text-shadow:
    -1px -1px 0 #fff,  1px -1px 0 #fff,
    -1px  1px 0 #fff,  1px  1px 0 #fff,
     0   -1px 0 #fff,  0    1px 0 #fff,
    -1px  0   0 #fff,  1px  0   0 #fff;
}

/* Nhãn của một vùng khoanh đặt ở tâm vùng — kéo về giữa cả hai chiều để không
   lệch sang phải như nhãn điểm. */
.vvbd .vvbd-chu-vung > span { transform-origin: 50% 50%; }
.vvbd .vvbd-chu-vung { transform: translate(-50%, -50%); }

/* ==========================================================================
   v1.7.0 — Watermark
   ==========================================================================
   ⚠️ RÀNG BUỘC CỨNG: watermark KHÔNG được che dòng ghi công OpenStreetMap.
   Ghi công là nghĩa vụ giấy phép ODbL; che nó là dùng sai phép — cùng loại
   rủi ro đã khiến plugin từ chối tile CARTO và Stamen.

   Leaflet đặt dòng ghi công ở góc DƯỚI-PHẢI. Nên hai vị trí dưới phải chừa
   chỗ cho nó bằng margin-bottom, chứ không phải bằng z-index (đè lên rồi hạ
   độ mờ vẫn là đè).
   ========================================================================== */
.vvbd .vvbd-wm {
  font-size: 12px;
  line-height: 1.2;
  color: #14241D;
  text-align: right;
  padding: 4px 7px;
  border-radius: 2px;
  background: rgba(255, 253, 249, .72);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .18);
  /* Chữ để NHÌN, không phải để bấm — bắt chuột là nó nuốt cú bấm lẽ ra thuộc
     về bản đồ, đúng ở cái góc người ta hay bấm. */
  pointer-events: none;
  user-select: none;
}

.vvbd .vvbd-wm b {
  display: block;
  font-weight: 700;
  letter-spacing: .2px;
}

.vvbd .vvbd-wm i,
.vvbd .vvbd-wm .vvbd-wm-goi {
  display: block;
  font-style: normal;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .3px;
}
/* Số điện thoại: màu xanh CỐ Ý trên mọi máy, và bấm được. Trước đây màu
   xanh chỉ có trên iOS — do Safari tự dò số rồi tự bọc link — nên máy tính
   không có, mà trên iOS thì `pointer-events:none` của watermark lại chặn
   mất cú chạm: trông y hệt link mà không phải link. `auto` ở đây là ngoại
   lệ DUY NHẤT được mở lại trong watermark. */
.vvbd .vvbd-wm .vvbd-wm-goi {
  color: #0A84FF;
  text-decoration: none;
  pointer-events: auto;
  cursor: pointer;
}
.vvbd .vvbd-wm .vvbd-wm-goi:hover,
.vvbd .vvbd-wm .vvbd-wm-goi:focus { text-decoration: underline; color: #0A84FF; }

/* Chừa chỗ cho dòng ghi công của Leaflet ở hàng dưới cùng. */
.vvbd .vvbd-wm-duoi-phai,
.vvbd .vvbd-wm-duoi-trai { margin-bottom: 22px; }

.vvbd .vvbd-wm-duoi-trai,
.vvbd .vvbd-wm-tren-trai { text-align: left; }

/* ==========================================================================
   v1.8.0 — Bản đồ nhiều dự án
   ========================================================================== */

/* Ô chọn "đo khoảng cách tới dự án nào". Chỉ có ở bản đồ tổng. */
.vvbd .vvbd-cg-chon {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 2px 0 7px;
  margin-bottom: 5px;
  border-bottom: 1px solid rgba(20, 36, 29, .12);
}
.vvbd .vvbd-cg-chon span { font-size: 11px; color: #7A7A72; }
.vvbd .vvbd-cg-chon select { max-width: 100%; font-size: 12px; }

/* Ghim dự án KHÔNG phải mốc đo: nhạt hơn, nhãn nhỏ hơn. Ba nhãn cùng cỡ thì
   không đọc ra dự án nào đang là gốc của mọi con số trên popup. */
.vvbd .vvbd-nhan-phu {
  background: rgba(20, 36, 29, .72);
  font-size: 11px;
  font-weight: 500;
  padding: 3px 7px;
}

/* Dòng phụ trong popup — km đường chim bay khi đã có km đường bộ. Nó vẫn cần
   có mặt (số tự tính, đúng tuyệt đối) nhưng không được cạnh tranh với số đo. */
.vvbd .vvbd-pop-nhe { color: #8a8a82; font-size: 11.5px; }

/* v1.12.0 — thẻ mọc vào chỗ bản đồ của theme. Chiều cao chép từ thẻ cũ trong
   JS; ở đây chỉ đặt mức sàn phòng khi thẻ cũ chưa có chiều cao lúc đo. */
.vvbd.vvbd-soan { display: block; min-height: 320px; }
.vvbd .vvbd-khung { min-height: 100%; }

/* v1.19.0 — ghim CHỌN vị trí trong admin. Đỏ và có vòng nhịp, để không lẫn với
   ghim vàng của dự án: hai ghim cùng màu thì kéo nhầm cái không kéo được. */
.vvbd .vvbd-ghim-chon > span {
  display: block;
  width: 18px;
  height: 18px;
  margin: 2px;
  border-radius: 50%;
  background: #B0574F;
  border: 3px solid #fff;
  box-shadow: 0 0 0 2px rgba(176, 87, 79, .5), 0 1px 4px rgba(0, 0, 0, .4);
  cursor: move;
}

/* v1.24.0 — nhãn ghim mờ khi bộ lọc Tìm căn báo dự án 0 căn khớp */
.vvbd .vvbd-nhan-mo { opacity: 0.45; }

/* ==================================================================
 * v1.53.0 — Chỉ đường + Toàn màn hình
 * ================================================================== */

/* Link mở Google Maps trong popup — cách khối số một nhịp cho khỏi dính. */
.vvbd .vvbd-pop-chi-duong {
  display: inline-block;
  margin-top: 7px;
  font-size: 12.5px;
  font-weight: 600;
  color: #4C7EA8;
  text-decoration: none;
  border-bottom: 1px solid rgba(76, 126, 168, 0.35);
}
.vvbd .vvbd-pop-chi-duong:hover { border-bottom-color: #4C7EA8; }

/* Nút toàn màn hình — cùng khổ nút zoom của Leaflet cho thẳng cột. */
.vvbd .vvbd-nut-mh {
  width: 30px;
  height: 30px;
  padding: 0;
  border: 2px solid rgba(0, 0, 0, 0.2);
  border-radius: 4px;
  background: #fff;
  color: #14241D;
  font-size: 16px;
  line-height: 26px;
  cursor: pointer;
}
.vvbd .vvbd-nut-mh:hover { background: #f4f4f4; }

/* Trạng thái phủ toàn trang. z-index phải cao hơn header dính của theme
 * (RealHomes dùng ~1000) nhưng để dưới trần 2147483647 cho các overlay
 * khẩn (cookie, admin bar khi đăng nhập vẫn thấy được nếu cần). */
.vvbd.vvbd-man-hinh {
  position: fixed;
  inset: 0;
  z-index: 100000;
  margin: 0;
  background: #fff;
}
.vvbd.vvbd-man-hinh .vvbd-khung {
  width: 100%;
  height: 100% !important;
  min-height: 100%;
}
/* Khoá cuộn trang phía sau — không thì chạm kéo trên iOS cuộn cả body. */
html.vvbd-khoa-cuon, html.vvbd-khoa-cuon body { overflow: hidden; }

/* ==================================================================
 * v1.54.0 — Popup thẻ dự án + ghim vùng (chế độ phân cấp)
 * ================================================================== */

.vvbd .vvbd-card-anh {
  display: block;
  width: 100%;
  max-width: 240px;
  height: 120px;
  object-fit: cover;
  border-radius: 3px;
  margin-bottom: 8px;
}
.vvbd .vvbd-card-xem {
  display: block;
  margin-top: 8px;
  padding: 6px 10px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  color: #fff;
  background: #14241D;
  border-radius: 3px;
  text-decoration: none;
}
.vvbd .vvbd-card-xem:hover { background: #B08D57; color: #fff; }

/* Ghim vùng: hộp nhãn to, tự co theo chữ (iconSize null).
 * ⚠️ Style nằm ở SPAN BÊN TRONG, không ở chính marker — Leaflet đặt
 * transform: translate3d(...) lên phần tử marker để định vị, đè transform
 * lên đó là ghim bay sai chỗ (bài học đã khắc ở nhanNoi). Căn giữa bằng
 * translate của span. */
.vvbd .vvbd-ghim-vung { width: auto !important; height: auto !important; }
.vvbd .vvbd-ghim-vung .vvbd-gv {
  display: block;
  padding: 7px 12px;
  background: #14241D;
  color: #fff;
  border-radius: 4px;
  border: 2px solid #B08D57;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
  cursor: pointer;
  white-space: nowrap;
  transform: translate(-50%, -50%);
}
.vvbd .vvbd-ghim-vung b { display: block; font-size: 13.5px; }
.vvbd .vvbd-ghim-vung i { display: block; font-style: normal; font-size: 11px; color: #d8cbb4; }

/* ==================================================================
 * v1.58.0 — So sánh 2 dự án + mini-map định vị
 * ================================================================== */

/* ==================================================================
 * v1.71.0 — NHÃN ĐO KHOẢNG CÁCH
 * ==================================================================
 * Du: "nhìn nó giống nhãn tên dự án quá". Đúng — bản cũ là viên thuốc
 * `#14241D` chữ kem bo 999px, tức GIỐNG HỆT `.vvbd-nhan-du-an`, khác mỗi
 * đường viền vàng 1px mà ở cỡ ấy thì không ai thấy.
 *
 * Nhãn tên dự án là MỘT ĐỊA DANH; nhãn đo là MỘT SỐ ĐO. Hai loại thông
 * tin khác nhau phải nhìn ra khác nhau NGAY, trước khi đọc chữ. Nên đảo
 * hẳn sắc độ: thẻ nền sáng, viền vàng, chữ tối, góc vuông hơn — trông ra
 * một cái phiếu đo chứ không phải một cái biển tên.
 */
.vvbd .vvbd-nhan-do {
  background: rgba(255, 253, 249, .66);
  color: #14241D;
  /* Du chốt: khung NÉT ĐỨT. Không chỉ vì đẹp — nét đứt là quy ước ĐANG DÙNG
     của chính việc đo (hai đoạn nối tới điểm cũng nét đứt), nên cái khung
     nhắc lại đúng thứ ngôn ngữ ấy. Và nó là dấu hiệu tách nhãn ĐO khỏi nhãn
     TÊN DỰ ÁN mà không cần hai bảng màu khác nhau: đo = đứt, tên = liền. */
  border: 1px dashed rgba(176, 141, 87, .95);
  border-radius: 9px;
  padding: 5px 10px;
  font-size: 11.5px;
  line-height: 1.4;
  white-space: nowrap;
  -webkit-backdrop-filter: blur(6px) saturate(1.15);
  backdrop-filter: blur(6px) saturate(1.15);
  box-shadow: 0 2px 10px rgba(20, 36, 29, .12);
}
.vvbd .vvbd-nhan-do::before { display: none; } /* bỏ mũi tên tooltip */
.vvbd .vvbd-do-dau {
  display: block;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .6px;
  text-transform: uppercase;
  opacity: .5;
  margin-bottom: 2px;
}
.vvbd .vvbd-do-dong { display: flex; align-items: center; gap: 6px; }
.vvbd .vvbd-do-cham {
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  font-style: normal;
}
/* `<b>` PHẢI tự khai màu: theme RealHomes có luật trần
   `b,strong{color:var(--rh-global-color-headings)}` khai THẲNG lên thẻ, mà
   khai trực tiếp luôn thắng giá trị THỪA KẾ bất kể độ đặc hiệu — đúng bẫy
   đã làm mờ tên vùng ở v1.62.0. */
.vvbd .vvbd-do-dong b { font-weight: 600; color: #14241D; }
.vvbd .vvbd-do-dong em {
  font-style: normal;
  font-weight: 700;
  margin-left: auto;
  padding-left: 4px;
  font-variant-numeric: tabular-nums;
  color: #14241D;
}

.vvbd .vvbd-mini {
  width: 150px;
  height: 110px;
  border: 2px solid rgba(20, 36, 29, 0.55);
  border-radius: 3px;
  overflow: hidden;
  background: #eee;
  box-shadow: 0 1px 6px rgba(0, 0, 0, 0.25);
  cursor: pointer;
}
/* Điện thoại: bản đồ đã nhỏ, la bàn 150px che mất nó. */
@media (max-width: 560px) {
  .vvbd .vvbd-mini { display: none; }
}

/* ==================================================================
 * v1.59.0 — LỚP KIỂU DÁNG "THẺ NỔI"
 * ==================================================================
 * Du gửi 4 ảnh 25/08 + 1 ảnh tham chiếu (bản đồ thuê nhà kiểu Google).
 * Đọc ra ba bệnh HÌNH THỂ, không phải bệnh màu:
 *
 *   1. CỘT PHẢI BA TẦNG CHỒNG NHAU. Chú giải mọc từ trên xuống; mini-map và
 *      watermark mọc từ dưới lên; cả ba cùng cột phải. Ảnh 2–4: mini-map đè
 *      mất dòng "Làm việc & KCN", watermark in xuyên qua chữ chú giải.
 *      → mini-map dời sang dưới-TRÁI (JS) + thân chú giải có TRẦN chiều cao
 *        và tự cuộn (dưới đây).
 *   2. THẺ POPUP RỘNG GẤP RƯỠI NỘI DUNG. Ảnh 2–3: thẻ ~445px mà chữ chỉ
 *      chiếm 240px, thừa một mảng trắng bên phải. Leaflet ghi thẳng
 *      `style.width` lên `.leaflet-popup-content` sau khi đo; theme RealHomes
 *      cũng có luật riêng cho Leaflet (bản đồ property của nó). Trả về `auto`
 *      rồi kẹp bằng min/max mới chắc — và phải `!important` vì đối thủ là
 *      style NỘI TUYẾN.
 *   3. NÚT VUÔNG VIỀN ĐEN. Nút zoom mặc định của Leaflet (viền
 *      `2px rgba(0,0,0,.2)`, góc 4px) là hình hài 2011. Bản đồ BĐS bây giờ
 *      đều một kiểu: nút TRẮNG, BO TRÒN, đổ bóng mềm, không viền cứng.
 *
 * ⚠️ VÌ SAO GẦN NHƯ CHỖ NÀO CŨNG `!important`: Leaflet dùng CHUNG với theme
 * (luật §3 của module), nên luật Leaflet của RealHomes áp lên đúng các phần
 * tử này. Thêm nữa theme có luật liệt kê trần `button` và `.realhomes-round-
 * corners button` (0,2,0) — bài học đã trả giá ở villaverde-blocks v1.10.0.
 * Mọi luật dưới đây đều tiền tố `.vvbd` nên KHÔNG rò ra bản đồ nào khác.
 *
 * ⚠️ KHÔNG dùng `transform` / `filter` / `backdrop-filter` ở tầng `.vvbd`:
 * `.vvbd.vvbd-man-hinh` là `position:fixed`, tổ tiên mang mấy thứ đó là nó
 * neo nhầm khối chứa (bài học 25/08).
 * ================================================================== */

/* ---- Khung ngoài: bo góc sâu hơn, viền nhạt đi ---- */
.vvbd .vvbd-khung {
  border-radius: 14px;
  border-color: rgba(20, 36, 29, .10);
  box-shadow: 0 1px 2px rgba(20, 36, 29, .05), 0 6px 24px rgba(20, 36, 29, .08);
}
/* Toàn màn hình thì bo góc là thừa — không có gì bên ngoài để bo cho tách. */
.vvbd.vvbd-man-hinh .vvbd-khung { border-radius: 0; box-shadow: none; }

/* ---- Nút zoom + nút toàn màn hình: trắng, tròn, bóng mềm ---- */
.vvbd .leaflet-control-zoom {
  border: 0 !important;
  border-radius: 10px !important;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(20, 36, 29, .12), 0 4px 14px rgba(20, 36, 29, .16);
}
.vvbd .leaflet-control-zoom a {
  width: 34px !important;
  height: 34px !important;
  line-height: 34px !important;
  background: #FFFDF9 !important;
  color: #14241D !important;
  border: 0 !important;
  border-bottom: 1px solid rgba(20, 36, 29, .09) !important;
  border-radius: 0 !important;
  font-size: 19px !important;
  font-weight: 400 !important;
}
.vvbd .leaflet-control-zoom a:last-child { border-bottom: 0 !important; }
.vvbd .leaflet-control-zoom a:hover,
.vvbd .leaflet-control-zoom a:focus { background: #F4EDE3 !important; color: #14241D !important; }
.vvbd .leaflet-control-zoom a.leaflet-disabled { opacity: .42; }

.vvbd .vvbd-nut-mh {
  width: 34px !important;
  height: 34px !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 10px !important;
  background: #FFFDF9 !important;
  color: #14241D !important;
  font-size: 15px;
  line-height: 34px;
  box-shadow: 0 1px 3px rgba(20, 36, 29, .12), 0 4px 14px rgba(20, 36, 29, .16);
}
.vvbd .vvbd-nut-mh:hover,
.vvbd .vvbd-nut-mh:focus { background: #F4EDE3 !important; color: #14241D !important; }

/* ---- Chú giải "Lớp bản đồ" ---- */
.vvbd .vvbd-chu-giai {
  background: #FFFDF9;
  border: 0;
  border-radius: 12px;
  box-shadow: 0 1px 3px rgba(20, 36, 29, .10), 0 8px 26px rgba(20, 36, 29, .16);
  max-width: 252px;
}
.vvbd .vvbd-cg-nut {
  background: transparent;
  border-bottom: 1px solid rgba(20, 36, 29, .09);
  border-radius: 12px 12px 0 0;
  padding: 9px 13px;
  font-size: 13px;
  letter-spacing: .1px;
}
.vvbd .vvbd-cg-thu .vvbd-cg-nut { border-bottom: 0; border-radius: 12px; }
.vvbd .vvbd-cg-nut:hover { background: #F4EDE3; }

/* TRẦN CHIỀU CAO — chỗ chữa bệnh chồng cột.
   `min()` lấy cái nhỏ hơn giữa mức tuyệt đối và mức theo màn hình: khung bản
   đồ cao `clamp(320px,55vh,560px)`, nên 34vh luôn còn chừa đáy cho watermark
   và dòng ghi công. `overscroll-behavior:contain` để cuộn hết danh sách thì
   DỪNG, không đá sang cuộn cả trang. */
.vvbd .vvbd-cg-than {
  padding: 7px 11px 9px;
  max-height: min(300px, 34vh);
  overscroll-behavior: contain;
}
.vvbd .vvbd-cg-dong {
  padding: 6px 5px;
  border-radius: 8px;
  align-items: center;
}
.vvbd .vvbd-cg-dong:hover { background: #F4EDE3; }
.vvbd .vvbd-cg-mau { margin-top: 0; }
.vvbd .vvbd-cg-cham { margin-top: 0; }
.vvbd .vvbd-cg-chon select {
  border: 1px solid rgba(20, 36, 29, .16);
  border-radius: 8px;
  padding: 5px 8px;
  background: #fff;
  color: #14241D;
}

/* ==================================================================
 * v1.78.0 — CHỐT BỀ RỘNG Ở CẢ BA TẦNG CỦA POPUP
 * ==================================================================
 * Ảnh Du gửi 23:17 (đã cài đúng 2.48.0) cho một số đo dứt điểm: ẢNH đúng
 * 78px và THẺ đúng 258px — tức luật của mình CÓ chạy — nhưng vùng nền kem
 * còn kéo dài thêm gần 180px sang phải. Nghĩa là thứ rộng 440px không phải
 * thẻ, cũng không phải `.leaflet-popup-content`, mà là TẦNG BỌC NGOÀI
 * `.leaflet-popup-content-wrapper`.
 *
 * Ba lượt trước em chỉ chốt hai tầng trong (`content` và `.vvbd-card`) rồi
 * suy rằng thế là đủ — sai, vì `width:auto` trên một thẻ khối KHÔNG phải
 * "co theo nội dung", nó là "rộng bằng thẻ cha". Cha rộng bao nhiêu thì con
 * ăn theo, và trần 288px chỉ cắt được con chứ không cắt được cha.
 *
 * Popup này dùng CHUNG với Leaflet của theme RealHomes — theme có bộ style
 * popup riêng cho bản đồ property của nó. Em KHÔNG đọc được luật ấy từ
 * sandbox, nên không chốt bằng cách đi tìm nó mà chốt bằng cách bịt cả ba
 * tầng: `fit-content` bắt tầng bọc ôm sát nội dung, `min-width:0` gỡ mọi
 * sàn bề rộng người khác đặt, và `!important` ở độ đặc hiệu (0,3,0) để
 * không thua một luật (0,1,0) hay (0,2,0) nào.
 */
.vvbd .leaflet-popup,
.vvbd .leaflet-popup .leaflet-popup-content-wrapper {
  width: -moz-fit-content !important;
  width: fit-content !important;
  min-width: 0 !important;
  /* v1.81.0 — trần nới 288 → 380 để thẻ NỞ NGANG theo tên dài (xem khối
     thẻ dự án ở cuối tệp). 380 chứa được tên ~34 ký tự; dài hơn nữa thì
     tên tự cắt bằng dấu ba chấm chứ thẻ không nở tiếp — một thẻ rộng gần
     nửa bản đồ thì che mất chính cái nó đang chỉ vào. */
  max-width: 380px !important;
}

/* ---- Thẻ popup ---- */
.vvbd .leaflet-popup-content-wrapper {
  padding: 0 !important;
  border-radius: 16px !important;
  background: #FFFDF9;
  box-shadow: 0 2px 6px rgba(20, 36, 29, .10), 0 14px 36px rgba(20, 36, 29, .22) !important;
  overflow: hidden;
}
/* `width:auto !important` là để THẮNG style nội tuyến Leaflet ghi sau khi đo;
   min/max thay nó làm việc kẹp. Không có dòng này thì thẻ rộng gấp rưỡi chữ. */
.vvbd .leaflet-popup-content {
  margin: 0 !important;
  width: auto !important;
  min-width: 236px;
  /* ⚠️ `!important` ở đây KHÔNG phải để chắc ăn. Cùng lý do dòng `width`
     ngay trên phải có: phần tử này dùng CHUNG với Leaflet của theme, và
     ảnh Du gửi 25/08 cho thấy thẻ rộng ~400px trong khi luật khai 288px —
     tức có một luật khác đang thắng. Em KHÔNG tái hiện được từ sandbox (không
     có trình duyệt), nên không dám nói đã tìm ra nó; nhưng chốt bề rộng bằng
     `!important` thì thẻ đứng đúng bất kể luật kia là gì. */
  max-width: 380px !important;
  /* v1.77.0 — ĐỆM VỀ 0. Trước đây thân popup tự đệm 13px dưới đáy, nên thẻ
     dự án (vốn phải tràn sát mép để ảnh chạm cạnh) luôn bị chừa một vệt kem
     ở đáy. Đệm nay giao cho TỪNG loại nội dung tự lo — xem hai luật ngay
     dưới. */
  padding: 0;
  font-size: 13px;
  line-height: 1.5;
}
/* ⚠️ HAI LUẬT NÀY PHẢI MIỄN TRỪ `.vvbd-card`, và đây là chỗ đã làm hỏng.
 *
 * `> :first-child:not(img)` có độ đặc hiệu (0,3,1) — hai lớp, một lớp giả
 * `:first-child`, một phần tử `img` trong `:not()`. Luật của thẻ card là
 * `> .vvbd-card` = (0,3,0), tức THUA. Nên thẻ vẫn ăn `margin-top: 13px` dù
 * chính nó khai `margin: 0`, và cùng với đệm đáy ở trên thì ảnh bị kẹp giữa
 * hai vệt kem trên–dưới. Đúng thứ Du nhìn ra là "kỳ".
 *
 * Chữa bằng MIỄN TRỪ ở luật gây ra, không bằng cách đôn điểm cho luật kia:
 * đua độ đặc hiệu là cách hai luật cùng sống mà chỉ một cái chạy, và người
 * sửa sau phải đoán cái nào.
 *
 * `:not(img)` VẪN CẦN: popup tiện ích in ảnh làm con TRỰC TIẾP (v1.56.0),
 * không bọc trong `.vvbd-card`. */
.vvbd .leaflet-popup-content > :first-child:not(img):not(.vvbd-card) { margin-top: 13px; }
.vvbd .leaflet-popup-content > :last-child:not(.vvbd-card) { margin-bottom: 13px; }
.vvbd .leaflet-popup-content > .vvbd-pop-ten,
.vvbd .leaflet-popup-content > .vvbd-pop-dong,
.vvbd .leaflet-popup-content > .vvbd-pop-nguon,
.vvbd .leaflet-popup-content > .vvbd-pop-chi-duong { margin-left: 14px; margin-right: 14px; }
/* ⚠️ v1.77.0 — TRẢ LẠI ẢNH TRÀN VIỀN CHO POPUP TIỆN ÍCH.
 *
 * `popTienIch` dùng CHUNG lớp `.vvbd-card-anh` (v1.56.0: "hai loại popup một
 * kiểu ảnh, khỏi nuôi hai bộ CSS") nhưng in nó làm con TRỰC TIẾP, tràn hết
 * bề ngang. Luật lo việc ấy bị v1.75.0 xoá mất khi em thay khối card, rồi
 * v1.76.0 còn ép nó xuống 78px vì luật ảnh của thẻ dự án quét cả nó.
 *
 * Bài học: dùng chung một lớp cho hai bố cục khác nhau là tiết kiệm giả.
 * Nay mỗi bố cục có bộ chọn RIÊNG — tiện ích qua `>`, dự án qua `.vvbd-card`
 * — nên sửa bên này không với sang bên kia được nữa. */
.vvbd .leaflet-popup-content > .vvbd-card-anh {
  width: 100%;
  max-width: none;
  height: 134px;
  border-radius: 0;
  margin: 0 0 11px;
}

.vvbd .leaflet-popup-content .vvbd-pop-ten { font-size: 14.5px; font-weight: 700; line-height: 1.3; }
/* ==================================================================
 * v1.76.0 — THẺ DỰ ÁN NẰM NGANG (A2), DỰNG LẠI CHO ĐÚNG
 * ==================================================================
 * Du: "kích thước gì kỳ vậy". Hai lỗi chồng nhau, và một là do em ẩu.
 *
 * (1) THỨ TỰ NGUỒN, KHÔNG PHẢI ĐỘ ĐẶC HIỆU. Khối card của v1.75.0 dùng
 *     `.vvbd .vvbd-card-than > .vvbd-card-xem` — ba lớp, tức (0,3,0), ĐÚNG
 *     BẰNG luật cũ `.vvbd .leaflet-popup-content .vvbd-card-xem`. Hoà độ
 *     đặc hiệu thì thắng thua do THỨ TỰ, mà luật cũ nằm ngay DƯỚI hai dòng.
 *     Nên nút giữ nguyên `padding: 9px 12px`, tên giữ nguyên 14.5px/700 —
 *     thẻ phình đúng như ảnh Du gửi.
 *
 *     ⚠️ Bản nháp của chính khối này chẩn đoán SAI: nó viết "dấu `>` không
 *     cộng điểm nên chỉ được (0,2,0)". Vế đầu đúng — `>` thật sự không cộng
 *     — nhưng phép đếm thì sai, vì `.vvbd-card-than` cũng là một lớp. Kết
 *     luận đúng phải là HOÀ, và hoà thì cứu bằng vị trí. Một lời giải thích
 *     sai trong chú thích còn tệ hơn không có: người sửa sau sẽ đi nâng độ
 *     đặc hiệu, thấy vẫn hỏng, rồi không hiểu vì sao.
 *
 *     Cách chữa: gom khối card về MỘT CHỖ và đặt SAU mọi luật popup khác.
 *     Bộ chọn cũng mang `.leaflet-popup-content` để nếu có ai chèn luật vào
 *     giữa thì vẫn không bị thua điểm.
 *
 * (2) BỀ RỘNG. Xem chú thích ở `.leaflet-popup-content` phía trên. Ngoài
 *     việc chốt bằng `!important`, thẻ tự khai bề rộng CỐ ĐỊNH: co giãn
 *     theo nội dung là chỗ mọi luật lạ chen vào được, mà một thẻ dự án thì
 *     chẳng có lý do gì phải rộng hẹp khác nhau tuỳ tên dài ngắn.
 */
/* v1.79.0 — ẢNH VUÔNG, BO GÓC, LÙI VÀO TRONG (Du chốt).
 *
 * Bản trước để ảnh TRÀN sát ba mép và cao bằng cả thẻ, nên nó luôn là một
 * vệt đứng — hình càng cao thì càng không ra vuông. Muốn vuông mà vẫn tràn
 * mép thì bề cao thẻ phải bằng bề rộng ảnh, tức phải trói bề cao thẻ vào
 * một con số; tên dự án dài xuống hai dòng là vỡ.
 *
 * Nên đi đường của chính ảnh Du gửi làm mẫu: thẻ có đệm, ảnh là một ô VUÔNG
 * bo góc nằm lọt bên trong. Vuông được bảo đảm bằng hai số bằng nhau, không
 * phụ thuộc bề cao thẻ — nội dung dài ngắn thế nào ảnh vẫn vuông. */
/* v1.80.0 — ẢNH ÔM SÁT VIỀN, VÀ VẪN VUÔNG (Du chốt, theo ảnh mẫu).
 *
 * Lượt trước em chọn nhầm đường: để giữ vuông chắc chắn, em cho thẻ đệm
 * 10px rồi thả ảnh vuông vào giữa — vuông thì đúng, nhưng hết ôm mép, và
 * Du nói thẳng là nhìn xấu. Ảnh mẫu Zillow làm ngược lại: ảnh CHẠM ba mép
 * trái–trên–dưới, thẻ không có đệm ở phía ấy.
 *
 * Cách giữ được CẢ HAI: ảnh kéo cao bằng thẻ (`align-self: stretch`) và thẻ
 * có SÀN chiều cao đúng bằng bề rộng ảnh. Ở mọi thẻ có tên một dòng — tức
 * gần hết — thẻ đứng đúng ở sàn ấy nên ảnh vuông khít.
 *
 * ⚠️ ĐÁNH ĐỔI PHẢI NÓI RA: tên dự án dài xuống HAI dòng thì thẻ cao hơn
 * sàn, và ảnh cao hơn rộng một chút. Em chọn thế thay vì cắt tên bằng dấu
 * ba chấm — một cái tên bị cụt trên thẻ bán hàng tệ hơn một ô ảnh lệch vài
 * pixel. Muốn vuông TUYỆT ĐỐI thì phải khoá chiều cao thẻ và cắt tên; Du
 * quyết thì em đổi.
 *
 * Góc bo của ảnh KHÔNG cần khai: tầng bọc đã `border-radius:16px` +
 * `overflow:hidden` nên nó tự cắt hai góc trái. Tự bo thêm ở đây là hai nơi
 * cùng lo một việc, lệch nhau một pixel là lộ vệt sáng ở vai thẻ. */
/* v1.81.0 — THẺ NỞ NGANG THEO TÊN DÀI (Du hỏi, và đây là cách đúng).
 *
 * Bản trước khoá cứng bề rộng 286px, nên tên dài buộc phải xuống dòng, và
 * xuống dòng thì thẻ cao lên — đó chính là lý do ảnh hết vuông ở ca ấy.
 * Nay đảo lại: TÊN KHÔNG BAO GIỜ XUỐNG DÒNG, thẻ nở ngang để chứa nó.
 *
 * Hệ quả đáng giá hơn cả việc nở: thẻ không còn cao lên được nữa, nên nó
 * luôn đứng đúng ở sàn 104px ⇒ ẢNH VUÔNG TUYỆT ĐỐI ở MỌI ca, không còn
 * "trừ khi tên hai dòng" như v1.80.0 phải rào.
 *
 * `width: max-content` là thứ làm thẻ ôm sát chữ; sàn 286 giữ cho thẻ tên
 * ngắn không teo lại; `max-width: 100%` giao phần chặn trên cho trần 380px
 * của tầng bọc, để chỉ có MỘT chỗ khai trần. */
.vvbd .leaflet-popup-content > .vvbd-card {
  display: flex;
  align-items: stretch;
  width: -moz-max-content;
  width: max-content;
  min-width: 286px;
  max-width: 100%;
  min-height: 108px;
  padding: 0;
  box-sizing: border-box;
  margin: 0;
}
/* ==================================================================
 * v1.83.0 — MỌI Ô ĐỀU LÀ SỐ TƯỜNG MINH. HẾT KHÔN VẶT.
 * ==================================================================
 * Lịch sử ba lần hỏng của đúng một ô ảnh, ghi lại để không ai đi lại:
 *
 *   v1.80.0  bề rộng ảnh = con số ƯỚC là chiều cao thẻ → ước sai (104 vs
 *            thực tế ~124) → chữ nhật.
 *   v1.82.0  `aspect-ratio` + `width:auto` để trình duyệt tự suy → rủi ro
 *            đã TỰ NHẬN RA từ trước ("ảnh có kích thước gốc để tranh")
 *            nhưng tự thuyết phục mình rằng ô bọc tránh được — KHÔNG:
 *            flex tính bề RỘNG trước khi biết bề cao, nên `width:auto`
 *            của ô bọc rơi về max-content = bề rộng file gốc. Ảnh nuốt
 *            cả thẻ, đúng ảnh Du gửi 23:50.
 *
 * Kết luận: chỗ này không được có bất kỳ giá trị nào để trình duyệt "tự
 * suy". VUÔNG = HAI SỐ PX BẰNG NHAU TRÊN CÙNG MỘT Ô. Và để chiều cao cột
 * chữ không còn là thứ phải ƯỚC, mọi dòng trong thẻ khai line-height bằng
 * PX tường minh (thừa kế 1.5 của thân popup chính là biến số đã làm
 * v1.80.0 ước trượt):
 *
 *     đệm trên 10 + tên (18+1) + khu vực 16 + chỉ đường (4+16)
 *     + nút (7+5+16+5) + đệm dưới 10  =  108
 *
 * Ô ảnh 108×108 = đúng tổng ấy. `align-self:center` là đường lùi hiền:
 * nếu một trình duyệt nào đó vẽ cột chữ dôi vài px thì ảnh hở một lát
 * mỏng đối xứng trên–dưới, chứ không méo và không nở. */
.vvbd .leaflet-popup-content .vvbd-card .vvbd-card-ohinh {
  flex: 0 0 auto;
  width: 108px;
  height: 108px;
  align-self: center;
  overflow: hidden;
  /* Bo hai góc TRÁI bằng ĐÚNG 16px của tầng bọc — lệch một pixel là lộ
     vệt sáng ở vai thẻ. Cặp số này có phép canh khoá. */
  border-radius: 16px 0 0 16px;
}
.vvbd .leaflet-popup-content .vvbd-card .vvbd-card-anh {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  border-radius: 0;
  margin: 0;
}
.vvbd .leaflet-popup-content .vvbd-card .vvbd-card-than {
  flex: 1 1 auto;
  min-width: 0;
  /* Chừa chỗ cho nút đóng: bố cục ngang thì góc trên-phải là CHỮ, không còn
     là ảnh như bố cục dọc cũ. Đệm còn lại do chính thẻ lo. */
  padding: 10px 28px 10px 12px;
}
/* ⚠️ BA DÒNG CHỮ ĐỀU PHẢI `nowrap`, KHÔNG CHỈ RIÊNG TÊN. Chỉ cần một dòng
   trong thẻ xuống hàng là thẻ cao lên và ảnh hết vuông — mà "Chỉ đường tới
   đây ↗" cũng đủ dài để xuống hàng khi thẻ ở sàn. `ellipsis` là lối thoát
   ở trần 380px: quá dài thì cắt bằng ba chấm chứ không nở tiếp. */
.vvbd .leaflet-popup-content .vvbd-card .vvbd-pop-ten {
  font-size: 13.5px;
  font-weight: 600;
  line-height: 18px;
  margin: 0 0 1px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vvbd .leaflet-popup-content .vvbd-card .vvbd-pop-dong {
  margin: 0;
  font-size: 11.5px;
  line-height: 16px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vvbd .leaflet-popup-content .vvbd-card .vvbd-pop-chi-duong {
  display: block;
  margin: 4px 0 0;
  font-size: 11.5px;
  line-height: 16px;
  white-space: nowrap;
}
.vvbd .leaflet-popup-content .vvbd-card .vvbd-card-xem {
  margin: 7px 0 0;
  padding: 5px 10px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 600;
  line-height: 16px;
}

.vvbd .leaflet-popup-tip {
  box-shadow: none !important;
  background: #FFFDF9 !important;
}

/* Nút đóng nổi thành viên tròn trên ảnh — nút chữ "×" trần chìm mất khi rơi
   trúng vùng sáng của ảnh. */
.vvbd .leaflet-popup-close-button {
  top: 7px !important;
  right: 7px !important;
  width: 22px !important;
  height: 22px !important;
  padding: 0 !important;
  border-radius: 50% !important;
  background: rgba(20, 36, 29, .07) !important;
  color: #14241D !important;
  font-size: 15px !important;
  font-weight: 700 !important;
  line-height: 22px !important;
  text-align: center;
  box-shadow: none;
}
.vvbd .leaflet-popup-close-button:hover { background: #fff !important; color: #B0574F !important; }

/* ==================================================================
 * v1.73.0 — BỘ NHÃN & GHIM Du DUYỆT MẪU 25/08 (1A · 2A · 3B · 4-2)
 * ==================================================================
 * 1A — chấm dự án: viền KEM + bóng đổ; mốc đang đo thêm QUẦNG vàng.
 *
 * ⚠️ `filter` ở đây an toàn vì nó nằm trên thẻ `<path>` của Leaflet — thẻ
 * ấy không chứa phần tử `position:fixed` nào. Bộ canh CSS vẫn cấm `filter`
 * trên `.vvbd` và `.vvbd.vvbd-man-hinh` (bẫy khối chứa của toàn màn hình);
 * đừng đôn luật này lên tổ tiên để "gọn hơn". */
.vvbd .vvbd-cham-da {
  filter: drop-shadow(0 2px 3px rgba(20, 36, 29, .38));
}
/* Quầng sáng CHỈ dành cho mốc đang đo — nó là phản hồi cho cú bấm của
   khách, không phải trang trí. Dùng chung một kênh với viền vàng nên không
   đẻ thêm nghĩa mới. */
.vvbd .vvbd-cham-moc {
  filter: drop-shadow(0 0 6px rgba(176, 141, 87, .95))
          drop-shadow(0 2px 3px rgba(20, 36, 29, .3));
}

/* v1.74.0 — đang chờ khách chỉ điểm đo: đổi con trỏ thành chữ thập. Đây là
 * dấu hiệu DUY NHẤT nói cho khách biết bản đồ đang ở một chế độ khác. */
.vvbd.vvbd-dang-chon-diem .leaflet-container,
.vvbd.vvbd-dang-chon-diem .leaflet-interactive { cursor: crosshair; }

/* ---- Ghim & nhãn ---- */
.vvbd .vvbd-nhan-du-an { padding: 4px 10px; font-size: 12.5px; }

/* 2A — ĐUÔI TRỎ VỀ CHẤM.
 *
 * Không chỉ để đẹp: trong ảnh Du gửi, "Setia Edenia" nằm lọt giữa hai chấm
 * và không ai biết tên ấy của chấm nào. Cái đuôi trả lời đúng câu đó.
 *
 * Canh dọc bằng `top: calc(50% - 6px)` chứ KHÔNG bằng `translateY(-50%)`:
 * `transform` biến thẻ thành KHỐI CHỨA của mọi con `position:fixed`, và
 * đó đúng là lỗi đã làm vỡ bảng mục lục mobile của villaverde-blocks. Nhãn
 * hôm nay không có con fixed nào, nhưng dùng phép canh không có tác dụng
 * phụ thì mai ai thêm cũng không sập. */
/* ⚠️⚠️ TUYỆT ĐỐI KHÔNG KHAI `position` Ở ĐÂY. Bản v1.73.0 thêm
 * `position: relative` cho cái đuôi có chỗ neo — và đó là MỘT LỖI, gây ra
 * đúng hai thứ Du báo trong cùng một ảnh:
 *
 *   Leaflet đặt `.leaflet-marker-icon { position: absolute }` ở độ đặc hiệu
 *   (0,1,0). Luật của mình là (0,2,0) nên nó THẮNG, và cái nhãn thôi được
 *   định vị tuyệt đối. Hậu quả kép:
 *     (a) nhãn rơi vào dòng chảy bình thường của lớp marker ⇒ nó là một
 *         thẻ BLOCK rộng bằng cả lớp ⇒ hộp trắng kéo dài quá chữ, đúng
 *         "chừa khoảng trống nhiều, choán chỗ";
 *     (b) `translate3d` Leaflet đặt lên nó nay cộng vào vị trí DÒNG CHẢY
 *         chứ không phải gốc toạ độ ⇒ nhãn trôi xuống dưới, rời khỏi chấm
 *         của nó, đúng "dự án ở đây mà label tít mãi dưới".
 *
 * Và không cần khai gì cả: thẻ nhãn ĐÃ là `position:absolute` nhờ chính
 * luật Leaflet, tức đã là khối chứa hợp lệ cho cái đuôi bên dưới. */
.vvbd .vvbd-nhan-du-an::before {
  content: '';
  position: absolute;
  left: -6px;
  top: calc(50% - 6px);
  width: 0;
  height: 0;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-right: 6px solid rgba(255, 253, 249, .94);
  border-left: 0;
}
.vvbd .vvbd-nhan-phu::before { border-right-color: rgba(255, 253, 249, .88); }
/* Dự án KHÔNG phải mốc đang đo: nhẹ hơn một nấc, nhưng vẫn phải đọc được —
   đây là NỘI DUNG của một bản đồ bán hàng, không phải chú thích phụ. */
.vvbd .vvbd-nhan-phu {
  padding: 3px 9px;
  font-size: 11.5px;
  background: rgba(255, 253, 249, .88);
  box-shadow: 0 1px 2px rgba(20, 36, 29, .08), 0 2px 7px rgba(20, 36, 29, .10);
}

/* ---- Chú giải hai tầng (v1.64.0) ----
 * Thụt lề là thứ DUY NHẤT nói cho mắt biết đâu là con của ai. Bỏ nó thì hai
 * tầng thành một danh sách phẳng có vài dòng in đậm — tệ hơn lúc chưa có
 * phân cấp, vì giờ có thêm dòng "Tiện ích" trông như một lớp thứ năm. */
.vvbd .vvbd-cg-me { margin-top: 6px; }
.vvbd .vvbd-cg-me:first-child { margin-top: 0; }
.vvbd .vvbd-cg-me .vvbd-cg-chu b { font-size: 12px; letter-spacing: .4px; text-transform: uppercase; opacity: .72; }
.vvbd .vvbd-cg-me .vvbd-cg-chu i { font-size: 10.5px; opacity: .6; }
.vvbd .vvbd-cg-con { padding-left: 22px; }
/* Vạch dọc chạy suốt đàn con — mắt bám vạch chứ không phải đếm khoảng trắng. */
.vvbd .vvbd-cg-con { position: relative; }
.vvbd .vvbd-cg-con::before {
  content: '';
  position: absolute;
  left: 10px;
  top: 0;
  bottom: 0;
  width: 1px;
  background: rgba(20, 36, 29, .13);
}

/* ---- Nhãn dự án nhường chỗ (v1.65.0) ----
 * `visibility` chứ KHÔNG phải `display:none`: nhãn bị giấu vẫn phải còn hộp
 * để lần đo sau tính đúng: `display:none` cho hộp 0×0, mọi nhãn đã giấu sẽ
 * "không chen với ai" và lần đo sau bật lại hết — bản đồ nhấp nháy vô tận.
 * Máy giãn nhãn bỏ lớp này ra trước khi đo, nhưng luật vẫn phải đúng cho
 * cảnh đo bị lỡ một nhịp. */
.vvbd .vvbd-nhan-an { visibility: hidden; }
/* Rê chuột lên chấm thì nhãn hiện lại và NỔI LÊN TRÊN mọi nhãn khác — nếu
   không nó hiện ra ngay dưới cái nhãn vốn đã chiếm chỗ ấy.
 *
 * ⚠️ TUYỆT ĐỐI KHÔNG KHAI `z-index` Ở ĐÂY (v1.89.0, sau khi trả giá).
 * Bản v1.65.0 khai `z-index: 650 !important` với đúng ý trên. Tới v1.87.0
 * nhãn xếp bằng `zIndexOffset` (uu*10000, mốc đang đo 990000) mà Leaflet ghi
 * thành style NỘI TUYẾN — và một luật `!important` trong stylesheet THẮNG
 * style nội tuyến. Con số 650 vì thế đổi nghĩa từ "trên cùng" thành "dưới
 * đáy": nhãn đang rê bị kéo từ 990000 xuống 650, hiện ra để không đọc được.
 * Thứ tự nay do JS quyết một mình (`UU_RE * BUOC_UU`) — một cơ chế một việc.
 *
 * Nền ĐỤC HOÀN TOÀN, không dùng `.88`/`.94` như nhãn thường: 6–12% trong
 * suốt trên nền bản đồ thì đẹp, nhưng nhãn đang rê là nhãn đang nằm CHỒNG
 * lên một nhãn khác, và phần trong suốt ấy thành chữ đen của nhãn dưới hắt
 * lên. Nâng lên trên mà vẫn đọc chồng chữ thì mới xong một nửa việc. */
.vvbd .vvbd-nhan-noi { visibility: visible; background: #FFFDF9; }
/* Đuôi trỏ cũng phải đục theo — hoà độ đặc hiệu với `.vvbd-nhan-phu::before`
   nên thắng thua do THỨ TỰ NGUỒN: luật này phải đứng SAU nó trong tệp. */
.vvbd .vvbd-nhan-noi::before { border-right-color: #FFFDF9; }

/* ---- Nhãn LẬT SANG TRÁI (v1.91.0) ----
 * Máy giãn nhãn ghi lớp này kèm một `margin-left` âm tính từ số đo thật, nên
 * ở đây KHÔNG khai bề rộng hay khoảng dời nào — khai là đẻ ra con số thứ hai
 * cho cùng một quãng, và hai con số thì lệch nhau ở lần sửa thứ hai.
 *
 * Việc của CSS chỉ là quay cái ĐUÔI: nhãn nay đứng bên trái chấm nên đuôi
 * phải mọc ở mép PHẢI và trỏ sang phải. Đổi chiều bằng cách tắt hẳn cạnh cũ
 * (`border-right: 0`) rồi khai cạnh mới — không để cả hai cùng sống, vì hai
 * cạnh viền cùng có màu là hai mũi tên chồng nhau, đúng lỗi ::after của
 * v1.72.0.
 *
 * ⚠️ Hoà độ đặc hiệu (0,2,1) với luật đuôi gốc ⇒ thắng thua do THỨ TỰ NGUỒN,
 * nên khối này phải đứng SAU. Riêng màu thì phải leo lên (0,3,1) để vượt
 * `.vvbd-nhan-phu::before` và `.vvbd-nhan-noi::before` đang khai màu cạnh
 * phải — cùng phần tử, khác cạnh, nên không thể trông vào thứ tự. */
.vvbd .vvbd-nhan-trai::before {
  left: auto;
  right: -6px;
  border-right: 0;
  border-left: 6px solid rgba(255, 253, 249, .94);
}
.vvbd .vvbd-nhan-phu.vvbd-nhan-trai::before { border-left-color: rgba(255, 253, 249, .88); }
.vvbd .vvbd-nhan-noi.vvbd-nhan-trai::before { border-left-color: #FFFDF9; }

/* ---- Chú giải thang màu pháp lý (v1.65.0) ---- */
.vvbd .vvbd-cg-thang {
  margin-top: 9px;
  padding-top: 9px;
  border-top: 1px solid rgba(20, 36, 29, .10);
}
.vvbd .vvbd-cg-thang-dau {
  margin-bottom: 5px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .4px;
  text-transform: uppercase;
  color: #14241D;
  opacity: .72;
}
.vvbd .vvbd-cg-thang-dong {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 2px 0;
  font-size: 12px;
  color: #14241D;
}

/* ---- Ghim vùng ----
 * ⚠️ BẪY THỪA KẾ, KHÔNG PHẢI BẪY ĐỘ ĐẶC HIỆU. Theme RealHomes có luật trần:
 *
 *     b, strong { font-weight: bolder; color: var(--rh-global-color-headings) }
 *
 * `.vvbd-gv` đặt `color:#fff` trên thẻ CHA, nhưng theme khai `color` THẲNG
 * lên chính thẻ `<b>`. Khai trực tiếp luôn thắng giá trị THỪA KẾ, bất kể độ
 * đặc hiệu — nên tên vùng lấy màu chữ tiêu đề (tối) đặt trên nền xanh đậm,
 * gần như không đọc được (ảnh Du 25/08). Bằng chứng xác nhận: thẻ `<i>` bên
 * dưới CÓ khai màu riêng nên nó vẫn sáng bình thường.
 *
 * Chữa bằng cách khai màu THẲNG lên `<b>`. Không cần `!important`: luật của
 * mình (0,2,1) đã hơn luật trần của theme (0,0,1) — chỉ cần nó tồn tại.
 *
 * ⚠️ Luật chung rút ra: mọi thẻ `<b>`/`<strong>` mình phát ra bên trong
 * `.vvbd` đều PHẢI tự khai màu, đừng trông vào thừa kế từ thẻ bọc. */
/* 3B — NHÃN VÙNG: chip kính MỘT DÒNG, tên + bong bóng số.
 *
 * Bản cũ là khối xanh đậm hai dòng, to gần bằng một cái thẻ và nặng hơn cả
 * nhãn dự án — trong khi nó chỉ là một cái cửa để bấm vào. Nay nhẹ đi hẳn
 * và về CÙNG HỌ SÁNG với nhãn dự án; thứ giữ nó khác biệt là viền vàng và
 * bong bóng số, chứ không phải một bảng màu riêng. */
.vvbd .vvbd-ghim-vung .vvbd-gv {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 6px 5px 13px;
  background: rgba(255, 253, 249, .82);
  border: 1px solid rgba(176, 141, 87, .9);
  border-radius: 999px;
  -webkit-backdrop-filter: blur(6px) saturate(1.15);
  backdrop-filter: blur(6px) saturate(1.15);
  box-shadow: 0 2px 10px rgba(20, 36, 29, .18);
}
.vvbd .vvbd-ghim-vung .vvbd-gv:hover {
  background: rgba(255, 253, 249, .95);
  border-color: #B08D57;
}
/* ⚠️ `<b>` PHẢI tự khai màu: theme RealHomes khai `b,strong{color:…}` THẲNG
   lên thẻ, mà khai trực tiếp luôn thắng giá trị THỪA KẾ bất kể độ đặc hiệu
   — đúng bẫy đã làm mờ chính nhãn này ở v1.62.0. */
.vvbd .vvbd-ghim-vung b {
  display: block;
  color: #14241D;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .1px;
}
/* Bong bóng số: nền vàng, chữ nâu sẫm cùng họ màu — không dùng đen trơn. */
.vvbd .vvbd-ghim-vung i {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 19px;
  height: 19px;
  padding: 0 5px;
  box-sizing: border-box;
  background: #B08D57;
  color: #3B2A12;
  border-radius: 999px;
  font-style: normal;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0;
}

/* Watermark dính ĐÚNG bẫy trên: `.vvbd-wm` khai `color:#14241D` cho thẻ bọc,
   còn `<b>` bên trong bị theme cướp. Nền watermark sáng nên hai màu đều tối
   và chưa ai thấy — nhưng đó là mầm, không phải sự lành. */
.vvbd .vvbd-wm b { color: #14241D; }

/* Huy hiệu tiện ích: giữ ĐÚNG 30px — JS khai `iconSize:[30,30]`,
   `iconAnchor:[15,15]`. Đổi cỡ ở đây là ghim lệch khỏi toạ độ thật. */
.vvbd .vvbd-icon-ti span {
  background: #FFFDF9;
  box-shadow: 0 2px 7px rgba(20, 36, 29, .26);
}

/* ---- Watermark + dòng ghi công + mini-map ---- */
.vvbd .vvbd-wm {
  border-radius: 9px;
  background: rgba(255, 253, 249, .88);
  box-shadow: 0 1px 4px rgba(20, 36, 29, .14);
}
/* Dòng ghi công: nhỏ và nhẹ đi, nhưng VẪN ĐỌC ĐƯỢC — nghĩa vụ ODbL, không
   phải thứ để giấu. */
.vvbd .leaflet-control-attribution {
  background: rgba(255, 253, 249, .86) !important;
  border-radius: 8px 0 0 0;
  padding: 2px 8px;
  font-size: 10.5px;
  color: #4a4a44;
}
.vvbd .vvbd-mini {
  border: 0;
  border-radius: 10px;
  box-shadow: 0 0 0 1px rgba(20, 36, 29, .12), 0 3px 12px rgba(20, 36, 29, .24);
}

/* ==================================================================
 * v1.66.0 — ĐẦU BẢNG CHÚ GIẢI
 * ==================================================================
 * Du 25/08: "màu xanh lá thì chữ phải tương phản lại màu trắng chứ, màu đen
 * nhìn xấu — hay là lỗi css?" Không phải lỗi CSS của mình, và cũng không
 * hẳn không phải: theme RealHomes có luật liệt kê trần kết thúc bằng
 * `button` đặt `background: var(--rh-global-color-primary)`. Luật của mình
 * khai `background: transparent` nhưng KHÔNG khai `color` cùng chỗ, nên nền
 * xanh của theme lọt vào mà chữ vẫn giữ màu tối của mình → chữ tối trên nền
 * xanh đậm. Nửa thắng nửa thua là cách hỏng xấu nhất: nếu thua cả hai thì
 * chữ đã trắng theo theme và chẳng ai thấy gì bất thường.
 *
 * ⚠️ NHƯNG KHÔNG ĐI GỠ MÀU XANH. Nó là màu thương hiệu, và một đầu bảng
 * xanh đậm chữ kem trông ĐẸP HƠN cái đầu bảng trong suốt cũ. Tai nạn chỉ ra
 * một thiết kế tốt hơn — nên nhận lấy và làm cho nó CỐ Ý: khai cả nền lẫn
 * chữ, khoá cứng, để lần sau theme đổi màu primary thì mình không đổi theo
 * một nửa.
 *
 * Du cũng hỏi "có nút thu gọn không?" — CÓ, từ lâu, nhưng dấu hiệu chỉ là
 * một chữ "▾" lẫn vào chữ. Hỏi tức là không thấy. Nay thành mũi tên hình
 * học XOAY khi gập, cộng nền đổi màu lúc rê chuột: nhìn là biết bấm được.
 */
.vvbd .vvbd-cg-nut {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 11px 14px !important;
  background: #14241D !important;
  color: #FFFDF9 !important;
  border: 0 !important;
  border-radius: 12px 12px 0 0 !important;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .2px;
  cursor: pointer;
}
.vvbd .vvbd-cg-thu .vvbd-cg-nut { border-radius: 12px !important; }
.vvbd .vvbd-cg-nut:hover,
.vvbd .vvbd-cg-nut:focus {
  background: #1E3529 !important;
  color: #FFFDF9 !important;
}
/* ==================================================================
 * v1.71.0 — MŨI TÊN GẬP DỰNG BẰNG SVG, KHÔNG BẰNG HAI CẠNH VIỀN XOAY
 * ==================================================================
 * Du: "cái icon hình thu gọn mở ra hình như bị lỗi". Ảnh cho thấy ở trạng
 * thái GẬP mũi tên ra một nét chéo lệch, không phải hình ∧ cân.
 *
 * ⚠️ EM KHÔNG TÁI HIỆN ĐƯỢC và cũng KHÔNG DÁM NÓI ĐÃ TÌM RA NGUYÊN NHÂN —
 * sandbox không có trình duyệt thật (Chromium ngoài allowlist mạng), mà
 * đây là lỗi HÌNH THỂ, thứ jsdom không tính. Chỉ đọc được ra một điểm
 * đáng ngờ: `rotate(θ) translate(-2px,-2px)` dịch chuyển TRONG HỆ ĐÃ XOAY,
 * nên hai trạng thái lệch nhau 180° thì cùng một lệnh translate đẩy hình
 * đi HAI HƯỚNG NGƯỢC NHAU trên màn hình (≈ 2,8px lên ở trạng thái mở, và
 * ≈ 2,8px xuống ở trạng thái gập) — mũi tên gập tụt khỏi tâm dòng.
 *
 * Nhưng đó mới là suy luận, không phải bằng chứng. Nên làm đúng thứ đã làm
 * hai lần trước ở chính module này (v1.52.0 bỏ emoji dùng SVG, v1.67.0 bỏ
 * gập-bằng-CSS): KHÔNG ĐOÁN, GỠ HẲN CƠ CHẾ. Hình vẽ bằng `background-image`
 * SVG — một đường gấp khúc khai bằng toạ độ tuyệt đối, máy nào cũng vẽ ra
 * đúng một hình — và trạng thái gập chỉ `rotate(180deg)` quanh TÂM, không
 * kèm translate nào để mà lệch.
 */
.vvbd .vvbd-cg-nut::after {
  content: '';
  flex: 0 0 auto;
  width: 12px;
  height: 12px;
  margin-right: 1px;
  opacity: .85;
  background: no-repeat center / 12px 12px
    url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 L6 8 L9.5 4.5' fill='none' stroke='%23FFFDF9' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  transform-origin: 50% 50%;
  transform: rotate(0deg);
  transition: transform .18s ease;
}
.vvbd .vvbd-cg-thu .vvbd-cg-nut::after { transform: rotate(180deg); }

/* Chấm mẫu "mốc đang đo": viền vàng dày, y như trên bản đồ. */
.vvbd .vvbd-cg-cham-moc {
  background: #FFFDF9;
  border: 3px solid #B08D57;
  box-sizing: border-box;
}

/* ==================================================================
 * v1.67.0 — BẢNG CHÚ GIẢI CHIA MỤC
 * ==================================================================
 * ⚠️ KHÔNG có luật nào ở đây GẬP hay BUNG mục. Việc ấy do JS ghi thẳng
 * `style.display` kèm !important — chỗ dựa vào CSS chính là thứ Du báo
 * hỏng. CSS ở đây chỉ lo hình thức.
 */
.vvbd .vvbd-cg-muc { border-top: 1px solid rgba(20, 36, 29, .09); }
.vvbd .vvbd-cg-muc:first-child { border-top: 0; }
.vvbd .vvbd-cg-muc-dau { display: flex; align-items: center; gap: 8px; }
.vvbd .vvbd-cg-muc-tick { flex: 0 0 auto; margin: 0; }

.vvbd .vvbd-cg-muc-gap {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 4px !important;
  background: transparent !important;
  color: #14241D !important;
  border: 0 !important;
  border-radius: 8px !important;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .5px;
  text-transform: uppercase;
  text-align: left;
  cursor: pointer;
}
.vvbd .vvbd-cg-muc-gap:hover,
.vvbd .vvbd-cg-muc-gap:focus { background: #F4EDE3 !important; color: #14241D !important; }
.vvbd .vvbd-cg-muc-gap i {
  font-style: normal;
  font-weight: 500;
  font-size: 10.5px;
  letter-spacing: 0;
  text-transform: none;
  opacity: .6;
}
/* Mũi tên đẩy sang phải bằng margin-left:auto — dùng chung hình học với
   mũi tên đầu bảng để hai cấp trông cùng một họ. */
.vvbd .vvbd-cg-muc-gap::after {
  content: '';
  flex: 0 0 auto;
  margin-left: auto;
  width: 6px;
  height: 6px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  opacity: .55;
  transform: rotate(-45deg) translate(-1px, 1px);
  transition: transform .18s ease;
}
.vvbd .vvbd-cg-muc-mo .vvbd-cg-muc-gap::after { transform: rotate(45deg) translate(-2px, -2px); }

.vvbd .vvbd-cg-muc-than { padding: 0 0 8px 4px; }
.vvbd .vvbd-cg-goi-y {
  margin: 6px 0 0;
  font-size: 11.5px;
  line-height: 1.45;
  color: #14241D;
  opacity: .62;
}

/* ==================================================================
 * v1.69.0 — BẢNG "CHÚ GIẢI": TẤM KÍNH Ở GÓC DƯỚI-TRÁI
 * ==================================================================
 * Du: "làm thành cái bảng gần như trong suốt" + "tab chú giải đổi màu hoặc
 * thiết kế khác với lớp bản đồ".
 *
 * Hai bảng nay khác nhau ở CHẤT LIỆU, không chỉ ở màu — vì chúng khác nhau
 * ở CÔNG VIỆC:
 *
 *   "Lớp bản đồ"  = bộ CÔNG TẮC  → thẻ ĐỤC, đầu bảng xanh đậm đặc, nổi lên
 *                                  trên bản đồ. Bấm là bản đồ đổi.
 *   "Chú giải"    = bảng TRA     → tấm KÍNH, chìm vào bản đồ, chữ nổi trên
 *                                  nền mờ. Đọc xong là xong.
 *
 * Khác chất liệu thì khách phân biệt được từ khoé mắt, không cần đọc tiêu
 * đề — thứ mà đổi mỗi màu đầu bảng không làm được.
 *
 * ⚠️ `backdrop-filter` Ở ĐÂY LÀ AN TOÀN, nhưng chỉ vì đúng một lý do: bảng
 * này KHÔNG chứa phần tử `position:fixed` nào. Nó vẫn là thuộc tính đã làm
 * vỡ bảng mục lục mobile của villaverde-blocks (biến tổ tiên thành KHỐI
 * CHỨA của con fixed), và bộ canh CSS vẫn cấm nó trên `.vvbd` /
 * `.vvbd.vvbd-man-hinh`. Ai thêm phần tử fixed vào trong bảng này thì phải
 * bỏ dòng blur đi.
 */
.vvbd .vvbd-bang-kh {
  background: rgba(255, 253, 249, .22);
  border: 1px solid rgba(255, 255, 255, .3);
  box-shadow: 0 1px 2px rgba(20, 36, 29, .05), 0 4px 14px rgba(20, 36, 29, .08);
  -webkit-backdrop-filter: blur(12px) saturate(1.25);
  backdrop-filter: blur(12px) saturate(1.25);
  max-width: 208px;
  margin: 0 0 8px 10px !important;
}
/* Máy không có backdrop-filter thì KHÔNG có gì làm nền dịu đi — 58% cream
   trên một bản đồ nhiều đường là chữ chồng chữ. Đục lên cho đọc được: xấu
   hơn ý đồ vẫn hơn đẹp mà không đọc nổi. */
@supports not ((-webkit-backdrop-filter: blur(2px)) or (backdrop-filter: blur(2px))) {
  .vvbd .vvbd-bang-kh { background: rgba(255, 253, 249, .9); }
}

/* Đầu bảng KHÔNG phải thanh xanh đậm của bảng công tắc: kính mà đội một
   thanh đặc thì hết là kính. Chữ nhỏ, in hoa, giãn — giọng của một cái nhãn
   dán, không phải một cái nút. */
.vvbd .vvbd-bang-kh .vvbd-cg-nut {
  background: rgba(20, 36, 29, .04) !important;
  color: #14241D !important;
  border-bottom: 1px solid rgba(20, 36, 29, .08) !important;
  padding: 7px 11px !important;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .9px;
  text-transform: uppercase;
}
.vvbd .vvbd-bang-kh .vvbd-cg-nut:hover,
.vvbd .vvbd-bang-kh .vvbd-cg-nut:focus {
  background: rgba(20, 36, 29, .11) !important;
  color: #14241D !important;
}
.vvbd .vvbd-bang-kh.vvbd-cg-thu .vvbd-cg-nut { border-bottom: 0 !important; }
/* Mũi tên của bảng kính phải TỐI: hình SVG ở luật gốc tô màu kem cho đầu
   bảng xanh đậm, để nguyên thì nó là chữ trắng trên nền kem — tàng hình. */
.vvbd .vvbd-bang-kh .vvbd-cg-nut::after {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 L6 8 L9.5 4.5' fill='none' stroke='%2314241D' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  opacity: .6;
}
.vvbd .vvbd-bang-kh .vvbd-cg-than {
  padding: 3px 11px 8px;
  max-height: min(260px, 38vh);
  overscroll-behavior: contain;
}

/* ---- một mục ---- */
.vvbd .vvbd-kh-dau {
  margin: 9px 0 3px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .7px;
  text-transform: uppercase;
  color: #14241D;
  opacity: .55;
}
.vvbd .vvbd-kh-dau:first-child { margin-top: 3px; }

.vvbd .vvbd-kh-dong {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  padding: 1px 0;
  font-size: 11px;
  line-height: 1.35;
  color: #14241D;
}
.vvbd .vvbd-kh-chu { flex: 1 1 auto; }
.vvbd .vvbd-kh-chu i {
  display: block;
  font-style: normal;
  font-size: 10px;
  opacity: .6;
}

/* ---- mẫu ký hiệu ----
 * ⚠️ ĐÂY LÀ CHỖ ĐÃ HỎNG TỪ v1.65.0, VÀ LÀ LÝ DO PHẢI CÓ BỘ LỚP RIÊNG.
 *
 * Bản cũ dựng chấm bằng `.vvbd-cg-cham` — một lớp BỔ NGỮ chỉ bẻ vệt thành
 * hình tròn, `background` nằm ở `.vvbd-cg-mau` mà JS không gắn. Chấm trong
 * suốt, `flex` bóp nốt bề rộng: cột màu rỗng đúng nghĩa đen (ảnh Du 25/08).
 *
 * Luật rút ra: MỘT LỚP MẪU PHẢI TỰ ĐỦ. Không có lớp nào ở đây chỉ có nghĩa
 * khi đi kèm một lớp khác — mỗi lớp `vvbd-kh-*` tự khai đủ nền, cỡ, hình.
 */
.vvbd .vvbd-kh-mau {
  flex: 0 0 auto;
  width: 18px;
  margin-top: 4px;
}
.vvbd .vvbd-kh-cham {
  width: 11px;
  height: 11px;
  margin: 3px 3px 0 3px;
  border-radius: 50%;
  background: var(--vvbd-kh-mau, #7A7A72);
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, .95);
}
/* Mốc đang đo: chấm rỗng viền vàng dày, y như trên bản đồ. */
.vvbd .vvbd-kh-moc {
  width: 11px;
  height: 11px;
  margin: 3px 3px 0 3px;
  border-radius: 50%;
  background: #FFFDF9;
  border: 3px solid #B08D57;
  box-sizing: border-box;
}
.vvbd .vvbd-kh-net {
  height: 4px;
  margin-top: 8px;
  border-radius: 2px;
  background: var(--vvbd-kh-mau, #7A7A72);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .85);
}
.vvbd .vvbd-kh-net-dut,
.vvbd .vvbd-kh-net-vang {
  height: 4px;
  margin-top: 8px;
  border-radius: 2px;
  background: repeating-linear-gradient(
    to right,
    var(--vvbd-kh-mau, #7A7A72) 0 5px,
    transparent 5px 9px
  );
}
/* Vùng khoanh: một ô tô mờ có viền, đúng thứ khách thấy trên bản đồ. */
/* Ký hiệu ga trong chú giải (v1.97.0) — dựng bằng đúng ngôn ngữ hình mà bản
   đồ dùng: ruột trắng, viền màu; đứt = ước lượng; lõi đặc = trung chuyển;
   quầng ngoài = TOD. Vẽ bằng border + box-shadow chứ không bằng SVG để đi
   chung một khuôn 14×14 với mọi ký hiệu khác trong bảng. */
.vvbd .vvbd-kh-ga,
.vvbd .vvbd-kh-ga-ul,
.vvbd .vvbd-kh-ga-tc,
.vvbd .vvbd-kh-ga-tod {
  width: 12px; height: 12px; border-radius: 50%;
  background: #fff;
  border: 2.5px solid var(--vvbd-kh-mau, #7A7A72);
  box-sizing: border-box;
}
.vvbd .vvbd-kh-ga-ul { border-style: dashed; }
.vvbd .vvbd-kh-ga-tc {
  border-width: 2px;
  background:
    radial-gradient(circle at 50% 50%,
      var(--vvbd-kh-mau, #7A7A72) 0 2.4px, #fff 2.4px 100%);
}
.vvbd .vvbd-kh-ga-tod {
  width: 10px; height: 10px;
  box-shadow: 0 0 0 2.5px rgba(255, 255, 255, .95),
              0 0 0 4px var(--vvbd-kh-mau, #7A7A72);
}

/* Ký hiệu BÊN ĐƯỜNG trong chú giải (v1.111.0) — cùng khuôn 14×14.
   ga-cr: dải mờ nằm ngang, chấm ở giữa. ga-ben: chấm nửa tô đặc bên trái. */
.vvbd .vvbd-kh-ga-cr {
  width: 14px; height: 8px; border-radius: 2px;
  background: color-mix(in srgb, var(--vvbd-kh-mau, #7A7A72) 18%, transparent);
  position: relative;
}
.vvbd .vvbd-kh-ga-cr::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 6px; height: 6px; margin: -3px 0 0 -3px; border-radius: 50%;
  background: #fff; border: 2px solid var(--vvbd-kh-mau, #7A7A72); box-sizing: border-box;
}
.vvbd .vvbd-kh-ga-ben {
  width: 12px; height: 12px; border-radius: 50%; box-sizing: border-box;
  border: 2.5px solid var(--vvbd-kh-mau, #7A7A72);
  background: linear-gradient(to right, var(--vvbd-kh-mau, #7A7A72) 50%, #fff 50%);
}

/* Ký hiệu CAO ĐỘ trong chú giải (v1.101.0) — dựng bằng đúng ngôn ngữ hình
   mà tuyến dùng: ruột đặc kèm quầng mực = nổi; rỗng ruột kèm viền mực = chìm;
   vạch mực = cửa hầm. */
.vvbd .vvbd-kh-doan-cao {
  height: 8px; border-radius: 2px;
  background: var(--vvbd-kh-mau, #7A7A72);
  box-shadow: 0 0 0 1.5px #fff, 0 0 3px 1.5px rgba(0, 0, 0, .38);
}
.vvbd .vvbd-kh-doan-ngam {
  height: 10px; border-radius: 2px; box-sizing: border-box;
  border: 3px solid var(--vvbd-kh-mau, #7A7A72);
  background: #FDFBF7;
  outline: 1px solid rgba(44, 44, 42, .55);
}
.vvbd .vvbd-kh-cua-ham {
  width: 4px; height: 14px; border-radius: 1px;
  margin: 0 5px; background: #2C2C2A;
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, .95);
}

.vvbd .vvbd-kh-vung {
  width: 16px;
  height: 11px;
  margin: 3px 1px 0;
  border-radius: 3px;
  background: rgba(176, 141, 87, .28);
  border: 1px solid rgba(176, 141, 87, .8);
  box-sizing: border-box;
}

/* ==================================================================
 * v1.70.0 — ĐIỂM ĐO KHÁCH TỰ CHỈ
 * ==================================================================
 * Hình CHỮ THẬP, không phải chấm tròn. Ba kênh thị giác của ghim dự án (màu
 * tô = pháp lý · cỡ = đặt tay · màu viền = mốc đang đo) đã kín chỗ; thêm một
 * chấm tròn nữa là ép khách đoán chấm này thuộc kênh nào. Khác HÌNH thì
 * không tranh chỗ kênh nào cả.
 *
 * Viền trắng quanh cả hai vạch để chữ thập còn đọc được trên nền đường sẫm —
 * bản đồ bên dưới có đủ mọi màu, một vạch trơn sẽ biến mất ở đâu đó.
 */
.vvbd .vvbd-diem-do { background: none; border: 0; }
.vvbd .vvbd-diem-do span,
.vvbd .vvbd-diem-do span::before {
  content: '';
  position: absolute;
  background: #14241D;
  box-shadow: 0 0 0 1.5px rgba(255, 255, 255, .95);
  border-radius: 1px;
}
.vvbd .vvbd-diem-do span {
  left: 11px; top: 2px;
  width: 2px; height: 20px;
}
.vvbd .vvbd-diem-do span::before {
  left: -9px; top: 9px;
  width: 20px; height: 2px;
}

/* Nút xoá điểm: nằm trong bảng công tắc nên theo giọng của bảng ấy — viền
   mảnh, chữ nhỏ. Khoá cứng ba thuộc tính hộp vì RealHomes Ultra có luật
   `button{…}` trần cùng độ đặc hiệu, hoà thì thắng thua do THỨ TỰ NẠP. */
.vvbd .vvbd-cg-nut-do {
  display: block;
  width: 100%;
  margin: 8px 0 0;
  padding: 8px 9px !important;
  background: #14241D !important;
  color: #FFFDF9 !important;
  border: 0 !important;
  border-radius: 8px !important;
  font: inherit;
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
}
.vvbd .vvbd-cg-nut-do:hover,
.vvbd .vvbd-cg-nut-do:focus { background: #1E3529 !important; color: #FFFDF9 !important; }
/* Đang chờ: đổi hẳn sang vàng thương hiệu — cùng màu với mốc đang đo, nên
   khách đọc ra "bản đồ đang ở chế độ đo" mà không phải học thêm quy ước. */
.vvbd .vvbd-cg-nut-do-bat {
  background: #B08D57 !important;
  color: #241A08 !important;
}
.vvbd .vvbd-cg-nut-do-bat:hover,
.vvbd .vvbd-cg-nut-do-bat:focus { background: #C9A227 !important; color: #241A08 !important; }

.vvbd .vvbd-cg-xoa-diem {
  display: block;
  width: 100%;
  margin: 8px 0 2px;
  padding: 7px 9px !important;
  background: transparent !important;
  color: #14241D !important;
  border: 1px solid rgba(20, 36, 29, .22) !important;
  border-radius: 8px !important;
  font: inherit;
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
}
.vvbd .vvbd-cg-xoa-diem:hover,
.vvbd .vvbd-cg-xoa-diem:focus {
  background: #F4EDE3 !important;
  color: #14241D !important;
}

/* Mẫu điểm đo trong bảng Chú giải — cùng hình chữ thập, thu nhỏ. */
.vvbd .vvbd-kh-diem {
  position: relative;
  width: 13px;
  height: 13px;
  margin: 2px 2px 0;
}
.vvbd .vvbd-kh-diem::before,
.vvbd .vvbd-kh-diem::after {
  content: '';
  position: absolute;
  background: #14241D;
  border-radius: 1px;
}
.vvbd .vvbd-kh-diem::before { left: 5.5px; top: 0; width: 2px; height: 13px; }
.vvbd .vvbd-kh-diem::after { left: 0; top: 5.5px; width: 13px; height: 2px; }

/* ==================================================================
 * v1.68.0 — CĂN CHỈNH CHO ĐIỆN THOẠI
 * ================================================================== */

/* Điện thoại: hai bảng cùng góc trên-phải, cộng lại dễ che kín bản đồ. Ba
   việc phải làm cùng lúc — bảng hẹp lại theo BỀ RỘNG MÀN HÌNH (không phải
   một số cứng, vì máy 320px và máy 430px khác nhau xa), trần chiều cao thấp
   xuống, và chữ nhỏ lại một nấc. Thiếu một trong ba thì hai bảng vẫn nuốt
   quá nửa khung nhìn. */
@media (max-width: 560px) {
  .vvbd .vvbd-chu-giai {
    max-width: min(64vw, 230px);
    font-size: 12px;
  }
  .vvbd .vvbd-cg-nut { padding: 9px 11px !important; font-size: 12px; }
  .vvbd .vvbd-cg-than { max-height: 30vh; padding: 6px 9px 8px; }
  /* Kính trên điện thoại: ĐỤC HƠN và BỎ BLUR. Hai lý do rời nhau — nền hẹp
     thì chữ chồng đường nhiều hơn, và `backdrop-filter` bắt máy tính lại
     vùng mờ mỗi khung hình khi khách kéo bản đồ, thứ Android tầm trung trên
     4G trả giá thật. Khách của villaverde.vn phần lớn là máy ấy. */
  .vvbd .vvbd-bang-kh {
    background: rgba(255, 253, 249, .88);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    max-width: min(58vw, 210px);
    /* ⚠️ 40px KHÔNG phải số cho đẹp — nó là chỗ chừa cho DÒNG GHI CÔNG.
     * Du: "chú giải trên mobile bị che mất". Dòng ghi công của Leaflet nằm
     * ở góc dưới-PHẢI, nhưng trên màn hẹp nó xuống hai dòng và trải gần hết
     * bề ngang; góc dưới-phải lại là góc Leaflet dựng SAU CÙNG nên nó vẽ
     * ĐÈ lên bảng chú giải ở góc dưới-trái. Đẩy chú giải lên trên nó.
     *
     * KHÔNG chữa bằng z-index: đè lại dòng ghi công OSM là dùng sai giấy
     * phép ODbL — cùng lý do watermark phải chừa chỗ bằng margin (§ trên).
     * Máy tính không dính vì bản đồ đủ rộng để ghi công gọn một dòng bên
     * phải, không với tới cột trái. */
    margin: 0 0 40px 8px !important;
  }
  .vvbd .vvbd-bang-kh .vvbd-cg-than { max-height: 32vh; padding: 4px 10px 8px; }
  .vvbd .vvbd-kh-dong { font-size: 11px; }
  /* Thẻ nở ngang tới 380px là hợp lý trên máy tính, nhưng trên máy 375px
     thì nó tràn khỏi bản đồ. Trần theo BỀ RỘNG MÀN HÌNH — số cứng sai vì
     máy 320px và máy 430px khác nhau xa (cùng lý do đã ghi ở bảng chú
     giải). Sàn thẻ cũng phải hạ theo, nếu không sàn 286 lại đẩy tràn. */
  /* ⚠️ KHÔNG thêm `.vvbd .leaflet-popup-content` vào đây: bộ canh có phép
     đòi bộ chọn ấy chỉ được khai ĐÚNG MỘT LẦN trong cả tệp (bài học hai
     luật cùng bộ chọn, v1.59.0), và nó vừa bắt được đúng lỗi này. Chặn ở
     hai tầng bọc là đủ — thân popup `width:auto` nên nó ăn theo. */
  .vvbd .leaflet-popup,
  .vvbd .leaflet-popup .leaflet-popup-content-wrapper { max-width: min(88vw, 340px) !important; }
  .vvbd .leaflet-popup-content > .vvbd-card { min-width: 0; }
  .vvbd .vvbd-cg-muc-gap { padding: 8px 3px !important; font-size: 11px; }
  .vvbd .vvbd-cg-thang-dong { font-size: 11.5px; }
  /* Ô chọn trên điện thoại phải đủ cao để bấm trúng — 16px chữ cũng là mẹo
     chặn iOS Safari tự phóng to trang khi chạm vào ô nhập. */
  .vvbd .vvbd-cg-chon select { min-height: 38px; font-size: 16px; }
}
