/* ALFA Software — stylesheet dùng chung cho alfasoftwares.com
   Bảng màu lấy từ ALFA Report (report.alfamedia.vn) để cả nhà ALFA cùng một tông.
   SÁNG LÀ MẶC ĐỊNH, TỐI LÀ CHỌN VÀO (SPEC §18.1 mục 4d-i, chủ dự án chốt 01/10 — đảo quyết định 21/09):
   cookie alfa_giao_dien=toi ⇒ <html data-giao-dien="toi"> ⇒ tokens.css định nghĩa lại CÙNG TÊN token.
   Viết luật mới thì dùng token, đừng viết màu trần — màu trần không đổi theo chế độ tối.
   Token màu, hình khối và color-scheme khai ở tokens.css — dùng chung với ung-dung.css; luật đầy đủ ở đó. */

@import url("tokens.css");

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--paper); color:var(--ink);
  font-family:"Inter","Segoe UI",system-ui,sans-serif;
  font-size:16px; line-height:1.65; -webkit-font-smoothing:antialiased;
  /* Chữ dài không có chỗ ngắt (email, URL trong bài, tên viết liền) thì tràn ngang. break-word CHỈ
     ngắt khi một từ không vừa dòng. Đo 26/09 bằng cách nhồi vào HTML 9 trang: không luật này thì
     tràn 131–410px ở 320/390 (tiêu đề chữ to tràn nặng nhất). Cùng luật với ung-dung.css. */
  overflow-wrap:break-word;
}
[hidden]{display:none!important}

/* ---------- thanh cảnh báo cấu hình ----------
   GIỮ --warn-soft đậm ở tối (1,45:1 so với nền), CỐ Ý — khác .band.wash/.pull (nền trang trí, phải phớt): đây là CẢNH
   BÁO cho người dựng trang, việc của nó là đập vào mắt. Và khách ⛔ không bao giờ thấy nó: chỉ hiện khi Vercel thiếu
   ALFA_PHONE/ALFA_EMAIL (đo 04/10: production đặt đủ cả hai). ⛔ Đừng hạ nó theo luật «-soft trên mặt lớn phải phớt». */
.cfgwarn{
  background:var(--warn-soft); color:var(--warn); border-bottom:1px solid var(--warn);
  font-family:"IBM Plex Mono",monospace; font-size:12px; padding:9px 16px; text-align:center;
}
.cfgwarn b{font-weight:500}

/* ---------- nav ---------- */
/* Chiều cao thanh đầu — MỘT chỗ khai. Mục lục dính và điểm neo đều tính
   theo nó. Trước đây ba chỗ đặt cứng 77/78/126px; hạ thanh đầu xuống 69px
   là mục lục hở ra một khe 8px, nội dung chạy lộ qua khe khi cuộn.
   69 = 12 (đệm) + 44 (hàng) + 12 + 1 viền, đúng ở mọi bề rộng vì trên màn
   hẹp các đường dẫn đã gom vào nút menu. */
:root{--cao-nav:69px}
body.la-app{--cao-nav:61px}
.nav{border-bottom:1px solid var(--line); background:var(--nen-dau); position:sticky; top:0; z-index:20}
/* Đường dưới thanh đầu: ở ĐỈNH trang nó là một đường kẻ nằm ngay trên hero (chủ dự án gạch X 04/10) ⇒ ẩn; khi đã
   cuộn, thanh đầu dính trên nội dung chạy qua thì đường ấy CẦN (ở tối nền thanh = nền trang = #000 từ 06/10, APL-245 ⇒ đường ấy là ranh giới DUY NHẤT; trước đó chênh ~1,09:1) ⇒ hiện
   dần trong 48px cuộn đầu. Trình duyệt chưa có scroll-timeline giữ đường như cũ — hướng hỏng an toàn. */
@supports (animation-timeline: scroll()){
  /* màu MẶC ĐỊNH trong suốt: trước khi scroll-timeline gắn vào (những khung hình đầu lúc nạp trang) luật nền là thứ
     áp dụng — thiếu dòng này thì đường dưới thanh đầu NHÁY lên rồi mới ẩn (đo 04/10, lượt đếm ngay khi nạp). */
  body:not(.la-app) .nav{border-bottom-color:transparent; animation:nav-vien linear both; animation-timeline:scroll(root); animation-range:0 48px}
  @keyframes nav-vien{from{border-bottom-color:transparent} to{border-bottom-color:var(--line)}}
}
.nav-in{
  max-width:1160px; margin:0 auto; padding-block:12px;
  padding-left:16px; padding-right:16px;
  display:flex; align-items:center; gap:18px; flex-wrap:wrap;
}
/* Khi đã đăng nhập, thanh trên phải cao ĐÚNG 61px để mép dưới của nó và mép
   dưới dải logo bên trái nối thành một đường.

   ĐỆM Ở NGOÀI, min-height Ở TRONG — đo trên bản chạy thật mới ra. Đặt cả
   hai lên .nav-in thì min-height:44 tính cả đệm (box-sizing:border-box),
   nên nó KHÔNG nâng được hàng: nút 38px + đệm 16px = 54, và min-height 44
   nhỏ hơn 54 nên vô nghĩa. Kết quả thanh trên cao 55 còn dải logo cao 61 —
   lệch 6px chạy dọc suốt đỉnh màn hình.

   8 (đệm .nav) + 44 (hàng .nav-in) + 8 + 1 viền = 61. */
body.la-app .nav{padding-block:8px}
body.la-app .nav-in{min-height:44px; padding-block:0; gap:6px; flex-wrap:nowrap}
.logo{
  font-family:"Orbitron","Inter",sans-serif;
  font-weight:800; font-size:24px; letter-spacing:.02em; text-decoration:none;
  color:var(--hieu-dau); display:inline-flex; gap:7px; align-items:baseline;
}
.logo span{color:var(--hieu-cuoi)}
/* Dấu hiệu ALFA Software cạnh chữ (chủ dự án: "không để mỗi cái tên được", ảnh khoanh đỏ 25/09).
   Cao 0.75em ≈ chiều cao chữ hoa Orbitron 800 (0.72em, đo bằng canvas) — theo em nên tự theo ba cỡ
   chữ logo (24 · 29 · 18px). Không khai align-self: .logo căn baseline, nên đáy dấu hiệu nằm trên
   đường chân chữ và đỉnh ngang đầu chữ hoa. .logo là inline-flex không xuống dòng: dấu hiệu và chữ
   là một khối, không tách nhau khi hẹp. Cả 8 trang dùng dấu hiệu NỀN TẢNG vì chữ bên cạnh là
   "ALFA Software", kể cả /adpilot (dấu hiệu sản phẩm của nó ở favicon/tab và trong trang). */
.logo > img{flex:none; width:.75em; height:.75em}
/* Dưới 360px thanh đầu công khai thiếu đúng 9px (đo 320px: logo + nút menu tràn 9) → chữ 22px. */
@media (max-width:359px){ body:not(.la-app) .logo{font-size:22px} }
/* Thanh đầu KHU THÀNH VIÊN dưới 414px: nút menu + logo + cụm phải KHÔNG vừa, kể cả trước khi có dấu
   hiệu (đo 25/09: tràn 54px ở 320, 14px ở 360). Ở đó chỉ giữ DẤU HIỆU — chữ vẫn trong DOM cho trình
   đọc màn hình (tên liên kết vẫn là "ALFA Software"), chỉ thu cỡ về 0 cho mắt. */
@media (max-width:413px){
  /* a.logo: phải THẮNG luật @media (max-width:560px) body.la-app .logo{font-size:18px} đứng SAU trong tệp */
  body.la-app a.logo{font-size:0; gap:0; align-items:center}
  body.la-app a.logo > img{width:26px; height:26px}
  /* Chỉ còn dấu hiệu thì logo rộng 26 — dưới mốc 40 (đo 27/09). Nới VÙNG BẤM bằng ::after như .mini,
     không đổi bố cục: 40px canh giữa phủ x 57–97, nút menu hết ở 56 (đo 320/360/390/413). */
  body.la-app a.logo{position:relative}
  body.la-app a.logo::after{content:""; position:absolute; left:50%; top:50%; width:40px; height:40px; transform:translate(-50%, -50%)}
}
/* To hơn trên site công khai ở màn rộng. KHÔNG đụng điện thoại (24px đã
   từng gây tràn ngang 15px) và KHÔNG đụng khu thành viên (thanh trên khớp
   đúng 61px với dải logo bên, to lên là lệch lại). */
@media (min-width:760px){ body:not(.la-app) .logo{font-size:29px} }
/* line-height sát chữ. Logo thừa hưởng line-height của chữ thân bài, nên
   chữ 29px nằm trong một hộp cao 60px — chính khoảng trống đó làm thanh
   trên phình ra và làm logo TRÔNG nhỏ: chữ nhỏ giữa một thanh dày. */
body:not(.la-app) .logo{line-height:1.1}
.nav-links{margin-left:auto; display:flex; gap:18px; flex-wrap:wrap; align-items:center}

/* ---------- nút menu, màn hẹp ----------
   Trước đây trên điện thoại, logo + bốn đường dẫn + nút đăng nhập tràn
   thành BA hàng: thanh đầu cao 178px, gần một phần tư màn hình, trước khi
   thấy được chữ nào của nội dung.

   CHỈ .nav.co-menu (bảy trang công khai) — không lọt sang khu thành viên.
   CHỈ khi html.co-js (một dòng trong <head>, chạy trước lúc vẽ): không có
   JS thì nút menu chết, giấu đường dẫn đi là khách mất lối. Thà để tràn
   như cũ còn hơn.
   Ngưỡng 999px phải trùng với nav.js. Nâng từ 899 ngày 27/09 khi thêm mục "Nối AI" (§21.6 B7c): đo
   thanh ngang cần 905px ở /adpilot (khung nhìn ≥952), và ở 900–960 dãy liên kết rớt xuống hàng hai,
   thanh cao 68 → 126px. 1000 chừa ~48px cho font dự phòng. Thêm mục nữa thì ĐO LẠI con số này. */
.nav-mo{display:none}
.nav-mo .i-dong{display:none}
.nav.mo .nav-mo .i-mo{display:none}
.nav.mo .nav-mo .i-dong{display:block}
@media (max-width:999px){
  html.co-js .nav.co-menu .nav-in{flex-wrap:nowrap; min-height:44px}
  html.co-js .nav.co-menu .nav-mo{
    display:inline-flex; align-items:center; justify-content:center; flex:none;
    margin-left:auto; width:44px; height:44px; padding:0;
    border:1px solid var(--vien-dieu-khien); border-radius:var(--bo-nho);
    background:var(--surface); color:var(--ink); cursor:pointer;
  }
  html.co-js .nav.co-menu .nav-mo:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
  html.co-js .nav.co-menu .nav-links{
    display:none; position:absolute; left:0; right:0; top:100%;
    flex-direction:column; align-items:stretch; gap:0; margin:0;
    padding:6px 16px 16px; background:var(--nen-dau);   /* nối dài thanh đầu (hết bề ngang, ngay dưới) ⇒ cùng nền thanh */
    border-bottom:1px solid var(--line);
    box-shadow:0 18px 30px -22px rgba(0,0,0,.4);
  }
  html.co-js .nav.co-menu.mo .nav-links{display:flex}
  html.co-js .nav.co-menu .nav-links a:not(.cta){
    padding:13px 2px; font-size:16px; border-bottom:1px solid var(--line);
  }
  html.co-js .nav.co-menu .nav-links a:not(.cta):last-child{border-bottom:0}
  html.co-js .nav.co-menu .nav-links a[aria-current="page"]{color:var(--accent); font-weight:700}
  html.co-js .nav.co-menu .nav-links a.cta{
    display:flex; justify-content:center; margin-top:14px; padding-block:12px; font-size:15.5px;
  }
  /* /tai-khoan: đã đăng nhập thì khu thành viên có #nut-menu riêng — nút và danh sách của menu công khai
     ẩn HẲN, kể cả khi menu đang mở dở lúc đăng nhập xong (.mo). Độ ưu tiên phải hơn hai luật hiện ở trên. */
  html.co-js body.la-app .nav.co-menu :is(.nav-mo, .nav-links){display:none}
}
.nav-links a{color:var(--ink-2); text-decoration:none; font-size:14.5px}
.nav-links a:hover{color:var(--accent)}
.nav-links a.cta{
  border:1px solid var(--accent); color:var(--accent);
  padding:6px 15px; border-radius:var(--bo-nho); font-weight:600; font-size:14px;
}
.nav-links a.cta:hover{background:var(--accent); color:var(--accent-ink)}
.nav-links a.cta.solid{background:var(--accent); color:var(--accent-ink)}
/* Khách: "Đăng nhập · Đăng ký". Máy đang có phiên (html.co-phien, script đầu <head> đọc dấu alfa_dn do
   /tai-khoan đặt): "Khu thành viên". CHỈ ẩn, không đặt display — để luật menu hẹp (display:flex) và luật
   rộng tự quyết. Cặp thứ hai có .nav.co-menu để đủ SÁU lớp, thắng luật menu hẹp
   html.co-js .nav.co-menu .nav-links a.cta{display:flex} (năm lớp) — đo 26/09: thiếu nó thì menu hẹp hiện cả ba nút. */
html:not(.co-phien) .nav-links a.cta.cho-tv,
html.co-phien .nav-links a.cta.cho-khach,
html:not(.co-phien) .nav.co-menu .nav-links a.cta.cho-tv,
html.co-phien .nav.co-menu .nav-links a.cta.cho-khach{display:none}

/* ---------- khối ---------- */
/* ⛔ KHÔNG đường kẻ giữa các băng (chủ dự án gạch X lên trang chủ 04/10: «các đường này ko nên có»). Đảo mặc định:
   băng tách nhau bằng NỀN và KHOẢNG THỞ, đường kẻ là thứ CHỌN VÀO — một luật «ghi đè cho đúng chỗ» (bản vá /ke
   chỉ phủ hai cặp lớp) hỏng ở chỗ thứ ba, và trang chủ là chỗ thứ ba.
   ⚠ Bỏ border mới bỏ ĐƯỜNG KẺ; hai nền khác nhau kề nhau vẫn là một RANH GIỚI nhìn thấy được ⇒ băng .alt và .wash
   TAN vào --paper ở mép (120–140px) thay vì cắt cứng. Màu đặc vẫn đặt dưới gradient: thước tương phản đọc màu đặc. */
.band{border-bottom:0}
.band.alt{background-color:var(--alt); background-image:linear-gradient(to bottom, var(--paper), transparent 120px, transparent calc(100% - 120px), var(--paper))}
.band.wash{background-color:var(--nen-wash); background-image:linear-gradient(to bottom, transparent calc(100% - 140px), var(--paper))}

/* Dải gọi hành động trước chân trang. Nền ĐẶC và tối để nó tách hẳn khỏi
   mọi mục phía trên — cả trang là nền sáng, nên một dải tối đọc ra là
   "hết phần giới thiệu, tới lượt bạn". MCPBundles dùng cam đặc; ALFA
   dùng xanh của chính mình chứ không mượn màu của họ. */
.band.goi{
  background:var(--nen-dam); border-bottom:0; color:var(--tren-toi);
  text-align:center;
}
.band.goi h2{color:var(--tren-toi); margin:0 0 12px}
.band.goi p{color:var(--tren-toi-2); margin:0 auto; max-width:62ch}
/* max-width:none — hàng nút là một <p>, nên dính luật chung p{max-width:62ch}:
   nút căn giữa bên trong một khối 62ch nằm SÁT LỀ TRÁI, tức lệch hẳn so với
   tiêu đề và dòng mô tả ở giữa trang. */
.goi-nut{display:flex; gap:12px; justify-content:center; flex-wrap:wrap; margin-top:26px!important; max-width:none}
.band.goi .btn.solid{background:var(--nut-dam-nen); color:var(--nut-dam-chu); border-color:var(--nut-dam-nen)}
.band.goi .btn.solid:hover{background:var(--nut-dam-hover); border-color:var(--nut-dam-hover)}
.band.goi .btn.vien{background:transparent; color:var(--tren-toi); border-color:var(--vien-toi)}
.band.goi .btn.vien:hover{background:var(--nen-toi-hover); border-color:var(--tren-toi)}
.wrap{max-width:1160px; margin:0 auto; padding-block:56px; padding-left:16px; padding-right:16px}
.narrow{max-width:760px}

h1{font-weight:800; font-size:clamp(28px,5vw,42px); line-height:1.12; letter-spacing:-.02em; margin:0 0 18px; text-wrap:balance; max-width:20ch}
h2{font-weight:600; font-size:clamp(20px,3.2vw,26px); line-height:1.25; letter-spacing:-.01em; margin:0 0 14px; text-wrap:balance; max-width:30ch}
h3{font-weight:600; font-size:17px; margin:26px 0 8px}
p{margin:0 0 15px; max-width:62ch; color:var(--ink-2)}
p.big{font-size:17.5px; color:var(--ink)}
p b,li b,td b{color:var(--ink); font-weight:600}
a{color:var(--accent)}
ul,ol{max-width:62ch; color:var(--ink-2); padding-left:22px}
li{margin-bottom:8px}
.eyebrow{
  font-family:"IBM Plex Mono",monospace; font-size:11.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink-3); margin:0 0 16px;
}
/* .upd là chữ MONO cho ghi chú KỸ THUẬT — dấu thời gian, mã, nhãn ngắn.
   Đừng dùng cho cả câu văn: mono 12,5px xám đọc một câu dài rất mệt. Đã
   dính lỗi ấy ở tám chỗ trên các trang mới ngày 21/09. Câu văn thì dùng
   .ghi-chu ngay dưới. */
.upd{font-family:"IBM Plex Mono",monospace; font-size:12.5px; color:var(--ink-3)}
#cc-tally{font-size:13px}   /* dòng đếm công cụ /adpilot là chữ khách đọc, không phải nhãn ngày */
.ghi-chu{font-size:13.5px; color:var(--ink-3); line-height:1.62; max-width:70ch}
.ghi-chu a{color:var(--accent)}

/* ---------- nút ---------- */
.ctas{display:flex; gap:10px; flex-wrap:wrap; margin-top:24px; align-items:center}
.btn{
  font-family:inherit; font-size:15px; font-weight:600; line-height:1.3;
  padding:12px 22px; border-radius:var(--bo-nho); border:1px solid var(--accent);
  color:var(--accent); background:transparent; text-decoration:none; display:inline-block;
}
.btn.solid{background:var(--accent); color:var(--accent-ink); box-shadow:var(--bong)}
.btn:hover{opacity:.88}
a:focus-visible,.btn:focus-visible,input:focus-visible,button:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
/* Trên nền TỐI (--hieu-dau) vòng --accent gần như trùng màu nền: đo được 1.19, dưới 3:1.
   Người dùng bàn phím không thấy mình đang ở nút nào. */
.band.goi :focus-visible, .sp-ban :focus-visible{outline-color:var(--tren-toi)}
.micro{font-size:13.5px; color:var(--ink-3); margin-top:12px}

/* ---------- bảng ---------- */
.tw{overflow-x:auto; margin:22px 0; border:1px solid var(--line-2); border-radius:var(--bo); background:var(--surface)}
table{border-collapse:collapse; width:100%; font-size:14.5px; min-width:460px}
th,td{padding:11px 14px; text-align:left; vertical-align:top; border-bottom:1px solid var(--line)}
th{
  font-family:"IBM Plex Mono",monospace; font-size:11.5px; font-weight:500; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-3); background:var(--alt); white-space:nowrap;
}
tr:last-child td{border-bottom:0}
/* Bảng HAI CỘT ở khổ hẹp: mỗi hàng thành một khối, ô đầu trên, ô sau dưới. Đo 26/09: min-width:460px
   làm MỌI bảng .tw cuộn ngang 174px ở 320 (104px ở 390) — không tràn trang, nên mọi phép đo tràn đều
   xanh, nhưng đọc cột hai phải cuộn sang rồi cuộn về cho từng hàng. Mà mọi bảng trang bán hàng đều là
   cặp "tên → lời giải thích" viết bằng câu, không cần thẳng cột. Bảng từ BA cột trở lên (hoá đơn, phiên
   đăng nhập…) là dữ liệu so hàng thật: giữ cuộn ngang. Nhận bảng hai cột bằng cấu trúc, không bằng lớp:
   không hàng nào có ô thứ ba. Tiêu đề cột còn hiện, gộp một dòng "A · B". Chiều rộng ô trong HTML
   (style="width:…") phải bỏ ở đây, nên cần !important. */
@media (max-width:559.98px){
  .tw > table:not(:has(tr > :nth-child(3))){display:block; min-width:0}
  .tw > table:not(:has(tr > :nth-child(3))) > :is(thead, tbody){display:block}
  .tw > table:not(:has(tr > :nth-child(3))) tr{display:block; padding:11px 14px; border-bottom:1px solid var(--line)}
  .tw > table:not(:has(tr > :nth-child(3))) > tbody > tr:last-child{border-bottom:0}
  .tw > table:not(:has(tr > :nth-child(3))) :is(th, td){display:block; width:auto !important; padding:0; border:0; white-space:normal}
  .tw > table:not(:has(tr > :nth-child(3))) > thead > tr{background:var(--alt)}
  .tw > table:not(:has(tr > :nth-child(3))) > thead th{display:inline; background:none}
  .tw > table:not(:has(tr > :nth-child(3))) > thead th + th::before{content:" · "}
  .tw > table:not(:has(tr > :nth-child(3))) > tbody > tr > :first-child{margin-bottom:4px}
  .tw > table:not(:has(tr > :nth-child(3))) > tbody > tr > td:first-child{font-weight:600; color:var(--ink)}
  .tw > table:not(:has(tr > :nth-child(3))) > tbody > tr > th{background:none}
}
/* Bảng TỪ BA CỘT (hoá đơn · người dùng · phiên đăng nhập) cuộn ngang — nhưng cuộn không cứu một ô bị ép.
   Đo 26/09 ở 320 bằng SỐ DÒNG của hàng cao nhất, không bằng px cuộn: hàng cao 6–9 dòng; số hoá đơn
   "HD-2026-000123" còn 44px, bẻ từng ký tự, vì luật code chung có word-break:break-word nên bề rộng tối
   thiểu của cột chỉ còn một ký tự. Mã không bao giờ bẻ (cùng lý do .khong-ngat). Và dưới 560px, nơi
   bảng đằng nào cũng cuộn, không ô nào xuống dòng: mỗi hàng 1–2 dòng, lướt theo hàng được. Ở khổ rộng
   ô vẫn xuống dòng như cũ — thử nowrap mọi khổ thì bảng hoá đơn cuộn 77px ở 1440, nơi trước đó vừa khung. */
.tw > table:has(tr > :nth-child(3)) code{white-space:nowrap; word-break:normal}
@media (max-width:559.98px){
  .tw > table:not(.data-table):has(tr > :nth-child(3)) :is(th, td){white-space:nowrap}
  /* .tw .tt{white-space:normal} (cho bảng giá) mở lại chỗ ngắt NGAY TRONG ô: đo 26/09 bằng dữ liệu ca xấu
     (4 sản phẩm), cột Sản phẩm của bảng Người dùng cao 117px ở 320 dù ô nowrap. Nay hàng 143 → 68px. */
  .tw > table:not(.data-table):has(tr > :nth-child(3)) .tt{white-space:nowrap}
}
/* .data-table (§18.7 luật 2) — CÙNG MỘT <table>, ở ≤640px mỗi <tr> thành một THẺ xếp dọc. Mượn nguyên từ
   ung-dung.css (app); khu thành viên nạp style.css nên cần bản ở đây. Bọc bằng .tw thay cho .cuon.
   Ở màn rộng lớp này không đổi gì: bảng vẫn là bảng, cuộn trong .tw như mọi bảng từ ba cột.
   · data-label = ĐÚNG chữ của <th>; sinh cả hai từ một mảng cột.
   · .data-table-title: ô làm tiêu đề thẻ, đứng ĐẦU thẻ dù cột nằm đâu. .data-table-meta: dòng phụ.
   · Hai luật "dưới 560px ô không xuống dòng" ở trên cố ý BỎ QUA .data-table — thẻ mà ô không xuống
     dòng thì tràn. Mã trong thẻ được xuống dòng ở gạch nối (mã tổ chức 40 ký tự dài hơn một thẻ 320). */
@media (max-width:640px){
  .tw:has(> .data-table){overflow:visible; border:0; background:none}
  .tw > table.data-table{display:block; min-width:0; margin:0; background:none}
  .data-table > tbody{display:block}
  .data-table > thead{
    position:absolute; width:1px; height:1px; margin:-1px; padding:0; border:0;
    overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap;
  }
  .data-table > tbody > tr{
    display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 14px;
    margin:0 0 10px; padding:12px 14px; background-color:var(--mau-o); background-image:var(--anh-o);
    border:1px solid var(--line); border-radius:var(--bo-nho);
  }
  .data-table > tbody > tr::before{content:""; order:-2; flex-basis:100%; height:0}
  .data-table > tbody > tr > :is(td,th){
    display:block; flex:1 1 100%; min-width:0; padding:4px 0; border:0;
    overflow-wrap:break-word; text-align:left; background:none; white-space:normal;
    font:inherit; letter-spacing:normal; text-transform:none; color:inherit;
  }
  .data-table > tbody > tr > :is(td,th):empty{display:none}
  .data-table > tbody > tr > [data-label]:not([data-label=""])::before{
    content:attr(data-label); content:attr(data-label) / "";
    display:block; margin-bottom:2px;
    font-family:"IBM Plex Mono",monospace; font-size:11.5px; letter-spacing:.06em;
    text-transform:uppercase; color:var(--ink-3); font-weight:500;
  }
  .data-table > tbody > tr > .data-table-title{
    order:-3; flex:0 1 auto; padding:0 0 2px; font-size:15.5px; font-weight:600; color:var(--ink);
  }
  .data-table > tbody > tr > .data-table-title[data-label]::before{content:none}
  .data-table > tbody > tr > .data-table-meta{order:-1; flex:0 1 auto; padding:0 0 6px; font-size:13.5px}
  .data-table > tbody > tr > .data-table-meta[data-label]:not([data-label=""])::before{display:inline; margin:0 6px 0 0}
  .tw > table.data-table code{white-space:normal; overflow-wrap:anywhere}
}
code{font-family:"IBM Plex Mono",monospace; font-size:.9em; background:var(--alt); padding:2px 6px; border-radius:var(--bo-nho); word-break:break-word}

/* ---------- thẻ ---------- */
/* Không đặt trần bề rộng: mọi khối khác trên trang (thẻ sản phẩm, bảng giá,
   bảng) đều lấp đủ khung 1128px. Riêng lưới thẻ dừng ở 1000px thì hụt một
   khoảng bên phải và trông như bị lệch trái. */
/* minmax(0,1fr) chứ không 1fr: 1fr là minmax(auto,1fr) — cụm chữ dài nhất (email, URL) quyết định bề rộng
   TỐI THIỂU của cả cột và ép lưới rộng quá khung (đo 26/09). Chữ bình thường: bố cục không đổi.
   Cùng lý do cho .grid và .luoi-goi bên dưới. */
.cards{display:grid; grid-template-columns:minmax(0,1fr); gap:14px}
@media(min-width:760px){.cards.c3{grid-template-columns:repeat(3,minmax(0,1fr))} .cards.c2{grid-template-columns:repeat(2,minmax(0,1fr))}}
.card{border:1px solid var(--line-2); border-radius:var(--bo); padding:20px 22px; background-color:var(--mau-o)}
/* QUẦNG TRONG Ô — MỘT luật cho mọi ô (chủ dự án 05/10: .mine-card ở /tai-khoan, rồi «sửa cả các ô trên trang chủ và cả
   trên adpilot» ⇒ .card ở 6 trang + .tool ở /adpilot, cùng hạng kích thước 343–557px). Radial ở GIỮA-hơi-lệch-lên, rất
   nhạt (--anh-o, tokens.css: SÁNG = quầng teal --quang-o · TỐI = quầng xám, APL-245 — nay cho MỌI khung), tan về đúng màu nền ⇒ ⛔ mép. LỚP NỀN THỨ HAI của chính ô, ⛔ ::before/z-index ⇒ ⛔ có
   đường nào chôn nó sau một thẻ đục. Toạ độ theo % ⇒ tự co theo cỡ ô. TĨNH.
   ⚠ Ô nào nhận quầng thì ⛔ được đặt «background:» VIẾT TẮT ở bất kỳ luật nào — nó reset background-image ⇒ quầng chết
   IM LẶNG. Chỉ dùng background-color. ⛔ Chép luật này ra bản thứ hai: thêm ô vào danh sách :is() dưới đây. */
:is(.card, .tool, .mine-card){background-image:var(--anh-o)}
.card h3{margin:0 0 6px; font-size:16px}
.card p{margin:0; font-size:14.5px}
.card .n{font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--accent); margin-bottom:8px}

/* ---------- khối nhấn ---------- */
/* Nền --nen-wash, ⛔ không --accent-soft: khối rộng hết khung, nên ở tối --accent-soft (#163B36) thành tấm màu đặc —
   cùng ca .band.wash 04/10. Vạch trái 3px --accent là thứ mang tín hiệu; nền chỉ đỡ. Sáng: hai token trùng giá trị. */
.pull{border-left:3px solid var(--accent); background:var(--nen-wash); padding:18px 22px; margin:24px 0; border-radius:0 var(--bo) var(--bo) 0}
.pull p{margin:0; color:var(--ink); font-weight:600; max-width:56ch}
.note{border:1px solid var(--line-2); background-color:var(--mau-o); background-image:var(--anh-o); padding:16px 20px; margin:24px 0; border-radius:var(--bo)}
.note p{margin:0; font-size:14.5px}
.note p + p{margin-top:10px}

/* ---------- chân trang ---------- */
/* cùng luật «⛔ đường kẻ giữa các băng» (04/10): nền chân trang TAN từ --paper thay vì một vạch + một nhát cắt nền */
footer{padding-block:36px; background-color:var(--alt); background-image:linear-gradient(to bottom, var(--paper), transparent 72px)}
footer .wrap{padding-block:0}
footer p{font-size:13.5px; color:var(--ink-3); max-width:66ch}
footer a{color:var(--ink-2)}
.foot-links{display:flex; gap:18px; flex-wrap:wrap; margin-bottom:14px}
.foot-links a{font-size:14px; text-decoration:none}
.foot-links a:hover{color:var(--accent)}

/* =====================================================================
   TRANG CHỦ — hero giữa, thanh tìm, chip lọc, lưới thẻ
   ===================================================================== */

.hero{text-align:center; padding-block:60px 44px}
/* h1 trang chủ nói VIỆC ("Cho AI chạy Google Ads…"), không lặp tên thương hiệu — tên đã ở logo ngay trên
   (SPEC §25f, 30/09). Lớp .mark (chữ Orbitron "ALFA Software") gỡ cùng lượt: không trang nào còn dùng. */
.hero .tag{font-size:clamp(15px,2.2vw,19px); color:var(--ink-2); margin:0 auto 26px; max-width:46ch}
/* h1 chung có max-width:20ch để khỏi chạy dài, nhưng KHÔNG có margin:auto.
   .hero căn giữa CHỮ trong hộp, còn cái hộp thì nằm sát lề trái — nên tiêu
   đề lệch trái trong khi .tag ngay dưới nằm giữa. */
.hero h1{margin-left:auto; margin-right:auto}
/* Tiêu đề hai VẾ (trang chủ 06/10, chủ dự án chốt «Bộ ứng dụng để AI làm việc thật cho bạn / Bạn duyệt trước khi nó chạm vào»,
   rồi «bỏ dấu chấm cuối câu … bố trí cho trơn hơn»): MỖI VẾ MỘT DÒNG CỐ ĐỊNH (block) ⇒ ngắt ở RANH GIỚI NGHĨA, ⛔ dấu chấm
   nào phải gánh việc tách hai câu. Khổ hẹp mà một vế tự gãy thì gãy CÂN trong vế (balance) ⇒ ⛔ chữ mồ côi. Trước đó: balance cả
   h1 chẻ một vế ở 1440, <br> cứng thì «vào» mồ côi ở 768–1920. CHỈ áp khi h1 có .ve ⇒ tiêu đề hero 4 trang kia ⛔ đổi. */
/* 08/10 (APL-260 ④): nới từ `.hero h1` ra MỌI h1 có .ve — /adpilot dùng cùng mẫu mà hero của nó ⛔ mang .hero. Chỉ VẾ, CỠ,
   MÀU vế 1 đi theo; đệm khung và margin-bottom:0 vẫn CHỈ của .hero (hero trang chủ ⛔ có gì dưới h1 ngoài .goi-nut). */
h1 > .ve{display:block; text-wrap:balance}
h1:has(> .ve){max-width:30ch}
/* HERO MỘT CÂU (07/10, APL-259 ③): chủ dự án chốt hero CHỈ có câu hai vế ⇒ nó là thứ duy nhất trong khung đầu, nên
   to và có khoảng thở thay vì dồn 266px sát thanh đầu (đo 1440). Cỡ chữ theo bề rộng (clamp), ⛔ một số cứng: 30 → 58px.
   Vế 1 (ALFA là gì) màu chữ chính đặc; vế 2 (lời hứa) giữ gradient .tieu-de-sang ⇒ «cái gì» rồi «vì sao tin được».
   Bộ chọn :has(> h1 > .ve) mạnh hơn `.hero{padding-block}` ở dưới (khối kệ) và CHỈ ăn hero hai vế ⇒ 4 trang kia ⛔ đổi. */
.hero:has(> h1 > .ve){padding-block:clamp(52px, 7vw, 104px) clamp(40px, 5vw, 72px)}
h1:has(> .ve){font-size:clamp(30px, 3.2vw + 12px, 56px); line-height:1.1; letter-spacing:-.025em}
.hero h1:has(> .ve){margin-bottom:0}
/* HERO HAI VẾ Ở ĐIỆN THOẠI (APL-260 vế 4, chủ dự án chụp iPhone 08/10: «chữ trên hero có vẻ hơi nhỏ»). Luật chung
   3,2vw + 12px chạm sàn 30px ở MỌI khổ dưới ~560 ⇒ ở 390 dòng rộng nhất chỉ 83% bề rộng nội dung, hai dòng vế 2 chỉ 63%.
   Ở đây cỡ chữ đi THẲNG theo bề rộng: 8,4vw ⇒ dòng rộng nhất ≈ 90–92% nội dung từ 360 tới 430 (đo 08/10, Range từng ký tự):
   375 → 31,5px 91% · 390 → 32,8px 91% · 414 → 34,8px 91% · 430 → 36,1px 90%; vẫn 2 + 2 dòng, ⛔ từ ghép nào bị chẻ.
   ⛔ Nâng tới «lấp 98%»: ở 390, 36px đã chẻ vế 1 thành 3 dòng ⇒ 8,4vw chừa ~8% cho Safari dựng chữ rộng hơn Chrome.
   Sàn 30px ⇒ 320 GIỮ NGUYÊN (3 + 2). Chỉ dưới 560px ⇒ dấu vân h1 ≥ 560 (gồm mốc ≥1024 đã duyệt) ⛔ đổi.
   72px − 7,5vw là vế HẠ: đỉnh ≈38px quanh 453px rồi về ĐÚNG 30px tại 560 ⇒ liền với luật chung. Bản đầu (chỉ 8,4vw, trần 40)
   nhảy 40 → 30px giữa 559 và 560 (đo 08/10). */
@media (max-width:559.98px){ .hero h1:has(> .ve){font-size:clamp(30px, min(8.4vw, 72px - 7.5vw), 40px)} }
h1.tieu-de-sang > .ve:first-child{color:var(--hieu-dau)}
.hero:has(> h1 > .ve) .goi-nut{margin-top:clamp(28px, 3.2vw, 40px)!important}
.hero:has(> h1 > .ve) .goi-nut .btn{font-size:16px; padding:13px 24px}

/* thanh tìm */
/* Ô tìm rộng ĐÚNG BẰNG .wrap (SPEC §30, chủ dự án gạch X lần 2 lên vùng trống hero /ke 04/10). Trước đây trần 660px
   căn giữa ⇒ hero hẹp hơn khối «Sản phẩm» ngay dưới. Phép miễn «khối mở đầu căn giữa» của §30 chỉ phủ eyebrow ·
   tiêu đề · đoạn dẫn · hàng nút — ô tìm là ĐIỀU KHIỂN, không phải câu dẫn, nên theo luật chung. */
.seek{
  display:flex; align-items:center; gap:10px;
  max-width:none; margin:0; background:var(--surface);
  border:1px solid var(--vien-dieu-khien); border-radius:var(--bo-nho);
  padding:4px 6px 4px 18px; box-shadow:var(--bong);
}
.seek svg{flex:none; color:var(--ink-3)}
.seek input{
  flex:1; border:0; background:transparent; color:var(--ink);
  font-family:inherit; font-size:15.5px; padding:12px 0; min-width:0;
}
.seek input::placeholder{color:var(--ink-3)}
.seek input:focus{outline:none}
/* ...nên KHUNG NGOÀI nhận dấu focus thay (WCAG 2.4.7) — trước đây không có gì thay, bấm Tab vào ô tìm là mất dấu. */
.seek:focus-within{border-color:var(--accent); outline:2px solid var(--accent); outline-offset:2px}
/* 40×40 như mọi thứ bấm được (đo 26/09: 32×32). Khung .seek đã cao ~51px nhờ ô nhập, nên nút lớn hơn
   không làm khung cao thêm — chỉ lấy của ô nhập 8px bề ngang. */
.seek .clr{
  border:0; background:var(--alt); color:var(--ink-2); cursor:pointer;
  border-radius:var(--bo-nho); width:40px; height:40px; font-size:16px; line-height:1;
  flex:none; margin-right:0;
}

/* chip lọc */
.chips{display:flex; gap:8px; flex-wrap:wrap; justify-content:center; margin:18px auto 0; max-width:820px}
.chip{
  font-family:inherit; font-size:13.5px; font-weight:500;
  border:1px solid var(--vien-dieu-khien); background:var(--surface); color:var(--ink-2);
  border-radius:var(--bo-nho); padding:6px 15px; cursor:pointer; white-space:nowrap; min-height:40px;
}
.chip:hover{border-color:var(--accent); color:var(--accent)}
.chip[aria-pressed="true"]{background:var(--accent); border-color:var(--accent); color:var(--accent-ink)}
/* Số đếm KẾ THỪA màu chip, không opacity (§21.6 B8, đo 27/09): opacity:.75 trộn --ink-2 với nền thành
   #849299 = 3.20:1 ở 11.5px, cần 4.5. Không đặt thẳng một màu xám: chip đang chọn chữ trắng trên nền đậm,
   xám ở đó lại trượt. Kế thừa thì đúng ở cả ba trạng thái — thường 5.33 · rê chuột · đang chọn. Phân biệt
   với chữ nhãn đã có font mono và cỡ nhỏ. */
.chip b{font-family:"IBM Plex Mono",monospace; font-size:11.5px; font-weight:500; margin-left:6px}

.tally{
  font-size:14.5px; color:var(--ink-3); text-align:center; margin:22px 0 0;
  max-width:none;
}
.tally b{font-family:"IBM Plex Mono",monospace; font-weight:500; color:var(--ink); font-size:17px}

/* băng mời */
.promo{
  max-width:1000px; margin:34px auto 0; background-color:var(--mau-o); background-image:var(--anh-o);
  border:1px solid var(--line-2); border-radius:var(--bo); padding:20px 24px;
  display:flex; gap:18px; align-items:center; flex-wrap:wrap; text-align:left;
  box-shadow:var(--bong);
}
.promo-k{font-family:"IBM Plex Mono",monospace; font-size:11.5px; letter-spacing:.13em; text-transform:uppercase; color:var(--accent); margin:0 0 4px}
.promo-t{font-weight:600; font-size:16px; color:var(--ink); margin:0 0 3px}
.promo p{margin:0; font-size:14px}
.promo .btn{margin-left:auto; flex:none; padding:10px 18px; font-size:14px}
.promo > div{flex:1 1 16rem; min-width:0}   /* mục flex: min-width:auto thì chữ dài ép .promo rộng quá khung */

/* ---------- lưới thẻ ---------- */
.shelf{margin-top:38px}
.shelf-h{display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; margin-bottom:14px}
.shelf-h h2{margin:0; font-size:19px; font-weight:600}
.shelf-h .cnt{font-family:"IBM Plex Mono",monospace; font-size:12px; color:var(--ink-3)}
/* liên kết cao 15px: đệm dọc 12px bù bằng lề âm → vùng bấm ~40px, dòng tiêu đề kệ không cao thêm */
.shelf-h .cnt a{display:inline-block; padding-block:12px; margin-block:-12px}
.grid{display:grid; gap:14px; grid-template-columns:minmax(0,1fr)}
@media(min-width:620px){.grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(min-width:980px){.grid{grid-template-columns:repeat(3,minmax(0,1fr))}}

/* thẻ sản phẩm lớn */
.prod{
  display:block; text-decoration:none; color:inherit;
  border:1px solid var(--line-2); border-radius:var(--bo); background-color:var(--mau-o); background-image:var(--anh-o);
  padding:24px 26px; box-shadow:var(--bong); grid-column:1/-1;
}
.prod:hover{border-color:var(--accent); box-shadow:var(--bong-cao)}
.prod-h{display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-bottom:6px}
.prod-name{font-weight:800; font-size:19px; color:var(--hieu-dau)}
.prod-name b{color:var(--hieu-cuoi)}
.prod-for{font-family:"IBM Plex Mono",monospace; font-size:13px; color:var(--ink-3); margin:0 0 12px}
.prod-desc{font-size:15px; color:var(--ink-2); margin:0 0 14px; max-width:70ch}
.prod-pts{margin:0 0 16px; padding-left:20px; font-size:14.5px; max-width:70ch}
.prod-pts li{margin-bottom:6px}
/* Dãy huy hiệu trên thẻ sản phẩm — để SO, không phải để đọc. Nhỏ hơn
   .badge ở đầu thẻ, vì cái kia là trạng thái sản phẩm còn cái này là
   thông số. */
/* ---------- MỤC LỤC DÍNH cho trang dài ----------
   Trang giá cao 4.260px, trang tài liệu cũng cỡ đó. Không có mục lục thì
   người đọc chỉ còn cách cuộn mò. Dính ngay dưới thanh trên (đo được 77px
   trên bản chạy thật), và là một dải NGANG chứ không phải cột bên — dải
   ngang chạy được ở mọi bề rộng, cột bên thì phải dựng lại cho điện thoại. */
.muc-luc{
  position:sticky; top:var(--cao-nav); z-index:19;
  background:var(--dau-nen);
  backdrop-filter:saturate(1.4) blur(10px);
  border-bottom:1px solid var(--line);
}
.muc-luc-in{
  max-width:1160px; margin:0 auto; padding:0 16px;
  display:flex; gap:4px; overflow-x:auto; scrollbar-width:none;
}
.muc-luc-in::-webkit-scrollbar{display:none}
/* GỢI Ý CUỘN — bóng mờ ở mép nào CÒN nội dung (đo 25/09: .muc-luc-in rộng 606px ở bang-gia và
   881px ở tai-lieu trong khung ~358px, thanh cuộn ẩn nên không gì báo còn mục bên phải; điện
   thoại dùng thanh cuộn nổi nên bảng .tw cũng vậy). Thuần CSS: hai lớp che (attachment local)
   trôi theo nội dung và đè lên bóng khi đã ở mép; hai lớp bóng (scroll) đứng yên ở mép khung.
   Không có gì để cuộn thì che luôn nằm đúng trên bóng: màn rộng không thấy gì khác.
   Lớp che phải CÙNG MÀU nền khung — màu ấy đi qua --phu-mep, xem ngay dưới. */
.muc-luc-in, .tw{
  background:
    linear-gradient(to right, var(--phu-mep, var(--surface)) 40%, transparent) left center / 36px 100% no-repeat local,
    linear-gradient(to left, var(--phu-mep, var(--surface)) 40%, transparent) right center / 36px 100% no-repeat local,
    linear-gradient(to right, var(--line-2), transparent) left center / 16px 100% no-repeat scroll,
    linear-gradient(to left, var(--line-2), transparent) right center / 16px 100% no-repeat scroll;
}
/* Lớp che phải CÙNG MÀU nền của CHÍNH khung: .tw nay là ô (APL-245, --mau-o — đen ở tối), còn .muc-luc-in nằm trên dải
   .muc-luc nền --dau-nen ≈ --surface ⇒ hai khung, hai màu che. Biến cục bộ --phu-mep, mặc định --surface. */
.tw{background-color:var(--mau-o); --phu-mep:var(--mau-o)}
/* Bóng mép ở trên MỘT MÌNH không đủ (đo 30/09, mọi bề rộng 320–440): dấu "còn nữa" rõ nhất là một mục
   bị CẮT NGANG chữ ở mép, và mép rơi vào khe giữa hai mục suốt một dải 34px mỗi trang — /tai-lieu
   345–378, /bang-gia 365–398, /noi-ai 376–409, tức đúng 360 · 375 · 390 · 393 · 402. Ở đó dấu duy
   nhất là bóng --line-2 16px, tương phản ~1,5:1. Nên thêm một lớp mờ dần + "›" ĐÈ lên mép phải.
   Chỉ hiện khi còn nội dung bên phải: hoạt ảnh gắn vào chính thanh cuộn của .muc-luc-in (timeline-scope
   để giả tố của cha đọc được timeline của con), 0 → 92% cuộn thì hiện, tới cuối thì tắt. Không có gì để
   cuộn thì timeline không hoạt động, hoạt ảnh không áp, lớp giữ opacity:0 gốc — màn rộng không thấy gì.
   Trình duyệt chưa có scroll-driven animation: cũng opacity:0 ⇒ còn lại đúng bóng mép như cũ. Hỏng về
   hiện trạng, không hỏng tệ hơn. pointer-events:none: mục nằm dưới lớp mờ vẫn bấm được. */
.muc-luc{timeline-scope:--muc-luc}
.muc-luc-in{scroll-timeline:--muc-luc inline}
.muc-luc::after{
  content:"›"; content:"›" / "";
  position:absolute; top:0; right:0; bottom:1px; width:44px;
  display:flex; align-items:center; justify-content:flex-end; padding-right:10px;
  font-size:22px; line-height:1; color:var(--ink-3); pointer-events:none;
  background:linear-gradient(to right, transparent, var(--surface) 55%);
  opacity:0; animation:muc-luc-con-nua linear both; animation-timeline:--muc-luc;
}
@keyframes muc-luc-con-nua{0%, 92%{opacity:1} 100%{opacity:0}}
.muc-luc a{
  flex:none; display:inline-flex; align-items:center; min-height:46px;
  padding:0 13px; font-size:14px; color:var(--ink-2); text-decoration:none;
  border-bottom:2px solid transparent; white-space:nowrap;
}
.muc-luc a:hover{color:var(--hieu-dau)}
.muc-luc a.dang{color:var(--accent); font-weight:700; border-bottom-color:var(--accent)}
/* Mục lục cao 47px, nên neo phải chừa thêm chỗ cho nó. */
body.co-muc-luc section[id]{scroll-margin-top:calc(var(--cao-nav) + 49px)}

/* ---------- BỐ CỤC TRANG GIÁ ---------- (thẻ gói: .bang-goi · .the-goi ngay dưới) */
/* ---------- BẢNG GÓI — .bang-goi · .the-goi (SPEC §28.10, chủ dự án chốt 03/10 kèm bản tham khảo) ----------
   MỘT hình cho HAI bề mặt: /bang-gia (markup tĩnh) và khu "Gói đang bán" của /tai-khoan (JS dựng từ goi_dang_ban()).
   Trước 03/10 hai bề mặt ở hai hình (3 cột + dùng thử dưới đáy · lưới 2×2) — cùng bốn gói mà hai hình thì sớm muộn
   lệch nội dung, theo hai chiều mà không phép so nào bắt được.

     <div class="bang-goi"><div class="luoi-goi">
       <article class="the-goi [chu-luc] [dang-dung]">
         <div class="goi-dau"><h3 class="prod-name">AdPilot · <b>Agency</b></h3>
           <span class="goi-hien-tai">Gói hiện tại</span></div>          ← pill: chỉ khi đang dùng
         <p class="goi-gia">1.490.000 ₫<span>/tháng</span></p>
         <p class="goi-thue">đã gồm thuế GTGT</p>
         <p class="goi-mo-ta">{goi.mo_ta}</p>
         <ul class="goi-ds"><li>…</li> ×4</ul>                                ← li.khong cho dòng "không có …"
         <a class="btn …">…</a> | <button class="btn …">…</button>
       </article> ×4
     </div></div>

   · BỐN CỘT MỘT HÀNG, dùng thử đứng TRONG hàng ở đầu (①): khách so bậc bằng cách ĐỌC NGANG; một thẻ ngoài hàng là
     một thẻ không so được. Cột đo bằng @container trên .bang-goi, KHÔNG đo cửa sổ: /tai-khoan có thanh bên 260px nên
     ở 1056 cửa sổ chỉ còn ~740px nội dung — bốn cột 175px thì giá "3.900.000 ₫" tràn thẻ. 4 cột từ 62rem bề rộng
     BẢNG · 2×2 từ 34rem · một cột dưới đó. Thứ tự giữ nguyên ở mọi khổ.
   · subgrid: sáu hàng của mọi thẻ (đầu · giá · thuế · mô tả · danh sách · nút) thẳng hàng NGANG nhau — mô tả dài
     ngắn khác nhau thì danh sách ✓ vẫn bắt đầu cùng một vạch, và bốn nút cùng một hàng (⑥). Trình duyệt chưa có
     subgrid thì rơi về cột flex, nút vẫn ở đáy nhờ margin-top:auto.
   · GIÁ LÀ NHÂN VẬT CHÍNH (②): số lớn, màu --hieu-cuoi (teal thương hiệu bản đậm, 4.61:1 trên trắng — chữ lớn chỉ
     cần 3:1), "/tháng" nhỏ nhạt CÙNG DÒNG. Inter số rộng đều, không mono: mono 34px làm "3.900.000 ₫" rộng 224px.
   · Danh sách ✓ CÙNG BỐN DÒNG, CÙNG THỨ TỰ ở mọi thẻ (⑤): tài khoản · câu hỏi Studio · ví lượt · trần ngày. Thiếu
     thì GHI "không có …" với li.khong (gạch ngang nhạt thay dấu ✓) — bỏ dòng là lệch hàng cả bảng.
   · Không màu nào mang nghĩa một mình: "Gói hiện tại" là CHỮ trong pill, bậc chủ lực có vạch viền, li.khong có chữ. */
/* KHUNG THEO SẢN PHẨM ở /tai-khoan (03/10): mỗi sản phẩm một .nhom-goi, tên sản phẩm (h4) ở trên bảng gói của nó.
     <section class="nhom-goi" aria-labelledby="…"><h4 class="nhom-goi-ten" id="…">ALFA AdPilot</h4>
       <div class="bang-goi">…</div></section>
   Tên nhóm là NHÃN của cả khối nên nó to hơn tên thẻ (17px) một bậc và có vạch kẻ chạy hết hàng — đọc thành
   "phần của AdPilot", không đọc thành một thẻ thứ năm. Hai nhóm cách nhau 32px. */
.nhom-goi + .nhom-goi{margin-top:32px}
.nhom-goi-ten{
  display:flex; align-items:center; gap:12px; margin:0 0 14px;
  font-size:19px; font-weight:800; line-height:1.3; color:var(--hieu-dau);
}
.nhom-goi-ten::after{content:""; flex:1; height:1px; background:var(--line-2)}
.bang-goi{container-type:inline-size; margin:0}
.luoi-goi{display:grid; gap:16px; grid-template-columns:minmax(0,1fr)}
@container (min-width:34rem){ .luoi-goi{grid-template-columns:repeat(2,minmax(0,1fr))} }
/* "/tháng" CÙNG DÒNG chỉ từ 66rem bề rộng BẢNG, ⛔ không 62rem: đo 03/10 bằng Range trên cụm giá, ở 62–65rem thẻ chỉ 238–263px mà
   "3.900.000 ₫/tháng" (32px) rộng ~272px ⇒ giá vượt mép nội dung thẻ tới 34px. Phép đo cũ (scrollWidth >
   clientWidth trên .goi-gia) KHÔNG thấy vì phần tràn không bị cắt — đo CỤM CHỮ, đừng đo hộp. */
/* Chủ dự án 03/10: "làm lại khung bảng giá như trang chủ" — /tai-khoan ở khổ của anh ấy ra 2×2 vì thanh bên ăn
   bề rộng. ⇒ 4 cột từ 56rem bảng (≈ cửa sổ 1235px khi thanh bên mở), và ở dải chật 56–66rem cụm giá đổi hình:
   26px, "/tháng" xuống dòng riêng. Đo cụm "3.900.000₫/tháng" bằng Range: 32px 217 · 26px 185 (cùng dòng ⇒ bảng
   ≥1008px) · 26px chỉ phần số+₫ 139 (⇒ bảng ≥820px, kể cả đệm thẻ 42 và 12px thở). */
@container (min-width:56rem){ .luoi-goi{grid-template-columns:repeat(4,minmax(0,1fr))} }
.the-goi{
  display:flex; flex-direction:column; min-width:0; margin:0;
  padding:22px 20px; border:1px solid var(--line-2); border-radius:var(--bo); background-color:var(--mau-o); background-image:var(--anh-o);
}
@supports (grid-template-rows:subgrid){
  .the-goi{display:grid; grid-row:span 6; grid-template-rows:subgrid; row-gap:0}
  /* Nút giãn hết hàng cuối: nhãn dài ("Đã gồm trong gói của bạn") xuống hai dòng thì nút ấy cao hơn, và với
     margin-top:auto mỗi nút dính đáy RIÊNG của nó ⇒ đo 03/10 ở 1440: hai mép trên khác nhau. Giãn ⇒ một hàng. */
  /* height:100%, KHÔNG align-self:stretch: đo 03/10, <button> trong ô lưới KHÔNG giãn theo stretch (65 · 65 · 46 · 46). */
  .the-goi > .btn{margin-top:0; height:100%; display:flex; align-items:center}
}
.the-goi.chu-luc{border-color:var(--accent); box-shadow:var(--bong-cao)}
.the-goi.dang-dung{border-color:var(--hieu-cuoi); box-shadow:inset 0 3px 0 var(--hieu-cuoi)}
.goi-dau{display:flex; flex-direction:column; align-items:flex-start; gap:8px}
.goi-dau > .prod-name{margin:0; font-size:17px; line-height:1.3}
/* Chữ --accent, ⛔ không --hieu-cuoi: 12px là chữ THƯỜNG theo WCAG (cần 4,5:1), mà --hieu-cuoi trên --accent-soft
   ở sáng chỉ 4,21 (thước tương phản 04/10, màn Gói của tôi). --accent: sáng 11,32 · tối 6,85. */
.goi-hien-tai{
  font-size:12px; font-weight:700; line-height:1; padding:5px 10px; border-radius:var(--bo-tron);
  background:var(--accent-soft); color:var(--accent); border:1px solid var(--line-2);
}
.goi-gia{
  margin:14px 0 0; font-size:32px; font-weight:800; line-height:1.1; letter-spacing:-.02em;
  color:var(--hieu-cuoi); font-variant-numeric:tabular-nums; white-space:nowrap;
}
.goi-gia > span{font-size:14px; font-weight:500; letter-spacing:0; color:var(--ink-3); margin-left:3px}
/* Ký hiệu tiền NHỎ hơn con số: con số là thứ so, "₫" chỉ là đơn vị — để nó cao bằng con số là kéo dài cụm giá
   mà không thêm thông tin. Bốn cột còn hẹp (66–84rem bảng) thì giá 28px; rộng hơn mới 32px. */
.goi-gia > .te{font-size:.6em; font-weight:700; letter-spacing:0; color:inherit; margin-left:.15em}
@container (min-width:66rem) and (max-width:83.99rem){ .goi-gia{font-size:28px} }
/* Dải chật 56–66rem (đặt SAU luật gốc .goi-gia: cùng độ ưu tiên thì luật sau thắng). */
@container (min-width:56rem) and (max-width:65.99rem){
  .goi-gia{font-size:26px}
  .goi-gia > span:not(.te){display:block; margin:3px 0 0}
}
.goi-thue{margin:4px 0 0; font-size:12.5px; color:var(--ink-3)}
.goi-mo-ta{margin:12px 0 0; font-size:14px; line-height:1.5; color:var(--ink-2)}
.goi-ds{list-style:none; margin:16px 0 20px; padding:14px 0 0; border-top:1px solid var(--line); font-size:14px}
.goi-ds > li{position:relative; padding-left:24px; margin:0 0 8px; overflow-wrap:anywhere}
.goi-ds > li:last-child{margin-bottom:0}
.goi-ds > li::before{
  content:""; position:absolute; left:3px; top:.42em; width:10px; height:5px;
  border-left:2px solid var(--hieu-cuoi); border-bottom:2px solid var(--hieu-cuoi); transform:rotate(-45deg);
}
.goi-ds > li.khong{color:var(--ink-3)}
.goi-ds > li.khong::before{top:.7em; width:10px; height:0; border-left:0; border-bottom:2px solid var(--ink-3); transform:none}
.the-goi > .btn{margin-top:auto; align-self:stretch; text-align:center; justify-content:center}
/* GÓI SẮP RA MẮT (§32.2, 12/10): hiện giá, ⛔ mua được. Hàng nút (hàng thứ sáu của subgrid) mang một DÒNG CHỮ, ⛔ một nút
   khoá: một <button disabled> vẫn đọc thành «nút» với trình đọc màn hình và trông như bấm được ở tương phản thấp.
   Viền NÉT ĐỨT, cùng cỡ chữ và cùng đệm với .btn ⇒ hàng cuối các thẻ vẫn thẳng nhau khi thẻ bán và thẻ sắp ra mắt
   đứng chung một lưới. Chữ --ink-2 trên nền thẻ: đủ 4,5:1 ở cả sáng lẫn tối (cùng cặp với .goi-mo-ta). */
.goi-sap{
  margin:auto 0 0; align-self:stretch; display:flex; align-items:center; justify-content:center; text-align:center;
  padding:12px 16px; border:1px dashed var(--line-2); border-radius:var(--bo-nho);
  font-size:14px; font-weight:600; line-height:1.3; color:var(--ink-2);
}
@supports (grid-template-rows:subgrid){ .the-goi > .goi-sap{margin-top:0; height:100%} }
/* Khối «sắp ra mắt» ở /adpilot/bang-gia: một nhãn đầu khối nói điều ấy MỘT lần cho cả khối, trước khi khách đọc giá. */
.nhan-sap{
  display:table; margin:48px 0 18px; padding:5px 12px; border-radius:var(--bo-tron);
  font-size:13px; font-weight:700; line-height:1.3; color:var(--accent); background:var(--accent-soft); border:1px solid var(--line-2);
}
/* Nhãn là đích của mục lục (#sap-ra-mat) mà nó là <p>, ⛔ section ⇒ luật scroll-margin của section[id] ⛔ áp; thiếu dòng
   này thì bấm «Sắp ra mắt» trên mục lục, nhãn nằm DƯỚI thanh dính (đo 12/10). Cùng số với luật section[id]. */
body.co-muc-luc .nhan-sap[id]{scroll-margin-top:calc(var(--cao-nav) + 49px)}
/* Luật đếm tài khoản — đứng NGAY dưới bảng, cùng bề rộng bảng. Là luật, không phải chú thích: chữ thường cỡ đọc
   được, không dùng .micro. Nền --accent-soft để nó thuộc về bảng giá chứ không trôi thành một đoạn văn riêng. */
.gia-dem{
  margin:18px 0 0; padding:16px 20px; border-radius:var(--bo);
  background:var(--accent-soft); border:1px solid var(--line-2);
}
.gia-dem p{margin:0; font-size:15px; color:var(--ink)}
.gia-dem p + p{margin-top:6px}

/* ---------- CHỌN THEO SỐ TÀI KHOẢN — .chon-tk (APL-260 ②) ----------
   Hàng radio trên bảng gói: bấm «Tới 30» thì thẻ Agency nổi lên. Thuần CSS bằng :has(), nên trình duyệt ⛔ có :has()
   thì CẢ HÀNG ẨN — một nút bấm mà ⛔ làm gì là tệ hơn ⛔ có nút (PM 08/10). Nhãn và ô cùng một <label> (luật o-nhap).
   Thẻ khớp tìm theo DANH TÍNH data-goi trong .goi-dau, ⛔ theo vị trí (:nth-child) — thêm một thẻ ⛔ đổi đích. */
.chon-tk{display:none}
@supports selector(:has(*)){
  .chon-tk{display:flex}
  /* Dưới 560px bốn nút (138 · 96 · 106 · 112 = 452px + khe) ⛔ vừa một hàng ⇒ flex-wrap cho 3 + 1, «Hơn 30» đứng lẻ (đo 08/10
     ở 390). Lưới 2 × 2 thì hai hàng bằng nhau. */
  @media (max-width:559.98px){ .chon-tk{display:grid; grid-template-columns:repeat(2, minmax(0, 1fr))} .chon-tk > label{justify-content:center} }
}
.chon-tk{flex-wrap:wrap; justify-content:center; gap:8px; margin:0 0 20px; padding:0; border:0; min-width:0}
.chon-tk > legend{width:100%; padding:0; margin:0 0 10px; text-align:center; font-size:15px; font-weight:600; color:var(--ink)}
.chon-tk > label{
  display:inline-flex; align-items:center; gap:8px; min-height:44px; padding:0 16px; cursor:pointer;
  border:1px solid var(--line-2); border-radius:var(--bo-tron); background-color:var(--mau-o);
  font-size:15px; color:var(--ink); font-variant-numeric:tabular-nums; white-space:nowrap;
}
.chon-tk > label > input{width:18px; height:18px; margin:0; accent-color:var(--accent); flex:none}
/* --accent trên --accent-soft: sáng 11,32 · tối 6,85 (thước tương phản 04/10, xem .goi-hien-tai). */
.chon-tk > label:has(:checked){border-color:var(--accent); background-color:var(--accent-soft); color:var(--accent); font-weight:600}
.chon-tk > label:has(:focus-visible){outline:2px solid var(--accent); outline-offset:2px}
#goi:has(.chon-tk [value="alfa-dung-thu"]:checked) .the-goi:has(> .goi-dau [data-goi="alfa-dung-thu"]),
#goi:has(.chon-tk [value="adpilot-khoi-dau"]:checked) .the-goi:has(> .goi-dau [data-goi="adpilot-khoi-dau"]),
#goi:has(.chon-tk [value="adpilot-agency"]:checked) .the-goi:has(> .goi-dau [data-goi="adpilot-agency"]),
#goi:has(.chon-tk [value="adpilot-khong-gioi-han"]:checked) .the-goi:has(> .goi-dau [data-goi="adpilot-khong-gioi-han"]){
  border-color:var(--accent); box-shadow:var(--bong-cao); outline:2px solid var(--accent); outline-offset:3px;
}
/* Đã chọn thì bậc chủ lực thôi nổi — hai thẻ cùng nổi là ⛔ nói được thẻ nào hợp. Độ ưu tiên (1,4,0) < luật trên (1,6,0)
   ⇒ khi chính Agency được chọn, luật trên vẫn thắng. */
#goi:has(.chon-tk :checked) .the-goi.chu-luc{border-color:var(--line-2); box-shadow:none}
/* Một cột (điện thoại): thẻ khớp lên ĐẦU, ⛔ thì bấm «Hơn 30» rồi phải cuộn qua ba thẻ mới thấy nó. Chỉ đổi thứ tự
   HIỂN THỊ của bốn thẻ độc lập — thứ tự đọc của trình đọc màn hình vẫn theo HTML. Hai cột trở lên ⇒ ⛔ đổi. */
@container (max-width:33.99rem){
  #goi:has(.chon-tk [value="alfa-dung-thu"]:checked) .the-goi:has(> .goi-dau [data-goi="alfa-dung-thu"]),
  #goi:has(.chon-tk [value="adpilot-khoi-dau"]:checked) .the-goi:has(> .goi-dau [data-goi="adpilot-khoi-dau"]),
  #goi:has(.chon-tk [value="adpilot-agency"]:checked) .the-goi:has(> .goi-dau [data-goi="adpilot-agency"]),
  #goi:has(.chon-tk [value="adpilot-khong-gioi-han"]:checked) .the-goi:has(> .goi-dau [data-goi="adpilot-khong-gioi-han"]){order:-1}
}

/* ---------- BẢNG SO SÁNH GÓI — .so-goi (APL-260 ②) ----------
   Năm cột ⇒ rơi vào luật .tw «từ ba cột»: cuộn ngang, ô ⛔ xuống dòng dưới 560px. Nhãn dòng là CÂU ⇒ chữ thường,
   ⛔ kiểu nhãn cột viết hoa mono. */
.so-goi tbody th{font-family:inherit; font-size:14px; font-weight:600; letter-spacing:0; text-transform:none; color:var(--ink); background:transparent}
.so-goi td{font-variant-numeric:tabular-nums}
.so-goi td > .te{margin-left:.1em}

/* ---------- HỎI–ĐÁP MỞ ĐƯỢC — .hoi-dap (APL-260 ③) ----------
   <details> trần, mỗi câu một khung. Tiêu đề là <summary> (một nút có tên ⇒ bàn phím + trình đọc màn hình dùng được).
   ⛔ Đặt giá hay hạn mức vào đây: khách phải thấy số mà ⛔ bấm (PM 08/10). Dấu +/− là CSS, ⛔ thông tin: trạng thái
   mở/đóng trình duyệt đã báo qua chính <details>. */
.hoi-dap{display:grid; gap:10px; margin:22px 0 0}
.hoi-dap > details{border:1px solid var(--line-2); border-radius:var(--bo); background-color:var(--mau-o); min-width:0}
.hoi-dap > details > summary{
  display:flex; align-items:center; justify-content:space-between; gap:14px; min-height:48px; padding:12px 20px;
  list-style:none; cursor:pointer; font-size:16px; font-weight:600; line-height:1.35; color:var(--ink);
}
.hoi-dap > details > summary::-webkit-details-marker{display:none}
.hoi-dap > details > summary::after{content:"+"; flex:none; font-size:22px; font-weight:500; line-height:1; color:var(--accent)}
.hoi-dap > details[open] > summary::after{content:"−"}
.hoi-dap > details > summary:focus-visible{outline:2px solid var(--accent); outline-offset:2px; border-radius:var(--bo)}
.hoi-dap > details > :not(summary){margin:0 20px 12px; font-size:14.5px}
.hoi-dap > details > :last-child{margin-bottom:18px}


/* Câu dẫn dưới tiêu đề mục — dài hơn .o-phu, đứng riêng một dòng. */
.dan{font-size:16px; color:var(--ink-2); max-width:70ch; margin:0 0 22px}

.prod-nhan{display:flex; gap:6px; flex-wrap:wrap; margin:0 0 14px}
.the-nho{
  font-family:"IBM Plex Mono",monospace; font-size:13px;
  padding:3px 9px; border-radius:var(--bo-tron);
  border:1px solid var(--line-2); background:var(--alt); color:var(--ink-3);
  /* KHÔNG nowrap: ở 13px, nhãn "Trong gói ALFA 499.000 ₫/tháng" rộng ~254px mà lòng thẻ ở 320px
     còn ~234px, lưới 1fr nở theo và cả trang tràn ngang 4px (đo 25/09). Đủ chỗ thì vẫn một dòng. */
}
.prod:hover .the-nho{border-color:var(--hieu)}
.prod-go{font-weight:600; font-size:14.5px; color:var(--accent)}

/* thẻ nhóm công cụ */
.tool{
  border:1px solid var(--line); border-radius:var(--bo); background-color:var(--mau-o);
  padding:18px 20px; display:flex; flex-direction:column; gap:8px;
}
.tool:hover{border-color:var(--line-2); box-shadow:var(--bong)}
.tool-h{display:flex; align-items:center; gap:9px}
.tool-k{
  font-family:"IBM Plex Mono",monospace; font-weight:500; font-size:12px;
  width:26px; height:26px; flex:none; border-radius:0; /* vuông như .loop-index của bộ gốc */
  background:var(--accent-soft); color:var(--accent);
  display:flex; align-items:center; justify-content:center;
}
.tool-h h3{margin:0; font-size:15.5px; font-weight:600; flex:1}
.tool-n{font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--ink-3)}
.tool p{margin:0; font-size:13.5px; color:var(--ink-3)}
.tool-list{display:flex; flex-wrap:wrap; gap:5px; margin-top:2px}
/* 13px, không 11.5: 65 tên monospace có gạch dưới (tai_khoan_hien_tai) ở 11.5px thì i/l/_ dính
   nhau. Đo 25/09 ở 390px: mục #cong-cu dài thêm 6% (2905 → 3078px); phiên nền tảng chọn 13px. */
.tool-list code{font-size:13px; background:var(--alt); color:var(--ink-2); padding:2px 7px; border-radius:var(--bo-tron)}
.tool-list code.dx{background:var(--accent-soft); color:var(--accent)}

/* nhãn */
/* Khối lưu ý trên NỀN SÁNG. Tông cảnh báo vì thứ nó nói luôn là một
   điều kiện kèm theo, không phải một lời quảng cáo. */
.luuy{
  background:var(--warn-soft); border:1px solid var(--warn);
  border-left-width:4px; border-radius:var(--bo);
  padding:16px 20px; margin:24px 0 0; max-width:74ch;
}
.luuy p{margin:0; font-size:14.5px; color:var(--ink)}
.luuy p + p{margin-top:9px}
.luuy .ai{font-size:13px; color:var(--warn)}

.badge{
  font-family:"IBM Plex Mono",monospace; font-size:11.5px; letter-spacing:.08em;
  text-transform:uppercase; padding:3px 10px; border-radius:var(--bo-tron);
  border:1px solid var(--line-2); color:var(--ink-3); background:var(--alt);
  white-space:nowrap;
}
.badge.live{border-color:var(--accent); color:var(--accent); background:var(--accent-soft)}
.badge.soon-b{border-style:dashed}

/* ô sản phẩm chưa có */
.soon{
  border:1px dashed var(--line-2); border-radius:var(--bo);
  padding:20px 24px; background:transparent; grid-column:1/-1;
}
.soon .prod-name{color:var(--ink-3); font-weight:600; font-size:16px}
.soon p{margin:0; font-size:14.5px}

/* không có kết quả */
.empty{
  border:1px dashed var(--line-2); border-radius:var(--bo);
  padding:34px 24px; text-align:center; grid-column:1/-1;
}
.empty p{margin:0 auto 14px; color:var(--ink-2)}

/* ---------- ba bước ---------- */
.steps{list-style:none; padding:0; margin:24px 0 0; max-width:820px; counter-reset:buoc}
.steps li{
  counter-increment:buoc; position:relative;
  padding-left:52px; padding-bottom:22px; margin-bottom:0;
  border-left:1px solid var(--line-2); margin-left:15px;
}
.steps li:last-child{border-left-color:transparent; padding-bottom:0}
.steps li::before{
  content:counter(buoc,decimal-leading-zero);
  position:absolute; left:-15px; top:0;
  width:30px; height:30px; border-radius:50%;
  background:var(--accent); color:var(--accent-ink);
  font-family:"IBM Plex Mono",monospace; font-size:11.5px; font-weight:500;
  display:flex; align-items:center; justify-content:center;
}
.steps h3{margin:3px 0 6px; font-size:16.5px}
.steps p{margin:0; font-size:14.5px}

/* ---------- /noi-ai: địa chỉ MCP chép được, và dòng "đã nối thử" kèm tuổi ----------
   .o-chep: ô chỉ đọc + nút. Ô KHÔNG đặt size (size ghim ô ở ~550px và tràn ở 320 — bài học 25/09):
   flex:1 + min-width:0 để ô co theo khung, địa chỉ dài cuộn trong ô chứ không đẩy nút ra ngoài.
   Hẹp dưới 480px thì nút xuống dòng, rộng bằng ô — vẫn một hàng bấm cao 40px. */
.dia-chi-ds{display:grid; gap:14px; max-width:760px}
.dia-chi{background-color:var(--mau-o); background-image:var(--anh-o); border:1px solid var(--line); border-radius:var(--bo); padding:16px 18px}
.dia-chi h3{margin:0 0 4px; font-size:16px}
.dia-chi p{margin:0 0 10px; font-size:14.5px; color:var(--ink-2)}
.o-chep{display:flex; gap:8px; align-items:stretch}
.o-chep input{
  flex:1 1 auto; min-width:0; min-height:40px; padding:8px 12px;
  font-family:"IBM Plex Mono",monospace; font-size:14px; color:var(--ink);
  background:var(--paper); border:1px solid var(--vien-dieu-khien); border-radius:var(--bo-nho);
}
.o-chep input:focus{outline:2px solid var(--accent); outline-offset:1px; border-color:var(--accent)}
/* Ô hẹp: "…" báo chữ còn nữa. Ô ĐỊA CHỈ thì cắt ĐẦU, giữ ĐUÔI — ba địa chỉ chỉ khác nhau ở đuôi (/mcp ·
   /mcp/de-xuat · /mcp/chi-doc), và đuôi nói mức quyền. Trang ĐÃ có JS hienDuoi() cuộn ô về đuôi từ 26/09;
   luật này phủ lúc JS tắt hoặc chưa chạy (ở 390 ô 368/318), và hai thứ không đánh nhau: trong rtl,
   scrollLeft = scrollWidth bị kẹp về 0, vẫn là phía đuôi. CHỈ cho giá trị bắt đầu bằng https:// — URL toàn ký
   tự LTR nên rtl chỉ đổi phía tràn; một câu tiếng Việt kết bằng "?" thì KHÔNG được (dấu "?" là ký tự trung
   tính, rtl đẩy nó sang trái). */
.o-chep input[readonly]{text-overflow:ellipsis}
.o-chep input[readonly][value^="https://"]{direction:rtl; text-align:left}
.o-chep .btn{flex:none; min-height:40px; padding:8px 16px; font-size:14px; white-space:nowrap}
@media (max-width:479.98px){
  .o-chep{flex-wrap:wrap}
  .o-chep input{flex:1 1 100%}
  .o-chep .btn{flex:1 1 100%}
}
/* Dòng đã nối thử: tên + ngày + tuổi (JS tính). .cu = quá ngưỡng hoặc ngày hỏng — tự hạ giọng. */
.da-thu{list-style:none; padding:0; margin:0 0 6px; display:flex; flex-wrap:wrap; gap:8px 18px}
.da-thu li{font-size:15px}
.da-thu-ngay{font-family:"IBM Plex Mono",monospace; font-size:13px; color:var(--ink-3); margin-left:4px}
.da-thu-ngay.cu{color:var(--flag)}
/* Câu hỏi mẫu: cùng ô chép, nhưng là CÂU tiếng Việt — chữ thường, không mono; đọc từ ĐẦU (hienDuoi chỉ cuộn ô địa chỉ). */
.cau-hoi-ds{display:grid; gap:10px; max-width:760px}
/* Câu hỏi mẫu là CHỮ để ĐỌC, không phải ô nhập (SPEC §25f, 30/09 — cùng hình màn Kết nối của app): trong
   <input> ở 390 bốn/năm câu bị cắt 423–473/356 và "…" chỉ nói CÓ bị cắt, không nói cắt mất gì. Câu xuống dòng
   trong chính nó; nút đứng CÙNG HÀNG ở mọi khổ (không rơi thành năm nút rộng trọn màn như hàng địa chỉ). */
.cau-hoi-ds .o-chep{align-items:center; padding:8px 8px 8px 14px; background:var(--surface); border:1px solid var(--line); border-radius:var(--bo-nho)}
.cau-hoi-ds .o-chep > .cau{flex:1 1 auto; min-width:0; margin:0; font-size:15px; color:var(--ink); overflow-wrap:break-word}
@media (max-width:479.98px){
  .cau-hoi-ds .o-chep{flex-wrap:nowrap}
  .cau-hoi-ds .o-chep .btn{flex:none}
}
.buoc-ud{margin:26px 0 0; font-size:17px}
/* Khối trả lời cảnh báo "Rủi ro cao" của ChatGPT: .note có viền cảnh báo — cùng giọng với thứ khách vừa đọc. */
.note.canh-bao{border-left:4px solid var(--flag); max-width:820px}
.note.canh-bao ul{margin:10px 0 10px; padding-left:20px}
.note.canh-bao li{font-size:14.5px; margin:4px 0}

@media (prefers-reduced-motion:reduce){*{animation:none!important; transition:none!important}}

/* an nut xoa mac dinh cua input[type=search] — da co nut .clr rieng */
.seek input::-webkit-search-cancel-button,
.seek input::-webkit-search-decoration{-webkit-appearance:none; appearance:none; display:none}

/* khit lai khoang giua bang moi va ke san pham */
.hero{padding-block:58px 28px}
#ke > .wrap{padding-block:34px 56px}
.wrap > .shelf:first-child{margin-top:0}

/* =====================================================================
   KHU VUC THANH VIEN
   ===================================================================== */

.field{margin-bottom:14px}
.field label{display:block; font-size:13px; font-weight:600; color:var(--ink-2); margin-bottom:5px}
.field :is(input, select), .ns-lam select{
  width:100%; font-family:inherit; font-size:15px; color:var(--ink);
  background:var(--paper); border:1px solid var(--vien-dieu-khien);
  border-radius:var(--bo-nho); padding:11px 13px;
}
.field :is(input, select):focus, .ns-lam select:focus{outline:2px solid var(--accent); outline-offset:1px; border-color:var(--accent)}
.field .hint{font-size:12.5px; color:var(--ink-3); margin-top:5px}

.btn-wide{width:100%; text-align:center; cursor:pointer; margin-top:4px}
.btn[disabled]{opacity:.55; cursor:not-allowed}
.linkish{
  background:none; border:0; padding:0; cursor:pointer;
  font-family:inherit; font-size:13.5px; color:var(--accent); text-decoration:underline;
}

.msg{border-radius:var(--bo-nho); padding:11px 14px; font-size:14px; margin-bottom:16px; border:1px solid}
.msg.loi{background:var(--flag-soft); border-color:var(--flag); color:var(--flag)}
.msg.on{background:var(--ok-soft); border-color:var(--ok); color:var(--ok)}
.msg.luu{background:var(--warn-soft); border-color:var(--warn); color:var(--warn)}

/* san pham cua toi */
.mine{
  display:grid; gap:14px; grid-template-columns:1fr; margin-top:6px;
}
@media(min-width:760px){.mine{grid-template-columns:repeat(2,1fr)}}
/* Quầng trong ô: luật CHUNG :is(.card, .tool, .mine-card) cạnh .card. Thẻ .nghi (đã dừng) ⛔ có quầng — thứ không
   chạy thì không sáng. */
.mine-card{
  border:1px solid var(--line-2); border-left:3px solid var(--accent);
  border-radius:var(--bo); background-color:var(--mau-o); padding:20px 22px; box-shadow:var(--bong);
}
.mine-card.nghi{border-left-color:var(--ink-3); opacity:.72; background-image:none}
.mine-h{display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-bottom:6px}
.mine-h .ten{font-weight:800; font-size:17px; color:var(--hieu-dau)}
.mine-h .ten b{color:var(--hieu-chu)}
.mine-meta{font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--ink-3); margin:0 0 10px}
.mine-card p{font-size:14px; margin:0 0 14px}
.pham-vi{font-size:13.5px; color:var(--accent); background:var(--accent-soft);
  border-radius:var(--bo-nho); padding:8px 12px; margin:0 0 12px!important}
/* Huỷ đơn chờ thanh toán (/tai-khoan, 04/10). Dòng thường: số đơn + nút .mini. Bấm thì nở .xn-huy TẠI CHỖ
   (§18.7 luật 8) — viền --flag vì đây là việc không lấy lại được; hai nút CÙNG CỠ (lối lùi không nhỏ hơn nút
   xác nhận). Thẻ .nghi mờ .72 — khối quyết định không được mờ theo, nên thẻ đang hỏi thì sáng lại. */
.huy-dong{display:flex; align-items:center; flex-wrap:wrap; gap:6px; font-size:13.5px; color:var(--ink-3)}
.huy-dong code{font-family:"IBM Plex Mono",monospace; font-size:12.5px; color:var(--ink-2)}
.mine-card.nghi:has(.xn-huy){opacity:1}
/* Thẻ gói khách chọn ở bảng giá TRƯỚC khi đăng nhập (APL-194): sau khi đăng nhập ô Gói mở và thẻ ấy được đánh dấu.
   Viền --accent bọc ngoài (outline, không đổi kích thước thẻ ⇒ lưới subgrid không xê dịch). */
.the-goi.duoc-chon{outline:2px solid var(--accent); outline-offset:3px}
.xn-huy{border:1px solid var(--flag); border-radius:var(--bo-nho); padding:12px 14px; background:var(--surface)}
.xn-huy p{font-size:14px; margin:0 0 10px}
.xn-huy code{font-family:"IBM Plex Mono",monospace; font-size:13px}
.xn-huy .xn-loi{color:var(--flag)}
.xn-nut{display:flex; flex-wrap:wrap; gap:10px}
.xn-nut .btn{padding:10px 16px; font-size:14px; cursor:pointer}
/* Màn Xác nhận thanh toán: danh sách đơn đang chờ đứng TRƯỚC ô tra. Bấm "Tra đơn này" cuộn tới ô tra — chừa
   chỗ cho thanh trên dính, như section[id]. */
.cho-tieu{margin:18px 0 8px; font-size:16px}
#form-tra{scroll-margin-top:calc(var(--cao-nav) + 12px)}

/* bang quan tri */
.admin{margin-top:40px; border-top:1px solid var(--line); padding-top:30px}
.admin-form{
  display:grid; gap:12px; grid-template-columns:1fr; align-items:end;
  background-color:var(--mau-o); background-image:var(--anh-o); border:1px solid var(--line-2);
  border-radius:var(--bo); padding:20px 22px; margin-bottom:22px;
}
@media(min-width:820px){.admin-form{grid-template-columns:2fr 1fr 2fr auto}}
@media(min-width:820px){
  #form-tra{grid-template-columns:1fr auto}
  /* Ghi tiền: MỘT hàng (chủ dự án 04/10, "bóp lại ô để hiện cùng 1 dòng"). Ô Số tiền có câu gợi ý hậu quả
     (#t-con) mà hai ô kia không — với align-items:end, ô ấy cao hơn nên nhãn hai ô kia TỤT xuống đúng bằng câu
     gợi ý. Không bỏ câu gợi ý: chia ba HÀNG CHUNG bằng subgrid (nhãn · ô · gợi ý) ⇒ nhãn thẳng nhãn, ô thẳng ô
     dù gợi ý dài bao nhiêu; nút đứng ở hàng Ô. Số tiền rộng nhất (một số dài, có câu gợi ý), mã giao dịch vừa. */
  #form-tt{grid-template-columns:minmax(0,1.4fr) minmax(0,1.8fr) minmax(0,1fr) auto; grid-template-rows:auto auto auto; row-gap:5px; align-items:start}
  #form-tt > .field{display:grid; grid-row:span 3; grid-template-rows:subgrid; row-gap:5px}
  #form-tt > .field > label{margin:0; align-self:end}
  #form-tt > .field > .hint{margin:0}
  /* grid-column:4 BẮT BUỘC: mục có grid-row tường minh được xếp TRƯỚC mục tự động, nên thiếu nó thì nút chiếm
     cột 1 và đẩy cả ba ô sang phải một cột (đo 04/10: «Mã giao dịch» 334px, «Số tiền» 186px — ngược ý). */
  #form-tt > button{grid-row:2; grid-column:4; align-self:center}
}
#hd-xem:not(:empty){margin:-4px 0 22px}
.btn[disabled]{opacity:.5; cursor:not-allowed; pointer-events:none}
.o-chon{display:flex; align-items:center; gap:10px; cursor:pointer; font-size:15px; margin-bottom:4px}
.o-chon input{width:18px; height:18px; accent-color:var(--accent); cursor:pointer; flex:none}
#form-xhd .field{margin-bottom:14px}
#form-xhd #x-o{margin-top:8px}
.note code{
  font-family:"IBM Plex Mono",monospace; font-size:13.5px;
  background:var(--alt); border:1px solid var(--line-2);
  padding:2px 7px; border-radius:var(--bo-nho); user-select:all;
}
.admin-form .field{margin:0}
.admin-form select{
  width:100%; font-family:inherit; font-size:15px; color:var(--ink);
  background:var(--paper); border:1px solid var(--vien-dieu-khien);
  border-radius:var(--bo-nho); padding:11px 13px;
}
.admin-form .btn{padding:11px 20px; white-space:nowrap}
.tt{font-family:"IBM Plex Mono",monospace; font-size:13px; padding:2px 8px; border-radius:var(--bo-tron); white-space:nowrap}
.tt.on{background:var(--ok-soft); color:var(--ok)}
.tt.nghi{background:var(--warn-soft); color:var(--warn)}
.tt.het{background:var(--flag-soft); color:var(--flag)}
.tt.trong{background:var(--alt); color:var(--ink-3)}
/* Trong bảng .tw thì .tt ĐƯỢC xuống dòng. Đo 25/09 ở 390px, bảng giá: .tt 13px mà nowrap làm cột
   hai đòi chỗ, cột đầu bị ép 132 → 81px và bảng cao 1084 → 1969px; cho xuống dòng thì cột đầu
   202px, bảng 1036px. Ngoài bảng (thanh bên khu thành viên) vẫn một dòng như cũ. */
.tw .tt{white-space:normal}
.mini{
  font-family:inherit; font-size:12px; font-weight:600; cursor:pointer;
  border:1px solid var(--vien-dieu-khien); background:var(--surface); color:var(--ink-2);
  border-radius:var(--bo-nho); padding:3px 11px; margin-left:5px;
  white-space:nowrap;   /* nhãn ngắn ("tạm dừng", "mở lại") không bẻ giữa hai dòng khi cột hẹp (đo 26/09) */
}
.mini:hover{border-color:var(--accent); color:var(--accent)}
/* Nút nhỏ cao 23px (đo 26/09: "Tải lại", "Đăng xuất máy khác", "tạm dừng" trong bảng). Giữ hình gọn
   nhưng nới VÙNG BẤM lên 40×40 bằng ::after trong suốt, không đổi bố cục — cùng cách td a. */
.mini{position:relative}
.mini::after{
  content:""; position:absolute; left:50%; top:50%;
  width:max(100%, 40px); height:max(100%, 40px); transform:translate(-50%, -50%);
}

/* ---------- thanh nav dinh: dat lai diem neo ---------- */
html{scroll-behavior:smooth}
section[id], div[id^="v-"], h2[id], h2 > span[id]{scroll-margin-top:calc(var(--cao-nav) + 1px)}   /* h2[id]: neo mục 6 /terms#hoan-tien · /en/terms#refund (APL-278) — ⛔ thì tiêu đề nằm DƯỚI thanh nav dính 69px. h2 > span[id]: neo PHỤ mang tên của bản kia (#refund trên /terms, #hoan-tien trên /en/terms) — middleware đẩy khách VN từ /en/terms về /terms mà trình duyệt GIỮ #refund */
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

/* ---------- bo qua toi noi dung, cho nguoi dung ban phim ---------- */
.bqua{
  position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--accent); color:var(--accent-ink);
  padding:11px 20px; border-radius:0 0 var(--bo) 0;
  font-weight:600; font-size:15px; text-decoration:none;
}
.bqua:focus{left:0}
/* Đích của .bqua (tabindex=-1) nhận tiêu điểm chỉ để Tab kế tiếp đi từ đó, không phải điều khiển — không vẽ viền.
   Cùng luật với ung-dung.css (đo 27/09: viền auto quanh cả khối main sau khi Enter trên .bqua). */
main[tabindex="-1"]:focus{outline:none}

/* ---------- vung bam du lon tren dien thoai ---------- */
.nav-links a{padding-block:8px}            /* 24px chu -> 40px vung bam */
.nav-links a.cta{padding-block:7px}
.linkish{padding:8px 4px; min-height:40px}
/* Liên kết ĐỨNG RIÊNG (không nằm giữa câu) cũng cần sàn 40px: đo 27/09 bằng Tab thật ở 390, B7d mới phủ
   đầu trang — còn 4 chỗ 17–20px (danh sách lối đi tiếp ở /404, "Đọc cổng duyệt…" ở /noi-ai). Liên kết
   giữa câu văn thì KHÔNG áp: WCAG 2.5.8 miễn cho nó, và nâng nó lên 40px làm giãn dòng chữ. */
.di-tiep a, a.lk-rieng{display:inline-flex; align-items:center; min-height:40px}
.foot-links a{display:inline-flex; align-items:center; min-height:40px}   /* đo 25/09: 35px ở cả 8 trang */
.logo{padding-block:6px}
/* Đệm cộng tay KHÔNG ra 40: đo 27/09 (§21.6 B7d) logo 38px ở 390, nút Đăng nhập/Đăng ký 39px và liên
   kết nav 39,x px ở 1440 — chữ ×line-height + đệm hụt vài phần px. Sàn min-height mới là thứ giữ số 40.
   Liên kết nav là mục flex (cha là flex), nên align-items:center của chính nó giữ chữ ở giữa sàn.
   Logo KHÔNG đổi align-items: nó căn baseline có chủ đích (dấu hiệu đứng trên đường chân chữ, xem
   .logo > img ở trên) — sàn chỉ thêm khoảng dưới, không dời dấu hiệu khỏi chữ. */
.nav-links a{min-height:40px; display:inline-flex; align-items:center}
.logo{min-height:40px}

/* =====================================================================
   TRANG DANG NHAP — hai nua: khung nhap trai, khung gioi thieu phai
   ===================================================================== */

.split{
  display:grid; grid-template-columns:1fr; gap:0;
  border:1px solid var(--line-2); border-radius:var(--bo);
  overflow:hidden; box-shadow:var(--bong); background-color:var(--mau-o); background-image:var(--anh-o);
  max-width:1000px; margin:0 auto;
}
@media(min-width:900px){ .split{grid-template-columns:1fr 1fr} }

/* --- nua trai --- */
.sp-form{padding:40px 38px}
@media(max-width:520px){ .sp-form{padding:28px 20px} }
.sp-form h1{font-size:clamp(22px,3.4vw,28px); line-height:1.22; margin:0 0 6px; max-width:none}
.sp-form .sub{color:var(--ink-2); font-size:14.5px; margin:0 0 24px}

.gbtn{
  width:100%; display:flex; align-items:center; justify-content:center; gap:11px;
  font-family:inherit; font-size:15px; font-weight:600; color:var(--ink);
  background:var(--surface); border:1px solid var(--vien-dieu-khien);
  border-radius:var(--bo-nho); padding:12px 16px; cursor:pointer;
}
.gbtn:hover{border-color:var(--ink-3); background:var(--paper)}
.gbtn[disabled]{opacity:.55; cursor:not-allowed}
.gbtn svg{flex:none}

.hoac{
  display:flex; align-items:center; gap:12px; margin:22px 0;
  font-family:"IBM Plex Mono",monospace; font-size:10.5px; letter-spacing:.12em;
  text-transform:uppercase; color:var(--ink-3);
}
.hoac::before,.hoac::after{content:""; flex:1; height:1px; background:var(--line)}

.hang{display:flex; justify-content:flex-end; align-items:center; margin:-4px 0 18px}
.doi-che-do{
  text-align:center; font-size:14px; color:var(--ink-2);
  margin:18px 0 0; padding-top:18px; border-top:1px solid var(--line);
}
.doi-che-do button{font-size:14px; font-weight:600}

/* --- nua phai --- */
.sp-ban{
  background:var(--nen-dam);
  color:var(--tren-toi); padding:40px 38px; display:flex; flex-direction:column; gap:22px;
}
@media(max-width:520px){ .sp-ban{padding:30px 20px} }
.sp-ban h2{color:var(--tren-toi); font-size:clamp(20px,3vw,25px); line-height:1.24; margin:0; max-width:18ch}
.sp-ban .loi{color:var(--tren-toi-2); font-size:15px; margin:0; max-width:34ch}

.duoc{background:rgba(0,0,0,.12); border-radius:var(--bo); padding:20px 22px}
.duoc-k{font-family:"IBM Plex Mono",monospace; font-size:11px; letter-spacing:.11em; text-transform:uppercase; color:var(--tren-toi-2); margin:0 0 12px}
.duoc ul{list-style:none; padding:0; margin:0; display:flex; flex-direction:column; gap:10px; max-width:none}
.duoc li{position:relative; padding-left:28px; color:var(--tren-toi-2); font-size:14.5px; margin:0}
.duoc li::before{
  content:"✓"; position:absolute; left:0; top:1px;
  width:18px; height:18px; border-radius:50%; background:var(--hieu);
  color:var(--hieu-dau); font-size:11px; font-weight:700; display:flex; align-items:center; justify-content:center;
}
.duoc li b{color:var(--tren-toi)}

.so{display:grid; grid-template-columns:repeat(2,1fr); gap:12px}
.so > div{background:rgba(0,0,0,.12); border-radius:var(--bo); padding:16px 18px}
.so .v{font-family:"IBM Plex Mono",monospace; font-size:26px; font-weight:500; color:var(--tren-toi); line-height:1.1}
.so .k{font-family:"IBM Plex Mono",monospace; font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--tren-toi-2); margin-top:6px}

/* .stat-grid — 2 đến 4 con số cùng cấp trên NỀN SÁNG (khu thành viên: tài nguyên, mức sử dụng).
   Mượn tên bộ gốc (.stat-grid .stat .stat-label .stat-value .stat-delta). .so ở trên là cho nền tối.
     <div class="stat-grid">
       <div class="stat">
         <div class="stat-label">Lượt hôm nay</div>
         <div class="stat-value">18<small>/50</small></div>
         <p class="stat-note">Lượt lỗi và lượt bị trần chặn không tính.</p>
       </div>…
   · Mức dùng là PHÂN SỐ CÓ MẪU SỐ, không phần trăm (SPEC §18.4): mẫu số trong <small>.
   · Luật đếm viết NGAY CẠNH con số (§18.4): .stat-note, lớp thêm so với bộ gốc.
   · Đọc không được thì KHÔNG hiện 0 (§17.1 luật 1): .stat-value.khong-biet với chữ
     "Không đọc được", nhỏ và nhạt hơn con số thật để không bị đọc nhầm thành một con số.
   · .stat-delta (.down khi giảm): thay đổi so với kỳ trước.
   Đường chia là gap 1px trên nền --line; số cột lấy theo SỐ Ô (2, 3 hay 4) nên không bao giờ
   thừa một ô trống màu đường kẻ. */
.stat-grid{
  display:grid; grid-auto-flow:column; grid-auto-columns:minmax(0,1fr); gap:1px;
  margin:14px 0; background:var(--line); border:1px solid var(--line); border-radius:var(--bo-nho); overflow:hidden;
}
.stat{min-width:0; padding:16px 18px; background:var(--surface)}
.stat-label{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  font-family:"IBM Plex Mono",monospace; font-size:11.5px; letter-spacing:.06em;
  text-transform:uppercase; color:var(--ink-3); font-weight:500;
}
.stat-value{
  margin-top:8px; font-size:26px; font-weight:700; letter-spacing:-.02em; line-height:1.15;
  color:var(--ink); font-variant-numeric:tabular-nums; overflow-wrap:anywhere;
}
.stat-value small{font-size:16px; font-weight:600; color:var(--ink-3); letter-spacing:0}
.stat-value.khong-biet{font-size:16px; font-weight:600; color:var(--ink-3); letter-spacing:0}
.stat-note{margin:6px 0 0; font-size:13px; color:var(--ink-3); line-height:1.45}
.stat-delta{font-family:inherit; font-size:13px; font-weight:600; letter-spacing:0; text-transform:none; color:var(--ok)}
.stat-delta.down{color:var(--flag)}
@media (max-width:640px){
  /* 2 hay 4 ô: hai cột; 3 ô: một cột (hai cột thì ô thứ ba đứng lẻ cạnh một ô trống) */
  .stat-grid{grid-auto-flow:row; grid-template-columns:repeat(2,minmax(0,1fr))}
  .stat-grid:has(> .stat:nth-child(3):last-child){grid-template-columns:minmax(0,1fr)}
  .stat{padding:14px 14px}
  .stat-value{font-size:22px}
}

/* .that DÀNH CHO NỀN TỐI — chữ nó là --tren-toi-2 (trắng mờ), đặt lên nền sáng thì gần
   như tàng hình. Đã dính lỗi ấy ở /bang-gia và /tai-lieu ngày 21/09.
   Nền sáng thì dùng .luuy ở ngay dưới. */
.that{border-left:3px solid rgba(255,255,255,.35); padding:2px 0 2px 16px; margin-top:auto}
.that p{color:var(--tren-toi-2); font-size:14px; margin:0; max-width:36ch}
.that .ai{font-size:12.5px; color:var(--tren-toi-2); margin-top:8px}

/* ==================================================================
   KHU VỰC THÀNH VIÊN — thanh bên cố định, khung chạy hết màn hình

   Số đo lấy thẳng từ ALFA Report (/d/alfa-report, globals.css), vì bên ấy
   đã đo trên bản chạy thật của GemLogin và GPM rồi:
     thanh bên 260px · mục menu cao 46px bo tròn hẳn · dải logo cao 61px
   Và một quyết định quan trọng của bên ấy, giữ nguyên ở đây:
     NỀN THANH BÊN LÀ NỀN TRANG, KHÔNG PHẢI TRẮNG.
   Khối trắng đặt trên nền trắng thì chỉ còn cái viền 1px phân biệt — đúng
   lỗi "hộp trong hộp". Nền xám thì mỗi khối nổi lên thành một thẻ thật.
   ================================================================== */

:root{ --ben:260px; --le:clamp(1rem,4vw,2rem); --dau-cao:61px }

/* THU GỌN CHỈ ĐỔI MỘT BIẾN. Thanh bên rộng theo --ben và thân trang chừa
   chỗ cũng theo --ben, nên khai lại đúng một dòng là cả hai đi theo. Không
   có chỗ nào cho hai con số lệch nhau. */
:root[data-ben="gap"]{ --ben:72px }

/* Khung chạy hết màn hình khi đã đăng nhập. Bật bằng class trên body chứ
   không dùng :has() — một class do JS đặt thì chắc chắn chạy ở mọi trình
   duyệt, còn :has() thì không. */
body.la-app .wrap{max-width:none; padding-inline:var(--le)}
body.la-app .nav-in{max-width:none; padding-inline:var(--le)}

/* Hai lớp bật tắt theo trạng thái đăng nhập. Không dùng thuộc tính hidden
   vì [hidden]{display:none!important} sẽ đè luôn lúc cần hiện. */
/* body:not(.la-app), không phải .chi-app trần: .kv-nut{display:inline-flex} đứng SAU dòng này với cùng
   độ ưu tiên và đã thắng — hai nút ≡ và thu gọn hiện với KHÁCH chưa đăng nhập, đè lên logo (đo 30/09,
   ảnh điện thoại thật của chủ dự án). Luật ẩn phải mạnh hơn mọi luật hiện của chính phần tử ấy. */
body:not(.la-app) .chi-app{display:none}
body.la-app .chi-app{display:inline-flex}
body.la-app .an-app{display:none}
/* Dưới 66rem dải logo bên trái ẩn, nên thanh trên phải giơ logo ra lại —
   không thì trang KHÔNG CÓ LOGO Ở ĐÂU CẢ trên điện thoại. */
@media (max-width:66rem){ body.la-app .logo{display:inline-flex} }
/* Ở 414px hàng trên thừa ĐÚNG 15px: logo 24px chiếm 217px, cộng nút ba
   gạch 38 và cụm bên phải 143 là vượt. Thu logo xuống 18px lấy lại ~54px.
   Đo trong khung 414px, không phải đoán. */
@media (max-width:560px){ body.la-app .logo{font-size:18px; gap:5px} }
/* Nút thu gọn chỉ có việc khi thanh bên cố định; nút menu thì ngược lại. */
@media (min-width:66rem){ body.la-app #nut-menu{display:none} }

.kv{display:block}

/* ---------- thanh bên ----------
   Bám cố định từ MÉP TRÊN màn hình, không phải từ dưới thanh trên: dải
   logo phải nằm đúng hàng với thanh trên thì hai đường viền dưới mới nối
   nhau thành một đường chạy ngang. Thân trang chừa chỗ bằng padding-left,
   nhờ thế mọi khối bên trong giữ nguyên cấu trúc cũ. */
.kv-ben{
  display:flex; flex-direction:column; gap:8px;
  background:transparent; border:0; padding:0; box-shadow:none;
}
@media (min-width:66rem){
  /* Nội dung ngắn thì chân trang treo LỬNG LƠ GIỮA MÀN HÌNH trong khi
     thanh bên chạy suốt xuống đáy — đo được: màn hình 911px, body chỉ
     480px. Trông như trang dựng dở.

     Ép body cao tối thiểu bằng màn hình rồi cho phần nội dung nở ra, nên
     chân trang luôn nằm ở đáy. Chỉ bật trong @media này: dưới 66rem
     không có thanh bên cố định nên không có cái lệch ấy.

     .bqua là position:absolute nên không thành mục flex — kiểm rồi. */
  body.la-app{
    padding-left:var(--ben);
    min-height:100vh; display:flex; flex-direction:column;
  }
  body.la-app > main{flex:1 0 auto}
  body.la-app > footer{flex:none}
  .kv-ben{
    position:fixed; inset:0 auto 0 0; z-index:40; width:var(--ben);
    padding:0 10px 14px; overflow-y:auto;
    background:var(--paper); border-right:1px solid var(--line);
  }
}

/* DẢI LOGO — cao đúng bằng thanh trên.
   61px = 44px hàng trong + 8px đệm trên + 8px đệm dưới + 1px viền. Cả trang
   khai box-sizing:border-box nên viền ăn VÀO TRONG chiều cao; khai 60 thì
   mép dưới dải dừng ở 60 trong khi thanh trên dừng ở 61, và một đường kẻ
   lệch một pixel chạy dọc suốt đỉnh màn hình.

   Lề ngang ÂM để huỷ đệm của .kv-ben: dải phải chạm hai mép thanh bên, còn
   mấy thẻ bên dưới thì vẫn thụt vào. Đổi đệm của .kv-ben thì đổi luôn số này. */
.kv-ten{
  display:none; align-items:center; flex:none;
  height:var(--dau-cao); margin-inline:-10px; padding:0 14px;
  border-bottom:1px solid var(--line);
  font-family:"Orbitron","Inter",sans-serif; font-weight:800;
  font-size:19px; letter-spacing:.01em; white-space:nowrap;
  color:var(--hieu-dau); text-decoration:none;
}
.kv-ten span span{color:var(--hieu-cuoi)}
.kv-ten{gap:10px}
.kv-ten > img{flex:none; width:26px; height:26px}   /* thu gọn: chữ ẩn, dấu hiệu còn, thay chữ "A" cũ */
@media (min-width:66rem){ .kv-ten{display:flex} }

/* KHÔNG khung (chủ dự án 03/10: "bỏ khung viền trong ngoài cho các menu"): nhóm mục nằm thẳng trên nền thanh bên,
   Cùng lượt với app (ung-dung.css .kv-ben > nav) — hai vỏ phải giống nhau. ⚠ border-right của .kv-ben thì GIỮ (đường chia
   HAI VÙNG, không phải khung một mục — chủ dự án 03/10; 4f7d2eb gỡ nhầm, trả lại cùng ngày). Nhóm phân
   cách bằng khoảng cách (#kv-menu gap) và nhãn nhóm, không bằng thẻ. */
.kv-toi, .kv-khoi{border-radius:var(--bo)}
.kv-khoi{padding:4px 4px}
#kv-menu{display:flex; flex-direction:column; gap:8px}

/* Chân thanh bên đẩy xuống đáy. */
.kv-toi{margin-top:auto}
.kv-toi-chu{min-width:0; flex:1 1 110px}

/* Icon ăn màu của mục qua currentColor: tự xám khi mục đứng yên, tự xanh
   khi mục đang mở. flex:none để hình không bị bóp khi nhãn dài. */
.kv-icon{flex:none; display:block}
.kv-nhan{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}

/* ---------- thu gọn còn một dải icon ----------
   Thu LẠI chứ không giấu hẳn: giấu hẳn thì nút ấy đổi 260px lấy việc cắt
   đứt điều hướng — bung lại ra mới đi đâu được. */
/* CHỈ từ 66rem — thu gọn là trạng thái của thanh bên CỐ ĐỊNH. Dưới 66rem menu là ngăn kéo che màn
   (APL-234); để các luật này rò xuống thì người đã thu gọn ở máy tính, thu cửa sổ hẹp lại, mở menu
   ra một ngăn 320px chỉ toàn icon không nhãn. */
@media (min-width:66rem){
:root[data-ben="gap"] .kv-nhan,
:root[data-ben="gap"] .kv-toi-chu,
:root[data-ben="gap"] .nhan-moi{
  position:absolute; width:1px; height:1px; margin:-1px;
  padding:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap;
}
:root[data-ben="gap"] .kv-nhom,
:root[data-ben="gap"] .kv-trong,
:root[data-ben="gap"] .kv-toi .tt{display:none}
:root[data-ben="gap"] .kv-m{justify-content:center; padding:0; gap:0}
:root[data-ben="gap"] .kv-khoi{padding:5px 4px}
:root[data-ben="gap"] .kv-toi{justify-content:center; padding:10px 6px}
:root[data-ben="gap"] .kv-ben{padding-inline:8px}
:root[data-ben="gap"] .kv-ten{margin-inline:-8px; padding:0; justify-content:center}
:root[data-ben="gap"] .kv-ten-chu{display:none}
/* Nhóm Sản phẩm RỖNG khi thu gọn: .kv-nhom và .kv-trong đều ẩn nên còn lại một thẻ trắng trống —
   không phân biệt được "nhóm rỗng" với "tải hỏng". Không có mục nào để đi tới thì không hiện thẻ. */
:root[data-ben="gap"] .kv-khoi:has(> #kv-sanpham > .kv-trong){display:none}
}

/* ---------- nút biểu tượng và menu người dùng trên thanh trên ---------- */
/* display VA list-style phai khai o day, khong phai chi o .kv-nut-ten.
   .kv-nut nay dung cho CA <button> lan <summary>, ma <summary> mac dinh
   la display:list-item — thieu hai dong nay thi tam giac cua details loi
   ra va bi day len tren, day icon xuong duoi. Thay ngay tren anh chup. */
.kv-nut{
  display:inline-flex; list-style:none;
  align-items:center; justify-content:center; flex:none;
  width:40px; height:40px; padding:0; margin-right:2px;   /* 40 như mọi thứ bấm được (26/09: trước là 38) */
  background:none; border:1px solid transparent; border-radius:var(--bo-nho);
  color:var(--ink-2); cursor:pointer; font:inherit;
}
.kv-nut:hover{background:var(--alt); color:var(--hieu-dau)}
.kv-nut:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
.kv-nut::-webkit-details-marker{display:none}
.kv-nut svg{display:block}
@media (pointer:coarse){ .kv-nut{width:44px; height:44px} }
/* Nút sáng/tối của khu thành viên (SPEC 18.1 mục 4d-i) — CÙNG luật với app (ung-dung.css), vì /tai-khoan nạp
   style.css chứ không nạp ung-dung.css nên luật bên ấy không tới đây. Ẩn bằng VISIBILITY tới khi script đặt
   co-giao-dien: không tiêu điểm, không bấm được, nhưng GIỮ CHỖ ⇒ nút hiện tại chỗ, không đẩy menu người dùng
   (đo 01/10 ở app: display:none làm menu co 144→41px ở 320). Hai hình nằm sẵn, CSS chọn theo data-giao-dien. */
#nut-giao-dien{visibility:hidden}
html.co-giao-dien #nut-giao-dien{visibility:visible}
#nut-giao-dien > svg[data-khi="dang-toi"]{display:none}
:root[data-giao-dien="toi"] #nut-giao-dien > svg[data-khi="dang-sang"]{display:none}
:root[data-giao-dien="toi"] #nut-giao-dien > svg[data-khi="dang-toi"]{display:block}
/* Nút thu gọn chỉ có việc khi thanh bên có thật. */
@media (max-width:66rem){ body.la-app #nut-gap{display:none} }

/* Ảnh đại diện là CHỮ CÁI ĐẦU, không phải ảnh thật: chưa có chỗ nào cho
   người dùng tải ảnh lên, mà mượn ảnh Google thì lộ dữ liệu sang bên thứ
   ba trên mọi lần mở trang. */
.kv-anh{
  flex:none; display:inline-flex; align-items:center; justify-content:center;
  width:28px; height:28px; border-radius:50%;
  background:var(--accent-soft); color:var(--accent);
  font-weight:700; font-size:13px; text-transform:uppercase;
}

/* Cụm bên phải đẩy sang phải MỘT LẦN, không phải từng nút. */
.kv-phai{align-items:center; gap:2px; margin-left:auto}
body.la-app .kv-phai{display:inline-flex}
.kv-hop{position:relative; flex:none}
.kv-nut-ten{
  display:inline-flex; align-items:center; gap:8px;
  min-height:40px; padding:0 10px 0 5px; border-radius:var(--bo-nho);
  cursor:pointer; list-style:none; color:var(--ink-2); font-size:14px;
}
.kv-nut-ten::-webkit-details-marker{display:none}
.kv-nut-ten:hover{background:var(--alt); color:var(--hieu-dau)}
.kv-hop[open] > .kv-nut-ten{background:var(--accent-soft); color:var(--accent)}
.kv-nut-chu{max-width:14ch; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.kv-nut-ten .mui{font-size:10px; color:var(--ink-3)}
@media (max-width:560px){ .kv-nut-chu{display:none} }

/* Neo vào mép PHẢI: nút này sát mép phải màn hình, neo trái thì hộp mọc ra
   ngoài khung. */
.kv-hop-noi{
  position:absolute; z-index:50; top:calc(100% + 6px); right:0;
  width:min(17rem, calc(100vw - 3rem));
  background:var(--noi); border:1px solid var(--line);
  border-radius:var(--bo); box-shadow:var(--bong-cao);
  padding:6px; display:flex; flex-direction:column;
}
/* ...nhưng CHỈ nút người dùng sát mép phải. Nút ngôn ngữ và chuông đứng lùi vào, nên hộp neo mép
   phải CỦA CHÚNG lấn ra ngoài mép trái ở khổ hẹp — đo 26/09 ở 320: ngôn ngữ -71px, chuông -29px (390:
   -33px). Khổ hẹp thì neo mọi hộp vào mép phải của THANH TRÊN (nav.nav là sticky nên là khối định vị). */
@media (max-width:560px){
  .kv-hop{position:static}
  .kv-hop-noi{right:12px}
}
.kv-hop-dau{padding:8px 10px 10px; border-bottom:1px solid var(--line); margin-bottom:5px}
.kv-hop-dau strong{display:block; color:var(--hieu-dau); font-size:14.5px}
.kv-hop-dau span{
  display:block; font-family:"IBM Plex Mono",monospace; font-size:11.5px;
  color:var(--ink-3); word-break:break-all; margin-top:2px;
}

/* Chế độ tối (§18.1 4d-i — khu thành viên đi theo cookie alfa_giao_dien của app): dấu hiệu bản NỀN TỐI. Bản sáng
   có ô vuông navy, trên nền tối nó chìm. Đổi bằng content vì <img> nằm sẵn trong markup; trình duyệt không nhận
   content trên <img> thì vẫn hiện bản sáng — đọc được, không hỏng. Không có data-giao-dien thì luật không ăn. */
:root[data-giao-dien="toi"] img[src*="/alfa-mark"]{content:url("/alfa-mark-tren-toi.svg")}
:root[data-giao-dien="toi"] img[src*="/adpilot-mark"]{content:url("/adpilot-mark-tren-toi.svg")}

/* Chấm đếm trên chuông. Neo vào góc trên phải của nút, viền cùng màu nền
   thanh trên để nó tách khỏi hình cái chuông. */
.kv-cham{
  position:absolute; top:2px; right:2px; min-width:17px; height:17px;
  display:inline-flex; align-items:center; justify-content:center;
  padding:0 4px; border-radius:var(--bo-tron); border:2px solid var(--surface);
  background:var(--flag); color:var(--flag-ink);
  font-family:"IBM Plex Mono",monospace; font-size:10px; font-weight:700; line-height:1;
}
/* word-break:break-all o .kv-hop-dau span la de cho EMAIL dai. Dong phu
   cua chuong la cau van, ngat giua chu doc thanh hai manh vo nghia. */
#kv-chuong-phu{
  font-family:inherit; word-break:normal; overflow-wrap:break-word;
  font-size:12px; line-height:1.45;
}
.kv-hop-hep{width:min(19rem, calc(100vw - 3rem))}
.kv-hop-trong{margin:0; padding:10px 12px 12px; font-size:13.5px; color:var(--ink-2)}
/* Bộ chọn ngôn ngữ trong hộp quả địa cầu (/tai-khoan): mặc áo dòng menu (.kv-hop-noi a) — .chon-ngon-ngu > a ở dưới
   đè min-width/căn giữa/chữ nhỏ ⇒ đè lại bằng #id. */
#kv-tieng .chon-ngon-ngu{width:100%; flex-direction:column; align-items:stretch; gap:0}
#kv-tieng .chon-ngon-ngu > a{
  justify-content:space-between; gap:10px; min-height:40px; padding:0 10px;
  font-size:14.5px; font-weight:400; letter-spacing:0; color:var(--ink-2);
}
#kv-tieng .chon-ngon-ngu > a[aria-current]{font-weight:600; color:var(--ink); text-decoration:none}
#kv-tieng .chon-ngon-ngu > a[aria-current]::after{content:"✓" / ""; color:var(--accent); font-weight:700}
@media (pointer:coarse){ #kv-tieng .chon-ngon-ngu > a{min-height:44px} }

/* Một mục việc trong chuông. Cùng hình dáng với mục trong menu tài khoản
   để hai hộp cạnh nhau không đọc thành hai thứ khác nhau. */
.kv-hop-ds{display:flex; flex-direction:column}
.kv-hop-ds button{
  display:flex; align-items:center; gap:10px; width:100%; text-align:left;
  min-height:44px; padding:0 12px; border:0; border-radius:var(--bo-nho);
  background:none; cursor:pointer; font:inherit; font-size:14px; color:var(--ink-2);
}
.kv-hop-ds button:hover{background:var(--alt); color:var(--hieu-dau)}
.kv-hop-nhan{flex:1 1 auto; min-width:0}
.kv-hop-nhan em{font-style:normal; color:var(--ink-3); font-size:12px}
.kv-hop-so{
  flex:none; font-family:"IBM Plex Mono",monospace; font-size:12px;
  background:var(--alt); color:var(--ink-2); padding:2px 8px; border-radius:var(--bo-tron);
}
.kv-hop-noi a, .kv-hop-ra{
  display:flex; align-items:center; min-height:40px; padding:0 10px;
  border-radius:var(--bo-nho); text-decoration:none;
  color:var(--ink-2); font-size:14.5px; font:inherit; font-size:14.5px;
  background:none; border:0; cursor:pointer; text-align:left; width:100%;
}
.kv-hop-noi a:hover, .kv-hop-ra:hover{background:var(--noi-hover); color:var(--hieu-dau)}
.kv-hop-ra{margin-top:5px; border-top:1px solid var(--line); border-radius:0 0 var(--bo-nho) var(--bo-nho)}
/* margin:auto 0 0 chứ KHÔNG phải margin:0 — luật này đứng SAU luật
   .kv-toi{margin-top:auto} trong file, nên margin:0 của nó ghi đè lên và
   khối người dùng đứng lửng lơ giữa thanh bên thay vì tụt xuống đáy.
   Đo bằng getComputedStyle mới thấy: marginTop trả về 0px. */
.kv-toi{padding:7px 8px; margin:auto 0 0; display:flex; align-items:center; gap:9px}
.kv-toi .ai{font-weight:600; color:var(--ink); line-height:1.3; font-size:14px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.kv-toi .em{display:none}
.kv-toi .tt{flex:none}

.kv-nhom{
  font-size:10.5px; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; color:var(--ink-3);
  margin:6px 9px 3px;
}
.kv-m{
  display:flex; align-items:center; gap:11px; width:100%; text-align:left;
  background:none; border:0; cursor:pointer; font:inherit;
  color:var(--ink-2); font-size:14.5px; font-weight:500;
  min-height:40px; padding:0 13px; border-radius:var(--bo-nho);
  text-decoration:none; margin-bottom:1px;
}
.kv-m:hover{background:var(--alt); color:var(--hieu-dau)}
/* Vạch 3px mép trái: bắt buộc từ khi bỏ khung — nền --accent-soft so với nền trang chỉ 1,02:1 (xem ung-dung.css). */
.kv-m.dang{background:var(--accent-soft); color:var(--accent); font-weight:700; box-shadow:inset 3px 0 0 var(--accent)}
.kv-m:focus-visible{outline:2px solid var(--accent); outline-offset:-2px}
.kv-trong{font-size:13px; color:var(--ink-3); padding:6px 14px; margin:0; font-style:italic}

/* Nhãn "mới" cạnh mục tiếp thị — cả hai sản phẩm tham khảo đều gắn nhãn
   để kéo mắt về đúng mục họ muốn người dùng bấm. */
.nhan-moi{
  margin-left:auto; font-size:10px; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; color:var(--accent-ink); background:var(--accent);
  padding:2px 7px; border-radius:var(--bo-tron);
}
.kv-m.dang .nhan-moi{background:var(--hieu-dau)}

/* Đường vào app mở TAB MỚI — dấu ↗ (.tab-moi) cho mắt, .chi-doc cho trình đọc màn hình (chỉ ẩn khỏi mắt).
   Trong mục thanh bên: dấu đứng cuối dòng, mờ hơn chữ; thu gọn còn dải icon thì ẩn dấu, lời báo nằm ở title. */
.chi-doc{position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip-path:inset(50%); white-space:nowrap}
/* .khong-ngat — CÙNG TÊN, CÙNG GIÁ TRỊ với ung-dung.css (hợp đồng §18.1 mục 6). /tai-khoan chỉ nạp style.css, nên trước 09/10
   mọi .khong-ngat ở đó là KHÔNG CÓ TÁC DỤNG (đo: getComputedStyle → white-space:normal): số tiền trong câu báo đặt gói gãy
   «490.000 ⏎ ₫» ở 390, mã tổ chức trong saTen() (Super admin, §18.7 luật 9) gãy được. Đổi giá trị thì đổi CẢ HAI tệp. */
.khong-ngat{white-space:nowrap}
.tab-moi{display:inline-block; flex:none; width:.8em; height:.8em; margin-left:.3em; vertical-align:-.02em}
.kv-m .tab-moi{margin-left:auto; width:14px; height:14px; color:var(--ink-3)}
@media (min-width:66rem){ :root[data-ben="gap"] .kv-m .tab-moi{display:none} }

/* Dải mời tham gia */
.bang-moi{
  display:flex; align-items:center; gap:20px; flex-wrap:wrap;
  background:var(--accent-soft); border:1px solid var(--line);
  border-radius:var(--bo); padding:20px 24px;
}
.bang-moi > div{flex:1 1 320px; min-width:0}
.bm-ten{margin:0 0 6px; font-size:18px; font-weight:700; color:var(--hieu-dau)}
.bm-phu{margin:0; font-size:14.5px; color:var(--ink-2); max-width:66ch}
.tt-link{margin:0 0 8px}
.tt-link code{
  font-size:14.5px; background:var(--surface); border:1px solid var(--line-2);
  padding:7px 12px; border-radius:var(--bo-nho); display:inline-block;
  word-break:break-all; user-select:all;
}

/* ---------- khung chính ---------- */
.kv-chinh{min-width:0}
.o-dau{display:flex; align-items:flex-start; gap:16px; flex-wrap:wrap; margin-bottom:18px}
.o-dau h2{margin:0; font-size:27px; letter-spacing:-.01em}
.o-dau h3{margin:0; font-size:18px; font-weight:600}
.o-dau .o-phu{margin:5px 0 0; font-size:14.5px; color:var(--ink-2); max-width:70ch}
.o-dau > :last-child:not(:first-child){margin-left:auto; flex-shrink:0}

/* ---------- bốn thẻ số ---------- */
.the4{display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:16px}
/* Tiếp thị liên kết: dải đường dẫn (.bang-moi, không lề dưới) rồi tới hàng thẻ (không lề trên) ⇒ đo 06/10
   teal.bottom 371 = the.top 371, HỞ 0px — chủ dự án khoanh đỏ, đọc như thẻ đè lên dải (APL-235 ①).
   Khoảng bằng gap của chính hàng thẻ, để dải và thẻ cách nhau như thẻ cách thẻ. */
#tt-wrap + .the4{margin-top:16px}
/* Thẻ số theo đúng phong cách ALFA Report: NỀN TRẮNG, viền trái có màu,
   nhãn ăn màu viền. Không tô kín như GPM — tô kín bốn thẻ cạnh nhau thì
   màu át số, mà số mới là thứ người ta vào đây để đọc. */
.the{
  border:1px solid var(--line); border-left:4px solid var(--line-2);
  border-radius:var(--bo); padding:16px 20px; background-color:var(--mau-o); background-image:var(--anh-o);
}
.the .nhan{font-size:11px; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; color:var(--ink-3); margin:0 0 8px}
.the .so{font-family:"IBM Plex Mono",monospace; font-size:29px; font-weight:500;
  line-height:1.15; color:var(--ink); margin:0; overflow-wrap:break-word}
.the .so.chu{font-family:inherit; font-size:20px; font-weight:700; line-height:1.3}
.the .duoi{font-size:12.5px; color:var(--ink-3); margin:7px 0 0; overflow-wrap:break-word}
.the.s1{border-left-color:var(--accent)}   .the.s1 .nhan{color:var(--accent)}
.the.s2{border-left-color:var(--ok)}       .the.s2 .nhan{color:var(--ok)}
.the.s3{border-left-color:var(--line-2)}
.the.s4{border-left-color:var(--warn)} .the.s4 .nhan{color:var(--warn)}

/* ---------- dải tab lọc ---------- */
.dai-tab{display:flex; align-items:center; gap:4px; flex-wrap:wrap;
  border-bottom:1px solid var(--line); margin-bottom:2px}
.dai-tab .tab{
  background:none; border:0; cursor:pointer; font:inherit; font-size:14.5px;
  color:var(--ink-2); padding:10px 14px; border-bottom:2px solid transparent;
  margin-bottom:-1px; min-height:44px;
}
.dai-tab .tab:hover{color:var(--ink)}
.dai-tab .tab.dang{color:var(--accent); font-weight:700; border-bottom-color:var(--accent)}
.dai-tab .tab:focus-visible{outline:2px solid var(--accent); outline-offset:-2px}
.dai-tab .cnt{margin-left:auto; font-family:"IBM Plex Mono",monospace; font-size:12px; color:var(--ink-3)}

/* =====================================================================
   TRANG TÀI KHOẢN CỦA TÔI
   ===================================================================== */

/* Thẻ hồ sơ: nền xanh nhạt, viền trái đậm. Khác hẳn mấy thẻ trắng bên
   dưới, vì đây là "bạn là ai" chứ không phải một ô để điền. */
.tk-the{
  display:flex; align-items:center; gap:18px; flex-wrap:wrap;
  background:var(--accent-soft); border:1px solid var(--line);
  border-left:4px solid var(--accent);
  border-radius:var(--bo); padding:18px 22px; margin-bottom:20px;
}
.tk-the-chu{min-width:0; flex:1 1 320px}
.tk-ten{margin:0; font-size:21px; font-weight:800; color:var(--hieu-dau); line-height:1.25}
.tk-mail{margin:3px 0 0}
.tk-mail code{font-family:"IBM Plex Mono",monospace; font-size:13px; color:var(--ink-3)}
.tk-huy{margin:10px 0 0; display:flex; align-items:center; gap:8px; flex-wrap:wrap}
.tk-tu{font-size:13px; color:var(--ink-3)}
.tk-nut{margin:14px 0 0; display:flex; align-items:center; gap:9px; flex-wrap:wrap}
.tk-nut .btn{padding:10px 16px; font-size:14px}   /* 7px thì nút cao 34 — dưới mốc 40 (đo 26/09) */
.tk-nhe{font-weight:400; font-size:12.5px; color:var(--ink-3)}

/* Nút BỎ ảnh mang màu cảnh báo: nó xoá thật, và xoá rồi không lấy lại
   được. Cùng hình dáng với nút cạnh nó, chỉ khác màu. */
.btn.bo{border-color:var(--flag); color:var(--flag)}
.btn.bo:hover{background:var(--flag-soft)}

/* Ảnh đại diện lớn trong thẻ hồ sơ. Chưa có ảnh thì hiện chữ cái đầu —
   cùng một khuôn, nên lúc tải ảnh lên bố cục không nhảy. */
.tk-anh{
  flex:none; width:74px; height:74px; border-radius:50%; overflow:hidden;
  display:flex; align-items:center; justify-content:center;
  background:var(--surface); border:2px solid var(--accent);
  color:var(--accent); font-weight:800; font-size:28px; text-transform:uppercase;
}
.tk-anh img, .kv-anh img{width:100%; height:100%; object-fit:cover; display:block}
.kv-anh.co-anh{background:none; padding:0; overflow:hidden}

/* Hai cột: thông tin cá nhân và mật khẩu. Dưới 900px xếp dọc — hai cột
   ô nhập cạnh nhau ở bề ngang ấy thì mỗi ô còn chưa tới 200px. */
.tk-hai{display:grid; grid-template-columns:1fr; gap:20px}
@media(min-width:900px){ .tk-hai{grid-template-columns:1fr 1fr} }
.tk-o{
  background-color:var(--mau-o); background-image:var(--anh-o); border:1px solid var(--line);
  border-radius:var(--bo); padding:20px 22px;
}
.tk-o h3{margin:0; font-size:18px; font-weight:700; color:var(--hieu-dau)}
.tk-phu{margin:5px 0 16px; font-size:14px; color:var(--ink-2); max-width:62ch}
.tk-o .field input:disabled{background:var(--alt); color:var(--ink-3); cursor:not-allowed}

/* Tên và email đứng cạnh nhau khi đủ chỗ, trong một khung viền đứt để
   thấy rõ đâu là phần sửa được. */
.tk-doi{
  display:grid; grid-template-columns:1fr; gap:14px;
  border:1px dashed var(--line-2); border-radius:var(--bo-nho);
  padding:16px 18px; margin-bottom:16px;
}
@media(min-width:560px){ .tk-doi{grid-template-columns:1fr 1fr} }
.tk-doi .field{margin:0}

/* ---------- ô hai dòng trong bảng ---------- */
.hai-dong .chinh{font-weight:600; color:var(--ink)}
.hai-dong .phu{font-family:"IBM Plex Mono",monospace; font-size:11.5px; color:var(--ink-3); margin-top:2px}

/* ---------- màn hình hẹp ----------
   Dưới 66rem thanh bên xuống thành một dải ngang: ở bề rộng ấy 260px là
   một phần tư màn hình chỉ để chứa menu. Mốc lấy từ ALFA Report. */
@media (max-width:66rem){
  /* ẨN HẲN, không phải hiện sẵn. Hiện sẵn thì mở khu thành viên trên
     điện thoại là một màn hình toàn menu: năm thẻ nhóm xếp dọc, nội
     dung nằm hết dưới màn. Đo trong khung 414px mới thấy. */
  .kv-ben{display:none}
  /* MỞ RA LÀ CHE MÀN, không đẩy trang (chủ dự án 06/10, APL-234: «menu trên điện chiếm page và đẩy trang
     chủ xuống, chứ không kiểu che màn»). Bản cũ position:static nằm TRONG main ⇒ một khối trọng lượng
     936px ở 390×703: nội dung bị đẩy xuống dưới, hàng tên người dùng đáy ở 1053 — ngoài màn.
     Nay là ngăn kéo fixed TỪ DƯỚI THANH TRÊN tới đáy: thanh trên vẫn bấm được (nút ba gạch đóng lại
     được), menu dài hơn màn thì CUỘN BÊN TRONG, nền khoá cuộn, phần còn lại phủ lớp mờ — bấm vào
     lớp mờ là đóng (bộ lắng click-ngoài ở tai-khoan.html). Lỗi gốc của nhánh này — «mở khu thành
     viên là một màn hình toàn menu» — vẫn được giải: menu vẫn ẨN tới khi bấm. */
  body.menu-mo{overflow:hidden}
  body.menu-mo::after{
    content:""; position:fixed; inset:var(--dau-cao) 0 0 0; z-index:35;
    background:rgb(4 16 24 / .55);
  }
  body.menu-mo .kv-ben{
    display:flex; flex-direction:column; gap:8px;
    position:fixed; top:var(--dau-cao); bottom:0; left:0; z-index:40;
    width:min(320px, calc(100vw - 64px));
    padding:12px 10px calc(14px + env(safe-area-inset-bottom));
    overflow-y:auto; overscroll-behavior:contain;
    background:var(--paper); border-right:1px solid var(--line);
    box-shadow:0 12px 32px rgb(0 0 0 / .28);
  }
  /* min-width:0 — mục flex giữ min-width:auto thì tên người dùng nowrap đẩy .kv-toi rộng theo tên: đo 26/09,
     tên hiển thị 60 ký tự (trần CHECK), menu mở ở 320 → .kv-toi 601px trong khung 288, cả trang tràn 297px.
     Có dòng này thì tên cắt "…" như ở màn rộng. flex:none — trong ngăn kéo cột, nó đứng ĐÁY khi menu
     ngắn (margin-top:auto) và đi theo luồng cuộn khi menu dài, không bị bóp. */
  .kv-toi{flex:none; margin-top:auto; min-width:0}
  #kv-menu{flex:none; flex-direction:column; gap:8px}
  .kv-khoi{flex:none}
  .kv-nhom{width:calc(100% - 18px); margin:8px 9px 3px}   /* 100% CỘNG lề 9+9 thì lố khối 4–18px (đo 26/09) */
  .the4{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:560px){
  .the4{grid-template-columns:1fr}
  .o-dau h2{font-size:23px}
}

/* ===== NHÂN SỰ (§24.4b · N1) =====
   .ns-gia  — khối giá NÓI TRƯỚC NÚT mời: tỉ lệ + bảng trước/sau do CSDL tính
   .ns-ds   — danh sách người / lời mời; mỗi <li> một hàng gập được ở 390 */
.ns-khoi{margin-top:20px}
.ns-gia{border:1px solid var(--warn); background:var(--warn-soft); border-radius:var(--bo-nho);
  padding:12px 14px; margin:0 0 16px; font-size:14px; color:var(--ink)}
.ns-gia p{margin:0}
.ns-gia p + p, .ns-gia p + table, .ns-gia table + p{margin-top:8px}
.ns-gia b{color:var(--ink)}
.ns-gia table{width:auto; min-width:0; font-size:13.5px}
.ns-gia th, .ns-gia td{padding:4px 10px 4px 0; text-align:left; border:0; background:none}
.ns-gia td:not(:first-child){font-variant-numeric:tabular-nums; white-space:nowrap}
.ns-gia.loi{border-color:var(--flag); background:var(--flag-soft); color:var(--flag)}
.ns-vai-giai{display:grid; grid-template-columns:max-content 1fr; gap:4px 12px;
  margin:14px 0 16px; font-size:13.5px; color:var(--ink-2)}
.ns-vai-giai dt{font-weight:600; color:var(--ink)}
.ns-vai-giai dd{margin:0}
.ns-ds{list-style:none; margin:0; padding:0}
.ns-ds > li{display:flex; align-items:center; flex-wrap:wrap; gap:8px 14px;
  padding:12px 0; border-top:1px solid var(--line)}
.ns-ds > li:first-child{border-top:0; padding-top:0}
.ns-ai{flex:1 1 220px; min-width:0}
.ns-ai b{display:block; overflow-wrap:anywhere}
.ns-ai span{display:block; font-size:13px; color:var(--ink-3); overflow-wrap:anywhere}
.ns-lam{display:flex; align-items:center; flex-wrap:wrap; gap:8px}
.ns-lam select{width:auto; padding:10px 12px; font-size:14px}
.ns-lam .btn{padding:10px 16px; font-size:14px}
.ns-ds > li > .xn-huy{flex:1 1 100%}
.ns-ghi{flex:1 1 100%; margin:0; font-size:13px; color:var(--ink-3)}
@media (max-width:560px){ .ns-vai-giai{grid-template-columns:1fr; gap:0} .ns-vai-giai dd{margin-bottom:6px} }
.ns-moi-toi{margin-bottom:20px; border-color:var(--accent)}
.ns-khoi-dau{margin-bottom:20px}
.ns-ten-tc{display:flex; flex-wrap:wrap; align-items:flex-end; gap:12px}
.ns-ten-tc .field{flex:1 1 260px; margin:0}
.ns-ten-tc-doc{margin:0; font-size:16px}

/* ===== MINH HOẠ SỐNG (bằng chứng 04/10 — học kỹ thuật Resend, KHÔNG lấy bảng màu) =====
   Minh hoạ dựng bằng MẢNH GIAO DIỆN THẬT của sản phẩm, không bằng ảnh. Bốn lớp, cả bốn chỉ dùng
   token ⇒ tự đổi theo sáng/tối (§18.1 4d-i), không lớp nào phụ thuộc nền đen:
   ① quầng sáng teal ở đỉnh (::before) · ② đường sáng 1px ở mép trên (::after)
   ③ lớp phủ mờ dần về MÀU NỀN THẺ (.mh-canh::after) — thay cho mask-image
   ④ chuyển động chậm, CHỈ khi người dùng không xin giảm chuyển động.
   Phần minh hoạ là hình — aria-hidden ở markup; chữ đọc được nằm ở .mh-chu. */
.minh-hoa{
  position:relative; isolation:isolate; overflow:hidden;
  background-color:var(--mau-o); background-image:var(--anh-o); border:1px solid var(--line); border-radius:16px;
  display:flex; flex-direction:column;
}
.minh-hoa::before{
  content:""; position:absolute; inset:0 0 auto; height:75%; z-index:-1; pointer-events:none;
  background:radial-gradient(70% 80% at 50% 0%, color-mix(in srgb, var(--hieu) 16%, transparent), transparent 70%);
}
.minh-hoa::after{
  content:""; position:absolute; top:-1px; left:50%; width:min(240px, 45%); height:1px; transform:translateX(-50%);
  background:linear-gradient(90deg, transparent, var(--hieu), transparent); pointer-events:none;
}
.mh-canh{ position:relative; height:210px; padding:26px 20px 0; overflow:hidden }
.mh-canh::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(to bottom, transparent 52%, var(--surface) 96%);
}
.mh-chu{ padding:6px 22px 22px }
.mh-chu h3{ margin:0 0 6px; font-size:17px; font-weight:700; color:var(--ink) }
.mh-chu p{ margin:0; font-size:14.5px; color:var(--ink-2); line-height:1.6 }

/* mảnh giao diện trong vùng hình */
.mh-de-xuat{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  max-width:420px; margin:0 auto; padding:10px 12px;
  background:var(--surface); border:1px solid var(--line); border-radius:12px; box-shadow:var(--bong-cao);
  font-size:13.5px; color:var(--ink);
}
.mh-de-xuat b{ flex:1 1 160px; min-width:0; font-weight:600 }
.mh-nhan{ font-size:12px; font-weight:600; padding:2px 8px; border-radius:var(--bo-tron); white-space:nowrap }
.mh-nhan.cao{ background:var(--warn-soft); color:var(--warn) }
.mh-nhan.on{ background:var(--ok-soft); color:var(--ok) }
.mh-nut{ font-size:12.5px; font-weight:600; padding:5px 12px; border-radius:var(--bo-tron);
  background:var(--accent); color:var(--accent-ink); white-space:nowrap }
.mh-nhat-ky{ list-style:none; margin:16px auto 0; padding:0; max-width:420px;
  font-family:"IBM Plex Mono",monospace; font-size:12.5px; color:var(--ink-2) }
.mh-nhat-ky li{ display:flex; gap:10px; padding:5px 2px; border-top:1px dashed var(--line) }
.mh-nhat-ky li span:first-child{ color:var(--ink-3) }
.mh-nhat-ky li .mh-nhan{ margin-left:auto; font-family:Inter,sans-serif }

/* ④ chuyển động: dòng nhật ký trôi lên rất chậm — CHỈ khi được phép */
@media (prefers-reduced-motion: no-preference){
  .mh-nhat-ky.troi{ animation:mh-troi 18s linear infinite }
  @keyframes mh-troi{ from{ transform:translateY(0) } to{ transform:translateY(-50%) } }
}

/* Tiêu đề tô gradient trên CHỮ (kỹ thuật tiêu đề Resend) — navy → teal đậm.
   🔴 CHỈ CHO TIÊU ĐỀ LỚN (≥24px hoặc ≥19px đậm). Đo 08/10 (APL-260, công thức L/tuongPhan của lõi tương phản), CẬN
   qua cả dải gradient: sáng trên --paper 4,89 · ngay TÂM .vung-sang (teal α0,3) 3,75 — đạt 3:1 chữ lớn, KHÔNG đạt 4,5
   chữ thường. Tối: 10,85 / 5,88. ⚠ Số cũ «4,29 / 3,32» (04/10) là của --hieu-cuoi #14846F; 8f4e7e0 (05/10) đổi sang
   #127A66 ⇒ đo lại mỗi lần đổi --hieu-dau/--hieu-cuoi. Lõi MÙ chữ clip:text và .vung-sang::before ⇒ phải tính tay. */
.tieu-de-sang{
  background:linear-gradient(115deg, var(--hieu-dau) 35%, var(--hieu-cuoi));
  -webkit-background-clip:text; background-clip:text; color:transparent;
}

/* ⚠ BẢN GẦN ĐÚNG, KHÔNG phải bản giống. ĐÃ CHỌN cho trang thật 04/10 (chủ dự án: «áp cho tất cả website và app»):
   chỉ khối MỞ ĐẦU và dải minh hoạ, ⛔ không rải mọi .band — điểm nhấn dùng khắp nơi thì thôi là điểm nhấn.
   Dải sáng chéo (Resend dùng ẢNH raster 1910×855; đây là bản GẦN ĐÚNG bằng CSS): một dải gradient
   xoay nghiêng và làm mờ, nằm SAU nội dung. Trên nền sáng nó là một vệt teal nhạt; trên nền tối nó sáng hơn.
   Nhịp thở chậm CHỈ khi người dùng không xin giảm chuyển động. */
.vung-sang{ position:relative; isolation:isolate; overflow:hidden }
/* .vung-sang nằm trên .wrap 1160 giữa một băng full rộng ⇒ overflow:hidden cắt quầng thành HAI MÉP ĐỨNG ở mép .wrap
   (đo 04/10: x≈380 ở 1920 — chủ dự án thấy thành «đường»). Dời việc cắt ra BĂNG: quầng tự tan ở hai đầu gradient,
   băng full rộng giữ cho trang ⛔ cuộn ngang. Trình duyệt chưa có :has giữ cách cắt cũ (an toàn, chỉ kém đẹp). */
@supports selector(:has(a)){
  .band:has(> .vung-sang){overflow-x:clip}
  .band > .vung-sang{overflow:visible}
}
.vung-sang::before{
  content:""; position:absolute; z-index:-1; pointer-events:none;
  left:-20%; right:-20%; top:38%; height:90px; transform:rotate(-9deg);
  background:linear-gradient(90deg, transparent 5%, color-mix(in srgb, var(--hieu) 30%, transparent) 45%, transparent 85%);
  filter:blur(28px);
}
/* «Nhịp thở» là lặp VÔ HẠN ⇒ CHỌN VÀO bằng .tho, ⛔ không phải mặc định (chủ dự án chốt 04/10: trang thật ⛔ không chuyển
   động lặp vô hạn). Đảo mặc định để mọi chỗ dùng mới AN TOÀN THEO CẤU TRÚC — một luật an toàn mà cần người nhớ ghi đè
   thì nó hỏng ở chỗ thứ ba. Hôm nay chỉ tủ kính /thanh-phan dùng .tho. */
@media (prefers-reduced-motion: no-preference){
  .vung-sang.tho::before{ animation:vung-tho 7s ease-in-out infinite alternate }
  @keyframes vung-tho{ from{ opacity:.55 } to{ opacity:1 } }
}

/* ===== MỘT CỘT, FULL CHIỀU RỘNG — mọi trang bán hàng (chủ dự án 04/10, PM chốt áp cho mọi trang) =====
   Lịch sử để không ai vá lại thứ đã được chọn: «cột hẹp ra giữa» (432780d) bị BÁC · «chia 2–3 cột» (6aadcd4) bị
   BÁC · «1 cột full chiều rộng từ trên xuống» (769f92e, /adpilot/bang-gia) được XÁC NHẬN «Đúng rồi đó».
   ⇒ Trong .band .wrap mọi khối con rộng đúng bề rộng .wrap, xếp MỘT cột; chữ bỏ trần 62ch/70ch.
   🔑 DÒNG DÀI LÀ LỰA CHỌN CỦA CHỦ DỰ ÁN, KHÔNG PHẢI LỖI ĐỂ VÁ — đừng đặt lại max-width cho đoạn văn ở đây.
   Phạm vi: TRỪ dải kêu gọi .band.goi (căn giữa trọn, đối xứng — đã duyệt cùng ảnh /bang-gia) · hero ·
   /tai-khoan (.split/.kv) · .wrap.van-ban = /privacy /terms (dấu TƯỜNG MINH trong markup) — CHƯA ĐO (PM 04/10: đo ký tự/dòng ở 1440
   rồi mới quyết; không phải ngoại lệ vĩnh viễn). Tiêu đề giữ 30ch như mọi tiêu đề của site.
   Băng CÓ khối phủ rộng: phần mở đầu (eyebrow · tiêu đề · đoạn dẫn ngay sau · hàng nút) CĂN GIỮA như /bang-gia.
   Băng CHỈ có chữ: căn trái, full rộng (như băng giới thiệu /bang-gia).
   ⚠ Cần :has() (Firefox ≥121, Safari ≥15.4, Chrome ≥105) — trình duyệt cũ nhận bố cục cũ, thoái hoá êm. */
.band:not(.goi):not(:has(.split, .kv, .hero)) .wrap:not(.van-ban){max-width:1160px}
.band:not(.goi):not(:has(.split, .kv, .hero)) .wrap:not(.van-ban) > :is(p, ul, ol, h3, .note, .pull, .luuy, .dia-chi-ds, .cau-hoi-ds, .gia-dem, .hoi-dap, .promo, .seek, .chips){width:auto; max-width:none; margin-inline:0}
.band:not(.goi):not(:has(.split, .kv, .hero)) .wrap:not(.van-ban) > :is(.note, .pull, .luuy) :is(p, ul, ol){max-width:none}
.band:not(.goi):not(:has(.split, .kv, .hero)) .wrap:not(.van-ban):has(> :is(.cards, .grid, .tw, .bang-goi, .shelf, .chips, .dia-chi-ds, .cau-hoi-ds, .gia-dem, .promo, ol.steps, form.seek, .hai-nua, .hai-cot)) > :is(.eyebrow, h1, h2, :is(h1, h2) + p, .goi-nut){margin-inline:auto; text-align:center}
.band:not(.goi):not(:has(.split, .kv, .hero)) .wrap:not(.van-ban):has(> :is(.cards, .grid, .tw, .bang-goi, .shelf, .chips, .dia-chi-ds, .cau-hoi-ds, .gia-dem, .promo, ol.steps, form.seek, .hai-nua, .hai-cot)) > .ctas{justify-content:center}
/* Nhãn kệ: nhãn TRÁI, đếm/liên kết PHẢI — hai đầu, thay vì cả cụm dồn trái trên một thẻ phủ rộng. */
.shelf-h{justify-content:space-between}

/* /adpilot/bang-gia — MỘT CỘT, FULL CHIỀU RỘNG (chủ dự án 04/10, hai lượt: bác «cột hẹp ra giữa»,
   rồi bác «chia 2–3 cột»: «không phải kiểu chia ra làm 3 cột, 1 cột thôi» · «làm 1 cột và full chiều rộng»).
   Mọi khối trong băng rộng đúng bề rộng .wrap, nội dung xếp từ trên xuống; chữ trong các khối này bỏ trần
   62ch để đi hết bề rộng thay vì chừa nửa phải trống. Tiêu đề giữ trần 30ch như mọi tiêu đề của site. */
.gia-dem, .hai-cot, .hoi-dap, .hai-nua{width:auto; max-width:none; margin-inline:0}
.wrap > .luuy.hai-cot{width:auto; max-width:none; margin-inline:0}
:is(.gia-dem, .hai-cot, .hoi-dap, .hai-nua) :is(p, ul, ol){max-width:none}
/* .hai-cot là TÊN LỊCH SỬ: bố cục đã về MỘT CỘT từ 769f92e (04/10, chủ dự án «1 cột thôi») — các đoạn xếp chồng, full .wrap.
   ⛔ Thêm lại grid/columns ở đây. Giữ tên vì 3 chỗ dùng ở bang-gia + các danh sách :is() trên; đổi tên ⛔ đổi gì cho khách. */
.hai-cot{margin-top:18px}
.hai-cot > p{margin:0; text-align:left}
.hai-cot > p + p{margin-top:10px}
.hoi-dap{margin-top:20px}
.hai-nua > div > :last-child{margin-bottom:0}
/* Đoạn dẫn dưới tiêu đề hai băng ấy cũng đi hết bề rộng — không để một dòng hẹp giữa các khối full. */
:is(#tinh-theo-gi, #khong-tinh) .wrap > .dan{max-width:none}
/* Dải kêu gọi tối căn giữa CHỮ nhưng h2 có max-width 30ch mà không margin auto ⇒ HỘP tiêu đề đứng mép trái (lỗi cũ, mọi trang). */
.band.goi h2{margin-inline:auto}
/* Nút sáng/tối trên thanh đầu site công khai: rộng thì nằm phải nhất sau dãy liên kết; 480–999 (menu gập)
   thì đứng NGAY TRƯỚC nút menu, ngoài danh sách gập — đổi chế độ không bắt người ta mở menu.
   Dưới 480 thanh không đủ chỗ (nút menu bị đẩy ra ngoài màn) ⇒ nav.js dời nút VÀO menu gập, thành một dòng
   có chữ. Ngưỡng 479px phải trùng với nav.js. :has(.nav-in > …) chứ không :has(…): khi nút đã vào menu,
   nút menu phải lấy lại margin-left:auto của nó. */
#nut-giao-dien .gd-chu{display:none}
@media (max-width:999px){
  html.co-js .nav.co-menu .nav-in > #nut-giao-dien{order:1; margin-left:auto}
  html.co-js .nav.co-menu:has(.nav-in > #nut-giao-dien) .nav-mo{order:2; margin-left:6px}
}
@media (max-width:479px){
  html.co-js .nav.co-menu .nav-in > #nut-giao-dien{display:none}
  html.co-js .nav.co-menu .nav-links > #nut-giao-dien{
    display:flex; justify-content:flex-start; gap:10px; width:auto; height:auto; margin:0;
    padding:13px 2px; border:0; border-radius:0; font-size:16px; color:var(--ink-2); text-align:left;
  }
  html.co-js .nav.co-menu .nav-links > #nut-giao-dien .gd-chu{display:inline}
}

/* ===== NÚT VI · EN (SPEC §11b.7 ②) — hai liên kết ?ngon_ngu=vi|en, ⛔ JS: middleware đặt cookie alfa_ngon_ngu rồi 303
   về bản đúng. Lớp .chon-ngon-ngu DÙNG CHUNG với app (ung-dung.css) — sửa một bên thì sửa bên kia.
   Nằm CUỐI .nav-links: ở khổ rộng đứng sau nút CTA; ≤999px nằm trong menu gập — ⛔ chen vào hàng 44px của thanh hẹp.
   aria-current="true" = ngôn ngữ ĐANG hiện (đậm + gạch dưới; bấm lại vẫn an toàn, middleware chỉ đặt lại cookie). */
.chon-ngon-ngu{display:inline-flex; align-items:center; gap:2px}
.chon-ngon-ngu > a{
  display:inline-flex; align-items:center; justify-content:center; min-width:40px; min-height:40px; padding:0 8px;
  border-radius:var(--bo-nho); font-size:13.5px; font-weight:500; letter-spacing:.06em; color:var(--ink-2); text-decoration:none;
}
.chon-ngon-ngu > a:hover{background:var(--alt); color:var(--hieu-dau)}
.chon-ngon-ngu > a[aria-current]{color:var(--ink); font-weight:700; text-decoration:underline; text-underline-offset:5px}
.chon-ngon-ngu > a:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
@media (pointer:coarse){ .chon-ngon-ngu > a{min-height:44px} }
@media (max-width:999px){
  /* Trong menu gập: một hàng hai nút, ⛔ hai dòng kẻ như mục điều hướng. Thắng luật «.nav-links a:not(.cta)» ở trên
     vì CÙNG độ ưu tiên và đứng SAU. */
  html.co-js .nav.co-menu .nav-links .chon-ngon-ngu{padding:10px 0 2px; gap:8px}
  html.co-js .nav.co-menu .nav-links .chon-ngon-ngu > a{padding:0 10px; min-height:44px; font-size:15px; border:1px solid var(--line)}
}
/* /tai-khoan bản tiếng Anh (§11b.7 ⑤): script <head> đặt html.dang-dich CHỈ khi cookie ngôn ngữ = en, module dịch xong
   thì gỡ (hẹn giờ 2 giây tự gỡ nếu module hỏng). Ẩn bằng visibility ⇒ bố cục giữ nguyên, không nháy chữ Việt rồi mới Anh. */
html.dang-dich body{visibility:hidden}

/* ===== HÌNH CỔNG DUYỆT — /adpilot khối 03 (④, 04/10) =====
   Một <ol> thật mặc áo sơ đồ: CSS không nạp thì còn danh sách đánh số đọc được (ca CSP 23/09).
   🔑 Nói CHỖ DỪNG: các bước nối bằng mũi tên, riêng chỗ giữa "Chờ người duyệt" và "Áp dụng" là
   dấu TẠM DỪNG (‖), không phải mũi tên — đi tiếp cần một người, không tự chảy.
   Hoàn tác là đường QUAY VỀ CỔNG (SPEC §5b), không phải bước thứ năm nối tiếp.
   Hẹp: cột dọc, mũi tên ↓. Từ 1000px: một hàng bốn ô (đo 04/10: ở 760 mỗi ô chỉ 136px, cao 216 — chữ bị bó) (subgrid để đường hoàn tác neo đúng tâm ô 3–4).
   Chuyển động: CHỈ khi cho phép VÀ trình duyệt có animation-timeline — gắn theo cuộn, chạy một
   lượt khi khung đi vào màn, không lặp. Không đủ điều kiện ⇒ hình tĩnh, đầy đủ. */
.cong{margin:28px 0 0; padding:22px 18px 20px; border:1px solid var(--line-2); border-radius:var(--bo); background-color:var(--mau-o); background-image:var(--anh-o)}
.cong-buoc{list-style:none; margin:0; padding:0; max-width:none; display:grid; grid-template-columns:minmax(0,1fr); gap:30px}
.cb{position:relative; padding:14px 16px; border:1px solid var(--line-2); border-radius:var(--bo); background:var(--paper)}
.cb b{display:block; font-size:15px; color:var(--ink); margin:0 0 4px}
.cb > span{display:block; font-size:14px; line-height:1.55; color:var(--ink-2)}
.cb::after{
  content:"↓" / ""; position:absolute; left:50%; bottom:-27px; transform:translateX(-50%);
  font-size:18px; line-height:24px; color:var(--ink-3);
}
.cb:last-child::after{content:none}
/* cổng: viền và nền màu cảnh báo — chỗ đứng lại */
.cb-cong{border:2px solid var(--warn); background:var(--warn-soft)}
.cb-cong b{color:var(--ink)}
/* thay mũi tên sau cổng bằng dấu tạm dừng: hai vạch đứng */
.cb-cong::after{
  content:""; bottom:-25px; width:10px; height:18px;
  border-left:3px solid var(--warn); border-right:3px solid var(--warn);
}
.cb-ap{border-color:var(--accent)}
.cong-lui{max-width:none; margin:22px 0 0; padding:12px 16px; border:2px dashed var(--line-2); border-radius:var(--bo)}
.cong-lui b{display:block; font-size:15px; color:var(--ink); margin:0 0 4px}
.cong-lui b::before{content:"↺ " / ""; color:var(--ink-3)}
.cong-lui > span{display:block; font-size:14px; line-height:1.55; color:var(--ink-2)}

@media (min-width:1000px){
  .cong{padding:26px 24px 22px; display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); column-gap:40px}
  .cong-buoc{grid-column:1 / -1; grid-template-columns:subgrid; gap:0 40px}
  .cb::after{content:"→" / ""; left:auto; right:-31px; bottom:auto; top:50%; transform:translateY(-50%)}
  .cb-cong::after{content:""; right:-25px}
  /* đường quay về: chữ U úp ngược từ tâm ô 4 về tâm ô 3, đầu mũi tên ở phía cổng */
  .cong-lui{
    grid-column:3 / 5; position:relative; margin:30px 0 0; padding:14px 16px 0;
    border:0; border-radius:0; text-align:center;
  }
  .cong-lui::before{
    content:""; position:absolute; top:-30px; height:22px;
    left:calc((100% - 40px) / 4); right:calc((100% - 40px) / 4);
    border:2px dashed var(--vien-dieu-khien); border-top:0; border-radius:0 0 12px 12px;
  }
  .cong-lui::after{
    content:""; position:absolute; top:-34px; left:calc((100% - 40px) / 4 - 5px);
    border:6px solid transparent; border-bottom:8px solid var(--vien-dieu-khien); border-top:0;
  }
}

@media (prefers-reduced-motion:no-preference){
  @supports (animation-timeline: view()){
    .cb, .cong-lui{animation:cong-hien linear both; animation-timeline:view()}
    .cb:nth-child(1){animation-range:entry 10% entry 70%}
    .cb:nth-child(2){animation-range:entry 25% entry 85%}
    .cb:nth-child(3){animation-range:entry 40% cover 35%}
    /* nghỉ một nhịp trước "Áp dụng": nó sáng lên MUỘN hơn hẳn — đúng nghĩa "chờ" */
    .cb:nth-child(4){animation-range:cover 30% cover 50%}
    .cong-lui{animation-range:cover 35% cover 55%}
    @keyframes cong-hien{from{opacity:.3; transform:translateY(8px)} to{opacity:1; transform:none}}
  }
}

/* APL-212 — khối báo «đăng nhập sai địa chỉ được mời» ở /tai-khoan: nhiều đoạn + một nút trong một .msg.luu.
   Gắn theo id, không theo .msg chung: các .msg khác do bao() đổ chữ trần vào, đừng đổi nhịp của chúng. */
#tb-sai-email p{margin:0 0 8px; max-width:none}
#tb-sai-email p:last-child{margin:0}

/* ===== DẢI MINH HOẠ SỐNG trên trang bán hàng — /adpilot ngay dưới đầu trang (chủ dự án chốt 04/10) =====
   Bố cục mà mẫu /thanh-phan viết NỘI TUYẾN (lớp .vung-sang/.tieu-de-sang/.minh-hoa chỉ mang HIỆU ỨNG).
   ⛔ Không chuyển động lặp vô hạn trên trang thật: .vung-sang nay TĨNH theo mặc định (nhịp thở chỉ khi có .tho).
   Thẻ nhật ký ở đây là danh sách tĩnh, không mang .troi. */
.mh-dai .vung-sang{padding:8px 0 32px; text-align:center}
.mh-dai .vung-sang h2{font-size:clamp(28px, 4.6vw, 40px); line-height:1.1; letter-spacing:-.02em; margin:0 auto; max-width:24ch}
.mh-dai .vung-sang p{margin:12px auto 0; color:var(--ink-2); max-width:46ch}
.mh-luoi{display:grid; grid-template-columns:repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap:20px}

/* ===== NHỊP SECTION trong một trang (chủ dự án 04/10: «mọi section tôn được điểm nhấn» + «tự nhiên, hài hoà») =====
   Cường độ có HÌNH DẠNG: MẠNH ở khối mở đầu (hero: quầng + tiêu đề chuyển màu) · LẮNG ở thân bài · MẠNH LẠI ở khối khép.
   Một khối LẮNG ⛔ không phải một khối TRỐNG: nó vẫn có tín hiệu, chỉ không giành chỗ. Mỗi khối một chữ ký KHÁC nhau
   trong cùng bộ từ vựng — lặp một hiệu ứng ở mọi khối thì thôi là điểm nhấn.
   .band.lang — thân bài: vạch teal 3px cạnh tiêu đề nhóm + viền teal đỉnh thẻ (mặt nâng). Không quầng, không chữ
     chuyển màu (h2 nhóm 19px < 24px — luật .tieu-de-sang).
   .band.khep — khối khép trang: quầng .vung-sang (thưa — chỉ mở đầu và khép) + h2 nâng lên ≥24px ở MỌI khổ để đủ
     điều kiện mang .tieu-de-sang. */
.band.lang .shelf-h h2{padding-left:12px; box-shadow:inset 3px 0 0 var(--accent)}
/* ⚠ ⛔ không ghép var(--bong) vào danh sách: --bong = none, và «none» trong một danh sách bóng làm CẢ khai báo vô hiệu (đo 04/10). */
.band.lang .prod{box-shadow:inset 0 3px 0 var(--hieu-cuoi)}
.band.lang .prod:hover{box-shadow:inset 0 3px 0 var(--accent), var(--bong-cao)}
.band.khep h2{font-size:clamp(24px, 3.4vw, 32px); line-height:1.18; letter-spacing:-.015em}
/* «Tự nhiên, hài hoà»: các băng CHUYỂN, không NỐI. Đường kẻ băng nay bỏ ở MẶC ĐỊNH (xem .band ở đầu tệp);
   băng khép CHUYỂN từ --paper sang --alt trong 160px đầu thay cho một nhát cắt. */
/* màu nền ĐẶC dưới gradient: hình không đổi, nhưng thước tương phản đo được chữ trong băng (không có nó: 6 chữ rơi vào boQua). */
.band.khep{background-color:var(--alt); background-image:linear-gradient(to bottom, var(--paper), var(--alt) 160px)}
/* Ô «sắp có» trong băng lắng: viền đứt mờ trên nền đen đọc thành một LỖ TRỐNG ở ảnh thu nhỏ ⇒ nền phớt --nen-wash,
   giữ viền đứt (vẫn là ô giữ chỗ, chỉ thôi trông như chỗ chưa ai đụng). */
.band.lang .soon{background:var(--nen-wash)}

/* ── Thẻ sản phẩm DÙNG bề rộng bằng BỐ CỤC, ⛔ không bằng dòng dài hơn (04/10) ──
   Thẻ rộng ~1128px mà chữ bị trần 70ch ⇒ nửa phải thẻ trống. Gỡ trần một mình thì đổi sang dòng dài. Phép sửa: những PHẦN TỬ KHÁC LOẠI (mô tả ·
   gạch đầu dòng · nhãn) xếp cạnh nhau. ⛔ Đây không phải «rót MỘT đoạn văn thành nhiều cột» (§30.1 cấm, 6aadcd4) —
   mỗi làn mang một loại thứ khác nhau, đọc độc lập. Hai số phải CÙNG đạt (SPEC §30.3): ≤ ~95 ký tự/dòng · thẻ ≤25%
   trống ở mép phải. Ba làn (mô tả · gạch · nhãn) đã thử và BỎ: ở .wrap 1160 làn nhãn còn 243px —
   chủ dự án giữ bề rộng 1160 (bác lượt nới full rộng 04/10), nên hai làn là đúng cỡ. */
@media (min-width:900px){
  .prod{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); column-gap:clamp(28px,3.5vw,56px);
        grid-template-areas:"h h" "for for" "desc pts" "nhan nhan" "go go"; align-items:start}
  .prod-h{grid-area:h} .prod-for{grid-area:for} .prod-desc{grid-area:desc} .prod-pts{grid-area:pts}
  .prod-nhan{grid-area:nhan} .prod-go{grid-area:go; justify-self:start}
  .prod-desc, .prod-pts{max-width:none}
  .soon{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); column-gap:clamp(28px,3.5vw,56px); align-items:baseline}
  .soon .prod-h{margin:0; grid-area:auto}  /* .prod-h{grid-area:h} ở trên ăn cả vào đây; .soon ⛔ không có vùng «h» ⇒ đẩy tiêu đề sang làn PHẢI (đo 04/10) */
  .soon p{max-width:none}
}
/* Khối khép: tiêu đề và văn bản CÙNG một hàng thay vì h2 30ch nằm trên văn chạy hết bề rộng (hai khối đọc như không
   liên quan). Làn văn bản 34rem ≈ ≤95 ký tự ở 16px (ĐO 04/10: 46rem ra 118, 37rem ra 101); làn tiêu đề nhận phần còn lại ⇒ không mép trống. */
@media (min-width:1000px){
  /* chỉ khi khối khép TOÀN chữ (eyebrow · h2 · đoạn văn) — đúng hình /ke. Khối có h3, hàng nút… (khép /adpilot) giữ
     một cột: lưới hai làn tự xếp những thứ ấy vào ô trống ⇒ rối. Trình duyệt chưa có :has ⇒ một cột (an toàn). */
  .band.khep .wrap:not(:has(> :not(p, h2))){display:grid; grid-template-columns:minmax(0,1fr) minmax(0,34rem); column-gap:clamp(40px,5vw,96px); align-items:start}
  .band.khep .wrap > .eyebrow{grid-column:1; grid-row:1}
  .band.khep .wrap > h2{grid-column:1; grid-row:2 / span 3; max-width:24ch}
  .band.khep .wrap > p:not(.eyebrow){grid-column:2}
  .band.khep .wrap > h2 + p{grid-row:1 / span 2}
}

/* ── Băng LẮNG ở mọi trang (trang chủ 04/10: «tất cả các section phải tôn lên điểm nhấn và nét đó, chứ ⛔ không phải mỗi
   hero») — cùng chữ ký với /ke: vạch teal NGẮN trước nhãn mục · viền teal đỉnh thẻ · dấu đầu dòng teal. Không quầng,
   không chữ chuyển màu (để dành cho khối mở đầu và khối khép). Vạch là ::before nội dòng nên đúng cả khi nhãn căn giữa. */
.band.lang .eyebrow::before{content:""; display:inline-block; width:18px; height:2px; margin-right:10px; vertical-align:middle; background:var(--accent)}
.band.lang :is(.card, .tool){box-shadow:inset 0 3px 0 var(--hieu-cuoi)}
.band.lang li::marker{color:var(--accent)}
/* Dải kêu gọi = khối KHÉP của trang có .band.goi: nền đậm + quầng (MẠNH lại). Quầng trên nền --nen-dam đổi màu
   giữa để đọc được trên nền xanh đậm thay vì --hieu (sát màu nền). */
.band.goi .vung-sang::before{background:linear-gradient(90deg, transparent 5%, color-mix(in srgb, var(--accent) 34%, transparent) 45%, transparent 85%)}
