/* ═══════════════════════════════════════════════════════════
   Nón Lá — hệ thiết kế ứng dụng
   Bảng màu sơn mài Việt: then, son, vàng lá, vỏ điệp + ngọc bích.
   ═══════════════════════════════════════════════════════════ */
:root{
  /* ngọc bích giữ lại cho phán quyết "giá bình thường" */
  --ngoc:#1F8A70; --ngoc-sau:#0E4A3C;
  /* son và vàng đồng — hai màu chủ của sơn mài và trống đồng */
  --son:#B0201A; --dong:#D9A227; --vang-la:#C9A227;
  /* Vàng lá dùng làm CHỮ thì phải sẫm hơn nhiều: #D9A227 trên nền giấy chỉ
     đạt 2,0:1. Bản này đo được 5,3:1 — cùng một sắc, đủ đọc ngoài nắng. */
  --dong-chu:#7D5F0E;
  /* Ba trọng số viền vàng. Tách ra thành token vì mockup dùng viền như một
     hệ thống — khung ngoài, chỉ trong, vòng đặc — chứ không phải trang trí
     rời rạc từng thẻ. Trộn tay mỗi chỗ một sắc là cách nhanh nhất phá nhịp. */
  --vien:rgba(201,162,39,.52);      /* khung ngoài, hairline */
  --vien-in:rgba(201,162,39,.28);   /* chỉ lót bên trong, lùi vào 5px */
  --vien-dam:#C9A227;               /* vòng đặc quanh ảnh và huy hiệu */
  /* cam đất cho mức cảnh báo nhẹ, tách khỏi vàng đồng của hoạ tiết */
  --ho-phach:#C8791F;
  /* giấy dó làm nền sáng; sơn mài xanh làm nền tối */
  --diep:#F5F0E4; --ngoc-nhat:#F5F0E4; --giay:#FBF7EC;
  --then:#0E2B24;          /* sơn mài xanh — nền tối chủ đạo */
  --then-sau:#08201B;
  --muc:#1D2A24; --muc-nhat:#5F6E64;
  --cham:#3A6EA8;          /* men lam Bát Tràng */
  --line:#E2D9C4;
  --son-dam:#8E1C17;   /* do son dam - chu tren nen hong, dat 4.5:1 */
  --hong:#FBEDE9;      /* nen the canh bao */
  --kem:#F3EEDF;       /* nen chip va anh rong */
  --xam-ghim:#6E6A62;  /* ghim chua du du lieu */
  --pad-x:18px;
  --r:20px; --pill:999px;
  /* Tiêu đề dùng serif — thứ tạo ra vẻ trang trọng trong bộ mockup.
     Thân và số vẫn là Inter: serif đọc số tiền ngoài nắng rất tệ. */
  --disp:"Playfair Display",Georgia,serif;
  --body:"Inter",system-ui,sans-serif;
  /* Không kéo thêm một họ mono nữa: Inter có chữ số đều bề rộng,
     đủ để cột giá và hoá đơn thẳng hàng. */
  --mono:"Inter",system-ui,sans-serif;
  --safe: env(safe-area-inset-bottom, 0px);
}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
html,body{height:100%}
body{
  font-family:var(--body);background:var(--muc);color:var(--muc);
  overscroll-behavior:none;
  font-feature-settings:"cv05" 1,"cv08" 1,"ss03" 1;  /* l có đuôi, chữ số một tầng */
}
/* Mọi chỗ hiển thị số tiền, mã, thời gian: chữ số đều bề rộng để thẳng cột.
   Thay cho họ mono ở bản trước. */
[style*="--mono"],.amt,.ja,.rline,.rtot,.kicker,.src,#busyPct,
.jstat b,.total .big{font-variant-numeric:tabular-nums}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
input,select{font:inherit}

#app{
  position:fixed;inset:0;display:flex;flex-direction:column;
  background:var(--ngoc-nhat);max-width:520px;margin:0 auto;
  box-shadow:0 0 60px rgba(0,0,0,.5);overflow:hidden;
}

/* ── vùng nội dung ─────────────────────────────────────── */
/* overflow-x phải kẹp: hoạ tiết nền và dấu nổi cố tình tràn mép phải,
   để trôi tự do thì sinh cuộn ngang và đẩy lệch toàn bộ giao diện. */
.view{flex:1;min-height:0;position:relative;overflow-y:auto;overflow-x:hidden;
  -webkit-overflow-scrolling:touch}
.view.noscroll{overflow:hidden}
.pad{padding:18px 18px calc(96px + var(--safe));position:relative;z-index:1}

/* Dấu chìm sau màn hình: CÓ, nhưng chỉ ở tab Nearby và chỉ dùng hoạ tiết
   trong assets/motifs/.
   Lần đầu thử lớp này đã phải gỡ, vì ảnh hoạ tiết trong assets/icons/ lưu
   bằng WEBP KHÔNG có kênh alpha (_shrink.py convert("RGB")): dùng làm
   background-image thì cái hiện ra là một khối chữ nhật đục. Bộ trong
   assets/motifs/ thì khác — clean-glyph.py dựng lại alpha từ độ sáng nên
   nền trong suốt thật, và đó là điều kiện đủ để dựng lại lớp này.

   Vì sao chỉ tab Nearby: dưới khối bản đồ là một mảng giấy trơn cao gần
   nửa màn, không có gì trong đó. Ba tab kia kín nội dung từ trên xuống,
   thêm dấu chìm vào chỉ làm chữ khó đọc hơn. */
#v-map::before{
  content:"";position:absolute;z-index:0;pointer-events:none;
  top:-14vw;right:-26vw;width:78vw;max-width:420px;aspect-ratio:1;
  background:no-repeat center/contain url("assets/motifs/trong-dong-v2.webp");
  opacity:.12;
}
/* Dải sóng nước chạy ngang ở cuối trang, chỗ nội dung đã hết. Lặp ngang
   nên bề ngang máy nào cũng khít, và nó đóng trang lại thay cho một
   khoảng trắng cụt. */
#v-map::after{
  content:"";position:absolute;z-index:0;pointer-events:none;
  left:0;right:0;bottom:calc(84px + var(--safe));height:46px;
  background:repeat-x center/auto 46px url("assets/motifs/song-nuoc.webp");
  opacity:.16;
}

/* dải hoạ tiết chạy ngang — dùng làm đường phân cách và chân trang */
/* background-size:contain giữ đúng tỉ lệ ô hoạ tiết rồi mới lặp ngang.
   Dùng "auto 100%" sẽ nén ô theo chiều cao và hoạ tiết vỡ nhịp. */
.frieze{height:24px;background-repeat:repeat-x;background-position:center;
  background-size:contain;opacity:.92;margin:14px 0}
.frieze.tall{height:32px}

/* dấu chìm linh vật cạnh tiêu đề mục */
.crest{position:absolute;pointer-events:none;opacity:.14;z-index:0}

/* ── khung ảnh ─────────────────────────────────────────
   App không ship kèm ảnh. Thả file vào assets/ là khung đầy.
   Thiếu ảnh thì hiện nền giấy dó có dấu nón lá — không bao giờ
   để lộ icon ảnh vỡ cho người dùng thấy. */
.ph{position:relative;width:100%;border-radius:16px;overflow:hidden;
  border:1px solid var(--line);background:var(--giay);margin:2px 0 12px}
.ph img{width:100%;height:100%;object-fit:cover;display:block}
.ph figcaption{
  position:absolute;left:11px;bottom:9px;z-index:2;
  font-family:var(--disp);font-size:15px;font-weight:600;color:#FBF7EC;
  text-shadow:0 1px 8px rgba(0,0,0,.7);
}
.ph::after{ /* lớp phủ để chữ đọc được trên ảnh sáng */
  content:"";position:absolute;inset:auto 0 0 0;height:52%;z-index:1;
  background:linear-gradient(transparent,rgba(8,32,27,.72));
}
.ph.empty{display:grid;place-items:center;
  background:
    radial-gradient(circle at 30% 25%,rgba(217,162,39,.10),transparent 55%),
    repeating-linear-gradient(101deg,rgba(0,0,0,.016) 0 3px,transparent 3px 7px),
    var(--giay);
}
.ph.empty::before{ /* nón lá vẽ một nét */
  content:"";width:64px;height:38px;opacity:.3;
  background:no-repeat center/contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 70'%3E%3Cpath d='M8 60 Q60 -8 112 60' fill='none' stroke='%235F6E64' stroke-width='4' stroke-linecap='round'/%3E%3Cpath d='M8 60 Q60 46 112 60' fill='none' stroke='%235F6E64' stroke-width='2.5' stroke-linecap='round' opacity='.5'/%3E%3C/svg%3E");
}
.ph.empty::after{background:none}
.ph.empty figcaption{position:static;color:var(--muc-nhat);text-shadow:none;
  font-size:12px;font-family:var(--body);font-weight:400;margin-top:8px}
/* Tranh minh hoạ theo loại quán: chú thích là LỜI KHAI "không phải ảnh của
   quán này", nên nhỏ, gọn, nhưng luôn đọc được — kể cả trên thẻ vuông. */
.ph.minhhoa figcaption{font-family:var(--body);font-size:11.5px;font-weight:600;
  letter-spacing:.02em;left:9px;right:9px;bottom:7px;line-height:1.25}
.ph.minhhoa img{background:var(--giay)}
/* Khối thông tin OSM trên thẻ quán: giờ, điện thoại, website, món chay. */
.osminfo{display:grid;gap:6px;margin:12px 0 4px;padding:10px 12px;border-radius:14px;
  background:rgba(14,74,60,.05);border:1px solid var(--line)}
.osminfo div{display:grid;grid-template-columns:86px 1fr;gap:10px;align-items:baseline}
.osminfo dt{font-size:12px;color:var(--muc-nhat);font-weight:600;text-transform:uppercase;letter-spacing:.04em}
.osminfo dd{margin:0;font-size:14px;color:var(--muc);overflow-wrap:anywhere}
.osminfo a{color:var(--then);font-weight:600}

h1.title{font-family:var(--disp);font-size:32px;font-weight:600;letter-spacing:-.012em;line-height:1.1}
h2.sect{font-family:var(--disp);font-size:19px;font-weight:600;letter-spacing:-.008em;margin:24px 0 10px}
.kicker{font-size:10px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--muc-nhat)}
.muted{color:var(--muc-nhat);font-weight:300;font-size:13px;line-height:1.6}

/* ── thanh điều hướng nổi, bo tròn ─────────────────────── */
.tabbar{
  position:absolute;left:12px;right:12px;bottom:calc(10px + var(--safe));z-index:60;
  height:68px;border-radius:34px;background:var(--then);
  border:1px solid rgba(217,162,39,.5);
  box-shadow:0 8px 24px rgba(14,43,36,.28),
             inset 0 1px 0 rgba(217,162,39,.2);
  display:grid;grid-template-columns:1fr 1fr 88px 1fr 1fr;
  align-items:center;justify-items:center;
}
.tab{display:grid;justify-items:center;gap:4px;position:relative;z-index:1;
  color:#CFC9B4;padding:8px 4px;min-width:56px;min-height:56px;align-content:center;
  transition:color .2s cubic-bezier(.22,.61,.36,1)}
.tab svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:1.75;
  stroke-linecap:round;stroke-linejoin:round}
.tab span{font-size:12px;font-weight:500;letter-spacing:.01em}
.tab[aria-current="page"]{color:var(--dong)}
.tab:focus-visible{outline:2px solid var(--dong);outline-offset:2px;border-radius:14px}

/* ── trợ lý hỏi giá (trolychat.js) ─────────────────────────
   Nút tròn nổi phía trên thanh tab, bên phải: ngón cái chạm tới, không che
   nút quét ở giữa. Khung chat phủ cả app, trên thanh tab. */
.tlfab{position:absolute;right:16px;bottom:calc(92px + var(--safe));z-index:59;
  width:52px;height:52px;border-radius:50%;border:1px solid rgba(217,162,39,.55);
  background:var(--then);color:#F6F2E6;display:grid;place-items:center;
  box-shadow:0 8px 22px rgba(14,43,36,.32);transition:transform .22s cubic-bezier(.22,.61,.36,1)}
.tlfab svg{width:24px;height:24px}
.tlfab[hidden]{display:none}
/* Bản đồ toàn màn hình và màn chào nằm TRƯỚC nút trong #app: khi chúng mở thì
   nút trợ lý không được nổi đè lên nút phóng to hay nút đăng nhập. */
#v-bigmap:not([hidden]) ~ .tlfab, #v-welcome:not([hidden]) ~ .tlfab{display:none}
.tlpanel{position:absolute;inset:0;z-index:75;display:grid;grid-template-rows:auto 1fr auto auto auto;
  background:var(--giay);padding-top:env(safe-area-inset-top,0px)}
.tlpanel[hidden]{display:none}
.tlhead{display:grid;grid-template-columns:auto 1fr auto;gap:10px;align-items:center;
  padding:14px 14px 12px;border-bottom:1px solid var(--line);background:rgba(251,247,236,.96)}
.tlava{width:38px;height:38px;border-radius:50%;background:var(--then);color:var(--dong);display:grid;place-items:center}
.tlava svg{width:20px;height:20px}
.tlname{display:grid;line-height:1.2}
.tlname b{font-family:var(--disp);font-size:18px;font-weight:600;color:var(--muc)}
.tlname i{font-style:normal;font-size:12px;color:var(--muc-nhat)}
.tlx{width:44px;height:44px;border-radius:50%;border:0;background:none;color:var(--muc);display:grid;place-items:center}
.tlx svg{width:22px;height:22px}
.tllog{overflow-y:auto;padding:14px;display:flex;flex-direction:column;gap:9px}
.tlmsg{max-width:86%;padding:10px 13px;border-radius:16px;font-size:14.5px;line-height:1.5;color:var(--muc);overflow-wrap:anywhere}
.tlmsg.bot{align-self:flex-start;background:#F1EBDC;border:1px solid var(--line);border-bottom-left-radius:6px}
.tlmsg.me{align-self:flex-end;background:var(--then);color:#F6F2E6;border-bottom-right-radius:6px}
.tlthink{color:var(--muc-nhat);font-style:italic}
.tlgoi{display:flex;gap:8px;overflow-x:auto;padding:0 14px 8px}
.tlchip{flex:0 0 auto;min-height:40px;padding:0 13px;border-radius:20px;border:1px solid var(--line);
  background:#fff;color:var(--then);font-size:13px;font-weight:500;white-space:nowrap}
.tlask{display:grid;grid-template-columns:1fr 50px;gap:8px;padding:8px 14px}
.tlask input{min-height:50px;border-radius:25px;border:1px solid var(--line);background:#fff;
  padding:0 16px;font:inherit;font-size:15px;color:var(--muc)}
.tlsend{width:50px;height:50px;border-radius:50%;border:0;background:var(--then);color:#F6F2E6;display:grid;place-items:center}
.tlsend svg{width:22px;height:22px}
.tlfoot{padding:0 16px calc(12px + var(--safe));font-size:11px;color:var(--muc-nhat);text-align:center}

/* FAB giữa nhô lên khỏi thanh, hai vòng viền vàng */
.scanbtn{
  width:68px;height:68px;border-radius:50%;position:relative;z-index:2;
  background:linear-gradient(160deg,#1F8A70,#0E4A3C);
  border:0;display:grid;place-items:center;transform:translateY(-24px);
  box-shadow:
    inset 0 0 0 1px var(--dong),
    0 0 0 3px var(--dong),
    0 0 0 5px var(--then),
    0 10px 26px -8px rgba(0,0,0,.85),
    0 0 30px rgba(31,138,112,.45);
  transition:transform .22s cubic-bezier(.22,.61,.36,1)}
.scanbtn:active{transform:translateY(-24px) scale(.97)}
.scanbtn:focus-visible{outline:2px solid var(--dong);outline-offset:8px}

@media (prefers-reduced-motion:reduce){
  .tab,.scanbtn,.nb-range{transition:none}
  .scanbtn:active{transform:translateY(-24px)}
}

/* ── màn hình quét ─────────────────────────────────────── */
#camWrap{position:absolute;inset:0;background:#08201B;overflow:hidden}
#cam{width:100%;height:100%;object-fit:cover;display:block}
#camFallback{position:absolute;inset:0;display:none;place-items:center;padding:30px;text-align:center;
  background:radial-gradient(150% 90% at 50% 15%,#4d5443,#15180f)}
#camFallback p{color:#C9D2C4;font-size:13px;line-height:1.65;font-weight:300}

.reticle{position:absolute;top:42%;left:50%;transform:translate(-50%,-50%);
  width:min(62vw,240px);aspect-ratio:1;pointer-events:none}
.reticle svg{width:100%;height:100%;overflow:visible}
.ring-slow{transform-origin:50% 50%;animation:spin 34s linear infinite}
.ring-rev{transform-origin:50% 50%;animation:spin 52s linear infinite reverse}
@keyframes spin{to{transform:rotate(360deg)}}

.modes{position:absolute;top:calc(14px + env(safe-area-inset-top,0px));left:0;right:0;z-index:20;
  display:flex;gap:7px;justify-content:center;flex-wrap:wrap;padding:0 12px}
.mode{background:rgba(10,16,12,.62);border:1px solid rgba(255,255,255,.16);color:#D6DED2;
  padding:8px 15px;border-radius:var(--pill);font-size:12px;font-weight:500;
  backdrop-filter:blur(10px)}
.mode[aria-pressed="true"]{background:var(--dong);border-color:var(--dong);color:#17130E;font-weight:600}

.hint{position:absolute;left:50%;transform:translateX(-50%);bottom:calc(150px + var(--safe));
  z-index:20;background:rgba(10,16,12,.7);backdrop-filter:blur(8px);
  border:1px solid rgba(255,255,255,.11);padding:9px 16px;border-radius:var(--pill);
  color:#DCE4D8;font-size:12px;white-space:nowrap;max-width:90vw;overflow:hidden;text-overflow:ellipsis}

/* Huy hiệu này ĐỨNG DƯỚI hàng chế độ, không đứng cạnh. Ở khổ 390px bốn
   viên Menu/Cash/Bill/Dish chiếm gần hết bề ngang, và huy hiệu neo phải đè
   lên chữ "Dish" — ảnh chụp màn hình cho hồ sơ dự thi bắt được đúng chỗ đó. */
.offline{position:absolute;top:calc(58px + env(safe-area-inset-top,0px));right:14px;z-index:25;
  display:none;align-items:center;gap:5px;background:rgba(31,138,112,.24);
  border:1px solid rgba(127,217,190,.42);color:#8FE3C6;font-family:var(--mono);
  font-size:9px;letter-spacing:.05em;padding:5px 10px;border-radius:var(--pill)}
.offline i{width:5px;height:5px;border-radius:50%;background:#5CD6AE}

/* dải cảnh báo ở viền — kín đáo, người bán không thấy */
.edge{position:absolute;inset:0;z-index:50;pointer-events:none;transition:box-shadow .35s}
#busy{border-radius:0}
.edge[data-level="ok"]{box-shadow:inset 0 0 0 4px var(--ngoc)}
.edge[data-level="warn"]{box-shadow:inset 0 0 0 4px var(--ho-phach)}
.edge[data-level="high"]{box-shadow:inset 0 0 0 4px var(--son),inset 0 0 30px rgba(176,32,26,.3)}

/* ── thẻ kết quả trượt lên ─────────────────────────────── */
.sheet{
  /* PHẢI cao hơn #v-bigmap và #v-foodmap (z-index 70). Ở 55, chạm một mốc
     tham quan trên bản đồ toàn khung thì thẻ chi tiết mở ra NGAY PHÍA SAU
     bản đồ — người dùng bấm và không thấy gì, tưởng nút chết. */
  position:absolute;left:0;right:0;bottom:0;z-index:82;
  background:var(--giay);color:var(--muc);
  border-radius:28px 28px 0 0;max-height:76%;
  display:flex;flex-direction:column;
  box-shadow:0 -16px 40px -14px rgba(0,0,0,.55);
  transform:translateY(101%);transition:transform .32s cubic-bezier(.32,.72,0,1);
}
.sheet.open{transform:translateY(0)}
.sheet .grab{width:36px;height:4px;border-radius:4px;background:#D8CCB4;margin:9px auto 2px;flex:0 0 auto}
/* Dấu X ở góc trên, NGOÀI phần cuộn: thẻ dài (quán, điểm tham quan) chỉ có nút
   Close ở tận cuối, phải cuộn hết mới đóng được. */
.sheet .sheetx{position:absolute;top:10px;right:12px;z-index:3;width:40px;height:40px;border-radius:50%;
  border:1px solid var(--line);background:rgba(251,247,236,.94);color:var(--muc);
  display:grid;place-items:center;box-shadow:0 2px 8px rgba(14,43,36,.12)}
.sheet .sheetx svg{width:18px;height:18px}
.sheet .inner{overflow-y:auto;padding:14px 17px calc(92px + var(--safe))}
/* Dải mây đầu thẻ đã gỡ, nên tiêu đề đứng sát mép trên: chừa chỗ để dấu X
   không đè lên chữ của tiêu đề dài. */
.sheet .inner > h3:first-child{padding-right:48px}
.sheet h3{font-family:var(--disp);font-size:22px;font-weight:600;letter-spacing:-.01em;margin:10px 0 3px}
.src{font-size:10.5px;color:var(--muc-nhat);font-weight:300;line-height:1.5}

.wave{display:block;width:100%;height:8px;margin:11px 0;opacity:.45}

/* ── dòng món ──────────────────────────────────────────── */
.row{display:grid;grid-template-columns:10px 1fr auto;gap:11px;align-items:center;
  padding:11px 0;border-bottom:1px solid var(--line);text-align:left;width:100%;background:none}
.row:last-child{border-bottom:0}
.dot{width:9px;height:9px;border-radius:50%;flex:0 0 auto}
.dot[data-l="ok"]{background:var(--ngoc)}
.dot[data-l="warn"]{background:var(--ho-phach)}
.dot[data-l="high"]{background:var(--son);box-shadow:0 0 0 3px rgba(192,57,43,.16)}
.dot[data-l="unknown"]{background:#BDC5B9}
.row .nm{display:block;font-size:13.5px;font-weight:500;line-height:1.3}
.row .note{display:block;font-size:10.5px;color:var(--muc-nhat);font-weight:300;margin-top:2px}
.row .amt{font-family:var(--mono);font-size:13px;font-weight:600;text-align:right;white-space:nowrap}
.row .amt small{display:block;font-size:9.5px;font-weight:400;color:var(--muc-nhat)}
.row .amt[data-l="high"]{color:var(--son)}

/* Dòng đoán món: tên món LÀ câu trả lời, nên nó phải đọc được từ xa một
   sải tay — người dùng đang cầm máy chĩa vào bát, không cúi sát màn hình. */
.row.guess{padding:15px 0}
.row.guess .nm{font-family:var(--disp);font-size:26px;font-weight:600;
  letter-spacing:-.015em;line-height:1.15}
.row.guess .note{font-size:11.5px;margin-top:5px}
.row.guess .amt{font-size:14px}

/* ── nút ───────────────────────────────────────────────── */
.btn{display:flex;align-items:center;justify-content:center;gap:8px;
  min-height:48px;width:100%;text-align:center;border-radius:14px;padding:13px;
  font-size:14px;font-weight:600;margin-top:10px}
/* Icon trong nút phải được ĐẶT KÍCH THƯỚC. Một <svg> có viewBox mà không có
   width/height thì trình duyệt cho nó cỡ mặc định 300×150 — nút "Share this
   dish" đo được 383px cao vì đúng chuyện đó. Ba nút có icon trước đây tự khai
   cỡ riêng (.btn.maps, .btn.save, .btn.sec.out), nên lỗi chỉ lộ ra ở nút thứ
   tư; đặt luật chung ở đây để nút thứ năm không phải phát hiện lại. */
.btn svg{width:18px;height:18px;flex:0 0 auto}
.btn.pri{background:var(--ngoc);color:#fff}
.btn.sec{border:1px solid var(--line);color:var(--muc)}
.btn.dark{background:var(--muc);color:#F3F1E9}
.btn:active{transform:scale(.985)}
.btn:focus-visible{outline:2px solid var(--ngoc);outline-offset:2px}

/* ── nói hộ ────────────────────────────────────────────── */
.say{display:flex;align-items:center;gap:11px;margin-top:13px;
  background:var(--ngoc-sau);color:#EAF6F1;border-radius:15px;padding:12px 14px;width:100%;text-align:left}
.say .vi{font-family:var(--disp);font-size:19px;font-weight:600}
/* Phiên âm nằm trên DÒNG RIÊNG dưới câu tiếng Việt. Trước đây nó là một
   <span> inline nên chạy dính ngay sau câu — mà kể cả thế cũng không ai
   thấy, vì lớp cũ tên `.ph` trùng với lớp khung ảnh và bị tô thành một
   mảng xám đặc. */
.say .sayph{display:block;font-size:11px;opacity:.72;font-weight:400;
  margin-top:3px;letter-spacing:.02em}
.say .spk{margin-left:auto;width:32px;height:32px;border-radius:50%;background:var(--ho-phach);
  display:grid;place-items:center;flex:0 0 auto}
.say .spk svg{width:15px;height:15px;fill:none;stroke:#14170F;stroke-width:1.9;stroke-linecap:round}

/* ── thẻ chung ─────────────────────────────────────────── */
.card{background:var(--giay);border:1px solid var(--line);border-radius:var(--r);padding:15px;margin-top:11px}
.card h4{font-family:var(--disp);font-size:18px;font-weight:600;letter-spacing:-.008em}
.tagrow{display:flex;gap:6px;flex-wrap:wrap;margin-top:9px}
.tg{font-size:10.5px;font-weight:500;padding:5px 10px;border-radius:var(--pill);background:#EFE6D3;color:var(--muc-nhat)}
.tg.hot{background:#FBE9DF;color:#B4521F}
.tg.alert{background:#FCEEEB;color:var(--son)}
.tg.veg{background:#E3F3EA;color:#166B52}
.badge{display:inline-flex;align-items:center;gap:5px;font-size:10.5px;font-weight:600;
  padding:4px 9px;border-radius:var(--pill);background:var(--ngoc);color:#fff}
.badge.no{background:#F2EEE4;color:var(--muc-nhat)}
.badge.flag{background:#FCEEEB;color:var(--son)}
.badge svg{width:11px;height:11px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round}

/* ── ô nhập tay (lối thoát bắt buộc) ───────────────────── */
.manual{display:grid;grid-template-columns:1fr 96px;gap:8px;margin-top:9px}
.manual input{border:1px solid var(--line);border-radius:12px;padding:11px 12px;font-size:14px;width:100%;background:var(--giay)}
.manual input:focus{outline:2px solid var(--ngoc);outline-offset:-1px}

/* ── tiến trình OCR ────────────────────────────────────── */
#busy{position:absolute;inset:0;z-index:84;display:none;place-items:center;
  background:rgba(11,14,9,.72);backdrop-filter:blur(3px)}
#busy.on{display:grid}
.lantern{width:56px;height:74px;animation:sway 2.6s ease-in-out infinite;transform-origin:50% 4%}
@keyframes sway{0%,100%{transform:rotate(-5deg)}50%{transform:rotate(5deg)}}
#busyTxt{margin-top:14px;color:#E4DFCE;font-size:12.5px;text-align:center;font-weight:300}
#busyPct{font-family:var(--mono);font-size:11px;color:var(--ho-phach);margin-top:5px}

/* ═══ TAB NEARBY — "Explore by map" ════════════════════
   Bố cục map-first: tiêu đề, một thẻ số liệu chia đôi, hàng bộ
   lọc cuộn ngang, khối bản đồ chiếm phần lớn màn hình, rồi khay
   thẻ cuộn ngang đè lên mép dưới bản đồ.

   Ba mức tin cậy luôn có ICON + CHỮ, không bao giờ chỉ dựa vào màu.
   ═════════════════════════════════════════════════════ */
/* Kính mờ: nền giấy trong suốt, làm mờ phần phía sau, viền sáng mảnh. */
.ex-head{position:relative;z-index:1;margin:0 0 4px;padding:14px 16px 16px;
  background:rgba(251,247,236,.58);
  -webkit-backdrop-filter:blur(16px) saturate(1.4);backdrop-filter:blur(16px) saturate(1.4);
  border:1px solid rgba(255,255,255,.7);border-radius:24px;
  box-shadow:0 10px 30px -18px rgba(93,72,20,.4), inset 0 1px 0 rgba(255,255,255,.6)}

.nb-topbar{display:flex;align-items:center;gap:9px;padding-right:58px;
  min-height:48px;position:relative;z-index:2}
.nb-topbar .pag{width:24px;height:24px;flex:0 0 auto;color:var(--then)}
.nb-topbar .kick{font-size:clamp(11px,3vw,13px);font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muc);line-height:1.2}
/* Chuông lấy viền vàng và mực ngọc, không phải viền xám mực đen: nó là
   nút duy nhất ở hàng trên cùng, và trên nền giấy ngà một viền xám nhạt
   làm nó biến mất hẳn. */
.nb-bell{position:absolute;top:0;right:0;width:48px;height:48px;border-radius:50%;
  background:#FDFAF1;border:1.5px solid var(--vien);display:grid;place-items:center;
  box-shadow:0 3px 10px -3px rgba(93,72,20,.24);color:var(--ngoc-sau);z-index:5}
.nb-bell svg{width:21px;height:21px}

.nb-h1{font-family:var(--disp);font-weight:600;color:var(--then);
  font-size:clamp(32px,10.2vw,54px);line-height:.98;letter-spacing:-.02em;
  margin-top:10px;position:relative;z-index:2}
/* Không còn blob nổi bên phải, nên tiêu đề và phụ đề dùng hết bề ngang.
   Bản trước kẹp max-width 56% để chừa chỗ cho blob — giữ lại thì tiêu đề
   vỡ thành bốn dòng mà bên phải trống trơn. */
.ex-h1{max-width:none}
.nb-sub{font-size:clamp(13px,3.6vw,16px);line-height:1.5;color:var(--muc-nhat);
  margin-top:12px;position:relative;z-index:2}
.ex-sub{max-width:34ch}

/* ── thẻ số liệu chia đôi ──────────────────────────── */
.ex-stats{display:flex;align-items:stretch;gap:10px;position:relative;z-index:2;
  margin-top:clamp(16px,4.6vw,22px);padding:14px 12px;border-radius:24px;
  background:var(--giay);border:1.5px solid var(--vien);
  box-shadow:0 8px 24px rgba(18,61,43,.08);overflow:hidden}
/* Dải mây Đông Sơn chìm ở đáy thẻ — sơn bằng JS trong paintMotifs() */
.ex-stat{flex:1 1 0;min-width:0;display:flex;align-items:center;gap:11px;
  position:relative;z-index:1}
.ex-stat .ico{width:clamp(44px,13vw,56px);aspect-ratio:1;border-radius:50%;flex:0 0 auto;
  display:grid;place-items:center;border:2px solid var(--vien-dam)}
.ex-stat .ico svg{width:52%;height:52%}
.ex-stat .ico.ok{background:linear-gradient(165deg,#134338,#0B2620);color:var(--dong)}
.ex-stat .ico.bad{background:var(--ho-phach);border-color:#9A5A12;color:#FFF6E8}
.ex-stat b{display:block;font-size:clamp(26px,8vw,34px);font-weight:700;
  letter-spacing:-.03em;line-height:1;color:var(--then);font-variant-numeric:tabular-nums}
.ex-stat i{display:block;font-style:normal;margin-top:4px;
  font-size:clamp(11px,3.1vw,12.5px);line-height:1.3;color:var(--muc-nhat)}
.ex-div{width:1px;flex:0 0 auto;background:var(--line);margin:2px 0}

/* ── chọn vùng ─────────────────────────────────────
   Cuộn ngang và tràn ra hai mép rồi tự đệm lại, cùng khuôn với .ex-chips:
   sáu vùng không bao giờ vừa một màn 360px, và cắt cụt thẻ cuối ở mép
   phải là cách chắc chắn nhất để người dùng tưởng chỉ có bốn vùng. */
/* Lưới, không cuộn ngang: vùng nào cũng hiện ra ngay, kể cả trên máy tính không
   có cử chỉ vuốt. Mỗi ô nhường đủ chỗ cho tên và số điểm tham quan. */
.zone-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:9px;
  padding:14px 0 2px;position:relative;z-index:2}
.zone-chip{display:grid;gap:1px;min-width:0;text-align:left;
  min-height:52px;padding:8px 14px;border-radius:16px;
  background:var(--giay);border:1.5px solid var(--vien-in);
  transition:transform .2s cubic-bezier(.22,.61,.36,1)}
.zone-chip b{font-family:var(--disp);font-size:15px;font-weight:600;color:var(--then);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.15}
.zone-chip span{font-size:11px;color:var(--muc-nhat);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.zone-chip:active{transform:scale(.97)}
.zone-chip[aria-pressed="true"]{background:var(--then);border-color:var(--vien-dam);
  box-shadow:0 6px 16px -8px rgba(14,43,36,.7)}
.zone-chip[aria-pressed="true"] b{color:#F6F2E6}
.zone-chip[aria-pressed="true"] span{color:var(--dong)}
.zone-chip:focus-visible{outline:2px solid var(--dong);outline-offset:2px}

/* ── khay điểm tham quan ───────────────────────────── */
.sight-rail{display:flex;gap:11px;overflow-x:auto;overflow-y:hidden;
  padding:2px var(--pad-x) 6px;margin:0 calc(-1 * var(--pad-x));
  scrollbar-width:none;overscroll-behavior-x:contain}
.sight-rail::-webkit-scrollbar{display:none}
.sight-card{flex:0 0 auto;width:148px;display:grid;gap:3px;text-align:left}
/* Dấu nón lá nằm DƯỚI ảnh nền, không phải một lớp phủ bật/tắt: ô nào có
   tranh thì tranh che nó đi, ô nào chưa có — hoặc ảnh 404 — thì nó lộ ra.
   Không cần onerror, không cần cờ trạng thái nào cả.
   background-size/position là BẮT BUỘC: thiếu chúng thì ảnh 1024px nằm
   nguyên cỡ trong ô 148px và chỉ lộ ra góc trên trái. Đúng lỗi đã làm ô
   tròn của thẻ chuyến đi trống trơn. */
.sight-art{position:relative;display:block;width:148px;height:100px;border-radius:14px;
  overflow:hidden;border:1px solid var(--vien-in);
  background:var(--kem) no-repeat center/cover}
.sight-art::before{content:"";position:absolute;inset:0;z-index:-1;
  background:no-repeat center/40px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 70'%3E%3Cpath d='M8 60 Q60 -8 112 60' fill='none' stroke='%235F6E64' stroke-width='4' stroke-linecap='round'/%3E%3C/svg%3E");
  opacity:.3}
.sight-star{position:absolute;top:7px;left:7px;width:24px;height:24px;border-radius:50%;
  display:grid;place-items:center;background:rgba(14,43,36,.88);color:var(--dong)}
.sight-star svg{width:14px;height:14px}
.sight-card b{font-family:var(--disp);font-size:13.5px;font-weight:600;color:var(--then);
  line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sight-en{font-size:11px;color:var(--muc-nhat);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sight-hero{margin-top:10px}

/* ── hàng bộ lọc ───────────────────────────────────── */
/* Tràn ra hai mép rồi tự đệm lại: chip cuối không bị cắt cụt ở mép phải,
   và người dùng thấy được là hàng này còn cuộn tiếp. */
.ex-chips{display:flex;gap:9px;overflow-x:auto;overflow-y:hidden;
  padding:12px var(--pad-x) 4px;margin:0 calc(-1 * var(--pad-x));
  scrollbar-width:none;overscroll-behavior-x:contain;position:relative;z-index:2}
.ex-chips::-webkit-scrollbar{display:none}
.ex-chip{display:inline-flex;align-items:center;gap:7px;flex:0 0 auto;
  min-height:44px;padding:0 15px;border-radius:var(--pill);white-space:nowrap;
  background:#fff;border:1.5px solid var(--vien);color:var(--muc);
  font-size:clamp(12.5px,3.5vw,14px);font-weight:600;
  transition:transform .2s cubic-bezier(.22,.61,.36,1)}
.ex-chip:active{transform:scale(.96)}
/* Icon nằm trong một đĩa màu riêng của từng bộ lọc, không phải một nét
   vẽ trần. Bản trước bốn chip là bốn viên trắng giống hệt nhau, icon
   cùng một sắc xanh — cả hàng đọc ra là một dải xám và không chip nào
   nói được nó lọc cái gì trước khi người dùng đọc chữ. Mỗi bộ lọc một
   sắc, lấy từ đúng bảng màu app đã dùng ở chỗ khác: ngọc cho "giá
   thường", son cho "vượt khoảng", nâu cà phê, vàng đồng cho hàng rong. */
.ex-chip svg{width:26px;height:26px;flex:0 0 auto;padding:4.5px;border-radius:50%;
  color:var(--ngoc-sau);background:rgba(31,138,112,.15);
  box-shadow:inset 0 0 0 1px rgba(31,138,112,.22)}
.ex-chip[data-exf="over"] svg{color:var(--son);background:rgba(176,32,26,.12);
  box-shadow:inset 0 0 0 1px rgba(176,32,26,.2)}
.ex-chip[data-exf="coffee"] svg{color:#6E4517;background:rgba(110,69,23,.13);
  box-shadow:inset 0 0 0 1px rgba(110,69,23,.2)}
.ex-chip[data-exf="street"] svg{color:#8A5A16;background:rgba(201,162,39,.2);
  box-shadow:inset 0 0 0 1px rgba(201,162,39,.34)}
.ex-chip[aria-pressed="true"]{background:var(--then);color:#F6F2E6;
  border-color:var(--vien-dam);box-shadow:0 6px 16px -8px rgba(14,43,36,.7)}
/* Chip đang chọn: nền then nuốt hết mọi đĩa màu nhạt, nên icon quay về
   vàng đồng trên nền trong — sắc duy nhất đọc được trên nền tối đó. */
.ex-chip[aria-pressed="true"] svg{color:var(--dong);background:rgba(217,162,39,.16);
  box-shadow:inset 0 0 0 1px rgba(217,162,39,.34)}
.ex-chip.round{width:48px;padding:0;justify-content:center}
.ex-chip.round svg{background:none;box-shadow:none;color:var(--muc-nhat);padding:0;
  width:19px;height:19px}
.ex-chip:focus-visible{outline:2px solid var(--dong);outline-offset:2px}

/* ── khối bản đồ ───────────────────────────────────── */
/* Cao theo svh chứ không phải vh: trên mobile vh tính cả thanh địa chỉ,
   nên khay thẻ bên dưới bị đẩy khuất khi thanh đó hiện ra. */
/* Chiều cao kẹp ở 36svh chứ không phải 48: cao hơn thì mép trên của khay
   thẻ rơi xuống dưới thanh nav, và màn hình mở ra trông như không có khay.
   Thẻ đầu tiên phải ló ra được thì người dùng mới biết là còn nội dung. */
.ex-map{position:relative;z-index:1;margin-top:12px;border-radius:24px;
  height:clamp(230px,36vh,340px);overflow:hidden;
  border:1.5px solid var(--vien);background:#F4EBD3;
  box-shadow:0 10px 28px rgba(14,43,36,.14)}
/* svh loại được thanh địa chỉ mobile ra khỏi phép tính, nhưng trình duyệt
   cũ không hiểu — khai riêng một dòng để bản trên chỉ đè khi hiểu được,
   gộp vào clamp ở trên thì cả khai báo hỏng và khối bản đồ cao 0. */
@supports (height:1svh){ .ex-map{height:clamp(230px,36svh,340px)} }
.ex-canvas{position:absolute;inset:0;overflow:hidden}
/* Lớp lót: chính tấm tranh của vùng, phóng phủ kín và làm mờ hẳn. Biến
   --ex-art do bigmap.js đặt sau khi biết vùng này có tranh nào.

   VÌ SAO CẦN LỚP NÀY
   fitArt cố phủ kín khung, nhưng có cụm cơ sở mà không mức phóng nào vừa
   phủ kín vừa chứa hết ghim — cụm bờ tây sông Hàn chẳng hạn, dài dọc mà
   tranh thì vuông. Lúc đó nó nhường chỗ cho việc hiện đủ ghim, và chỗ hở
   ra là một mảng giấy phẳng lì: người dùng đọc ngay ra "ảnh tải hỏng".
   Một lớp mờ của chính tấm tranh thì không bao giờ đọc ra là lỗi.
   Vùng chưa có tranh không đặt biến này, nên lớp lót tự tắt. */
.ex-canvas::before{
  content:"";position:absolute;inset:-8%;z-index:0;
  background:var(--ex-art,none) center/cover no-repeat;
  filter:blur(16px) saturate(.86) brightness(1.04);
  opacity:.85;pointer-events:none;
}
.ex-canvas .ex-base{position:relative;z-index:1;width:100%;height:100%;display:block}
/* Tranh vẽ tay đã neo toạ độ. Kích thước và độ lệch do JS đặt theo phép
   georeference, nên KHÔNG dùng object-fit — object-fit tự cắt theo ý nó
   và mọi ghim lệch khỏi mái nhà của nó ngay. */
.ex-art{position:absolute;left:0;top:0;z-index:1;transform-origin:0 0;
  max-width:none;display:block;image-rendering:auto}
.ex-art[hidden]{display:none}
.ex-pins{position:absolute;inset:0;z-index:3;pointer-events:none}
/* Ghim neo bằng transform do JS đặt, nên căn tâm bằng margin âm —
   thêm translate vào transform sẽ bị JS ghi đè mỗi lần vẽ lại.
   Hộp 44×52 là VÙNG CHẠM, hình vẽ 30×40 nằm sát đáy hộp: mũi nhọn
   của ghim trùng đúng toạ độ, còn ngón tay vẫn có đủ 44px để bấm. */
.ex-pin{position:absolute;left:0;top:0;width:44px;height:52px;
  margin-left:-22px;margin-top:-52px;pointer-events:auto;
  display:grid;place-items:end center;
  filter:drop-shadow(0 3px 5px rgba(14,43,36,.42))}
.ex-pin svg{width:30px;height:40px;display:block}
/* `display:grid` ở trên là quy tắc của tác giả nên nó ĐÈ luôn display:none
   mà trình duyệt gán cho [hidden]. Thiếu dòng này thì bộ lọc đổi thuộc tính
   hidden nhưng ghim vẫn nằm nguyên trên bản đồ — phép thử đếm theo thuộc
   tính vẫn xanh trong khi mắt thấy sai. */
.ex-pin[hidden]{display:none}
/* Ghim của cơ sở nằm NGOÀI mép tranh, bị bigmap.js kéo về sát viền. Phải
   trông khác hẳn ghim thường: nó không chỉ vào mái nhà nào cả, chỉ nói
   "còn một chỗ nữa, về phía này". Mờ đi và nhỏ lại là đủ — thêm mũi tên
   hướng thì lại phải tính hướng, mà hướng đó cũng đã bị phép kẹp làm sai. */
.ex-pin[data-off]{opacity:.62;filter:none}
.ex-pin[data-off] svg{width:24px;height:32px}
.ex-pin:focus-visible{outline:2px solid var(--dong);outline-offset:2px;border-radius:8px}
/* Quán chưa có lượt quét ở khung xem trước: chấm neo ĐÚNG toạ độ (tâm chấm),
   vùng chạm vẫn 44px. Viền kem và bóng sẫm để đọc được trên tranh nhiều màu. */
.ex-pin.dot{height:44px;margin-top:-22px;place-items:center}
.ex-pin.dot::before{content:"";width:13px;height:13px;border-radius:50%;background:#8A7A66;
  border:2.5px solid #FBF7EC;box-shadow:0 1px 4px rgba(14,43,36,.55)}
.ex-me{position:absolute;left:0;top:0;z-index:2;width:0;height:0}
.ex-me i{position:absolute;left:-7px;top:-7px;width:14px;height:14px;border-radius:50%;
  background:var(--cham);border:2.5px solid #fff;box-shadow:0 0 0 9px rgba(58,110,168,.18)}

/* Nút phủ kín bản đồ: chạm chỗ trống mở bản đồ chi tiết. Nằm DƯỚI lớp
   ghim (z-index 1 so với 3) nên không nuốt cú chạm vào ghim. */
.ex-open{position:absolute;inset:0;z-index:1;display:block}
/* Cách đáy 26px chứ không 12: khay thẻ bên dưới trượt đè lên mép dưới bản
   đồ, và ở 12px thì nó cắt ngang viên "Open full map" làm đôi — nút đọc ra
   là một mảnh chữ bị xén. Cùng lý do với hai nút tròn bên phải. */
/* z-index 5 — TRÊN cả lớp ghim (3). Nhãn là chữ, bị một cái ghim đè lên
   là mất nghĩa; ghim bị nhãn đè lên thì vẫn còn 5 cái khác cùng loại.
   pointer-events:none để cú chạm rơi xuống .ex-open nằm dưới. */
/* Về lại sát đáy. Con số 26 trước đây chỉ tồn tại để né phần khay đè
   lên; khay thôi đè thì nút không còn gì phải né, và giữ nó ở 26 là ăn
   mất một dải bản đồ mà không đổi lại được gì. */
.ex-openlabel{position:absolute;left:12px;bottom:14px;z-index:5;pointer-events:none;
  display:inline-flex;align-items:center;min-height:38px;padding:0 15px;
  border-radius:var(--pill);background:rgba(14,43,36,.94);color:#F6F2E6;
  border:1px solid var(--vien);
  font-size:clamp(11.5px,3.2vw,13px);font-weight:600;
  box-shadow:0 8px 20px -8px rgba(14,43,36,.8)}
/* Khung chứa KHÔNG nhận chạm, chỉ hai cái đĩa tròn nhận. Khung là một ô
   lưới 52×114 kể cả khe hở giữa hai nút, và ở trạng thái nhận chạm nó
   nuốt luôn cú chạm vào cái ghim nằm lọt phía sau khe đó — đo được thật:
   ghim banh-mi-goc trả về DIV.ex-fabs thay vì chính nó. */
.ex-fabs{position:absolute;right:12px;bottom:14px;z-index:4;display:grid;gap:10px;
  pointer-events:none}
.ex-fabs>*{pointer-events:auto}
.ex-fab{width:52px;height:52px;border-radius:50%;background:#FDFAF1;
  border:1.5px solid var(--vien);display:grid;place-items:center;color:var(--ngoc-sau);
  box-shadow:0 6px 18px -6px rgba(14,43,36,.45);
  transition:transform .2s cubic-bezier(.22,.61,.36,1)}
.ex-fab:active{transform:scale(.94)}
.ex-fab svg{width:22px;height:22px}
/* HAI nút tròn cạnh nhau, hai việc khác hẳn nhau: một cái tìm chỗ đang
   đứng, một cái mở bản đồ chi tiết. Bản trước cả hai đều là đĩa trắng
   icon đen — nhìn ra là một cặp nút song sinh, và không cái nào nói được
   rằng mở bản đồ mới là việc chính ở đây. Nút chính lấy nền then + chỉ
   vàng của nút chính toàn app; nút phụ giữ nền giấy. */
.ex-fab[data-act="bigMap"]{
  background:linear-gradient(165deg,#12483A,#0B2A22);
  border-color:var(--vien-dam);color:var(--dong);
  box-shadow:0 8px 20px -6px rgba(11,42,34,.62)}

/* ── khay thẻ dưới ─────────────────────────────────── */
/* KHÔNG đè lên bản đồ nữa. Bản đầu đè 26px, bản sau 14px — cả hai xuất
   phát từ một ý đúng (khay phải ló ra thì người dùng mới biết dưới còn
   nội dung) nhưng giải sai: thứ ló ra không cần là khay, vì hàng thẻ quán
   bên trong nó đã tự lộ một nửa ở mép phải màn hình rồi.

   Cái giá thì thật: 14px cuối của bản đồ bị che, và đó đúng là dải chứa
   viên "Open full map" cùng hai nút tròn — chỗ đắt nhất của cả khối.

   8px khe hở thay vì 0: hai khối bo góc chạm sát nhau thì hai đường cong
   ngược chiều tạo ra một khe hình thoi trông như lỗi dựng hình. */
.ex-sheet{position:relative;z-index:2;margin-top:8px;
  padding:10px 14px 14px;border-radius:26px;
  background:var(--diep);border:1.5px solid var(--vien);
  box-shadow:0 -6px 24px rgba(14,43,36,.10)}
.ex-grab{display:block;width:44px;height:5px;border-radius:var(--pill);
  background:#D6CDBA;margin:0 auto 4px}
/* Trong khay, hàng tiêu đề phải nằm gọn MỘT dòng: tiêu đề xuống dòng thì
   đường diềm co lại còn một gạch ngắn và cả hàng trông như hỏng. Bỏ luôn
   đường diềm ở đây — bề ngang còn lại sau "See all" không đủ cho nó. */
.ex-sheet .sect-row{margin:6px 0 10px;gap:9px}
.ex-sheet .sect-row h2{font-size:clamp(16px,4.4vw,20px)}
.ex-sheet .sect-row .rule{display:none}

.ex-rail{display:grid;grid-auto-flow:column;grid-auto-columns:min(86%,300px);
  gap:12px;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;
  padding:3px 14px 8px;margin:0 -14px;
  scrollbar-width:none;overscroll-behavior-x:contain}
.ex-rail::-webkit-scrollbar{display:none}

.ex-card{scroll-snap-align:center;text-align:left;position:relative;overflow:hidden;
  display:grid;grid-template-columns:clamp(80px,24vw,96px) 1fr;gap:12px;align-items:stretch;
  background:linear-gradient(168deg,#fff 58%,#FDFAF1);
  border:1.5px solid var(--vien);border-radius:20px;padding:12px;
  box-shadow:0 4px 16px rgba(14,43,36,.07);
  transition:transform .22s cubic-bezier(.22,.61,.36,1)}
/* Mây xoắn chìm góc trên trái — sơn bằng JS trong paintMotifs() */
.ex-card:active{transform:scale(.97)}
.ex-card>*{position:relative;z-index:1}
.ex-card .ph.sq{width:100%}
/* Các thẻ trong khay cao bằng nhau (thẻ tên dài nhất quyết định). Dùng flex
   để đẩy nhãn trạng thái xuống đáy — để nó bám theo chữ thì thẻ tên ngắn
   có một mảng trống lơ lửng dưới nhãn. */
.ex-body{display:flex;flex-direction:column;gap:6px;min-width:0}
.ex-card .nm{font-family:var(--disp);font-size:clamp(16px,4.8vw,19px);
  font-weight:600;color:var(--then);letter-spacing:-.008em;line-height:1.2}
.ex-card .meta{display:flex;align-items:center;gap:5px;
  font-size:clamp(11.5px,3.3vw,13px);color:var(--muc-nhat);line-height:1.3}
.ex-card .meta svg{width:14px;height:14px;flex:0 0 auto;color:var(--dong)}
.ex-row{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.since{display:inline-flex;align-items:center;gap:4px;
  font-size:clamp(10.5px,3vw,12px);font-weight:600;padding:4px 9px;
  border-radius:var(--pill);background:rgba(31,138,112,.12);
  border:1px solid rgba(31,138,112,.3);color:var(--ngoc-sau)}
.since svg{width:12px;height:12px;flex:0 0 auto}
/* margin-top:auto đẩy nhãn xuống đáy thẻ. Các thẻ cao bằng nhau, nên nhãn
   ở mọi thẻ thẳng một hàng thay vì bậc thang theo độ dài tên quán. */
.ex-card .pill{width:100%;margin-top:auto;padding-top:2px}
.ex-card .ex-thumb{align-self:start}

.ex-empty{display:flex;align-items:center;gap:9px;padding:10px 2px 4px;
  font-size:clamp(12.5px,3.6vw,14px);color:var(--muc-nhat)}
.ex-empty svg{width:18px;height:18px;flex:0 0 auto;color:var(--dong)}

/* ── hàng tiêu đề mục ──────────────────────────────── */
.sect-row{display:flex;align-items:center;gap:11px;margin:clamp(26px,7vw,34px) 0 14px}
.sect-row .spark{width:19px;height:19px;color:var(--dong);flex:0 0 auto}
.sect-row h2{margin:0;flex:0 1 auto;min-width:0;font-family:var(--disp);
  font-size:clamp(18px,5.2vw,23px);font-weight:600;color:var(--then);letter-spacing:-.01em}
/* Đường kẻ nhạt dần về hai đầu — kẻ vàng đều tay trông như một thanh chắn,
   kiểu này đọc ra là đường diềm. */
.sect-row .rule{flex:1 1 auto;height:1px;min-width:10px;
  background:linear-gradient(90deg,var(--vien-dam),rgba(201,162,39,.14))}
.sect-row .act{display:inline-flex;align-items:center;gap:5px;min-height:46px;
  padding:0 4px;font-size:clamp(13px,3.8vw,15px);font-weight:600;
  color:var(--dong-chu);flex:0 0 auto}
.sect-row .act svg{width:15px;height:15px}

.ph.sq{aspect-ratio:1/1;border-radius:16px;margin:0;
  border:1px solid var(--vien);background:var(--kem)}
.ph.round{aspect-ratio:1;border-radius:50%;margin:0;border:2px solid var(--vien-dam)}
/* Vòng vàng kép quanh ảnh: viền đặc, một chỉ trắng, rồi quầng vàng mỏng.
   Dùng box-shadow chứ không phải outline lồng nhau — box-shadow không
   chiếm chỗ nên không đẩy lệch lưới thẻ. */
.alert-card .ph.round{
  box-shadow:0 0 0 1.5px #fff,0 0 0 4.5px rgba(201,162,39,.34)}
.ph.sq figcaption,.ph.sq::after,.ph.round figcaption,.ph.round::after{display:none}
.ph.round.empty::before,.ph.sq.empty::before{width:46%;height:30%}

/* ── nhãn trạng thái: LUÔN icon + chữ ──────────────── */
.pill{display:inline-flex;align-items:center;justify-content:center;gap:7px;
  min-height:44px;padding:0 16px;border-radius:var(--pill);
  font-size:clamp(13px,3.8vw,15px);font-weight:600;white-space:nowrap;
  transition:transform .22s cubic-bezier(.22,.61,.36,1)}
.pill:active{transform:scale(.97)}
.pill svg{width:17px;height:17px;flex:0 0 auto}
.pill.ok{background:var(--then);color:#F6F2E6;width:100%}
.pill.ok svg{color:var(--dong)}
.pill.bad{background:#fff;color:var(--son-dam);border:1.5px solid rgba(176,32,26,.5);
  min-height:42px;padding:0 14px;font-size:clamp(12.5px,3.6vw,14px)}
.pill.unknown{background:var(--kem);color:var(--muc-nhat);min-height:42px}
.chip-scan{display:inline-block;font-size:clamp(11.5px,3.3vw,13px);font-weight:500;
  padding:5px 12px;border-radius:var(--pill);background:var(--kem);
  border:1px solid var(--vien-in);color:var(--muc-nhat);font-variant-numeric:tabular-nums}

.rail-dots{display:flex;justify-content:center;gap:7px;margin-top:6px}
.rail-dots i{width:7px;height:7px;border-radius:50%;background:var(--line);
  transition:background .22s cubic-bezier(.22,.61,.36,1)}
.rail-dots i.on{background:var(--dong)}

/* ── thẻ cảnh báo ──────────────────────────────────── */
/* Thẻ cảnh báo cũng nằm trong hệ viền vàng, nhưng chỉ lót giữ sắc son —
   đủ để thẻ này khác hẳn nhóm thẻ đạt chuẩn mà không rơi ra ngoài bộ. */
.alert-card{position:relative;overflow:hidden;display:grid;
  grid-template-columns:clamp(74px,25vw,96px) 1fr;gap:14px;align-items:start;
  background:var(--hong);border:1.5px solid var(--vien);
  border-radius:20px;padding:18px;margin-top:18px;text-align:left;width:100%;
  transition:transform .22s cubic-bezier(.22,.61,.36,1)}
.alert-card::before{content:"";position:absolute;inset:5px;border-radius:15px;
  border:1px solid rgba(176,32,26,.22);pointer-events:none;z-index:2}
.alert-card:active{transform:scale(.97)}
.alert-card>*{position:relative;z-index:1}
.alert-card .nm{display:block;font-family:var(--disp);font-size:clamp(19px,5.6vw,22px);
  font-weight:600;color:var(--son-dam);letter-spacing:-.01em;line-height:1.2}
.alert-card .meta{display:block;font-size:clamp(12.5px,3.6vw,14px);
  color:var(--muc-nhat);margin-top:3px}
/* Cột nội dung là block thường, không phải lưới flex: sau khi bỏ chip số lần
   quét thì mỗi phần tử chiếm trọn bề ngang, nên tên quán không còn bị nhãn
   bóp xuống ba dòng ở khổ 390px và không cần luật wrap riêng nữa. */
.alert-card .body{display:block;min-width:0}
.alert-card .pill{margin-top:10px}
/* Lời giải thích. Lớp KHÔNG được đặt tên "why": app.css còn một `.why` dùng
   chung cho thẻ <details> gấp mở, và nó áp nền giấy cùng bo góc 16px lên đây
   — dòng giải thích biến thành một cái hộp lơ lửng. Cùng tên, hai nghĩa. */
.alert-card .reason{display:block;margin-top:12px;padding-left:11px;
  border-left:2px solid rgba(176,32,26,.28);
  font-size:clamp(12.5px,3.6vw,14px);color:var(--son-dam);line-height:1.45}
.alert-card .known{display:block;font-size:clamp(12px,3.5vw,13.5px);
  color:var(--muc-nhat);margin-top:10px;line-height:1.5}
.alert-card .known b{display:block;font-weight:600;margin-bottom:2px}

/* ── danh sách đầy đủ, mở bằng See all ─────────────── */
.mini-grid{display:grid;grid-template-columns:1fr 1fr;gap:11px;margin-top:12px}
/* Thẻ nhỏ chỉ lấy khung ngoài, không có chỉ lót: ở khổ này hai đường
   cách nhau 5px sẽ dính vào nhau thành một vệt dày. */
.mini-card{position:relative;background:#fff;border:1.5px solid var(--vien);
  border-radius:18px;padding:12px;text-align:left;display:grid;gap:8px;align-content:start;
  transition:transform .22s cubic-bezier(.22,.61,.36,1)}
.mini-card:active{transform:scale(.97)}
.mini-card .row1{display:flex;gap:10px;align-items:flex-start}
.mini-card .row1>span:last-child{min-width:0;flex:1 1 auto}
.mini-card .avwrap{position:relative;width:54px;flex:0 0 auto}
.mini-card .nm{display:block;font-family:var(--disp);font-size:15px;font-weight:600;
  color:var(--then);letter-spacing:-.008em;line-height:1.25;padding-right:26px;
  overflow-wrap:anywhere}
.mini-card .meta{display:block;font-size:11px;color:var(--muc-nhat);margin-top:3px}
.mini-card .known{font-size:11px;color:var(--muc-nhat);line-height:1.45}
.mini-card .known b{display:block;font-weight:600;margin-bottom:2px}
.mini-card .flag{position:absolute;top:10px;right:10px;width:28px;height:28px;
  border-radius:50%;display:grid;place-items:center}
.mini-card .flag svg{width:16px;height:16px}
.mini-card .flag.ok{background:#0E4A3C;color:#fff}
.mini-card .flag.unknown{background:var(--kem);color:var(--muc-nhat)}

@media (prefers-reduced-motion:reduce){
  .trust-card,.alert-card,.mini-card,.pill,.rail-dots i{transition:none}
  .trust-card:active,.alert-card:active,.mini-card:active,.pill:active{transform:none}
}


/* ═══ TAB EAT ══════════════════════════════════════════
   Trên cùng là món được tiến cử của vùng, trình bày như một
   trang chi tiết: ảnh tròn, tên, nhãn Đúng Giá, ba ô dữ kiện,
   thanh so giá. Kéo xuống là danh sách các món khác, dùng LẠI
   đúng thẻ .dish-card của hàng "Signature dishes" phía trên —
   một hình thức, hai ngữ cảnh.
   ═════════════════════════════════════════════════════ */

/* ── thanh trên cùng ───────────────────────────────── */
.eat-top{display:flex;align-items:center;gap:10px;margin-bottom:6px}
.eat-top .kick{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:8px;
  font-size:clamp(11px,3vw,13px);font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muc)}
.eat-top .kick .pag{width:22px;height:22px;flex:0 0 auto;color:var(--then)}
.eat-top .kick span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.iconbtn{width:44px;height:44px;flex:0 0 auto;border-radius:50%;
  background:#fff;border:1px solid var(--line);display:grid;place-items:center;
  color:var(--then);box-shadow:0 2px 8px -4px rgba(14,43,36,.2);
  transition:transform .22s cubic-bezier(.22,.61,.36,1)}
.iconbtn:active{transform:scale(.94)}
.iconbtn svg{width:20px;height:20px}
.iconbtn:focus-visible{outline:2px solid var(--dong);outline-offset:2px}

/* ── khối tiến cử ──────────────────────────────────── */
.eat-hero{display:grid;grid-template-columns:minmax(0,42%) minmax(0,1fr);
  gap:clamp(12px,4vw,20px);align-items:start;margin-top:10px}
.eat-hero .avwrap{position:relative;padding-bottom:16px}
.eat-hero .ph{aspect-ratio:1;border-radius:50%;margin:0;
  border:2px solid rgba(217,162,39,.65);
  box-shadow:0 8px 22px -10px rgba(14,43,36,.45)}
.eat-hero .ph figcaption,.eat-hero .ph::after{display:none}
.eat-hero .ph.empty::before{width:44%;height:26%}
.eat-hero .seal{position:absolute;left:50%;bottom:0;transform:translateX(-50%);
  width:clamp(40px,12vw,52px);aspect-ratio:1;border-radius:50%;
  background:linear-gradient(160deg,#1B6B57,#0B2620);
  border:2.5px solid var(--dong);display:grid;place-items:center;color:var(--dong);
  box-shadow:0 4px 12px -4px rgba(0,0,0,.55)}
.eat-hero .seal svg{width:52%;height:52%}
.eat-hero .nm{font-family:var(--disp);font-weight:600;color:var(--then);
  font-size:clamp(22px,6.6vw,30px);line-height:1.12;letter-spacing:-.012em}
.eat-hero .meta{display:flex;align-items:center;gap:5px;margin-top:7px;
  font-size:clamp(12.5px,3.6vw,14px);color:var(--muc-nhat)}
.eat-hero .meta svg{width:15px;height:15px;flex:0 0 auto;color:var(--dong)}
.eat-hero .pill{margin-top:11px}
.eat-hero .blurb{margin-top:11px;font-size:clamp(13px,3.7vw,15px);
  line-height:1.5;color:var(--muc)}

/* ── ba ô dữ kiện ──────────────────────────────────── */
.fact-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:9px;
  margin-top:clamp(18px,5vw,26px)}
.fact{background:var(--giay);border:1px solid var(--line);border-radius:18px;
  padding:12px 9px;display:grid;gap:7px;align-content:start;text-align:center}
.fact .hd{display:grid;justify-items:center;gap:6px}
.fact .ico{width:clamp(32px,9vw,40px);aspect-ratio:1;border-radius:50%;
  display:grid;place-items:center;border:1.5px solid var(--dong);
  background:rgba(217,162,39,.1);color:var(--dong)}
.fact .ico svg{width:52%;height:52%}
.fact .ttl{font-family:var(--disp);font-size:clamp(13px,3.7vw,15px);
  font-weight:600;color:var(--then);line-height:1.2}
.fact .val{font-size:clamp(12px,3.4vw,13.5px);line-height:1.45;color:var(--muc);
  font-variant-numeric:tabular-nums}
.fact .val b{font-weight:600}
.fact .note{border-top:1px solid var(--line);padding-top:8px;
  font-size:clamp(10.5px,3vw,11.5px);line-height:1.4;color:var(--muc-nhat)}

/* ── thanh so giá ──────────────────────────────────── */
.pricecheck{background:var(--giay);border:1px solid var(--line);border-radius:20px;
  padding:15px;margin-top:14px}
.pricecheck .hd{display:flex;align-items:flex-start;gap:10px}
.pricecheck .hd .spark{width:18px;height:18px;color:var(--dong);flex:0 0 auto;margin-top:3px}
.pricecheck .hd h3{flex:1 1 auto;min-width:0;font-family:var(--disp);
  font-size:clamp(17px,5vw,20px);font-weight:600;color:var(--then);letter-spacing:-.01em}
.pricecheck .hd p{font-size:clamp(11.5px,3.3vw,13px);color:var(--muc-nhat);margin-top:2px}
.pricecheck .verdict{flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;
  min-height:34px;padding:0 12px;border-radius:var(--pill);
  font-size:clamp(11.5px,3.2vw,13px);font-weight:600}
.pricecheck .verdict svg{width:15px;height:15px}
.pricecheck .verdict.in{background:#E4F1E9;color:#16624C}
.pricecheck .verdict.out{background:var(--hong);color:var(--son-dam)}

.pcbar{margin-top:14px}
.pcbar .lead{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.pcbar .lead .who{font-size:clamp(12px,3.4vw,13.5px);color:var(--muc-nhat);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:60%}
.pcbar .lead .amt{font-size:clamp(20px,6vw,26px);font-weight:700;
  letter-spacing:-.02em;color:var(--then);font-variant-numeric:tabular-nums}
.pcbar .track{position:relative;height:12px;border-radius:999px;margin-top:12px;
  background:linear-gradient(90deg,#E7DFC9,#EFE7D3)}
.pcbar .fill{position:absolute;inset:0 auto 0 0;border-radius:999px;
  background:linear-gradient(90deg,#1B7C64,#0E4A3C)}
.pcbar .mark{position:absolute;top:50%;width:26px;height:26px;border-radius:50%;
  transform:translate(-50%,-50%);display:grid;place-items:center;
  background:#0E4A3C;color:#fff;border:2px solid var(--giay);
  box-shadow:0 3px 8px -2px rgba(0,0,0,.45)}
.pcbar .mark svg{width:14px;height:14px}
.pcbar .mark.out{background:var(--son)}
.pcbar .scale{display:flex;justify-content:space-between;gap:8px;margin-top:12px}
.pcbar .scale div{font-size:clamp(10.5px,3vw,11.5px);color:var(--muc-nhat);
  letter-spacing:.04em;text-transform:uppercase;font-weight:600}
.pcbar .scale div:nth-child(2){text-align:center}
.pcbar .scale div:last-child{text-align:right}
.pcbar .scale b{display:block;margin-top:3px;font-size:clamp(12.5px,3.6vw,14.5px);
  font-weight:700;letter-spacing:-.01em;text-transform:none;
  font-variant-numeric:tabular-nums;color:var(--muc)}
.pcbar .scale div:nth-child(2) b{color:var(--dong)}
.pcbar .scale div:last-child b{color:var(--son)}

/* ── thẻ món: dùng chung cho hàng ngang và danh sách dọc ── */
.dish-rail{display:grid;grid-auto-flow:column;grid-auto-columns:min(78%,268px);
  gap:11px;overflow-x:auto;overflow-y:hidden;scroll-snap-type:x mandatory;
  padding:3px var(--pad-x) 8px;margin:0 calc(-1 * var(--pad-x));
  scrollbar-width:none;overscroll-behavior-x:contain}
.dish-rail::-webkit-scrollbar{display:none}
.dish-list{display:grid;gap:10px;margin-top:2px}

.dish-card{scroll-snap-align:start;display:grid;
  grid-template-columns:clamp(64px,20vw,84px) minmax(0,1fr);gap:12px;
  align-items:start;text-align:left;width:100%;
  background:var(--giay);border:1px solid var(--line);border-radius:18px;padding:11px;
  box-shadow:0 3px 12px -8px rgba(14,43,36,.28);
  transition:transform .22s cubic-bezier(.22,.61,.36,1)}
.dish-card:active{transform:scale(.97)}
.dish-card .ph{aspect-ratio:1;border-radius:14px;margin:0;
  border:1px solid rgba(217,162,39,.45);background:var(--kem)}
.dish-card .ph figcaption,.dish-card .ph::after{display:none}
.dish-card .ph.empty::before{width:52%;height:32%}
.dish-card .nm{display:block;font-family:var(--disp);
  font-size:clamp(16px,4.6vw,19px);font-weight:600;color:var(--then);
  letter-spacing:-.008em;line-height:1.2}
.dish-card .amt{display:block;margin-top:4px;font-size:clamp(13px,3.7vw,15px);
  font-weight:700;color:#16624C;letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.dish-card .amt small{font-weight:500;color:var(--muc-nhat);font-size:.82em;margin-left:3px}
.dish-card .desc{display:block;margin-top:5px;font-size:clamp(11.5px,3.3vw,12.5px);
  line-height:1.45;color:var(--muc-nhat)}
.dish-card .tagrow{margin-top:6px;gap:5px}
.dish-card .tg{font-size:10.5px;padding:3px 8px}

/* ── nút lưu ───────────────────────────────────────── */
.btn.save{display:flex;align-items:center;justify-content:center;gap:9px;
  min-height:52px;border-radius:var(--pill);background:var(--then);color:#F6F2E6;
  font-size:clamp(14px,4vw,16px);font-weight:600;margin-top:18px;
  border:1px solid rgba(217,162,39,.45);
  box-shadow:0 8px 20px -10px rgba(14,43,36,.7);
  transition:transform .22s cubic-bezier(.22,.61,.36,1)}
.btn.save:active{transform:scale(.97)}
.btn.save svg{width:19px;height:19px;color:var(--dong)}
.savenote{text-align:center;font-size:clamp(11.5px,3.3vw,13px);
  color:var(--muc-nhat);margin-top:9px}

@media (prefers-reduced-motion:reduce){
  .iconbtn,.dish-card,.btn.save{transition:none}
  .iconbtn:active,.dish-card:active,.btn.save:active{transform:none}
}


/* ═══ MÀN HÌNH BẢN ĐỒ CHI TIẾT ═════════════════════════
   Vector tự vẽ, không tile. Ghim là phần tử DOM thật để đạt
   vùng chạm 44px — vẽ trong SVG thì bắt chạm rất khó chính xác.
   ═════════════════════════════════════════════════════ */
#v-bigmap{position:absolute;inset:0;z-index:70;background:#F4EBD3;
  overflow:hidden;display:block}
#v-bigmap[hidden]{display:none}

.bm-canvas{position:absolute;inset:0;touch-action:none;cursor:grab;
  overscroll-behavior:contain}
.bm-canvas:active{cursor:grabbing}
.bm-canvas>svg{position:absolute;inset:0;width:100%;height:100%;display:block}

.bm-pins{position:absolute;inset:0;pointer-events:none}
.bm-pin{position:absolute;top:0;left:0;pointer-events:auto;
  display:grid;justify-items:center;gap:2px;
  min-width:44px;min-height:44px;padding:0 4px;
  margin-left:-22px;margin-top:-46px;
  transition:filter .2s cubic-bezier(.22,.61,.36,1)}
.bm-pin[hidden]{display:none}
.bm-pin .glyph{width:30px;display:block;filter:drop-shadow(0 3px 5px rgba(14,43,36,.45))}
.bm-pin .glyph svg{width:100%;height:auto;display:block}
/* Nhãn TÊN nằm ngoài luồng và không nhận cú chạm.
   Để nhãn trong luồng thì nút rộng bằng cả cái tên — 118px với "Cô Thảo ·
   Cơm gà" — và vùng chạm đó phủ lên mọi thứ nằm dưới. Ở Hội An nó nuốt trọn
   ba mốc Chùa Cầu, Nhà cổ Tấn Ký và Hội quán Phúc Kiến, tức cả lộ trình đèn
   lồng, chỉ vì tên quán dài. Ghim vẫn nằm trên và vẫn thắng khi chồng ĐÚNG
   chỗ — nhưng chỉ ở phần ký hiệu 44px, không phải cả dải chữ. */
.bm-pin{width:44px;min-width:0;padding:0}
.bm-pin .lbl{position:absolute;top:100%;left:50%;transform:translateX(-50%);
  pointer-events:none;margin-top:2px;
  max-width:118px;font-size:11px;font-weight:600;line-height:1.25;
  text-align:center;color:var(--muc);background:rgba(251,247,236,.94);
  border:1px solid var(--line);border-radius:9px;padding:3px 7px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.bm-pin .lbl i{display:block;font-style:normal;font-weight:500;font-size:10px;
  color:var(--muc-nhat);font-variant-numeric:tabular-nums}
.bm-pin.sel .glyph{filter:drop-shadow(0 0 0 3px var(--dong)) drop-shadow(0 4px 8px rgba(0,0,0,.4))}
.bm-pin.sel .lbl{border-color:var(--dong);background:#fff}
/* placePins() gắn .nolbl cho ghim có nhãn chồng lên một nhãn đã đặt. Ghim
   vẫn hiện và vẫn bấm được; chỉ viên chữ bị giấu. Ghim đang chọn không bao
   giờ bị giấu nhãn. */
.bm-pin.nolbl:not(.sel) .lbl{display:none}
/* Quán thật chưa có lượt quét: chấm nhỏ neo ĐÚNG toạ độ (tâm chấm, không
   phải mũi ghim), vùng chạm vẫn 44px, không nhãn — tên hiện khi chọn. */
.bm-pin.dot{margin-top:-22px;align-content:center}
.bm-pin.dot .glyph{display:none}
.bm-pin.dot::before{content:"";width:12px;height:12px;border-radius:50%;
  background:#8A7A66;border:2px solid #FBF7EC;box-shadow:0 1px 3px rgba(14,43,36,.45)}
.bm-pin.dot .lbl{display:none}
/* Trên ẢNH VỆ TINH thì chấm nâu viền kem biến thành đốm trắng lẫn vào mái
   nhà: đảo lại — lõi sáng, viền sẫm — để chấm còn đọc được trên nền nhiều
   chi tiết. bigmap.js gắn .anh-ve-tinh khi nền là ảnh vệ tinh. */
.anh-ve-tinh .bm-pin.dot::before{background:#F6F2E6;border-color:rgba(16,28,24,.78);
  box-shadow:0 1px 4px rgba(0,0,0,.55)}
.bm-pin:focus-visible{outline:2px solid var(--dong);outline-offset:2px;border-radius:12px}

/* ── ghim điểm tham quan ────────────────────────────────
   Cố tình KHÁC hình với ghim giá: chấm tròn viền vàng, không phải giọt
   nước. Ghim giá là phán quyết, landmark là mốc định hướng — nhìn một
   cái phải phân biệt được ngay, không cần đọc nhãn.
   Nằm dưới ghim giá trong thứ tự xếp lớp: khi hai thứ chồng nhau thì
   thông tin giá là thứ phải thắng.                                    */
.bm-marks{position:absolute;inset:0;pointer-events:none;z-index:1}
.bm-pins{z-index:2}
.bm-mark{position:absolute;top:0;left:0;pointer-events:auto;
  display:grid;justify-items:center;gap:2px;
  min-width:44px;min-height:44px;padding:0 4px;
  margin-left:-22px;margin-top:-22px;align-content:center;
  transition:filter .2s cubic-bezier(.22,.61,.36,1)}
.bm-mark .dot{position:relative;display:block}

/* ── mốc must-see: ghim giọt nước vàng đồng có ngôi sao ──
   Neo ở MŨI ghim chứ không phải tâm, nên margin-top phải bằng cả chiều cao
   hình. Để nguyên -22px như chấm tròn thì ghim cắm lệch xuống dưới địa điểm
   nó đang chỉ đúng nửa thân. */
.bm-mark.must{margin-top:-46px;align-content:start}
.bm-mark.must .dot{width:30px;height:40px}
.bm-mark.must .dot svg{width:100%;height:100%;display:block;
  filter:drop-shadow(0 3px 5px rgba(14,43,36,.45))}

/* ── điểm phụ: chấm tròn vàng nhỏ có sao ── */
.bm-mark.minor .dot{width:18px;height:18px;border-radius:50%;
  background:#FBF3DE;border:2px solid var(--vien-dam);
  box-shadow:0 2px 5px rgba(14,43,36,.3);display:grid;place-items:center}
.bm-mark.minor .dot svg{width:10px;height:10px;color:#C9922B;display:block}
/* Chỉ hiện khi phóng đủ gần — placeMarks() gắn .far theo mức thu phóng. */
.bm-mark.minor.far{display:none}

/* Icon dán phủ lên hình vẽ bên dưới. Khi ảnh thiếu, JS gỡ thẻ <img> đi và
   hình vẽ lộ lại — một lối lui, không phải hai đường vẽ song song phải giữ
   cho khớp nhau. */
.bm-mark .dot img{position:absolute;left:50%;bottom:100%;
  width:38px;height:38px;margin-left:-19px;margin-bottom:-6px;
  object-fit:contain;filter:drop-shadow(0 2px 3px rgba(14,43,36,.45))}
.bm-mark.minor .dot img{width:30px;height:30px;margin-left:-15px;margin-bottom:-4px}
/* Cùng lý do như nhãn ghim giá: chữ để đọc, không phải để bấm. */
.bm-mark{width:44px;min-width:0;padding:0}
.bm-mark .lbl{position:absolute;top:100%;left:50%;transform:translateX(-50%);
  pointer-events:none;margin-top:2px;
  max-width:110px;font-size:10.5px;font-weight:600;line-height:1.2;
  text-align:center;color:var(--muc);background:rgba(244,235,211,.94);
  border:1px solid var(--vien-in);border-radius:8px;padding:2px 6px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  display:none}
/* Nhãn chỉ bật khi đủ gần — placeMarks() gắn .named theo mức thu phóng. */
.bm-mark.named .lbl{display:block}

/* ── lớp quán ăn (OpenStreetMap) ────────────────────────
   Ký hiệu phải TRUNG TÍNH tuyệt đối: chấm tròn rỗng, không giọt nước,
   không màu phán quyết. Quán ở lớp này chưa được quét lần nào — mượn
   sắc xanh Đúng Giá hay sắc son Trên khoảng là app nói dối bằng màu.
   Nằm dưới cả mốc tham quan lẫn ghim giá: đây là lớp đông nhất và ít
   thẩm quyền nhất, chồng lên thì nó nuốt mất hai lớp kia.       */
.bm-eat{position:absolute;inset:0;pointer-events:none;z-index:0}
.bm-eat[hidden]{display:none}
.bm-eat .bm-eat{display:none}
.bm-eat>button{position:absolute;top:0;left:0;pointer-events:auto;
  width:44px;height:44px;margin:-22px 0 0 -22px;
  display:grid;place-items:center;padding:0}
.bm-eat>button .dot{width:11px;height:11px;border-radius:50%;
  background:#FBF7EC;border:2px solid #8A7E63;
  box-shadow:0 1px 3px rgba(14,43,36,.3)}
.bm-eat>button[data-kind="cafe"] .dot{border-color:#7A6A4E;border-style:double;border-width:3px}
.bm-eat>button[data-kind="street"] .dot{border-radius:2px}
/* Có icon sinh theo loại thì nó đè lên chấm — chấm trở thành nền đỡ.
   Ảnh tự gỡ khi hỏng (onerror), lúc đó chấm lộ lại nguyên vẹn. */
.bm-eat>button .dot:has(img){width:24px;height:24px;background:none;border:none;box-shadow:none}
.bm-eat>button .dot img{width:24px;height:24px;object-fit:contain;display:block;
  filter:drop-shadow(0 1px 2px rgba(14,43,36,.4))}
.bm-eat>button .lbl{position:absolute;top:100%;left:50%;transform:translateX(-50%);
  pointer-events:none;margin-top:-8px;max-width:96px;
  font-size:9.5px;font-weight:600;line-height:1.15;text-align:center;color:#4A4436;
  background:rgba(251,247,236,.92);border:1px solid var(--vien-in);border-radius:6px;
  padding:1px 5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:none}
.bm-eat>button.named .lbl{display:block}
.bm-eat>button.sel .dot{background:var(--dong);border-color:var(--then);transform:scale(1.3)}
.bm-eat>button:focus-visible{outline:2px solid var(--dong);outline-offset:-6px;border-radius:12px}
.bm-chip.eat[aria-pressed="true"]{background:#6B5E42;border-color:#6B5E42;color:#F6F2E6}

/* Nút đổi phẳng ↔ 3D. Dùng CHỮ chứ không icon: "3D" và "Flat" đọc ra ngay,
   còn một hình khối lập phương thì người dùng phải đoán. */
.bm-zoom .iconbtn.viewmode{font-size:12px;font-weight:700;letter-spacing:.04em}
.bm-zoom .iconbtn.viewmode[aria-pressed="true"]{background:var(--then);color:#F6F2E6;
  border-color:var(--vien-dam)}
/* Ở 3D nhãn phố nằm nghiêng theo mặt đất nên khó đọc hơn — hạ bớt độ nổi
   của nhãn ghim để chúng không cạnh tranh với chính hình khối thành phố. */
#v-bigmap.is3d .bm-eat>button .lbl{opacity:.9}
.bm-mark .lbl i{display:block;font-style:normal;font-weight:500;font-size:9.5px;
  color:var(--muc-nhat);font-variant-numeric:tabular-nums}
.bm-mark.sel .dot{border-color:var(--son);transform:scale(1.25)}
.bm-mark.sel .lbl{border-color:var(--vien-dam);background:#fff}
.bm-mark:focus-visible{outline:2px solid var(--dong);outline-offset:2px;border-radius:12px}

.bm-me{position:absolute;top:0;left:0;width:20px;height:20px;margin:-10px 0 0 -10px;
  pointer-events:none;display:grid;place-items:center}
.bm-me i{width:14px;height:14px;border-radius:50%;background:#2C6BE0;
  border:2.5px solid #fff;box-shadow:0 0 0 6px rgba(44,107,224,.22),0 2px 6px rgba(0,0,0,.35)}

.bm-top{position:absolute;top:calc(12px + env(safe-area-inset-top,0px));
  left:12px;right:12px;z-index:5;display:flex;align-items:center;gap:10px}
.bm-title{flex:1 1 auto;min-width:0;display:grid;justify-items:center;gap:1px;
  background:rgba(251,247,236,.95);border:1px solid var(--line);border-radius:var(--pill);
  padding:7px 14px;box-shadow:0 3px 10px -5px rgba(14,43,36,.3)}
.bm-title b{font-family:var(--disp);font-size:15px;font-weight:600;color:var(--then);
  max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bm-title small{font-size:11px;color:var(--muc-nhat);font-variant-numeric:tabular-nums}

.bm-filters{position:absolute;left:0;right:0;z-index:5;
  top:calc(66px + env(safe-area-inset-top,0px));
  display:flex;gap:7px;overflow-x:auto;padding:0 12px 4px;
  scrollbar-width:none;overscroll-behavior-x:contain}
.bm-filters::-webkit-scrollbar{display:none}
.bm-chip{flex:0 0 auto;min-height:38px;padding:0 14px;border-radius:var(--pill);
  background:rgba(251,247,236,.95);border:1px solid var(--line);
  font-size:12.5px;font-weight:600;color:var(--muc-nhat);
  box-shadow:0 2px 8px -5px rgba(14,43,36,.3);
  transition:background .2s cubic-bezier(.22,.61,.36,1),color .2s}
.bm-chip[aria-pressed="true"]{background:var(--then);color:#F6F2E6;border-color:var(--then)}
.bm-chip[data-lvl="ok"][aria-pressed="true"]{background:#0E4A3C;border-color:#0E4A3C}
.bm-chip[data-lvl="bad"][aria-pressed="true"]{background:var(--son);border-color:var(--son)}
.bm-chip[data-lvl="unknown"][aria-pressed="true"]{background:#6E6A62;border-color:#6E6A62}
.bm-chip:focus-visible{outline:2px solid var(--dong);outline-offset:2px}

.bm-zoom{position:absolute;right:12px;z-index:5;display:grid;gap:8px;
  top:50%;transform:translateY(-50%)}

.bm-foot{position:absolute;left:12px;right:12px;z-index:5;
  bottom:calc(14px + var(--safe));display:grid;gap:8px;justify-items:start}
.bm-scale{background:rgba(251,247,236,.95);border:1px solid var(--line);
  border-radius:8px;padding:5px 8px}
.bm-scale>span{display:block;border-bottom:2px solid var(--muc-nhat);
  border-left:2px solid var(--muc-nhat);border-right:2px solid var(--muc-nhat);
  height:12px;position:relative}
.bm-scale i{position:absolute;left:0;right:0;top:-3px;text-align:center;
  font-style:normal;font-size:10px;font-weight:600;color:var(--muc-nhat);
  font-variant-numeric:tabular-nums}
.bm-attr{background:rgba(251,247,236,.92);border:1px solid var(--line);
  border-radius:12px;padding:8px 11px;font-size:11px;line-height:1.45;
  color:var(--muc-nhat);max-width:100%}
.bm-attr b{color:var(--then);font-weight:600}

/* nút mở sang ứng dụng bản đồ trong thẻ chi tiết cơ sở */
.btn.maps{display:flex;align-items:center;justify-content:center;gap:9px;
  min-height:48px;border-radius:14px;border:1px solid var(--line);
  background:var(--giay);color:var(--then);font-size:14px;font-weight:600;margin-top:10px}
.btn.maps svg{width:18px;height:18px;color:var(--dong)}

@media (prefers-reduced-motion:reduce){
  .bm-pin,.bm-mark,.bm-chip{transition:none}
}

/* ── danh sách địa điểm ────────────────────────────────── */
.place{display:block;width:100%;text-align:left;background:var(--giay);border:1px solid var(--line);
  border-radius:var(--r);padding:14px;margin-top:10px}
.place .top{display:flex;align-items:center;gap:9px;justify-content:space-between}
.place .nm{display:block;font-family:var(--disp);font-size:18px;font-weight:600;letter-spacing:-.008em}
.place .st{display:block;font-size:11.5px;color:var(--muc-nhat);font-weight:300;margin-top:2px}

/* ── nhật ký ───────────────────────────────────────────── */
.view.lacquer{background:
  radial-gradient(circle at 22% 14%,rgba(201,162,39,.1),transparent 44%),
  radial-gradient(circle at 80% 76%,rgba(192,57,43,.08),transparent 42%),
  var(--then);color:#EDE4D2}
.view.lacquer .muted{color:#A99B80}
.view.lacquer .kicker{color:var(--vang-la)}
.view.lacquer h1.title,.view.lacquer h2.sect{color:#F2E7CF}
.jrow{display:grid;grid-template-columns:auto 1fr auto;gap:11px;align-items:center;
  padding:13px 0;border-bottom:1px solid rgba(201,162,39,.2)}
.jrow .jd{width:9px;height:9px;border-radius:50%}
.jrow .jn{display:block;font-size:13.5px;font-weight:500;color:#EDE4D2}
.jrow .js{display:block;font-size:10.5px;color:#A99B80;font-weight:300;margin-top:2px}
.jrow .ja{font-family:var(--mono);font-size:12.5px;color:var(--vang-la)}
.jstat{display:flex;gap:22px;margin-top:16px;padding-top:14px;border-top:1px solid rgba(201,162,39,.26)}
.jstat div small{font-family:var(--mono);font-size:8.5px;color:#9A8E74;display:block;letter-spacing:.1em}
.jstat div b{font-family:var(--body);font-size:24px;color:var(--vang-la);font-weight:700;letter-spacing:-.02em}

/* ── thông báo ─────────────────────────────────────────── */
#toast{position:absolute;left:50%;transform:translate(-50%,20px);bottom:calc(88px + var(--safe));
  z-index:86;background:var(--muc);color:#F2F0E8;padding:11px 17px;border-radius:var(--pill);
  font-size:12.5px;opacity:0;pointer-events:none;transition:.25s;max-width:88%;text-align:center}
#toast.on{opacity:1;transform:translate(-50%,0)}

.warnbox{display:flex;gap:9px;background:#FCEEEB;border-radius:13px;padding:11px 13px;
  margin-top:11px;font-size:12.5px;color:var(--son);font-weight:500;line-height:1.45}
/* Các icon trong I không mang width/height, nên làm con trực tiếp của một
   flex container chúng nở ra bằng cả hộp — 292px trên khung 360px. Phải
   ghim cỡ ở đây, không ở từng chỗ gọi: có 10 chỗ dựng .warnbox. */
.warnbox>svg{width:17px;height:17px;flex:0 0 auto;margin-top:1px}
.okbox{background:#E7F3EC;color:#166B52}
.infobox{background:#EEF1F7;color:var(--cham)}

.seedwarn{font-size:10.5px;color:var(--muc-nhat);font-weight:300;line-height:1.5;
  border-left:2px solid var(--ho-phach);padding-left:9px;margin-top:11px}

@media (prefers-reduced-motion:reduce){
  .ring-slow,.ring-rev,.lantern{animation:none}
  .sheet{transition:none}
}

/* ── xưởng icon (tab You) ────────────────────────────────
   Lưới icon có nút vẽ lại từng cái. Ô rỗng hiện cây bút chứ không hiện
   khung ảnh vỡ: chưa vẽ là một trạng thái bình thường của màn hình này,
   không phải lỗi. */
.ic-actions{display:flex;gap:9px;margin:10px 0 8px;flex-wrap:wrap}
.ic-actions .btn{flex:1 1 auto;min-width:140px;margin:0}
.ic-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(76px,1fr));
  gap:9px;margin-top:10px}
.ic-cell{position:relative;display:grid;justify-items:center;gap:4px;
  padding:7px 4px 6px;border-radius:14px;background:var(--giay);
  border:1px solid var(--vien-in)}
.ic-art{width:48px;height:48px;border-radius:12px;display:grid;place-items:center;
  background:var(--kem);border:1px solid var(--line);overflow:hidden}
.ic-art img{width:100%;height:100%;object-fit:contain;display:block}
.ic-art i{display:grid;place-items:center;width:20px;height:20px;color:var(--muc-nhat)}
.ic-art i svg{width:100%;height:100%;display:block}
.ic-art.run{animation:icPulse 1.1s ease-in-out infinite}
.ic-art.fail{border-color:rgba(176,32,26,.45);background:var(--hong)}

/* ── nhóm trong xưởng ảnh ───────────────────────────────
   Danh mục đầy đủ hơn 70 tấm. Đổ hết vào một lưới thì người dùng cuộn
   mãi không thấy đầu cuối, và không cách nào sinh riêng một nhóm. */
.ic-sect{margin-top:6px}
.ic-sect .sect-row{margin:18px 0 10px}
.ic-sect .sect-row h2{font-size:clamp(15px,4.4vw,18px)}
.ic-sect .sect-row .act{min-height:40px;font-size:13px}
/* Ảnh cơ sở là ảnh cảnh 16/10, không phải icon vuông — ép chúng vào ô
   48px thì chỉ còn thấy một vệt màu, không kiểm được ảnh có đạt không. */
.ic-grid.photos{grid-template-columns:repeat(auto-fill,minmax(132px,1fr))}
.ic-cell.wide .ic-art{width:100%;height:auto;aspect-ratio:16/10;border-radius:14px}
.ic-cell.wide .ic-art img{object-fit:cover}
.ic-cell.wide .ic-name{font-size:11px;text-align:center;line-height:1.25}
@keyframes icPulse{0%,100%{opacity:1}50%{opacity:.45}}
.ic-name{font-size:10.5px;line-height:1.2;text-align:center;color:var(--muc-nhat);
  max-width:72px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ic-redo{position:absolute;top:2px;right:2px;width:44px;height:44px;
  display:grid;place-items:center;color:var(--dong-chu);border-radius:12px}
.ic-redo svg{width:15px;height:15px}
.ic-redo[disabled]{opacity:.35}
.ic-err{grid-column:1/-1;font-size:9.5px;line-height:1.25;color:var(--son-dam);
  text-align:center;max-width:74px;overflow:hidden}
@media (prefers-reduced-motion:reduce){ .ic-art.run{animation:none;opacity:.6} }

/* ── thẻ mời đi tuyến (tab Nearby) ───────────────────────── */
.walk-teaser{display:grid;grid-template-columns:46px 1fr 20px;gap:12px;align-items:center;
  width:100%;text-align:left;margin-top:12px;padding:13px 14px;border-radius:20px;
  background:linear-gradient(168deg,#fff 58%,#FDFAF1);
  border:1.5px solid var(--vien);box-shadow:0 4px 16px rgba(14,43,36,.07);
  transition:transform .22s cubic-bezier(.22,.61,.36,1)}
.walk-teaser:active{transform:scale(.98)}
.wt-ico{width:46px;height:46px;border-radius:50%;display:grid;place-items:center;
  background:var(--then);color:var(--dong);border:1.5px solid var(--vien-dam)}
.wt-ico svg{width:20px;height:20px}
.wt-name{display:block;font-family:var(--disp);font-size:clamp(16px,4.6vw,19px);
  font-weight:600;color:var(--then)}
.wt-meta{display:block;font-size:12.5px;color:var(--muc-nhat);margin-top:2px;
  font-variant-numeric:tabular-nums}
.wt-go{color:var(--dong-chu)}
.wt-go svg{width:16px;height:16px}

/* ── màn hình tuyến đi bộ ────────────────────────────────── */
.rt-actions{position:absolute;left:10px;right:10px;top:74px;z-index:12;
  display:flex;gap:7px;overflow-x:auto;padding:2px;scrollbar-width:none}
.rt-actions::-webkit-scrollbar{display:none}
.rt-btn{display:inline-flex;align-items:center;gap:6px;flex:0 0 auto;
  min-height:44px;padding:0 14px;border-radius:var(--pill);white-space:nowrap;
  background:rgba(251,247,236,.96);border:1px solid var(--line);
  font-size:13px;font-weight:600;color:var(--muc);
  box-shadow:0 3px 10px -4px rgba(14,43,36,.35)}
.rt-btn svg{width:16px;height:16px;color:var(--then)}
.rt-btn.primary{background:var(--then);color:#F6F2E6;border-color:var(--vien-dam)}
.rt-btn.primary svg{color:var(--dong)}
.rt-btn .ico{display:grid;place-items:center;width:16px;height:16px}

/* Thẻ tiến trình nổi trên bản đồ, giống bản mockup: nó phải đọc được mà
   không che mất tuyến, nên bám mép trái và chỉ rộng 62%. */
/* Thẻ nằm ở GÓC DƯỚI TRÁI, ngay trên danh sách chặng — không phải góc trên.
   Đặt trên cùng thì nó che mất chặng đầu tiên, đúng cái chặng người dùng
   đang đứng và cần nhìn thấy nhất. */
/* Dải NGANG sát trên danh sách chặng, không phải thẻ nổi bên trái. Thẻ nổi
   chiếm 62% bề ngang đúng chỗ tuyến bắt đầu, nên hai chặng đầu — chặng người
   dùng đang đứng và chặng kế tiếp — nằm khuất sau chính cái thẻ đang nói về
   chúng. Dải ngang thấp trả lại toàn bộ bề ngang cho bản đồ. */
/* Dải NGANG DẸP sát trên danh sách chặng. Thẻ nổi bên trái chiếm 62% bề
   ngang đúng chỗ tuyến bắt đầu, nên hai chặng đầu nằm khuất sau chính cái
   thẻ đang nói về chúng. Dải thấp trả lại bản đồ cho người dùng. */
.rt-card{position:absolute;left:10px;right:10px;top:auto;bottom:calc(31% + 10px);z-index:11;
  display:grid;grid-template-columns:1fr auto;gap:3px 10px;align-items:baseline;
  padding:9px 13px 10px;border-radius:18px;background:rgba(255,253,247,.97);
  border:1px solid var(--vien);box-shadow:0 8px 22px -8px rgba(14,43,36,.45)}
.rt-card .now{grid-column:1;display:flex;align-items:center;gap:7px;
  font-family:var(--disp);font-size:16px;font-weight:600;color:var(--then);line-height:1.15}
.rt-card .count{grid-column:2;justify-self:end;font-size:11.5px;font-weight:600;
  color:var(--muc-nhat);font-variant-numeric:tabular-nums;white-space:nowrap}
.rt-card .nxt{grid-column:1/-1;display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  font-size:13px;font-weight:600;color:var(--muc);line-height:1.2}
.rt-card .nxt .arrow{color:var(--dong-chu);font-weight:700}
.rt-card .nxt.done{color:var(--ngoc-sau)}
.rt-card .num{flex:0 0 auto;width:19px;height:19px;border-radius:50%;
  background:var(--then);color:var(--dong);display:grid;place-items:center;
  font-family:var(--body);font-size:11px;font-weight:700}
.rt-card .nxt .num{background:var(--dong);color:var(--then-sau)}
.rt-card .walk{font-size:11.5px;font-weight:500;color:var(--muc-nhat);
  font-variant-numeric:tabular-nums}
.rt-bar{grid-column:1/-1;height:6px;border-radius:3px;background:var(--line);
  margin-top:4px;overflow:hidden}
.rt-bar i{display:block;height:100%;border-radius:3px;background:var(--dong);
  transition:width .35s cubic-bezier(.22,.61,.36,1)}
/* Mẹo kẹp ở 2 dòng: mẹo dài làm dải cao lên và lại nuốt mất bản đồ. */
.rt-card .tip{grid-column:1/-1;margin-top:6px;padding-top:6px;
  border-top:1px dashed var(--line);font-size:11.5px;line-height:1.4;color:var(--muc-nhat);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.rt-card .tip b{color:var(--son-dam);font-size:10px;letter-spacing:.12em;
  text-transform:uppercase;margin-right:6px}

/* Trong chế độ tuyến, mốc phụ ẩn hẳn: màn hình này nói về BỐN chặng, thêm
   tám nhãn mốc nữa thì số thứ tự chìm nghỉm giữa một đám chữ. */
#v-bigmap.rt .bm-mark.minor{display:none}

/* ── ghim chặng: vòng tròn đánh số ─────────────────────────
   Cố tình KHÁC hình với ghim giá và ghim tham quan: đây là thứ tự đi, không
   phải một phán quyết hay một mốc. Số nằm trong vòng tròn là ký hiệu duy
   nhất đọc được ngay mà không cần chú giải. */
.bm-stops{position:absolute;inset:0;pointer-events:none;z-index:3}
.bm-stop{position:absolute;top:0;left:0;pointer-events:auto;
  width:44px;height:44px;margin:-22px 0 0 -22px;display:grid;place-items:center}
.bm-stop .num{width:28px;height:28px;border-radius:50%;display:grid;place-items:center;
  font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;
  background:var(--then);color:#F6F2E6;border:2px solid #FBF3DE;
  box-shadow:0 3px 8px -2px rgba(14,43,36,.6);
  transition:transform .22s cubic-bezier(.22,.61,.36,1)}
.bm-stop.done .num{background:var(--ngoc-sau);color:#CFE3DA}
.bm-stop.now .num{background:var(--dong);color:var(--then-sau);
  transform:scale(1.22);box-shadow:0 0 0 5px rgba(201,146,43,.28),0 4px 10px -2px rgba(0,0,0,.5)}
.bm-stop:focus-visible{outline:2px solid var(--dong);outline-offset:2px;border-radius:50%}

/* ── danh sách chặng ở đáy ─────────────────────────────────── */
.rt-sheet{position:absolute;left:0;right:0;bottom:0;z-index:12;
  max-height:31%;overflow-y:auto;padding:10px 12px calc(14px + var(--safe));
  background:var(--diep);border-radius:26px 26px 0 0;
  border-top:1.5px solid var(--vien);box-shadow:0 -8px 26px rgba(14,43,36,.18)}
.rt-list{display:grid;gap:7px}
.rt-stop{display:grid;grid-template-columns:30px 1fr;gap:11px;align-items:center;
  width:100%;text-align:left;min-height:52px;padding:8px 10px;border-radius:16px;
  background:var(--card,#FDFAF3);border:1px solid var(--vien-in)}
.rt-stop.on{border-color:var(--vien-dam);background:#fff}
.rt-stop .n{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;
  font-size:13px;font-weight:700;background:var(--kem);color:var(--muc-nhat);
  border:1px solid var(--vien-in);font-variant-numeric:tabular-nums}
.rt-stop.on .n{background:var(--dong);color:var(--then-sau);border-color:var(--vien-dam)}
.rt-stop .nm{display:block;font-family:var(--disp);font-size:15px;font-weight:600;
  color:var(--then);line-height:1.2}
.rt-stop .mt{display:block;font-size:11.5px;color:var(--muc-nhat);margin-top:2px;
  font-variant-numeric:tabular-nums}
@media (prefers-reduced-motion:reduce){
  .rt-bar i,.bm-stop .num,.walk-teaser{transition:none}
}

/* ── quy đổi ngoại tệ ────────────────────────────────────
   Tiền đồng là con số chính; ngoại tệ nhỏ hơn, nhạt hơn, luôn có dấu ≈.
   Kích cỡ và độ đậm phải nói rõ cái nào là giá thật — đảo lại là app tự
   nhận mình biết tỉ giá quầy đổi tiền. */
.fx{display:block;font-size:.72em;font-weight:500;color:var(--muc-nhat);
  letter-spacing:0;margin-top:1px;font-variant-numeric:tabular-nums}
.amt .fx{color:var(--dong-chu)}
.amt[data-l] .fx{color:inherit;opacity:.72}

/* ── bảng so giá từng món ────────────────────────────────
   Ba cột cố định: món / khoảng giá vùng / giá quán. Không dùng <table>
   vì trên màn hẹp bảng thật sẽ tràn ngang và người dùng phải cuộn hai
   chiều để đọc một dòng. */
.pcmp{border:1.5px solid var(--vien);border-radius:18px;overflow:hidden;
  background:#fff;margin-top:4px}
.pcmp-h,.pcmp-r{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr) minmax(0,1fr);
  gap:8px;padding:10px 12px;align-items:start}
.pcmp-h{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muc-nhat);background:var(--kem);border-bottom:1px solid var(--vien-in)}
.pcmp-r{border-top:1px solid var(--line);font-size:12.5px}
.pcmp-r:first-of-type{border-top:0}
.pcmp-r .nm{display:block;font-weight:600;color:var(--then);line-height:1.25}
.pcmp-r .un{display:block;font-size:11px;color:var(--muc-nhat)}
.pcmp-r .rg,.pcmp-r .pd{font-variant-numeric:tabular-nums;color:var(--muc)}
.pcmp-r .pd{font-weight:700}
.pcmp-r .tag{display:block;font-size:10px;font-weight:600;margin-top:3px;
  padding:2px 7px;border-radius:var(--pill);width:fit-content}
/* Trạng thái LUÔN có chữ, không chỉ dựa vào màu — nền hồng nhạt với chữ
   son đậm đạt 4.5:1, nhưng người mù màu vẫn phải đọc được kết luận. */
.pcmp-r[data-s="bad"] .pd{color:var(--son-dam)}
.pcmp-r[data-s="bad"] .tag{background:var(--hong);color:var(--son-dam)}
.pcmp-r[data-s="ok"] .tag{background:#E6EFE7;color:#14503F}
.pcmp-r[data-s="low"] .tag{background:var(--kem);color:var(--muc-nhat)}
.pcmp-r[data-s="none"] .tag{background:var(--kem);color:var(--muc-nhat)}

/* ── ba việc nên làm ── */
.todo{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:9px;margin-top:4px}
.todo>div{background:#fff;border:1.5px solid var(--vien);border-radius:18px;padding:12px;
  display:grid;gap:4px;align-content:start}
.todo .ic{width:34px;height:34px;border-radius:50%;display:grid;place-items:center;
  background:var(--then);color:var(--dong);margin-bottom:2px}
.todo .ic svg{width:17px;height:17px}
.todo b{font-family:var(--disp);font-size:14.5px;color:var(--then);line-height:1.2}
.todo small{font-size:11.5px;color:var(--muc-nhat);line-height:1.4}

/* ── ra bên ngoài: bản đồ và mạng xã hội ─────────────────── */
.outrow{display:grid;gap:8px;margin-top:8px}
.outrow .btn{margin:0}
.btn.sec.out{display:flex;align-items:center;justify-content:center;gap:9px;min-height:48px}
.btn.sec.out svg{width:18px;height:18px;color:var(--dong-chu)}

/* Lưới nền tảng: hai cột trên máy hẹp, tự giãn ra ba khi có chỗ. Mỗi ô là
   một ĐÍCH CHẠM đủ 48px — đây là hàng nút dễ bị bóp nhỏ nhất trong app vì
   nội dung mỗi ô ngắn. */
.netgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));
  gap:8px;margin-top:9px}
.netchip{display:flex;align-items:center;gap:10px;min-height:52px;padding:9px 12px;
  border-radius:16px;background:var(--giay);border:1px solid var(--line);
  color:var(--muc);text-decoration:none;
  transition:transform .18s cubic-bezier(.22,.61,.36,1),border-color .18s}
.netchip:active{transform:scale(.975)}
.netchip:hover{border-color:var(--vien)}
.netchip:focus-visible{outline:2px solid var(--ngoc);outline-offset:2px}
.netchip svg{width:19px;height:19px;flex:0 0 auto;color:var(--then)}
.netchip span{display:grid;min-width:0}
.netchip b{font-size:13.5px;font-weight:600;color:var(--then);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.netchip i{font-style:normal;font-size:11px;color:var(--muc-nhat);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ── đi trong ngày (tab Nearby) ──────────────────────────── */
.trip-list{display:grid;gap:8px}
.trip-card{display:grid;grid-template-columns:44px 1fr 18px;gap:12px;align-items:center;
  width:100%;text-align:left;padding:11px 13px;border-radius:18px;
  background:linear-gradient(168deg,#fff 60%,#FDFAF1);
  border:1.5px solid var(--vien);box-shadow:0 3px 12px rgba(14,43,36,.06);
  transition:transform .2s cubic-bezier(.22,.61,.36,1)}
.trip-card:active{transform:scale(.985)}
/* background-size/position/repeat là BẮT BUỘC, không phải trang trí thêm.
   tripCardHTML đặt background-image bằng style nội tuyến, còn icon ship
   kèm app là ảnh 256×256. Thiếu ba dòng này thì ảnh nằm nguyên cỡ và ô
   44px chỉ lộ ra góc trên trái của nó — với "heritage" (phế tích giữa
   khung) và "craft" (xưởng đèn lồng giữa khung) thì góc đó là nền kem
   trắng trơn, nên hai thẻ Mỹ Sơn và Thanh Hà hiện ra một ô TRỐNG.
   Trông y hệt thiếu ảnh, mà ảnh vẫn nằm đó, đủ nét, đúng tên. */
.trip-ico{width:44px;height:44px;border-radius:14px;overflow:hidden;
  background:var(--kem) no-repeat center/cover;
  border:1.5px solid var(--vien-in);display:grid;place-items:center}
.trip-ico img{width:100%;height:100%;object-fit:cover}
.trip-body{display:grid;min-width:0}
.trip-body .nm{font-family:var(--disp);font-size:clamp(15px,4.2vw,17px);
  font-weight:600;color:var(--then);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.trip-body .note{font-size:12px;color:var(--muc-nhat);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.trip-meta{font-size:11.5px;color:var(--dong-chu);font-variant-numeric:tabular-nums;
  margin-top:2px}

/* ── quán thuộc phân khúc cao cấp ────────────────────────────
   CỐ Ý không dùng .trip-card hay .ex-card: những thẻ ấy bấm được và dẫn
   sang một màn của Nón Lá, còn đây là danh sách để ĐỌC, mỗi dòng dẫn ra
   ngoài tới nguồn. Cho nó trông giống thẻ bấm được là hứa một cú chạm
   không tồn tại.

   Cũng không dùng màu cảnh báo. Cam/đỏ ở app này nghĩa là "giá vượt
   khoảng" — mà mấy quán đây có làm gì sai đâu. Viền vàng đồng là màu của
   khối thông tin, đúng thứ nó đang là. */
.prem-list{display:grid;gap:8px;margin:0;padding:0;list-style:none}
.prem{padding:11px 13px;border-radius:16px;background:#fff;
  border:1.5px solid var(--vien);box-shadow:0 3px 12px rgba(14,43,36,.05)}
.prem-top{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.prem-top b{font-family:var(--disp);font-size:clamp(14.5px,4vw,16.5px);
  font-weight:600;color:var(--then);min-width:0}
.prem-seg{font-size:11.5px;color:var(--dong-chu);background:var(--kem);
  border-radius:999px;padding:2px 8px;white-space:nowrap}
/* Số tiền để tabular-nums và không xuống dòng giữa chừng: đây là thứ người
   đọc quét mắt qua, và một dải giá gãy làm đôi thì phải đọc lại từ đầu. */
.prem-band{display:block;margin-top:4px;font-size:13px;font-weight:600;
  color:var(--muc);font-variant-numeric:tabular-nums}
.prem-known{display:block;margin-top:2px;font-size:12px;color:var(--muc-nhat)}
.prem-links{display:flex;gap:14px;margin-top:7px}
.prem-links a{font-size:12.5px;font-weight:600;color:var(--dong-chu);
  text-decoration:underline;text-underline-offset:2px;
  min-height:34px;display:inline-flex;align-items:center}

/* ── màn mở đầu ──────────────────────────────────────────────
   Kiểu của nó nằm HẲN trong welcome.css, không còn một dòng nào ở đây.
   Màn đó chạy đúng một lần trong đời một lần cài app và là khối duy nhất
   phủ kín cả tabbar — nó không dùng chung một token nào với bốn tab
   thường trực, nên để lẫn vào đây chỉ khiến mỗi lần sửa nó phải đọc qua
   1300 dòng không liên quan. Bản trước để cả hai nơi cùng khai .wc-title
   và .wc-art, và luật nào thắng thì tuỳ thứ tự <link> trong index.html —
   một cách hỏng rất khó lần ra. */

/* Bài lưu trên máy: nhãn phải khác hẳn bài trên máy chủ, nếu không người
   dùng tưởng mình vừa đăng cho cả thế giới xem. */
.clocal{display:flex;align-items:center;gap:8px;margin:2px 0 12px;padding:10px 12px;
  border-radius:14px;background:#FBF2E2;border:1px solid rgba(200,121,31,.35);
  font-size:12.5px;color:var(--muc-nhat);line-height:1.45}
.clocal b{font-family:var(--disp);font-size:13px;color:var(--then);white-space:nowrap}
.cpost .conly{display:inline-block;margin-left:6px;padding:1px 7px;border-radius:var(--pill);
  background:#FBF2E2;border:1px solid rgba(200,121,31,.4);
  font-size:10.5px;font-weight:600;color:#8A5A16}

/* Ghi chép của chính mình trên thẻ quán — khác feed công khai: không sao
   trung bình, không cỡ mẫu, chỉ là những gì người này đã viết. */
.cnote-mine{display:grid;grid-template-columns:auto 1fr;gap:11px;align-items:start;
  padding:11px 0;border-bottom:1px solid var(--line)}
.cnote-mine:last-of-type{border-bottom:0}
.cnote-mine img{width:56px;height:56px;border-radius:12px;object-fit:cover;
  border:1px solid var(--line)}
.cnote-mine>div{min-width:0}

/* ── lớp tile bản đồ thật ───────────────────────────────────
   Nằm DƯỚI mọi lớp khác của bản đồ: ghim, mốc và tuyến là dữ liệu của
   app, tile chỉ là nền. pointer-events:none để cú chạm rơi xuống
   .bm-canvas bên dưới — nếu không, kéo bản đồ trên chỗ có tile thì
   trình duyệt tưởng người dùng đang kéo một tấm ảnh đi. */
.bm-tiles{position:absolute;inset:0;z-index:0;overflow:hidden;pointer-events:none}
.bm-tiles img{
  position:absolute;left:0;top:0;transform-origin:0 0;
  display:block;max-width:none;
  /* Tile OSM gốc xanh đỏ rực; app này là giấy dó và mực nho. Một lượt
     ngả nâu nhẹ kéo nó về đúng bảng màu mà không làm mất chữ trên bản
     đồ — sepia mạnh hơn .4 là nhãn phố bắt đầu chìm. */
  filter:sepia(.32) saturate(.82) brightness(1.04) contrast(.96);
}
/* Ảnh VỆ TINH thì không ngả nâu, không giảm tương phản: bộ lọc làm mềm từng
   mái ngói, đúng thứ người dùng cần nhìn rõ. Lớp phủ chữ nằm trên ảnh nền. */
.anh-ve-tinh .bm-tiles img{filter:none}
.bm-tiles img.phu{z-index:1}
/* Tile đã lên thì nền vector tắt hẳn: hai lớp cùng vẽ phố sẽ lệch nhau
   một hai điểm ảnh và cả bản đồ đọc ra là bị nhoè. */
#bmBase.thin{display:none}

/* ── cầu nối sang bản web máy tính ──────────────────────────
   App khoá bề ngang 520px, nên mở trên màn hình 1440px là hai bên toàn
   nền tối. Dải này nằm ở khoảng trống đó và chỉ hiện từ 900px trở lên —
   dưới ngưỡng ấy nó vừa vô nghĩa vừa cướp chỗ của nội dung. */
.deskhint{display:none}
/* 1200px chứ không phải 900px, và nằm trong LỀ TRÁI chứ không giữa màn:
   cột app rộng 520px, nên dưới 1200px hai bên chỉ còn ~190px — một dải
   ngang đặt giữa sẽ nằm ĐÈ LÊN nút chính của app (đã thử: nó che đúng
   nút "Next" của màn mở đầu). Chỗ trống thật sự là hai lề tối hai bên. */
@media (min-width:1200px){
  .deskhint{
    display:grid;gap:8px;
    position:fixed;left:24px;bottom:24px;width:320px;z-index:5;
    padding:16px 18px;border-radius:16px;
    background:rgba(251,247,236,.96);border:1px solid var(--vien);
    box-shadow:0 10px 40px rgba(0,0,0,.28);
    font-size:13px;color:var(--muc);text-decoration:none;
  }
  .deskhint b{font-family:var(--disp);font-size:15.5px}
  .deskhint span{color:var(--muc-nhat)}
  .deskhint i{
    font-style:normal;font-weight:600;justify-self:start;
    padding:9px 16px;border-radius:999px;background:var(--ngoc-sau);color:#FBF7EC;
  }
  .deskhint:hover{border-color:var(--vien-dam)}
}

/* ── bản đồ Google nhúng trong thẻ ─────────────────────────
   Khung 16/10 bo góc, cùng hình dạng với mọi khung ảnh khác trong thẻ
   (.ph), để nó đọc ra là một phần của thẻ chứ không phải một mảnh web
   lạ dán vào. border-radius phải đi kèm overflow:hidden — iframe không
   tự bo theo khung cha. */
.gmap{position:relative;width:100%;aspect-ratio:16/10;margin:2px 0 12px;
  border-radius:16px;overflow:hidden;border:1px solid var(--line);
  background:var(--kem)}
.gmap iframe{width:100%;height:100%;border:0;display:block}

/* ── màn khảo sát giá ───────────────────────────────────────
   Phủ toàn màn hình như #v-bigmap. Nền giấy đặc chứ không trong suốt:
   đây là một phiên làm việc, không phải một lớp phủ tra cứu, và nhìn
   thấy tab bên dưới chỉ mời người ta bấm ra giữa chừng. */
#v-survey{position:fixed;inset:0;z-index:70;overflow-y:auto;
  -webkit-overflow-scrolling:touch;background:var(--ngoc-nhat);
  max-width:520px;margin:0 auto;padding:0 var(--pad-x) calc(28px + var(--safe))}
#v-survey[hidden]{display:none}

.sv-head{display:flex;align-items:center;gap:12px;padding:14px 0 6px;
  position:sticky;top:0;z-index:2;background:var(--ngoc-nhat)}
.sv-head h1{font-family:var(--disp);font-size:23px;font-weight:600;color:var(--then);line-height:1.1}
.sv-head .kicker{margin:0}
.sv-count{margin-left:auto;font-size:12px;font-weight:700;color:var(--dong-chu);
  font-variant-numeric:tabular-nums}

.sv-place{display:grid;gap:5px;margin-top:8px;font-size:12.5px;color:var(--muc-nhat)}
.sv-place small{color:var(--xam-ghim)}
.sv-place input{min-height:46px;padding:10px 12px;border-radius:12px;
  border:1px solid var(--line);background:#fff;color:var(--muc);font:inherit;width:100%}

/* Ô nhập giá là thứ to nhất trên màn — người dùng đang gõ nó hàng chục
   lần liên tiếp, và mỗi lần trượt ngón tay là một lần phải gõ lại. */
.sv-entry{margin-top:12px;padding:12px;border-radius:16px;
  background:var(--giay);border:1.5px solid var(--vien)}
.sv-picked b{display:block;font-family:var(--disp);font-size:18px;color:var(--then)}
.sv-picked span{font-size:12px;color:var(--muc-nhat)}
.sv-entry input{width:100%;margin-top:9px;min-height:58px;padding:10px 14px;
  border-radius:14px;border:1.5px solid var(--vien);background:#fff;
  font-size:26px;font-weight:700;color:var(--then);font-variant-numeric:tabular-nums}
.sv-entry .btn{margin-top:9px}

.sv-tip{margin-top:12px;padding:12px;border-radius:14px;background:var(--kem);
  border:1px solid var(--vien-in);font-size:13px;line-height:1.5;color:var(--muc-nhat)}

.sv-list{display:grid;gap:6px;margin-top:14px}
/* Cột phải ĐẶT TÊN RÕ, không để lưới tự xếp. `.tick` mang grid-row:1/3
   nên khi không chỉ định cột, thuật toán tự xếp đặt nó vào cột 1 — ô đầu
   tiên còn trống — và đẩy tên món sang cột 2. Kết quả là cả danh sách
   đọc ngược: con số bên trái, tên món dạt sang phải, chữ chồng lên nhau. */
.sv-dish{display:grid;grid-template-columns:1fr auto;grid-template-rows:auto auto;
  gap:2px 10px;text-align:left;
  padding:10px 12px;min-height:52px;border-radius:12px;
  background:var(--giay);border:1px solid var(--vien-in)}
.sv-dish .nm{grid-column:1;grid-row:1;font-weight:600;color:var(--then);font-size:14px}
/* KHÔNG dùng tên `.hint`: app.css đã có một `.hint` toàn cục cho dòng
   nhắc trên màn quét, và nó định vị TUYỆT ĐỐI giữa màn hình. Đặt trùng
   tên thì 41 dòng phụ ở đây chồng hết lên nhau thành một viên thuốc đen
   trôi giữa danh sách — mất hai phút mới lần ra vì CSS không báo gì. */
.sv-dish .svsub{grid-column:1;grid-row:2;font-size:11px;color:var(--xam-ghim)}
.sv-dish .tick{grid-column:2;grid-row:1/3;align-self:center;font-size:12px;font-weight:700;
  color:var(--dong-chu);font-variant-numeric:tabular-nums}
.sv-dish.on{border-color:var(--vien-dam);background:var(--kem)}
/* Món đã đủ mẫu mờ đi nhưng KHÔNG biến mất: giá đổi theo mùa, và đi qua
   lần nữa thì vẫn đáng ghi thêm. */
.sv-dish.done{opacity:.55}
.sv-dish.done .tick{color:var(--ngoc)}

.sv-sect{font-family:var(--disp);font-size:15px;color:var(--then);margin:16px 0 6px}
.sv-recent{display:grid;gap:4px}
.sv-row{display:flex;align-items:center;gap:10px;padding:7px 12px;border-radius:10px;
  background:var(--kem);font-size:13px;color:var(--muc-nhat)}
.sv-row b{margin-left:auto;color:var(--then);font-variant-numeric:tabular-nums}
.sv-row button{width:32px;height:32px;border-radius:50%;color:var(--son-dam);font-size:18px}

.sv-foot{display:grid;gap:8px;margin-top:18px}
.sv-note{margin-top:8px;font-size:12px;line-height:1.5;color:var(--xam-ghim)}
/* Màn xin phép gửi giá. Hai dòng "đi" và "ở lại" phải đọc được trong một
   liếc mắt, nên chúng có gạch màu ở lề trái thay vì chỉ khác cỡ chữ. */
.sv-consent{margin-top:18px;padding:14px;border:1px solid var(--line);border-radius:16px}
.sv-consent h2{margin:0 0 10px;font-size:15px;line-height:1.4}
.sv-consent p{margin:0 0 8px;font-size:13px;line-height:1.55;padding-left:10px;
  border-left:3px solid var(--line)}
.sv-consent .go{border-left-color:var(--ngoc-sau)}
.sv-consent .stay{border-left-color:var(--xam-ghim)}
.sv-consent .sv-foot{margin-top:12px}

/* ── dải cảnh báo khi đi bộ ─────────────────────────────────
   Nằm ngay TRÊN thanh nav, không phải giữa màn hình: người dùng đang đi
   bộ, cầm máy thấp, và ngón cái ở nửa dưới. Một hộp thoại giữa màn chặn
   mất bản đồ đúng lúc họ cần nhìn nó nhất. */
#walkwarn{position:fixed;left:50%;transform:translateX(-50%) translateY(140%);
  bottom:calc(96px + var(--safe));z-index:60;
  width:min(calc(100% - 24px),496px);display:flex;align-items:stretch;gap:0;
  border-radius:18px;overflow:hidden;
  background:#FBF2E2;border:1.5px solid rgba(200,121,31,.5);
  box-shadow:0 12px 34px -10px rgba(58,42,10,.5);
  transition:transform .3s cubic-bezier(.22,.61,.36,1),opacity .3s;opacity:0;
  pointer-events:none}
#walkwarn.on{transform:translateX(-50%) translateY(0);opacity:1;pointer-events:auto}
#walkwarn>button:first-child{flex:1;display:flex;align-items:center;gap:11px;
  text-align:left;padding:11px 12px;min-height:56px}
#walkwarn .wi{flex:0 0 auto;width:34px;height:34px;border-radius:50%;
  display:grid;place-items:center;background:var(--ho-phach);color:#FFF6E8}
#walkwarn .wi svg{width:18px;height:18px}
#walkwarn .wt{display:grid;gap:2px;min-width:0}
#walkwarn .wt b{font-family:var(--disp);font-size:15px;color:var(--then);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#walkwarn .wt i{font-style:normal;font-size:11.5px;line-height:1.35;color:#8A5A16}
#walkwarn .wx{flex:0 0 auto;width:46px;color:#8A5A16;font-size:20px;
  border-left:1px solid rgba(200,121,31,.3)}
@media (prefers-reduced-motion:reduce){ #walkwarn{transition:none} }

/* ── chia hoá đơn ───────────────────────────────────────────
   Số người là một hàng nút to: người dùng đang ngồi ở bàn, có tiếng ồn,
   và đây là thao tác đầu tiên họ làm — nó phải trúng ngay lần đầu. */
/* Bảy nút phải nằm gọn MỘT hàng. Ở 46px + khe 7px chúng cần 364px, quá
   bề ngang còn lại trên máy 390px, nên nút "8" rớt xuống một hàng riêng —
   trông như một lựa chọn khác loại với sáu nút kia. */
.sp-n{display:flex;gap:6px;margin:10px 0 4px}
.sp-nbtn{flex:1 1 0;min-width:0;height:46px;border-radius:14px;font-size:16px;font-weight:700;
  background:var(--giay);border:1.5px solid var(--vien-in);color:var(--muc-nhat)}
.sp-nbtn.on{background:var(--then);border-color:var(--vien-dam);color:#F6F2E6}

.sp-rows{display:grid;gap:8px;margin-top:10px}
.sp-row{padding:10px 12px;border-radius:14px;background:var(--giay);
  border:1px solid var(--vien-in)}
.sp-line{display:flex;align-items:baseline;gap:10px;font-size:14px;color:var(--muc)}
.sp-line span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sp-line b{color:var(--then);font-variant-numeric:tabular-nums}
.sp-chips{display:flex;gap:6px;margin-top:8px;flex-wrap:wrap}
/* 40px chứ không 44: tám chip phải vừa một hàng trên máy 360px, và chúng
   nằm sát nhau theo hàng ngang nên ngón tay có cả chiều cao để trượt. */
.sp-who{width:40px;height:40px;border-radius:50%;font-size:14px;font-weight:700;
  background:#fff;border:1.5px solid var(--line);color:var(--xam-ghim)}
.sp-who.on{background:var(--ngoc);border-color:var(--ngoc-sau);color:#fff}

.sp-out{display:grid;grid-template-columns:repeat(auto-fit,minmax(96px,1fr));gap:8px}
.sp-p{display:flex;align-items:center;gap:9px;padding:10px 12px;border-radius:14px;
  background:var(--kem);border:1px solid var(--vien-in)}
.sp-p span{width:26px;height:26px;border-radius:50%;display:grid;place-items:center;
  background:var(--then);color:var(--dong);font-size:12px;font-weight:700;flex:0 0 auto}
.sp-p b{font-variant-numeric:tabular-nums;color:var(--then);font-size:15px}

/* ── màn xoay ngược cho người bán đọc ──────────────── */
/* Nền THEN, không phải nền giấy như mọi màn khác. Đây là màn duy nhất
   được đọc từ xa một mét, chéo góc, có khi dưới nắng chói — chữ sáng
   trên nền sẫm giữ được tương phản ở góc nhìn mà nền sáng thì loá. Nó
   cũng là tín hiệu cho chính người dùng rằng màn này khác: bạn đang
   không còn đọc app nữa, bạn đang đưa nó cho người khác. */
#v-show{position:fixed;inset:0;z-index:75;display:flex;flex-direction:column;
  background:var(--then);color:var(--diep);
  padding:0 var(--pad-x) calc(16px + var(--safe))}
#v-show[hidden]{display:none}

.sc-top{display:flex;align-items:center;gap:10px;padding:10px 0}
.sc-top p{flex:1;text-align:center;font-size:11.5px;letter-spacing:.06em;
  text-transform:uppercase;color:rgba(245,240,228,.62)}
.sc-top .iconbtn{background:rgba(245,240,228,.1);border-color:rgba(201,162,39,.4);
  color:var(--diep);box-shadow:none;font-size:18px}
.sc-top .iconbtn.on{background:var(--dong);color:var(--then-sau);border-color:var(--dong)}

/* Khối của người bán. Chiếm phần lớn màn hình vì nó LÀ tính năng. */
.sc-face{flex:1;display:grid;place-content:center;text-align:center;
  border:1px solid rgba(201,162,39,.34);border-radius:var(--r);
  background:linear-gradient(160deg,rgba(201,162,39,.1),rgba(245,240,228,.03));
  padding:22px 16px;min-height:0;
  transition:transform .34s cubic-bezier(.22,.61,.36,1)}
.sc-face.flip{transform:rotate(180deg)}
/* clamp chứ không phải một cỡ cố định: câu ngắn nhất ở đây là hai chữ,
   câu dài nhất là mười — một cỡ vừa cho câu dài thì câu ngắn nhỏ đến vô
   nghĩa, mà cả điểm của màn này là ĐỌC ĐƯỢC TỪ XA. */
.sc-vi{font-family:var(--disp);font-weight:600;line-height:1.16;
  font-size:clamp(30px,8.4vw,46px);letter-spacing:-.015em;color:var(--diep);
  text-wrap:balance}
.sc-qty{margin-top:14px;font-size:clamp(34px,11vw,58px);font-weight:800;
  color:var(--dong);font-variant-numeric:tabular-nums;letter-spacing:-.03em}

.sc-mine{flex:0 0 auto;padding-top:12px}
.sc-speak{display:grid;grid-template-columns:1fr auto;align-items:center;
  gap:12px;width:100%;text-align:left;padding:12px 14px;border-radius:16px;
  border:1px solid rgba(201,162,39,.3);background:rgba(245,240,228,.07);
  color:var(--diep);min-height:56px}
.sc-speak:active{background:rgba(245,240,228,.13)}
.sc-ph{display:block;font-size:16px;font-weight:600;letter-spacing:.01em}
.sc-en{display:block;font-size:12.5px;color:rgba(245,240,228,.6);margin-top:2px}
.sc-spk{grid-row:1/3;grid-column:2;display:grid;place-items:center;color:var(--dong)}
.sc-spk svg{width:26px;height:26px}

.sc-count{display:flex;align-items:center;justify-content:center;gap:18px;
  margin-top:10px;font-variant-numeric:tabular-nums}
.sc-count button{width:44px;height:44px;border-radius:50%;font-size:22px;
  border:1px solid rgba(201,162,39,.4);background:rgba(245,240,228,.07);color:var(--diep)}
.sc-count span{min-width:34px;text-align:center;font-size:22px;font-weight:700}

/* Khoảng giá — nhỏ, ở NỬA CỦA BẠN, và không bao giờ đi lên khối trên. */
.sc-band{margin-top:10px;text-align:center;font-size:12.5px;
  color:rgba(245,240,228,.58);font-variant-numeric:tabular-nums}

.sc-chips{display:flex;gap:7px;overflow-x:auto;margin:12px -18px 0;
  padding:2px 18px 4px;scrollbar-width:none}
.sc-chips::-webkit-scrollbar{display:none}
.sc-chip{flex:0 0 auto;padding:11px 14px;border-radius:var(--pill);font-size:13px;
  font-weight:600;white-space:nowrap;min-height:44px;
  border:1px solid rgba(201,162,39,.3);background:rgba(245,240,228,.06);
  color:rgba(245,240,228,.82)}
.sc-chip.on{background:var(--dong);border-color:var(--dong);color:var(--then-sau)}

/* Lối vào màn xoay ngược, nổi trên khung camera. Nền sẫm mờ chứ không
   phải nút đặc: nó nằm ĐÈ LÊN hình camera đang chạy, và một khối màu đặc
   ở đây che mất đúng phần thực đơn người dùng đang ngắm. */
.sayhere{position:absolute;left:50%;transform:translateX(-50%);
  bottom:calc(150px + var(--safe));z-index:3;
  padding:10px 18px;min-height:42px;border-radius:var(--pill);
  font-size:13.5px;font-weight:600;letter-spacing:.01em;
  color:var(--diep);background:rgba(14,43,36,.62);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  border:1px solid rgba(201,162,39,.45)}
.sayhere:active{background:rgba(14,43,36,.8)}

/* ── khối "vì sao lại nói thế" ─────────────────────── */
.why,.fold{margin-top:12px;border:1px solid var(--line);border-radius:16px;
  background:var(--giay);overflow:hidden}
.why summary,.fold summary{display:flex;align-items:center;gap:9px;padding:13px 14px;
  min-height:48px;font-size:14px;font-weight:650;color:var(--then);
  cursor:pointer;list-style:none}
.why summary::-webkit-details-marker,.fold summary::-webkit-details-marker{display:none}
/* Mũi chỉ hướng vẽ bằng CSS, không thêm một icon nữa vào bộ: nó chỉ có
   một việc là cho biết khối này mở ra được. */
.why summary::after,.fold summary::after{content:"";margin-left:auto;width:8px;height:8px;flex:0 0 auto;
  border-right:2px solid var(--muc-nhat);border-bottom:2px solid var(--muc-nhat);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .2s}
.why[open] summary::after,.fold[open] summary::after{transform:rotate(-135deg) translate(-2px,-2px)}
.why[open] summary,.fold[open] summary{border-bottom:1px solid var(--line)}

/* Chấm màu = bậc tin cậy. Cùng bảng màu với chấm phán quyết ở hàng kết
   quả, nên người dùng không phải học hai hệ ký hiệu. */
.wdot{width:9px;height:9px;border-radius:50%;flex:0 0 auto;background:var(--xam-ghim)}
.wdot[data-l="seed"],.wdot[data-l="sourced"],.wdot[data-l="thin"]{background:var(--ho-phach)}
.wdot[data-l="ready"]{background:var(--dong)}
.wdot[data-l="fair"],.wdot[data-l="strong"]{background:var(--ngoc)}

.wtag{margin-left:auto;margin-right:6px;font-size:11px;font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;color:var(--muc-nhat)}
.why>p{padding:0 14px;font-size:13px;line-height:1.5;color:var(--muc-nhat)}
.why>p:first-of-type{padding-top:12px}
.wtitle{font-weight:700;color:var(--muc)!important}
.why .btn{margin:12px 14px 14px;width:calc(100% - 28px)}

.wgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1px;
  margin:12px 14px;background:var(--line);border:1px solid var(--line);
  border-radius:12px;overflow:hidden}
.wgrid>div{background:var(--diep);padding:9px 11px}
.wgrid dt{font-size:10.5px;letter-spacing:.05em;text-transform:uppercase;
  color:var(--muc-nhat)}
.wgrid dd{font-size:15px;font-weight:700;color:var(--then);
  font-variant-numeric:tabular-nums;margin-top:1px}
.wfoot{font-size:12px!important;color:var(--xam-ghim)!important}

/* ── đếm tiền thối ─────────────────────────────────── */
.ch-bill{display:grid;gap:5px;margin-top:12px;font-size:12.5px;color:var(--muc-nhat)}
.ch-bill input{min-height:52px;padding:10px 12px;border-radius:14px;
  border:1px solid var(--line);background:#fff;color:var(--muc);
  font:inherit;font-size:20px;font-weight:700;width:100%;
  font-variant-numeric:tabular-nums}

/* Bàn phím mệnh giá. Lưới 5 cột chứ không phải hàng cuộn ngang: chín tờ
   là con số cố định và người dùng phải với tới TỜ NÀO CŨNG ĐƯỢC mà không
   cần cuộn — họ đang cầm tiền bằng tay còn lại. */
.ch-pad{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:6px;margin-top:8px}
.ch-note{min-height:46px;border-radius:12px;border:1px solid var(--line);
  background:var(--giay);color:var(--then);font-size:14px;font-weight:700;
  font-variant-numeric:tabular-nums}
.ch-note:active{background:var(--kem);transform:scale(.96)}

.ch-tally{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-top:8px;
  min-height:34px}
.ch-tally b{margin-left:auto;font-size:16px;font-variant-numeric:tabular-nums;
  color:var(--then)}
.ch-chip{padding:6px 11px;border-radius:var(--pill);font-size:12.5px;font-weight:700;
  background:var(--ngoc);color:#fff;border:0;font-variant-numeric:tabular-nums;
  min-height:32px}
.ch-chip::after{content:" ×";opacity:.55;font-weight:400}
.ch-empty{font-size:12.5px;color:var(--xam-ghim)}

.ch-due{margin-top:14px;padding:12px 14px;border-radius:16px;
  border:1px solid var(--vien);background:var(--kem)}
.ch-big{font-size:30px;font-weight:800;letter-spacing:-.03em;color:var(--then);
  font-variant-numeric:tabular-nums;margin-top:2px}
.ch-due .src{margin-top:4px}

/* Tờ tiền thối vẽ lại theo tông màu polymer. Cặp 20k/500k và 10k/200k cố ý
   gần màu nhau, vì ngoài đời chúng cũng dễ nhầm — số "k" trên tờ là thứ phân biệt. */
.ch-notes{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.ch-bill-note{display:grid;place-items:center;width:58px;height:32px;border-radius:5px;
  font-size:12.5px;font-weight:800;color:#fff;letter-spacing:-.01em;
  border:1.5px solid rgba(255,255,255,.55);box-shadow:0 1px 2px rgba(0,0,0,.25);
  text-shadow:0 1px 1px rgba(0,0,0,.35);font-variant-numeric:tabular-nums}
.ch-bill-note[data-n="500000"]{background:#2f8fb5}
.ch-bill-note[data-n="200000"]{background:#a8493a}
.ch-bill-note[data-n="100000"]{background:#3f8a4f}
.ch-bill-note[data-n="50000"]{background:#c4527d}
.ch-bill-note[data-n="20000"]{background:#3b6fb0}
.ch-bill-note[data-n="10000"]{background:#9a6a2f}
.ch-bill-note[data-n="5000"]{background:#5a6f92}
.ch-bill-note[data-n="2000"]{background:#7a7a76}
.ch-bill-note[data-n="1000"]{background:#8a6c4a}

/* Bảng cộng dồn các lần so, nằm trong màn Journal — nền sơn mài, nên
   mọi màu chữ ở đây phải là màu SÁNG, không dùng lại token của nền giấy. */
.jtax{margin-top:8px;padding:13px 14px;border-radius:16px;
  border:1px solid rgba(201,162,39,.34);background:rgba(245,240,228,.06)}
.jtaxline{font-size:13.5px;line-height:1.5;color:#EDE4D2}
.jtaxd{margin-top:10px;display:grid;gap:1px;background:rgba(201,162,39,.22);
  border-radius:11px;overflow:hidden}
.jtaxrow{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:10px;
  align-items:center;padding:9px 11px;background:rgba(8,32,27,.55)}
.jtaxrow .nm{font-size:13.5px;font-weight:600;color:#EDE4D2;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.jtaxrow .js{font-size:11.5px;color:rgba(237,228,210,.62)}
.jtaxrow b{font-size:14px;font-variant-numeric:tabular-nums}
.jtaxrow b[data-l="high"]{color:#E88A80}
.jtaxrow b[data-l="low"]{color:#6FCBA8}
.jtaxrow b[data-l="same"]{color:rgba(237,228,210,.62)}

/* ── so hai tấm thực đơn ───────────────────────────── */
.tx-head{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  gap:10px;margin-top:12px}
.tx-head span{display:grid;font-size:10.5px;letter-spacing:.05em;
  text-transform:uppercase;color:var(--xam-ghim);text-align:center}
.tx-head b{font-size:13.5px;letter-spacing:0;text-transform:none;
  color:var(--then);margin-top:2px}
.tx-swap{width:40px;height:40px;border-radius:50%;flex:0 0 auto;font-size:17px;
  border:1px solid var(--line);background:var(--giay);color:var(--then)}

.tx-list{margin-top:12px;border:1px solid var(--line);border-radius:14px;
  overflow:hidden;background:var(--giay)}
.tx-row{display:grid;grid-template-columns:minmax(0,1fr) auto 16px auto;
  align-items:center;gap:8px;padding:10px 12px;font-variant-numeric:tabular-nums}
.tx-row+.tx-row{border-top:1px solid var(--line)}
.tx-row .nm{font-size:13.5px;font-weight:600;color:var(--muc);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tx-a{font-size:13.5px;color:var(--muc-nhat)}
.tx-arrow{text-align:center;color:var(--xam-ghim);font-size:12px}
.tx-b{font-size:14px;font-weight:700}
.tx-b[data-l="high"]{color:var(--son)}
.tx-b[data-l="low"]{color:var(--ngoc)}
.tx-b[data-l="same"]{color:var(--muc-nhat)}

/* ── bưu thiếp ─────────────────────────────────────── */
.pc-card{display:flex;align-items:center;gap:13px;width:100%;text-align:left;
  margin-top:14px;padding:14px;border-radius:var(--r);
  border:1px solid var(--vien);background:var(--kem);min-height:64px}
.pc-card:active{transform:scale(.99)}
.pc-ic{width:42px;height:42px;flex:0 0 auto;border-radius:50%;display:grid;
  place-items:center;background:var(--then);color:var(--dong)}
.pc-ic svg{width:19px;height:19px}
.pc-card b{display:block;font-size:15px;color:var(--then)}
.pc-card small{display:block;font-size:12.5px;color:var(--muc-nhat);
  line-height:1.4;margin-top:2px}

/* Canvas 1080×1350 co về đúng bề rộng thẻ. aspect-ratio giữ chỗ TRƯỚC khi
   vẽ xong, nếu không thẻ nhảy cao lên một nhịp khi tranh nền tải về. */
.pc-wrap{margin-top:12px;border-radius:16px;overflow:hidden;
  border:1px solid var(--line);background:var(--diep)}
.pc-wrap canvas{display:block;width:100%;height:auto;aspect-ratio:1080/1350}

/* ── Lưới món cho chế độ "không có thực đơn" ──────────────────
   Xe đẩy vỉa hè không có gì để chĩa camera vào, mà đó lại đúng chỗ
   khách dễ bị hớ nhất. Lưới ảnh để chạm thay cho việc gõ tên món —
   khách không cần biết đọc tiếng Việt, chỉ cần nhận ra món trước mặt. */
.dishgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:8px 0 4px}
.dishgrid button{background:none;border:0;padding:0;text-align:center;cursor:pointer}
.dishgrid button:active{transform:scale(.96)}
.dishgrid .ph{aspect-ratio:1;border-radius:14px;margin:0;
  border:1px solid rgba(217,162,39,.45);background:var(--kem)}
.dishgrid .ph figcaption,.dishgrid .ph::after{display:none}
.dishgrid .lbl{display:block;font-size:14px;line-height:1.25;margin-top:5px;color:var(--muc)}
.dishgrid .rng{display:block;font-size:14px;color:var(--muc-nhat)}

/* ── Ước tính hoá đơn trước khi gọi ─────────────────────────── */
.po-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px;align-items:center;
  padding:9px 0;border-bottom:1px solid var(--line)}
.po-row .nm{display:block;font-size:15px}
.po-row .sub{display:block;font-size:14px;color:var(--muc-nhat)}
.po-step{display:flex;align-items:center;gap:9px}
.po-step button{width:34px;height:34px;border-radius:11px;border:1px solid var(--line);
  background:var(--giay);font-size:18px;line-height:1;cursor:pointer}
.po-step .n{min-width:20px;text-align:center;font-size:15px}
.po-total{display:flex;justify-content:space-between;align-items:baseline;
  margin-top:12px;padding-top:11px;border-top:2px solid var(--vien-dam);font-size:17px}
.po-total b{font-size:20px}

/* Thân khối gập: đệm trong để nút bên trong không dính mép. */
.fold .foldin{padding:4px 12px 12px}
.fold .foldin .btn{margin-top:8px}
/* Một dòng cảnh báo gọn thay cho một khối cho mỗi bẫy. Bấm mới mở chi tiết. */
.trapline{display:flex;align-items:center;gap:9px;margin-top:10px;padding:11px 13px;
  border-radius:14px;background:var(--canh-bao-nen,#fdf4ea);
  border:1px solid var(--canh-bao-vien,rgba(181,101,29,.35));font-size:14px}
/* Chấm cam của dòng cảnh báo bẫy đơn vị — cùng vai trò với .wdot của khối
   "vì sao", nên dùng chung kích thước để không phải học hai hệ ký hiệu. */
.trapdot{width:9px;height:9px;border-radius:50%;flex:0 0 auto;background:#b5651d}

/* ── lịch Việt ────────────────────────────────────────────
   Dải mảnh, chỉ hiện những hôm có gì đáng nói — ba trăm ngày trong
   năm nó không tồn tại. Nên nó được phép dùng màu; thứ hiếm mới đáng
   một màu riêng. Viền trái chứ không phải nền đặc: nền đặc cạnh tấm
   thẻ phán quyết giá sẽ tranh mắt với chính phán quyết ấy. */
.lich{border-left:2px solid var(--vien-dam);padding:9px 0 9px 11px;margin:13px 0 4px}
.lich[data-kind="denlong"]{border-left-color:var(--ho-phach)}
.lichday{font-size:10px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muc-nhat);margin:0 0 4px}
.lichline{font-size:13px;line-height:1.55;font-weight:400;color:var(--muc);margin:0}
.lichin{font-size:11px;color:var(--muc-nhat);white-space:nowrap}
.lichnote{font-size:10.5px;color:var(--muc-nhat);font-weight:300;line-height:1.5;margin:6px 0 0}
.lich .fold{margin-top:7px}

/* ── chuyện món ───────────────────────────────────────────
   Đọc chậm hơn phần còn lại của thẻ, nên cỡ chữ nhỉnh hơn một chút và
   dòng thưa hơn. Không có nền, không có viền: đây là văn xuôi, và bỏ
   một đoạn văn vào hộp là bảo người đọc rằng nó ngang hàng với một
   con số — trong khi cả tấm thẻ này được dựng để phân biệt hai thứ. */
.story{font-size:14px;line-height:1.72;font-weight:300;color:var(--muc);margin:2px 0 0}
.storylink{font-size:11.5px;line-height:1.55;color:var(--muc-nhat);font-weight:400;
  margin:9px 0 0;padding-left:9px;border-left:2px solid var(--vien-in)}

/* Ngày chay ở tab Eat — hai hôm mỗi tháng âm, nên được phép chiếm một dòng. */
.chayline{font-size:12.5px;line-height:1.55;color:var(--muc-nhat);font-weight:400;
  margin:11px 0 2px;padding-left:10px;border-left:2px solid var(--ngoc,#1F8A70)}

/* Khối "sắp tới" ở tab You — lịch âm sáu tuần tới. */
.lich-list{display:flex;flex-direction:column;gap:1px;margin:2px 0 6px}
.lich-row{display:flex;gap:12px;align-items:baseline;padding:8px 0;
  border-bottom:1px solid rgba(29,42,36,.08)}
.lich-when{flex:0 0 78px;font-size:12.5px;font-weight:600;color:var(--muc);
  display:flex;flex-direction:column;line-height:1.25}
.lich-when i{font-style:normal;font-size:10px;font-weight:400;color:var(--muc-nhat)}
.lich-what{font-size:12.5px;line-height:1.5;font-weight:300;color:var(--muc-nhat)}

/* ── phiếu "điều hai bên vừa cùng đọc" (phieuui.js) ───────────
   Cùng khuôn với #v-show: toàn màn hình, nền then, z-index trên sheet.
   Khác một chỗ quan trọng — màn kia chỉ để ĐỌC, màn này người bán CHẠM
   VÀO, nên vùng chạm phải to hơn hẳn và không có gì nhỏ hơn 44px. */
#v-phieu{position:fixed;inset:0;z-index:76;overflow-y:auto;
  background:var(--then);color:var(--diep);
  padding:0 var(--pad-x) calc(20px + var(--safe))}
#v-phieu[hidden]{display:none}

.pt-thanh{display:flex;justify-content:space-between;padding:10px 0;
  position:sticky;top:0;background:var(--then);z-index:2}
.pt-thanh .iconbtn{background:rgba(245,240,228,.1);border-color:rgba(201,162,39,.4);
  color:var(--diep);box-shadow:none;font-size:18px}
.pt-thanh .iconbtn.on{background:var(--dong);color:var(--then-sau);border-color:var(--dong)}

/* Lật cả tờ phiếu 180°, không lật từng phần: người bán đọc một tờ giấy
   quay ngược, không đọc một giao diện bị đảo lộn từng mảnh. */
.pt-mat.lat{transform:rotate(180deg)}

.pt-tieu{margin:4px 0 14px;font-size:15px;line-height:1.35;font-weight:600}
.pt-tieu span{display:block}
.pt-tieu span[lang=en]{color:rgba(245,240,228,.6);font-weight:400;font-size:13.5px}

.pt-dong{border-top:1px solid rgba(245,240,228,.16);padding:11px 0}
.pt-dong.thieu{border-left:3px solid var(--dong);padding-left:10px;
  margin-left:-13px;background:rgba(201,162,39,.06)}
.pt-ten{display:flex;justify-content:space-between;gap:10px;align-items:baseline}
.pt-ten b{font-size:16px}
.pt-ten span{font-size:13px;color:rgba(245,240,228,.62);white-space:nowrap}
.pt-tien{text-align:right;font-size:15px;font-variant-numeric:tabular-nums;margin-top:2px}

.pt-hoi{margin-top:8px}
.pt-hoi p{margin:0;font-size:14px;line-height:1.4}
.pt-hoi p[lang=en]{color:rgba(245,240,228,.58);font-size:12.5px}
.pt-o{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:8px}
.pt-o input{min-height:44px;min-width:96px;padding:8px 12px;font-size:16px;
  border-radius:10px;border:1px solid rgba(201,162,39,.45);
  background:rgba(245,240,228,.08);color:var(--diep)}
.pt-g{color:rgba(245,240,228,.6);font-size:13px}
.pt-nguoi{display:inline-flex;align-items:center;gap:7px;font-size:13px;
  color:rgba(245,240,228,.72)}
.pt-chon{min-height:44px;padding:9px 15px;border-radius:22px;font-size:14px;
  border:1px solid rgba(201,162,39,.45);background:rgba(245,240,228,.08);
  color:var(--diep);cursor:pointer}
.pt-chon:active{background:var(--dong);color:var(--then-sau)}

.pt-tong{border-top:2px solid rgba(201,162,39,.5);margin-top:14px;padding:14px 0}
.pt-tong.chua{border-color:rgba(201,162,39,.35);display:grid;
  grid-template-columns:1fr auto;align-items:center;gap:4px 12px}
.pt-tong.chua p{margin:0;font-size:14px}
.pt-tong.chua p[lang=en]{color:rgba(245,240,228,.58);font-size:12.5px;grid-column:1}
.pt-tong.chua b{grid-row:1/3;grid-column:2;font-size:30px;color:var(--dong);
  font-variant-numeric:tabular-nums}
.pt-mot{display:block;text-align:right;font-size:28px;color:var(--dong);
  font-variant-numeric:tabular-nums}
.pt-hai span{display:flex;justify-content:space-between;align-items:baseline;
  gap:10px;padding:3px 0;font-variant-numeric:tabular-nums}
.pt-hai i{font-style:normal;font-size:12.5px;color:rgba(245,240,228,.6)}
.pt-hai i[lang=en]{flex:1}
.pt-hai b{font-size:22px;color:var(--dong)}

.pt-dau{margin:12px 0;padding:10px 12px;border-radius:10px;
  background:rgba(201,162,39,.12);border:1px solid rgba(201,162,39,.4)}
.pt-dau p{margin:0;font-size:13.5px}
.pt-dau p[lang=en]{color:rgba(245,240,228,.6);font-size:12px}
.pt-dau time{display:block;margin-top:4px;font-size:12px;color:var(--dong)}

#v-phieu .btn.pri{width:100%;margin-top:12px;min-height:52px}
#v-phieu .btn.pri[disabled]{opacity:.4;pointer-events:none}

/* NÚT PHỤ TRÊN NỀN THEN. `.btn.sec` mặc định lấy màu mực của nền giấy, và
   tấm phiếu là màn duy nhất nền sẫm có nút ấy — nên chữ "Just note it for
   myself" gần như tàng hình. Không ai thấy trong lúc bấm thử vì vẫn bấm
   trúng; ảnh chụp cho hồ sơ mới lộ ra. test.mjs canh lại luật này. */
#v-phieu .btn.sec{width:100%;margin-top:10px;min-height:52px;background:transparent;
  color:var(--diep);border-color:rgba(245,240,228,.34)}

/* Câu "đây không phải hợp đồng". Nhỏ nhưng KHÔNG mờ tới mức đọc không
   ra — nó là thứ giữ tấm phiếu ở đúng chỗ của nó. */
.pt-chan{margin:14px 0 0;font-size:12px;line-height:1.45;
  color:rgba(245,240,228,.72)}
.pt-chan span{display:block}
.pt-chan span[lang=en]{color:rgba(245,240,228,.5)}

/* ── bảng khai điều kiện giá (hochieuui.js) ───────────────────
   Nền GIẤY, không nền then như #v-phieu và #v-show. Hai màn kia được
   chìa qua bàn trong một khoảnh khắc căng; màn này là một tờ khai người
   ta đọc kỹ, và chủ quán ngồi gõ số ở đây hàng chục phút. */
#v-hochieu{position:fixed;inset:0;z-index:74;overflow-y:auto;
  background:var(--giay);color:#1b1b1b;
  padding:0 var(--pad-x) calc(24px + var(--safe))}
#v-hochieu[hidden]{display:none}

.hc-thanh{display:flex;align-items:center;gap:10px;padding:10px 0;
  position:sticky;top:0;background:var(--giay);z-index:2}
.hc-thanh p{flex:1;margin:0;font-size:11.5px;letter-spacing:.06em;
  text-transform:uppercase;color:#6b6b6b}

.hc-tieu{margin:6px 0 1px;font-size:20px;color:var(--then)}
.hc-pho{margin:0 0 12px;font-size:13px;color:#6b6b6b}

/* Ba bậc, và không bậc nào nói gì về giá cao hay thấp. */
.hc-muc{border-left:4px solid var(--vien,#D9CFBA);background:#fff;
  padding:9px 12px;margin:10px 0;border-radius:0 8px 8px 0}
.hc-muc[data-m="du"]{border-left-color:#2E6B4F}
.hc-muc[data-m="dang"]{border-left-color:var(--dong)}
.hc-muc b{display:block;font-size:14.5px}
.hc-muc span{display:block;font-size:12.5px;color:#6b6b6b}
.hc-muc i{display:block;margin-top:3px;font-size:12px;font-style:normal;color:#8a8a8a}

/* Câu "đây là lời khai". Nhỏ nhưng KHÔNG mờ tới mức đọc không ra. */
.hc-loikhai{margin:10px 0 14px;font-size:12px;line-height:1.45;color:#5b5b5b}
.hc-loikhai span{display:block}
.hc-loikhai span[lang=en]{color:#8a8a8a}

.hc-chup{margin:0 0 12px;padding:8px 11px;border-radius:8px;font-size:12.5px;
  background:#FBF3E3;border:1px solid #E4D3A8;color:#6b5520}

.hc-dong{border-top:1px solid #E4DCC9;padding:11px 0}
.hc-ten b{font-size:16px}
.hc-ten i{display:block;font-style:normal;font-size:12.5px;color:#8a8a8a}
.hc-gia{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 9px;margin-top:4px}
.hc-gia .so{font-size:19px;font-weight:700;font-variant-numeric:tabular-nums}
.hc-gia .so em{font-size:14px;font-style:normal;font-weight:600;color:var(--son)}
.hc-gia .dv{font-size:12.5px;color:#6b6b6b}
/* Nhãn nguồn nằm TRONG khối giá, không ở chân trang. */
.hc-khai{font-size:11px;letter-spacing:.04em;text-transform:uppercase;
  background:#EFE8D8;border:1px solid #D9CFBA;border-radius:9px;padding:1px 7px;color:#6b6b6b}
.hc-note{margin:4px 0 0;font-size:12.5px;color:#5b5b5b}
.hc-thieu{margin:5px 0 0;font-size:12.5px;color:var(--son)}
.hc-trong{margin:16px 0;font-size:14px;color:#6b6b6b}

/* Khoảng chênh khai ↔ đo. KHÔNG đỏ, KHÔNG dấu cảnh báo: nó là một câu
   hỏi, và ba lý do lương thiện nằm ngay trong cùng khối. */
.hc-chenh{margin-top:7px;padding:8px 11px;border-radius:8px;
  background:#EEF2F4;border-left:3px solid #4A6B7A;font-size:12.5px}
.hc-chenh b{font-variant-numeric:tabular-nums}
.hc-chenh span{display:block;margin-top:3px;color:#5b6b73}
.hc-chenh span[lang=en]{color:#8a9a9f}

.hc-sect{margin:20px 0 4px;font-size:15px;color:var(--then)}
.hc-nhan{display:block;margin:12px 0 4px;font-size:12.5px;color:#5b5b5b}
.hc-sua h3{margin:8px 0 2px;font-size:17px;color:var(--then)}
.hc-sua input[type=number]{width:100%;min-height:46px;padding:9px 12px;font-size:16px;
  border-radius:10px;border:1px solid #D9CFBA;background:#fff;color:#1b1b1b}
.hc-tick{display:flex;align-items:center;gap:9px;margin:12px 0;font-size:13.5px;
  min-height:44px}
.hc-tick input{width:22px;height:22px}

.hc-chips{display:flex;flex-wrap:wrap;gap:7px;margin:6px 0}
.hc-chip{min-height:40px;padding:8px 13px;border-radius:20px;font-size:13px;
  border:1px solid #D9CFBA;background:#fff;color:#1b1b1b;cursor:pointer}
.hc-chip.on{background:var(--then);color:var(--diep);border-color:var(--then)}

/* Lỗi CHẶN và lỗi ĐÁNG XEM LẠI phải trông khác nhau: một cái khoá nút
   Lưu, một cái không. Cùng màu là mời người ta bỏ qua cả hai. */
.hc-loi{margin:12px 0;padding:9px 12px;border-radius:8px;font-size:13px;
  background:#FBF3E3;border-left:3px solid var(--dong)}
.hc-loi.chan{background:#FBEFEA;border-left-color:var(--son)}
.hc-loi p{margin:0 0 4px}
.hc-loi p:last-child{margin-bottom:0}
.hc-loi span[lang=en]{display:block;font-size:11.5px;color:#8a8a8a}

#v-hochieu .btn{width:100%;margin-top:10px;min-height:50px}
#v-hochieu .btn.pri[disabled]{opacity:.4;pointer-events:none}

/* Dấu "khách tự ghi" nhạt hơn dấu "người bán đã đọc": hai mức bằng chứng
   khác nhau thì không được trông giống nhau. */
.pt-dau.nhe{background:rgba(245,240,228,.07);border-color:rgba(245,240,228,.22)}
.pt-dau.nhe time{color:rgba(245,240,228,.5)}

/* ── Deal Recorder, quán tự thêm, Local Compass, ứng xử ──────────────── */
#v-ghikeo{position:fixed;inset:0;z-index:76;overflow-y:auto;
  background:var(--then);color:var(--diep);
  padding:0 var(--pad-x) calc(24px + var(--safe))}
#v-ghikeo[hidden]{display:none}
.gk-bar{display:flex;justify-content:flex-end;padding:10px 0;position:sticky;top:0;
  background:var(--then);z-index:2}
.gk-h{font-size:22px;margin:4px 0 6px}
.gk-sub,.gk-priv,.gk-note{font-size:14px;line-height:1.45;opacity:.85;margin:0 0 12px}
.gk-lab{display:block;font-size:14px;margin:14px 0 6px;opacity:.9}
.gk-in{width:100%;min-height:48px;padding:10px 12px;font-size:16px;border-radius:10px;
  border:1px solid rgba(201,162,39,.45);background:rgba(245,240,228,.08);color:inherit}
#v-ghikeo .btn{width:100%;min-height:52px;margin-top:10px}
.gk-mic.on{outline:3px solid var(--vang, #c9a227)}
.gk-chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.gk-chip{min-height:48px;padding:8px 14px;border-radius:12px;text-align:left;
  border:1px solid rgba(201,162,39,.55);background:rgba(245,240,228,.08);color:inherit}
.gk-chip small{display:block;opacity:.75;font-size:12px}
.gk-warn{font-size:14px;margin:8px 0;color:#e8a33d}
.gk-ok{font-size:15px;margin:10px 0 0;color:#7fd18b}
.gk-card{margin-top:18px;padding:16px;border-radius:16px;
  border:2px solid rgba(201,162,39,.6);background:rgba(245,240,228,.06)}
.gk-k{margin:0;font-weight:600}
.gk-k small{font-weight:400;opacity:.8}
.gk-amt{font-size:26px;font-weight:700;margin:10px 0 4px;line-height:1.25}
.gk-dv{margin:0 0 8px;opacity:.9}
.gk-read{display:flex;flex-direction:column;gap:6px;margin:12px 0 4px}
#sheet .gk-lab{color:inherit}
#sheet .gk-in{border:1px solid var(--line, #cdbf9a);background:transparent;color:inherit}
.ux-list{margin:0;padding-left:18px;line-height:1.5}
.ux-list li{margin:3px 0}
details.compass{margin-top:10px;padding:10px 12px;border-radius:12px;
  border:1px solid var(--line, #cdbf9a)}
details.compass summary{cursor:pointer;min-height:44px;display:flex;flex-wrap:wrap;
  align-items:center;gap:8px}
details.compass summary small{opacity:.7}

/* ═══ Đánh giá Google trên thẻ quán ═══ */
.grate { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.grate-n { font: 600 22px/1 var(--disp); color: var(--then); }
.grate-t { font-size: 13px; color: var(--muted, #5b6b66); }
.grate-l { margin-left: auto; font-size: 13px; color: var(--ngoc); text-decoration: underline; text-underline-offset: 2px; }

/* ═══ Đổi mật khẩu trong tab Bạn ═══ */
.pw-box { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.pw-h { font: 600 15px/1.2 var(--disp); color: var(--then); margin: 0 0 8px; }

/* ═══ Chuyển tab và chuyển khối: trượt nhẹ theo chiều, các khối hiện lần lượt ═══ */
@keyframes trIn { from { opacity: 0; transform: translateX(calc(var(--dir, 1) * 22px)); } to { opacity: 1; transform: none; } }
@keyframes trUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.view.tr-in { animation: trIn .34s cubic-bezier(.22,.61,.36,1) both; }
.view.tr-in > .pad > * { animation: trUp .44s cubic-bezier(.22,.61,.36,1) both; }
.view.tr-in > .pad > :nth-child(2) { animation-delay: .04s; }
.view.tr-in > .pad > :nth-child(3) { animation-delay: .08s; }
.view.tr-in > .pad > :nth-child(4) { animation-delay: .12s; }
.view.tr-in > .pad > :nth-child(n+5) { animation-delay: .16s; }
@media (prefers-reduced-motion: reduce) {
  .view.tr-in, .view.tr-in > .pad > * { animation: none; }
}

/* ═══ Trợ lý: trống đồng giữa màn, hiệu ứng mở/đóng, tin nhắn và lỗi ═══ */
.tlpanel.tl-open { animation: tlSheetIn .34s cubic-bezier(.22,.61,.36,1) both; }
.tlpanel.tl-closing { animation: tlSheetOut .24s cubic-bezier(.4,0,1,1) both; }
@keyframes tlSheetIn { from { opacity: 0; transform: translateY(24px) scale(.985); } to { opacity: 1; transform: none; } }
@keyframes tlSheetOut { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(24px) scale(.985); } }
.tlpanel .tlhead { animation: tlFadeDown .4s .05s cubic-bezier(.22,.61,.36,1) both; }
@keyframes tlFadeDown { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

.tlava { overflow: hidden; background: var(--giay); border: 1px solid var(--vien-in); }
.tlava img { width: 100%; height: 100%; object-fit: contain; padding: 3px; }

/* Trống đồng ở giữa khi chưa có câu hỏi; xoay rất chậm, tắt khi người dùng giảm chuyển động. */
.tlhero { flex: 1 1 auto; display: grid; place-items: center; min-height: 200px; pointer-events: none;
  animation: tlHeroIn .6s .1s cubic-bezier(.22,.61,.36,1) both; }
.tlhero img { width: min(70vw, 260px); aspect-ratio: 1; object-fit: contain; opacity: .95;
  animation: tlSpin 90s linear infinite; }
@keyframes tlHeroIn { from { opacity: 0; transform: scale(.92); } to { opacity: 1; transform: none; } }
@keyframes tlSpin { to { transform: rotate(360deg); } }

.tlmsg { animation: tlMsgIn .32s cubic-bezier(.22,.61,.36,1) both; }
@keyframes tlMsgIn { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }
.tlmsg.err { border-color: rgba(176,32,26,.35); background: #FBEDE7; }

/* Ba chấm nhấp nháy khi đang trả lời. */
.tlthink { display: inline-flex; gap: 5px; align-items: center; padding: 4px 2px; }
.tlthink i { width: 7px; height: 7px; border-radius: 50%; background: var(--muc-nhat); display: block;
  animation: tlDot 1.1s ease-in-out infinite; }
.tlthink i:nth-child(2) { animation-delay: .15s; }
.tlthink i:nth-child(3) { animation-delay: .3s; }
@keyframes tlDot { 0%, 80%, 100% { opacity: .25; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-4px); } }

.tlretry { margin-top: 8px; min-height: 36px; padding: 0 14px; border-radius: 18px; border: 1px solid var(--line);
  background: #fff; color: var(--then); font: 600 13px/1 var(--body); cursor: pointer; }
.tlretry:focus-visible { outline: 2px solid var(--dong); outline-offset: 2px; }

.tlchip { transition: transform .18s cubic-bezier(.22,.61,.36,1), background .18s; }
.tlchip:active { transform: scale(.96); }
.tlsend { transition: transform .18s cubic-bezier(.22,.61,.36,1); }
.tlsend:active { transform: scale(.92); }

/* Nút nổi: xuất hiện mềm, nhấn thì co lại. */
.tlfab { animation: tlFabIn .5s .3s cubic-bezier(.22,.61,.36,1) both; }
.tlfab:active { transform: scale(.93); }
@keyframes tlFabIn { from { opacity: 0; transform: translateY(10px) scale(.9); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .tlpanel.tl-open, .tlpanel.tl-closing, .tlpanel .tlhead, .tlhero, .tlhero img,
  .tlmsg, .tlthink i, .tlfab { animation: none; }
}
