/* ══════════════════════════════════════════════════════════════════════════
   NSyS · NAMVINI — BẢN MOBILE
   Chuẩn thiết kế: iPhone 15 Pro Max, 430 x 932 CSS px, có safe-area.

   VÌ SAO LÀ TỆP RIÊNG, KHÔNG PHẢI CSS ĐÈ LÊN BẢN DESKTOP
   ──────────────────────────────────────────────────────
   ĐÃ CẮN 13/08/2026. Lượt đầu tôi bọc DOM desktop vào bốn tab rồi gọi đó là
   bản mobile. Người dùng nói đúng: "mới chỉ giãn dòng để nắn về mobile thôi
   chứ có design gì đâu... bạn vẽ layout rõ đẹp nhưng lại dùng bản cũ để sửa".

   Bản trước nữa còn tệ hơn: 57 lần !important để ẨN CỘT — nén desktop bằng
   cách xoá bớt, người dùng mất thông tin mà không được đổi lại gì. Và tôi
   làm mất XEM CHART, thứ v6 vốn làm rất tốt.

   Bảng desktop có 8-9 cột. Không có cách nào nắn 9 cột vào 430px mà còn đọc
   được; mọi phép nắn đều là xoá. Điện thoại cần MỘT HÌNH THỨC KHÁC: hàng hai
   dòng, chạm để mở tờ chi tiết, chart toàn màn hình.

   Đây KHÔNG phải bản sao logic. Số vẫn do api.feed() tính, chart vẫn do
   nscOpen() vẽ. Chỉ CÁCH BÀY là mới — và đó đúng là thứ phải mới.
   ══════════════════════════════════════════════════════════════════════════ */

body.view-mobile{padding:0;margin:0;background:#08090B}

/* ══════════════════════════════════════════════════════════════════════════
   BỎ ĐỘ TRỄ ~300ms CỦA MỌI CÚ CHẠM.  [THÊM 24/08/2026]
   ══════════════════════════════════════════════════════════════════════════

   Chủ hệ nói tờ trượt "chậm". Đo ra thì mã chạy 0,6 ms và nội dung điền sau
   17 ms — không có gì để tối ưu. Thủ phạm nằm ngoài mã:

       viewport   width=device-width, initial-scale=1.0   -> KHÔNG khoá phóng to
       touch-action khai ở 4 chỗ: #nsc-grip · .nsc-head · .nsc-stage · .nsc-find
       các hàng CHẠM ĐƯỢC (.mb-r · .mb-tab · .mo-chart · .dong · .nsc-tl
       · .nsc-pb)                                          -> KHÔNG khai chỗ nào

   Còn cho phép chạm-hai-lần-để-phóng-to thì sau MỖI cú chạm trình duyệt phải
   CHỜ xem có cú thứ hai không rồi mới sinh `click`. Đó là ~300 ms trễ THUẦN
   TUÝ — không một dòng mã nào của ta chạy trong quãng ấy.

   `17 ms + 300 ms = 317 ms`. **95% thời gian cảm được là trình duyệt đang chờ.**

   ── VÌ SAO KHÔNG DÙNG `user-scalable=no` ───────────────────────────────
   Cách ấy nghe gọn hơn (một chữ trong thẻ `meta`, chữa cả trang) nhưng SAI
   hai lần:
     ① Nó tắt phóng to của NGƯỜI DÙNG. Ai cần phóng để đọc thì mất khả năng
        ấy — đổi một lỗi tốc độ lấy một lỗi tiếp cận.
     ② Safari trên iOS **BỎ QUA** `user-scalable=no` từ iOS 10, đúng vì lý do
        ①. Nên trên chính thiết bị đang có vấn đề, nó không làm gì cả.

   `touch-action:manipulation` nói đúng điều cần nói: phần tử NÀY không có
   nghĩa gì cho chạm-hai-lần, nên bắn `click` ngay. Phóng to bằng chụm hai
   ngón vẫn nguyên vẹn.

   ── VÌ SAO QUÉT THEO LOẠI, KHÔNG LIỆT KÊ TÊN ──────────────────────────
   `button, a, [onclick]` phủ mọi thứ chạm được hiện có VÀ mọi thứ thêm sau
   này. Liệt kê sáu tên lớp là hẹn một lỗi cho cái thứ bảy — và không ai nhớ
   quay lại đây khi thêm nó.

   ── BỐN CHỖ ĐÃ KHAI `touch-action` KHÔNG BỊ ĐỤNG ──────────────────────
   `touch-action` tính theo CẢ CHUỖI tổ tiên, và giá trị hẹp hơn thắng:
       `.nsc-stage` · `#nsc-grip`  `none`    — hẹp nhất, giữ nguyên pan/pinch của chart
       `.nsc-head`                 `pan-y`   — tập con của `manipulation`
       `.nsc-find`                 `auto`    — luật riêng, khai sau
   Nên luật này KHÔNG nới lỏng chỗ nào đang siết, và KHÔNG siết chỗ nào đang
   cần nới. Có bài kiểm canh đúng bốn chỗ ấy.

   ⚠ `manipulation` KHÔNG cấm cuộn hay chụm — nó chỉ bỏ chạm-hai-lần. Cử chỉ
   vuốt-xuống-đóng vừa làm hôm nay nhờ đó còn nhạy hơn.
   ══════════════════════════════════════════════════════════════════════════ */
body.view-mobile button,
body.view-mobile a,
body.view-mobile [onclick]{touch-action:manipulation}
body.view-mobile #app,
body.view-mobile #hdrBrandRow{display:none!important}
/* ── THANH CHỌN NGÀY: ẨN SẴN, XỔ KHI CHẠM — [SỬA 14/08/2026] ──────────────
   Người dùng: *"khi chuyển sang giao diện mobile mới, bạn bỏ qua phần xem
   lại ngày quá khứ… bản desktop vẫn ok"*.

   Trước đây `#hdrDateRow` nằm CHUNG luật `display:none` với `#app` và
   `#hdrBrandRow`. Ba thứ ấy đều thuộc vỏ desktop nên gộp một luật trông rất
   hợp lý — nhưng hai cái kia là VỎ, còn cái này là CÔNG NĂNG. Gộp chúng làm
   một là xoá mất một việc người dùng vẫn cần, và không ai định bỏ nó.

   Nay tách ra: vẫn ẩn mặc định (390px không đủ chỗ cho một thanh luôn hiện),
   nhưng chạm vào ngày ở dải đỉnh là xổ ra. Dùng LẠI đúng thanh của desktop —
   không dựng bản thứ hai, nên `#dgo`/`#dnow`/`#dpick` giữ nguyên tay bấm đã
   nối ở `khung.html`, và câu "đang xem phiên nào" vẫn chỉ có MỘT đường trả
   lời (`_NGAY_XEM`). */
body.view-mobile #hdrDateRow{display:none!important}
/* ── THANH XEM LẠI — [SỬA 20/08/2026, LƯỢT HAI] ──────────────────────────
   Chủ hệ, lần hai: *"Bạn càng làm thì thanh ngày tháng hạ xuống càng bị che
   bởi banner trên cùng, sửa lại."*

   LƯỢT TRƯỚC tôi tính TAY công thức `env()+34px`, làm tròn `env()+40px` —
   và VẪN THIẾU. Nguyên nhân chính xác không quan trọng bằng bài học: **một
   con số tính tay đã sai một lần thì tính tay lần nữa không có gì bảo đảm
   đúng hơn** — nó chỉ thay một số đoán bằng một số đoán khác.

   NAY `top` LẤY THẲNG `--mb-dinh` — biến CSS này đã khai TỪ TRƯỚC (dấu vết
   một ý định cũ: đo động rồi gán bằng JS) nhưng CHƯA TỪNG được đặt, nên nó
   luôn rơi về dự phòng. `mobile.js::_mbDoDinh()` nay ĐO THẬT chiều cao
   `.mb-cong` bằng `getBoundingClientRect()` và gán vào biến này mỗi lượt vẽ
   — đúng bất kể nội dung dài ngắn, có ATO hay không, máy nào, cỡ chữ hệ
   thống ra sao. Dự phòng `calc(env()+40px)` GIỮ NGUYÊN, chỉ dùng khi JS
   chưa kịp chạy (một khung hình đầu tiên, hiếm khi người dùng bấm kịp). */
body.view-mobile.mb-ngay-mo #hdrDateRow{
  display:flex!important;position:fixed;
  top:var(--mb-dinh, calc(env(safe-area-inset-top,0px) + 40px));left:0;right:0;
  z-index:60;background:#0B0D10;border-bottom:1px solid #1C1D21;
  padding:10px 12px;gap:8px;justify-content:center;flex-wrap:wrap}
/* Vùng chạm 44px cho mọi ô nhập và nút — sàn của iOS. Thanh gốc dựng cho
   chuột nên các ô chỉ cao ~28px. */
body.view-mobile.mb-ngay-mo #hdrDateRow input[type=text],
body.view-mobile.mb-ngay-mo #hdrDateRow button,
body.view-mobile.mb-ngay-mo #hdrDateRow label{min-height:40px}
body.view-mobile.mb-ngay-mo #hdrDateRow #dd,
body.view-mobile.mb-ngay-mo #hdrDateRow #dm{width:46px;font-size:15px}
body.view-mobile.mb-ngay-mo #hdrDateRow #dy{width:64px;font-size:15px}
/* Ngày ở dải đỉnh nay là NÚT — cho thấy nó bấm được, không để trông như
   chữ chết. Gạch chân mờ + vùng chạm rộng hơn chữ. */
body.view-mobile .mb-cong s.ngay{text-decoration:none;cursor:pointer;
  padding:4px 6px;margin:-4px -6px;border-bottom:1px dashed #4A4D55;
  -webkit-tap-highlight-color:transparent}
body.view-mobile.mb-ngay-mo .mb-cong s.ngay{border-bottom-color:var(--gold);
  color:var(--gold)}
/* HAI Ô NỔI CỦA BẢN DESKTOP che mất thanh tab.
   `#nsc-idxbadge` (điểm VN-Index) và `#nsc-seek` (tra mã) đều
   `position:fixed; bottom:14px` — đúng chỗ thanh tab ngồi. Trên máy tính
   chúng hữu ích; trên 430px chúng đè lên đường đi lại chính. Ẩn hẳn: điểm
   VN-Index đã có ở tab THỊ TRƯỜNG với cỡ chữ lớn hơn nhiều, và tra mã thuộc
   về trình xem chart chứ không phải màn hình chính.

   [SỬA 21/08/2026] TÁCH ĐÔI — chủ hệ đòi lại RIÊNG nút tra mã:
   *"bổ sung thêm nút tra mã luôn nằm ở vị trí trên tab Thị trường, góc
   dưới màn hình bên tay trái... trên bản desktop vẫn còn nhưng không hiểu
   sao bản mobile bị mất."* Chính luật này là chỗ "mất" — không phải thanh
   tab đè, mà `display:none!important` ẩn hẳn.

   `#nsc-idxbadge` GIỮ NGUYÊN ẩn: lý do gốc ở trên vẫn đúng nguyên vẹn
   (điểm VN-Index đã có sẵn ở tab THỊ TRƯỜNG, cỡ chữ lớn hơn hẳn) — chủ hệ
   chỉ xin lại nút tra mã, không xin badge.
   `#nsc-seek` bỏ ẩn, và ĐẨY LÊN TRÊN thanh tab (`chart.css`, luật
   `body.view-mobile #nsc-seek{bottom:calc(74px + …)}`) để không đè lên
   đường đi lại chính — giải quyết đúng mối lo đã ghi ở đoạn trên, thay vì
   ẩn đi. */
body.view-mobile #nsc-idxbadge{display:none!important}
body.view-mobile #mb-app{display:block}
#mb-app{display:none}

/* DẢI CỔNG · ghim đỉnh. Trạng thái cổng quyết định mọi việc ở bốn tab, nên
   nó phải thấy được từ bất kỳ đâu. Mở xanh, đóng vàng, cầu dao đỏ. */
.mb-cong{position:sticky;top:0;z-index:40;
  padding:calc(env(safe-area-inset-top,0px) + 9px) 16px 9px;
  display:flex;align-items:center;justify-content:space-between;
  font-family:var(--mono);font-size:11.5px;letter-spacing:.11em;
  background:#0F2418;border-bottom:1px solid #1C4230;color:var(--safe)}
.mb-cong.warn{background:#241E0F;border-bottom-color:#42351C;color:var(--watch)}
.mb-cong.danger{background:#241213;border-bottom-color:#431E1F;color:var(--danger)}
.mb-cong s{text-decoration:none;opacity:.55;font-size:11px;margin-left:auto}
/* CHIP ATO — chỉ số đang giữ ở phiên trước, giá vị thế vẫn sống.
   Cam như `.mb-canh`: cam là thứ ĐANG TỚI, đỏ dành cho thứ ĐÃ xảy ra.
   `margin-left:auto` ở `s` ghim ngày sang phải, nên chip ngồi sát tên hệ
   thống thay vì bị `space-between` đẩy ra giữa. */
/* ── CHIP ATO/ATC + ĐỒNG HỒ — [SỬA 06/09/2026] ─────────────────────────
   Chủ hệ: *"ATO / HH:MM:SS · căn vào chính giữa banner, đúng vị trí của
   chip hiện tại."*

   Hai dòng trong MỘT chip: tên phiên trên, giờ dưới. `display:inline-flex`
   + `column` giữ nguyên vị trí và nền của chip cũ — không dựng phần tử thứ
   hai cạnh nó, vì thế là đổi cả bố cục banner cho một tính năng nhỏ.

   Giờ nhỏ hơn tên một bậc và mờ hơn: tên phiên là TIN, giờ là thứ để đối
   chiếu. `tabular-nums` để sáu chữ số không nhảy ngang mỗi giây — không có
   nó thì `1` hẹp hơn `8` và cả chip giật liên tục. */
.mb-cong i.ato{font-style:normal;font-family:var(--mono);
  display:inline-flex;flex-direction:column;align-items:center;gap:1px;
  letter-spacing:.12em;padding:3px 8px;border-radius:4px;line-height:1.15;
  background:#20180E;border:1px solid #4A3116;color:var(--risk)}
.mb-cong i.ato b{font-size:9.5px;font-weight:600;letter-spacing:.12em}
.mb-cong i.ato s{font-size:9px;text-decoration:none;opacity:.78;
  letter-spacing:.06em;font-variant-numeric:tabular-nums}

/* Đệm đáy phải LỚN HƠN thanh tab, nếu không hàng cuối nằm dưới nó và không
   ai cuộn tới được — hỏng câm, vì trang vẫn cuộn bình thường.
   [SỬA 14/08/2026] 80 -> 96px: thanh tab cao từ ~44 lên 60px (xem `.mb-tab`).
   Đây là CẶP RÀNG BUỘC: đổi chiều cao tab mà quên dòng này là che mất hàng
   cuối của cả bốn tab. */
/* `overflow-x:clip` CHỨ KHÔNG `hidden` — cắt 18px mà tấm mới trượt vào.

   `hidden` thì CSS ÉP trục còn lại thành `auto`, biến `.mb-than` thành khung
   cuộn riêng và cướp luôn cuộn dọc của cả trang. `clip` không ép, không tạo
   khung cuộn — đúng thứ cần ở đây. Xem `mobile.js::mbTab`. */
.mb-than{padding:0 16px calc(env(safe-area-inset-bottom,0px) + 96px);overflow-x:clip}
.mb-tsec{display:none}
/* ĐỔI TAB CÓ HIỆU ỨNG — [THÊM 15/08/2026].
   Người dùng: *"đã swipe được và hiện rất nhanh, nhưng cảm giác hơi giật
   cục, cần có hiệu ứng cho mượt hơn"*.

   `animation` chứ không `transition`: tấm đi từ `display:none` sang `block`,
   mà `transition` không chạy trên phần tử vừa được hiện. Keyframe thì chạy —
   và tự khởi động lại mỗi lần lớp `.on` được gắn, nên không cần mẹo ép vẽ lại.

   190ms · ease-out: đủ để mắt bắt được chiều đi, chưa đủ để tay phải chờ.
   Dịch 18px chứ không cả màn — trượt nguyên trang làm mỗi lần đổi tab tốn
   một nhịp thở, mà bảng này người ta lật qua lật lại liên tục.

   `opacity` bắt đầu ở .35 chứ không 0: nội dung không loé từ đen: */
.mb-tsec.on{display:block;animation:mbVaoTab .19s cubic-bezier(.22,.61,.36,1)}
@keyframes mbVaoTab{
  from{opacity:.35;transform:translate3d(var(--mb-tu,0),0,0)}
  to{opacity:1;transform:none}
}
/* Người dùng khai muốn ít chuyển động thì bỏ hẳn — đây là thiết lập trợ
   năng của hệ điều hành, không phải sở thích trang trí.

   [SỬA 25/08/2026] Gộp luôn hai keyframe của THANH TAB vào đây thay vì mở
   một `@media` thứ hai ở cuối tệp. Hai khối cùng điều kiện là hai chỗ phải
   nhớ sửa, và lần quên là một hiệu ứng lặng lẽ vẫn chạy với người đã tắt
   chuyển động. */
@media (prefers-reduced-motion: reduce){
  .mb-tsec.on{animation:none}
  .mb-tab button[aria-current="true"],
  .mb-tab button[aria-current="true"] i,
  .mb-tab button[aria-current="true"] span{animation:none}
}

.mb-gate{padding:26px 0 20px;border-bottom:1px solid #15171A}
.mb-gate .w{font-family:var(--serif);font-size:66px;line-height:.94}
.mb-gate .lb{margin-top:7px;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.14em;color:#4E4D49}
.mb-gate .ln{margin-top:15px;display:flex;gap:10px;align-items:flex-start}
.mb-gate .ln i{font-style:normal;font-family:var(--mono);font-size:11px;flex:0 0 auto}
.mb-gate .ln p{margin:0;font-size:13.5px;line-height:1.5;color:#C3C6CB}

/* VN-INDEX — chỉ số và % TRÊN CÙNG MỘT DÒNG, căn giữa.
   Tách % xuống dòng riêng làm nó trông như một số độc lập, trong khi nó là
   thuộc tính của chính chỉ số ngay bên cạnh. */
/* ── BĂNG CHỈ SỐ HAI CỘT — VN-INDEX · VN30F1M ─────────────────────────────
   [SỬA 14/08/2026] Người dùng vẽ tay bố cục và yêu cầu áp cho cả hai bản.
   Vách ngăn `<i>` rộng 1px, cùng lối `.mb-tab` dùng — mắt thấy HAI cụm chứ
   không thấy bốn con số dàn hàng.
   Cỡ chữ 26px thay vì 32px của bản một cột: hai cụm chia đôi bề ngang, giữ
   32px là `1.731,06` tràn ra ngoài ở máy 320px. */
.mb-idx2{padding:18px 0 16px;border-bottom:1px solid #15171A;
  display:grid;grid-template-columns:1fr 1px 1fr;align-items:start}
.mb-idx2 > i{background:#15171A;align-self:stretch}
.mb-idx2 .o{text-align:center;padding:0 4px;min-width:0}
.mb-idx2 .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;color:#4E4D49}
.mb-idx2 .v{margin-top:7px}
/* ĐIỂM SỐ chỉ số — màu TRUNG TÍNH, không theo tăng giảm. Giống `hero-px` của
   bản desktop (`var(--ink)`). Chiều tăng/giảm đã do `%` và số điểm ngay dưới
   nói rõ; tô cả con số lớn nữa là ba thứ cùng nói một điều, và con số lớn
   nhất màn hình đổi màu liên tục thì mắt bị kéo về đó thay vì về nội dung. */
.mb-idx2 .v b{font-family:var(--mono);font-size:26px;font-weight:400;line-height:1;
  letter-spacing:-.01em;color:#E8E6DF}
.mb-idx2 .p{margin-top:5px;display:flex;align-items:baseline;
  justify-content:center;gap:6px;flex-wrap:wrap}
.mb-idx2 .p s{text-decoration:none;font-family:var(--mono);font-size:13px}
.mb-idx2 .p u{text-decoration:none;font-family:var(--mono);font-size:11px;opacity:.8}

.mb-idx{padding:18px 0 16px;border-bottom:1px solid #15171A;text-align:center}
.mb-idx .k{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;color:#4E4D49}
.mb-idx .v{margin-top:7px;display:flex;align-items:baseline;justify-content:center;gap:10px}
.mb-idx .v b{font-family:var(--mono);font-size:32px;font-weight:400;line-height:1}
.mb-idx .v s{text-decoration:none;font-family:var(--mono);font-size:14px}

/* HAI Ô SỐ — mỗi ô có DÒNG PHỤ mang ngữ cảnh, đúng như bản desktop:
   khối lượng kèm %VMA20, B50 kèm số mã. Thiếu dòng phụ thì con số mất nghĩa:
   151,7M là nhiều hay ít? 33,8% của bao nhiêu mã? */
.mb-o2{display:grid;grid-template-columns:1fr 1fr;gap:1px;
  background:#15171A;border-bottom:1px solid #15171A}
.mb-o2>div{background:#08090B;padding:15px 4px 16px;text-align:center}
.mb-o2 .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;color:#4E4D49}
.mb-o2 .v{margin-top:6px;font-family:var(--mono);font-size:21px}
.mb-o2 .p{margin-top:4px;font-family:var(--mono);font-size:10.5px;color:#5A5954}

/* BA Ô — thành tích của trạng thái (profit factor · tỷ lệ thắng · crash20) */
.mb-o3{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;
  background:#15171A;border-bottom:1px solid #15171A}
.mb-o3>div{background:#08090B;padding:14px 2px 15px;text-align:center}
.mb-o3 .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;color:#4E4D49}
/* [SỬA 20/08/2026] 19px -> 22px. Chủ hệ: *"điểm rủi ro và B50 nhìn có vẻ
   hơi bé, kém cân đối"*.

   ĐO: `.v.to` (S7) 27px so `.v` 19px = tỷ lệ 1,42. Phân cấp là ĐÚNG — số
   trạng thái là tiêu đề của cả khối — nhưng 1,42 đẩy hai ô kia xuống hạng
   phụ, trong khi RISK SCORE và B50 cũng là số phải liếc là thấy. 22px cho
   tỷ lệ 1,23: vẫn rõ ai là tiêu đề, mà hai ô kia đọc được ngang hàng.

   CHỖ CÓ VỪA KHÔNG: ô rộng (390 − 2 khe)/3 ≈ 129px, trừ đệm còn ~125px.
   `48.4%` là 5 ký tự mono, ở 22px ≈ 66px. Dư nửa ô. */
.mb-o3 .v{margin-top:6px;font-family:var(--mono);font-size:22px}
/* Dòng phụ — tab THỊ TRƯỜNG không dùng (ba ô thành tích không có ngữ cảnh
   nào để thêm), tab VỊ THẾ thì có: `% NAV` và `chỗ trống`. `min-height` giữ
   ba ô cao bằng nhau kể cả khi một ô bỏ trống dòng này. */
.mb-o3 .p{margin-top:4px;font-family:var(--mono);font-size:10px;
  color:#5A5954;min-height:13px}

/* ── BIẾN THỂ TAB 1: TRẠNG THÁI · RISK SCORE · B50 ────────────────────────
   [SỬA 14/08/2026] Ba ô cũ (profit factor · tỷ lệ thắng · crash20) là THÀNH
   TÍCH LỊCH SỬ, không đổi trong phiên. Ba ô mới là TÌNH TRẠNG HÔM NAY.

   `.to` cho ô trạng thái: người dùng nói "S4 quan trọng nên có thể làm to
   hơn". 27px so 19px của hai ô kia — đủ để mắt rơi vào đó trước, mà không
   phá lưới ba cột đều nhau.

   Chỉ khai thêm MỘT lớp, không nhân bản `.mb-o3`: tab VỊ THẾ vẫn dùng
   `.mb-o3` trần, và hai bảng chung một lưới thì đổi bề rộng một lần là cả
   hai cùng theo. */
.mb-o3s .v.to{font-size:27px;line-height:1.05;letter-spacing:-.01em}
/* Tên trạng thái có thể dài ("Phân phối đỉnh") — cho phép xuống dòng thay vì
   tràn, và bỏ `min-height` cứng để ba ô tự cao bằng nhau theo lưới. */
.mb-o3s .p{line-height:1.3;white-space:normal}
/* ── Ô TRẠNG THÁI KHI CẤP RỦI RO ≥ 3 — VỆT NỀN, KHÔNG VIỀN ───────────────
   Chủ hệ hỏi có nên tô VIỀN màu rủi ro quanh ô. Ba lý do chọn nền:
     ① `.mb-o3` là lưới `gap:1px` — ba ô đã có vạch ngăn sẵn; viền quanh một
       ô sẽ chồng lên vạch ấy, trông như bảng vẽ hỏng chứ không như điểm nhấn
     ② viền bật/tắt làm xê dịch bố cục mỗi lần đổi cấp
     ③ con số đã đổi sang cam/đỏ; viền cùng màu là nói lần thứ hai

   Cùng nếp `.mb-vt5.canh/.cap` đã dùng cho hàng danh mục cần chú ý, và chú
   thích ở đó giải đúng bài toán này: nền thì không có mép cứng để dính vào
   chữ, và không chiếm một pixel nào trong lưới.

   `background-image` chứ KHÔNG `background`: `.mb-o3>div` khai
   `background:#08090B`, ghi đè cả cụm là mất nền ô và lộ màu vạch ngăn ra
   sau chữ.

   HAI SẮC PHẢI KHỚP `TIERBG[2]`/`TIERBG[3]` ở `khung.html`. Đây là bản sao
   — rgba không viết được từ hằng số CSS mà không dùng `color-mix` (chưa
   dám tin trên mọi máy). `test_khoi01_mau_cap.py` so từng kênh với hex gốc,
   nên hai bên không trôi khỏi nhau được. */
.mb-o3s > div.rui3{background-image:
  linear-gradient(180deg,transparent 38%,rgba(245,130,43,.13))}
.mb-o3s > div.rui4{background-image:
  linear-gradient(180deg,transparent 38%,rgba(245,69,58,.15))}

/* BẢN ĐỒ TRẠNG THÁI — dùng thẳng `renderStateMap()` của bản desktop, chỉ
   nắn lại cỡ chữ cho màn 430px. Không dựng bảng thứ hai. */
.mb-bando{margin-top:22px}
.mb-bando #sec-map{font-size:12px}
.mb-bando #sec-map span:nth-child(2){font-size:20px!important}
.mb-bando #sec-map span:nth-child(3){display:none}

/* ══════════════════════════════════════════════════════════════════════════
   THANH 20 PHIÊN — HAI CHẾ ĐỘ, Ô SÁNG LUÔN Ở CUỐI BÊN PHẢI  [SỬA 27/08/2026]
   ══════════════════════════════════════════════════════════════════════════
   Chủ hệ: *"chạm vào thanh là kích hoạt phần xem lịch sử này, di chuyển sang
   trái thì từng ngày được tô sáng ở vị trí cuối cùng, di đến ngày nào thì
   hiện ngày tháng của ngày đó lên khu vực giữa thanh để biết ngày đó đang
   được chọn, click vào ngày đó thì hiển thị phiên ngày đó."*

       NGHỈ   20 ô lấp kín bề ngang, ô sáng ở cuối — Y HỆT bản gốc
       KÉO    trọn lịch sử trượt qua, ô sáng VẪN ở cuối, nhãn ngày ở giữa

   ⛔ HAI LƯỢT TRƯỚC TÔI ĐẶT KIM Ở GIỮA, và chủ hệ bắt đúng cái giá của nó:
   *"2 lần thay đổi của bạn vừa rồi luôn không xem được 10 ngày cuối cùng."*
   Kim giữa cần đệm `calc(50% − nửa ô)` HAI BÊN, nên khi ô chọn về giữa thì
   nửa màn hình bên phải là đệm trống — mất đúng mười ngày đáng nhìn nhất.

   Neo mép PHẢI thì đệm chỉ cần một bên (trái), và trọn bề ngang dùng để bày
   19 ngày TRƯỚC ngày đang chọn — đúng thứ cần khi lần ngược lịch sử.

   `padding-left: calc(100% − ô)` là thứ cho ngày XA NHẤT cũng về được mép
   phải; không có nó thì chỉ hai mươi ngày cuối tới được vị trí ấy.

   ── BỀ RỘNG Ô ĐO TỪ MÀN HÌNH THẬT ───────────────────────────────────────
   `--o` do JS đặt (`_mbStripNoi`): 20 ô phải lấp KÍN bề ngang mà bề ngang
   mỗi máy một khác. Dùng chung cho CẢ HAI chế độ, nên ô không đổi cỡ khi
   sang kéo — mắt thấy thanh trượt ra, không thấy nó co giãn. */
.mb-strip{padding:16px 0;border-bottom:1px solid #15171A}
/* KHUNG CAO HƠN Ô — 34 so 26. Chỗ dư ấy để ô đang chọn nở ra mà không bị
   `overflow` của thanh cuộn xén mất đỉnh và đáy. */
.mb-strip .sc{position:relative;margin-top:11px;height:34px}
.mb-strip .r{display:block;overflow:hidden;height:34px}
.mb-strip .tr{display:flex;gap:3px;height:34px;align-items:center}
/* Ô CHIA ĐỀU, KHÔNG ĐO — [SỬA 27/08/2026].

   ⛔ ĐÃ CẮN. Chủ hệ: *"khi chuyển từ tab khác về tab thị trường thì nó không
   hiện đủ 20 ô luôn mà hiện thiếu vài ô rồi mới hiện đủ, cảm giác như cái lò
   xo nén lại rồi đẩy ra."*

   Bản trước để `flex:0 0 var(--o)` cho CẢ HAI chế độ, mà `--o` do JS đo
   `clientWidth` rồi đặt. Nhưng `.mb-tsec{display:none}` — tab đang ẩn thì bề
   ngang bằng 0, `doO()` bỏ qua, và `--o` KHÔNG BAO GIỜ được đặt:

       đang ở tab khác  ->  `W()` dựng lại khối 01 -> `.mb-strip` mới, mất
                            `--o` cũ -> `doO()` đo được 0 -> im lặng bỏ qua
       quay về tab 1    ->  ô rơi về `15px` dự phòng, hụt so với bề ngang
       một giây sau     ->  `W()` dựng lại lần nữa, lần này tab ĐANG HIỆN,
                            `doO()` đo đúng -> ô nở ra   <- CÁI LÒ XO

   Chế độ NGHỈ không cần đo gì cả: `flex:1 1 0` để trình duyệt chia đều phần
   còn lại sau 19 khe — đúng cách bản gốc làm (`flex:1`) và đúng lúc nào bố
   cục cũng đúng, kể cả khi tab vừa hiện ra.

   Chỉ chế độ KÉO mới cần bề rộng CỐ ĐỊNH (để cuộn và neo mép phải), và nó
   chỉ vào được bằng một cú chạm — tức lúc tab chắc chắn đang hiện. Đo ở đó
   thì không có ca nào đo phải số 0. */
.mb-strip .tr i{flex:1 1 0;height:26px;border-radius:2px;
  display:block;cursor:pointer;opacity:.72}
/* Ô SÁNG — phiên đang xem, ở chế độ nghỉ nó luôn là ô cuối bên phải. */
.mb-strip .tr i.moi{opacity:1;
  box-shadow:inset 0 0 0 1.5px rgba(240,237,232,.85)}

/* `proximity` CHỨ KHÔNG `mandatory` — [SỬA 28/08/2026].

   Chủ hệ: *"đôi khi muốn kéo lùi và tiến về xa cuộn chậm rất sốt ruột và
   mỏi tay."*

   `mandatory` buộc mọi lượt cuộn phải KẾT THÚC đúng một mốc neo, nên trình
   duyệt cắt đà trôi ngay ô kế tiếp: vuốt mạnh hay nhẹ đều đi được chừng ấy.
   Đó chính là cảm giác "đẩy mà không chạy".

   `proximity` chỉ hít về mốc KHI dừng lại gần một mốc — đà trôi giữ nguyên,
   nên vuốt mạnh đi xa, vuốt nhẹ đi gần, đúng như ngón tay bảo.

   Cái giá: chỗ dừng có thể lệch mốc vài pixel. Chấp nhận được, vì `oChonIdx`
   tìm ô GẦN NHẤT chứ không đòi ô phải khít, và nhãn ngày mới là thứ người ta
   đọc. */
.mb-strip.keo .r{overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x proximity;overscroll-behavior-x:contain;
  -webkit-overflow-scrolling:touch;scrollbar-width:none}
.mb-strip.keo .r::-webkit-scrollbar{display:none}
.mb-strip.keo .tr{padding-left:calc(100% - var(--o,15px))}
/* Chế độ KÉO khoá bề rộng ô — cần cho cuộn, cho nam châm, và cho phép neo
   mép phải. `--o` đúng bằng bề rộng mà `flex:1 1 0` vừa chia ở chế độ nghỉ,
   nên lúc chuyển sang kéo ô KHÔNG đổi cỡ: mắt thấy thanh trượt ra, không
   thấy nó co giãn. */
.mb-strip.keo .tr i{flex:0 0 var(--o,15px);scroll-snap-align:end}
/* Ô ĐANG CHỌN — chủ hệ: *"phóng to lên 1 chút chẳng hạn"*.

   `transform-origin:right` chứ không tâm ô: ô này luôn nằm SÁT MÉP PHẢI
   khung, nên nở từ tâm là nửa phần nở ra bị `overflow` xén mất. Nở về bên
   TRÁI thì nguyên vẹn, và nó lấn vào khe 3px chứ không che ô hàng xóm.

   `transform` chứ không `width`/`height`: đổi kích thước thật là bắt trình
   duyệt tính lại bố cục cả dải 3.400 ô, ngay giữa lúc cuộn — đúng chỗ giật
   khung hình dễ thấy nhất. */
.mb-strip.keo .tr i.chon{transform:scale(1.12,1.28);
  transform-origin:right center;opacity:1;position:relative;z-index:2;
  border-radius:3px;
  box-shadow:inset 0 0 0 1.5px rgba(240,237,232,.9),0 0 0 1px #0A0B0D;
  transition:transform .1s ease-out}

/* TRẠNG THÁI + RISK — một hàng ba phần. Mã trạng thái (S0..S10) là thứ
   người dùng tra trong bản đồ, nên nó phải hiện rõ chứ không chỉ có tên. */
.mb-st{display:flex;align-items:center;gap:12px;padding:16px 0;
  border-bottom:1px solid #15171A}
.mb-st .bx{width:46px;height:46px;flex:0 0 auto;border-radius:9px;
  border:1px solid;display:flex;align-items:center;justify-content:center}
.mb-st .bx b{font-family:var(--mono);font-size:17px;font-weight:400}
.mb-st .tx{min-width:0}
.mb-st .tx span,.mb-st .rs span{display:block;font-family:var(--mono);
  font-size:9.5px;letter-spacing:.13em;color:#4E4D49}
.mb-st .tx b{display:block;margin-top:3px;font-family:var(--mono);
  font-size:14px;color:#E8E6DF;font-weight:400}
.mb-st .rs{margin-left:auto;text-align:right;flex:0 0 auto}
.mb-st .rs b{font-family:var(--mono);font-size:26px;font-weight:400;line-height:1}
.mb-st .rs s{text-decoration:none;font-family:var(--mono);font-size:11px;color:#4E4D49}

/* CẢNH BÁO — dấu hiệu đã lên nòng, chưa nổ. Cam chứ không đỏ: đỏ dành cho
   thứ ĐÃ xảy ra, cam là thứ đang tới. */
/* [SỬA 16/08/2026] BỎ NỀN. Người dùng: *"chip dấu hiệu đến gần vẽ ko cần
   tô màu background (giống ở 04 mobile khi có dấu hiệu MA50 hoặc cắt lỗ
   đến gần, vẽ chỉ viền màu ko có màu background)"*.

   Khối này nói "ĐANG TIẾN GẦN" — tức mức NHẸ NHẤT trong hệ ba mức
   (`khung.html::.chip`). Mà nó lại là thứ duy nhất trong tab THỊ TRƯỜNG có
   nền đặc, nên nó hút mắt mạnh hơn cả những việc ĐANG xảy ra. Ngược mức.

   Viền cũng pha loãng từ `--risk` thay vì gõ `#3A2B16`: cùng luật với
   `.chip-1`, và không sinh thêm một mã hex cho một sắc đã có tên. */
.mb-canh{margin-top:12px;padding:10px 13px;border-radius:8px;
  background:none;border:1px solid color-mix(in srgb,var(--risk) 34%,transparent);
  display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.mb-canh b{font-family:var(--mono);font-size:11.5px;color:var(--risk);font-weight:400}
.mb-canh span{font-size:12.5px;color:#9A9892}

/* HÀNG TIÊU ĐỀ MANG CẢ BA THỨ — [SỬA 27/08/2026].

   Chủ hệ: *"sắp xếp lại cho thẳng hàng ô ngày tháng với 'hôm nay'… tốt nhất
   là thẳng hàng với dòng chữ '20 phiên gần nhất'."*

       20 PHIÊN GẦN NHẤT ......... [14/07/2026] [↺ HÔM NAY]

   Ô ngày TRƯỚC đây neo tuyệt đối `top:-26px` so với dải, tức lơ lửng giữa
   hai dòng — không thẳng hàng với gì cả. Nay nó là một phần tử flex bình
   thường của chính hàng này, nên nó thẳng hàng theo bố cục chứ không theo
   một con số dịch chuyển phải canh bằng mắt.

   `align-items:center` thay `baseline`: hàng này nay trộn chữ 10,5px với
   hai chip cao 22px, mà `baseline` của một `inline-flex` phụ thuộc dòng chữ
   đầu bên trong nó — một cơ chế đúng do may. Căn giữa thì không có gì để
   may rủi.

   `min-height` giữ hàng KHÔNG nhảy khi đổi chế độ: lúc nghỉ nó chỉ có hai
   dòng chữ ~13px, lúc kéo có hai chip 22px. */
.mb-strip .hh{display:flex;align-items:center;gap:8px;min-height:22px;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.13em;color:#4E4D49}
/* ══════════════════════════════════════════════════════════════════════════
   HAI CHIP CỦA CHẾ ĐỘ XEM LỊCH SỬ   [THIẾT KẾ LẠI 27/08/2026]
   ══════════════════════════════════════════════════════════════════════════
   Chúng làm HAI việc khác hẳn nhau, nên phải TRÔNG khác nhau:

       [14/07/2026]   ĐI TỚI ngày đang chọn   -> việc chính, tô vàng
       [↺ HÔM NAY]    QUAY VỀ phiên đang mở   -> lối thoát, xám nhạt

   Cùng sắc vàng thì mắt phải đọc chữ mới biết cái nào làm gì; khác sắc thì
   liếc là biết. Vàng là sắc HÀNH ĐỘNG của cả hệ (`--gold`), nên nó thuộc về
   ô ngày — thứ người ta kéo cả dải để tìm.

   ↺ (U+21BA) thay cho một chữ "về": một ký tự đọc được ở 10px, và nó nói
   "quay lại" mà không tốn bề ngang của một từ.

   Bo tròn hẳn (`999px`) để hai thứ này đọc là CHIP BẤM ĐƯỢC, tách khỏi các
   ô vuông của dải phía dưới — hình dạng cũng là một lời giải thích.

   `-webkit-tap-highlight-color` tắt lớp phủ xám của iOS: nó vẽ một hình chữ
   NHẬT lên trên chip bo tròn, và cú chạm nào cũng lộ ra góc vuông ấy. */
/* ══════════════════════════════════════════════════════════════════════════
   CỤM ĐIỀU KHIỂN PHIÊN — MỘT HÀNG RIÊNG   [THIẾT KẾ LẠI 28/08/2026]
   ══════════════════════════════════════════════════════════════════════════
   ⛔ BẢN TRƯỚC LÀ MỘT THẤT BẠI, VÀ LÝ DO TỆ HƠN TÔI TƯỞNG.

   Chủ hệ: *"3 phím previous và next quá bé, quá gần nhau và… quá xấu, nó
   không được thiết kế, nó chỉ xuất hiện cho có."*

   Truy ra: CSS cho hai nút ấy **chưa bao giờ được ghi**. Script vá lượt
   trước hỏng ở bước đầu (sai tệp) rồi dừng, nên phần CSS không chạy — mà
   tôi lại báo "xong" vì `pytest` xanh. Chủ hệ nhìn thấy NÚT MẶC ĐỊNH TRẦN
   của trình duyệt.

   Bài học: `pytest` xanh không chứng minh thứ mình vừa viết đã tới đĩa.
   Luật G của `luat/LUAT.md` nói đúng chuyện này — câu trả lời là một con số,
   không phải một màu xanh.

   Và kể cả có CSS, thiết kế cũ vẫn sai: tôi nhét ba nút vào hàng TIÊU ĐỀ —
   một hàng NHÃN cao 22px, chữ 10,5px. Đó không phải mặt điều khiển, đó là
   chỗ còn trống. Ngưỡng chạm được của Apple lẫn Google đều là 44px.

   ── HÀNG RIÊNG, VÀ BA THỨ THUỘC VỀ NHAU THÌ Ở CÙNG NHAU ────────────────
       [   ‹   ][    14/07/2026    ][   ›   ]

   Lùi · ngày đang chọn · tiến là MỘT việc: đi lại trong thời gian. Gộp thành
   một cụm liền khối thì mắt đọc một lần, và mỗi vùng chạm cao đủ 44px.

   Ô ngày ở GIỮA vì nó vừa là chỗ ĐỌC vừa là nút MỞ phiên — thứ được bấm
   nhiều nhất thì nằm chỗ ngón cái với tới dễ nhất. Hai mũi tên rộng 64px:
   đủ trúng khi cầm máy một tay, đủ xa nhau để không bấm nhầm nhau.

   Chỉ hiện ở chế độ kéo — chế độ nghỉ không có "phiên đang chọn" nào để mà
   lùi hay tiến. */
.mb-strip .dieu{display:none;margin-top:12px;gap:8px}
.mb-strip.keo .dieu{display:flex}
.mb-strip .dieu>*{height:44px;border-radius:4px;cursor:pointer;
  font-family:var(--mono);display:flex;align-items:center;
  justify-content:center;-webkit-tap-highlight-color:transparent}

/* MŨI TÊN — ô vuông 44×44, viền mảnh, nền chìm. Cùng ngôn ngữ với ô nhập
   ngày ở đầu trang (`#dd`/`#dm`/`#dy`): nền tối, viền một pixel, bo 4px.

   ⚠ KHÔNG gộp ba thứ thành một khối liền. Bản trước làm thế và trông như
   một thanh xám dài — chủ hệ: *"vẫn còn xấu chưa đạt yêu cầu"*. Hộp xem
   lại ngày đẹp hơn vì nó là những Ô RỜI có viền, mắt tách ra được ngay. */
.mb-strip .dh{flex:0 0 56px;font-size:22px;line-height:1;
  color:var(--ink-faint);background:var(--panel);
  border:1px solid color-mix(in srgb,var(--ink) 16%,transparent)}
.mb-strip .dh:active{color:var(--ink);
  background:color-mix(in srgb,var(--ink) 14%,transparent)}

/* Ô NGÀY — việc chính, nên nó là ô DUY NHẤT mang sắc vàng, đúng cách nút
   `XEM` của hộp xem lại ngày tự tách mình khỏi `HÔM NAY`. */
.mb-strip .nhan{flex:1 1 auto;font-size:15px;letter-spacing:.08em;
  line-height:1;white-space:nowrap;color:var(--gold);
  background:color-mix(in srgb,var(--gold) 12%,transparent);
  border:1px solid color-mix(in srgb,var(--gold) 45%,transparent)}
.mb-strip .nhan:active{background:color-mix(in srgb,var(--gold) 26%,transparent)}

/* ĐÃ NHẬN — giữ tới khi trang mới thay trang cũ.

   Đo 28/08: trang xem lại nặng 1,13 MB (429 KB sau nén gzip); máy chủ trả
   trong 69 ms nhưng điện thoại còn phải đọc và chạy chừng ấy JavaScript.
   Khoảng lặng sau cú bấm là CÓ THẬT, và `:active` tắt ngay khi nhấc tay —
   đúng lúc khoảng lặng bắt đầu. */
.mb-strip .dh.bam,.mb-strip .nhan.bam{color:var(--gold);
  background:color-mix(in srgb,var(--gold) 26%,transparent);
  border-color:color-mix(in srgb,var(--gold) 60%,transparent)}
/* HẾT ĐƯỜNG — bấm một nút không làm gì là cách nhanh nhất để người dùng
   thôi tin vào nút. */
.mb-strip .dh.tat{opacity:.28;pointer-events:none}

.mb-strip .goi{margin-left:auto;font-style:normal;letter-spacing:.06em;
  font-size:9.5px;color:#3A3D42;text-transform:none}

/* HÔM NAY — lối THOÁT, ở lại hàng tiêu đề. Không cùng loại việc với cụm
   trên: kia là ĐI LẠI trong lịch sử, đây là RA KHỎI lịch sử. */
.mb-strip .nay{display:none;align-items:center;gap:5px;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;line-height:1;
  border-radius:999px;cursor:pointer;white-space:nowrap;
  padding:5px 11px 5px 9px;color:var(--ink-faint);
  background:color-mix(in srgb,var(--ink) 5%,transparent);
  border:1px solid color-mix(in srgb,var(--ink) 16%,transparent);
  -webkit-tap-highlight-color:transparent}
.mb-strip .nay::before{content:"\21BA";font-size:11px;letter-spacing:0}
.mb-strip .nay:active{color:var(--ink-soft);
  background:color-mix(in srgb,var(--ink) 11%,transparent);
  border-color:color-mix(in srgb,var(--ink) 26%,transparent)}
.mb-strip.keo .nay{display:inline-flex}
.mb-strip.keo .goi{display:none}

/* [GỠ 13/08/2026] `.mb-bd` · `.mb-more` · `.mb-tin` đã xoá.
   `.mb-bd`/`.mb-more` là bản đồ tóm tắt ba nhóm giấu sau một nút — lớp thừa
   chen giữa người đọc và bảng thật; nay cuộn thẳng tới `renderStateMap()`.
   `.mb-tin` là bản tin, di sản v6 đã gỡ khỏi bản mobile. */
.mb-h{display:flex;align-items:baseline;gap:9px;padding:20px 0 11px}
.mb-h b{font-family:var(--mono);font-size:10px;color:var(--gold);font-weight:400}
.mb-h span{font-family:var(--serif);font-size:20px;color:#E8E6DF}
.mb-h em{margin-left:auto;font-style:normal;font-family:var(--mono);
  font-size:10px;letter-spacing:.1em;color:#4E4D49}

/* HÀNG MÃ · hai dòng, chạm cả hàng. 430px không đủ cho 9 cột. Hai dòng thì
   đủ cho 6 số mà chữ vẫn 15px và vùng chạm cao ~62px, trên ngưỡng 44px. */
.mb-row{display:block;width:100%;text-align:left;background:none;border:none;
  border-bottom:1px solid #15171A;padding:11px 2px 12px;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.mb-row:active{background:#0E1013}
.mb-row .t{display:flex;align-items:baseline;gap:10px}
.mb-row .tk{font-family:var(--mono);font-size:15.5px;color:#E8E6DF}
.mb-row .px{margin-left:auto;font-family:var(--mono);font-size:15.5px}
.mb-row .pc{font-family:var(--mono);font-size:12px;min-width:58px;text-align:right}
.mb-row .b{margin-top:5px;display:flex;align-items:baseline;gap:10px;
  font-family:var(--mono);font-size:11px;color:#5A5954}
.mb-row .b u{text-decoration:none;margin-left:auto;color:#8A8880}
.mb-row .b s{text-decoration:none;color:var(--gold);min-width:58px;text-align:right}

/* ── HÀNG WATCHLIST · NĂM CỘT ─────────────────────────────────────────────
   [SỬA 14/08/2026] Người dùng yêu cầu bố trí lại khối 03 trên mobile:
   "hiện tại đang là 3 cột và 1 dòng diễn giải ở dưới, mới: 5 cột và 1 dòng
   diễn giải ở dưới".

       MÃ    GIÁ      %       KL      KÍCH HOẠT
       STB   72.80   -0,41%   694K    75.70
       Man 5/8 · Supp 11/12 · đáy 52W +58,3% · còn 4,0%

   `grid` chứ không `flex`: năm cột phải THẲNG HÀNG giữa các mã, nếu không
   mắt phải dò lại từng dòng. `flex` của `.mb-row .t` căn theo nội dung nên
   mỗi hàng lệch một kiểu — đó là lý do bản cũ chỉ để được ba ô.

   Bề rộng: đo trên 390px (iPhone thường) trừ 32px đệm còn 358px. Cột MÃ cố
   định 46px, bốn cột số chia đều phần còn lại — đủ cho `-0,41%` và `694K` ở
   12px mono mà không xuống dòng. `minmax(0,1fr)` để nội dung dài không đẩy
   vỡ lưới; số dài bất thường thì co chữ chứ không tràn.

   Đầu bảng dùng CHUNG lưới này (`.mb-hd5`) — hai lưới rời nhau là hai cơ hội
   để cột lệch khỏi tiêu đề. */
.mb-r5{display:grid;
  grid-template-columns:62px repeat(4,minmax(0,1fr));
  align-items:baseline;gap:6px;font-family:var(--mono)}
/* ══════════════════════════════════════════════════════════════════════════
   KHỐI 02 MOBILE — BẢNG + MỞ TRONG DÒNG   [DỰNG LẠI 16/08/2026]

   Người dùng: *"thanh tiêu đề: Mã - Giá mua - KL Mua - Cắt lỗ, dòng dưới
   trở đi là liệt kê các mã thỏa mãn điều kiện, khi bấm vào mã thì SỔ LỆNH
   và các detail của cổ phiếu của ô này được đưa vào ĐÂY, không như hiện tại
   — show các detail làm 2 dòng và hiện luôn."*

   Bản cũ là THẺ ba dòng cho mỗi mã: dòng giá, bốn ô chi tiết, một dòng phụ.
   Ba mã là chín dòng — cuộn mãi không hết, và không so được mã nào với mã
   nào vì số không thẳng cột.

   Nay dùng CHUNG lưới `.mb-r5` với khối 03·04·06 — bốn bảng, một lưới, số
   thẳng cột. Chi tiết chuyển vào phần MỞ RA, chỉ hiện khi bấm.

   NĂM CỘT: MÃ · GIÁ HT · GIÁ MUA · KL MUA · CẮT LỖ — người dùng chốt
   16/08. Giá hiện tại đứng ngay cạnh giá mua thì so được bằng mắt, không
   phải mở ra mới biết còn cách bao xa.

   Dùng ĐÚNG lưới `.mb-r5` sẵn có, không đè `grid-template-columns`: năm cột
   là đúng năm rãnh nó vốn có. Bản đầu tôi đè xuống bốn cột — thừa một lượt
   sửa, và một luật riêng để trôi khỏi bốn bảng kia. */
/* [GỠ 17/08/2026] `.mb-b2 .tk .mui` (tam giác báo xổ) ĐÃ XOÁ — người dùng:
   *"không cần tam giác báo hiệu có xổ xuống, đơn giản là remove nó đi."*
   Bảng nào chạm cũng mở ra thì một dấu nhắc trên MỌI hàng chỉ là nhiễu. */
.mb-b2 .c.gm{color:#E8E6DF}                    /* giá mua — số chính */
.mb-b2 .c.kl{color:#8A8880}
.mb-b2 .c.cl{color:#E8865F}                    /* cắt lỗ — cùng sắc cảnh báo */

/* CHIP CỔNG ĐÓNG dính sát thanh tiêu đề — [SỬA 17/08/2026].
   Người dùng: *"Chip cổng đóng đang liền sát với tiêu đề, đẩy tiêu đề xuống
   1 chút là đẹp."* `.mb-hd5` không có lề trên, còn `.mb-canh` chỉ có lề
   dưới bằng 0 — hai khối chạm nhau.

   Dùng bộ chọn ANH EM KỀ, cùng lối `.mb-o6 + .mb-hd5` đã có sẵn: chỉ nới
   khi thật sự đứng cạnh nhau, không đụng ba bảng kia. */
.mb-canh + .mb-hd5{margin-top:15px}

/* [GỠ 20/08/2026] `.mb-b2mo` · `.mb-b2.mo + .mb-b2mo` · `.mb-b2mo .trong`
   ĐÃ XOÁ. Ba luật ấy dựng hiệu ứng XỔ TRONG DÒNG cho khối 02; nay khối này
   mở TỜ TRƯỢT như ba khối kia (`mobile.js::mbB2`), nên không phần tử nào
   còn mang các lớp ấy. CSS mồ côi không kêu bao giờ — xoá luôn thay vì để
   lại cho người sau tưởng hàng vẫn xổ được.

   `.mb-b2w` thay chỗ: chỉ là hộp bọc một hàng, giữ cho `.mb-b2` có cha
   riêng như `.mb-vt5` của khối 04 — hai bảng cùng khuôn thì sửa một chỗ. */
.mb-b2w{border-bottom:1px solid #15171A}
/* [GỠ 17/08/2026] `.mb-b2kv` ĐÃ XOÁ — bốn ô CỠ LỆNH · GTGD20 · ĐÁY 52W ·
   HỖ TRỢ không còn. Người dùng: *"Bỏ toàn bộ 4 detail ở dưới thanh tiêu đề…
   những thông tin đó không cần ngoài thông tin Đáy 52W"*, và Đáy 52W đã dời
   xuống hàng cuối của sổ lệnh. Giữ lại một luật CSS cho khối đã gỡ là để
   người sau tưởng nó còn dùng. */

/* [GỠ 17/08/2026] `.mb-b2ct` ĐÃ XOÁ — nó bọc CHART NHỎ, mà chart nhỏ là thứ
   của BẢN DESKTOP. Người dùng: *"chart nhỏ là ở bản desktop… còn mobile thì
   không có chart nhỏ mà là có thanh Xem chart để mở chart toàn màn hình."*

   Nay dùng thẳng `nsChartBtn()` — thanh `.nsc-btn` mà chính khối 02 đã dùng
   ở `khung.html:1033`. Có sẵn CSS, có sẵn hành vi, không cần luật nào ở đây. */

.mb-r5 .tk{font-size:15px;color:#E8E6DF}
.mb-r5 .tk .sao{margin-left:3px}   /* cờ sao nằm TRONG ô mã, không có `gap` đỡ */
.mb-r5 .c{font-size:12.5px;text-align:right;
  /* CHẶN RÒ TỪ LUẬT CŨ. `.mb-row .px{margin-left:auto}` và `.mb-row .pc
     {min-width:58px}` vẫn khớp vào đây vì hàng mới nằm TRONG `.mb-row`.
     Với ô lưới, `margin-left:auto` làm ô co về bề rộng chữ rồi dạt phải —
     đo được 14/08: rãnh GIÁ rộng 71px mà ô chỉ 42px, lệch 29px khỏi đầu
     bảng. Nhìn thì "gần đúng" nên rất dễ bỏ qua; chỉ đo mới thấy.
     Đặt lại tại đây thay vì sửa `.mb-row`: ba khối kia vẫn đang dùng luật
     ấy đúng mục đích của nó. */
  margin:0;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mb-r5 .c.px{font-size:14px}
.mb-r5 .c.kh{color:var(--gold)}          /* giá kích hoạt — vàng như `.mb-row .b s` */
.mb-r5 .c.kl{color:#8A8880}

/* Ô NSyS của bảng VN30 — CHẤM trạng thái + điểm hỗ trợ.
   [SỬA 14/08/2026] Chấm mang đúng ba trạng thái của `chart.js::_v30RowBtn`:
       xanh đặc  đủ cổng mua        (`buy`)
       vàng      đủ khe hỗ trợ      (`supp >= min_supp`)
       rỗng      còn lại
   Bản trước mobile dùng chip chữ "MUA" chiếm nguyên một ô; gộp vào chấm thì
   cùng thông tin mà tiết kiệm được một cột cho KL.

   Lớp trạng thái đặt trên chính Ô, không trên chấm: con số `supp` là TEXT
   NODE trần nên không selector anh-em nào với tới được. Bản nháp đầu tôi
   viết `.cham.mua ~ *` và nó im lặng không ăn — sai lớp lỗi khó thấy nhất,
   vì CSS không kêu. */
.mb-r5 .c.ns{color:#8A8880;display:flex;align-items:baseline;
  justify-content:flex-end;gap:5px}
.mb-r5 .c.ns .cham{width:6px;height:6px;border-radius:50%;flex:0 0 auto;
  border:1px solid #3A3D42;background:none;align-self:center}
.mb-r5 .c.ns.gan{color:#DCD9D3}
.mb-r5 .c.ns.gan .cham{border-color:var(--gold);background:#C9A24C}
.mb-r5 .c.ns.mua{color:#DCD9D3}
.mb-r5 .c.ns.mua .cham{border-color:var(--safe);background:#2FBE78}

/* Đầu bảng năm cột. Chỉ vẽ MỘT lần trên mỗi danh sách, không lặp theo hàng:
   năm con số trần thì không ai đoán được cột nào là gì. */
.mb-hd5{display:grid;
  grid-template-columns:62px repeat(4,minmax(0,1fr));
  gap:6px;padding:0 2px 7px;border-bottom:1px solid #15171A;
  font-family:var(--mono);font-size:9px;letter-spacing:.1em;color:#5A5954}
.mb-hd5 span{text-align:right}
.mb-hd5 span:first-child{text-align:left}

/* NÚT SẮP XẾP — chỉ bảng VN30 dùng. Vùng chạm phải cao hơn chữ 9px rất
   nhiều, nên `padding` dọc rộng tay; nền trong suốt để đầu bảng vẫn nhẹ.
   `on` = cột đang sắp: sáng lên và có mũi tên chiều. */
.mb-hd5 button.s{background:none;border:none;padding:6px 0;margin:-6px 0;
  font:inherit;color:inherit;letter-spacing:inherit;text-align:right;
  cursor:pointer;-webkit-tap-highlight-color:transparent;
  display:flex;align-items:center;justify-content:flex-end;gap:3px}
.mb-hd5 button.s:first-child{justify-content:flex-start}
.mb-hd5 button.s.on{color:var(--gold)}
.mb-hd5 button.s i{font-style:normal;font-size:7.5px;line-height:1}
.mb-hd5 button.s:active{color:#E8E6DF}

/* ── DÒNG DIỄN GIẢI — DÙNG CHUNG LƯỚI NĂM CỘT ─────────────────────────────
   [SỬA 14/08/2026 lượt hai] Người dùng nhìn bản vừa dựng và chỉ ra: khoảng
   trống dưới cột KL "rất vừa và logic cho chỉ số KL cần để kích hoạt".

   Đúng — và nó chỉ vừa khi dòng dưới dùng ĐÚNG lưới của dòng trên. Bản trước
   là `flex` với `margin-left:auto` đẩy `còn` sang phải: `cần` bỏ vào đấy sẽ
   trôi tự do theo độ dài ba mục bên trái, mã này nằm dưới KL, mã kia lệch
   sang KÍCH HOẠT. Nay `grid` cùng `grid-template-columns`, nên:

       cột 1–3   Man · Supp · đáy 52W      (nhóm trái, tự xuống dòng khi hẹp)
       cột 4     cần <KL>                  <- THẲNG dưới cột KL
       cột 5     còn <%>                   <- THẲNG dưới cột KÍCH HOẠT

   [ĐO LẠI HAI LƯỢT — và cả hai lượt ước lượng của tôi đều SAI.]

   Đo thật bằng `do_T2/do_be_rong_dk.py` ở 390px, cỡ chữ 10px:

       Man 5/8         42px
       Supp 11/12      60px
       đáy 52W +58.3%  84px
       ───────────────────
       cần 202px · CÓ 200px · THIẾU ĐÚNG 2px

   Nên khe trong nhóm để `6px`: 186 + 2×6 = 198 ≤ 200, dư 2px. Ba lần trước
   tôi nhẩm "khoảng 204px", "chắc 195px" rồi sửa mò — hai lượt phí. Chỗ sát
   nút đến từng pixel thì phải ĐO, và bài đo ⑤ canh lại mỗi lần.

   320px vẫn hai dòng (chỉ có 165px) — chấp nhận: ép vừa ở đó phải cắt chữ
   "đáy 52W" mà người dùng yêu cầu GIỮ NGUYÊN. */
.mb-r5b{margin-top:6px;display:grid;
  grid-template-columns:62px repeat(4,minmax(0,1fr));
  gap:6px;align-items:baseline;
  font-family:var(--mono);font-size:10.5px;color:#5A5954}
.mb-r5b .dk{grid-column:1 / 4;display:flex;flex-wrap:wrap;gap:2px 6px;
  font-size:10px}
.mb-r5b u{text-decoration:none}
.mb-r5b b{font-weight:400;color:#8A8880}
/* `cần` và `còn` chỉ khác nhau MỘT chữ và đứng cạnh nhau, nên phải khác
   MÀU: `cần` là khối lượng (xám, cùng tông cột KL), `còn` là khoảng cách giá
   (vàng, cùng tông cột KÍCH HOẠT). Cùng màu thì mắt đọc nhầm hai số. */
.mb-r5b .can{text-align:right;color:#8A8880;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mb-r5b .con{text-align:right;color:var(--gold);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* THẺ KHỐI 02 — mã ĐÃ chạm điểm mua. Thẻ chứ không phải hàng: trước khi
   đặt lệnh phải thấy cùng lúc GIÁ MUA · CẮT LỖ · KHỐI LƯỢNG · CỠ LỆNH.
   Nhồi bốn số ấy vào một hàng hai dòng là ép thông tin vào khuôn không vừa —
   đúng lỗi mà bản desktop nắn-lại đã mắc. */
.mb-card{background:#0C0E11;border:1px solid #1A1C20;border-radius:10px;
  padding:14px 15px;margin-bottom:10px;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.mb-card:active{background:#101317}
.mb-card .t{display:flex;align-items:baseline;gap:8px}
.mb-card .tk{font-family:var(--mono);font-size:17px;color:#E8E6DF}
.mb-card .px{margin-left:auto;font-family:var(--mono);font-size:17px}
.mb-card .pc{font-family:var(--mono);font-size:12px;min-width:58px;text-align:right}
.mb-card .kv{margin-top:13px;display:grid;grid-template-columns:1fr 1fr;gap:10px 14px}
.mb-card .kv div{display:flex;flex-direction:column;gap:3px}
.mb-card .kv span{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;color:#4E4D49}
.mb-card .kv b{font-family:var(--mono);font-size:14.5px;font-weight:400;color:#DCD9D3}
.mb-card .ph{margin-top:12px;display:flex;flex-wrap:wrap;gap:6px}
.mb-card .ph u{text-decoration:none;font-family:var(--mono);font-size:10px;
  padding:3px 8px;border-radius:4px;background:#14171B;color:#8A8880}

/* CỜ SAO — `rs_sweet`, mã ở vùng RS đẹp. Tín hiệu Namvini dùng để xếp ưu
   tiên; bỏ đi là mất một lớp thông tin mà không được gì. */
.sao{font-family:var(--mono);font-size:11px;color:var(--gold)}
/* MỚI — `fresh`, tín hiệu vừa xuất hiện HÔM NAY. Khác hẳn mã đã đứng trong
   danh sách nhiều phiên: đây là việc mới phát sinh, đáng nhìn trước. */
.moi{font-family:var(--mono);font-size:8.5px;letter-spacing:.1em;
  padding:2px 5px;border-radius:3px;background:#132A1E;color:var(--safe)}

.mb-rong{padding:15px;border:1px dashed #24262A;border-radius:8px;
  font-size:12.5px;color:#5A5954;text-align:center}

/* DẢI CƠ SỞ — chỉ số mà mọi số bên dưới quy chiếu về. Đặt trước danh sách
   chứ không nhét vào tiêu đề: nó là mốc đọc, không phải nhãn. */
.mb-coso{display:flex;align-items:baseline;gap:10px;padding:11px 13px;
  margin-bottom:11px;border-radius:8px;background:#0C0E11;border:1px solid #15171A}
.mb-coso span{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;color:#4E4D49}
.mb-coso b{margin-left:auto;font-family:var(--mono);font-size:17px;
  font-weight:400;color:#E8E6DF}
.mb-coso s{text-decoration:none;font-family:var(--mono);font-size:12px;
  min-width:58px;text-align:right}

/* THẺ HỢP ĐỒNG — BASIS là số quan trọng nhất của khối 05, nên nó có ô riêng
   ngay dưới giá: chênh lệch so với chỉ số cơ sở nói phái sinh đang đắt hay rẻ. */
.mb-ps{display:grid;grid-template-columns:1fr 1fr;gap:9px;padding-top:2px}
.mb-ps>div{background:#0C0E11;border:1px solid #15171A;border-radius:9px;padding:12px 12px 11px}
.mb-ps .m{display:flex;align-items:baseline;gap:6px;
  font-family:var(--mono);font-size:11px;color:#8A8880;letter-spacing:.06em}
.mb-ps .m u{text-decoration:none;margin-left:auto;font-size:9px;color:#4E4D49}
.mb-ps .g{margin-top:7px;font-family:var(--mono);font-size:19px}
.mb-ps .d{margin-top:2px;font-family:var(--mono);font-size:11px;color:#5A5954}
.mb-ps .bs{margin-top:9px;padding-top:8px;border-top:1px solid #15171A;
  display:flex;align-items:baseline;gap:8px}
.mb-ps .bs span{font-family:var(--mono);font-size:9px;letter-spacing:.11em;color:#4E4D49}
.mb-ps .bs b{margin-left:auto;font-family:var(--mono);font-size:14px;font-weight:400}
.mb-ps .kl{margin-top:7px;display:flex;flex-wrap:wrap;gap:5px}
.mb-ps .kl u{text-decoration:none;font-family:var(--mono);font-size:9.5px;
  padding:2px 6px;border-radius:3px;background:#14171B;color:#7A7973}

/* THẺ VỊ THẾ — viền trái đổi màu theo mức ưu tiên `muc`, nên lướt dọc là
   thấy ngay cái nào cần xử lý mà chưa cần đọc chữ nào. */
.mb-vt{background:#0C0E11;border:1px solid #15171A;border-radius:10px;
  padding:14px 15px;margin-bottom:11px}
.mb-vt.cap{border-left:3px solid var(--danger);background:#100C0D}
.mb-vt.canh{border-left:3px solid #E8865F}
.mb-vt .t{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.mb-vt .tk{font-family:var(--mono);font-size:17px;color:#E8E6DF}
.mb-vt .hd{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;
  padding:3px 7px;border-radius:4px;border:1px solid}
.mb-vt .px{margin-left:auto;font-family:var(--mono);font-size:17px}

/* LÃI/LỖ — số lớn nhất thẻ. Người giữ vị thế hỏi câu này trước mọi câu
   khác, nên nó phải trả lời trước mọi số khác. */
.mb-vt .lai{margin-top:12px;display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.mb-vt .lai b{font-family:var(--mono);font-size:27px;font-weight:400;line-height:1}
.mb-vt .lai span{font-family:var(--mono);font-size:10.5px;color:#4E4D49}
.mb-vt .lai u{text-decoration:none;margin-left:auto;font-family:var(--mono);font-size:11px}

/* LỆNH VIỆC — `hanh_dong` nói phải LÀM GÌ ("THOÁT — đóng cửa dưới MA50"),
   khác `trang_thai` chỉ là nhãn nói CHUYỆN GÌ ("THỦNG MA50"). Thiếu nó thì
   người dùng phải tự suy hành động từ một nhãn. */
.mb-vt .hdo{margin-top:11px;padding:9px 12px;border-radius:7px;
  border:1px solid;font-family:var(--mono);font-size:12px;line-height:1.45}

/* THANH RỦI RO — chữ ký của tab. Mốc trái CẮT LỖ, mốc phải MA50, chấm là
   giá hiện tại. Bốn con số rời rạc không nói được "tôi đang ở đâu"; một
   thanh thì nói ngay. */
.mb-rr{margin-top:14px}
.mb-rr .tr{display:flex;justify-content:space-between;
  font-family:var(--mono);font-size:9.5px;color:#4E4D49}
.mb-rr .th{position:relative;height:5px;margin-top:6px;border-radius:3px;
  background:linear-gradient(90deg,#3A1D1C 0%,#2A2416 55%,#152A1E 100%)}
.mb-rr .th u{position:absolute;top:-3px;width:11px;height:11px;border-radius:50%;
  margin-left:-5.5px;border:2px solid #0C0E11}

.mb-vt .kv{margin-top:14px;display:grid;grid-template-columns:1fr 1fr;gap:10px 14px}
.mb-vt .kv div{display:flex;justify-content:space-between;align-items:baseline;
  font-family:var(--mono);font-size:12.5px;color:#DCD9D3}
.mb-vt .kv span{color:#4E4D49;font-size:9.5px;letter-spacing:.1em}
.mb-vt .kv em{font-style:normal;font-size:11px}
.mb-vt .gc{margin-top:11px;padding:9px 11px;border-radius:6px;
  background:#101215;font-size:12.5px;color:#9A9892;line-height:1.5}
.mb-vt .go{margin-top:13px;width:100%;padding:11px;border-radius:7px;
  background:none;border:1px solid #2A2416;color:var(--gold);
  font-family:var(--mono);font-size:11px;letter-spacing:.1em;cursor:pointer}

/* ── NAV · PHÂN RÃ BA PHẦN ────────────────────────────────────────────
   NAV KHÔNG PHẢI SỐ KHAI BÁO TĨNH — nó là `vốn ban đầu + lãi đã chốt + lãi
   chưa chốt`. Bản trước hiện thẳng `f.nav_ty`, tức VỐN BAN ĐẦU: khai 3 tỷ
   thì ô NAV đứng yên 3 tỷ mãi mãi, dù đã chốt lời hai lệnh.

   VÌ SAO PHÂN RÃ chứ không chỉ một con số: ba thành phần trả lời ba câu
   khác nhau — bỏ vào bao nhiêu, đã rút ra được bao nhiêu, còn đang treo bao
   nhiêu. Gộp lại thành một số thì "3,12 tỷ" không cho biết đó là lãi thật
   đã về tài khoản hay lãi trên giấy có thể bay mất trong một phiên. */
.mb-nav{padding:16px 15px;border-radius:10px;background:#0C0E11;
  border:1px solid #15171A;margin-bottom:11px}
.mb-nav .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;color:#4E4D49}
.mb-nav .v{margin-top:7px;display:flex;align-items:baseline;gap:10px}
.mb-nav .v b{font-family:var(--mono);font-size:30px;font-weight:400;
  line-height:1;color:var(--ink)}
.mb-nav .v s{text-decoration:none;margin-left:auto;font-family:var(--mono);font-size:13px}
.mb-nav .br{margin-top:14px;padding-top:12px;border-top:1px solid #15171A;
  display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.mb-nav .br>div{text-align:center;min-width:0}
.mb-nav .br span{display:block;font-family:var(--mono);font-size:8.5px;
  letter-spacing:.1em;color:#4E4D49}
.mb-nav .br b{display:block;margin-top:5px;font-family:var(--mono);
  font-size:13.5px;font-weight:400;color:#DCD9D3}
/* Dòng phụ % — `realized_pct` và `open_pl_pct` xuống đây sau khi hai ô lưới
   trùng lặp bị gỡ (14/08/2026). Số tuyệt đối và số tương đối của CÙNG một
   đại lượng thì đứng cạnh nhau, không tách ra hai khối cách nhau nửa màn. */
.mb-nav .br i{display:block;margin-top:3px;font-style:normal;
  font-family:var(--mono);font-size:9.5px;color:#4E4D49;min-height:12px}

/* ── LỊCH SỬ GIAO DỊCH · thu gọn, bấm mở ──────────────────────────────
   Khác bản đồ trạng thái ở tab THỊ TRƯỜNG (cuộn thẳng tới, không giấu):
   bản đồ là thứ tra CÙNG LÚC với việc đang làm, còn lịch sử là thứ xem lại
   theo lượt và DÀI VÔ HẠN — mỗi lệnh đóng thêm một hàng, mãi mãi. Mở sẵn
   thì vị thế đang giữ bị đẩy trôi đi bởi thứ ít dùng hơn.

   DÒNG TÓM TẮT hiện cả khi đang đóng: "5 lãi / 2 lỗ · trung bình +3,1%".
   Đó là câu trả lời cho phần lớn lần người ta định mở nó ra. */
.mb-ls{margin-top:16px;border-radius:10px;background:#0C0E11;
  border:1px solid #15171A;overflow:hidden}
.mb-ls .hh{padding:13px 14px;display:flex;flex-wrap:wrap;align-items:baseline;
  gap:5px 10px;cursor:pointer;-webkit-tap-highlight-color:transparent}
.mb-ls .hh:active{background:#101317}
.mb-ls .hh b{font-family:var(--mono);font-size:10.5px;letter-spacing:.11em;
  color:#8A8880;font-weight:400}
.mb-ls .hh span{flex:1 1 100%;font-size:12px;color:#5A5954}
.mb-ls .r{border-top:1px solid #15171A;padding:11px 14px 12px}
.mb-ls .r .t{display:flex;align-items:baseline;gap:10px}
.mb-ls .r .tk{font-family:var(--mono);font-size:14.5px;color:#DCD9D3}
.mb-ls .r .pl{margin-left:auto;font-family:var(--mono);font-size:14.5px}
.mb-ls .r .b{margin-top:5px;display:flex;align-items:baseline;gap:10px;
  font-family:var(--mono);font-size:10.5px;color:#5A5954}
.mb-ls .r .b u{text-decoration:none}
.mb-ls .r .b s{text-decoration:none;margin-left:auto;text-align:right;
  letter-spacing:.05em;color:#7A7973}

/* ── THANH BỐN TAB ────────────────────────────────────────────────────────
   [SỬA 14/08/2026] CAO LÊN VÀ NỔI MÀU. Người dùng: "tăng kích thước của các
   tab cao lên cho dễ touch, tô màu phù hợp để nổi 4 tab lên cho dễ nhìn".

   Bản trước `padding:9px 2px 11px` + chữ 10px cho ra vùng chạm ~44px — đúng
   sàn tối thiểu của iOS, không có dư. Ngón cái chạm ở đáy màn hình lệch dễ
   dàng 8–10px, nên sàn tối thiểu là chạm hụt. Nay `min-height:60px`.

   Chữ nghỉ ở `#4E4D49` gần như chìm vào nền `#0A0B0D` — bốn tab trông như
   một dải xám. Nay nâng lên `#8E8C87`, và tab ĐANG MỞ có nền + vạch đỉnh
   theo đúng màu cổng.

   MỘT BẢNG MÀU, KHÔNG BA. Bản trước lặp ba khối `g-warn`/`g-danger` chỉ để
   đổi màu chữ; thêm nền và vạch là thành chín dòng gần giống nhau — đúng
   kiểu ba bản sao rồi trôi khỏi nhau. Nay khai biến ở `.mb-tab`, hai lớp
   trạng thái chỉ ghi đè biến. Màu lấy NGUYÊN của `.mb-cong` ở trên: dải
   cổng và thanh tab phải nói cùng một màu cho cùng một trạng thái.
   ────────────────────────────────────────────────────────────────────── */
.mb-tab{position:fixed;left:0;right:0;bottom:0;z-index:40;
  --tab-on:var(--safe); --tab-on-nen:#0F2418; --tab-on-vach:#1C4230;
  display:grid;grid-template-columns:repeat(4,1fr);
  background:#0A0B0D;border-top:1px solid #17191C;
  padding-bottom:env(safe-area-inset-bottom,0px)}
body.view-mobile.g-warn .mb-tab{
  --tab-on:var(--watch); --tab-on-nen:#241E0F; --tab-on-vach:#42351C}
body.view-mobile.g-danger .mb-tab{
  --tab-on:var(--danger); --tab-on-nen:#241213; --tab-on-vach:#431E1F}
.mb-tab button{background:none;border:none;cursor:pointer;
  min-height:60px;padding:11px 2px 13px;
  border-top:2px solid transparent;      /* giữ chỗ sẵn: bật vạch không xê dịch chữ */
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;
  font-family:var(--mono);color:var(--ink-faint);-webkit-tap-highlight-color:transparent}
/* Vách ngăn mảnh giữa bốn tab — mắt thấy BỐN ô thay vì một dải liền. */
.mb-tab button + button{box-shadow:inset 1px 0 0 #17191C}
.mb-tab i{font-style:normal;font-size:8.5px;letter-spacing:.06em;color:#34363A}
.mb-tab span{font-size:11.5px;letter-spacing:.05em;line-height:1.22;text-align:center}
/* ── TAB MỘT DÒNG + DÒNG PHỤ LÀ % — [THÊM 27/08/2026] ──────────────────
   Chủ hệ: *"không viết xuống dòng nữa… bổ sung dòng dưới là % thay đổi…
   Lưu ý căn chỉnh độ lớn của chữ để hiển thị cân đối."*

   ── SỐ ĐO, KHÔNG PHẢI ƯỚM MẮT ────────────────────────────────────────
   Bốn tab chia đều `1fr`. Máy hẹp nhất còn dùng là 360px -> mỗi tab 90px,
   trừ `padding 2px` hai bên còn 86px lọt chữ.

       "THỊ TRƯỜNG"  10 ký tự · IBM Plex Mono, bề rộng chữ 0,6em
       10px:  10 × 6,0 + 10 × 0,02em  =  62px      -> dư 24px
       11,5px: 10 × 6,9 + 10 × 0,05em =  75,5px    -> dư 10,5px, sát quá

   Chọn 10px: một chữ hoa dấu (Ị · Ư · Ờ) rộng hơn ô danh nghĩa đôi chút,
   và `white-space:nowrap` sẽ TRÀN chứ không xuống dòng — tràn thì hỏng
   lặng lẽ, nên phải chừa biên thật.

   ── CÂN CHIỀU CAO VỚI BA TAB CÒN LẠI ─────────────────────────────────
   Ba tab kia vẫn hai dòng, và cụm chữ của chúng cao:

       2 dòng × 11,5px × 1,22                    = 28,1px
       nhãn 10 × 1,22 + gap 3 + % 12 × 1,1       = 28,4px

   Lệch 0,3px — mắt không thấy, và cả hai nằm trong `min-height:60px` căn
   giữa nên không ô nào xê dịch. `gap` khai ở `.mb-tab button` (4px) hạ
   xuống 3px CHỈ cho tab có dòng phụ, không đụng ba tab kia.

   `%` TO HƠN NHÃN (12 so 10) vì nó là con số người ta liếc, còn nhãn thì
   đã thuộc lòng. Đây cũng là lý do chỉ MỘT trong hai được tô màu. */
.mb-tab span.lien{font-size:10px;letter-spacing:.02em;white-space:nowrap}
.mb-tab button:has(> .pc){gap:3px}
.mb-tab b.pc{font-style:normal;font-weight:600;font-size:12px;
  letter-spacing:.02em;line-height:1.1;font-variant-numeric:tabular-nums}
.mb-tab button[aria-current="true"]{
  color:var(--tab-on);background:var(--tab-on-nen);border-top-color:var(--tab-on);
  animation:mbTabSang .22s cubic-bezier(.22,.61,.36,1)}
.mb-tab button[aria-current="true"] i{color:var(--tab-on)}
.mb-tab button[aria-current="true"] span{font-weight:600}
.mb-tab button[aria-current="true"] i,
.mb-tab button[aria-current="true"] span{
  animation:mbTabChu .22s cubic-bezier(.22,.61,.36,1)}
/* NỬA CÒN THIẾU CỦA HIỆU ỨNG ĐỔI TAB — [THÊM 25/08/2026].

   Chủ hệ: *"nó nhanh quá nên đôi khi không nhận ra việc chuyển tab"*.

   ĐO TRƯỚC (`do_T2/soi_hieu_ung_tab_2508.py`), và số đo đổi hẳn việc phải
   làm so với dự định ban đầu:

       tấm nội dung   anim `mbVaoTab` 190ms · `--mb-tu` ±18px   ✓ ĐANG CHẠY
       nút thanh tab  anim KHÔNG CÓ · transition all / 0s       ← 0 mili giây

   Tức hiệu ứng thêm ngày 15/08 vẫn sống và vẫn đúng chiều — KHÔNG phải ca
   "đã có mà chưa ai gọi", nên viết thêm một hiệu ứng nội dung nữa là nhân
   đôi cái đang chạy. Chỗ thủng là THANH TAB: thứ mắt dùng để xác nhận
   "đang ở tab nào" lại là thứ duy nhất đổi tức thì.

   CÙNG CƠ CHẾ VỚI `.mb-tsec.on`, không dựng cái thứ hai: `[aria-current]`
   đổi giá trị -> nút BẮT ĐẦU khớp bộ chọn -> keyframe tự chạy lại. Y hệt
   cách lớp `.on` khởi động `mbVaoTab`, và cũng vì lý do ấy mà `transition`
   không dùng được — không có trạng thái đầu để nội suy.

   220ms, nhỉnh hơn tấm nội dung 30ms: vạch sáng lên NGAY SAU khi nội dung
   đã yên, nên mắt bắt được hai nhịp chứ không phải một cú loé.

   Tách chữ khỏi nền làm hai keyframe vì `transform` trên chính nút sẽ dịch
   cả vạch 2px ở mép trên thanh cố định — nhìn như thanh bị rung. */
@keyframes mbTabSang{
  from{background:transparent;border-top-color:transparent}
  to{background:var(--tab-on-nen);border-top-color:var(--tab-on)}
}
@keyframes mbTabChu{
  from{opacity:.45;transform:translateY(2px)}
  to{opacity:1;transform:none}
}
.mb-tab button:active{background:#111316}

/* TỜ TRƯỢT · chi tiết một mã. Chạm một hàng thì tờ này trượt lên, KHÔNG rời
   trang. Giữ được ngữ cảnh: đóng lại là vẫn đúng chỗ vừa xem. */
/* [16/08/2026] `overscroll-behavior:none` — CÙNG LỚP LỖI với `#nsChart`.
   Tờ trượt cũng là lớp phủ toàn màn hình có vùng cuộn bên trong. Kéo quá
   mép thì cuộn LAN xuống trang nền; ở chế độ standalone (icon home screen)
   không có thanh địa chỉ hấp thụ nên nó lan thẳng, trang nền trôi dưới lớp
   phủ đứng yên. Xem lý do đầy đủ ở `chart.css::#nsChart`.
   Đặt ở đây chứ không đợi gặp lỗi: cùng cấu hình thì cùng nguy cơ. */
.mb-sheet{position:fixed;inset:0;z-index:70;display:none;overscroll-behavior:none}
.mb-sheet.on{display:block}
.mb-sheet .bg{position:absolute;inset:0;background:rgba(0,0,0,.62)}
.mb-sheet .sh{position:absolute;left:0;right:0;bottom:0;max-height:88%;
  /* ── VA TÊN LỚP VỚI BẢN DESKTOP — ĐÃ CẮN, và có sẵn từ lâu ────────────
     `khung.html:108` khai một luật TOÀN CỤC:

         .sh{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;…}

     Đó là lớp của bản desktop, trùng tên với tờ trượt mobile. `.mb-sheet .sh`
     đè được `position`/`padding`/`background`… nhưng KHÔNG khai `display`,
     nên tờ trượt xưa nay là một FLEX HÀNG CÓ XUỐNG DÒNG, không phải khối
     xếp dọc như mọi người tưởng khi đọc mã.

     Hệ quả đo được (`do_T2/do_rong_tosheet.py`): `#mb-sl` chỉ rộng 299px
     trong khi tờ trượt cho 358px — nó co theo nội dung vì là flex item, chứ
     không lấp đầy. Cộng thêm `gap:12px` và `align-items:baseline` chen vào
     giữa các khối. Đây là phần lớn cái "thừa thừa thiếu thiếu, kém cân đối"
     mà người dùng thấy.

     Khai `display:block` TƯỜNG MINH là đủ — ba thuộc tính flex kia trở thành
     vô hiệu. Không đổi tên lớp vì `.sh` chỉ xuất hiện một chỗ trong bản mẫu
     và không mã JS nào tra nó; đổi tên là rủi ro không đổi lấy gì thêm.
     `test_o.py` nay có bài chặn việc quên dòng này. */
  display:block;
  overflow-y:auto;background:#0A0B0D;border-top:1px solid #1C1D19;
  border-radius:16px 16px 0 0;
  padding:0 16px calc(env(safe-area-inset-bottom,0px) + 18px)}
.mb-sheet .grip{width:38px;height:4px;border-radius:2px;background:#26292F;
  margin:9px auto 4px}
/* ── KÉO XUỐNG ĐỂ ĐÓNG — 20/08/2026 ────────────────────────────────────
   `will-change` báo trước cho trình duyệt: `_mbKeoDi` ghi `transform` mỗi
   khung hình khi ngón di. Không khai thì lượt kéo đầu tiên bị giật một
   nhịp trong lúc trình duyệt dựng lớp hợp thành.

   VÙNG CHẠM CỦA VẠCH KÉO: vạch chỉ dày 4px, không ai chạm trúng. Nhưng cử
   chỉ KHÔNG đòi chạm đúng vạch — `_mbKeoDuoc` nhận mọi điểm trong `.sh` khi
   `scrollTop === 0`, nên vạch thuần tuý là DẤU HIỆU. Nới `padding` để nó
   cách thanh tiêu đề đủ thoáng, không phải để bắt ngón.

   KHÔNG khai `touch-action:none` ở đây: thân tờ trượt PHẢI cuộn dọc được
   như thường. `_mbKeoDi` tự gọi `preventDefault` sau khi đã quyết là đang
   kéo — chặn bằng CSS là chặn cả cuộn.

   [SỬA 24/08/2026] Nay CÓ khai `touch-action`, nhưng là `manipulation` —
   thứ VẪN cho cuộn và chụm, chỉ bỏ chạm-hai-lần-để-phóng-to. Xem luật ngay
   dưới; câu trên vẫn đúng với `none`, và đó mới là thứ nó cấm. */
.mb-sheet .sh{will-change:transform}
/* ── THÂN TỜ TRƯỢT CŨNG PHẢI `manipulation` — [THÊM 24/08/2026] ──────────
   Luật quét ở đầu tệp chỉ phủ `button, a, [onclick]`. Đo được: MỌI ô trong
   thân tờ trượt (`.sl-muc` · `.sl-hang` · `.kv-n` · `.sl-ke` · `.sl-kv`)
   đều là `auto` — tức chạm hai lần ở đó vẫn là lệnh PHÓNG TO của trình
   duyệt.

   Đó là điều kiện TIÊN QUYẾT của cử chỉ chạm-đúp-mở-chart (xem
   `mobile.js::_mbChamDoi`): thiếu dòng này thì cử chỉ ấy không thể tồn tại,
   vì trình duyệt cướp cú chạm thứ hai trước khi `click` kịp bắn.

   `manipulation` = `pan-x pan-y pinch-zoom` — CUỘN tờ trượt và CHỤM để
   phóng vẫn nguyên. Chỉ bỏ đúng chạm-hai-lần-để-phóng-to. */
.mb-sheet .sh{touch-action:manipulation}
/* ── HIỆU ỨNG TRƯỢT LÊN KHI MỞ — [THÊM 23/08/2026] ─────────────────────
   Chủ hệ: *"thêm hiệu ứng trượt lên khi mở, giống như khi swipe down khi
   đóng nó có hiệu ứng kéo xuống."*

   Đường ĐÓNG đã có hiệu ứng từ 20/08 — `_mbKeoXong` ghi
   `transition:transform .18s ease-out` rồi `translateY(100%)`. Đường MỞ thì
   chưa: `.mb-sheet.on{display:block}` bật cái một, tờ trượt hiện ra tại chỗ.
   Hai chiều của cùng một cử chỉ mà một chiều có chuyển động, một chiều
   không — mắt đọc ra ngay là chưa xong.

   DÙNG `@keyframes`, KHÔNG dùng `transition`: `display` nhảy từ `none` sang
   `block` trong CÙNG một khung hình với việc thêm lớp `.on`, nên trình duyệt
   không có trạng thái đầu để nội suy — `transition` sẽ không chạy. Ảnh động
   thì chạy ngay khi phần tử xuất hiện, đúng thứ cần ở đây.

   `.18s` KHỚP ĐÚNG nhịp đóng ở `_mbKeoXong`, và `cubic-bezier(.32,.72,0,1)`
   là đường cong tờ trượt gốc của iOS — nhanh lúc đầu, dừng êm. Nền mờ dần
   theo, vì lúc kéo đóng nó cũng mờ dần (`_mbKeoDi` chỉnh `opacity`).

   ⛔ KHÔNG `fill-mode` — ĐÃ CẮN NGAY LƯỢT ĐẦU, 23/08/2026.
   Bản đầu tôi viết `… .18s cubic-bezier(…) both`. Chủ hệ báo lại ngay:
   *"bạn thêm hiệu ứng trượt lên thì lại cắt hiệu ứng trượt xuống."*

   Đo được (`do_T2/do_anh_dong_de_2308.py`), sau khi ảnh động đã chạy xong:

       ảnh động: {ten:'mb-sheet-len', trangThai:'finished', fill:'both'}
       ghi  sh.style.transform = 'translateY(50px)'
       đọc  getComputedStyle -> matrix(1,0,0,1,0,0)      ← KHÔNG ĂN

   `fill:both` giữ giá trị CUỐI áp lên phần tử MÃI MÃI sau khi chạy xong, và
   trong thứ tự tầng CSS ảnh động THẮNG CẢ `style` nội tuyến. Nên mọi thứ
   `_mbKeoDi`/`_mbKeoXong` ghi vào `transform` đều bị nuốt — cử chỉ kéo
   xuống chết TRỌN VẸN, không phải chỉ mất hiệu ứng.

   Bỏ `both` thì hết giai đoạn chạy là ảnh động thôi áp giá trị, và `style`
   nội tuyến ăn lại như thường. Không cần `forwards`: trạng thái nghỉ của
   `.sh` vốn đã là `translateY(0)`.

   LỚP THỨ HAI ở `mobile.js`: `_mbKeoDi` gán `style.animation='none'` ngay
   khi quyết là đang kéo, phòng ca ngón đặt xuống TRONG 180ms ảnh động còn
   chạy — lúc ấy `fill` không liên quan, nhưng ảnh động ĐANG chạy thì vẫn
   thắng. `_mbKeoVe` trả lại `''`.

   `prefers-reduced-motion` — người tắt hiệu ứng trong cài đặt máy thì tắt
   hẳn, không rút ngắn. Đó là lựa chọn về sức khoẻ, không phải sở thích. */
@keyframes mb-sheet-len{
  from{transform:translateY(100%)}
  to{transform:translateY(0)}
}
@keyframes mb-sheet-nen{ from{opacity:0} to{opacity:1} }
.mb-sheet.on .sh{animation:mb-sheet-len .18s cubic-bezier(.32,.72,0,1)}
.mb-sheet.on .bg{animation:mb-sheet-nen .18s ease-out}
@media (prefers-reduced-motion: reduce){
  .mb-sheet.on .sh,.mb-sheet.on .bg{animation:none}
}
/* ── THANH TIÊU ĐỀ TỜ TRƯỢT ───────────────────────────────────────────────
   `align-items:baseline` — [SỬA 20/08/2026], BỆNH Ở MỌI TỜ TRƯỢT.

   Chủ hệ: *"hạ % tăng giảm xuống cùng hàng với các số và chữ còn lại, hiện
   tại nó đang bị lệch lên (đáy cao hơn đáy của điểm số — nhìn cứ như bay
   lên), bệnh này ở tất cả các tờ trượt không chỉ ở 05."*

   GỐC: `align-items:center` căn theo TÂM Ô CHỮ. Ba con số ở đây khác cỡ —
   mã 19px, giá 17px, % 12.5px — nên tâm trùng nhau thì CHÂN CHỮ lệch nhau:
   chữ nhỏ có ô thấp hơn, tâm ngang nhau tức đáy của nó nằm cao hơn. Đó đúng
   là "bay lên".

   `baseline` căn theo ĐƯỜNG CHÂN CHỮ, tức thứ mắt thật sự đọc là "cùng
   hàng". Đây là mặc định của chữ chảy trong một dòng văn; `center` mới là
   thứ phải khai thêm, và nó được khai cho NÚT chứ không phải cho SỐ.

   Hai nút phải giữ căn TÂM — `align-self:center` ở luật riêng của chúng:
   nút vuông 30–40px không có đường chân chữ nào để căn. */
/* ĐỆM PHẢI 15px — GIÁ VÀ % THẲNG CỘT "KL bán".  [SỬA 29/08/2026]

   Chủ hệ: *"đẩy giá và % thay đổi trên header sao cho ký tự cuối cùng thẳng
   hàng với 'KL bán' ở sổ lệnh, hiện tại đang được căn phải đến tận cùng của
   header, nhìn nó hơi lệch."*

   Con số 15 KHÔNG chọn bằng mắt, nó cộng ra được:

       .sh          padding:0 16px   -> mép trong của tờ trượt
       .sl-box      border 1px       -> thẻ sổ lệnh nằm sát mép ấy
       .sl-nhan     padding:0 14px   -> mép phải chữ "KL bán"
                                        1 + 14 = 15px vào trong

   Đổi một trong ba số trên thì phải đổi số này theo —
   `tests/test_keo_dong_sheet.py::test_HEADER_thang_cot_KL_ban` cộng lại và
   đỏ nếu chúng rời nhau. */
.mb-sheet .hd{display:flex;flex-wrap:wrap;align-items:baseline;gap:10px;padding:8px 15px 8px 0;
  border-bottom:1px solid #15171A;position:sticky;top:0;background:#0A0B0D;z-index:2}
/* NÚT ĐÓNG — góc TRÁI, người dùng thao tác bằng tay trái.
   Vùng chạm 40x40 (sàn của iOS là 44; ở đây 40 vì nút nằm sát mép trên tờ
   trượt, phần đệm của `.hd` cộng thêm ~10px nữa). `margin-left:-8px` kéo dấu
   ✕ về sát mép cho cân quang học mà vùng chạm vẫn nguyên. */
.mb-sheet .hd .dong{width:40px;height:40px;margin:-8px 0 -8px -10px;
  flex:0 0 auto;align-self:center;background:none;border:none;cursor:pointer;
  font-family:var(--mono);font-size:17px;line-height:1;color:#8A8880;
  -webkit-tap-highlight-color:transparent}
.mb-sheet .hd .dong:active{color:#E8E6DF}
.mb-sheet .hd b{font-family:var(--mono);font-size:19px;color:#E8E6DF;font-weight:400}
/* ── NÚT MỞ CHART — biểu tượng ngay sau tên mã. [THÊM 20/08/2026] ────────
   Thay chip "XEM CHART TOÀN MÀN HÌNH" cao 44px + lề 18px ở cuối tờ trượt.
   Chủ hệ: *"cho gọn gàng, tránh kéo tờ trượt lên quá cao"*.

   KÍCH THƯỚC: hình 13px như bản desktop — *"gọn gàng không cần lớn"*. Vùng
   chạm 30x30 nhờ `padding`, nhỏ hơn sàn 44px của iOS nhưng đây là đường
   THỨ HAI tới chart (bấm mã ở bảng cũng mở chart được), và nới rộng nữa thì
   nó chen vào giá trên cùng thanh.

   `margin-left:-2px` kéo sát tên mã cho thành MỘT cụm "mã + chart", thay vì
   một nút trôi lơ lửng giữa thanh. `margin-right:auto` đẩy giá và % về mép
   phải như cũ — trước đây `.hd u` giữ việc ấy bằng `margin-left:auto`, nay
   nút chen vào giữa nên phải chuyển vai.

   MÀU `--chart` (đất nung, sắc logo Claude — chủ hệ chọn). Nó KHÔNG mã hoá
   trạng thái, nên không bao giờ được dùng cho một con số; xem `:root`. */
.mb-sheet .hd .mo-chart{display:flex;align-items:baseline;gap:7px;
  flex:0 0 auto;align-self:baseline;
  margin:0 auto 0 -2px;padding:3px 4px;
  background:none;border:none;cursor:pointer;color:var(--chart);
  -webkit-tap-highlight-color:transparent}
/* ── MỘT ĐƯỜNG CHÂN CHO MỌI CHỮ — [SỬA 23/08/2026] ────────────────────────
   Chủ hệ: *"tên cổ phiếu, và Giá % thay đổi phải nằm trên cùng 1 line phần
   bottom, hiện tại tôi nhìn cứ bị lệch lệch. Biểu tượng chart thì nên nằm
   giữa chữ của tên cổ phiếu."*

   GỐC: `.hd` vốn ĐÃ là `align-items:baseline` — nhưng `.mo-chart` tự đặt
   `align-self:center`, nên cả cụm "tên mã + sàn + biểu tượng" bị lôi ra
   khỏi phép căn ấy và căn GIỮA theo chiều cao thanh. Tên mã 19px do đó
   không còn chung đường chân với giá 17px và `%` 12,5px — ba con chữ, ba
   đường chân, và mắt đọc ra ngay là "lệch lệch".

   Nút này còn là một hộp flex NỮA, nên phải sửa cả hai tầng:
     · `align-self:baseline`  -> cụm tham gia phép căn của `.hd`
     · `align-items:baseline` -> `<b>` bên trong baseline, và nhờ đó CHÍNH
       nút phơi ra đường chân của `<b>` cho `.hd` dùng
   Thiếu vế thứ hai thì nút là hộp flex có con căn giữa, và trình duyệt
   phải TỰ CHẾ một đường chân từ mép hộp — ra một con số không ai đoán
   được, đúng kiểu "sửa rồi mà vẫn lệch".

   QUY ƯỚC CHUNG, áp cho cả đầu trang chart (`chart.css`):
       CHỮ            -> đường chân chung
       BIỂU TƯỢNG · CHIP -> căn GIỮA theo chiều cao chữ
   Xem hai luật ngay dưới. */
.mb-sheet .hd .mo-chart>svg{align-self:center}
.mb-sheet .hd .mo-chart:active{opacity:.55}
/* TÊN SÀN — giữa tên mã và biểu tượng chart, thẳng hàng với cả hai.
   [THÊM 21/08/2026] Chủ hệ: *"bổ sung tên sàn của cổ phiếu trên thanh tiêu
   đề, nằm thẳng hàng và giữa tên cổ phiếu và chart nhỏ."*
   Cùng sắc `--chart` với biểu tượng ngay cạnh — hai thứ ấy làm thành MỘT
   cụm "mở chart", còn tên mã giữ màu chữ riêng để vẫn là thứ đọc trước.
   `:empty` — mã không tra được sàn niêm yết thì ô biến mất hẳn, không để
   lại một khung viền rỗng. `quyche.BangGia` cấm đoán sàn, nên rỗng là
   trạng thái BÌNH THƯỜNG chứ không phải lỗi. */
.mb-sheet .hd .san{font-family:var(--mono);font-size:9.5px;letter-spacing:.09em;
  line-height:1;color:var(--chart);align-self:center;
  border:1px solid color-mix(in srgb,var(--chart) 38%,transparent);
  border-radius:3px;padding:2px 5px}
.mb-sheet .hd .san:empty{display:none}
/* ── BA SỐ TRÊN THANH TIÊU ĐỀ — CỘT CỐ ĐỊNH, CĂN PHẢI ──────────────────
   [SỬA 23/08/2026] Chủ hệ, về tờ trượt khối 05: *"xoá khối lượng đi và đưa
   về định dạng fix và căn chỉnh lại vị trí cho đều tương ứng với các tờ
   trượt khác… tờ trượt khối này khác với những tờ trượt khối khác vì nó có
   thêm phần thay đổi số điểm, vẫn là ưu tiên căn phải cho đồng bộ."*

   ⚠ KHAI TRỌN Ở ĐÂY, MỘT LUẬT MỘT Ô. Bản đầu tôi để nguyên ba dòng cũ rồi
   thêm một khối `tabular-nums`/`min-width` ở CUỐI tệp — hai lần khai cho
   cùng một ô, và bài kiểm bắt ngay vì nó đọc trúng lần khai đầu. Cascade thì
   vẫn ra đúng, nhưng ai đọc mã sẽ thấy `.hd u` ở dòng 847 và tin rằng đó là
   tất cả. Đó là cách một luật CSS âm thầm trôi khỏi luật kia.

   `tabular-nums` cho CẢ BA: chữ số cùng bề rộng thì con số đổi mỗi giây
   không làm hàng nhúc nhích. Thiếu nó ở `i.diem` là mỗi nhịp giá lại đẩy
   `%` sang trái một tí — thứ mắt bắt được mà khó gọi tên.

   `min-width` + `text-align:right` khoá CỘT chứ không khoá chữ: mã nào cũng
   đặt `%` ở đúng một chỗ, nên mở tờ trượt khối 02 rồi khối 05 thì `%` không
   nhảy. Đo được: mép phải `%` = 374px ở CẢ HAI khối.

   `i.diem` 52px — vừa `-12.34` ở 12,5px mono. Nó ẩn hẳn ở mọi khối trừ 05
   (`mbMo` gỡ `display`), nên cột này không ăn chỗ của ai. */
.mb-sheet .hd u{text-decoration:none;font-family:var(--mono);font-size:17px;
  font-variant-numeric:tabular-nums}
/* SỐ ĐIỂM THAY ĐỔI — CHỈ hợp đồng phái sinh, xem `mobile.js::mbMo`.
   CÙNG cỡ với `%` ngay cạnh: chủ hệ *"kích thước bằng kích thước của % tăng
   giảm"*. Hai số nói cùng một chuyện bằng hai đơn vị, nên không số nào được
   trông quan trọng hơn số kia. */
.mb-sheet .hd i.diem{font-style:normal;font-family:var(--mono);font-size:12.5px;
  font-variant-numeric:tabular-nums;min-width:52px;text-align:right}
.mb-sheet .hd s{text-decoration:none;font-family:var(--mono);font-size:12.5px;
  font-variant-numeric:tabular-nums;min-width:58px;text-align:right}
/* `.mb-sheet .go` ĐÃ XOÁ — 20/08/2026. Đó là chip "XEM CHART TOÀN MÀN HÌNH"
   cuối tờ trượt, nay thay bằng biểu tượng `.chart` trên thanh tiêu đề.
   Xoá luôn chứ không để lại: CSS mồ côi không kêu bao giờ, và `#mb-go` cũng
   đã rời `khung.html` nên luật này không còn khớp phần tử nào. */


/* ══ SỔ LỆNH TRÊN MOBILE — BÀY LẠI 14/08/2026 ═════════════════════════════

   Người dùng: *"sổ lệnh trên Mobile (ở tất cả các panel) nhìn rất xấu xí,
   kém tinh tế và thậm chí là bị chèn chữ, nó thừa thừa thiếu thiếu, kém cân
   đối"*.

   ĐO ĐƯỢC (`do_T2/soi_solenh_mb.py`, máy chủ thật, màn 390px):

       «317.7K» được 10px · cần 43px · THIẾU 33px
       «300.0K» được 10px · cần 43px · THIẾU 33px
       … cả SÁU ô khối lượng đều thiếu 26–33px

   Cộng dồn nguyên nhân từ mã nguồn:

       .mb-sheet .sh  padding 0 16px         390 -> 358
       .sl-box        border 1px             358 -> 356
       .sl-chia       1.15fr | 1fr           cột trái 190,4
                      border-right 1px               189,4
       .sl-muc        padding 2px 14px               161,4
       .sl-hang       1fr|60px|1px|60px|1fr, khe 5px
                      cố định 121 + 4 khe = 141
                      còn cho HAI ô khối lượng = 20,4  ->  10,2px MỖI Ô

   Gốc rễ: MỘT bố cục phục vụ HAI bề rộng rất khác nhau. Trên panel desktop
   rộng, `1fr` dư dả. Trên 390px, 141px cột cố định ăn gần hết 161px. Không
   phải chỉnh vài pixel — nó quá tải GẤP BỐN LẦN.

   ── HAI QUYẾT ĐỊNH THIẾT KẾ ──────────────────────────────────────────────

   ① BỎ CHIA ĐÔI TRÁI–PHẢI. Sổ lệnh chiếm TRỌN bề ngang; kẻ giá xuống dưới.
      Đang có ELEVEN con số ép nằm ngang trên 358px. Sau khi xếp dọc:
          .sl-muc rộng 356 − 28 = 328
          1fr | 58 | 1 | 58 | 1fr, khe 6  ->  cố định 141  ->  2fr = 187
          MỖI ô khối lượng 93px, cần 43px  ->  dư hơn gấp đôi

   ② TÁCH HAI PHÉP MÃ HOÁ RA HAI LÀN. Ô giá 60px đang gánh cùng lúc:
          nền xanh/đỏ  = BÊN (mua/bán) và ĐỘ LỚN khối lượng
          màu chữ      = so với THAM CHIẾU (trần vàng, trên xanh, dưới đỏ)
      Nên sinh ra ô "chữ đỏ trên nền xanh" — đúng thứ người dùng gọi là màu
      mè, khó hiểu, trùng thông tin. Và thanh khối lượng vẽ sau lưng ô GIÁ
      trong khi CON SỐ khối lượng nằm ở ô bên cạnh: phải ghép hai chỗ mới đọc
      được một đại lượng.

      Nay: làn NGOÀI = khối lượng (số + thanh nền mọc từ trục ra), làn TRONG
      = giá (chữ màu theo tham chiếu, NỀN TRƠN). Mỗi làn một đại lượng.

   ── VÌ SAO PHẢI `!important` ─────────────────────────────────────────────

   `slBlock`/`slVe` dựng bố cục bằng INLINE STYLE, và inline style thắng mọi
   selector CSS thường. Giữ nguyên chúng là điều kiện để bản DESKTOP không
   đổi một pixel — nên bản mobile buộc phải ghi đè bằng `!important`.
   Đây không phải lười; đối thủ là inline style.
   ═══════════════════════════════════════════════════════════════════════ */

/* ① XẾP DỌC */
/* ── CHỪA SẴN CHỖ CHO BẢNG SỔ LỆNH — [SỬA 24/08/2026] ────────────────────
   Chủ hệ: *"mở tờ trượt… đôi khi là khựng 1 cái rồi mới mở hết, nhưng cũng
   có lúc gần như tức thì."*

   ĐO ĐƯỢC, và nó bác bỏ giả thuyết của cả hai chúng tôi (P·V·T tính lâu):

       ngay sau `mbMo`   .sl-chia  32px (rỗng)  ·  .sl-pvt 165px  <- P·V·T CÓ NGAY
       sau 400 ms        .sl-chia 368px (có bảng) · .sl-pvt 165px  <- không đổi

   P·V·T dựng ngay khung hình đầu, tốn 0 ms chờ. Thứ nhảy là BẢNG SỔ LỆNH:
   `.sl-chia` phình 32 -> 368px, tức tờ trượt cao hơn GẤP ĐÔI sau khi mở.
   Đó là *layout shift*, không phải chậm.

   VÌ SAO LÚC THẤY LÚC KHÔNG: `slBlock` có `if(_SL.d[tk]) setTimeout(slVe,0)`.
   Có sẵn sổ lệnh -> `slVe` kịp CÙNG khung hình -> mắt không thấy nhảy. Chưa
   có -> phải chờ `/api/nsys_solenh` + RTT đường hầm -> sang khung hình khác
   -> thấy nhảy. Trên `127.0.0.1` RTT≈0 nên hai nhánh trùng nhau và tôi đo
   hụt lần đầu; trên điện thoại RTT 80–150 ms tách chúng ra hẳn.

   `min-height:0!important` ngay dưới KHÔNG sai — nó gỡ ràng buộc 212px mà
   desktop đặt cho bố cục HAI CỘT, thứ vô nghĩa khi mobile xếp dọc. Nhưng
   lượt ấy chỉ nghĩ tới việc GỠ, không nghĩ tới việc bố cục dọc cần một con
   số CỦA RIÊNG NÓ. Nay có: 368px, đo trên 7 mã khác nhau, cả 7 đều đúng
   368 — bảng sổ lệnh luôn đủ ba bậc giá nên chiều cao không đổi theo mã.

   Chừa chỗ thì hết nhảy BẤT KỂ mạng nhanh chậm — chữa tận gốc, không phải
   làm cho nhanh hơn rồi mong không kịp thấy.

   ⛔ CHỪA ĐÚNG VÙNG, KHÔNG CHỪA CẢ KHUNG — [SỬA 29/08/2026]

   Chủ hệ, kèm hai ảnh CÙNG mã STB cùng sổ lệnh: *"các hàng sổ lệnh chênh
   lệch nhau về khoảng cách… panel 03 nhìn đẹp và cân đối hơn bất kỳ panel
   nào khác"*, và ở khối 04 *"để 1 deadspace rất xấu xí"*.

   Một nguyên nhân, hai triệu chứng. `min-height` đặt trên `.sl-chia` — mà
   trên mobile nó là LƯỚI HAI HÀNG (thang giá xếp trên, kê giá xếp dưới).
   Phần dôi ra được lưới CHIA VÀO CÁC HÀNG:

       khối 03   kê giá BA nhóm  -> gần đủ 368  -> gần như không giãn
       khối 04   kê giá HAI nhóm -> dôi ~60px   -> chảy vào ba bậc giá
                 (`.sl-hang` mang `flex:1 1 auto`) VÀ vào đáy kê giá

   Tức chiều cao ba bậc giá phụ thuộc việc khối BÊN DƯỚI có mấy nhóm. Một
   khối dùng chung mà mỗi panel một nhịp.

   Chỗ chừa VẪN CẦN — bỏ nó là làm sống lại cú nhảy vừa tả ở trên. Nên
   chuyển nó xuống ĐÚNG VÙNG có kích thước xác định thay vì rải lên cả khung:

       .sl-muc    30 (đầu bảng) + 3×38 (ba bậc) + 4 (đệm)  = 148px
       .sl-tong   12 (đệm) + 6 + 14 + 3 + 18 (một nhóm kv) =  53px

   Hai vùng ấy giống hệt nhau ở MỌI khối, nên chừa được bằng một con số. Kê
   giá thì không — 02/03 ba nhóm, 04/05/06 hai nhóm — và đó chính là lý do
   không được chừa chung. Nó còn nhảy một nhịp nhỏ ở cuối; đổi lấy việc mọi
   panel cùng một nhịp và hết dead space. */
body.view-mobile .sl-chia{grid-template-columns:1fr!important;
  min-height:0!important;align-content:start!important}
body.view-mobile .sl-muc{min-height:148px!important}
body.view-mobile .sl-trai{border-right:none!important}
body.view-mobile .sl-nhan{padding:0 14px!important;height:30px!important}

/* ② THANG GIÁ — khung nay ĐÃ là bốn cột bằng nhau (xem `slVe`), nên mobile
   KHÔNG cần đổi `grid-template-columns` nữa. Chỉ nới chiều cao hàng cho ngón
   tay và phóng chữ lên một nhịp. Bốn cột đều ở 328px = 82px mỗi cột; "317.7K"
   cần 43px, dư gần gấp đôi.

   `flex:0 0 38px` — [THÊM 29/08/2026]. Khuôn dựng trong `chart.js` cho hàng
   `flex:1 1 auto`, tức nó NUỐT mọi khoảng dôi của `.sl-muc` và cao lên theo.
   Đó là đường mà `min-height` trên `.sl-chia` đã dùng để kéo giãn ba bậc giá
   của khối 04 (xem chú thích ①). Ghim cứng ở đây thì ba bậc luôn đúng 38px
   ở MỌI panel, kể cả khi sau này có ai chừa chỗ ở một vùng khác. */
body.view-mobile .sl-hang{height:38px!important;font-size:14px!important;
  flex:0 0 38px!important}
body.view-mobile .sl-mg,
body.view-mobile .sl-bg{font-size:15px!important}
body.view-mobile .sl-dau{height:28px!important;font-size:10px!important}

/* ③ KẺ GIÁ XUỐNG DƯỚI — khuôn VNDirect: nhãn một hàng, số một hàng.
   [DỰNG LẠI 14/08/2026 lượt hai] Bản trước ép lưới `52px | 1fr` và người
   dùng báo *"vỡ bố cục và lên xuống dòng loạn xới"* — nhãn `SỐ PHIÊN NẮM
   GIỮ` (~100px) nhét vào ô 52px thì xuống ba dòng.

   Nay `_kv` tự sinh đúng khuôn ấy cho CẢ HAI bản, nên khối này KHÔNG còn
   một dòng `!important` nào: mobile chỉ nới đệm và cỡ chữ.

   `#mb-sl .ct` ĐI CHUNG KHAI BÁO — [THÊM 29/08/2026]. Ba hàng đặc trưng của
   khối 04 nằm ngay dưới khối kê giá trong cùng một thẻ, nên đệm và vạch của
   chúng phải bằng nhau ĐÚNG TỪNG PX. Cách chắc chắn nhất là không cho khối
   04 có con số riêng: một khai báo, hai bộ chọn.

   KHÔNG gán lớp `sl-ke` cho `.ct` thay vì làm thế này: `slVe` tìm khối kê
   bằng `box.querySelector('.sl-ke')` — trả về phần tử ĐẦU TIÊN. Thêm một
   `.sl-ke` thứ hai là đặt sẵn cái bẫy đã cắn ba lần. Dùng chung LUẬT thì
   được, dùng chung TÊN thì không. */
body.view-mobile .sl-ke,
#mb-sl .ct{padding:4px 12px 10px!important;border-top:1px solid #16171A}
body.view-mobile .sl-tong{padding:4px 12px 8px!important;min-height:53px}
/* BA NHÓM KÊ GIÁ SIẾT LẠI — [SỬA 20/08/2026].
   Chủ hệ: *"có thể giảm khoảng cách giữa 3 hàng: Khớp - %VMA20 - Giá TB;
   Sàn - TC - Trần; Thấp - Mở - Cao, hiện tại đang để giãn nhiều quá, chỉ
   giãn hơn 1 chút so với khối sổ lệnh để có sự khác một chút nhưng không
   quá nhiều như hiện tại."*

   ĐO: mỗi nhóm cao 14 (nhãn) + 18 (số) + 3 (row-gap) = 35px nội dung. Đệm
   7px trên+dưới đẩy lên 49px, tức 40% chiều cao là khoảng trắng, và ba nhóm
   cộng lại thừa 24px. Xuống 3px thì mỗi nhóm 41px — vẫn hở hơn hàng bậc giá
   (không đệm dọc riêng), đúng "khác một chút".

   KHÔNG cần `!important`: `_kv` đã thôi gõ `padding` vào inline (20/08), nên
   luật này thắng `chart.css::.sl-kv` bằng độ đặc hiệu như luật CSS thường. */
body.view-mobile .sl-kv{padding:3px 0}
body.view-mobile .sl-kv .kv-n{font-size:10px}
body.view-mobile .sl-kv .kv-v{font-size:14px}

/* ══ KHỐI 04 · DANH MỤC — HÀNG NĂM CỘT, XỔ XUỐNG ═════════════════════════
   [DỰNG LẠI 14/08/2026] Bản trước là một THẺ cao ~260px mỗi vị thế, và nó
   nói cùng một điều ba lần: nhãn `trang_thai`, câu `hanh_dong`, và thanh rủi
   ro — cả ba đều trả lời "mã này đang ở đâu so với MA50". Sáu vị thế là hơn
   1.500px cuộn trước khi thấy hết.

   Nay một hàng ~38px dùng CHUNG lưới `.mb-r5` với khối 03 và 06; chi tiết
   chỉ hiện khi chạm. Dùng chung lưới nghĩa là ba bảng không thể lệch cột
   nhau — đổi bề rộng một lần là cả ba cùng theo.
   ═══════════════════════════════════════════════════════════════════════ */
.mb-vt5{border-bottom:1px solid #15171A}
/* ── DẤU MỨC RỦI RO — [DỰNG LẠI 14/08/2026] ───────────────────────────────
   Người dùng: *"3 gạch vàng ở 3 vị thế nhìn quá xấu, nó sát vào chữ nhìn như
   bị dính vào tên mã"*. Đúng — vạch cao gần hết hàng và chỉ cách chữ 2px, nên
   mắt đọc nó thành một nét của chữ `OCB` chứ không phải một dấu riêng.

   Bản nháp đầu tôi định thay bằng CHẤM TRÒN đứng trước mã. Bỏ, vì hàng chỉ
   có 2px đệm trái — chấm phải nằm ở `left:-11px`, tức LỌT RA NGOÀI màn hình;
   mà nới đệm để chứa nó thì năm cột lệch khỏi đầu bảng đúng cái lỗi 2px vừa
   chữa xong.

   Nay là VỆT SÁNG MỜ tràn từ mép trái rồi tắt dần. Không có mép cứng nào để
   dính vào chữ, quét cả danh sách vẫn thấy ngay, và vì nó là NỀN nên không
   chiếm một pixel nào trong lưới. */
.mb-vt5.canh{background:linear-gradient(90deg,
  rgba(214,164,25,.17), rgba(214,164,25,.03) 40%, transparent 68%)}
.mb-vt5.cap{background:linear-gradient(90deg,
  rgba(224,69,58,.18), rgba(224,69,58,.035) 40%, transparent 68%)}
/* `.mb-vt5.mo` ĐÃ BỎ — 20/08/2026. Nó tô nền hàng đang XỔ, mà hàng không
   còn xổ nữa: chạm là mở tờ trượt. Lớp `mo` không nơi nào đặt, nên luật này
   là CSS mồ côi — và CSS mồ côi không kêu bao giờ. */
.mb-vt5 > .hang{display:block;width:100%;background:none;border:none;
  padding:9px 2px 10px;text-align:left;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.mb-vt5 > .hang:active{background:#0E1013}
/* GIÁ mang màu theo THAM CHIẾU, đặt bằng inline style trong `_mbHangVT` —
   không khai màu ở đây. Luật `.c.px{color:#E8E6DF}` cũ ĐÃ GỠ: inline style
   thắng nó nên nó vô hiệu, nhưng để lại thì lượt sau đọc CSS sẽ tưởng cột
   GIÁ phải trắng và đi "sửa" ngược.
   GIÁ VỐN thì mờ — số của quá khứ, không có chiều hôm nay. */
.mb-vt5 .mb-r5 .c.von{color:#8A8880}
/* Cột HÀNH ĐỘNG là CHỮ, không phải số — cho xuống dòng thay vì cắt cụt,
   vì "SÁT MA50" và "THỦNG MA50" khác nhau đúng ở chữ bị cắt. */
.mb-vt5 .mb-r5 .c.hd{font-size:10px;line-height:1.15;white-space:normal;
  overflow:visible;letter-spacing:.02em}

/* ── CHI TIẾT MỘT VỊ THẾ ──────────────────────────────────────────────────
   [ĐỔI NEO 20/08/2026] Khối này TRƯỚC nằm trong `.mb-vt5` (phần xổ dưới
   hàng); NAY nằm trong `#mb-sl`, tức thân TỜ TRƯỢT — xem `_mbHangVT`.

   Bảy luật dưới đây từng neo `.mb-vt5 .ct …`. Chuyển khối mà quên đổi neo
   thì chi tiết vị thế mất SẠCH định dạng: lưới ba cột thành dòng chảy, nhãn
   9px thành chữ thân, câu VIỆC CẦN LÀM mất viền — và KHÔNG GÌ KÊU, vì CSS
   không khớp thì im lặng bỏ qua. `test_keo_dong_sheet.py` khoá lại.

   Neo `#mb-sl .ct` chứ không neo `.ct` trần: `.ct` là tên hai chữ, quá dễ
   trùng với một lớp khác sinh sau.

   VẠCH CHIA nằm ở MÉP TRÊN: chi tiết đứng SAU sổ lệnh (chủ hệ chốt 20/08).
   Hai khối trả lời hai câu khác nhau — "thị trường đang kê giá thế nào" và
   "đang lãi lỗ ra sao, phải làm gì" — nên cần một ranh giới, không phải một
   khoảng trống. Đổi thứ tự mà quên đổi chiều vạch thì nét kẻ rơi xuống đáy
   tờ trượt, không ngăn cách gì, và CSS sai chiều thì không gì kêu.

   MỘT luật cho một bộ chọn: bản đầu tôi viết `#mb-sl .ct{}` hai lần, một
   cho đệm một cho vạch. Hai khối cùng bộ chọn là mời người sau sửa một chỗ
   rồi tưởng đã xong. */
/* ⛔ CHI TIẾT KHỐI 04 ĂN ĐÚNG LUẬT CỦA KÊ GIÁ — [SỬA 29/08/2026 lượt hai]

   Chủ hệ: *"khoảng cách giữa các dòng và các cột là khác nhau… lấy khối 03
   làm mẫu, đúng từng px một chứ không làm ang áng."*

   Bản trước tôi tự gõ `padding:7px 0 2px` và viền `#15171A` — đệm ngang 0
   (kê giá là 12px) nên cột lệch hẳn, và sắc viền lệch một bậc so với
   `#16171A` của mọi vạch chia khác. Hai con số ang áng, hai chỗ lệch.

   Nay `.ct` GHÉP VÀO CHÍNH LUẬT của `.sl-ke` ở mục ③ phía trên — một khai
   báo, hai bộ chọn, nên khối 04 không còn con số riêng nào để trôi, và đổi
   kê giá thì chi tiết đổi theo, tự động. */
/* BA HÀNG, mỗi hàng ba ô. Lưới sao chép ĐÚNG `chart.js::_kv` — cùng số cột,
   cùng `column-gap:8px`, cùng `row-gap:3px` — vì hai bảng nằm chồng nhau
   trong một tờ trượt thì phải cùng một nhịp mắt.

   CỠ CHỮ THÌ KHÔNG sao chép: hàng mang luôn lớp `sl-kv` và các ô mang
   `kv-n`/`kv-v`, nên chúng ăn thẳng luật của sổ lệnh
   (`body.view-mobile .sl-kv .kv-n` 10px · `.kv-v` 14px). Bản đầu tôi gõ
   9px/13px ở đây và chủ hệ đọc ra ngay là mất cân đối. Nay không còn con số
   cỡ chữ nào ở phía khối 04 để trôi. */
#mb-sl .ct .so{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  column-gap:8px;row-gap:3px;text-align:center}
/* VẠCH CHIA GIỮA BA HÀNG — dựng lại ĐÚNG `chart.js::_hr`, thứ ngăn các nhóm
   trong kê giá: `height:1px; background:#16171A; margin:7px 0`. Ở đây làm
   bằng viền trên + 7px mỗi bên, cho ra đúng cùng một nhịp 7·1·7. Bản trước
   là `margin-top:4px` trần — không vạch, và giãn cách khác hẳn nhóm trên. */
#mb-sl .ct .so + .so{border-top:1px solid #16171A;margin-top:7px;padding-top:7px}
/* Số của khối 04 SÁNG HƠN sổ lệnh (`_kv` mặc định `#A8A69E`): đây là số của
   riêng vị thế, không phải số thị trường chung. Chỉ khác SẮC, không khác
   CỠ — cỡ là thứ chủ hệ chê lệch. Ô nào có màu riêng (P/L, KC) thì màu
   inline thắng luật này. */
#mb-sl .ct .so .kv-v{color:#DCD9D3}
#mb-sl .ct .gc{margin-top:10px;font-size:11.5px;color:#5A5954;
  font-style:italic;line-height:1.4}

/* HAI Ô "SỔ LỆNH · CHART" ĐÃ BỎ — 20/08/2026, cùng lượt với `.hai` trong
   `mobile.js`. Sổ lệnh nay nằm ngay dưới trong cùng tờ trượt; chart là thanh
   `#mb-go` cuối tờ. Xoá luôn bốn luật `.hai` thay vì để lại: CSS mồ côi
   không kêu bao giờ, và người sau đọc nó sẽ tưởng hai nút vẫn còn. */

/* ── SÁU Ô TÓM TẮT DANH MỤC — lưới 3×2, đúng nội dung bản desktop ──────────
   Sáu cột trên một hàng ở 390px là mỗi cột 65px; "1,22 tỷ" không nằm vừa.
   Chia 3×2 giữ đủ sáu ô mà mỗi ô còn ~118px. */
.mb-o6{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;
  background:#15171A;border-bottom:1px solid #15171A}
.mb-o6 > div{background:#08090B;padding:12px 3px 13px;text-align:center;min-width:0}
.mb-o6 .k{font-family:var(--mono);font-size:8.5px;letter-spacing:.07em;
  color:#4E4D49;line-height:12px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mb-o6 .v{margin-top:6px;font-family:var(--mono);font-size:16px;line-height:20px;
  white-space:nowrap}
/* Dòng phụ giữ chiều cao kể cả khi rỗng, để sáu ô cao bằng nhau. */
.mb-o6 .p{margin-top:3px;font-family:var(--mono);font-size:9.5px;
  color:#5A5954;min-height:12px;line-height:12px;white-space:nowrap}

/* NỚI ĐẦU BẢNG DANH MỤC KHỎI LƯỚI SÁU Ô — [SỬA 14/08/2026].
   Người dùng: *"nới khoảng cách dòng tiêu đề của danh mục xuống 1 chút so
   với box 6 ô thông tin tổng hợp nhìn cho nó đỡ bị díu mắt"*.

   Từ lúc gỡ thẻ "N VỊ THẾ cần xử lý", `.mb-hd5` dính ngay dưới `.mb-o6` —
   hai lưới khác hẳn nhau về vai trò mà không có gì ngăn, nên mắt đọc chúng
   thành một khối.

   Bộ chọn ANH EM KỀ chứ không phải `#mb-t4 .mb-hd5`: `.mb-hd5` dùng chung
   với khối 03 và 06, và chỉ ở tab 4 nó mới đứng ngay sau lưới sáu ô. Ràng
   theo QUAN HỆ thì luật tự đúng ở bất kỳ tab nào có cùng cấu trúc, không
   phải nhớ sửa lại khi đổi số hiệu tab. */
.mb-o6 + .mb-hd5{margin-top:18px}

/* ── ĐẦU HỘP SỔ LỆNH — ẨN TRÊN MOBILE ─────────────────────────────────────
   `slBlock` gắn một dòng `MÃ · giá · %` ở đầu hộp cho bản DESKTOP, nơi hộp
   xổ ra bên dưới hàng và hàng đã trôi khỏi tầm mắt.

   Mobile thì thanh tiêu đề tờ trượt (`.mb-sheet .hd`) đã mang đúng ba số ấy
   VÀ nó dính khi cuộn — hữu ích hơn hẳn. Giữ cả hai là nói hai lần trên một
   màn hình 390px, đúng thứ người dùng gọi là "trùng thông tin". */
body.view-mobile .sl-dinh{display:none!important}

/* [GỠ 23/08/2026] Ba luật `.mb-sheet .hd u/i.diem/s` từng khai LẠI ở đây,
   và ô khối lượng `.mb-sheet .hd em` từng nằm ngay dưới.

   Ba luật số nay khai TRỌN ở chỗ định nghĩa gốc (cạnh `.hd .san`) — một
   luật một ô. Khai hai lần thì cascade vẫn ra đúng, nhưng ai đọc mã sẽ thấy
   lần khai đầu và tin đó là tất cả.

   Ô khối lượng gỡ HẲN: nó mang `flex:0 0 100%` với ý xuống DÒNG RIÊNG,
   nhưng `.hd` là flex `nowrap` nên nó nằm CÙNG HÀNG và làm thanh tiêu đề
   tràn ngang — chủ hệ: *"bị vỡ định dạng vì khi mở tờ trượt thì bị thừa
   thông tin khối lượng khi kéo ngang tờ trượt."* Một luật viết cho `wrap`
   đặt vào một hàng `nowrap`, im lặng từ 15/08 vì tràn ngang chỉ lộ ra khi
   có ai kéo thử. Gỡ cả hàm `_mbSheetKL`, phần tử `<em>`, và lời gọi mỗi
   giây trong `mbVe`. */

/* ══ KHỐI 05 · BỐN HỢP ĐỒNG PHÁI SINH — MỖI CÁI MỘT HÀNG ═════════════════
   [DỰNG LẠI 14/08/2026] Bản trước là bốn THẺ, mỗi thẻ năm dòng rời — cao gần
   600px cho hai mươi con số, và số của hợp đồng này không thẳng hàng với số
   của hợp đồng kia. Muốn so basis giữa F1M và F2M phải đưa mắt chéo cả khối.

   Nay dùng CHUNG lưới `.mb-r5` với khối 03·04·06 — bốn bảng, một lưới.
   ═══════════════════════════════════════════════════════════════════════ */
/* Đệm ngang 2px GIỐNG HỆT `.mb-hd5` và `.mb-row` — thiếu nó thì hàng hợp
   đồng lệch đúng 2px khỏi ba bảng kia. Đo được, không nhìn ra bằng mắt. */
.mb-ps5{border-bottom:1px solid #15171A;padding:9px 2px 10px}

/* CỘT MÃ 62px — vừa `VN30F1M` (bảy ký tự ở 12,5px mono ≈ 56px). Khai ở ĐÂY,
   một chỗ, để cả bốn bảng năm cột cùng theo: khối 03 watchlist, khối 04 danh
   mục, khối 05 hợp đồng, khối 06 rổ VN30. Mã ba ký tự chỉ dôi chỗ, không sai. */
.mb-ps5 .mb-r5 .tk{font-size:12.5px;letter-spacing:-.02em}
/* Số phiên còn lại — nhỏ, mờ, nằm sau mã. Nó là ngữ cảnh của mã chứ không
   phải một đại lượng riêng, nên không được chiếm cột. */
.mb-ps5 .mb-r5 .tk i{font-style:normal;font-size:9px;color:#5A5954;margin-left:3px}

/* GIÁ hợp đồng TRUNG TÍNH — người dùng: *"chỉ số thì để màu trắng giống ở
   khối 01, % thay đổi và số điểm thay đổi mới đổi màu theo giá trị"*. */
.mb-ps5 .mb-r5 .c.px{color:#E8E6DF;font-size:13.5px}

/* `%` VÀ SỐ ĐIỂM — HAI DÒNG, không nhét chung một dòng.
   Đo được lượt đầu: `-1,17%-22.3` dính liền và TRÀN ô. Chúng là hai đại
   lượng của cùng một chiều nên ở chung cột là đúng, nhưng phải xuống dòng
   thì mắt mới tách được. */
.mb-ps5 .mb-r5 .c em{display:block;font-style:normal;font-size:10px;
  line-height:13px;opacity:.85;margin-top:1px}
.mb-ps5 .mb-r5 .c{white-space:normal;line-height:15px}
.mb-ps5 .mb-r5 .c.kl{color:#8A8880;font-size:11.5px}

/* ── TIÊU ĐỀ KHỐI MANG LUÔN CHỈ SỐ ────────────────────────────────────────
   Bỏ dòng `.mb-coso` riêng: nó chỉ chở hai con số mà chiếm trọn một dòng.
   Chỉ số TRUNG TÍNH, chỉ `%` đổi màu — cùng luật với bốn hợp đồng ở trên và
   với băng chỉ số khối 01. Ba chỗ, một luật. */
.mb-h-idx .idx{text-decoration:none;margin-left:auto;font-family:var(--mono);
  font-size:14px;color:#E8E6DF}
.mb-h-idx .idxp{text-decoration:none;margin-left:7px;font-family:var(--mono);
  font-size:11.5px}

/* ── RỔ VN30 ──────────────────────────────────────────────────────────────
   [SỬA 14/08/2026 lượt hai] Người dùng: *"2 bảng cùng là 5 cột thì không có
   lí do gì không làm thẳng hàng cả 2 bảng với nhau… cột khối lượng của vn30
   bạn phải căn phải để nó thẳng tắp chứ? … căn chỉnh theo tiêu chuẩn chứ ko
   phải làm bừa, tạm bợ"*.

   Phê bình đúng. Lượt trước tôi vá theo TỪNG KHỐI: căn giữa ba cột ở khối
   06, ép cột NSyS còn 44px, đổi bề rộng riêng cho khối 05. Ba luật riêng cho
   ba bảng vốn dùng CHUNG một lưới — chính là lộn xộn.

   Và chúng thừa: `.mb-hd5` gốc ĐÃ đúng chuẩn bảng số từ đầu —

       cột chữ (MÃ)   căn TRÁI
       cột số         căn PHẢI, để chữ số thẳng cột
       tiêu đề cột    căn theo đúng cột của nó

   Nên bản vá đúng chỉ có MỘT dòng: nới cột mã ở `.mb-r5` và `.mb-hd5` cho
   vừa `VN30F1M` (bảy ký tự). Sửa một chỗ, bốn bảng cùng theo — đó mới là lý
   do chúng dùng chung lưới.

   Toàn bộ luật `#mb-t3 …` và `.mb-ps5 .mb-r5{grid-template-columns…}` ĐÃ GỠ. */



/* ══════════════════════════════════════════════════════════════════════════
   HAI TRANG TRONG TỜ TRƯỢT — [VIẾT LẠI 04/09/2026]
   ══════════════════════════════════════════════════════════════════════════
   Chủ hệ bác bản đầu: *"bản chất vẫn là 1 panel chỉ là kéo giãn độ rộng…
   chứ không phải là 2 panel riêng biệt nên khi trượt nó không trơn chu."*

   ĐÚNG, VÀ ĐÓ LÀ LỖI THIẾT KẾ CHỨ KHÔNG PHẢI LỖI TINH CHỈNH. Bản đầu dùng
   `.mb-bang{width:200%}` với hai con nằm cạnh nhau — nên chiều cao khung là
   MAX của hai trang. Sổ lệnh ba bậc cao gấp mấy lần trang cơ bản, và trang
   cơ bản thừa ra một khoảng trắng đúng bằng phần chênh. Trượt sang thì tờ
   trượt không đổi cao, nhìn như một tấm bị kéo giãn — vì nó đúng là thế.

   NAY HAI TRANG ĐỘC LẬP: chỉ trang đang xem nằm trong luồng (`display`),
   nên chiều cao tờ trượt bằng chiều cao THẬT của trang ấy. Chuyển bằng ảnh
   động vào (mờ + trượt nhẹ 14px) thay vì kéo 1:1 — cũng là lý do đã ghi ở
   `_mbKeoDi`: kéo `transform` của cây sổ lệnh 60 lần/giây là quá đắt.

   ⚠ BIẾN MÀU: `--bg` · `--panel` · `--panel2` · `--line` · `--ink` ·
   `--ink-soft` · `--ink-faint` · `--chart`. Bản đầu tôi gõ `--nen`,
   `--nen-2`, `--vach` — KHÔNG TỒN TẠI, nên nền và viền không vẽ gì cả và
   khối chỉ tiêu trơ ra thành danh sách chữ. Đó mới là "nhìn rất xấu", không
   phải bố cục.

   `--chart` = `--s-dat` = #D97757, đúng màu logo Claude.
   ══════════════════════════════════════════════════════════════════════════ */
.mb-trang{display:flex;gap:5px;padding:0 12px 10px}
.mb-trang button{
  flex:1;padding:7px 0;cursor:pointer;
  border:1px solid var(--line);border-radius:8px;background:transparent;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.7px;
  color:var(--ink-faint);
  transition:background .15s ease,color .15s ease,border-color .15s ease;
}
.mb-trang button.on{
  background:var(--chart);border-color:var(--chart);
  color:var(--bg);font-weight:600;
}

.mb-bang{
  position:relative;
  /* ── `touch-action: pan-y` LÀ PHẦN THEN CHỐT — [THÊM 04/09/2026] ────────
     Chủ hệ ba lần báo vuốt kẹt. Hai lần đầu tôi chỉnh ngưỡng (34 -> 20) và
     vẫn kẹt, vì gốc không nằm ở ngưỡng.

     Không khai `touch-action`, trình duyệt tự quyết cử chỉ này là CUỘN DỌC
     ngay khi thấy thành phần dọc đầu tiên — thường trong 1-2 khung hình đầu.
     Sau khi đã khoá thì `preventDefault` trong `touchmove` KHÔNG gỡ được
     nữa. Đua với trình duyệt bằng ngưỡng là đua không thắng: ngưỡng càng
     nhỏ càng dễ nhầm với cuộn, càng lớn càng trễ hơn lúc nó khoá.

     `pan-y` khai TRƯỚC, ngay lúc dựng: chiều dọc là của trình duyệt, chiều
     NGANG là của ta. Không còn cuộc đua nào để thua. */
  touch-action:pan-y;
}
.mb-tr{display:none}
.mb-tr.on{display:block;animation:mbTrVao .19s cubic-bezier(.22,.61,.36,1)}
@keyframes mbTrVao{
  from{opacity:0;transform:translateX(var(--mb-tu,14px))}
  to{opacity:1;transform:none}
}

/* ── TRANG CƠ BẢN ─────────────────────────────────────────────────────────
   Chủ hệ: *"bạn không thiết kế thông tin ở tab cơ bản, nhìn dạng liệt kê
   rất xấu, tôi cần 1 sự chuyên nghiệp ở đây."*

   Bản đầu đổ 12 ô vào một lưới phẳng — mười hai con số ngang hàng nhau thì
   mắt không biết đọc cái nào trước. Nay chia THEO CÂU HỎI người đọc đang
   hỏi, và mỗi nhóm khai luôn kỳ/cơ sở của nó:

       hero      VỐN HOÁ      con số nhận dạng doanh nghiệp
       ĐỊNH GIÁ  P/E P/B EPS BVPS     "theo giá hiện tại"
       HIỆU QUẢ  ROE ROA Biên LNST    "4 quý gần nhất"
       CẤU TRÚC  Nợ/VCSH Cổ tức NN

   Nhãn nhóm mang cả CƠ SỞ TÍNH, vì P/E theo giá sống và ROE theo quý là hai
   thời điểm khác nhau — để chúng cạnh nhau mà không nói gì là mời đọc nhầm. */
.cb-ten{
  padding:2px 12px 0;font-size:14.5px;line-height:1.35;font-weight:600;
  color:var(--ink);letter-spacing:.1px;
}
.cb-chip{display:flex;gap:5px;padding:6px 12px 0;flex-wrap:wrap}
.cb-chip span{
  font-family:var(--mono);font-size:9px;letter-spacing:.5px;
  padding:3px 7px;border-radius:5px;
  background:var(--panel);color:var(--ink-faint);
}
/* ── HAI Ô NỔI BẬT CẠNH NHAU — [SỬA 05/09/2026] ────────────────────────
   Chủ hệ: *"không nâng chiều cao của panel nữa, còn nhiều deadspace có thể
   tối ưu mà không cần mở rộng diện tích."*

   Bản trước là MỘT ô cao 60px chứa vốn hoá, với dòng CP lưu hành nhỏ bên
   dưới. Hai ô cạnh nhau chiếm ĐÚNG chiều cao ấy mà chứa gấp đôi — vốn hoá
   và CP lưu hành ngang hàng, cả hai đều là số nhận dạng quy mô. */
.cb-hero{
  margin:12px 12px 0;display:grid;grid-template-columns:repeat(3,1fr);gap:1px;
  background:var(--line);border:1px solid var(--line);
  border-radius:10px;overflow:hidden;
}
/* CĂN GIỮA cho đồng bộ với lưới chỉ tiêu bên dưới — chủ hệ 05/09.
   Hàng quan trọng nhất mà lệch trục với phần còn lại thì mắt phải
   đổi điểm neo hai lần khi đọc từ trên xuống. */
.cb-hero > div{background:var(--panel);padding:9px 8px 8px;text-align:center}
.cb-hero b{
  display:block;font-family:var(--mono);font-size:8.5px;letter-spacing:.6px;
  color:var(--ink-faint);font-weight:400;
}
.cb-hero em{
  display:block;font-family:var(--mono);font-size:13.5px;font-style:normal;
  color:var(--chart);margin-top:3px;letter-spacing:-.3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.cb-nhom{margin:11px 12px 0}
.cb-nhom h4{
  margin:0 0 6px;font-family:var(--mono);font-size:9px;letter-spacing:.7px;
  color:var(--ink-faint);font-weight:400;
  display:flex;justify-content:space-between;align-items:baseline;
}
.cb-nhom h4 em{font-style:normal;font-size:8.5px;color:var(--ink-dim)}
/* BỐN CỘT, không phải hai: mỗi nhóm gọn trong MỘT hàng thay vì hai, nên
   bốn nhóm chiếm đúng chỗ hai nhóm cũ. Nhãn ngắn (`P/E`, `NIM`, `LDR`) nên
   4 cột vẫn đọc được trên màn 360px — ô rộng ~78px. */
.cb-luoi{
  display:grid;grid-template-columns:repeat(4,1fr);gap:1px;
  background:var(--line);border:1px solid var(--line);
  border-radius:9px;overflow:hidden;
}
.cb-o{background:var(--panel2);padding:7px 6px 6px;text-align:center}
.cb-o b{
  display:block;font-family:var(--mono);font-size:8.5px;letter-spacing:.3px;
  color:var(--ink-faint);font-weight:400;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.cb-o span, .cb-o span b{
  display:block;font-family:var(--mono);font-size:12.5px;margin-top:2px;
  color:var(--ink-soft);font-weight:400;
}
/* ══════════════════════════════════════════════════════════════════════
   BẢNG THEO QUÝ — [THÊM 07/09/2026]
   ══════════════════════════════════════════════════════════════════════
   Chủ hệ: *"phần ghi chỉ số theo quý cực kỳ xấu về bố cục… không phải vứt
   bừa vào ô đủ để đọc như hiện tại. Phần trên đã rất đẹp và ngăn nắp rồi."*

   Bản đầu mượn `.cb-luoi`/`.cb-o` — lưới BỐN CỘT của những ô "nhãn trên,
   số dưới". Nó sinh ra cho *bốn chỉ tiêu ngang hàng*, không cho *một bảng
   có hàng và cột*. Nhồi lịch sử quý vào đó thì kỳ thành nhãn, hai con số
   khác đơn vị dính vào nhau trong một ô, không số nào thẳng cột nào, và ba
   quý để lại một ô trống lệch ở cuối hàng.

   ── VÌ SAO `auto` RỒI MỚI `3×1fr` ────────────────────────────────────
   Cột kỳ (`2026 Q2`) rộng cố định theo nội dung; ba cột số chia đều phần
   còn lại. Ngược lại — `4×1fr` — thì cột kỳ thừa chỗ còn cột số chật, và
   trên màn 360px số bắt đầu xuống dòng.

   ── VÌ SAO CĂN PHẢI + `tabular-nums` ─────────────────────────────────
   Đây là thứ duy nhất làm một cột số ĐỌC ĐƯỢC theo chiều dọc: chữ số cùng
   bề rộng nên dấu phẩy thập phân thẳng hàng, mắt so `13,05 / 11,98 / 13,49`
   trong một lượt quét thay vì đọc từng ô. Căn giữa như `.cb-o` là đúng cho
   một ô đứng riêng, sai cho một cột.

   Giữ nguyên `--mono`, `--ink-faint` cho nhãn, `--ink-soft` cho số, viền
   1px trên nền `--line` — cùng bộ với `.cb-hero` và `.cb-luoi`. Một tấm,
   một phong cách. */
.cb-quy{
  display:grid;grid-template-columns:auto repeat(3,1fr);gap:1px;
  background:var(--line);border:1px solid var(--line);
  border-radius:9px;overflow:hidden;
}
.cb-quy > span{
  background:var(--panel2);padding:6px 9px 5px;
  font-family:var(--mono);font-variant-numeric:tabular-nums;
  white-space:nowrap;
}
/* Đầu bảng: nền `--panel` để tách khỏi thân, cùng lối `.cb-hero > div`. */
.cb-quy > .cb-qh{
  background:var(--panel);padding:5px 9px 4px;
  font-size:8.5px;letter-spacing:.6px;color:var(--ink-faint);text-align:right;
}
.cb-quy > .cb-qk{font-size:11px;color:var(--ink-dim);letter-spacing:.2px}
.cb-quy > .cb-qs{font-size:12.5px;color:var(--ink-soft);text-align:right}
/* Kỳ ĐANG BÀY ở phần trên — nối hai khối bằng màu. Không tô nền: nền đổi
   sẽ phá đường kẻ 1px vốn là thứ giữ bảng ngay ngắn. */
.cb-quy > .nay{color:var(--chart)}
/* ── ĐÃ GỠ `.cb-ch` — [07/09/2026] ────────────────────────────────────
   Chân panel cũ ghi `Số tài chính kỳ … · biết từ … · cập nhật …`. Bảng
   THEO QUÝ ngay trên đã tô hàng của kỳ đang bày, nên dòng ấy chỉ nhắc lại
   điều mắt vừa thấy. Chủ hệ: *"bỏ dòng dưới cùng đi nữa là xong."*

   Gỡ cả luật, không để lại: một lớp không ai dùng là một lời mời dùng lại
   nó cho việc khác rồi lệch mất bố cục. */

/* TRỢ NĂNG — mọi hiệu ứng phải có nhánh này, và `test_vuot_doi_tab` bắt
   đúng lúc tôi quên nó cho `.mb-tr.on`. Ảnh động chuyển trang là trang
   trí; người tắt chuyển động vẫn phải đổi trang được, chỉ là đổi ngay. */
@media (prefers-reduced-motion: reduce){
  .mb-tr.on{animation:none}
  .mb-trang button{transition:none}
}


/* ══════════════════════════════════════════════════════════════════════════
   PANEL LỊCH CHIA — tab Cổ Phiếu, xổ xuống  [THÊM 06/09/2026]
   ══════════════════════════════════════════════════════════════════════════
   Chủ hệ: *"thiết kế tương đồng với các panel khác trong tab cổ phiếu, và là
   1 panel ấn xổ xuống, mặc định là không xổ."*

   Mượn đúng ngôn ngữ của `.mb-hd5` (đầu bảng khối 02/03): phông đều, chữ
   nhỏ giãn, màu `--ink-faint`. Không dựng quy ước thứ hai.

   ⚠ BIẾN MÀU: `--bg` · `--panel` · `--panel2` · `--line` · `--ink` ·
   `--ink-soft` · `--ink-faint` · `--chart`. Đã cắn 04/09 khi gõ `--nen`,
   `--vach` — hai biến KHÔNG TỒN TẠI, nên nền và viền không vẽ gì cả.
   ══════════════════════════════════════════════════════════════════════════ */
/* Lề khai ở khối "BẢNG NĂM CỘT QUYỀN" bên dưới — [07/09/2026] nới
   `12px -> 6px` để bảng rộng thêm 12px và chữ to lên được. */
.mb-lc-hd{
  width:100%;display:grid;grid-template-columns:auto 1fr auto;
  align-items:center;gap:8px;
  background:var(--panel);border:1px solid var(--line);border-radius:9px;
  padding:9px 11px;cursor:pointer;
}
.mb-lc-hd b{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.7px;
  color:var(--ink);font-weight:600;
}
.mb-lc-hd span{
  font-family:var(--mono);font-size:9.5px;color:var(--ink-faint);
  text-align:right;
}
/* Mũi xoay 90° khi mở — cùng lối các nút xổ khác, và rẻ hơn hẳn so với
   đổi ký tự (không phải lo phông thiếu glyph). */
.mb-lc-hd i{
  font-style:normal;font-size:15px;line-height:1;color:var(--chart);
  transition:transform .16s ease;display:inline-block;
}
.mb-lc-hd i.x{transform:rotate(90deg)}

/* ── THÂN PANEL: KHỐI THEO NGÀY — [THIẾT KẾ LẠI 06/09/2026] ────────────
   Chủ hệ: *"sắp xếp chữ và giá cũng thò thụt rất tệ."*

   GỐC: bản đầu để mỗi hàng tự co theo nội dung, nên cột giá của `8,50` và
   `126,62` không thẳng nhau, và mắt phải dò lại từ đầu mỗi dòng.

   Nay lưới CỐ ĐỊNH bốn cột — mã · giá · nhãn · nút. Ba cột đầu neo trái/
   phải rõ ràng, và giá dùng `tabular-nums` để chữ số không co giãn. Đọc
   theo cột chứ không theo dòng: đó là khác biệt giữa một bảng và một danh
   sách chữ. */
.mb-lc-than{
  border:1px solid var(--line);border-top:none;border-radius:0 0 9px 9px;
  overflow:hidden;
}
/* ── ĐÃ GỠ `.mb-lc-ng` — [07/09/2026] ─────────────────────────────────
   Dòng ngày từng là một `div` RIÊNG, ngoài lưới bảng. Đó chính là nguyên
   nhân đường kẻ cột "dừng lưng chừng": `gap:1px` chỉ kẻ được giữa các ô
   TRONG một lưới, nên mỗi ngày một lưới là mỗi ngày một chỗ đứt.

   Nay nó là ô `.mb-lc-b > .ng` bên trong lưới chung — xem khối dưới. */

/* ══════════════════════════════════════════════════════════════════════
   MỘT LƯỚI DUY NHẤT — [SỬA 07/09/2026, lượt ba]
   ══════════════════════════════════════════════════════════════════════
   Chủ hệ: *"bạn kẻ cột bị không hoàn thiện bởi dòng ngày tháng, các cột ở
   giữa dòng kẻ cột bị dừng lưng chừng mà không có dòng kẻ gạch ngang."*

   ⛔ ĐÚNG, VÀ GỐC LÀ HAI LƯỚI RỜI. Đường kẻ ở đây không phải `border` —
   nó là `gap:1px` để lộ nền `--line` phía sau. Mà `gap` chỉ tồn tại GIỮA
   các ô TRONG một lưới. Bản trước dựng dòng ngày là `div` riêng rồi MỘT
   lưới cho mỗi ngày, nên mỗi dải ngày là một lưới mới: đường dọc dừng ở
   mép lưới, và không có gì nối chúng qua dòng ngày.

   Nay dòng ngày là một Ô `grid-column:1/-1` TRONG chính lưới ấy — `gap`
   sinh đường ngang liền cả hai phía nó, đường dọc chạy đúng tới mép mỗi
   dải. Không nét nào cụt, và không cần thêm một `border` nào.

   ── ĐẦU BẢNG CHỈ MỘT LẦN ─────────────────────────────────────────────
   Lưới chung nghĩa là cột thẳng trục qua MỌI ngày, nên đầu bảng không phải
   lặp lại mỗi dải. Bớt một dòng cho mỗi ngày — với cửa sổ 10 ngày là bớt
   khoảng chục dòng, đúng hướng chủ hệ muốn danh sách ngắn lại.

   ── LƯỚI LẤY ĐÚNG CỦA WATCHLIST ──────────────────────────────────────
   `.mb-r5` (khối 02/03) dùng `62px repeat(4,minmax(0,1fr))`. Chép đúng con
   số ấy chứ không tự chọn: hai bảng chồng nhau trên cùng màn hình mà lệch
   trục thì mắt phải đổi điểm neo giữa chừng. */
.mb-lc{margin:15px 6px 0}
.mb-lc-b{
  display:grid;grid-template-columns:62px repeat(4,minmax(0,1fr));
  align-items:center;background:var(--line);gap:1px;
}
.mb-lc-b > span, .mb-lc-b > .r{
  background:var(--panel2);padding:7px 7px 6px;
  font-family:var(--mono);font-variant-numeric:tabular-nums;
}
/* Đầu bảng: nền `--panel` để tách khỏi thân, cùng lối `.cb-quy > .cb-qh`.
   Nhãn ĐẦY ĐỦ (`Tiền mặt`·`Cổ phiếu`) thay cho `CT TM`·`CT CP` — chủ hệ
   07/09; panel tên "LỊCH SỰ KIỆN" nên chữ "cổ tức" đã ở trong ngữ cảnh. */
.mb-lc-b > .h{
  background:var(--panel);padding:5px 7px 4px;
  font-size:9px;letter-spacing:.3px;color:var(--ink-faint);text-align:right;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.mb-lc-b > .h.l{text-align:left;padding-left:11px}
/* DẢI NGÀY — một ô trải hết bề ngang, nên `gap` kẻ liền trên và dưới nó. */
.mb-lc-b > .ng{
  grid-column:1 / -1;background:var(--panel);
  display:flex;justify-content:space-between;align-items:baseline;
  padding:7px 11px 6px;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.5px;
  color:var(--ink);font-weight:600;
}
.mb-lc-b > .ng em{
  font-style:normal;font-size:9px;font-weight:400;color:var(--ink-faint);
}
/* NGÀY HÔM NAY nổi bằng một vạch màu bên trái — không tô nền, vì tô nền thì
   nó cạnh tranh với chính các hàng dữ liệu bên dưới. */
.mb-lc-b > .ng.nay{border-left:2px solid var(--chart);padding-left:9px}
.mb-lc-b > .ng.nay,
.mb-lc-b > .ng.nay em{color:var(--chart)}
.mb-lc-b > .r{
  border:none;cursor:pointer;text-align:left;padding-left:11px;
  font-size:13.5px;color:var(--ink);font-weight:600;letter-spacing:.3px;
}
.mb-lc-b > .r:active{color:var(--chart)}
.mb-lc-b > .v{
  font-size:12.5px;color:var(--chart);text-align:right;white-space:nowrap;
}
/* Ô TRỐNG là dấu chấm mờ, không phải khoảng trắng: bốn ô trắng trơn trông
   như lỗi tải, bốn dấu chấm nhạt đọc ra ngay "mã này chỉ có một loại". */
.mb-lc-b > .v.rong{color:var(--ink-faint)}
/* Dòng phụ cho nhóm `khac` — riêng lẻ · CBCNV · trái phiếu · đấu giá.
   Không cho cổ đông hiện hữu quyền gì nên không có cột, nhưng có thật nên
   không được giấu. */
.mb-lc-b > .kh{
  grid-column:1 / -1;font-size:10px;color:var(--ink-dim);
  padding:2px 11px 6px;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis;
}
.mb-lc-tt{
  padding:12px 11px;border:1px solid var(--line);border-top:none;
  border-radius:0 0 9px 9px;background:var(--panel2);
  font-size:12px;color:var(--ink-faint);
}

/* ── HOA THỊ: MÃ CÓ SỰ KIỆN Ở PHIÊN ĐANG XEM — [THÊM 06/09/2026] ───────
   Chủ hệ: *"để không cần ấn vào tờ trượt hoặc không cần mở panel lịch sự
   kiện cũng biết là chúng đang có sự kiện."*

   `sup` chứ không phải ký tự trong chuỗi mã: dấu sao nằm ngoài luồng chữ
   nên KHÔNG làm lệch cột mã — mà cột ấy vừa được căn thẳng ở trên. */
.mb-sk-sao{
  color:var(--chart);font-size:11px;line-height:0;margin-left:2px;
  vertical-align:super;
}


@media (prefers-reduced-motion: reduce){
  .mb-lc-hd i{transition:none}
}


/* ══ THANH TIÊU ĐỀ TỜ TRƯỢT: CÂN LẠI — [SỬA 06/09/2026] ══════════════════
   Chủ hệ: *"chip sàn và chip chart đang không được căn thẳng nhau, hơi lệch
   ở bottom thì phải."*

   ĐÚNG, VÀ GỐC LÀ `align-items:baseline` CỦA `.hd`.

   `<b>` tên mã có đường chân chữ. Chip `.san` cũng có, nhưng đường chân ấy
   nằm BÊN TRONG hộp có đệm và viền, nên mép dưới hộp thấp hơn đường chân.
   Còn `<svg>` thì KHÔNG có chữ nào — trình duyệt lấy MÉP DƯỚI của nó làm
   đường chân. Ba thứ, ba mốc khác nhau, xếp trên một đường.

   LUẬT NHÀ ĐÃ CÓ, ghi ở `chart.css`: *"CHỮ căn đường chân, BIỂU TƯỢNG căn
   giữa."* Áp đúng luật ấy: giữ `baseline` cho tên mã, còn chip và biểu
   tượng thì `align-self:center`. */
.mb-sheet .hd .mo-chart{display:inline-flex;align-items:baseline;gap:7px}
.mb-sheet .hd .mo-chart svg{align-self:center}
.mb-sheet .hd .san{align-self:center}

/* ── DÒNG SỰ KIỆN QUYỀN — [VIẾT LẠI 06/09/2026] ────────────────────────
   Chủ hệ: *"cho chip GDKHQ xuống dòng riêng, không cần đóng khung, nó quá
   nổi bật, chỉ cần 1 dòng với màu claude."*

   ĐÚNG, VÀ ĐÓNG KHUNG LÀ SAI CẤP BẬC. Khung viền là ngôn ngữ của thứ CHẠM
   ĐƯỢC hoặc thứ PHẢI QUYẾT — chip sàn, nút, thẻ. Dòng này chỉ là một ghi
   chú: "mã này sắp chia". Cho nó khung là đẩy nó lên ngang hàng giá và %,
   trong khi nó đứng dưới cả hai.

   Màu Claude giữ lại — đủ để mắt bắt được mà không cần khung.

   `order:9` + `flex:0 0 100%` giữ nguyên: đó là thứ ép xuống dòng. Bỏ
   `max-width` vì nay không còn hộp để kẹp.

   ── CHIỀU CAO: BỚT KHOẢNG CHẾT ────────────────────────────────────────
   Chủ hệ: *"tiêu đề tờ trượt này phía trên bị thừa nhiều khoảng chết."*
   `.hd` đang `padding:10px 15px 12px 0`. Với dòng sự kiện thêm vào, tổng
   cao lên gần 90px cho một thanh chỉ mang bốn thông tin. Hạ đệm dưới còn
   8px và `margin-top` của dòng còn 3px — tiết kiệm 8px mà không dòng nào
   chạm nhau. */
.mb-sheet .hd .sk{
  order:9;flex:0 0 100%;align-self:flex-start;margin-top:3px;
  font-family:var(--mono);font-size:10px;letter-spacing:.3px;
  color:var(--chart);
}
.mb-sheet .hd .sk:empty{display:none;margin:0}
.mb-sheet .hd .sk.qua{color:var(--ink-faint)}

/* ══════════════════════════════════════════════════════════════════════════
   NÚT ⓘ — [THÊM 16/09/2026]
   ══════════════════════════════════════════════════════════════════════════
   Hình 26px, vùng chạm 44px. Hai con số khác nhau và cố ý: mắt cần 26 để nút
   không lấn tên mã trên màn 360px, ngón cái cần 44 để không bấm trượt. Gộp
   chúng làm một là hoặc nút xấu hoặc nút khó bấm.

   Ở TRẠNG THÁI NGHỈ NÓ MỜ. Nút này không phải việc chính của tờ trượt — sổ
   lệnh mới là. Một nút sáng bằng tên mã sẽ tranh chú ý mỗi lần mở tờ, mà
   người ta chỉ cần nó thỉnh thoảng. `--ink-dim` đủ để thấy, không đủ để gọi.
   ══════════════════════════════════════════════════════════════════════════ */
.hd .mb-i{
  order:9;                       /* cuối thanh, cùng luật `.sk` */
  flex:none;
  display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;margin:-9px -6px -9px 0;   /* vùng chạm nở ra ngoài */
  padding:0;border:0;background:none;cursor:pointer;
  color:var(--ink-dim);
  -webkit-tap-highlight-color:transparent;
}
.hd .mb-i svg{
  width:26px;height:26px;display:block;
  /* Chuyển màu chậm hơn chuyển hình: mắt bắt màu trước, và nếu cả hai cùng
     nhanh thì cú chạm trông giật. */
  transition:color .18s ease, transform .12s ease;
}
.hd .mb-i:hover{color:var(--ink-soft)}
.hd .mb-i:active svg{transform:scale(.9)}
.hd .mb-i.on{color:var(--gold)}
.hd .mb-i:focus-visible{outline:2px solid var(--gold);outline-offset:-10px;
  border-radius:50%}

/* ══════════════════════════════════════════════════════════════════════════
   LỚP PHỦ CƠ BẢN — [THÊM 16/09/2026]
   ══════════════════════════════════════════════════════════════════════════
   Che kín màn, trượt lên từ dưới. KHÔNG dùng `position:absolute` trong tờ
   trượt: tờ ấy có `transform` riêng khi kéo, và một lớp con `absolute` sẽ đi
   theo phép biến hình của cha — nghĩa là lớp phủ rung theo mỗi lần kéo tờ.
   `position:fixed` neo vào khung nhìn, đứng yên.
   ══════════════════════════════════════════════════════════════════════════ */
.mb-cblop{
  position:fixed;inset:0;z-index:90;display:flex;flex-direction:column;
  background:var(--bg);
  overscroll-behavior:none;
  transform:translateY(100%);
  transition:transform .26s cubic-bezier(.32,.72,0,1);
  visibility:hidden;
}
.mb-cblop.on{transform:none;visibility:visible}
/* ⛔ ✕ BÊN TRÁI — [SỬA 16/09/2026].
   Chủ hệ: *"nút tắt x thì lại ở góc trên cùng bên tay phải, tôi dùng điện
   thoại tay trái nên tắt rất khó."*

   Bản đầu tôi đặt bên phải và còn viết hẳn một lý do nghe hợp lý: "ô tra mã
   mở kèm bàn phím nên ✕ bên trái, lớp phủ này cuộn bằng ngón cái phải". Lý
   do ấy dựng trên một giả định TÔI TỰ ĐẶT về tay nào cầm máy — và giả định
   ấy sai. Ngày 11/09 chủ hệ đã dời ✕ của ô tra mã sang trái vì đúng lý do
   này; tôi có dữ kiện ấy trong tay mà vẫn suy ra ngược.

   Nay ✕ bên trái ở CẢ HAI chỗ. Một chỗ thoát, một vị trí. */
.mb-cbhd{
  flex:none;display:flex;flex-direction:row-reverse;align-items:center;gap:10px;
  padding:calc(env(safe-area-inset-top,0px) + 12px) 14px 11px;
  border-bottom:1px solid var(--line);background:var(--panel2);
}
.mb-cbhd .tn{flex:1;min-width:0;font-size:14px;font-weight:600;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mb-cbhd .x{
  flex:none;width:40px;height:40px;margin:-8px 0 -8px -10px;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:17px;line-height:1;color:var(--ink-dim);
  background:none;border:0;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
}
.mb-cbhd .x:active{color:var(--ink)}
.mb-cbtb{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
  padding:0 0 calc(env(safe-area-inset-bottom,0px) + 24px)}

/* ══════════════════════════════════════════════════════════════════════════
   BẢNG CỔ PHIẾU CÙNG NGÀNH — [SỬA 16/09/2026]
   ══════════════════════════════════════════════════════════════════════════
   Bảng do `chart.js::nscNganhBang` dựng, dùng nguyên lớp `.nsc-ngw`/`.v30-*`
   của thư mục ngành — không luật nào của chúng bị khoá trong `#nsChart`, đã
   đo trước khi đưa sang. Ở đây CHỈ chỉnh hai thứ thuộc về bối cảnh tờ trượt.

   Luật của bảng tự vẽ cũ (`.mb-ngr` và họ hàng) ĐÃ GỠ — chúng mồ côi từ lúc
   `mbNganhVe` chuyển sang gọi bản gốc, và một luật mồ côi là lời mời cho
   người sau gắn lại phần tử đã chết.
   ══════════════════════════════════════════════════════════════════════════ */
/* Nút "‹ Ngành" là lối quay về THƯ MỤC ngành — trong tờ trượt không có thư
   mục nào để về, nên ẩn. Giữ lại tên ngành vì nó vẫn nói được điều cần nói. */
#mb-ng .nsc-ngb{display:none}
#mb-ng .nsc-ngh{padding-left:14px}
.mb-ngnote{padding:16px 14px;font-size:12px;line-height:1.55;
  color:var(--ink-dim)}


/* ══════════════════════════════════════════════════════════════════════════
   PANEL CƠ BẢN MỚI — [THÊM 16/09/2026]
   ══════════════════════════════════════════════════════════════════════════
   Năm khối: nhận xét · định giá · vì sao P/E đổi · kinh doanh · thanh kéo.

   NGUYÊN TẮC: mỗi con số mang theo lịch sử của chính nó. "P/E 7,62" không
   trả lời được câu duy nhất đáng hỏi — với chính doanh nghiệp này, 7,62 là
   cao hay thấp. Nên mỗi ô có bốn lớp: số · câu phân vị · dải 8 năm kèm mốc
   ngành · đường 33 quý.

   MÀU LẤY TỪ TOKEN NGỮ NGHĨA, không lấy sắc nền: `--safe`/`--danger`/
   `--watch`/`--gold`. Mã chỉ được nói Ý, bảng màu mới được nói MÀU —
   `test_bang_mau` canh đúng luật này.
   ══════════════════════════════════════════════════════════════════════════ */
.cbm{padding:0 14px 8px}
.cbm-nhom{margin-top:16px}
.cbm-dau{display:flex;align-items:baseline;justify-content:space-between;
  gap:8px;margin-bottom:8px}
.cbm-dau h3{margin:0;font-size:10px;font-weight:600;letter-spacing:.14em;
  color:var(--ink-faint);text-transform:uppercase}
.cbm-dau em{font-style:normal;font-size:9.5px;color:var(--ink-dim)}

/* Thanh trượt `input[type=range]` ĐÃ THAY bằng dải khấc + hàng
   điều khiển — xem `THANH THỜI GIAN 33 QUÝ` ở dưới. Luật cũ gỡ
   hết: một luật mồ côi là lời mời cho người sau gắn lại phần tử
   đã chết. */

/* ── ô chỉ tiêu: nhãn · số · dải · đường ── */
.cbm-o{background:var(--panel);border:1px solid var(--line);border-radius:9px;
  padding:10px 12px 9px;margin-bottom:6px}
.cbm-o .h{display:flex;align-items:baseline;justify-content:space-between;gap:8px}
.cbm-o .tn{font-size:12.5px;font-weight:600;color:var(--ink)}
.cbm-o .so{font:600 18px/1 var(--mono);letter-spacing:-.01em}
.cbm-o .so i{font-style:normal;font-size:11px;color:var(--ink-dim)}
.cbm-o .pv{font:10px/1.35 var(--mono);color:var(--ink-dim);letter-spacing:.03em;
  margin-top:3px}
.cbm-o .ng{font-size:10px;line-height:1.35;color:var(--ink-dim);margin-top:3px}
.cbm-o .ng b{font-weight:600}
.cbm-o .ng .mo{opacity:.75;font-style:italic}

/* DẢI PHÂN VỊ — nền là trọn 8 năm, hộp đậm là nửa giữa, vạch là kỳ đang
   xem, hình thoi rỗng là trung vị ngành. Ba mốc trên MỘT trục: so với chính
   mình và so với hàng xóm cùng một lúc, không cần hai biểu đồ. */
.cbm-dai{position:relative;height:24px;margin:8px 0 1px}
.cbm-dai .nen{position:absolute;left:0;right:0;top:10px;height:4px;
  border-radius:2px;background:var(--line)}
.cbm-dai .iqr{position:absolute;top:8px;height:8px;border-radius:3px;
  background:var(--line-soft);box-shadow:inset 0 0 0 1px var(--line)}
/* Hình thoi RỖNG, không đặc: đây là mốc tham chiếu, không phải giá trị của
   mã — không được nặng bằng vạch màu. */
.cbm-dai .ngd{position:absolute;top:7.5px;width:9px;height:9px;
  margin-left:-4.5px;border:1.4px solid var(--ink-faint);
  transform:rotate(45deg);background:var(--bg)}
.cbm-dai .vach{position:absolute;top:3px;width:2.5px;height:18px;
  border-radius:2px}
.cbm-dai .mc{position:absolute;top:18px;font:8.5px/1 var(--mono);
  color:var(--ink-dim);letter-spacing:.04em}
.cbm-dai .mc.t{left:0}.cbm-dai .mc.p{right:0}
.cbm-sp{display:block;width:100%;height:32px;margin-top:5px}

/* ── nhận xét: NHÃN KẾT LUẬN trước, bằng chứng sau ── */
.cbm-nx{background:var(--panel);border:1px solid var(--line);
  border-left:3px solid var(--ink-dim);border-radius:9px;
  padding:10px 12px;margin-bottom:6px}
.cbm-nx.tot{border-left-color:var(--safe)}
.cbm-nx.xau{border-left-color:var(--danger)}
.cbm-nx.trung{border-left-color:var(--watch)}
.cbm-nx .ten{font-size:9px;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-faint);margin-bottom:5px}
.cbm-nx .nhan{font-size:12px;font-weight:700;letter-spacing:.02em;
  line-height:1.3;margin-bottom:4px;display:flex;align-items:baseline;gap:6px}
.cbm-nx .nhan::before{content:'\25CF';font-size:8px;line-height:1;flex:none}
.cbm-nx.tot .nhan{color:var(--safe)}
.cbm-nx.xau .nhan{color:var(--danger)}
.cbm-nx.trung .nhan{color:var(--watch)}
.cbm-nx .cau{font-size:12px;line-height:1.55;color:var(--ink-soft)}
.cbm-nx .cau b{color:var(--ink);font-weight:600}
/* BÁO CÁO CƠ BẢN [THÊM 22/09/2026, GĐ7] — `_cbBaoCao` trong mobile.js. Thân
   báo cáo dùng lại `.cbm-nx`; ở đây chỉ tiêu đề mục và dòng chữ thường. */
.cbm-bc > summary{cursor:pointer;list-style:none}
.cbm-bc > summary::-webkit-details-marker{display:none}
.cbm-bc .bc-muc{font-size:10px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-faint);margin:12px 0 6px}
.cbm-bc .bc-chu{font-size:11px;line-height:1.5;color:var(--ink-faint);margin:0 0 6px}
/* VĂN PHONG v2 [22/09/2026] — ba trục tổng quan, đoạn nhận định, cần theo dõi,
   phần gập (chi tiết khác · giải thích chỉ số). */
.cbm-bc .bc-truc{display:flex;gap:8px;align-items:baseline;padding:5px 0;
  border-bottom:1px solid var(--line);font-size:12px}
.cbm-bc .bc-truc b{flex:none;min-width:118px;font-weight:600;color:var(--ink-soft)}
.cbm-bc .bc-truc span{font-weight:700}
.cbm-bc .bc-truc.tot span{color:var(--safe)}
.cbm-bc .bc-truc.xau span{color:var(--danger)}
.cbm-bc .bc-truc.trung span{color:var(--watch)}
.cbm-bc .bc-nd{font-size:13px;line-height:1.6;color:var(--ink);margin:10px 0 4px}
.cbm-bc .bc-nd b{font-weight:600}
.cbm-bc .bc-td{font-size:12px;line-height:1.5;color:var(--ink-soft);margin:0 0 5px;
  padding-left:12px;position:relative}
.cbm-bc .bc-td::before{content:'\2022';position:absolute;left:2px;color:var(--ink-faint)}
.cbm-bc .bc-gap > summary{cursor:pointer;list-style:none}
.cbm-bc .bc-gap > summary::-webkit-details-marker{display:none}
.cbm-bc .bc-gt{font-size:11.5px;line-height:1.55;color:var(--ink-soft);margin:0 0 7px}
.cbm-bc .bc-gt b{color:var(--ink);font-weight:600}
/* ĐỘ TIN VỪA: vẫn bày, chỉ mờ đi — giấu là để người đọc tin quá mức. */
.cbm-nx.vua{opacity:.82}
.cbm-nx.vua .ten::after{content:' \00B7 độ tin vừa';letter-spacing:.03em;
  text-transform:none;font-weight:400;color:var(--ink-dim)}

/* ── phân rã P/E ── */
.cbm-pr{background:var(--panel);border:1px solid var(--line);border-radius:9px;
  padding:10px 12px 8px}
.cbm-pr svg{width:100%;height:76px;display:block}
.cbm-pr .ct{display:flex;gap:14px;margin-top:6px;font:9.5px/1 var(--mono);
  letter-spacing:.05em;color:var(--ink-dim)}
.cbm-pr .ct i{display:inline-block;width:9px;height:2.5px;border-radius:2px;
  margin-right:5px;vertical-align:middle;font-style:normal}
.cbm-chu{font-size:11.5px;line-height:1.5;color:var(--ink-soft);margin-top:7px}
.cbm-chu b{color:var(--ink);font-weight:600}
.cbm-ghi{font-size:10px;line-height:1.55;color:var(--ink-dim);margin-top:14px;
  padding-top:10px;border-top:1px solid var(--line-soft)}

/* Đầu lớp phủ: MÃ đậm · tên công ty · chip ngành. Ba lớp thông tin, ba mức
   nổi — mã là thứ tra cứu, tên là thứ nhận ra, ngành là bối cảnh. */
.mb-cbhd .tn{display:flex;align-items:baseline;gap:7px;flex-wrap:nowrap}
.mb-cbhd .tn b{flex:none;font-weight:700;letter-spacing:.04em}
.mb-cbhd .tn .dn{flex:1;min-width:0;font-weight:400;color:var(--ink-soft);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mb-cbhd .tn .ng{flex:none;font:600 9px/1 var(--mono);letter-spacing:.09em;
  text-transform:uppercase;color:var(--gold);
  background:color-mix(in srgb, var(--gold) 12%, transparent);
  border-radius:4px;padding:4px 6px}

/* Ô TRA NÂNG TẦNG khi mở từ lớp phủ cơ bản — xem `mbCoBanTra`. Chỉ khi có
   lớp này; z gốc của `.nsc-find` giữ nguyên cho năm lối vào còn lại. */
body.mb-cb-tra .nsc-find{z-index:95}

/* Tên trên đầu lớp phủ BẤM ĐƯỢC — dấu hiệu là mũi tên nhỏ, không phải gạch
   chân: gạch chân trong một thanh tiêu đề đọc thành liên kết web. */
.mb-cbhd .tn{cursor:pointer;-webkit-tap-highlight-color:transparent}
.mb-cbhd .tn::after{content:'\25BE';flex:none;font-size:9px;
  color:var(--ink-dim);margin-left:1px;transform:translateY(-1px)}
.mb-cbhd .tn:active b{color:var(--gold)}

/* ══════════════════════════════════════════════════════════════════════════
   THANH THỜI GIAN 33 QUÝ — [THÊM 17/09/2026]
   ══════════════════════════════════════════════════════════════════════════
   Chủ hệ: *"ở dưới ghi năm, ở trên ghi quý, có khấc đánh dấu nhẹ… phần này
   khá khó vì thanh ngắn mà nhiều quý, hoặc có thể tham khảo thanh 20 phiên
   gần nhất."*

   Đo bài toán: 33 quý trên 332px lọt lòng (360px trừ lề) = 10,1px mỗi nấc.
   Đầu ngón tay cần ~44px. Một `input[type=range]` ở mật độ ấy là thứ kéo
   trượt nấc liên tục.

   THANH 20 PHIÊN ĐÃ GIẢI BÀI NÀY, và nó giải bằng HAI TẦNG chứ không bằng
   một thanh khéo hơn:

       dải khấc          nhìn toàn cảnh + nhảy thô, chạm được nhưng không cần chính xác
       hàng điều khiển   ‹ · nhãn · ›  cao 44px, đi từng nấc TUYỆT ĐỐI chính xác

   Chép đúng cấu trúc ấy. Mật độ khấc không đổi được — 33 quý vẫn là 33 quý —
   nhưng khi có đường đi chính xác song song thì mật độ thôi là vấn đề.

   KHẤC CAO THẤP THEO QUÝ: Q1 cao nhất (mốc năm), Q3 cao vừa (giữa năm),
   Q2·Q4 thấp. Mắt bắt nhịp bốn-một mà không cần đọc chữ, nên nhãn năm ở
   dưới chỉ để xác nhận chứ không phải để dò.
   ══════════════════════════════════════════════════════════════════════════ */
.cbm-tg{margin:12px 0 2px;padding:10px 12px 9px;background:var(--panel);
  border:1px solid var(--line);border-radius:9px}
.cbm-tg .qs{display:flex;gap:2px;align-items:flex-end;height:26px}
.cbm-tg .qs i{flex:1 1 0;display:block;border-radius:1.5px;cursor:pointer;
  background:var(--line);transition:background .12s ease,height .12s ease}
.cbm-tg .qs i.q1{height:18px}
.cbm-tg .qs i.q3{height:12px}
.cbm-tg .qs i.q2,.cbm-tg .qs i.q4{height:8px}
/* Vùng chạm nở ra ngoài khấc: khấc chỉ 10px nhưng ô chạm phủ trọn chiều
   cao 26px, nên ngón tay không cần nhắm theo chiều dọc. */
.cbm-tg .qs i::before{content:'';position:absolute}
.cbm-tg .qs i.chon{background:var(--gold);height:22px}
.cbm-tg .qs i.truoc{background:var(--ink-faint)}
.cbm-tg .nam{display:flex;gap:2px;margin-top:4px}
.cbm-tg .nam span{font:9px/1 var(--mono);letter-spacing:.04em;
  color:var(--ink-dim);text-align:center;overflow:hidden;white-space:nowrap}
.cbm-tg .nam span.co{color:var(--ink-soft)}

/* HÀNG ĐIỀU KHIỂN — cao 44px, đúng số của thanh 20 phiên. Đây là đường đi
   CHÍNH XÁC, còn dải khấc ở trên là đường đi NHANH. Có cả hai thì mật độ
   khấc thôi là vấn đề. */
.cbm-tg .dieu{display:flex;gap:8px;margin-top:9px}
.cbm-tg .dieu>*{height:44px;border-radius:4px;cursor:pointer;
  font-family:var(--mono);display:flex;align-items:center;
  justify-content:center;-webkit-tap-highlight-color:transparent;
  border:1px solid color-mix(in srgb, var(--ink) 12%, transparent)}
.cbm-tg .dh{flex:0 0 56px;font-size:22px;line-height:1;
  color:var(--ink-faint);background:var(--panel2)}
.cbm-tg .dh:active{color:var(--ink);
  background:color-mix(in srgb, var(--ink) 14%, transparent)}
/* TẮT thay vì GIẤU ở hai đầu dải: nút biến mất làm hai nút còn lại nhảy
   chỗ, và ngón tay đang nhắm thì bấm trượt. */
.cbm-tg .dh.tat{opacity:.28;pointer-events:none}
.cbm-tg .nhan{flex:1 1 auto;font-size:15px;letter-spacing:.08em;line-height:1;
  white-space:nowrap;color:var(--gold);
  background:color-mix(in srgb, var(--gold) 14%, transparent);
  border-color:color-mix(in srgb, var(--gold) 26%, transparent)}
.cbm-tg .nhan:active{background:color-mix(in srgb, var(--gold) 26%, transparent)}
.cbm-tg .nhan em{font-style:normal;font-size:9.5px;letter-spacing:.1em;
  color:var(--ink-dim);margin-left:8px;text-transform:uppercase}
