/* ==========================================================================
   FONT TỰ CHỨA — đặt trong src/assets/fonts/, KHÔNG gọi sang Google Fonts.
   ⚠️ Chỉ khai báo ở đây; việc CHỌN dùng font nào nằm ở ⚙️ Cài đặt chung.
   ⚠️ Ba họ này đủ chữ tiếng Việt (đã kiểm từng dấu). File Inter tải kèm bị BỎ vì nó
   chỉ có 230 ký tự, thiếu chữ có dấu — Inter vẫn lấy bản đầy đủ từ Google Fonts.
   ⚠️ font-display:swap để chữ hiện ngay bằng font dự phòng rồi đổi, thay vì để trống
   một nhịp. Với bài dài thì khoảng trống đó rất khó chịu.
   ========================================================================== */
@font-face{font-family:'HarmonyOS Sans'; src:url('/assets/fonts/HarmonyOS_Sans_Regular.woff2') format('woff2');
  font-weight:400; font-style:normal; font-display:swap;}
@font-face{font-family:'HarmonyOS Sans'; src:url('/assets/fonts/HarmonyOS_Sans_Medium.woff2') format('woff2');
  font-weight:500 700; font-style:normal; font-display:swap;}
@font-face{font-family:'NTH Justice Mist'; src:url('/assets/fonts/cam-nang-nth-justice-mist-regular.woff2') format('woff2');
  font-weight:400; font-style:normal; font-display:swap;}
@font-face{font-family:'NTH Justice Mist'; src:url('/assets/fonts/camnang-nth-justice-mist-bold.woff2') format('woff2');
  font-weight:500 900; font-style:normal; font-display:swap;}
@font-face{font-family:'NTH Justice Valor'; src:url('/assets/fonts/camnang-nth-justice-valor.woff2') format('woff2');
  font-weight:400 900; font-style:normal; font-display:swap;}

:root{
  /* Nền chính lấy tông xám xanh nhạt như menu hai bên của Facebook.
     Khung nội dung để TRẮNG nên tách hẳn khỏi nền — đây là điểm khác so với
     nền kem cũ (#FAF6EC) vốn chỉ tối hơn trắng 3%, mắt gần như không phân biệt. */
  --void:#F2F4F7;
  --void-2:#FFFFFF;
  --void-3:#E4E6EB;
  /* Khung bài viết. Chế độ SÁNG dùng nền trắng cho dễ phối màu chữ.
     ⚠️ 4 biến này đổi theo chế độ tối ở khối html[data-theme="dark"] bên dưới —
     sửa ở đây phải sửa cả bên đó, nếu không chế độ tối sẽ chữ đen trên nền đen. */
  --paper:#FFFFFF;
  /* ⚠️ ĐỪNG quay lại các mã ấm (#E4E1DA cho viền, #F6F4EF cho nền phụ). Chúng lệch
     sang vàng, đặt cạnh nền trắng và nền xám xanh #F2F4F7 thì lộ ra một mảng ngà đục.
     Cả hai giờ dùng đúng mã trung tính của --line và --void, không còn tông kem. */
  --paper-edge:#DADDE1;
  --ink:#1E1B16;
  --ink-soft:#4A463E;
  /* ===== HAI BẬC CHỮ (24/09/2026) =====
     Trước đây chữ THÂN BÀI và dòng NGÀY ĐĂNG / lưu ý / khung Discord dùng CHUNG --ink-soft
     nên luôn trùng màu — người đọc không phân biệt được đâu là nội dung chính, đâu là phụ.
     Tách thành hai vai trò. Đã kiểm WCAG AA (cần >= 4.5:1 cho chữ nhỏ):
       sáng: chính #24211C 16:1 · phụ #6B6F76 5,1:1 (trên #FFFFFF)
       tối : chính #EAE0C8 14:1 · phụ #958C78 5,5:1 (trên #17140F)
     ⚠️ Đừng làm chữ phụ nhạt hơn: #857D6B ở chế độ tối đã trượt dưới 4.5:1. */
  --chu-chinh:#24211C;
  --chu-phu:#6B6F76;
  /* Nền phụ (khối ghi chú, khối hỏi đáp cuối bài): xám trung tính, KHÔNG kem.
     Vẫn giữ nền chứ không để trắng trơn — khối ghi chú nằm trong khung bài vốn đã
     trắng, bỏ nền đi thì nó chìm mất, chỉ còn trơ mỗi vạch màu bên trái. */
  --paper-soft:#F2F4F7;
  --seal:#A83C34;
  --seal-soft:#C15A50;
  --jade:#3F6B5C;
  --gold:#B08D3F;
  /* Đường kẻ và chữ mờ chuyển sang trung tính: giữ tông ấm cũ trên nền xám xanh
     sẽ ra màu ngà đục, nhìn bẩn. ⚠️ Chỉ đổi ở chế độ SÁNG, chế độ tối giữ nguyên. */
  --line:#DADDE1;
  --text-dim:#5C6067;
  --text-dim-2:#80858E;
  --text-main:var(--ink);
  /* ---- Bộ màu tương tác kiểu Facebook ----
     Facebook KHÔNG đổi nền sang trắng khi rê chuột — trắng làm mục menu nhảy vọt lên
     trước nền xám, nhìn như đang được chọn. Họ phủ một lớp đen rất mờ, nên mục chỉ
     sẫm lại một chút. Dùng rgba (không dùng mã màu đặc) để lớp phủ chạy đúng trên
     MỌI nền: nền trang, nền trắng của thẻ, nền xanh của mục đang chọn.
     ⚠️ Đổi --hover-bg sang mã màu đặc là mất tính chất đó, mục trong khung trắng
     sẽ bị viền xám lộ ra. */
  --hover-bg:rgba(0,0,0,0.05);
  /* Mục ĐANG CHỌN — bản 02: nền XÁM + chữ ĐEN ĐẬM + vạch xanh 3px bên trái.
     ⚠️ ĐỪNG quay lại nền xanh + chữ xanh. Chữ xanh #1877F2 trên nền xanh #E7F3FF là
     hai màu cùng họ, độ tương phản tụt xuống rất thấp nên đọc lâu bị mỏi mắt — đó mới
     là nguyên nhân, không phải cái nền. Facebook cũng không dùng viên xanh ở cột trái;
     cột trái của họ chỉ có xám, xanh dành cho liên kết và biểu tượng trên thanh trên.
     Đậm hơn --hover-bg một bậc để mục đang chọn vẫn phân biệt được với mục đang rê chuột. */
  --sel-bg:rgba(0,0,0,0.09);
  --sel-fg:var(--text-main);
  /* Vạch đánh dấu: xanh chỉ còn 3px ở rìa, đủ nhận ra mục đang mở giữa cột dài
     mà không đem màu vào nền hay vào chữ. */
  --sel-bar:#1877F2;
  --fb-blue:#1877F2;
  /* Nền ô nhập (ô tìm kiếm, nút gạt) — Facebook để nền xám đặc, KHÔNG viền. */
  --field-bg:#E4E6EB;
  --field-bg-hover:#D8DADF;
  /* Chiều cao thật của header = padding trên + logo + padding dưới + 1px viền.
     Cột trái sticky và mã neo cuộn tới đều phải trừ đúng con số này, nếu không
     phần trên của chúng chui xuống dưới header.
     ⚠️ Đổi chiều cao logo hoặc padding header thì PHẢI tính lại biến này. */
  --header-h:71px;
  /* Vàng kem #FAF4E7 — dùng RIÊNG cho dòng hỏi đáp Discord ở cuối mỗi bài.
     Đây là màu ẤM DUY NHẤT còn lại trong bố cục, để dành cho đúng MỘT chỗ nên nó mới là
     điểm nhấn. ⚠️ Đừng đem tô cho khối Ghi chú hay khối Bước — chúng xuất hiện nhiều lần
     trong một bài, tô vàng hết thì cả bài loang lổ và điểm nhấn mất tác dụng. */
  --note-bg:#FAF4E7;
  /* Ghi chú phân cấp [r]/[r2]: nền và màu đường kẻ chữ L. Xám nhạt kiểu Facebook. */
  --r-bg:#F2F4F7;
  --r-line:#C4C8CE;
  /* Nhãn khu vực [k]: nền hồng cam rất nhạt, chữ nâu đỏ. */
  /* Độ đậm của nền nhãn khu vực. Màu thì lấy từ chính nhãn, xem .kv. */
  --kv-a:22%;
  /* [k] địa danh KHÔNG thuộc danh sách khu vực (không có trong regionColors.json):
     kiểu biển báo vàng/đen — chữ gần đen trên nền vàng, khác hẳn 17 màu khu vực. */
  /* Nền nhãn [k] (chế độ sáng): độ sáng = l × --kv-Lk + --kv-L0 (màu gốc l .4→.66 ra nền
     .66→.79), độ đục --kv-A. Trước đây pha loãng màu gốc 22% -> xỉn; rồi ép CỐ ĐỊNH L .85
     -> rực nhưng hai sắc cách nhau ~17° (Trích Tiên Đảo/Thương Châu, Đào Khê Thôn/nhãn
     vàng) ra y hệt nhau. Giữ lại một nửa độ đậm nhạt của màu gốc thì tách được (30/09/2026). */
  --kv-Lk:.5;
  --kv-L0:.46;
  --kv-A:.62;
  --kv-Cmin:.13;
  /* Chữ nhãn [k]: ĐEN in đậm cho mọi khu vực — màu riêng chỉ còn ở nền. Chữ màu trên nền
     cùng màu pha loãng kém nổi hơn chữ đen (người dùng so thực tế 30/09/2026). */
  --kv-chu:#1C1E21;
}
/* Nền #F2F4F7 rất nhạt (chỉ tối hơn trắng ~10%) nên riêng màu KHÔNG đủ tách khối.
   Giá trị lấy ĐÚNG từ tab Computed của forum.gamer.com.tw:
       box-shadow: rgba(0,0,0,0.33) 0px 2px 4px 0px
   ⚠️ ĐỘ LỆCH DỌC 2px là phần quan trọng nhất, ĐỪNG đổi về 0. Bóng lệch xuống thì hai
   bên sườn gần như sạch. Nếu dùng quầng toả đều `0 0 Npx`, quầng xám đó bao quanh cả
   phần ẢNH ở đầu thẻ: ảnh tối nên quầng SÁNG hơn ảnh -> mắt đọc là ảnh THỤT VÀO, trong
   khi phần chữ nền trắng thì quầng lại TỐI hơn -> mắt đọc là khối trắng NHÔ RA. Hai
   hiệu ứng ngược nhau trên cùng một thẻ, thành cảm giác ảnh lệch bậc dù đo pixel thì
   hai mép trùng khít.
   ⚠️ CHỈ áp cho chế độ SÁNG: nền tối vốn đã tách rõ, thêm bóng vào chỉ thành vệt bẩn.
   ⚠️ Sửa Ở ĐÂY, đừng khai báo box-shadow trong từng khối — quy tắc gộp này có độ ưu
   tiên cao hơn nên sẽ đè mất, sửa mãi không thấy đổi. */
html:not([data-theme="dark"]) .article-card,
html:not([data-theme="dark"]) .post-paper{
  box-shadow:0 2px 4px rgba(0,0,0,0.33);
}
/* Ghi chú lịch sử: trước đây `aside.side-right > *` là <div> TRẦN không nền không viền,
   nên bóng đổ vẽ ra viền mờ bao quanh khoảng trống — đóng khung từng mục vô cớ.
   Đã thử nền trắng + bóng, rồi thử viền mờ, BỎ CẢ HAI: đóng khung mục điều hướng làm cột
   phải nặng hơn hẳn cột trái. Nay chúng trần hoàn toàn, chỉ .discord-card và .donate-mini
   có nền trắng vì đó là nội dung bổ sung.
   ⚠️ ĐỪNG đưa `aside.side-right > *` vào quy tắc bóng ở trên. */
html:not([data-theme="dark"]) .article-card:hover{
  box-shadow:0 4px 8px rgba(0,0,0,0.38);
}

html[data-theme="dark"]{
  --void:#0F0D0B;
  --void-2:#171411;
  --void-3:#1B1815;
  --line:#332C22;
  --text-dim:#A79A7B;
  --text-dim-2:#8B8168;
  /* ⚠️ Đặt màu THẲNG, KHÔNG dùng var(--paper): chế độ tối đổi --paper thành nền tối,
     lấy nó làm màu chữ là chữ tối trên nền tối, không đọc được. */
  --text-main:#EDE3CC;
  /* Khung bài ở chế độ tối: nền tối, chữ sáng, viền theo tông chung */
  --paper:#17140F;
  --paper-edge:#332C22;
  --ink:#EDE3CC;
  --ink-soft:#C7BCA0;
  --chu-chinh:#EAE0C8;
  --chu-phu:#958C78;
  --paper-soft:#1F1B15;
  /* Nền tối thì lớp phủ phải là TRẮNG mờ; phủ đen lên nền đen là không thấy gì. */
  --hover-bg:rgba(255,255,255,0.08);
  --sel-bg:rgba(255,255,255,0.14);
  --sel-fg:var(--text-main);
  --sel-bar:#4A9BFF;
  --fb-blue:#4A9BFF;
  --field-bg:#1B1815;
  --field-bg-hover:#241F1A;
  /* Nền tối thì kem đặc sẽ chói; dùng lớp phủ vàng rất mờ để vẫn ra sắc ấm. */
  --note-bg:rgba(217,166,72,0.10);
  /* Nền tối vốn đã tách rõ khỏi dải, giữ đúng màu nền trang là đẹp. */
  --crumb-bg:var(--void);
  --r-bg:rgba(255,255,255,0.05);
  --r-line:#4A443A;
  --kv-a:32%;
  /* Nền tối: nhãn [k] dùng ĐÚNG màu khu vực trong regionColors.json làm nền (xem quy tắc
     html[data-theme="dark"] .kv ở phần nhãn khu vực), không qua công thức oklch. Đã thử
     tông pha (.6/.42 ra màu bùn; .5/.62 kiểu đá quý) — người dùng chốt 30/09/2026 giữ
     nguyên màu khu vực. Chữ gần trắng vì nền đặc màu trung bình. */
  --kv-chu:#F2EDE2;
}
*{box-sizing:border-box; margin:0; padding:0;}
html{scroll-behavior:smooth;}
body{
  /* Hai lớp phủ ấm cũ làm nền xám xanh ngả sang hồng/vàng -> giảm còn rất nhẹ,
     đủ để nền không phẳng lì mà không phá tông. */
  background:
    radial-gradient(900px 500px at 10% -10%, rgba(160,60,52,0.025), transparent 60%),
    radial-gradient(700px 400px at 100% 0%, rgba(63,107,92,0.025), transparent 55%),
    var(--void);
  color:var(--text-main);
  /* ⚠️ Dùng BIẾN, đừng ghi thẳng tên font. Phần Cài đặt chung trong /admin ghi đè biến này
     để đổi font toàn trang mà không phải sửa CSS. Xem mục Font chữ trong README. */
  font-family:var(--font-body, 'Inter'), sans-serif;
  min-height:100vh;
}
.serif{font-family:var(--font-title, 'Noto Serif'), serif;}
.mono{font-family:'JetBrains Mono', monospace;}
a{color:inherit; text-decoration:none;}
button{font-family:inherit; cursor:pointer;}
ul{list-style:none;}
img{max-width:100%; display:block;}
/* Ảnh CHÈN TRONG BÀI nằm cùng dòng với chữ, chỉ xuống dòng khi người viết tự xuống.
   Quy tắc img{display:block} ở trên vẫn giữ cho ảnh bìa, thumbnail, logo... vì chúng
   có quy tắc riêng đè lên. Icon vật phẩm nhỏ giờ đứng cạnh chữ được. */
.article-body img{display:inline-block; vertical-align:middle; margin:0 3px;}

/* ---------- PHÓNG TO ẢNH ----------
   Con trỏ kính lúp báo cho người đọc biết bấm được. ⚠️ Loại trừ ảnh TRANG TRÍ
   (icon danh mục, emoji tiêu đề) — phải khớp với danh sách loại trừ trong base.njk. */
.article-body img:not(.cat-ref-icon):not(.title-emoji){cursor:zoom-in;}
.img-zoom{
  position:fixed; inset:0; z-index:200; display:none;
  align-items:center; justify-content:center; padding:28px;
  background:rgba(0,0,0,0.88);
}
.img-zoom.open{display:flex;}
/* width/height:auto để ảnh giữ ĐÚNG tỉ lệ gốc; hai max- chỉ chặn tràn màn hình. */
.img-zoom img{max-width:100%; max-height:100%; width:auto; height:auto; border-radius:4px; cursor:zoom-out;}
.img-zoom .zoom-close{
  position:absolute; top:10px; right:14px; padding:8px 12px;
  background:none; border:none; color:#fff; font-size:28px; line-height:1; cursor:pointer;
}
.img-zoom .zoom-cap{
  position:absolute; left:0; right:0; bottom:12px; margin:0;
  text-align:center; color:#E4E6EB; font-size:13px; padding:0 28px;
}

/* ---------- HEADER ---------- */
/* Padding 5px + logo 60px + 5px + 1px viền = 71px, ĐÚNG BẰNG chiều cao header cũ
   (13 + 44 + 13 + 1). Nhờ vậy logo to thêm 36% mà không đẩy nội dung trang xuống,
   không phải chỉnh lại vị trí sticky của cột trái.
   ⚠️ Đổi một trong hai số này thì phải cập nhật --header-h ở :root. */
header{
  position:sticky; top:0; z-index:50;
  padding:5px 0;
  border-bottom:1px solid var(--line);
  background:var(--void);
  backdrop-filter:blur(8px);
}
.header-inner{
  max-width:1400px; margin:0 auto; padding:0 24px;
  display:grid; grid-template-columns:230px minmax(0,1fr) 300px; gap:0;
  align-items:center;
}
@media(max-width:1180px){ .header-inner{grid-template-columns:210px minmax(0,1fr) 260px;} }
@media(max-width:980px){ .header-inner{grid-template-columns:auto 1fr auto; padding:0 16px; gap:16px;} }
/* Logo nhỏ lại ở màn hình hẹp -> header thấp đi -> phải khai báo lại --header-h,
   nếu không menu điện thoại sẽ hở một dải trống ngay dưới header. */
@media(max-width:1180px){ :root{--header-h:65px;} }
@media(max-width:980px){ :root{--header-h:55px;} }
/* Lề phải thu từ 16px còn 8px và lề trái từ 16px còn 10px: cột logo rộng 230px mà
   logo chỉ 124px thì thừa gần 80px, nhìn như logo bị lệch vào một góc. */
.header-inner .brand{margin-right:8px;}
/* ⚠️ padding-right 20px BẰNG padding ngang của aside.side-right — nhờ vậy số phiên bản
   thẳng lề phải với khối NỔI BẬT ngay bên dưới. Đổi padding của cột phải thì đổi luôn ở đây. */
/* Máy tính: VIỀN khung Sáng/Tối (.nth-seg) trùng viền ngoài khối sidebar (yêu cầu 30/09/2026).
   Hai bước: padding-right 0 ở cụm này, và margin-right -10px ở header .nth-theme (bên dưới) để bù
   đệm trong suốt 10px của nút. ⚠️ Đo mép .nth-seg (phần có viền), KHÔNG đo mép nút .nth-theme —
   đo nhầm nút là lệch đúng 10px, lỗi đã gặp. Điện thoại giữ 12px như cũ. */
.header-actions{display:flex; align-items:center; gap:10px; justify-self:end; padding-right:12px;}
@media(min-width:981px){ .header-actions{padding-right:0;} header .nth-theme{margin-right:-10px;} }
/* ⚠️ Ghi thẳng font Inter, KHÔNG dùng var(--font-body) — người dùng có thể đổi font nội dung
   sang font viết tay, còn cụm điều khiển này phải luôn là font thường. */
.hd-patch, .hd-fb{font-family:'Inter', sans-serif; font-size:13.5px; white-space:nowrap; color:var(--text-dim-2);}
.hd-fb{text-decoration:none; transition:color .12s; padding-right:10px; border-right:1px solid var(--line); line-height:1.1;}
.hd-fb:hover{color:#1877F2;}
html[data-theme="dark"] .hd-fb:hover{color:#5AA2FF;}
/* ⚠️ Màn hình hẹp giấu số phiên bản nhưng GIỮ nút Light/Dark — đó là nút duy nhất để đổi
   giao diện, giấu nốt thì trên điện thoại không còn cách nào. */
@media(max-width:980px){ .hd-patch, .hd-fb{display:none;} .header-actions{gap:8px;} .nth-opt{padding:4px 7px;} }
.brand{display:flex; align-items:center; gap:12px; padding-left:10px; min-width:0;}
@media(max-width:980px){ .brand{padding-left:0;} }
/* Logo cao 60px -> rộng ~170px (ảnh 840x297, tỉ lệ 2.83), lấp gần kín 212px còn lại
   của cột. max-width:100% giữ cho logo tỉ lệ khác không bao giờ tràn sang ô tìm kiếm.
   ⚠️ Thay ảnh logo có tỉ lệ khác thì chiều rộng tự đổi theo — muốn cân lại thì chỉnh
   height ở đây, ĐỪNG đặt width cứng (ảnh sẽ méo). */
.brand-logo{height:60px; width:auto; max-width:100%; display:block; object-fit:contain;}
@media(max-width:1180px){ .brand-logo{height:54px;} }
@media(max-width:980px){ .brand-logo{height:44px;} }
/* ⚠️ padding PHẢI bằng padding ngang của main.content-main (32px). Thanh tìm kiếm nằm
   cùng cột lưới với phần nội dung, nhưng cột nội dung có đệm 32px còn thanh này thì
   không — nên hai đầu thanh lố ra đúng 32px mỗi bên so với khung bài và lưới thẻ.
   Đổi padding của main.content-main thì PHẢI đổi luôn ở đây. */
.header-search-wrap{position:relative; display:none; padding:0 32px;}
@media(min-width:981px){.header-search-wrap{display:block;}}
/* Facebook: ô tìm kiếm là một viên thuốc nền xám ĐẶC, KHÔNG viền. Viền + nền trắng
   như cũ tạo ra hai đường kẻ (viền ô và mép nền) nằm sát nhau, nhìn rối.
   border trong suốt chứ không bỏ hẳn — bỏ hẳn thì ô co lại 2px khi rê chuột. */
.header-search{display:flex; align-items:center; gap:8px; background:var(--field-bg); border:1px solid transparent; border-radius:10px; padding:8px 16px; width:100%; color:var(--text-dim-2); font-size:13px; transition:background 0.12s;}
.header-search:hover{background:var(--field-bg-hover);}
.header-search:focus-within{background:var(--void-2); border-color:var(--fb-blue);}
.header-search input{background:none; border:none; outline:none; color:var(--text-main); font-size:13px; flex:1; font-family:'Inter',sans-serif;}
@media(max-width:980px){.header-search input{font-size:16px;}}
.header-search input::placeholder{color:var(--text-dim-2);}
.search-results{
  display:none; position:absolute; top:calc(100% + 8px); left:0; right:0;
  background:var(--void-2); border:1px solid var(--line); border-radius:8px;
  max-height:360px; overflow-y:auto; z-index:60;
  /* Bóng cũ (đen 60%) vốn tính cho nền tối; trên nền sáng nó thành một vũng đen.
     Facebook dùng bóng loang rộng và rất mờ. Chế độ tối lấy lại bóng đậm bên dưới. */
  box-shadow:0 12px 28px rgba(0,0,0,0.12), 0 2px 4px rgba(0,0,0,0.08);
}
html[data-theme="dark"] .search-results{box-shadow:0 16px 40px -12px rgba(0,0,0,0.7);}
.search-results.open{display:block;}
.search-item{display:flex; flex-direction:column; gap:2px; padding:10px 14px; border-bottom:1px solid var(--line);}
.search-item:last-child{border-bottom:none;}
.search-item:hover{background:var(--hover-bg);}
/* KHÔNG dùng flex ở đây: emoji nằm xen giữa dòng chữ, mà flex sẽ cắt mỗi mẩu chữ
   thành một ô riêng rồi chèn khoảng cách vào giữa. Để chảy tự nhiên như chữ thường. */
.search-item-title{font-size:13px; color:var(--text-main); font-weight:600; overflow-wrap:anywhere;}
.search-item-title strong{font-weight:700;}
/* ⚠️ currentColor chứ KHÔNG phải var(--seal). Gạch chân phải lấy MÀU CỦA CHÍNH ĐOẠN CHỮ
   nó nằm dưới; ép cứng màu triện thì "Lan Dạ Lưu Ba" chữ cam mà gạch chân lại đỏ. */
.search-item-title u{text-decoration:underline; text-decoration-color:currentColor; text-decoration-color:color-mix(in srgb, currentColor 72%, transparent); text-decoration-thickness:1px; text-underline-offset:3px;}
/* Dấu gạch ngang ngăn từ khoá với tiêu đề — màu xám mờ để không tranh chỗ với hai bên. */
.search-item-dash{color:var(--text-dim-2); font-weight:400;}
.search-item-emoji{height:1.1em; width:auto; max-width:2.2em; object-fit:contain;
  display:inline-block; vertical-align:-0.16em; margin-right:0.12em;}
.search-item-meta{font-family:'JetBrains Mono', monospace; font-size:10.5px; color:var(--text-dim-2);}
.search-empty{padding:14px; font-size:12.5px; color:var(--text-dim-2); text-align:center;}

/* ⚠️ display:none LÀ MẶC ĐỊNH — nút ba gạch CHỈ hiện ở màn hình ≤980px (xem media query
   ngay dưới). Thiếu dòng này thì nút hiện cả trên máy tính, bấm vào là menu điện thoại
   bung ra giữa giao diện rộng. Đã mất một lần khi viết lại khối CSS bên trên, rất khó
   nhận ra vì không có lỗi cú pháp nào. */
.hamburger{display:none; flex-direction:column; gap:5px; background:none; border:none; padding:6px;}
.hamburger span{width:22px; height:2px; background:var(--paper); display:block;}
@media(max-width:980px){.hamburger{display:flex;}}

.mobile-menu{display:none; position:fixed; inset:0; top:var(--header-h); z-index:49; background:var(--void); padding:16px; flex-direction:column; gap:6px; overflow-y:auto;}
.mobile-menu.open{display:flex;}
.mobile-menu .mobile-search-wrap{position:relative; width:100%;}
.mobile-menu .mobile-search{width:100%;}

.home-mobile-search-wrap{display:none; position:relative; margin-bottom:20px;}
.home-mobile-search{width:100%;}
@media(max-width:980px){.home-mobile-search-wrap{display:block;}}
.mobile-menu .m-home{padding:12px 10px; border-bottom:1px solid var(--line); font-size:15px; color:var(--text-main); font-weight:600; margin-top:4px;}
.m-category-grid{display:grid; grid-template-columns:1fr 1fr; gap:6px; margin-bottom:8px;}
.m-category-grid a{
  display:flex; justify-content:space-between; align-items:center;
  padding:11px 12px; background:var(--void-2); border-radius:8px;
  font-size:13px; color:var(--text-dim);
}
.mobile-menu .m-donate{
  display:block; text-align:center; margin-top:8px; padding:13px;
  background:var(--seal); color:var(--paper); font-weight:700; font-size:14px; border-radius:8px;
}

/* ---------- BREADCRUMB ---------- */
/* ==========================================================================
   DẢI ĐƯỜNG DẪN + NÚT SÁNG/TỐI
   ┌── BỐN SỐ DƯỚI ĐÂY LÀ CHỖ DUY NHẤT CẦN SỬA khi muốn chỉnh cỡ ────────────┐
   │  --crumb-size   : cỡ chữ đường dẫn                                      │
   │  --crumb-btn    : cỡ chữ nút Sáng/Tối                                   │
   │  --crumb-pad    : đệm TRÊN-DƯỚI của nút -> quyết định CHIỀU CAO cả dải  │
   │  --crumb-icon   : cỡ hình mặt trời / mặt trăng                          │
   │  --crumb-gap    : khoảng cách giữa hình và chữ Sáng/Tối                  │
   │  --crumb-bg     : màu nền của dải (chế độ SÁNG)                          │
   └─────────────────────────────────────────────────────────────────────────┘
   ⚠️ Chiều cao dải KHÔNG đặt trực tiếp — nó bằng chiều cao của nút, mà nút thì cao theo
   --crumb-pad. Làm vậy để nền lúc rê chuột luôn CHẠM SÁT hai đường kẻ trên dưới, không
   bao giờ hở ra một vệt trắng. Muốn dải cao hơn thì tăng --crumb-pad.
   ========================================================================== */
:root{
  --crumb-size:13px;
  --crumb-btn:18px;
  --crumb-pad:5px;
  --crumb-icon:22px;
  --crumb-gap:3px;
  /* ⚠️ ĐẬM HƠN --void (#F2F4F7) một bậc. Để trùng màu nền trang thì dải chìm hẳn,
     chỉ còn trơ một đường kẻ, không ra hình một thanh. Đừng đậm quá 2-3 bậc: dải này
     là thứ phụ, đậm bằng thẻ bài thì nó tranh chỗ với nội dung chính. */
  --crumb-bg:#E7EAEF;
}
.crumb-bar{border-bottom:1px solid var(--line); background:var(--crumb-bg);}
/* ⚠️ Lưới PHẢI khớp .page từng con số. Nhờ vậy nút rơi đúng cột thứ ba và mép TRÁI của
   vùng nền thẳng hàng với đường kẻ dọc của cột phải. Đổi lưới .page thì đổi luôn ở đây. */
.crumb-inner{
  /* ⚠️ Đệm dọc lấy từ --crumb-pad. Trước đây chiều cao dải do nút Light/Dark quyết
     định nên để 0; nút đã dời lên thanh đầu trang, không còn gì chống đỡ nữa. */
  max-width:1400px; margin:0 auto; padding:var(--crumb-pad) 24px;
  display:grid; grid-template-columns:230px minmax(0,1fr) 300px; align-items:center;
}
@media(max-width:1180px){ .crumb-inner{grid-template-columns:210px minmax(0,1fr) 260px;} }
/* ⚠️ padding-left 24px = .side-left(16px) + .menu-heading(8px). Cột trái có HAI lớp đệm
   cộng dồn, còn dải đường dẫn chỉ có đệm của .crumb-inner — thiếu dòng này thì chữ
   "Trang chủ" bắt đầu ở 24px trong khi biểu tượng nhà ngay bên dưới ở 48px, lệch hẳn 24px.
   ⚠️ Đổi padding của .side-left hoặc .menu-heading thì PHẢI tính lại con số này. */
.breadcrumb{
  grid-column:1 / 3; padding-left:24px;
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  font-family:'JetBrains Mono', monospace; font-size:var(--crumb-size); color:var(--text-dim-2);
}

/* ---------- NÚT SÁNG / TỐI ----------
   Một kiểu dùng cho CẢ HAI chỗ: thanh đầu trang và dải đường dẫn.
   ⚠️ Ghi thẳng font Inter, KHÔNG dùng var(--font-body). Người dùng có thể đổi font nội dung
   sang font viết tay trong ⚙️ Cài đặt — nút giao diện phải luôn là font thường. */
/* ⚠️ padding:0 — KHÔNG đệm quanh nút. Bản thân hai ô màu đã là vùng bấm rồi; để đệm thì
   ô màu bị đẩy vào trong, không thẳng lề với đường kẻ dọc của cột phải.
   ⚠️ Đã BỎ hover đổi nền: cụm này đã trông rõ là nút bấm nhờ hai ô màu, thêm nền lúc rê
   chuột chỉ làm rối. */
.nth-theme{
  display:inline-flex; align-items:stretch;
  background:none; border:none; cursor:pointer; padding:0;
  color:var(--text-dim);
}
/* ---------- BỘ CHỌN SÁNG/TỐI (kiểu Theme Switcher của Chrome Labs) ----------
   ⚠️ HAI lựa chọn hiện cùng lúc, cái ĐANG DÙNG được tô nền màu. Cả cụm là MỘT nút, bấm
   đâu cũng đảo chế độ — không cần thêm hàm JS nào.
   ⚠️ Việc tô nền do CSS đọc data-theme, KHÔNG do JS. Để JS tô thì lúc trang mới tải sẽ
   nháy một nhịp ở ô sai trước khi nhảy sang ô đúng. */
/* ⚠️ KHÔNG bo góc: hai ô màu phải chạm sát hai đường kẻ trên dưới của dải, giống cách
   vùng nền lúc rê chuột từng làm. Bo góc thì nó co lại thành viên thuốc lửng lơ. */
/* ⚠️ Rãnh có VIỀN 1px và đệm 2px, ô bên trong bo góc 6px — KHÔNG dùng overflow:hidden để
   cắt ô màu. Cắt kiểu đó thì ô đang chọn chỉ tròn ở mép ngoài còn mép trong phẳng lì, nhìn
   như nó đè lên ô kia. Đây là lỗi đã gặp thật.
   ⚠️ BA số phải ăn khớp: rãnh bo 8px = đệm 2px + ô bo 6px. Đổi một số thì tính lại hai số
   kia, lệch là đường cong trong và ngoài không song song, lộ ra vệt hở ở bốn góc. */
.nth-seg{
  display:inline-flex; align-items:stretch;
  border-radius:8px; padding:2px; border:1px solid var(--line);
  background:var(--field-bg);
}
/* ⚠️ CHỈ CÒN HÌNH, không có chữ. gap:0 vì không còn gì để cách. */
.nth-opt{
  display:inline-flex; align-items:center; gap:0;
  padding:4px 8px; border-radius:6px;
  color:var(--text-dim-2); transition:background 0.15s, color 0.15s;
}
.nth-opt svg{width:15px; height:15px; flex-shrink:0;}
/* ⚠️ Nền vàng ấm cho Sáng, xanh lam cho Tối — tự nó nói lên chế độ, không phải đọc chữ.
   Bản mẫu của Chrome Labs dùng đỏ cho Sáng; ở đây đổi sang vàng vì đỏ đã là màu tiêu đề
   bài viết, dùng lại sẽ lẫn. */
html:not([data-theme="dark"]) .nth-opt-sang{background:#F5D06A; color:#4A3410;}
html[data-theme="dark"] .nth-opt-toi{background:#2D5FA8; color:#EAF1FB;}
/* ⚠️ KHÔNG bo góc. Vùng nền lúc rê chuột phải là một khối vuông chạm sát hai đường kẻ,
   giống mozilla.org — bo góc thì nó co lại thành một viên thuốc lửng lơ giữa dải. */
.nth-theme{border-radius:0;}
/* Hai hình nằm sẵn trong SVG, CSS chỉ ẩn hiện; nét ăn theo currentColor. */
.nth-theme-icon .ic-moon{display:none;}
html[data-theme="dark"] .nth-theme-icon .ic-sun{display:none;}
html[data-theme="dark"] .nth-theme-icon .ic-moon{display:block;}
/* ⚠️ Nút trên thanh đầu trang thì bo góc nhẹ, vì ở đó nó KHÔNG nằm trong một dải có đường
   kẻ, để vuông sẽ trông như bị cắt cụt. */
header .nth-theme{border-radius:6px; padding:6px 10px;}
/* ⚠️ Ẩn nút ở thanh đầu trang khi trang đó ĐÃ có dải đường dẫn — tránh hai nút cùng chức
   năng. Trang chủ không có dải này nên vẫn giữ nút ở thanh đầu. */
/* Nút ở thanh đầu trang đã gỡ hẳn — dải đường dẫn nay hiện ở mọi trang nên chỉ cần
   một nút duy nhất, vị trí không đổi giữa các trang. */
@media(max-width:980px){
  .crumb-inner{grid-template-columns:minmax(0,1fr) auto; padding:0 16px;}
  /* Màn hình hẹp thì cột trái ẩn đi, không còn gì để canh theo -> bỏ đệm. */
  .breadcrumb{grid-column:1; padding-left:0;}
}
@media(max-width:640px){ .nth-theme{padding:var(--crumb-pad) 9px;} }
.breadcrumb a{color:var(--gold);}
.breadcrumb a:hover{color:var(--seal-soft);}
.breadcrumb .sep{color:var(--line);}
.breadcrumb .current{color:var(--text-dim); max-width:280px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;}

/* ---------- 3 CỘT ---------- */
.page{max-width:1400px; margin:0 auto; padding:0 24px; display:grid; grid-template-columns:230px minmax(0,1fr) 300px; gap:0; align-items:start;}
@media(max-width:1180px){ .page{grid-template-columns:210px minmax(0,1fr) 260px;} }
@media(max-width:980px){ .page{grid-template-columns:1fr; padding:0 16px 60px;} .side-left{display:none;} }
/* ⚠️ display:flex PHẢI nằm trong media query min-width, KHÔNG được để ở quy tắc gốc.
   Dòng ẩn menu trên điện thoại (.side-left{display:none}) nằm TRƯỚC quy tắc này trong file,
   nên để display:flex ở quy tắc gốc là đè mất nó -> menu trái chiếm chỗ, vỡ toàn bộ
   giao diện điện thoại. Đã xảy ra một lần rồi. */
@media(min-width:981px){ .side-left{display:flex; flex-direction:column;} }

.side-left{
  position:sticky; top:var(--header-h); height:calc(100vh - var(--header-h)); border-right:1px solid var(--line); padding:24px 16px; overflow-y:auto;
  /* ⚠️ Lấn sang lề trái của .page 16px (margin âm + đệm bù bằng nhau): chữ đứng yên chỗ cũ,
     nhưng khung rộng thêm về bên trái. Khung này có thanh cuộn nên CẮT mọi thứ tràn ra ngoài
     mép nó — trước đây hoa văn mục đang chọn chỉ cách mép 3px, quầng sáng ~12px bị chặt
     thẳng thành cạnh VUÔNG (người dùng chụp lại, 24/09/2026). Giờ có 19px để quầng tỏa.
     Làm được vì .side-left KHÔNG có nền riêng và .page có sẵn lề 24px. Thêm nền cho cột trái
     thì nền sẽ lòi ra 16px bên trái — lúc đó phải tính lại. */
  margin-left:-16px; padding-left:32px;
  scrollbar-width:none; -ms-overflow-style:none;
}
.side-left::-webkit-scrollbar{display:none;}
/* Tiêu đề nhóm. ⚠️ ĐỪNG dùng var(--gold) với letter-spacing lớn ở đây.
   Vàng nhạt trên nền sáng đã khó đọc, cộng thêm chữ giãn 0.15em và cỡ 10.5px thì mắt
   phải ghép từng chữ cái một -> đọc lâu rất mỏi. Facebook để nhãn nhóm ở cột trái là
   chữ xám đậm, in đậm, cỡ vừa, không giãn — nặng nét nhưng nhạt màu, nên nó phân
   nhóm được mà không tranh chỗ với các mục bên dưới.
   Bỏ luôn font monospace: dùng cho nhãn tiếng Việt có dấu thì dấu bị chen chúc. */
.menu-heading{
  display:flex; align-items:center; gap:8px;
  font-size:12px; letter-spacing:0.02em; text-transform:uppercase;
  color:var(--text-dim); font-weight:700; margin:20px 0 8px; padding:0 8px;
}
.menu-heading::after{content:''; flex:1; height:1px; background:var(--line);}
.menu-heading:first-child{margin-top:0;}
/* ---------- BIỂU TƯỢNG NHÀ thay cho chữ "DANH MỤC" ----------
   ⚠️ Vẫn mang class .menu-heading nên nó giữ nguyên đường kẻ ngang và khoảng cách của một
   tiêu đề nhóm — chỉ đổi phần chữ thành hình. Bỏ class đó đi là lệch hết nhịp cột trái. */
.mh-home{color:var(--text-dim); padding:0 8px; text-decoration:none; transition:color 0.12s;}
.mh-home:hover{color:var(--text-main);}
.mh-home-icon{width:19px; height:19px; flex-shrink:0;}
/* ⚠️ Ảnh biểu tượng phải CÙNG CỠ với hình vẽ dự phòng, nếu không lúc người dùng tải ảnh
   lên là cả hàng menu nhảy cao thấp. object-fit:contain giữ nguyên tỉ lệ ảnh gốc. */
.mh-home-img{width:19px; height:19px; flex-shrink:0; object-fit:contain;}
.mh-home-text{font-size:12px; font-weight:700; letter-spacing:0.02em; text-transform:uppercase;}
/* Đang ở trang chủ thì tô đậm để biết mình đang đứng đâu. */
.mh-home[aria-current="page"]{color:var(--sel-fg);}
.mh-home[aria-current="page"] .mh-home-icon{stroke-width:2.3;}
/* ⚠️ padding DỌC 6px chứ không phải 9px: dải nền khi rê chuột / khi được chọn chính là
   ô này, 9px làm nó cao 37px trong khi chữ chỉ 19px — nhìn như một thanh chắn.
   6px cho ra 31px, chỉ nhỉnh hơn chữ một chút, đúng kiểu Discord.
   margin-bottom tăng 2px -> 3px để tổng nhịp của danh sách không bị co lại quá. */
.menu-list a{display:flex; align-items:center; justify-content:space-between; padding:6px 10px; border-radius:6px; font-size:13.5px; color:var(--text-dim); margin-bottom:3px;}
/* Biểu tượng menu do người dùng tự tải qua /admin. Chưa tải thì thẻ <img> không được
   sinh ra, mục menu chỉ còn chữ — không để lại khoảng trống. */
.menu-icon{width:18px; height:18px; object-fit:contain; flex-shrink:0; display:block;}
/* Bọc icon + chữ thành một khối, vì .menu-list a dùng space-between để đẩy số bài sang phải */
.menu-label{display:flex; align-items:center; gap:7px; min-width:0;}
.m-home .menu-icon{display:inline-block; vertical-align:-3px; margin-right:7px;}
.region-submenu .menu-icon{width:15px; height:15px;}
/* ⚠️ ĐỪNG quay lại background:var(--void-2) — đó là màu TRẮNG. Trên nền xám xanh
   #F2F4F7 thì trắng sáng hơn nền, mục đang rê chuột nổi bật hơn cả mục đang chọn,
   nhìn như bấm nhầm. Facebook phủ đen 5% để mục chỉ sẫm lại một chút. */
.menu-list a:hover{background:var(--hover-bg); color:var(--text-main);}
/* box-shadow inset thay cho border-left: border làm chữ xê dịch 3px khi được chọn,
   inset vẽ đè lên trong lòng ô nên chữ đứng yên. Bo góc trái phải bằng 0 để vạch
   chạm sát mép trên và mép dưới, không bị bo tròn cụt hai đầu. */
/* Menu không còn style nội tuyến màu danh mục (bỏ 23/09/2026) nên bỏ luôn !important ở đây —
   trước đây nó BẮT BUỘC để mục đang chọn không giữ màu danh mục trên nền xám đậm.
   ⚠️ Nếu có ngày tô màu menu lại thì phải trả !important về, không thì lỗi cũ quay lại. */
.menu-list a.active{
  background:var(--sel-bg); color:var(--sel-fg); font-weight:600;
  box-shadow:inset 3px 0 0 var(--sel-bar); border-radius:0 6px 6px 0;}
/* Mục đang chọn rê chuột vào vẫn sẫm thêm được, vì --hover-bg là lớp phủ trong suốt
   nên nó chồng lên nền xám sẵn có chứ không xoá mất. */
.menu-list a.active:hover{background:var(--sel-bg); color:var(--sel-fg);}
.menu-list a .count{font-family:'JetBrains Mono', monospace; font-size:10px; color:var(--text-dim-2);}
.menu-list a.active .count{color:var(--text-dim);}

main.content-main{min-width:0; padding:24px 32px;}
@media(max-width:980px){ main.content-main{padding:20px 0;} }

.section-head{display:flex; align-items:baseline; justify-content:space-between; margin-bottom:16px; border-bottom:1px solid var(--line); padding-bottom:12px;}
.section-head h2, .section-head h3, .section-head .section-h1{font-family:'Noto Serif', serif; font-size:20px; font-weight:700;}
.section-head .section-h1{margin:0;}
.section-head .see-all{font-family:'JetBrains Mono', monospace; font-size:11px; color:var(--jade);}

/* ---------- THẺ BÀI VIẾT ---------- */
/* stretch để các thẻ cùng hàng cao bằng nhau; chân thẻ đã có margin-top:auto nên
   khoảng dư dồn xuống dưới mô tả, KHÔNG chen vào giữa tiêu đề và mô tả. */
.article-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:14px; align-items:stretch;}
/* ⚠️ min-width:0 là BẮT BUỘC. Ô lưới mặc định rộng tối thiểu bằng nội dung dài nhất,
   nên một từ dài không dấu cách (tên nhiệm vụ gõ nhầm, đường dẫn...) sẽ đẩy phình cả
   cột và vỡ toàn bộ hàng. Đặt 0 để ô lưới tôn trọng bề rộng cột. */
.article-grid > *{min-width:0;}
@media(max-width:1180px){.article-grid{grid-template-columns:repeat(2,1fr);}}
@media(max-width:640px){.article-grid{grid-template-columns:1fr;}}
/* ⚠️ KHÔNG viền. Viền vẽ ra một đường khép kín quanh thẻ, nên mọi sai lệch nhỏ bên trong
   (mép ảnh so với mép thẻ, khoảng đệm hai bên) đều được đem ra so với đường đó và lộ hết.
   Bỏ viền thì bóng lo việc tách thẻ khỏi nền, mắt không còn đường chuẩn để soi. */
.article-card{background:var(--void-2); border:none; border-radius:8px; padding:16px; display:flex; flex-direction:column; gap:6px; min-width:0; transition:box-shadow 0.2s, transform 0.15s;}
.article-card:not(.featured){min-height:300px; height:100%;}
/* Thẻ không còn viền nên hover báo bằng nhấc lên 2px + đậm bóng (khai báo ở đầu file).
   ⚠️ ĐỪNG quay lại đổi border-color trên hover — không còn viền nào ở đó cả.
   ⚠️ Cũng ĐỪNG tô viền vàng: vàng là màu duy nhất trên thẻ nên nó hút mắt như một
   cảnh báo, trong khi đây chỉ là trạng thái rê chuột. */
.article-card:hover{transform:translateY(-2px);}
/* Thẻ nổi bật NẰM NGANG hết hàng: ảnh 3:2 bên trái, chữ bên phải.
   Chiếm trọn 3 ô lưới -> FEATURED_SLOTS trong .eleventy.js phải để 3.
   Vì sao không để nó chiếm 2 cột: thẻ đứng 2 cột cao hơn hẳn thẻ thường bên cạnh,
   hàng đó bị hụt một mảng trống to. Nằm ngang hết hàng thì không bao giờ hụt.
   Ảnh vẫn dùng chung .art-thumb 3:2 với thẻ thường, không có ô vuông riêng. */
.article-card.featured{
  align-self:start;
  grid-column:1 / -1; flex-direction:row; align-items:stretch;
  gap:0; padding:0; overflow:hidden;
  /* KHOÁ chiều cao thẻ theo đúng tỉ lệ ảnh: 3.57 = (3/2) ÷ 0.42.
     Ô ảnh rộng 42% và cao 100% thẻ -> tỉ lệ ảnh ra đúng 3:2, không cắt.
     Vì sao phải khoá: nếu để chiều cao chạy theo cột chữ thì cột nào cao hơn quyết định,
     chữ dài hơn ảnh là thừa một khoảng dưới ảnh, ảnh dài hơn chữ là thừa dưới chữ.
     ⚠️ Đổi 42% hoặc đổi tỉ lệ ảnh thì phải tính lại con số 3.57 cho khớp. */
  aspect-ratio:3.57;
}
.article-card.featured .art-thumb{
  width:42%; height:100%; aspect-ratio:auto; flex-shrink:0;
  margin:0; border-radius:0; border-bottom:0; border-right:1px solid var(--line);
}
.article-card.featured .feat-body{
  display:flex; flex-direction:column; justify-content:center;
  padding:18px 20px; min-width:0; flex:1; overflow:hidden;
}
/* ⚠️ KHOÁ CỨNG TỈ LỆ 3:2 Ở MỌI BỀ RỘNG MÀN HÌNH.
   Trước đây dùng height:150px cố định + bề rộng co giãn -> tỉ lệ ô ảnh nhảy từ 1.32 đến 2.85
   tuỳ cửa sổ người đọc, nên cùng một ảnh lúc bị cắt hai bên lúc cắt trên dưới, và KHÔNG
   cách nào cắt sẵn cho vừa được. Khoá 3:2 thì ảnh xuất từ /cat-anh/ khớp tuyệt đối.
   Sửa tỉ lệ này thì PHẢI sửa mảng PRESETS trong src/cat-anh.njk cho khớp. */
.art-thumb{
  /* 3/2 thay cho 16/9: ảnh cao thêm ~27px mà thẻ gần như không đổi, nhờ bỏ khoảng
     trống giả của phần mô tả. Đổi số này PHẢI đổi luôn PRESETS trong cat-anh.njk
     và aspect-ratio của .article-card.featured. */
  width:calc(100% + 32px); height:auto; aspect-ratio:3/2;
  margin:-16px -16px 12px -16px;
  border-radius:8px 8px 0 0; overflow:hidden;
  background:linear-gradient(135deg, var(--void-3), var(--void));
  border-bottom:1px solid var(--line);
  display:flex; align-items:center; justify-content:center; font-size:24px;
}
.art-thumb img{width:100%; height:100%; object-fit:cover; display:block;}
/* Tỉ lệ 3:2 đã khoá ở trên cho mọi màn hình, đây chỉ còn bỏ chiều cao tối thiểu của thẻ */
@media(max-width:640px){
  .article-card:not(.featured){min-height:0;}
}
.art-badges{display:flex; gap:6px; flex-wrap:wrap;}
.badge{font-family:'JetBrains Mono', monospace; font-size:9.5px; padding:3px 9px; border-radius:20px; text-transform:uppercase;}
.badge.new{background:rgba(168,60,52,0.2); color:var(--seal-soft); border:1px solid rgba(168,60,52,0.45);}
/* ---------- NHÃN KHU VỰC ----------
   ⚠️ Màu lấy từ --kv-c do template gắn vào từng nhãn (macro trong src/_includes/nhan.njk,
   đọc regionColors.json). ĐÚNG biến mà shortcode [k] dùng, nên nhãn "Hàng Châu" trên thẻ bài
   và nhãn [k]Hàng Châu[ek] trong bài luôn cùng một màu — đổi regionColors.json là đổi cả hai.
   ⚠️ Dòng rgba(...) đầu là lưới đỡ cho trình duyệt không hiểu color-mix, và cũng là màu khi
   template quên gắn --kv-c. ĐỪNG xoá. */
.badge.region{background:rgba(63,107,92,0.18); color:var(--jade); border:1px solid rgba(63,107,92,0.4);}
.badge.region{
  background:color-mix(in srgb, var(--kv-c, #3F6B5C) 18%, transparent);
  color:var(--kv-c, #3F6B5C);
  border:1px solid color-mix(in srgb, var(--kv-c, #3F6B5C) 40%, transparent);
}
/* ⚠️ Nhãn khu vực trên thẻ bài/đầu bài NAY dùng .kv .kv-the (xem nhan.njk), không còn là
   .badge.region. Hai quy tắc trên chỉ giữ làm lưới đỡ nếu template nào còn dùng lớp cũ.
   .kv-the: gỡ kiểu mà các khung nhãn (.lt-tags>span, .art-badges…) áp cho mọi phần tử con —
   đệm, bo góc, IN HOA, font mono — để nhãn trông y hệt [k] trong bài. Cỡ chữ theo nơi đặt. */
/* ⚠️ Ngoài bài viết nhãn đứng cạnh các nhãn bo góc khác nên cũng BO GÓC 4px và nền ĐẶC
   (bỏ mờ hai đầu — mờ thì góc bo không thấy). Trong bài vẫn mờ hai đầu, góc vuông. */
.kv.kv-the{
  background:var(--kv-bg);
  padding:1px 6px; border-radius:4px; border:0;
  text-transform:none; letter-spacing:0; white-space:nowrap; text-decoration:none;
  align-items:center; line-height:1.45;
}
/* Cỡ chữ cho cân với nhãn danh mục đứng cạnh. Trang chủ (.lt-tags) đã tự đặt cỡ cho <span>
   con nên không cần. Thiếu hai dòng này thì nhãn kế thừa cỡ chữ lớn của khung, to lệch. */
.art-badges .kv-the{font-size:11px; padding-block:0; line-height:1.3;}
.cat-row .kv-the{font-size:13.5px;}
/* Cao BẰNG nhãn danh mục/cấp đứng cạnh: giãn theo chiều cao hàng nhãn (hàng là flex), chữ
   và icon canh giữa. Đệm 1px của .kv làm nhãn thấp hơn hẳn các nhãn khác (báo 30/09/2026). */
:is(.lt-tags, .art-badges, .cat-row) > .kv-the{display:inline-flex; align-self:stretch;}

/* ---------- NHÃN DANH MỤC ----------
   Hai lớp màu, template gắn vào từng nhãn:
     --bd-c   : màu danh mục (categoryColors.json) — LUÔN có
     --bd-nen, --bd-chu : chỉ danh mục nào có kiểu riêng trong categoryBadge.json
   Không có kiểu riêng thì rơi về nền mờ + chữ đúng màu danh mục, giống dáng nhãn cũ.
   ⚠️ Trước đây chỉ "Kỳ Ngộ" có lớp riêng (.badge.cat-kyngo), mọi danh mục khác dùng chung
   .badge.region của nhãn KHU VỰC — nên Nhân Gian trông y hệt Hàng Châu. Đã bỏ hẳn lớp đó. */
.badge.cat-badge{
  background:var(--bd-nen, color-mix(in srgb, var(--bd-c, #A83C34) 20%, transparent));
  color:var(--bd-chu, var(--bd-c, #A83C34));
  border:1px solid var(--bd-nen, color-mix(in srgb, var(--bd-c, #A83C34) 42%, transparent));
}
/* ⚠️ Nhãn nền ĐẶC lấy đúng màu trong game, mà màu đó tương phản với chữ chỉ 2,9:1 (Nhân Gian)
   và 3,4:1 (Kỳ Ngộ) — dưới mức dễ đọc cho chữ 8,5px. KHÔNG chữa bằng cách đổi màu: đã thử
   đậm/nhạt đi cho đủ tương phản thì nhìn lệch hẳn ảnh trong game, nhận ra ngay.
   Chữa bằng nét chữ: đậm 600, cộng một lớp bóng cho nhãn CHỮ TRẮNG (đặt trong categoryBadge.json,
   khoá "bong"). ⚠️ Chữ TỐI trên nền nhạt thì ĐỪNG thêm bóng: nhòe như chạm nổi, game cũng không có.
   Nhãn nền mờ KHÔNG dùng lớp này, chữ trên nền nhạt vốn đã rõ. */
.badge.cat-dac{font-weight:600; text-shadow:var(--bd-bong, none);}
/* overflow-wrap:anywhere: từ dài quá thì ngắt giữa từ thay vì tràn ra ngoài thẻ.
   Chỉ ngắt khi KHÔNG còn chỗ nào khác, chữ bình thường vẫn xuống dòng theo dấu cách. */
.art-title{font-size:15px; font-weight:600; line-height:1.4; overflow-wrap:anywhere;}
.article-card.featured .art-title{font-size:19px; font-family:'Noto Serif', serif;}
.article-card.featured .art-desc{font-size:13.5px;}
.art-desc{
  font-size:11.5px; color:var(--text-dim); line-height:1.5; overflow-wrap:anywhere;
  /* KHÔNG có min-height: đó chính là khoảng trống giả đẩy mô tả xa tiêu đề khi tiêu đề
     chỉ 1 dòng. Mô tả nằm ngay dưới tiêu đề, tiêu đề dài bao nhiêu thì lấy bấy nhiêu.
     flex:1 + min-height:0 để mô tả ăn phần không gian còn lại; chạm giới hạn thì
     -webkit-line-clamp cắt và hiện dấu ba chấm. */
  /* max-height PHẢI khớp số dòng của line-clamp. Thiếu nó thì ô cao hơn 2 dòng nên
     dòng thứ 3 vẫn hiện, trong khi dấu ba chấm đã cắt ở cuối dòng 2 -> nhìn như lỗi. */
  flex:0 1 auto; min-height:0; max-height:calc(1.5em * 3);
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden;
}

/* Nhãn trong thẻ bài viết: nhỏ gọn, viền chữ nhật (không bo tròn kiểu pill) */
.article-card .art-badges{gap:4px;}
.article-card .badge{font-size:8.5px; padding:1px 5px; border-radius:3px;}
.article-card .art-title{
  font-size:14px;
  /* KHÔNG có min-height. Đây mới là thứ tạo khoảng trống giả to nhất: tiêu đề 1 dòng
     vẫn chiếm chỗ 2 dòng, đẩy mô tả xuống. Tiêu đề dài bao nhiêu lấy bấy nhiêu,
     tối đa 2 dòng rồi cắt bằng dấu ba chấm. */
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.art-title-row{display:flex; align-items:flex-start; gap:6px;}
.art-title-row .badge{display:none;} /* tạm ẩn nhãn cấp bậc (Đại Cát/Trung Cát...) cạnh tiêu đề - xóa dòng này để hiện lại */
.art-title-row .badge{flex-shrink:0; margin-top:2px;}
.art-title-row .art-title{flex:1; min-width:0;}
.art-meta{display:flex; align-items:center; justify-content:space-between; gap:8px; flex-wrap:wrap; min-width:0; font-family:'JetBrains Mono', monospace; font-size:10.5px; color:var(--text-dim-2); margin-top:auto; padding-top:8px;}
.art-meta .art-badges{flex-wrap:wrap;}
.art-meta span{flex-shrink:0; white-space:nowrap;}
/* Màn hình hẹp: lưới còn 1-2 cột nên thẻ nổi bật trải hết hàng */
/* Màn hình hẹp: xếp dọc lại như thẻ thường. PHẢI bỏ aspect-ratio của thẻ,
   không thì thẻ đứng bị ép thành dải ngang dẹt lép. */
@media(max-width:760px){
  .article-card.featured{flex-direction:column; aspect-ratio:auto;}
  .article-card.featured .art-thumb{width:100%; height:auto; aspect-ratio:3/2;
    border-right:0; border-bottom:1px solid var(--line);}
}
@media(max-width:640px){
}

/* ---------- BÀI VIẾT ĐƠN ---------- */
.cat-row{display:flex; align-items:center; gap:8px; margin-bottom:14px;}
h1.article-title{font-family:'Noto Serif', serif; font-weight:800; font-size:clamp(26px,3.4vw,38px); line-height:1.28; color:var(--text-main); margin-bottom:16px; max-width:760px; overflow-wrap:anywhere;}
.article-meta{display:flex; flex-wrap:wrap; gap:18px; font-family:'JetBrains Mono', monospace; font-size:11.5px; color:var(--text-dim); padding-bottom:22px; margin-bottom:26px; border-bottom:1px solid var(--line); max-width:760px;}
.article-meta span{display:flex; align-items:center; gap:6px;}
.article-meta [hidden]{display:none;} /* ô lượt xem chờ có số; display:flex ở trên sẽ đè hidden */
/* Điện thoại: dòng thông tin không đủ chỗ, nên dấu | trước lượt xem biến thành chỗ xuống hàng —
   "Lượt xem | Chia sẻ" nằm gọn hàng 2, không để | treo cuối hàng 1. Chỉ có khi bật hiện lượt xem. */
@media(max-width:600px){ .article-meta #viewSep:not([hidden]){flex-basis:100%; height:0; margin:0; overflow:hidden; visibility:hidden;} }

/* ---------- LƯU Ý GIỚI HẠN KỲ NGỘ (dòng dưới ngày đăng, chỉ bài Kỳ Ngộ) ----------
   Khuôn ở src/_includes/post.njk (tìm "kn-han"), số liệu ở src/_data/gioiHanKyNgo.json.
   Cố ý NHỎ và NHẠT: một lưu ý nhỏ, không tranh chú ý với nội dung chính (24/09/2026).
   flex-basis:100% = tự xuống hàng mới trong .article-meta, vẫn nằm TRÊN đường kẻ của khối.
   Phông nội dung (không phải JetBrains Mono của dòng ngày đăng): câu tiếng Việt dài đọc
   bằng phông đơn cách rất mỏi.
   ⚠️ Đã thử và BỎ: khung viền vàng kiểu khung Discord — "nhìn khó chịu", nổi hơn nội dung. */
.kn-han{flex-basis:100%; font-family:var(--font-body, 'Inter'), sans-serif; font-size:12px; line-height:1.5; color:var(--chu-phu);}
.kn-han b{font-weight:600;}
/* chữ "Lưu ý:" — đậm + gạch chân mảnh, cùng màu chữ của dòng */
.kn-han .kn-han-nhan{font-weight:700; text-decoration:underline; text-decoration-thickness:1px; text-underline-offset:3px;}
/* tên cấp: màu theo nhãn cấp tương ứng */
.kn-han .han-dai-cat{color:#C9A24E;}
.kn-han .han-trung-cat{color:#5E9C84;}
.kn-han .han-tieu-cat{color:var(--text-dim);}
.kn-han .han-hung{color:#D46A5E;}
/* cấp của chính bài đang xem: đậm hơn + gạch chân mảnh cùng màu */
.kn-han .la-cap-nay{font-weight:800; text-decoration:underline; text-decoration-thickness:1px; text-underline-offset:3px;}
/* nền sáng: màu nhãn cấp bản chế độ sáng (cùng bộ với .post-paper .badge.tag-*) cho đủ tương phản */
html:not([data-theme="dark"]) .kn-han .han-dai-cat{color:#8A6B24;}
html:not([data-theme="dark"]) .kn-han .han-trung-cat{color:#2C4E43;}
html:not([data-theme="dark"]) .kn-han .han-hung{color:#8A2F28;}
/* ⚠️ Chỉ cấp của CHÍNH bài đang đọc giữ màu; ba cấp kia về màu chữ phụ. Bốn màu cùng lúc làm
   dòng phụ này tranh chú ý với nội dung (phần "hai bậc chữ", 24/09/2026). Muốn cả bốn cấp có
   màu như trước thì xoá khối này. */
/* ⚠️ Lặp .kn-han-cap hai lần là CỐ Ý để tăng độ ưu tiên lên (0,4,0): các quy tắc màu cấp
   của chế độ sáng ở trên là html:not([data-theme="dark"]) .kn-han .han-* = (0,3,1), cao hơn
   (0,3,0) — viết một lần thì chế độ sáng vẫn giữ đủ bốn màu. */
.kn-han .kn-han-cap.kn-han-cap:not(.la-cap-nay){color:inherit; font-weight:500;}

/* Khoá tỉ lệ 760/280 = 2.714 vì lý do y hệt .art-thumb ở trên: cao cố định + rộng co giãn
   thì dưới 760px tỉ lệ sẽ đổi và ảnh cắt sẵn không còn vừa. */
.hero-image{height:auto; aspect-ratio:760/280; border-radius:8px; border:1px solid var(--line); background:repeating-linear-gradient(135deg, rgba(217,166,72,0.04) 0 2px, transparent 2px 26px), linear-gradient(160deg, var(--void-3), var(--void)); display:flex; align-items:center; justify-content:center; margin-bottom:32px; max-width:760px; overflow:hidden;}
.hero-image.cover{background:none; padding:0;}
.hero-image.cover img{width:100%; height:100%; object-fit:cover; display:block;}

.toc{background:var(--void-2); border:1px solid var(--line); border-radius:6px; padding:18px 20px; margin-bottom:32px; max-width:760px;}
.toc summary{font-family:'JetBrains Mono', monospace; font-size:11.5px; letter-spacing:0.15em; color:var(--gold); cursor:pointer; list-style:none;}
.toc summary::-webkit-details-marker{display:none;}
.toc ol{list-style:none; margin-top:14px; display:flex; flex-direction:column; gap:9px;}
.toc ol ol{margin-top:9px; margin-left:16px; border-left:1px solid var(--line); padding-left:12px;}
.toc a{font-size:13px; color:var(--text-dim); display:block; padding:2px 0; transition:color 0.2s;}
.toc a:hover{color:var(--text-main);}

/* Nội dung bài có thể chứa đường dẫn hoặc chuỗi dài không dấu cách */
.article-body{overflow-wrap:anywhere; max-width:760px;}

.article-body h2{font-family:'Noto Serif', serif; font-size:22px; font-weight:700; margin:38px 0 14px; scroll-margin-top:80px;}
.article-body h3{font-family:'Noto Serif', serif; font-size:17px; font-weight:700; margin:24px 0 10px;}
/* ⚠️ Thân bài dùng CHUNG hai biến với [box] [n] [r]… (khai báo ở khối .main-box): giãn dòng
   --khoi-lh và khoảng cách câu --cach-cau — người dùng muốn "y chang" (24/09/2026).
   Enter trong Decap = đoạn mới, Shift+Enter = xuống dòng: HAI CÁCH GIỜ CÁCH NHAU BẰNG NHAU
   (--cach-cau), vì transform tachCauSyntax tách cả dòng Shift+Enter trong <p>. Trước đây
   Enter cách 4px còn Shift+Enter sát hẳn — đã bỏ quy ước đó theo yêu cầu.
   ⚠️ Danh sách (li) CHƯA đổi, vẫn 1.45. */
.article-body p{font-size:15px; line-height:var(--khoi-lh); color:var(--chu-chinh); margin-bottom:var(--cach-cau);}
/* ---------- GẠCH CHÂN <<…>> ----------
   ⚠️ PHẢI đặt text-underline-offset. Mặc định trình duyệt vẽ nét gạch SÁT chân chữ, cắt
   ngang đuôi các chữ có nét thả xuống (g, y, ạ, ụ) nên nhìn rối và không giống nét gạch
   trong game. 4px đẩy nét xuống đủ xa để đuôi chữ thở.
   ⚠️ currentColor chứ KHÔNG ép màu cứng — nét gạch phải ăn theo màu của chính đoạn chữ.
   ⚠️ Nét 1px, KHÔNG phải 1.5px. Trước đây đặt 1.5px: trên màn hình thường trình duyệt làm
   tròn lên 2px nên nét dày bằng nửa nét chữ, trông nặng hơn hẳn nét gạch mảnh trong game.
   Màu pha 72% với trong suốt để nét NHẠT hơn chữ một chút, giống game — chữ vẫn là chính.
   Dùng color-mix trên currentColor chứ không dùng opacity: opacity làm mờ cả chữ.
   ⚠️ Sửa ở đây thì sửa luôn .step-block-body u và .search-item-title u cho đồng bộ. */
.article-body u{
  text-decoration:underline;
  /* Dòng đầu là lưới đỡ cho trình duyệt cũ không hiểu color-mix — ĐỪNG xoá. */
  text-decoration-color:currentColor;
  text-decoration-color:color-mix(in srgb, currentColor 72%, transparent);
  text-decoration-thickness:1px;
  text-underline-offset:4px;
}
.article-body ul, .article-body ol{margin:0 0 8px 20px;}
/* Trả lại dấu chấm/số đầu dòng — bị lệnh reset ul{list-style:none} ở đầu file xoá mất */
.article-body ul{list-style:disc;}
.article-body ol{list-style:decimal;}
.article-body li{font-size:14.5px; line-height:1.45; color:var(--chu-chinh); margin-bottom:2px;}

/* ---------- KHỐI GHI CHÚ [n]...[en] ---------- */
/* Gạch dọc trái + chữ nhỏ mờ. KHÔNG bo góc: bo góc chỉ dùng khi có viền đủ 4 cạnh.
   KHÔNG đệm trên/dưới: vạch dọc cao đúng bằng dòng chữ, thừa ra là vạch dài lêu nghêu. */
/* ---------- KHỐI CHÍNH [box]…[ebox] + KHỐI GIẢI THÍCH [rep]…[erep] ----------
   Cặp đi với nhau: khối chính viền LIỀN, khối giải thích thụt vào, viền ĐỨT màu đỏ triện,
   nối bằng đường kẻ chữ L cũng màu đỏ triện.
   ⚠️ CẢ HAI đều NỀN TRẮNG. Chữ để màu mặc định của bài, KHÔNG ép màu — như vậy các mã màu
   [luc] [cam]… gõ bên trong vẫn hiện đúng. Ép màu ở đây là đè mất màu người viết chọn. */
/* ---------- GHI CHÚ MŨI TÊN [r]…[er] và [r2]…[er2] ----------
   Dùng cho chuỗi "tin đồn -> việc cần làm" lặp nhiều lần. Nhẹ hơn hẳn khối có viền:
   lặp mười lần vẫn không thành một chồng hộp.
   ⚠️ Mũi tên vẽ bằng ::before đặt tuyệt đối, KHÔNG gõ ký tự ↳ vào nội dung — gõ tay thì
   nó lọt vào chỉ mục tìm kiếm và vào phần mô tả thẻ bài.
   ⚠️ left của mũi tên PHẢI bằng ÂM margin-left của cấp đó, để mũi tên rơi đúng lề của
   dòng chữ phía trên. Cấp 1: margin 18px / left -18px. Cấp 2: 38px / -18px (lùi thêm
   20px so với cấp 1). Đổi một số thì đổi số kia. */
/* ---------- GHI CHÚ PHÂN CẤP [r] / [r2]: đường kẻ chữ L ----------
   ⚠️ Màu đường kẻ là XÁM NHẠT kiểu Facebook, KHÔNG phải xanh. Đường nối là thứ phụ, tô màu
   mạnh thì nó tranh mắt với chính nội dung nó đang nối. Đã thử xanh #1877F2 và bỏ.
   ⚠️ Dùng BIẾN --r-line: chế độ tối cần xám sáng hơn, ghi cứng một mã là ở chế độ kia
   đường kẻ chìm nghỉm.
   ⚠️ BA số phải ăn khớp: top(-9) + height(17) = 8 -> nét ngang nằm ở 8px tính từ đỉnh khối,
   đúng giữa dòng đầu. top càng âm thì đầu chữ L càng vươn lên gần nội dung phía trên; đổi
   top thì PHẢI đổi height ngược lại cho tổng vẫn là 8.
   ⚠️ Cấp 2 chỉ đổi margin-left, KHÔNG đổi left của đường kẻ — đường kẻ luôn cách chữ một
   khoảng cố định dù ở cấp nào. */
.arrow-note{
  position:relative;
  margin:4px 0 7px 28px; padding:4px 10px;
  background:var(--r-bg); border-radius:5px;
  font-size:12.5px; line-height:var(--khoi-lh); /* như .main-box — xem ghi chú ở đó */
}
.arrow-note::before{
  content:''; position:absolute; left:-18px; top:-9px;
  width:12px; height:17px;
  border-left:1.5px solid var(--r-line);
  border-bottom:1.5px solid var(--r-line);
  border-bottom-left-radius:4px;
}
/* ⚠️ Mỗi cấp lùi thêm ĐÚNG 24px. Giữ đều bước thì mắt đọc ra ngay đây là năm bậc của
   cùng một thang; bước không đều thì trông như các khối rời rạc.
   Thêm cấp mới thì thêm một dòng ở đây VÀ nới vòng lặp trong .eleventy.js. */
.arrow-note-2{margin-left:52px;}
.arrow-note-3{margin-left:76px;}
.arrow-note-4{margin-left:100px;}
.arrow-note-5{margin-left:124px;}
.arrow-note p{margin:0;}
.arrow-note + .arrow-note{margin-top:2px;}

/* ⚠️ Giãn dòng của [box] [boxx] [r] [rep] [n] dùng CHUNG biến --khoi-lh (khai báo ngay dưới).
   Lịch sử: 1.5 -> 1.75 (23/09, chín câu dính thành mảng) -> 1.5 -> 1.65 (24/09, người dùng thử lại
   sau khi đã có TÁCH CÂU: khoảng cách giữa các câu giờ do --cach-cau lo, nên giãn dòng không
   còn phải gánh việc tách ý nữa).
   ⚠️ Khung xem trước Decap ghi cứng số này ở năm chỗ trong admin/index.html (nó không nạp file
   này) — đổi --khoi-lh thì đổi luôn ở đó. */
:root{--khoi-lh:1.65;}
.main-box{
  border:1.5px solid var(--line); border-radius:6px;
  background:none; padding:6px 11px; margin:9px 0;
  font-size:12.5px; line-height:var(--khoi-lh);
}
.main-box p{margin:0;}
/* [box] màu theo khung thông báo Gmail; cỡ chữ 12.5px bằng [n] [r] [rep] để khung nhẹ hơn thân bài 15px (yêu cầu 28/09/2026) — CHỈ [box]; [boxx] (.main-box-nhan) giữ nguyên.
   Các biến --box-* do Decap → Giao diện → "Khung nội dung [box] / [n]" đặt (src/_data/kieuKhoi.js,
   chèn ở base.njk). Số sau dấu phẩy là mặc định khi ô để trống.
   ⚠️ Chữ đậm lấy --box-dam NHƯNG không đè chữ nằm trong vùng tác giả đã tô màu, nhãn danh mục
   hay nhãn khu vực — giữ màu nội dung do tác giả đặt.
   ⚠️ Bộ chọn :is(p,li) phải mạnh hơn palette.css (html[data-palette] .post-paper .article-body :is(p,li)). */
.main-box:not(.main-box-nhan){
  font-family:var(--box-font,inherit);
  background:var(--box-nen,#D3E3FD); color:var(--box-chu,#041E49);
  font-size:var(--box-co,12.5px); line-height:var(--box-lh,20px);
}
html[data-theme="dark"] .main-box:not(.main-box-nhan){background:var(--box-nen,#233A5E); color:var(--box-chu,#D3E3FD);}
html .post-paper .article-body .main-box:not(.main-box-nhan) :is(p,li){color:inherit; font-size:inherit; line-height:inherit;}
.main-box:not(.main-box-nhan) :is(strong,b):not([style*="color"] *, .cat-ref *, .kv *){color:var(--box-dam,#041E49); font-weight:700;}

/* ---------- TÁCH CÂU trong [box] [boxx] [r] [rep] [n] ----------
   Transform tachCauSyntax trong .eleventy.js bọc mỗi dòng (mỗi lần Shift+Enter) thành
   <span class="nth-cau">. Dòng bị ngắt do hết chiều ngang vẫn nằm chung một span nên vẫn sát.
   --cach-cau : khoảng cách THÊM giữa hai câu, cộng vào giãn dòng 1.75 sẵn có.
                Người dùng tự chỉnh được, như các thông số --pin-*.
   ⚠️ Khung xem trước Decap ghi cứng số này (admin/index.html, hàm nthTachCau, biến CACH) vì nó không nạp
      file này — đổi số ở đây thì đổi luôn ở đó. */
:root{--cach-cau:5.5px;}
/* 5.5px có lý do: chữ 12.5px cao ~15px, dòng 20.6px (--khoi-lh 1.65) -> giữa hai dòng CÙNG câu
   hở ~5.5px. Cộng 5.5px ở đây thì giữa hai câu KHÁC nhau hở ~11px = đúng GẤP ĐÔI — mức mắt tách
   nhóm dứt khoát. 4.5px (1.8 lần) người dùng thấy "hơi bé". Quá ~7px thì mỗi câu trông như một
   đoạn văn riêng, khung mất vẻ gọn. Đổi --khoi-lh thì tính lại số này theo cùng cách. */
.nth-cau{display:block;}
.nth-cau + .nth-cau{margin-top:var(--cach-cau);}

/* ---------- NHÃN KHU VỰC [k]…[k] ----------
   ⚠️ Biểu thức khoá đóng là \[e?k\] — chữ e ĐỨNG TRƯỚC và là phần tuỳ chọn, để nhận cả
   [k] lẫn [ek]. Viết \[ek?\] là sai: nó cho ra [e] hoặc [ek], KHÔNG nhận [k]. Đã dính.
   ⚠️ display:inline chứ KHÔNG phải inline-flex/inline-block. Đệm trên dưới của thẻ inline
   KHÔNG làm giãn chiều cao dòng, nên nhãn nằm gọn trong một dòng chữ thường. Dùng
   inline-block là cả đoạn văn giãn ra, thấy rõ nhất khi một câu có hai ba nhãn.
   ⚠️ Nền mờ dần HAI ĐẦU, không có mép cứng — nhãn nằm giữa câu nên mép cứng sẽ cắt ngang
   dòng chữ. Đó cũng là lý do KHÔNG bo góc và KHÔNG viền.
   ⚠️ Màu lấy từ biến: chế độ tối cần nền loãng hơn và chữ sáng hơn, ghi cứng một mã là ở
   chế độ kia hoặc chìm nghỉm hoặc chói. */
.kv{
  /* Padding ngang 6px (trước 9px): transform đã nuốt khoảng trắng hai đầu, nền nhãn tự
     làm khoảng cách với chữ xung quanh — 9px thì hở quá.
     ⚠️ Đã thử và người dùng BỎ (30/09/2026): hạ riêng dải màu xuống 1.05em (cắt dấu tiếng
     Việt), 1.25em, và thu cả nhãn .9em. Giữ cỡ chữ 100% và dải màu cao hết hộp chữ. */
  display:inline; padding:1px 6px;
  /* ⚠️ --kv-c là màu RIÊNG của khu vực, do transform gắn vào từng nhãn. Không có thì lùi
     về màu mặc định. color-mix pha loãng chính màu đó ra nền, nên chỉ cần MỘT mã màu cho
     mỗi khu vực thay vì phải đặt riêng màu chữ và màu nền. */
  --kv-c:#9E4530;
  /* ⚠️ Nền PHẢI tính ngay tại đây, KHÔNG đặt ở :root. Đặt ở :root thì color-mix lấy
     --kv-c mặc định của gốc trang chứ không lấy màu riêng mà transform gắn vào từng nhãn
     — kết quả là mọi khu vực chung một nền. Đã dính đúng lỗi này. */
  /* Dự phòng cho trình duyệt cũ không hiểu oklch(from …): pha loãng màu gốc như trước. */
  --kv-bg:color-mix(in srgb, var(--kv-c) var(--kv-a, 22%), transparent);
  /* ⚠️ Mờ dần chỉ trong 6px ĐẦU/CUỐI (bằng padding), không theo % bề rộng. Trước đây mờ từ
     0→30% và 70→100% nên nhãn dài có vệt mờ rộng, trông như có dấu cách thừa hai bên. */
  background:linear-gradient(90deg,
    rgba(0,0,0,0) 0, var(--kv-bg) 6px, var(--kv-bg) calc(100% - 6px), rgba(0,0,0,0) 100%);
  color:var(--kv-chu); font-weight:700;
  font-family:'Google Sans Text',system-ui,-apple-system,'Segoe UI',Roboto,Arial,sans-serif;
  box-decoration-break:clone; -webkit-box-decoration-break:clone;
}
/* Nền rực: giữ SẮC của màu khu vực, độ sáng theo --kv-Lk/--kv-L0 và độ đậm màu tối thiểu
   --kv-Cmin để màu trầm (đỏ đô, nâu) cũng lên tươi như nền vàng. Chữ đen/trắng không đổi. */
@supports (color: oklch(from red l c h)){
  .kv{--kv-bg:oklch(from var(--kv-c) calc(l * var(--kv-Lk) + var(--kv-L0)) max(c, var(--kv-Cmin, .13)) h / var(--kv-A));}
}
/* Chế độ tối: nền là ĐÚNG màu khu vực, chữ trắng ngà (--kv-chu). */
html[data-theme="dark"] .kv{--kv-bg:var(--kv-c);}
/* Địa danh ngoài danh sách khu vực: nền ĐẶC #FFD78E (người dùng chọn 30/09/2026) + chữ đen,
   ở CẢ HAI chế độ, KHÔNG qua công thức oklch ở trên.
   ⚠️ Trước đây Trích Tiên Đảo là #885E00 (hổ phách) — làm sáng lên trùng màu này, nên đã đổi
   Trích Tiên Đảo sang xanh dầu #00576F trong regionColors.json. Chọn màu khu vực mới thì
   TRÁNH sắc vàng/hổ phách (oklch hue ~70–95) — đã có Đào Khê Thôn và nhãn này ở đó. */
.kv.kv-khac{--kv-c:#FFD78E; --kv-bg:#FFD78E;}
html[data-theme="dark"] .kv.kv-khac{color:#1C1E21;}
/* Biển chỉ đường (viewBox cắt sát 320×512 trong base.njk): cao 1.1em, thấp hơn ô 1.28em của
   hình thoi nên không đội chiều cao dòng; rộng .69em = 320/512 × 1.1em, lệch tỉ lệ là méo. */
.kv-pin.kv-sign{width:.69em; height:1.1em; vertical-align:-.2em;}
/* ⚠️ Cỡ theo em để icon co giãn cùng chữ. vertical-align âm kéo nó xuống cho ngang tâm chữ. */
.kv-pin{
  /* ⚠️ Icon có gradient và bóng riêng, KHÔNG ăn theo màu chữ — nên nó giống nhau ở cả
     hai chế độ sáng tối, đúng như trong game. */
  /* ⚠️ BA con số dưới đây ăn khớp nhau, đổi một thì phải tính lại cả ba:
       height 1.28em  — ô chứa icon. Đây LÀ thẻ inline-block nên chiều cao của nó CÓ
         tính vào hộp dòng. Dòng thân bài: 15px × 1.45 = 21.75px, mép trên hộp dòng ở
         khoảng 16.3px trên đường cơ sở, mép dưới khoảng 5.4px dưới. Với height 19.2px
         và vertical-align -4.2px thì icon chiếm từ -15.0 tới +4.2 — còn chừa gần 1.3px
         mỗi đầu, nên KHÔNG đội chiều cao dòng lên. Nhích lên 1.4em là bắt đầu đội.
       width .94em    — đúng tỉ lệ 20.5/28 của viewBox trong base.njk. Sai tỉ lệ thì
         preserveAspectRatio căn giữa và chừa lề trống hai bên, icon trông lệch.
       vertical-align -.28em — phần thò xuống dưới đường cơ sở.
     ⚠️ Hình thoi cao bằng 25/28 chiều cao ô, tức ~1.14em — trước đây viewBox rộng thùng
     thình nên cũng ô 1.15em mà hình chỉ cao 0.82em. Phần lớn độ cao thêm được là nhờ
     SỬA viewBox chứ không phải nhờ phóng ô, xem ghi chú ở symbol#kvPin trong base.njk. */
  width:.94em; height:1.28em; display:inline-block; vertical-align:-.28em;
  margin-right:.12em; overflow:visible;
}

/* ---------- NHÃN [k] — KIỂU NGÀY 26/09/2026 (khôi phục 01/10/2026 theo yêu cầu) ----------
   Lấy đúng từ bản sao lưu .sao-luu/ban-goc-2026-09-26…/source/src/assets/style.css:
   nền = màu khu vực pha 22% (tối 32%), mờ dần từ 30% bề rộng mỗi đầu; chữ tô ĐÚNG màu khu
   vực, đậm 600; đệm 1px 9px; hình thoi cách chữ .26em.
   Chỉ áp cho khu vực TRONG danh sách ([k] trong thân bài). KHÔNG áp cho:
     .kv-khac — địa danh tự viết, giữ biển chỉ đường vàng như hiện tại (người dùng dặn);
     .kv-the  — nhãn khu vực trên thẻ bài/đầu bài, giữ kiểu hiện tại.
   Các kiểu đã thử và bỏ hôm 01/10: xem mục "Nhãn khu vực [k]" trong AGENTS.md. */
.kv:not(.kv-the):not(.kv-khac){
  padding:1px 9px;
  --kv-bg:color-mix(in srgb, var(--kv-c) 22%, transparent);
  background:linear-gradient(90deg,
    rgba(0,0,0,0) 0%, var(--kv-bg) 30%, var(--kv-bg) 70%, rgba(0,0,0,0) 100%);
  color:var(--kv-c); font-weight:600;
}
html[data-theme="dark"] .kv:not(.kv-the):not(.kv-khac){--kv-bg:color-mix(in srgb, var(--kv-c) 32%, transparent);}
/* Thêm so với bản 26/09: chế độ tối nâng sáng CHỮ (oklch l ≥ .72). Màu khu vực đậm như
   Trích Tiên Đảo #00576F (đổi từ hổ phách hôm 30/09) gần như tàng hình trên nền tối. */
@supports (color: oklch(from red l c h)){
  html[data-theme="dark"] .kv:not(.kv-the):not(.kv-khac){color:oklch(from var(--kv-c) max(l, .72) c h);}
}
.kv:not(.kv-the):not(.kv-khac) > .kv-pin{margin-right:.26em;}
/* ---------- CẢNH KHU VỰC SAU TÊN [k] — 01/10/2026 ----------
   Mỗi khu vực một cảnh riêng (src/assets/kv-canh/<slug>.webp, alpha thật, cao 112px, người
   dùng vẽ, màu khớp regionColors.json) đứng SAU tên; dưới tên là đường kẻ CSS cùng màu khu
   vực — ĐÃ BỎ đường kẻ theo yêu cầu (01/10/2026); cảnh và hình thoi sát chữ. KHÔNG nền màu (đè nền của khối 26/09 ở trên);
   chữ vẫn màu khu vực.
   Chỉ áp cho khu vực trong danh sách (transform gắn data-kv); địa danh tự viết (.kv-khac)
   và nhãn trên thẻ bài (.kv-the) không đổi.
   Số riêng từng khu vực: --hv-ar = tỉ lệ rộng/cao ảnh cảnh (đo từ file).
   ⚠️ Thẻ inline nên đệm KHÔNG dãn dòng; cảnh chỉ chờm lên khoảng giữa hai dòng.
   ⚠️ white-space:nowrap — không cho cảnh/đường kẻ vỡ đôi khi xuống dòng.
   Chỉnh nhanh: --kv-canh-cao (cỡ cảnh), --kv-canh-chom (0 = vừa khít; dương = cảnh chui dưới đuôi tên).
   Thêm/đổi cảnh: thay file cùng tên, sửa --hv-ar; khung xem trước Decap: bảng CANH_KV. */
.kv[data-kv]:not(.kv-the){
  --kv-canh-cao:1.75em;
  --kv-canh-chom:0;
  --kv-canh-rong:calc(var(--kv-canh-cao) * var(--hv-ar, 2));
  /* NỀN MỜ cùng màu khu vực phủ cả hình thoi + tên + cảnh, mờ dần ở hai đầu (01/10/2026;
     người dùng muốn NỀN, không phải viền — viền đã thử, bỏ). --kv-nen-mo: độ đậm nền. */
  --kv-nen-mo:14%;
  --kv-nen:color-mix(in srgb, var(--kv-c) var(--kv-nen-mo), transparent);
  white-space:nowrap; margin:0 .3em 0 2px;
  /* Đệm trên = dưới (1px) để nền mờ dày đều hai phía chữ (người dùng chỉnh 01/10/2026). */
  /* --hv-lech (riêng từng khu vực, mặc định 0): dời cảnh sang trái khi ảnh có mép trái trống/nhạt. */
  padding:1px calc(var(--kv-canh-rong) * (1 - var(--kv-canh-chom)) - var(--hv-lech, 0em)) 1px 6px;
  border-radius:6px;
  background:linear-gradient(90deg, transparent, var(--kv-nen) 6px, var(--kv-nen) calc(100% - 10px), transparent);
  /* Cảnh là lớp ::after NẰM DƯỚI chữ (z-index -1 trong nhóm xếp lớp riêng của nhãn —
     isolation giữ nó không chui xuống dưới nền khung bài). */
  position:relative; isolation:isolate;
}
/* Cảnh đặt VỪA KHÍT ngay sau tên, không chồng chữ, không mask (chốt lại 01/10/2026 sau khi thử
   kiểu chữ nằm giữa cảnh — người dùng bỏ).
   ⚠️ Thẻ inline + nowrap nên chỉ có một mảnh hộp — ::after tuyệt đối neo đúng góc phải-dưới. */
.kv[data-kv]:not(.kv-the)::after{
  content:""; position:absolute; z-index:-1; pointer-events:none;
  right:0; bottom:0; width:var(--kv-canh-rong); height:var(--kv-canh-cao);
  background:var(--hv-canh) right bottom / contain no-repeat;
}
/* Hình thoi sát chữ; tắt bóng của SVG (--kv-pin-fx, xem base.njk) — không nền thì bóng lộ và bị cắt. */
.kv[data-kv]:not(.kv-the) > .kv-pin{margin-right:.08em; --kv-pin-fx:none;}
html[data-theme="dark"] .kv[data-kv]:not(.kv-the){--kv-nen-mo:24%;}
.kv[data-kv="tam-thanh-son"]{--hv-ar:1.982; --hv-canh:url(/assets/kv-canh/tam-thanh-son.webp);}
.kv[data-kv="dao-khe-thon"]{--hv-ar:1.884; --hv-canh:url(/assets/kv-canh/dao-khe-thon.webp);}
.kv[data-kv="bien-kinh"]{--hv-ar:2.339; --hv-canh:url(/assets/kv-canh/bien-kinh.webp);}
.kv[data-kv="hang-chau"]{--hv-ar:2.161; --hv-canh:url(/assets/kv-canh/hang-chau.webp);}
.kv[data-kv="tu-chau"]{--hv-ar:1.973; --hv-canh:url(/assets/kv-canh/tu-chau.webp);}
.kv[data-kv="thuong-chau"]{--hv-ar:2.25; --hv-canh:url(/assets/kv-canh/thuong-chau.webp);}
.kv[data-kv="nhan-mon-quan"]{--hv-ar:1.875; --hv-canh:url(/assets/kv-canh/nhan-mon-quan.webp);}
.kv[data-kv="bien-canh-tong-lieu"]{--hv-ar:2.973; --hv-canh:url(/assets/kv-canh/bien-canh-tong-lieu.webp);}
.kv[data-kv="tien-cu-nguyen"]{--hv-ar:2.045; --hv-canh:url(/assets/kv-canh/tien-cu-nguyen.webp);}
.kv[data-kv="trich-tien-dao"]{--hv-ar:1.25; --hv-canh:url(/assets/kv-canh/trich-tien-dao.webp);}
.kv[data-kv="kinh-thien-cac"]{--hv-ar:2.045; --hv-lech:.65em; --hv-canh:url(/assets/kv-canh/kinh-thien-cac.webp);}
.kv[data-kv="trich-tinh-cung"]{--hv-ar:1.598; --hv-canh:url(/assets/kv-canh/trich-tinh-cung.webp);}
.kv[data-kv="lien-van-trai"]{--hv-ar:2.062; --hv-canh:url(/assets/kv-canh/lien-van-trai.webp);}
.kv[data-kv="vinh-da-tinh-do"]{--hv-ar:1.982; --hv-canh:url(/assets/kv-canh/vinh-da-tinh-do.webp);}
.kv[data-kv="bach-de-thanh"]{--hv-ar:1.67; --hv-canh:url(/assets/kv-canh/bach-de-thanh.webp);}
.kv[data-kv="bich-huyet-doanh"]{--hv-ar:2.384; --hv-canh:url(/assets/kv-canh/bich-huyet-doanh.webp);}
.kv[data-kv="duoc-vuong-coc"]{--hv-ar:1.884; --hv-canh:url(/assets/kv-canh/duoc-vuong-coc.webp);}
.kv[data-kv="dao-hoa-o"]{--hv-ar:2.196; --hv-canh:url(/assets/kv-canh/dao-hoa-o.webp);}

/* ---------- CHỮ SỐ TRONG ĐOẠN IN ĐẬM ----------
   Chế độ TỐI: chữ đậm màu kem #EDE3CC nằm lẫn giữa chữ thường cũng màu kem, nên một con
   số như 753.937 chìm hẳn vào câu dù đã in đậm. Tô vàng là tách hẳn nó ra.
   ⚠️ Thẻ <span class="so"> do transform boldNumberSyntax trong .eleventy.js cắt ra, CHỈ
   trong vùng thân bài và CHỈ khi chữ số nằm trong <strong>/<b> mà không nằm trong thẻ đã
   tự đặt màu. Xoá transform đó thì quy tắc này thành vô dụng, không báo lỗi gì.
   ⚠️ CHỈ đổi ở chế độ tối. Nền trắng mà chữ vàng #FEC701 thì tương phản chỉ 1.7:1, gần
   như không đọc được — đó là lý do có bộ chọn html[data-theme="dark"] chứ không phải để
   cho gọn. Đừng gỡ nó ra.
   ⚠️ Cỡ chữ và độ đậm KHÔNG đặt ở đây: thẻ này nằm trong <strong> nên đã đậm sẵn, và nó
   phải co giãn theo [N]…[eN] bọc ngoài. */
html[data-theme="dark"] .so{color:#FEC701;}

/* ⚠️ [boxx] — khung NHẤN MẠNH: viền ĐỨT màu đỏ triện. Chỉ đổi thuộc tính border,
   mọi thứ khác thừa hưởng .main-box để hai khung luôn cùng cỡ và cùng lề.
   ⚠️ Dùng ít thôi. Viền đứt đỏ lặp nhiều lần trong một bài thì hết nhấn mạnh —
   lỗi đã gặp với [rep] bản đầu, tám khung đỏ liên tiếp làm người đọc lướt qua hết. */
.main-box-nhan{border:1.5px dashed var(--seal);}

/* ⚠️ Đường kẻ L vẽ bằng MỘT ô trống chỉ có viền trái + viền dưới, bo góc dưới-trái.
   Không ảnh, không ký tự.
   ⚠️ top + height PHẢI luôn bằng 16 (nửa chiều cao dòng đầu của khối). Hiện -9 + 25.
   Đổi top thì đổi height ngược lại, nếu không nét ngang đâm lệch khỏi giữa dòng.
   Từng để top:-14px và đường kẻ dính vào chữ phía trên. */
.reply-block{
  position:relative;
  margin:9px 0 10px 34px; padding:6px 11px;
  background:none; border:1.5px dashed var(--seal); border-radius:6px;
  font-size:12.5px; line-height:var(--khoi-lh); /* như .main-box — xem ghi chú ở đó */
}
.reply-block::before{
  content:''; position:absolute; left:-24px; top:-9px;
  width:16px; height:25px;
  border-left:2px solid var(--seal);
  border-bottom:2px solid var(--seal);
  border-bottom-left-radius:10px;
}
/* Hai khối [rep] liền nhau: rút ngắn đường kẻ cho khỏi hở. Vẫn giữ tổng 16. */
.reply-block + .reply-block{margin-top:6px;}
.reply-block + .reply-block::before{top:-6px; height:22px;}
.reply-block p{margin:0;}

.note-block{
  border-left:3px solid var(--gold); border-radius:0 5px 5px 0;
  /* ⚠️ Nền XÁM --paper-soft, KHÔNG phải vàng kem. Vàng kem để dành RIÊNG cho dòng hỏi
     đáp Discord cuối bài — đó là thứ duy nhất cần điểm nhấn ấm. Khối Ghi chú xuất hiện
     nhiều lần trong một bài, tô vàng hết thì cả bài loang lổ. */
  /* ⚠️ Cập nhật 28/09/2026: người dùng chọn nền vàng nhạt #FDF8E4 (thay ý cũ ở trên).
     Chỉnh tại Decap → Giao diện → "Khung nội dung [box] / [n]"; ô trống = giá trị sau dấu phẩy. */
  font-family:var(--note-font,inherit);
  background:var(--note-nen,#FDF8E4);
  padding:6px 11px 6px 11px; margin:7px 0 9px;
  font-size:var(--note-co,12.5px); line-height:var(--note-lh,20px); /* như .main-box — xem ghi chú ở đó */ color:var(--note-chu,var(--text-dim));
}
.post-paper .note-block{color:var(--note-chu,var(--ink-soft));}
html .post-paper .article-body .note-block.note-block :is(p,li){color:inherit; font-size:inherit; line-height:inherit;}
.note-block :is(strong,b):not([style*="color"] *, .cat-ref *, .kv *){color:var(--note-dam,inherit);}
/* Ghi chú nằm trong khối Bước thì thu nhỏ lề cho gọn */
.step-block-body .note-block{margin:5px 0 4px;}
/* Chữ in đậm giữ NGUYÊN màu chữ thường. Muốn đổi màu thì dùng cú pháp [màu]...[màu].
   Trước đây ép màu vàng/đỏ ở đây khiến mọi chữ đậm bị đổi màu ngoài ý muốn. */
.article-body strong{font-weight:700;}

/* ---------- THẺ NHẮC DANH MỤC [kn]...[kn] ---------- */
/* Chữ mang màu danh mục, kèm icon nhỏ. Icon khoá theo CHIỀU CAO như .title-emoji:
   ép ô vuông thì ảnh ngang chỉ cao bằng nửa dòng chữ, nhìn bé xíu. */
.cat-ref{font-weight:600; white-space:nowrap;}

/* ---------- CHẤM TRÒN ĐẦU DÒNG [dot]...[dot] ---------- */
/* Dùng ::before thay cho thẻ danh sách thật: bọc được nhiều dòng trong một lần bấm,
   và không bị Markdown đòi dấu * phải nằm đầu dòng. */
/* Số đo lấy đúng theo gạch đầu dòng thật ở trên: ul lùi 20px, chấm nằm ở mép lùi đó.
   Màu chấm để inherit -> giống hệt chấm của danh sách Markdown, không tô vàng. */
/* Ảnh chèn cùng dòng: canh theo đáy chữ để không đội dòng lên. */
.inline-img{display:inline-block; vertical-align:middle; margin:0 3px;
  border-radius:4px; max-width:100%;}

/* Mỗi dòng [dot] nằm trong một ĐOẠN VĂN riêng (Rich Text tách đoạn theo mỗi lần Enter),
   nên khoảng cách giữa hai đoạn tạo ra một dòng hở. Đoạn nào chỉ chứa dòng chấm thì bỏ
   khoảng cách dưới, và dòng chấm ngay sau đoạn chấm khác thì sát vào nhau.
   :has() cần trình duyệt từ 2023 trở đi — Chrome, Edge, Safari, Firefox hiện đều có. */
.article-body p:has(> .dot-line){margin-bottom:0;}
.article-body p:has(> .dot-line) + p:has(> .dot-line){margin-top:0;}

.dot-line{display:block; position:relative; padding-left:34px; margin:0 0 2px 0;
  font-size:14.5px; line-height:1.45;}
/* Thụt sâu hơn danh sách Markdown một bậc theo yêu cầu: chấm ở 20px, chữ ở 34px */
.dot-line::before{content:'•'; position:absolute; left:20px; top:0;}
/* Gắn link vào chữ đã tô màu / gạch chân thì link KHÔNG được cướp màu.
   Người viết đã chọn màu bằng cú pháp rồi, link chỉ nên thêm khả năng bấm. */
.cat-ref a, .article-body span[style*="color"] a, .article-body u a{color:inherit;}
.cat-ref-icon{height:1em; width:auto; max-width:2em; display:inline-block;
  vertical-align:-0.14em; object-fit:contain; margin-right:0.16em;}

/* ---------- KHỐI HỎI ĐÁP CUỐI BÀI ---------- */
/* inline-flex là điểm mấu chốt: khối co đúng bằng nội dung thay vì kéo hết chiều ngang
   như .discord-cta. Bài ngắn thì nó không lấn át phần nội dung. */
/* Khối hỏi đáp cuối bài — viền đứt nét, RỘNG BẰNG CỘT NỘI DUNG, chữ căn giữa bên trong.
   KHÔNG dùng flex: để chữ chảy như văn bản thường thì khi màn hình hẹp,
   logo + tên kênh xuống dòng CÙNG NHAU thay vì tên kênh rơi trơ trọi một mình.
   Trước đây từng để inline-block cho khối bó sát chữ, nhưng khi đó mép phải rơi vào
   chỗ ngẫu nhiên theo độ dài câu, nhìn lệch so với các đoạn văn xung quanh. */
.ask-wrap{margin:18px 0 4px;}
.ask-discord{
  display:block; width:100%; text-align:center;
  border:1px dashed rgba(88,101,242,0.5); border-radius:4px;
  /* Dùng CHUNG nền với khối Ghi chú và khối Bước. */
  background:var(--note-bg);
  padding:1px 6px;
  font-size:12.5px; line-height:1.6; color:var(--text-dim);
  transition:border-color .15s, background .15s;
}
.ask-discord:hover{border-color:#5865F2; background:var(--note-bg);}
/* white-space:nowrap giữ logo dính liền tên kênh, không cho tách ra hai dòng */
.ask-discord-channel{white-space:nowrap; color:#3F4899; font-weight:500;}
.ask-discord-logo{width:14px; height:14px; display:inline-block; vertical-align:-2px;
  margin-right:3px; color:#5865F2;}
/* Trên nền giấy dùng màu mực cho phần chữ dẫn, chữ xám nhạt đọc không rõ trên giấy kem */
.post-paper .ask-discord{color:var(--chu-phu);}

/* ---------- KHUNG MỜI DISCORD ---------- */
/* Thanh gọn MỘT DÒNG, nền màu Discord. Giữ nguyên màu ở cả chế độ sáng/tối và trên
   nền giấy — đây là màu thương hiệu, đổi theo giao diện thì mất tác dụng nhận diện. */
.discord-cta{display:flex; align-items:center; gap:11px; flex-wrap:wrap; background:#5865F2; border:0; border-radius:6px; padding:9px 10px 9px 14px; margin:22px 0;}
.discord-cta-icon{display:flex; align-items:center; flex-shrink:0; color:#fff;}
.discord-cta-icon svg{width:20px; height:20px; display:block;}
.discord-cta-text{flex:1; min-width:150px; font-size:13px; color:#fff; line-height:1.5;}
/* Nút trắng đặc: tương phản cao nhất trên nền tím, và vùng bấm rộng hơn hẳn chữ thường */
.discord-cta-btn{font-family:'JetBrains Mono', monospace; font-size:12px; font-weight:600; padding:7px 14px; border-radius:5px; background:#fff; color:#4149C4; white-space:nowrap; margin-left:auto;}
.discord-cta-btn:hover{background:#E4E6EB;}
.post-paper .discord-cta{background:#5865F2; border-color:transparent;}
.post-paper .discord-cta-text{color:#fff;}

/* ---------- PHÂN TRANG TỪNG BƯỚC (Bước 1, Bước 2...) ---------- */

/* Khối "Bước" - tự đẹp sẵn dù có JS phân trang hay không */
/* ⚠️ .step-block KHÔNG có nền — nền nằm ở .step-content, tức là BẮT ĐẦU SAU vòng số.
   Vòng số phải nằm ngoài khối màu thì đường nối 01→02→03 mới chạy được trong khoảng trống
   bên trái. Đặt nền lên .step-block là nó bọc trùm cả vòng số và nuốt mất đường nối.
   Đã BỎ đường kẻ ngăn ngang giữa các bước: nền đã tách chúng ra rồi. */
.step-block{
  display:flex; gap:14px; position:relative;
  padding-bottom:0; margin-bottom:14px; border-bottom:none;
}
.step-block:last-child{margin-bottom:0;}
.step-num{
  width:26px; height:26px; border-radius:50%; flex-shrink:0; position:relative; z-index:1;
  background:var(--seal); color:var(--paper);
  display:flex; align-items:center; justify-content:center;
  font-family:'JetBrains Mono', monospace; font-weight:700; font-size:10.5px;
}
/* Đường nối 01 → 02 → 03. ⚠️ Đặt trên .step-block (position:relative) chứ KHÔNG phải trên
   .step-num: trước đây nó là một đoạn cụt cao 41px CỐ ĐỊNH, nội dung dài hơn thì đường đứt
   lửng giữa chừng. Giờ chạy từ đáy vòng số xuống hết khối cộng đúng khe hở, nên luôn chạm
   tới vòng số của bước kế tiếp dù nội dung dài bao nhiêu.
   ⚠️ left:13px = nửa của vòng số 26px. Đổi kích thước vòng số thì phải đổi số này.
   ⚠️ bottom:-14px PHẢI bằng margin-bottom của .step-block. */
.step-block:not(:last-child)::after{
  content:''; position:absolute; left:13px; top:30px; bottom:-14px;
  width:1.5px; transform:translateX(-50%);
  background:var(--seal); opacity:0.25;
}
.step-content{
  min-width:0; flex:1;
  /* ⚠️ Nền XÁM giống khối Ghi chú, nhưng KHÔNG có vạch dọc bên trái. Vạch vàng là dấu hiệu
     RIÊNG của khối Ghi chú — thêm vào đây thì hai loại khối nhìn y hệt nhau, người đọc
     không phân biệt được đâu là ghi chú đâu là bước. Khối Bước đã có vòng số làm dấu. */
  background:var(--paper-soft);
  border-radius:5px;
  padding:9px 12px;
}
.step-block-title{font-family:'Noto Serif', serif; font-weight:700; font-size:15px; color:var(--gold); margin-bottom:6px;}
.step-block-body p:last-child{margin-bottom:0;}
.step-block-body u{text-decoration:underline; text-decoration-color:currentColor; text-decoration-color:color-mix(in srgb, currentColor 72%, transparent); text-decoration-thickness:1px; text-underline-offset:4px;}
.post-paper .step-block-body u{text-decoration-color:var(--seal);}
.post-paper .step-num{background:var(--seal);}
.post-paper .step-block:not(:last-child)::after{background:var(--seal);}
.post-paper .step-block-title{color:var(--seal);}
/* ---------- BẢNG (dạng bảng tính) ---------- */
.article-body table{
  width:100%; border-collapse:collapse; margin:20px 0;
  font-size:13.5px; background:rgba(255,255,255,0.35);
  border:1px solid var(--paper-edge);
}
.article-body thead th{
  /* Chữ trên nền triện đỏ: trắng thuần, không dùng kem #F5E6C0 nữa. */
  background:var(--seal); color:#FFFFFF;
  font-family:'JetBrains Mono', monospace; font-size:11px; letter-spacing:0.06em;
  text-transform:uppercase; text-align:left; padding:10px 12px; font-weight:700;
  border-right:1px solid rgba(255,255,255,0.18);
}
.article-body thead th:last-child{border-right:none;}
.article-body tbody td{
  padding:9px 12px; border-top:1px solid var(--paper-edge);
  border-right:1px solid var(--paper-edge); vertical-align:top;
}
.article-body tbody td:last-child{border-right:none;}
.article-body tbody tr:nth-child(even){background:rgba(168,60,52,0.05);}
.article-body tbody tr:hover{background:rgba(176,141,63,0.14);}
.article-body tbody td:first-child{font-weight:600; white-space:nowrap;}
/* Điện thoại: cuộn ngang thay vì bóp chữ nát */
.table-scroll{overflow-x:auto; -webkit-overflow-scrolling:touch; margin:20px 0; border-radius:6px;}
.table-scroll table{margin:0; min-width:520px;}
@media(max-width:640px){
  .article-body table{font-size:12.5px;}
  .article-body thead th{padding:8px 10px; font-size:10px;}
  .article-body tbody td{padding:8px 10px;}
}

.article-body mark.hl-marker{
  background:rgba(217,166,72,0.28); color:var(--text-main);
  padding:1px 5px; border-radius:3px; box-decoration-break:clone; -webkit-box-decoration-break:clone;
}
.post-paper .article-body mark.hl-marker{background:rgba(168,60,52,0.18); color:var(--ink);}

.tier{font-family:'JetBrains Mono', monospace; font-size:9.5px; padding:3px 9px; border-radius:20px; font-weight:500;}
.tier.trung{background:rgba(63,107,92,0.18); color:var(--jade); border:1px solid rgba(63,107,92,0.4);}
.tier.tieu{background:rgba(140,140,140,0.13); color:var(--text-dim-2); border:1px solid rgba(140,140,140,0.3);}

.coord-card{background:var(--void-2); border:1px solid var(--line); border-radius:8px; padding:18px 20px; margin:20px 0 26px; display:grid; grid-template-columns:1fr auto; gap:16px; align-items:center; max-width:760px;}
@media(max-width:520px){.coord-card{grid-template-columns:1fr;}}
.coord-label{font-family:'JetBrains Mono', monospace; font-size:10.5px; letter-spacing:0.12em; color:var(--gold); margin-bottom:8px;}
.coord-place{font-family:'Noto Serif', serif; font-size:16px; font-weight:700; margin-bottom:4px;}
.coord-xy{display:flex; gap:18px; font-family:'JetBrains Mono', monospace; font-size:14px; color:var(--text-main);}
.coord-xy span b{color:var(--text-dim-2); font-weight:500; margin-right:4px;}
.coord-actions{display:flex; gap:8px; flex-direction:column;}
.btn-copy, .btn-map{font-family:'JetBrains Mono', monospace; font-size:11.5px; padding:9px 14px; border-radius:6px; border:1px solid var(--line); background:var(--void-3); color:var(--text-main); white-space:nowrap; display:flex; align-items:center; gap:6px; justify-content:center; transition:all 0.15s;}
.btn-copy:hover{border-color:var(--text-dim); color:var(--text-main);}
.btn-map{background:var(--seal); border-color:var(--seal);}
.btn-map:hover{opacity:0.88;}
.btn-copy.copied{border-color:var(--jade); color:var(--jade);}

.npc-card{display:flex; align-items:center; gap:14px; background:var(--void-2); border:1px solid var(--line); border-radius:8px; padding:14px 16px; margin:16px 0 26px; max-width:760px;}
.npc-avatar{width:44px; height:44px; border-radius:50%; flex-shrink:0; background:linear-gradient(135deg, var(--void-3), var(--void)); border:1px solid var(--line); display:flex; align-items:center; justify-content:center; font-size:18px;}
.npc-info{flex:1; min-width:0;}
.npc-name{font-size:14px; font-weight:600;}
.npc-sub{font-family:'JetBrains Mono', monospace; font-size:11px; color:var(--text-dim-2); margin-top:2px;}
.npc-card .btn-map{padding:8px 14px; font-size:11px;}

.article-footer{margin-top:44px; padding-top:26px; border-top:1px solid var(--line); max-width:760px;}
.tags-row{display:flex; flex-wrap:wrap; gap:8px; margin-bottom:20px;}
.tag-pill{font-family:'JetBrains Mono', monospace; font-size:11.5px; padding:6px 13px; background:var(--field-bg); border:1px solid transparent; border-radius:20px; color:var(--text-dim); transition:background 0.12s, color 0.12s;}
.tag-pill:hover{background:var(--field-bg-hover); color:var(--text-main);}

body.has-bg{
  background-image:
    linear-gradient(180deg, rgba(250,246,236,0.85), rgba(250,246,236,0.95)),
    var(--page-bg-image);
  background-size:cover;
  background-position:top center;
  background-attachment:fixed;
}
html[data-theme="dark"] body.has-bg{
  background-image:
    linear-gradient(180deg, rgba(15,13,11,0.82), rgba(15,13,11,0.94)),
    var(--page-bg-image);
}
@media(max-width:768px){
  body.has-bg{ background-attachment:scroll; } /* fixed hay giật lag trên mobile */
}

/* Khối .scroll-rod (thanh gỗ cuộn) đã gỡ 10/09/2026 — markup cũng đã gỡ khỏi post.njk. */

/* ---------- BANNER ẢNH BÌA TOÀN CHIỀU RỘNG ---------- */

/* ---------- SUBMENU VÙNG ĐẤT (xổ ra) ---------- */

/* Danh sách khu vực giãn HẾT phần còn lại của cột trái, thay cho max-height:280px cứng.
   Khoá 280px thì chỉ hiện 8 trong 17 khu vực, cột trái hụt hẳn so với cột giữa.
   Cột trái là sticky cao bằng màn hình nên không thể dài bằng cột giữa nhiều bài,
   nhưng ít nhất luôn chạm đáy màn hình. */
.region-scroll{
  /* Giãn HẾT phần còn lại của cột trái để hiện được nhiều khu vực nhất có thể.
     ⚠️ TUYỆT ĐỐI không đặt max-height ở đây — danh sách sẽ bị bóp lại còn vài dòng. */
  flex:1 1 auto; min-height:0; overflow-y:auto; padding-right:2px;
  /* lấn lề trái 16px: xem .side-left .menu-list ở khối HOA VĂN bên dưới */
}
.region-scroll::-webkit-scrollbar{display:none;}

.region-group{margin-bottom:0;}
/* ⚠️ PHẢI khớp .menu-list a ở trên: cùng padding 6px 10px, cùng border-radius 0 6px 6px 0.
   Trước đây mục DANH MỤC bo góc còn mục KHU VỰC vuông, hai bên nhìn như hai thành phần
   khác nhau dù cùng là một danh sách điều hướng.
   ⚠️ Vạch đánh dấu vẽ bằng box-shadow inset, KHÔNG dùng border-left — border chiếm chỗ
   thật nên chữ ở đây bị đẩy lệch 2px so với mục DANH MỤC bên trên. */
.region-toggle{
  width:100%; display:flex; align-items:center; justify-content:space-between;
  background:none; border:none;
  padding:6px 10px; border-radius:0 6px 6px 0;
  font-size:13.5px; font-weight:500; color:var(--text-dim); cursor:pointer; font-family:inherit; text-align:left;
}
.region-toggle{transition:background 0.12s;}
.region-toggle:hover{color:var(--text-main); background:var(--hover-bg);}
.region-toggle.active{
  color:var(--sel-fg); font-weight:700;
  background:var(--sel-bg); box-shadow:inset 3px 0 0 var(--sel-bar);
}
.region-toggle-right{display:flex; align-items:center; gap:8px;}
.region-toggle .count{font-family:'JetBrains Mono', monospace; font-size:10px; color:var(--text-dim-2); font-weight:400;}
.region-toggle.active .count{color:var(--text-dim); font-weight:700;}

/* ---------- HOA VĂN + ĐƯỜNG SÁNG (menu trái trên máy tính) ----------
   Theo giao diện game:
     - một ĐƯỜNG KẺ MỜ chạy dọc suốt mỗi danh sách (danh mục, khu vực)
     - mục đang chọn: hoa văn chong chóng nằm trên đường kẻ, đường kẻ SÁNG LÊN hai phía,
       đoạn sáng TÁCH RỜI khỏi hoa văn (hở 4px) và mỗi đầu có một nét gạch chéo cách điệu
   Nền xám của mục đang chọn GIỮ NGUYÊN.
   ⚠️ CÙNG MỘT BỘ MÀU cho cả hai chế độ, theo ý người dùng: hoa văn TRẮNG + quầng XANH.
      ĐỪNG tô hoa văn thành xanh đậm ở chế độ sáng — đã làm và bị yêu cầu bỏ.
      Nhưng chế độ sáng có QUẦNG RIÊNG, đậm và sát nét hơn: quầng xanh nhạt của chế độ tối
      trên nền sáng gần như mất hút, hoa văn trắng chìm luôn. Quầng đậm là thứ làm cho BẢN THÂN
      hoa văn trông như đang phát sáng — xem html:not([data-theme="dark"]) ngay dưới :root.
   ⚠️ CHỈ trong .side-left. Menu điện thoại cũng có .menu-list nhưng lề khác, hoa văn thò ra
      ngoài sẽ bị cắt — ở đó giữ vạch xanh cũ (quy tắc gốc .menu-list a.active phía trên).
   ⚠️ Toàn bộ nằm trong @supports mask: trình duyệt không hiểu mask sẽ vẽ ra một Ô VUÔNG ĐẶC
      thay cho hoa văn. Không hiểu thì bỏ qua cả khối, vạch xanh cũ vẫn hiện như trước.
   ⚠️ BỐN con số phải ăn khớp — sửa một số thì tính lại cả bốn, lệch là hoa văn trượt khỏi
      đường kẻ:
        danh sách lấn lề trái 16px     (.side-left .menu-list: padding-left/margin-left)
        tâm đường kẻ mờ  = 16 - 4 = 12px  -> vẽ 2px từ 11px
        tâm đoạn sáng    = -20 + 32/2 = -4px (so với mép mục)
        tâm hoa văn      = -13 + 18/2 = -4px (so với mép mục)                              */
:root{
  /* ===== THÔNG SỐ NGƯỜI DÙNG TỰ CHỈNH =====
     --pin-gap      : khoảng cách từ TÂM hoa văn tới đầu đoạn sáng PHÍA DƯỚI.
                      Hoa văn cao 18px nên 9px là chạm mép ô hoa văn. Giảm = sát hoa văn hơn.
     --pin-gap-tren : như trên, cho đoạn sáng PHÍA TRÊN. Để riêng vì mép cánh hoa phía trên là
                      đường XIÊN — cùng một số thì mắt thấy đoạn trên hở hơn đoạn dưới, như bị
                      đứt khúc (người dùng nhận xét 24/09/2026). Đo theo cột giữa thì hình gần
                      đối xứng (mép trên cách tâm ~6.0px, mép dưới ~6.6px) — lệch là do mắt,
                      không đo ra được, nên chỉnh bằng mắt.
     --pin-cut-w/h  : chiều ngang / chiều dọc của khấc cắt (w lớn h nhỏ = khấc nằm thoải)
     --pin-ray-w    : độ dày đoạn sáng — VÀ độ dày nét khấc cắt (hai thứ luôn dày bằng nhau)
     --pin-base-w   : độ dày đường kẻ mờ chạy dọc danh sách
     --pin-glow-w/a : độ rộng / độ đậm QUẦNG SÁNG quanh đoạn sáng. Tách riêng khỏi lõi: trước đây
                      quầng sinh ra từ chính nét kẻ (drop-shadow), nét 0.5px thì quầng yếu theo.
                      Người dùng muốn LÕI MẢNH nhưng QUẦNG VẪN ĐẬM (24/09/2026).
     Đổi số ở đây là đủ — mọi chỗ khác đều đọc từ các biến này. */
  --pin-gap:11.5px;
  --pin-gap-tren:9.5px;
  --pin-cut-w:3.5px;
  --pin-cut-h:2.5px;
  --pin-ray-w:1.5px;
  --pin-base-w:1.25px;
  --pin-glow-w:3px;      /* độ RỘNG dải quầng sáng nằm dưới lõi đoạn sáng */
  --pin-glow-a:0;        /* độ ĐẬM dải quầng, 0 -> 1. 0 = tắt dải, chỉ còn quầng drop-shadow */
  /* Lõi đoạn sáng TRẮNG như hoa văn; màu xanh là do quầng --pin-lf bọc ngoài, không phải
     màu của lõi. Trước đây lõi xanh nhạt — người dùng yêu cầu đổi (24/09/2026). */
  --pin-ray:#FFFFFF;
  /* Đường kẻ chạy dọc danh sách: MỘT ĐƯỜNG THẲNG XÁM, đều suốt chiều dài, hai đầu cắt bằng,
     KHÔNG quầng. Đo từ ảnh game: #667E95 trên nền #42546D = lớp xám sáng ngả xanh trong
     suốt ~20-25%. Chỉ đoạn của mục ĐANG CHỌN mới sáng trắng pha quầng (::before bên dưới).
     ⚠️ Lịch sử (24/09/2026): đã làm lõi trắng + quầng elip + thon hai đầu — người dùng phóng to
        ảnh game chỉ ra là sai, đường kẻ gốc chỉ là một vạch xám thẳng. Đừng làm lại. */
  --pin-base:rgba(200,215,235,.30);
  --pin-f:drop-shadow(0 0 2px #BFE8FF) drop-shadow(0 0 6px #4AA8FF) drop-shadow(0 0 12px rgba(60,150,255,.8));
  --pin-lf:drop-shadow(0 0 2px rgba(150,215,255,.95)) drop-shadow(0 0 6px rgba(74,168,255,.85));
}
html:not([data-theme="dark"]){
  /* lớp 1px xanh đậm ôm sát viền -> hình hoa văn trắng hiện rõ; hai lớp sau là vầng sáng */
  --pin-f:drop-shadow(0 0 1px rgba(20,90,190,.95)) drop-shadow(0 0 4px rgba(40,130,230,.85)) drop-shadow(0 0 10px rgba(60,150,255,.6));
  --pin-lf:drop-shadow(0 0 1px rgba(20,90,190,.9)) drop-shadow(0 0 4px rgba(74,168,255,.85));
  /* ⚠️ Nền sáng: xám SÁNG sẽ chìm trên #F2F4F7, nên dùng xám ĐẬM mờ — vẫn là một vạch xám. */
  --pin-base:rgba(60,75,95,.28);
}
/* ⚠️ Lấn sang lề trái của .side-left 16px (padding + margin âm bằng nhau): chữ đứng yên chỗ
   cũ, nhưng danh sách rộng ra đủ chứa đường kẻ và hoa văn. Riêng danh sách KHU VỰC là một
   khung cuộn — khung cuộn cắt mọi thứ tràn ra ngoài nó, thiếu hai dòng này thì hoa văn bị
   cắt mất một nửa (đã dính, 24/09/2026). Nằm NGOÀI @supports vì nó vô hại. */
.side-left .menu-list{padding-left:16px; margin-left:-16px;}
/* ⚠️⚠️ Hoa văn vẽ bằng ẢNH NỀN (PNG trắng), KHÔNG dùng mask. Đã dùng mask ở hai lượt trước
   và hoa văn KHÔNG HỀ PHÁT SÁNG mà không ai nhận ra ngay: trong CSS, filter chạy TRƯỚC mask —
   drop-shadow được tính trên nguyên ô vuông, rồi mask cắt theo hình chong chóng và cắt mất luôn
   phần quầng tỏa ra ngoài. Ảnh nền thì drop-shadow bám theo đúng hình trong suốt của ảnh.
   Đổi lại: không tô được màu hoa văn bằng CSS nữa — muốn màu khác thì phải đổi file ảnh. */
/* Đường kẻ mờ: vẽ bằng ẢNH NỀN của danh sách, không dùng ::before. Với khung cuộn (danh
   sách khu vực), ảnh nền mặc định đứng yên theo khung chứ không trôi theo nội dung — nên
   đường kẻ luôn dài đủ chiều cao nhìn thấy. ::before thì sẽ trôi đi khi cuộn. */
.side-left .menu-list{
  /* tâm đường kẻ luôn ở 12px (= 16px lấn lề - 4px), dày bao nhiêu cũng vậy */
  /* một màu đặc, không mờ dần ở hai đầu — như vạch trong game */
  background:linear-gradient(var(--pin-base), var(--pin-base)) calc(12px - var(--pin-base-w) / 2) 0 / var(--pin-base-w) 100% no-repeat;
  /* ⚠️ CẮT THEO CHIỀU DỌC đúng mép danh sách: đoạn sáng của mục đang chọn cao 150px, mục ĐẦU
     hoặc CUỐI danh sách mà được chọn thì nó thò ra ngoài, vượt qua đầu vạch xám, xuyên cả tiêu
     đề "CẨM NANG" (người dùng chụp lại, 24/09/2026). Giờ tới mép là dừng, đúng chỗ vạch xám dừng.
     ⚠️ Dùng clip-path polygon RỘNG hơn danh sách 60px mỗi bên, KHÔNG dùng overflow:hidden:
        overflow cắt cả chiều ngang, quầng hoa văn thò sang trái sẽ bị chặt vuông như lỗi cũ.
        Polygon cho phép cắt riêng chiều dọc.
     Danh sách KHU VỰC vốn đã tự cắt ở mép vì là khung cuộn — giờ hai danh sách cư xử như nhau. */
  clip-path:polygon(-60px 0, calc(100% + 60px) 0, calc(100% + 60px) 100%, -60px 100%);
}
.side-left .menu-list a.active, .side-left .region-toggle.active{position:relative; box-shadow:none;}
.side-left .menu-list a.active > *, .side-left .region-toggle.active > *{position:relative; z-index:1;}
/* Đoạn sáng: hai lớp nền, trên dừng ở 50% - --pin-gap-tren, dưới bắt đầu ở 50% + --pin-gap.
   Hai KHẤC CẮT KHÔNG nằm ở đây mà nằm trong ::after cùng hoa văn — xem ghi chú ở đó.
   Cao 150px, thò đè qua các mục bên cạnh — cố ý, như game. pointer-events:none để không
   chặn cú bấm. Mục ở ĐẦU/CUỐI danh sách khu vực thì đoạn sáng bị khung cuộn cắt ở mép —
   giới hạn của khung cuộn, chấp nhận được vì đường kẻ mờ cũng dừng đúng ở mép đó. */
.side-left .menu-list a.active::before, .side-left .region-toggle.active::before{
  content:""; position:absolute; left:-20px; width:32px; top:50%; height:150px; margin-top:-75px;
  background:
    linear-gradient(to bottom, transparent, var(--pin-ray)) center top / var(--pin-ray-w) calc(50% - var(--pin-gap-tren)) no-repeat,
    linear-gradient(to top, transparent, var(--pin-ray)) center bottom / var(--pin-ray-w) calc(50% - var(--pin-gap)) no-repeat,
    /* dải quầng: nằm DƯỚI lõi (lớp nền sau vẽ dưới lớp trước), rộng hơn, mờ hơn;
       drop-shadow bên dưới làm mềm mép dải thành vầng sáng */
    linear-gradient(to bottom, transparent, rgb(110 190 255 / var(--pin-glow-a))) center top / var(--pin-glow-w) calc(50% - var(--pin-gap-tren)) no-repeat,
    linear-gradient(to top, transparent, rgb(110 190 255 / var(--pin-glow-a))) center bottom / var(--pin-glow-w) calc(50% - var(--pin-gap)) no-repeat;
  filter:var(--pin-lf);
  pointer-events:none; z-index:0;
}
/* Hoa văn + hai khấc cắt.
   ⚠️ Khấc nằm CÙNG lớp với hoa văn (không nằm với đoạn sáng) để dùng CHUNG filter --pin-f:
      lõi TRẮNG như hoa văn, quầng xanh bọc ngoài. Để ở ::before thì nó ăn filter của đường kẻ,
      ra màu xanh nhạt — người dùng yêu cầu sửa (24/09/2026).
   ⚠️ Ô cao 40px (không phải 18px) để chứa được cả hai khấc; hoa văn vẫn 18px ở giữa.
      Hoa văn dùng "18px auto" chứ không "contain": ô giờ là hình chữ nhật đứng, contain vẫn
      đúng nhưng ghi rõ cỡ thì đọc code khỏi phải đoán.
   Khấc vẽ bằng linear-gradient "to bottom right": dải màu giữa (50%) nối góc TRÊN-PHẢI với góc
   DƯỚI-TRÁI -> nét chéo "/". Độ dày tính vuông góc với nét = đúng --pin-ray-w.
   ⚠️ KHÔNG dùng SVG nhúng cho khấc: SVG trong url() không đọc được biến CSS, độ dày nét phải
      ghi cứng và lệch khỏi đoạn sáng mỗi khi đổi --pin-ray-w. Đã dùng SVG hai lượt trước. */
.side-left .menu-list a.active::after, .side-left .region-toggle.active::after{
  content:""; position:absolute; left:-13px; top:50%; width:18px; height:40px; margin-top:-20px;
  background:
    linear-gradient(to bottom right, transparent calc(50% - var(--pin-ray-w) / 2), #FFFFFF calc(50% - var(--pin-ray-w) / 2), #FFFFFF calc(50% + var(--pin-ray-w) / 2), transparent calc(50% + var(--pin-ray-w) / 2)) center calc(50% - var(--pin-gap-tren)) / var(--pin-cut-w) var(--pin-cut-h) no-repeat,
    linear-gradient(to bottom right, transparent calc(50% - var(--pin-ray-w) / 2), #FFFFFF calc(50% - var(--pin-ray-w) / 2), #FFFFFF calc(50% + var(--pin-ray-w) / 2), transparent calc(50% + var(--pin-ray-w) / 2)) center calc(50% + var(--pin-gap)) / var(--pin-cut-w) var(--pin-cut-h) no-repeat,
    url(/assets/ui/menu-pin.png) center / 18px auto no-repeat;
  filter:var(--pin-f);
  pointer-events:none; z-index:2;
}
/* Hoa văn trước tiêu đề mục ở sidebar phải (NỔI BẬT, CỘNG ĐỒNG), như tiêu đề mục trong game.
   .side-title là flex có gap 8px, nên ::before tự đứng trước chữ và cách chữ 8px.
   ⚠️ ::after của .side-title là đường kẻ ngang kéo hết dòng — ĐỪNG dùng ::after ở đây.
   ⚠️ flex:none: không có thì flex co hoa văn lại khi tiêu đề dài. */
.side-title::before{
  content:""; flex:none; width:15px; height:15px;
  background:url(/assets/ui/menu-pin.png) center / contain no-repeat; filter:var(--pin-f);
}

.region-toggle .chevron{
  font-size:12px; color:var(--text-dim-2); display:inline-block;
  transition:transform 0.2s;
}
/* mũi tên theo trạng thái MỞ (.mo), không theo .active — xem ghi chú ở nút trong base.njk */
.region-toggle.mo .chevron{transform:rotate(180deg); color:var(--text-dim);}

.region-submenu{
  display:none; flex-direction:column; gap:0;
  margin:2px 10px 8px 22px; position:relative;
}
.region-submenu.open{display:flex;}
.region-submenu::before{
  content:''; position:absolute; left:-11px; top:2px; bottom:14px; width:1px;
  background:var(--line);
}
/* justify-content:flex-start là CỐ Ý: .menu-list a ở trên đặt space-between để đẩy số bài
   sang phải, và quy tắc đó lan xuống cả link trong submenu. Submenu không có số bài,
   nên nếu không chặn thì icon và chữ bị tách ra hai đầu. */
/* Có số bài thì đẩy số sang mép phải; không có số thì chữ vẫn nằm sát trái. */
.region-submenu a{
  justify-content:space-between;
  position:relative;
  display:flex; align-items:center; gap:7px;
  /* ⚠️ ĐỪNG quay lại var(--gold). Vàng trên nền xám sáng có độ tương phản rất thấp,
     mà đây là danh sách điều hướng chứ không phải chữ trang trí — phải đọc được.
     opacity bỏ luôn: nó nhân với nền nên chữ trôi màu khác nhau ở mỗi khối. */
  padding:5px 8px; font-size:12.5px; color:var(--text-dim); border-radius:5px;
  border-radius:4px; transition:background 0.12s, opacity 0.12s;
}
.region-submenu a::before{
  content:''; position:absolute; left:-11px; top:50%; width:9px; height:1px;
  background:var(--line);
}
.region-submenu a:hover{background:var(--hover-bg); color:var(--text-main);}

/* ---------- NHÃN DÁN (Mới / Hot / Nổi bật) ---------- */
.badge.tag-moi{background:rgba(168,60,52,0.2); color:var(--seal-soft); border:1px solid rgba(168,60,52,0.45);}
.badge.tag-hot{background:rgba(217,119,6,0.2); color:#F2994A; border:1px solid rgba(217,119,6,0.45);}
.badge.tag-noi-bat{background:rgba(176,141,63,0.2); color:var(--gold); border:1px solid rgba(176,141,63,0.45);}
.badge.tag-dai-cat{background:rgba(176,141,63,0.2); color:var(--gold); border:1px solid rgba(176,141,63,0.45);}
.badge.tag-trung-cat{background:rgba(63,107,92,0.2); color:var(--jade); border:1px solid rgba(63,107,92,0.45);}
.badge.tag-tieu-cat{background:rgba(140,140,140,0.15); color:var(--text-dim); border:1px solid rgba(140,140,140,0.3);}
.badge.tag-hung{background:rgba(168,60,52,0.28); color:var(--seal-soft); border:1px solid rgba(168,60,52,0.55);}

/* Emoji cạnh tiêu đề - kích thước bằng emoji thông thường, canh theo dòng chữ */
/* Emoji tiêu đề nằm TRƯỚC chữ. Khoá theo CHIỀU CAO, bề rộng tự co theo ảnh:
   nếu ép cả hai chiều thành ô vuông thì ảnh ngang (vd 16:9) chỉ cao bằng nửa dòng chữ,
   nhìn bé xíu. max-width chặn ảnh quá ngang không đẩy tiêu đề xuống dòng. */
.title-emoji{height:1.05em; width:auto; max-width:2.4em; display:inline-block;
  vertical-align:-0.16em; object-fit:contain; margin-right:0.12em;}
/* ---------- BÓNG ĐỔ CHO EMOJI: MẶC ĐỊNH TẮT ----------
   drop-shadow bám theo ĐỘ TRONG SUỐT của ảnh. Ảnh cắt tay từ game thường còn sót
   viền nền tối ở mép, bóng sẽ tô đậm đúng cái viền đó lên -> nhìn bẩn.
   Chỉ bật khi ảnh đã tách nền sạch: /admin -> ⚙️ Cài đặt chung -> Donate & Footer
   -> "Đổ bóng cho emoji tiêu đề". Bật rồi mà vẫn xấu thì lỗi ở file ảnh, không phải CSS. */
html[data-emoji-shadow="on"] .title-emoji{filter:drop-shadow(0 1px 2px rgba(0,0,0,0.4));}
html[data-emoji-shadow="on"] .post-paper h1.article-title .title-emoji{filter:drop-shadow(0 1px 2px rgba(36,31,22,0.3));}
html[data-emoji-shadow="on"] .search-item-emoji{filter:drop-shadow(0 1px 2px rgba(0,0,0,0.35));}
h1.article-title .title-emoji{height:0.9em; max-width:2em; vertical-align:-0.08em; margin-right:0.1em;}
.badge.tag-default{background:rgba(140,140,140,0.15); color:var(--text-dim); border:1px solid rgba(140,140,140,0.3);}

.post-paper{
  position:relative;
  background:var(--paper);
  color:var(--ink);
  border:1px solid var(--paper-edge);
  border-radius:10px;
  /* 44px cũ là để chừa chỗ cho thanh gỗ cuộn và hình trang trí góc. Cả hai đã gỡ nên
     hạ về 32px, nếu không đầu bài hở một mảng trắng vô cớ. */
  padding:32px 40px 40px;
  overflow:hidden;
  box-shadow:0 18px 40px -24px rgba(0,0,0,0.5);
}
/* ⚠️ Hai hình trang trí góc (cành mai trên trái, vệt mực trên phải) đã GỠ 10/09/2026.
   Chúng là SVG nhúng base64 tông nâu #3a2f22 và đỏ #A83C34. Lý do gỡ: cành mai to và
   đậm tới mức chồng lên cả nhãn danh mục lẫn tiêu đề, còn vệt mực ở cỡ đó không đọc
   ra hình gì. Trước đây chúng cân được vì có hai thanh gỗ nâu ở trên dưới làm đối
   trọng; gỡ thanh gỗ rồi thì chúng thành thứ nặng nhất trên khung.
   Đây là lựa chọn CÓ CÂN NHẮC, không phải quên — muốn thêm hoa văn mới thì bàn lại. */
.post-paper > *{ position:relative; z-index:1; }

.post-paper .article-meta{color:var(--chu-phu); border-bottom-color:var(--paper-edge);}
/* ---------- ĐƯỜNG NGĂN CÓ HOA VĂN giữa đầu bài và thân bài (24/09/2026) ----------
   Đường kẻ chừa một khoảng ở giữa, hoa văn chong chóng của menu nằm trong khoảng đó —
   dấu hiệu "nội dung bắt đầu từ đây", cùng họa tiết với menu trái.
   Đường kẻ = ảnh nền (không phải border) để chừa được khoảng giữa; nằm cao hơn đáy khối 7px
   để tâm hoa văn (cao 14px, ở ::after) rơi đúng lên đường kẻ.
   ⚠️ Hoa văn là PNG TRẮNG: nền sáng thì trắng trên trắng, nên chế độ sáng có quầng xanh mảnh
      quanh viền (--ngan-f), giống cách làm với hoa văn menu. Chế độ tối để trơn. */
.post-paper .article-meta{
  border-bottom:0; padding-bottom:30px;
  background:linear-gradient(to right, var(--paper-edge) calc(50% - 20px), transparent calc(50% - 20px), transparent calc(50% + 20px), var(--paper-edge) calc(50% + 20px)) left calc(100% - 7px) / 100% 1px no-repeat;
}
.post-paper .article-meta::after{
  content:""; position:absolute; left:50%; bottom:0; width:14px; height:14px; margin-left:-7px;
  background:url(/assets/ui/menu-pin.png) center / 14px auto no-repeat;
  filter:var(--ngan-f, none); pointer-events:none;
}
html:not([data-theme="dark"]) .post-paper .article-meta{--ngan-f:drop-shadow(0 0 1px rgba(20,90,190,.9)) drop-shadow(0 0 3px rgba(40,130,230,.55));}
.post-paper h1.article-title{color:var(--ink);}
.post-paper .article-body h2, .post-paper .article-body h3{color:var(--ink);}
.post-paper .article-body p, .post-paper .article-body li{color:var(--chu-chinh);}
/* Khi chữ in đậm nằm trong khối tô màu [xanh]..[xanh], ưu tiên màu tuỳ chỉnh đó */
/* Quy tắc ép strong về color:inherit ĐÃ BỎ — không còn cần vì strong không tự đổi màu nữa. */
/* ---------- NHÃN TRONG TRANG BÀI VIẾT ---------- */
/* Vẽ lại theo mẫu trong game: góc vuông bo nhẹ thay vì viên thuốc, chữ thường
   thay vì IN HOA, cỡ chữ to hơn hẳn cho dễ đọc. Nhãn danh mục TÔ ĐẶC, các nhãn
   còn lại chỉ có viền — để mắt bắt ngay nhãn nào là danh mục. */
.post-paper .cat-row{gap:8px;}
.post-paper /* ⚠️ Nhãn CẤP nay là thẻ <a> chứ không còn là <span>. Phải bỏ gạch chân và giữ nguyên
   màu chữ, nếu không nó sẽ mang màu liên kết mặc định của trình duyệt. */
.cat-row a.badge{text-decoration:none; color:inherit;}
.cat-row a.badge:hover{filter:brightness(1.12);}
.cat-row .badge{
  font-family:var(--font-body, 'Inter'), sans-serif; font-size:12.5px; font-weight:500;
  text-transform:none; letter-spacing:0; border-radius:4px; padding:4px 10px;
}
/* Nhãn danh mục: nền đặc, màu lấy từ "Màu theo danh mục" trong /admin.
   Không đặt màu thì rơi về màu triện đỏ mặc định. */
/* ⚠️ Trong bài, nhãn danh mục là nền ĐẶC (khác thẻ bài ngoài trang chủ dùng nền mờ).
   Danh mục có kiểu riêng thì lấy đúng nền/chữ của nó, không thì nền là màu danh mục + chữ trắng.
   ⚠️ Bộ chọn phải đủ mạnh để thắng .cat-row a.badge{color:inherit} ở trên. */
.post-paper .cat-row .badge.cat-badge{
  background:var(--bd-nen, var(--bd-c, #A83C34));
  color:var(--bd-chu, #FFFFFF);
  border:1px solid transparent;
}
/* Các nhãn còn lại: chỉ viền, nền trong suốt */
.post-paper .cat-row .badge:not(.cat-badge){background:transparent;}
/* ⚠️ Nhãn khu vực ở đây là thẻ <a>, mà .cat-row a.badge đặt color:inherit — không có dòng này
   thì nó mất màu khu vực, thành màu chữ thường. */
.post-paper .cat-row a.badge.region{color:var(--kv-c, #3F6B5C);}
/* Nhãn dạng link: giữ nguyên dáng, chỉ sáng lên khi rê chuột cho biết bấm được */
.post-paper .cat-row a.badge{text-decoration:none; transition:filter .15s, opacity .15s;}
.post-paper .cat-row a.badge:hover{filter:brightness(1.08); opacity:0.88;}

html:not([data-theme="dark"]) .post-paper .badge.new{background:rgba(168,60,52,0.12); color:#8A2F28; border-color:rgba(168,60,52,0.35);}
html:not([data-theme="dark"]) .post-paper .badge.tag-moi{background:rgba(168,60,52,0.12); color:#8A2F28; border-color:rgba(168,60,52,0.35);}
html:not([data-theme="dark"]) .post-paper .badge.tag-hot{background:rgba(217,119,6,0.12); color:#B35A0A; border-color:rgba(217,119,6,0.35);}
html:not([data-theme="dark"]) .post-paper .badge.tag-noi-bat{background:rgba(176,141,63,0.15); color:#8A6B24; border-color:rgba(176,141,63,0.4);}
html:not([data-theme="dark"]) .post-paper .badge.tag-dai-cat{background:rgba(176,141,63,0.15); color:#8A6B24; border-color:rgba(176,141,63,0.4);}
html:not([data-theme="dark"]) .post-paper .badge.tag-trung-cat{background:rgba(63,107,92,0.15); color:#2C4E43; border-color:rgba(63,107,92,0.4);}
.post-paper .badge.tag-tieu-cat{background:rgba(90,80,50,0.1); color:var(--ink-soft); border-color:rgba(90,80,50,0.3);}
html:not([data-theme="dark"]) .post-paper .badge.tag-hung{background:rgba(168,60,52,0.18); color:#8A2F28; border-color:rgba(168,60,52,0.45);}
/* ⚠️ Chế độ SÁNG trong khung giấy: vẫn theo màu khu vực, chỉ giảm độ đậm của nền cho hợp nền giấy.
   Trước đây dòng này ép cứng màu xanh ngọc #2C4E43 cho MỌI khu vực. */
html:not([data-theme="dark"]) .post-paper .badge.region{
  background:color-mix(in srgb, var(--kv-c, #3F6B5C) 12%, transparent);
  color:var(--kv-c, #3F6B5C);
  border-color:color-mix(in srgb, var(--kv-c, #3F6B5C) 35%, transparent);
}
.post-paper .article-footer{border-top-color:var(--paper-edge);}
.post-paper .tag-pill{color:var(--ink-soft); border-color:var(--paper-edge);}
.post-paper .tag-pill:hover{border-color:var(--seal); color:var(--seal);}
@media(max-width:640px){
  .post-paper{padding:28px 20px 28px;}
}

/* ---------- TRANG BÀI: HAI KHỐI (đầu bài / thân bài) ----------
   Chỉ áp khi <article> có lớp "hai-khoi" (post.njk). Thẻ .post-paper thành khung trong suốt;
   hai khối con mang lại đúng nền, viền, bóng của thẻ cũ, nhưng GÓC VUÔNG (người dùng không muốn
   bo tròn), cách nhau một khe nhỏ — vừa đủ thấy là hai khối.
   ⚠️ Không vạch màu danh mục, không hoa văn giữa khe, không đường ngăn trong đầu bài: khe đã
      tách hai phần rồi, thêm nữa là thừa (người dùng chốt 25/09/2026).
   ⚠️ Đã thử và BỎ: tranh thủy mặc trong thân bài — chỉ hợp bài dài vừa phải, bài quá ngắn/dài
      thì làm khó đọc hơn. File src/assets/ui/wuxia-mountain.webp không còn được dùng.
   --khe-khoi : khoảng hở giữa hai khối — người dùng tự chỉnh được.
   Màu nền khối THÂN BÀI chỉnh trong /admin -> ⚙️ Cài đặt chung (biến --than-bai-nen, xem
   mauThanBai.js). Không chọn gì = cùng màu khối đầu bài (--paper). */
:root{--khe-khoi:8px;}
html body .post-paper.hai-khoi{
  background:transparent; border:0; border-radius:0; box-shadow:none; padding:0; overflow:visible;
}
.post-paper.hai-khoi > .dau-bai, .post-paper.hai-khoi > .than-bai{
  background:var(--paper); border:1px solid var(--paper-edge); border-radius:0;
  box-shadow:0 18px 40px -24px rgba(0,0,0,0.5);
}
html:not([data-theme="dark"]) .post-paper.hai-khoi > .dau-bai,
html:not([data-theme="dark"]) .post-paper.hai-khoi > .than-bai{box-shadow:0 2px 4px rgba(0,0,0,0.33);}
.post-paper.hai-khoi > .dau-bai{padding:32px 40px 26px;}
.post-paper.hai-khoi > .than-bai{padding:28px 40px 40px; margin-top:var(--khe-khoi); background:var(--than-bai-nen, var(--paper));}
/* đường ngăn + hoa văn cuối dòng ngày đăng: thừa khi đã có khe -> tắt trong kiểu hai khối */
.post-paper.hai-khoi .article-meta{background:none; border-bottom:0; padding-bottom:0; margin-bottom:0;}
.post-paper.hai-khoi .article-meta::after{display:none;}
@media(max-width:640px){
  .post-paper.hai-khoi > .dau-bai{padding:26px 20px 22px;}
  .post-paper.hai-khoi > .than-bai{padding:24px 20px 28px;}
}
/* Cột phải là ANH EM SINH ĐÔI của cột trái: cùng nằm trên nền xám, cùng có một đường
   kẻ dọc ngăn với phần nội dung ở giữa. Chỉ khung bài Ở GIỮA mới được đóng khối — đó là
   điểm nhấn của trang, hai cột hai bên phải lùi lại làm nền.
   ⚠️ padding-top 33px KHÔNG phải 24px: để chữ "NỔI BẬT" nằm ĐÚNG NGANG HÀNG với chữ
   "Trang chủ" bên cột trái. Cột trái = padding 24px + .menu-list a có padding 9px = 33px
   tính tới đỉnh chữ; còn .side-title không có padding riêng nên phải bù 9px ở đây.
   ⚠️ Đổi padding của .side-left hoặc của .menu-list a thì PHẢI tính lại con số này. */
aside.side-right{display:flex; flex-direction:column; gap:24px; position:sticky; top:80px; padding:33px 20px 40px; border-left:1px solid var(--line);}
/* Mỗi khối ở cột phải là MỘT tấm nền trắng, cùng ngôn ngữ với khung bài và thẻ bài.
   Trước đây chúng là <div> trần nằm trên nền xám, nên cả cột trông trống và rời rạc —
   riêng cột phải là lỗ hổng duy nhất giữa một bố cục toàn khối trắng.
   ⚠️ Đã bỏ `border-left` của chính <aside>: khi các khối bên trong đã có nền và bóng thì
   đường kẻ dọc đó thành vạch thừa chạy song song ngay cạnh mép chúng.
   ⚠️ gap giảm 26px -> 18px: các khối giờ có nền nên tự tách nhau, không cần khoảng hở lớn.
   Bóng nằm ở quy tắc gộp đầu file, ĐỪNG khai báo box-shadow ở đây (sẽ bị đè). */
/* ⚠️ Con trực tiếp của <aside> KHÔNG có nền, viền, bo góc hay đệm — chúng là mục điều
   hướng, phải trần như các mục bên cột trái. Đã thử đóng khung (nền trắng + bóng, rồi
   viền mờ) và BỎ CẢ HAI: đóng khung mục "NỔI BẬT" làm cột phải nặng hơn hẳn cột trái,
   hai bên màn hình lệch tông nhau.
   Chỉ .discord-card và .donate-mini mới được nền trắng — đó là NỘI DUNG bổ sung, không
   phải điều hướng, nên đóng khung là có chủ đích. */
@media(max-width:980px){ aside.side-right{border-left:none; border-top:1px solid var(--line); position:static; padding:24px 0 0;} }
/* Đồng bộ với .menu-heading — xem ghi chú ở đó về lý do bỏ vàng và bỏ chữ giãn. */
.side-title{font-size:12px; letter-spacing:0.02em; text-transform:uppercase; font-weight:700; color:var(--text-dim); margin-bottom:12px; display:flex; align-items:center; gap:8px;}
.side-title::after{content:''; flex:1; height:1px; background:var(--line);}
.feat-card{display:block; padding:10px 0; border-bottom:1px solid var(--line);}
.feat-card:last-child{border-bottom:none;}
.feat-info{display:flex; flex-direction:column; gap:5px; min-width:0;}
.feat-info .badge{font-size:8px; padding:2px 6px; border-radius:3px; align-self:flex-start;}
.feat-title{font-size:12.5px; font-weight:600; line-height:1.4;}
.feat-card:hover .feat-title{color:var(--text-main);}
.donate-mini{
  /* ⚠️ ĐỪNG quay lại linear-gradient(..., #E8DCC0). Đó là dải chuyển sang kem vàng,
     thứ duy nhất còn sót lại làm cột phải lệch tông so với phần còn lại của trang.
     NỀN TRẮNG là CÓ CHỦ ĐÍCH, cùng lý do với .discord-card ở trên. */
  background:var(--paper);
  color:var(--ink); border-radius:10px; padding:20px;
  border:1px solid var(--paper-edge);
}
.donate-head{display:flex; align-items:center; gap:10px; margin-bottom:8px;}
.donate-icon-badge{
  width:30px; height:30px; border-radius:8px; flex-shrink:0;
  background:var(--seal); color:#fff;
  display:flex; align-items:center; justify-content:center; font-size:14px;
}
.donate-mini h4{font-family:'Noto Serif', serif; font-size:15px; font-weight:700;}
.donate-mini p{font-size:11.5px; color:var(--ink-soft); margin-bottom:14px; line-height:1.6;}

.donate-method{
  /* Thẻ ngoài giờ đã trắng nên nền trắng 50% không còn thấy gì — dùng xám nhạt
     để ô nhập vẫn tách khỏi thẻ. */
  background:var(--paper-soft); border:1px solid var(--paper-edge);
  border-radius:8px; padding:14px; margin-bottom:4px;
}
.donate-method-label{
  font-family:'JetBrains Mono', monospace; font-size:9.5px; letter-spacing:0.1em;
  color:var(--seal); text-transform:uppercase; text-align:center; margin-bottom:10px;
}
.donate-qr{width:100%; max-width:150px; margin:0 auto 8px; aspect-ratio:1/1; border-radius:6px; overflow:hidden; border:1px solid var(--paper-edge); background:#fff;}
.donate-qr img{width:100%; height:100%; object-fit:contain; display:block;}
.donate-note{font-family:'JetBrains Mono', monospace; font-size:10px; color:var(--ink-soft); text-align:center;}

.donate-divider{display:flex; align-items:center; gap:10px; margin:14px 0; color:var(--ink-soft); font-size:10.5px;}
.donate-divider::before, .donate-divider::after{content:''; flex:1; height:1px; background:var(--paper-edge);}

.donate-paypal-btn{
  display:flex; align-items:center; justify-content:center; gap:8px; width:100%;
  background:#fff; color:#003087; font-weight:700; font-size:12.5px;
  padding:10px; border-radius:8px; border:1px solid var(--paper-edge);
  transition:opacity 0.2s;
}
.donate-paypal-btn:hover{opacity:0.85;}
.paypal-mark{
  font-family:'Georgia', serif; font-style:italic; font-weight:900; font-size:13px;
  color:#003087; letter-spacing:-0.5px;
}

.btn-donate-mini{width:100%; background:var(--seal); color:var(--paper); font-weight:600; font-size:12.5px; padding:9px; border-radius:6px; border:none;}
.topic-chips{display:flex; flex-wrap:wrap; gap:7px;}
/* Nền đặc thay cho viền: 17 chip có viền xếp cạnh nhau tạo ra một lưới đường kẻ,
   đúng thứ làm cột phải trông như bị đóng khung. */
.topic-chips a{font-family:'JetBrains Mono', monospace; font-size:10.5px; padding:5px 11px; background:var(--field-bg); border:1px solid transparent; border-radius:20px; color:var(--text-dim); transition:background 0.12s, color 0.12s;}
.topic-chips a:hover{background:var(--field-bg-hover); color:var(--text-main);}
/* NỀN TRẮNG là CÓ CHỦ ĐÍCH: đây là nội dung ta bổ sung chứ không phải điều hướng, nên nó
   được phép nổi lên khỏi cột. Đừng gỡ nền này để "cho đồng bộ với NỔI BẬT" — hai thứ
   khác loại nhau. */
.discord-card{
  background:var(--void-2); border:1px solid var(--line); border-radius:10px;
  padding:18px; text-align:center;
}
.discord-card-icon{
  width:56px; height:56px; border-radius:14px; object-fit:cover;
  margin:0 auto 12px; display:block; border:1px solid var(--line);
}
.discord-card-text{
  font-size:12.5px; color:var(--text-dim); line-height:1.6; margin-bottom:14px;
}
.discord-card-btn{
  display:flex; align-items:center; justify-content:center; gap:8px;
  background:#5865F2; color:#fff; font-weight:700; font-size:12.5px;
  padding:10px; border-radius:8px; transition:opacity 0.2s;
}
.discord-card-btn:hover{opacity:0.88;}
/* Đã xoá 10/09/2026: một quy tắc .topic-chips a:hover trùng lặp nằm ở đây, tô vàng
   viền và chữ. Nó đứng SAU quy tắc hover kiểu Facebook ở phần trên nên âm thầm ghi đè
   quy tắc đó. ⚠️ Sửa màu mà không thấy đổi thì tìm quy tắc trùng ở cuối file trước. */

footer.site-footer{border-top:1px solid var(--line); padding:26px 24px; display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:12px; max-width:1400px; margin:0 auto;}
footer.site-footer .mono{font-size:11px; color:var(--text-dim-2);}

/* ---------- PHÂN TRANG TRANG CHỦ ---------- */
.pager{display:flex; gap:6px; justify-content:center; flex-wrap:wrap; margin:26px 0 8px;}
.pager a, .pager span{font-family:'JetBrains Mono', monospace; font-size:12px;
  padding:7px 13px; border-radius:6px; border:1px solid var(--line); color:var(--text-dim);}
.pager a:hover{border-color:var(--text-dim); color:var(--text-main);}
.pager .on{background:var(--sel-bg); border-color:var(--text-dim); color:var(--text-main); font-weight:600;}
/* Nút Trước/Sau khi không còn trang để đi: làm mờ hẳn, không phải link */
.pager .off{color:var(--void-3); border-color:var(--void-2);}

/* Số bài trong submenu: nhỏ và mờ hơn số ở menu chính cho khỏi tranh chỗ với tên danh mục */
.region-submenu .count{font-size:10px; color:var(--text-dim-2); flex-shrink:0;}

/* ---------- MÃ NEO CỦA TỪ KHOÁ [xx]...[exx] ---------- */
/* Bản thân mã neo không đổi hình dáng chữ. Chỉ khi người đọc nhảy tới đúng nó
   (:target) mới sáng lên vài giây để chỉ rõ "chỗ bạn tìm nằm đây". */
/* ⚠️ Lấy theo --header-h chứ ĐỪNG ghi cứng 80px. Thanh đầu trang cao 71px trên máy tính
   nhưng 65px rồi 55px ở màn hình hẹp — ghi cứng thì ở một cỡ màn hình nào đó dòng được
   nhảy tới sẽ nằm khuất sau thanh đó, người dùng tưởng là bấm không ăn. */
.kw-anchor{scroll-margin-top:calc(var(--header-h) + 24px);}
.kw-anchor:target{
  background:rgba(217,166,72,0.35); border-radius:3px;
  box-shadow:0 0 0 4px rgba(217,166,72,0.35);
  animation:kw-flash 2.4s ease-out 1;
}
@keyframes kw-flash{
  0%, 55%{background:rgba(217,166,72,0.55); box-shadow:0 0 0 4px rgba(217,166,72,0.55);}
  100%{background:rgba(217,166,72,0.16); box-shadow:0 0 0 4px rgba(217,166,72,0.16);}
}

/* ---------- DÒNG THÔNG TIN DƯỚI TIÊU ĐỀ ---------- */
/* Icon nhúng thẳng dạng SVG, không nạp bộ icon ngoài -> không thêm request, không phụ thuộc mạng. */
.article-meta{display:flex; align-items:center; gap:9px; flex-wrap:wrap;}
.meta-item{display:inline-flex; align-items:center; gap:5px;}
/* Dấu ngăn mờ hơn chữ để mắt lướt qua, không đọc thành ký tự */
.meta-sep{color:var(--paper-edge); user-select:none;}
/* Icon dùng lại cho Chia sẻ và Lượt xem. Nhúng SVG thẳng, không nạp bộ icon ngoài. */
.meta-ic{width:14px; height:14px; flex-shrink:0; opacity:0.6;}
.share-btn{position:relative; display:inline-flex; align-items:center; gap:5px;
  background:none; border:0; padding:0; cursor:pointer; color:inherit;
  font-family:inherit; font-size:inherit;}
.share-btn:hover{color:var(--ink);}
/* Tên tác giả: nút thật để bàn phím Tab tới được, nhưng trông như chữ thường */
.author-btn{position:relative; background:none; border:0; padding:0; cursor:pointer;
  font-family:var(--font-body, 'Inter'), sans-serif; font-size:12.5px; font-weight:700; color:#3B72C4;}
.author-btn.plain{cursor:default;}
.author-btn:hover{text-decoration:underline;}
/* Báo "đã sao chép" hiện NGAY TRÊN tên, không phải khung nổi giữa màn hình */
.author-tip{position:absolute; left:50%; bottom:calc(100% + 6px); transform:translateX(-50%);
  background:#1C1E21; color:#FFFFFF; font-size:10.5px; font-weight:500; white-space:nowrap;
  padding:3px 8px; border-radius:4px; opacity:0; pointer-events:none; transition:opacity .15s;}
.author-tip::after{content:''; position:absolute; left:50%; top:100%; transform:translateX(-50%);
  border:4px solid transparent; border-top-color:#241F16;}
.author-tip b{color:#D9A648; font-weight:700;}
.author-btn.copied .author-tip, .share-btn.copied .author-tip{opacity:1;}
/* Chữ "Patch" do hệ thống tự sinh, người viết chỉ điền số phiên bản */
.patch-label{color:var(--ink); font-weight:700;}

/* ======================================================================================
   TRANG CHỦ "LÂM TUYẾT" — dựng theo demo-lam-tuyet.html (người dùng duyệt)
   CSS dưới đây là CSS của demo, chuyển TỰ ĐỘNG: mọi tên lớp thêm tiền tố "lt-", mọi bộ chọn gói
   trong .lt (khuôn: src/index.njk). Nội dung từng quy tắc giữ nguyên.
   ⚠️ Vì sao đổi tên lớp: site có sẵn quy tắc chung cho .badge, .row, .panel, .count, .meta, header…
      dùng nguyên tên của demo là hai bên đè nhau.
   ⚠️ Muốn sửa giao diện: sửa ở đây (tên lt-…), đừng dán lại CSS gốc của demo.
   ====================================================================================== */
/* --- nền móng: biến màu của demo khai báo trên .lt, nên màu chữ / phông cũng đặt trên .lt --- */
.lt{color:var(--ink);font-family:Georgia,"Times New Roman",serif}
/* --- trung hoà CSS chung của site chen vào khu .lt --- */
.lt header{position:relative;top:auto;z-index:auto;padding:0;border:0;background:none;backdrop-filter:none}
.lt :is(h1,h2,h3){font-family:inherit;letter-spacing:normal}
.lt{--ink:#182b50;--blue:#164c83;--muted:#728098;--gold:#cbb17b;--paper:#f6faff;--gap:20px}
.lt *{box-sizing:border-box}
.lt [hidden]{display:none!important}
html:has(.lt){scroll-behavior:smooth}
body:has(> .lt){margin:0;color:var(--ink);background:#eaf0f5;font-family:Georgia,"Times New Roman",serif}
.lt button, .lt input{font:inherit}
.lt button{cursor:pointer;color:inherit}
.lt button:focus-visible, .lt input:focus-visible{outline:3px solid #5c95bd;outline-offset:4px}
.lt .lt-page{max-width:1440px;margin:auto;background:var(--paper);overflow:hidden;position:relative}
.lt .lt-hero{height:540px;position:relative}
.lt .lt-hero-art{position:absolute;width:100%;height:100%;object-fit:cover;object-position:center 36%;display:block}
.lt .lt-hero:after{content:"";position:absolute;inset:auto 0 -1px;height:165px;background:linear-gradient(0deg,var(--paper) 4%,#f6faffed 17%,#f6faff9c 38%,#f6faff33 65%,transparent);pointer-events:none}
.lt .lt-hero-content{position:absolute;left:50%;width:40%;top:35%;z-index:1}
.lt .lt-hero h1{margin:0 0 20px}
.lt .lt-brand{display:block;width:100%;filter:drop-shadow(0 3px 8px #17395388)}
.lt .lt-search{display:flex;align-items:center;gap:12px;border:1px solid var(--gold);border-radius:6px;background:#ffffffef;box-shadow:0 4px 20px #22446915;padding:0 15px;height:46px}
.lt .lt-search button{background:none;border:0;padding:0;width:24px;height:24px;color:#537da3}
.lt .lt-search svg{width:24px;height:24px}
.lt .lt-search input{min-width:0;flex:1;outline:none;border:0;background:none;color:var(--ink);font-size:13px}
.lt .lt-search input::placeholder{color:#7c879c}
.lt .lt-search:focus-within{box-shadow:0 0 0 3px #7ea6c33b}
.lt main{width:90%;max-width:1260px;position:relative;z-index:2;margin:auto}
.lt .lt-categories{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--gap);position:relative;margin:-37px 0 var(--gap)}
.lt .lt-category{position:relative;isolation:isolate;display:flex;align-items:center;justify-content:center;gap:13px;height:78px;border:1px solid #bda16a;border-radius:10px 3px 10px 3px;background:linear-gradient(135deg,#fff 0%,#f8fcff 38%,#deebf6 100%);padding:8px 16px;color:#203e66;font-size:18px;font-weight:bold;box-shadow:0 4px 7px #41648919,inset 0 0 0 3px #ffffff,inset 0 0 0 4px #dfd1b2;transition:transform .18s,box-shadow .18s}
.lt .lt-category:before, .lt .lt-category:after{content:"◇";position:absolute;color:#b79a5e;font-size:16px;line-height:1;pointer-events:none}
.lt .lt-category:before{top:3px;left:5px}
.lt .lt-category:after{bottom:3px;right:5px}
.lt .lt-category img{width:57px;height:57px;object-fit:contain;flex-shrink:0;filter:drop-shadow(0 3px 2px #4f77975c);transform:translateY(-3px)}
.lt .lt-category span{position:relative}
.lt .lt-category:hover{transform:translateY(-3px);box-shadow:0 7px 14px #41648928,inset 0 0 0 3px white,inset 0 0 0 4px #c6ae7a}
.lt .lt-category[aria-pressed=true]{background:linear-gradient(135deg,#f9fcff,#cadfec);border-color:#789dad;box-shadow:0 3px 9px #41648922,inset 0 0 0 3px white,inset 0 0 0 4px #c8b684}
.lt .lt-content-layout{display:grid;grid-template-columns:minmax(0,1fr) 280px;gap:var(--gap);align-items:start}
.lt .lt-main-column{min-width:0}
.lt .lt-panel{position:relative;border:1px solid #dbe6f0;border-radius:11px;background:linear-gradient(135deg,#ffffffed,#f7fbffeb);padding:20px;box-shadow:0 4px 18px #3b658508}
.lt .lt-section-head{display:flex;align-items:center;gap:14px;margin-bottom:18px;position:relative;z-index:1}
.lt .lt-section-head h2{display:flex;align-items:center;gap:12px;color:#154779;font-size:24px;white-space:nowrap;margin:0}
.lt .lt-lotus{font-size:31px;line-height:1;color:#477db1}
.lt .lt-rule{height:1px;background:#deebf5;flex:1}
.lt .lt-corner{position:absolute;right:0;top:0;width:110px;opacity:.25;pointer-events:none;filter:saturate(.3)}
.lt .lt-feature-grid{display:grid;grid-template-columns:51% minmax(0,1fr);gap:22px;position:relative;z-index:1}
.lt .lt-thumbnail{width:100%;height:100%;min-height:270px;object-fit:cover;border-radius:7px}
.lt .lt-feature-copy{min-width:0;display:flex;align-items:flex-start;flex-direction:column}
.lt .lt-badge{display:inline-block;padding:6px 10px;border-radius:4px;font:600 10px Arial,sans-serif;line-height:1.3;white-space:nowrap;text-align:center}
.lt .lt-ky-ngo{background:#ffded5;color:#b04b34}
.lt .lt-nhan-gian{background:#dbe7fc;color:#365caa}
.lt .lt-thanh-tuu{background:#ecddfb;color:#854dac}
.lt .lt-tham-hiem-bi-an{background:#f9e5c6;color:#9b6a32}
.lt .lt-feature-copy h3{font-size:27px;line-height:1.22;margin:12px 0 10px}
.lt .lt-feature-copy p{font-size:15px;line-height:1.65;color:var(--muted);margin:0 0 14px}
.lt .lt-meta{display:flex;flex-wrap:wrap;gap:15px;font-size:12px;color:var(--muted);margin:auto 0 15px}
.lt .lt-primary{display:flex;align-items:center;justify-content:center;gap:20px;width:100%;max-width:320px;background:linear-gradient(#315e89,#17476f);border:1px solid #b69a5e;box-shadow:inset 0 0 0 3px #315578,inset 0 0 0 4px #a99a70;border-radius:7px 2px 7px 2px;color:#fff;padding:12px 16px;font-size:15px}
.lt .lt-primary span{font:22px Arial}
.lt .lt-primary:hover{filter:brightness(1.1)}
.lt .lt-latest{margin-top:var(--gap);padding-bottom:10px;scroll-margin-top:20px}
.lt .lt-latest .lt-section-head{margin-bottom:5px}
.lt .lt-show-all{border:0;background:none;font-size:12px;color:var(--blue);white-space:nowrap;padding:5px 0}
.lt .lt-show-all span{font:20px Arial;margin-left:9px}
.lt .lt-row{display:grid;grid-template-columns:88px minmax(0,1fr) 93px 34px;align-items:center;gap:14px;min-height:89px;padding:14px 0;border-bottom:1px solid #e0ebf3}
.lt .lt-row:last-child{border:0}
.lt .lt-row>.lt-badge{justify-self:start;min-width:78px}
.lt .lt-article-title{font-size:18px;font-weight:bold;border:0;background:none;padding:0;text-align:left}
.lt .lt-article-title:hover{color:#467ca4}
.lt .lt-row p{margin:7px 0 0;font-size:13px;line-height:1.5;color:var(--muted)}
.lt .lt-row time{font:11px Arial;color:#77889e;white-space:nowrap}
.lt .lt-row time span{display:none}
.lt .lt-arrow{border:1px solid #d4e3ef;background:#eaf2fa;border-radius:50%;width:34px;height:34px;font:23px Arial;color:#315e86}
.lt .lt-arrow:hover{background:#d6e7f4}
.lt .lt-result-note, .lt .lt-empty{font:13px Arial;color:var(--muted);padding:15px 0}
.lt .lt-sidebar{display:grid;gap:15px}
.lt .lt-side-card{padding:17px;border:1px solid #dbe6f0;border-radius:10px;background:linear-gradient(135deg,#fff,#f4f9ffec);box-shadow:0 4px 18px #3b658508}
.lt .lt-side-heading{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:12px}
.lt .lt-side-heading h2{font-size:19px;color:#1b4b7b;margin:0}
.lt .lt-side-heading>span{color:#7890a8}
.lt .lt-directory button{display:flex;width:100%;gap:11px;align-items:center;padding:8px 0;border:0;border-bottom:1px solid #e4edf5;background:none;text-align:left;font-size:13px}
.lt .lt-directory button:last-child{border-bottom:0}
.lt .lt-directory img, .lt .lt-story-icon{width:25px;height:25px;object-fit:contain;filter:drop-shadow(0 1px 2px #38618a70)}
.lt .lt-story-icon{font-size:25px;text-align:center;color:#9f854d}
.lt .lt-count{margin-left:auto;color:#8794a6;font-size:11px}
.lt .lt-directory button:hover, .lt .lt-directory button.lt-active{color:#327cad;background:#edf5fb}
.lt .lt-support{text-align:center;background:radial-gradient(ellipse at 0% 100%,#e0eaf5,transparent 62%),linear-gradient(135deg,#fff,#fafcff)}
.lt .lt-support .lt-side-heading{justify-content:center;margin-bottom:8px}
.lt .lt-heart{color:#baa06f;font-size:22px}
.lt .lt-support>p{font-size:12px;line-height:1.5;color:#7b889f;margin:0 0 12px}
.lt .lt-qr-placeholder{width:123px;height:123px;border:1px solid #c8b184;outline:1px solid #e4d6bb;outline-offset:3px;border-radius:7px 1px;margin:8px auto 16px;background:#fffdf9;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:7px;color:#877148}
.lt .lt-qr-placeholder svg{width:37px;height:37px;opacity:.6}
.lt .lt-qr-placeholder strong{font-size:12px;font-weight:normal;letter-spacing:1px}
.lt .lt-qr-placeholder>span{font-size:9px;color:#a0947f}
.lt .lt-support-note{font-size:12px;font-style:italic;color:#9c865d}
.lt .lt-supporters ol{list-style:none;margin:0;padding:0}
.lt .lt-supporters li{display:flex;align-items:center;gap:9px;padding:9px 0;border-bottom:1px solid #e6edf4}
.lt .lt-supporters li:last-child{border:0}
.lt .lt-rank{border-radius:50%;width:25px;height:25px;display:grid;place-items:center;font-size:13px;box-shadow:inset 0 0 0 2px #ffffffa3}
.lt .lt-gold{background:#e9cc8f;color:#8e6c2b}
.lt .lt-silver{background:#d8e1ea;color:#6c8095}
.lt .lt-bronze{background:#e8d1bb;color:#9b7352}
.lt .lt-supporters li strong{font-size:12px;font-weight:normal}
.lt .lt-supporters li small{display:none}
.lt .lt-supporters li b{margin-left:auto;font-size:11px;color:#998052;font-weight:normal;white-space:nowrap}
.lt .lt-sample-note{font:9px Arial;color:#97a5b2;line-height:1.5;margin:9px 0 0}
.lt .lt-month{font-size:10px;color:#8b9bad;white-space:nowrap}
.lt .lt-discord-card{position:relative;padding:20px 17px;text-align:left;border:1px solid #d6e3f3;border-radius:10px;background:radial-gradient(ellipse at bottom right,#bad0e8,transparent 70%),linear-gradient(135deg,#e7eefc,#f6faff);color:#254976;overflow:hidden}
.lt .lt-discord-mark{display:none}
.lt .lt-discord-kicker{font:8px Arial;letter-spacing:1.3px;color:#6f88a8}
.lt .lt-discord-card h2{font-size:20px;margin:9px 0}
.lt .lt-discord-card p{font-size:12px;line-height:1.5;color:#6c80a0;margin:0 0 12px}
.lt .lt-discord-card button{border:1px solid #6a85b0;border-radius:5px;background:linear-gradient(#617daf,#3b5c8d);color:white;width:100%;padding:9px;font-size:13px}
.lt .lt-discord-card button span{margin-left:12px}
.lt .lt-discord-card small{display:block;font:8px Arial;margin-top:8px;color:#8195b1}
.lt footer{height:355px;margin-top:0;position:relative;z-index:1;background-image:linear-gradient(to bottom,var(--paper) 0%,#f6faffd9 10%,#f6faff88 24%,#f6faff22 43%,transparent 63%),url("/assets/home-v6/footer/footer-lam-tuyet.webp");background-size:100% 100%,cover;background-position:center,center bottom;background-repeat:no-repeat}
.lt .lt-footer-copy{position:absolute;bottom:0;left:0;right:0;padding:32px 20px 17px;background:linear-gradient(transparent,#f6faffed 50%);text-align:center;color:#4c6a8c;font-size:12px}
.lt .lt-footer-copy strong{display:block;font-size:18px;color:#254b73;margin-bottom:8px}
.lt .lt-footer-copy span{font-size:10px;color:#7b91a9}
@media(min-width:1600px){.lt .lt-hero{height:560px}}
@media(max-width:1100px){.lt .lt-hero{height:480px}
.lt .lt-hero-content{left:48%;width:44%}
.lt .lt-category{font-size:15px;gap:8px;padding:8px}
.lt .lt-category img{width:45px;height:45px}
.lt .lt-content-layout{grid-template-columns:minmax(0,1fr) 250px}
.lt .lt-feature-grid{grid-template-columns:1fr}
.lt .lt-thumbnail{height:220px;min-height:0}
.lt .lt-feature-copy h3{font-size:26px}
.lt .lt-primary{max-width:280px}
.lt .lt-meta{margin:0 0 14px}
.lt .lt-row{grid-template-columns:80px minmax(0,1fr) 32px;gap:10px}
.lt .lt-row time{display:none}
.lt .lt-section-head h2{font-size:22px}
.lt .lt-panel{padding:17px}
.lt .lt-side-card{padding:15px}}
@media(max-width:800px){.lt{--gap:16px}
.lt main{width:92%}
.lt .lt-categories{grid-template-columns:1fr 1fr}
.lt .lt-content-layout{grid-template-columns:1fr}
.lt .lt-feature-grid{grid-template-columns:1fr 1fr}
.lt .lt-thumbnail{height:100%;min-height:230px}
.lt .lt-sidebar{grid-template-columns:1fr 1fr;gap:16px}
.lt .lt-row{min-height:80px;grid-template-columns:88px minmax(0,1fr) 93px 34px}
.lt .lt-row time{display:block}
.lt .lt-category{font-size:17px;height:70px}
.lt .lt-category img{width:52px;height:52px}
.lt .lt-hero-content{top:35%}
.lt footer{height:285px}}
@media(max-width:540px){.lt main{width:90%}
.lt .lt-hero{height:560px}
.lt .lt-hero-art{object-position:center top}
.lt .lt-hero-content{top:auto;bottom:90px;left:7%;width:86%}
.lt .lt-hero:after{height:120px}
.lt .lt-hero h1{margin-bottom:16px}
.lt .lt-categories{margin-top:-34px;gap:12px}
.lt .lt-category{height:68px;font-size:14px;padding:8px;gap:7px}
.lt .lt-category img{width:42px;height:42px}
.lt .lt-feature-grid{grid-template-columns:1fr;gap:17px}
.lt .lt-thumbnail{height:auto;min-height:0;aspect-ratio:1.7}
.lt .lt-section-head h2{font-size:21px;gap:8px}
.lt .lt-section-head{gap:10px}
.lt .lt-feature-copy h3{font-size:27px}
.lt .lt-feature-copy p{font-size:16px;line-height:1.6}
.lt .lt-primary{max-width:none}
.lt .lt-row{grid-template-columns:minmax(0,1fr) 34px;gap:6px 10px;padding:15px 0}
.lt .lt-row>.lt-badge{grid-column:1;min-width:0}
.lt .lt-row>div{grid-column:1}
.lt .lt-row time{display:none}
.lt .lt-row .lt-arrow{grid-column:2;grid-row:1/3}
.lt .lt-row p{font-size:13px}
.lt .lt-sidebar{grid-template-columns:1fr}
.lt .lt-side-card{padding:20px}
.lt .lt-directory button{font-size:14px;padding:10px 0}
.lt .lt-side-heading h2{font-size:21px}
.lt .lt-support>p, .lt .lt-support-note{font-size:14px}
.lt .lt-qr-placeholder{width:150px;height:150px}
.lt .lt-supporters li strong, .lt .lt-supporters li b{font-size:14px}
.lt .lt-supporters li{padding:12px 0}
.lt .lt-discord-card{padding:23px}
.lt .lt-discord-card p{font-size:14px}
.lt .lt-discord-card button{font-size:15px;padding:12px}
.lt .lt-show-all{font-size:11px}
.lt .lt-show-all span{margin-left:4px}
.lt footer{height:240px;background-position:center,center bottom}
.lt .lt-footer-copy{font-size:11px}}
@media(prefers-reduced-motion:reduce){html:has(.lt){scroll-behavior:auto}
.lt *{transition:none!important}}
.lt main{margin-top:-24px}
.lt .lt-row{grid-template-columns:minmax(0,1fr) 93px 34px;gap:16px;min-height:106px;padding:17px 0}
.lt .lt-row-copy{min-width:0}
.lt .lt-article-tags{display:flex;align-items:center;flex-wrap:wrap;gap:7px;margin:0 0 10px;font-family:Arial,sans-serif}
.lt .lt-article-tags .lt-badge{font-size:10px;font-weight:500;padding:4px 8px;min-width:0;line-height:1.35}
.lt .lt-tier-tag{background:#f6ecd6;color:#967337}
.lt .lt-region-tag{background:#e8f0f8;color:#587995}
.lt .lt-tag-separator{font-size:11px;color:#bcc6d1}
.lt .lt-feature-copy h3{margin-top:0}
.lt .lt-feature-copy .lt-article-tags{margin-bottom:12px}
.lt .lt-directory button[aria-pressed=true]{color:#327cad;background:#edf5fb}
.lt .lt-row .lt-article-title{line-height:1.4}
.lt .lt-row p{margin-top:5px}
@media(max-width:1100px){.lt .lt-row{grid-template-columns:minmax(0,1fr) 34px}
.lt .lt-row time{display:none}}
@media(max-width:800px){.lt .lt-row{grid-template-columns:minmax(0,1fr) 93px 34px}
.lt .lt-row time{display:block}}
@media(max-width:540px){.lt main{margin-top:-25px}
.lt .lt-row{grid-template-columns:minmax(0,1fr) 34px;gap:12px;padding:17px 0}
.lt .lt-row>div{grid-column:1}
.lt .lt-row .lt-arrow{grid-column:2;grid-row:1}
.lt .lt-row time{display:none}
.lt .lt-article-tags{gap:5px}
.lt .lt-article-tags .lt-badge{font-size:10px;padding:4px 7px}}
.lt .lt-article-tags{gap:5px;margin-bottom:8px;align-items:center;justify-content:flex-start}
.lt .lt-article-tags .lt-badge{display:inline-flex;flex:0 0 auto;width:max-content;max-width:100%;min-width:0!important;padding:2px 5px!important;font-size:9px!important;line-height:1.35;font-weight:400!important;border-radius:3px;letter-spacing:0}
.lt .lt-article-tags .lt-ky-ngo{background:#f8eae5;color:#9a7165}
.lt .lt-article-tags .lt-tier-tag{background:#f4f0e5;color:#918365}
.lt .lt-article-tags .lt-region-tag{background:#edf2f6;color:#7b8c9e}
.lt .lt-row .lt-article-title{font-size:19px}
.lt .lt-feature-copy .lt-article-tags{margin-bottom:9px}
.lt .lt-carousel-controls{display:flex;align-items:center;gap:8px;flex-shrink:0}
.lt .lt-carousel-controls button{display:grid;place-items:center;width:28px;height:28px;padding:0;background:#f3f8fc;border:1px solid #d6e4ef;border-radius:50%;color:#507696;font:22px Arial}
.lt .lt-carousel-controls button:hover{background:#e2edf6}
.lt .lt-carousel-count{font:10px Arial;color:#8596a8;white-space:nowrap}
.lt .lt-carousel-pagination{display:flex;justify-content:center;gap:7px;margin-top:17px}
.lt .lt-carousel-dot{position:relative;border:0;background:transparent;padding:0;width:23px;height:24px}
.lt .lt-carousel-dot:before{content:"";display:block;width:6px;height:6px;border-radius:10px;background:#ccdbe6;margin:auto;transition:width .16s,background .16s}
.lt .lt-carousel-dot[aria-pressed=true]:before{width:19px;background:#779bb8}
.lt .lt-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
.lt .lt-feature-copy h3{min-height:2.44em}
.lt .lt-featured .lt-thumbnail{aspect-ratio:1.5}
.lt .lt-featured .lt-feature-copy>p{min-height:7.5em}
@media(max-width:540px){.lt .lt-featured .lt-section-head{gap:7px}
.lt .lt-featured .lt-section-head h2{font-size:19px}
.lt .lt-carousel-controls{gap:5px}
.lt .lt-carousel-controls button{width:25px;height:25px}
.lt .lt-featured .lt-section-head .lt-rule{display:none}
.lt .lt-carousel-controls{margin-left:auto}
.lt .lt-carousel-count{font-size:9px}
.lt .lt-feature-copy h3, .lt .lt-featured .lt-feature-copy>p{min-height:0}
.lt .lt-article-tags .lt-badge{font-size:9px!important;padding:2px 5px!important}}
@media(prefers-reduced-motion:reduce){.lt .lt-carousel-dot:before{transition:none}}
.lt .lt-carousel-viewport{position:relative;overflow:hidden;isolation:isolate}
.lt .lt-carousel-viewport>.lt-feature-grid{width:100%;margin:0}
.lt .lt-carousel-outgoing{position:absolute!important;inset:0 auto auto 0;width:100%;pointer-events:none}
.lt .lt-carousel-viewport.lt-is-sliding>.lt-feature-grid{will-change:transform}
.lt .lt-carousel-viewport.lt-is-sliding{overflow:hidden}

/* --- phần THÊM so với demo: phần tử demo là <button> (mở hộp thoại "bản xem thử") -> trên site
       là LIÊN KẾT thật tới bài; và ảnh QR thật thay ô giữ chỗ --- */
.lt a{color:inherit}
.lt .lt-feature-grid > a{display:block}
.lt .lt-feature-copy h3 a, .lt .lt-article-title{text-decoration:none;color:inherit}
.lt .lt-article-title{display:inline-block}
.lt .lt-primary, .lt .lt-arrow, .lt .lt-discord-btn, .lt .lt-donate-link{text-decoration:none}
.lt .lt-arrow{display:grid;place-items:center}
.lt .lt-discord-btn{display:block;text-align:center;border:1px solid #6a85b0;border-radius:5px;background:linear-gradient(#617daf,#3b5c8d);color:#fff;width:100%;padding:9px;font-size:13px}
.lt .lt-discord-btn span{margin-left:12px}
.lt .lt-qr{display:block;width:150px;height:150px;object-fit:contain;margin:8px auto 16px;background:#fffdf9;border:1px solid #c8b184;outline:1px solid #e4d6bb;outline-offset:3px;border-radius:7px 1px}
.lt .lt-donate-link{display:inline-block;margin:0 auto 12px;padding:8px 18px;border:1px solid #b69a5e;border-radius:5px;background:linear-gradient(#315e89,#17476f);color:#fff;font-size:13px}
.lt .lt-badge.lt-khac, .lt .lt-article-tags .lt-khac{background:#eef2f6;color:#6b7c8e}
/* ô tìm kiếm dùng bộ tìm kiếm toàn site: khung kết quả thả xuống dưới ô */
.lt .lt-search{position:relative}
.lt .lt-search .search-results{position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:30;text-align:left;font-family:var(--font-body,'Inter'),sans-serif}

/* Liên kết thông tin ở footer (Giới thiệu, Liên hệ, Chính sách...) — chỉ chữ, không ảnh. */
.footer-links{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 18px;font-size:12.5px;line-height:1.6}
.footer-links a{color:var(--ui-muted,var(--text-dim-2));text-decoration:none}
.footer-links a:hover{color:#1877F2}
.lt-footer .footer-links{margin-bottom:8px}

/* Trang thông tin: Giới thiệu, Liên hệ, Chính sách bảo mật, Điều khoản. */
.info-page h1{font-size:26px;margin:0 0 12px}
.info-page h2{font-size:18px;margin:24px 0 8px}
.info-page p,.info-page li{font-size:14.5px;line-height:1.8}
.info-page ul{padding-left:22px;margin:0 0 12px}
.info-page .info-updated{font-size:12.5px;color:var(--ink-soft);margin:-4px 0 16px}
.info-page ul{list-style:disc}
.info-page li{margin:2px 0}
.info-page a{color:#1877F2}

/* Mô tả bài trên thẻ (trang chủ, danh mục, khu vực, cấp) — font thông báo Gmail như khung [box].
   Tên bài trong mô tả tự sinh được bọc <strong> (excerptHtml trong .eleventy.js). */
.art-desc, .lt-row p, .lt-feature-copy > p{font-family:'Google Sans Text',system-ui,-apple-system,'Segoe UI',Roboto,Arial,sans-serif;}
.art-desc strong, .lt-row p strong, .lt-feature-copy > p strong{font-weight:700;}

/* ---------- BÀI VIẾT LIÊN QUAN (dưới bài, post.njk) — 30/09/2026 ----------
   Khối PHỤ, cố ý nhạt hơn thân bài (người dùng thấy bản đầu giành chú ý với bài chính):
   tiêu đề khối giữ kiểu .side-title nhỏ in hoa như sidebar; tên bài 15px chữ thường (không dùng
   font tiêu đề đậm); mô tả 12.5px chữ trơn, 2 dòng; không nhấc ô khi rê chuột, chỉ đổi màu viền.
   Lưới 2 cột, điện thoại 1 cột. Cả ô là một link, không gạch chân. */
/* KHÔNG bọc khung .ui-block (nền trắng, viền kép, hoa văn đáy): nằm thẳng trên nền trang. */
.bai-lien-quan{margin-top:28px; padding:0 2px; max-width:100%;}
.blq-luoi{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px;}
.blq-o{display:flex; flex-direction:column; gap:4px; min-width:0; padding:10px 14px; border:1px solid var(--line); border-radius:8px;
  background:var(--void-2); color:inherit; text-decoration:none; transition:border-color .15s, background .15s;}
/* Từng ô giữ nền trắng (tối: nền khối), chỉ bỏ khung bọc ngoài — theo ý người dùng 30/09/2026. */
.blq-o:hover{border-color:#8DB6EC; background:color-mix(in srgb, #1877F2 4%, var(--void-2));}
.blq-o:focus-visible{outline:2px solid #1877F2; outline-offset:2px;}
.blq-ten{display:flex; align-items:center; gap:6px; font-weight:600; font-size:15px; line-height:1.45; overflow-wrap:anywhere;}
.blq-ten .title-emoji{width:18px; height:18px; flex:none; object-fit:contain; margin:0;}
.blq-mo{font-size:12.5px; line-height:1.6; color:var(--text-dim); display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;}
@media(max-width:640px){ .blq-luoi{grid-template-columns:1fr;} .bai-lien-quan{padding:0 4px;} }
@media(prefers-reduced-motion:reduce){ .blq-o{transition:none;} }
