:root{
  /* ── Giao diện SƠN MÀI: đỏ son, vàng đồng, chữ vàng kem ──
     Trước đây đây là bảng SÁNG (nền trời nhạt, thẻ trắng, nhấn xanh dương).
     Bỏ đi vì hai lẽ: nó không cùng nhà với bàn cờ gỗ vàng chữ đỏ nằm giữa
     trang, và mặc định của trang đã là nền tối từ lâu nên gần như không ai
     bấm sang. Nay nấc ấy là sơn mài — cùng bảng màu với trang chủ.

     Số đo giữ đúng ràng buộc của bảng tối:
       • thẻ nổi hơn nền 1.22 lần (cần ≥1.20 thì mắt mới tách được hai lớp)
       • chữ mờ nhất (--faint) đạt 5.11 trên mặt thẻ, trên ngưỡng 4.5 của WCAG AA
       • chữ trên nút vàng đạt 10.6
     Mọi thứ nằm TRÊN MẶT GỖ vẫn giữ nguyên như trước (--board-trim, --hint,
     --last): bàn cờ không đổi màu theo giao diện. */
  --bg:#2A0A08;
  --surface:#46180F;
  --surface-2:#38120C;
  --edge:#6B2E22;
  --ink:#F4E7C8;
  --muted:#C9A882;
  --faint:#B4906A;
  --gold:#D9A441;
  --gold-soft:#A97C34;
  --gold-vivid:#F0C868;
  --grad:linear-gradient(135deg,#F0C868 0%,#B3221E 100%);
  --on-accent:#3A0C0A;
  --cinnabar:#EC6A5C;
  /* Xanh "được việc": dùng cho dòng báo đã lưu và nhãn tin công khai. Trên nền
     đỏ son thì xanh ngọc là màu DUY NHẤT không lẫn vào đâu — vàng thì trùng
     màu nhấn, đỏ thì trùng nền. */
  --jade:#5DCD98;
  /* Viền quân đang chọn. Cố định cho cả sáng lẫn tối như mọi màu bàn cờ khác:
     người chơi nhớ "quân sáng xanh là quân mình đang cầm", đổi màu theo chế độ
     máy thì mỗi lúc một khác. Xanh lục chứ không lấy màu nhấn của trang — nhấn
     của trang là vàng/hổ phách, đúng màu ô đánh dấu nước vừa đi. */
  --chon:#12B981;
  --piece-red:#B02A1C;
  --piece-black:#123048;
  --jet:#1A0605;
  --wood-1:#FCDFAC;
  --wood-2:#F6D08D;
  --wood-3:#EFC077;
  --wood-ink:rgba(120,72,24,.16);
  --board:#F6D08D;
  --board-2:#EFC077;
  --board-trim:#C98B2E;
  --line:#4A260C;
  --disc:#FDF8EE;
  --disc-2:#F2E7D2;
  --disc-edge:#9A7443;
  /* VÀNH GỖ quanh con cờ — thứ làm nên khối ở PHÍA NGOÀI mặt cờ.
     Bảy vòng đồng tâm nhích dần ra, sáng ở trong tối dần ra ngoài, cộng một
     vệt bắt sáng lệch lên trên-trái cho đúng hướng nguồn sáng của mặt cờ. Ở
     cỡ bàn thường mỗi vòng chưa dày tới một điểm ảnh, nên mắt đọc cả dãy
     thành MỘT mặt cong chứ không thành bảy vòng riêng.
     Gói vào một biến vì ba nơi phải dùng đúng dãy này — quân thường, quân
     đang chọn, quân đang bay. Ba nơi ấy đều viết đè cả box-shadow, nên chép
     tay ra ba chỗ là bảo đảm có ngày lệch nhau.
     Màu ĐẶT CỨNG chứ không lấy theo biến chủ đề: bàn cờ phải giữ nguyên màu
     ở cả chế độ sáng lẫn tối. */
  --vanh-quan:
    0 0 0 .14cqw #F1DBAB,
    0 0 0 .27cqw #E0B972,
    0 0 0 .41cqw #C79647,
    -.07cqw -.11cqw 0 .53cqw #F6E4BC,
    0 0 0 .56cqw #A6762F,
    0 0 0 .68cqw #7C511E,
    0 0 0 .75cqw #4A2C0E;
  /* VÀNH VÁT ở mặt trong, ngay sát vành gỗ: một nét sáng ôm nửa trên-trái và
     một nét tối ôm nửa dưới-phải, cả hai đều SẮC cạnh chứ không loang. Đây là
     thứ làm con cờ đọc ra như một khối kim loại dập chìm chứ không phải một
     đĩa gỗ phẳng — cùng kiểu vát mà trình duyệt vẽ cho viền "outset".
     Dùng ở BỐN chỗ: quân thường, quân đang chọn, quân đang bay, và quân trong
     khay soạn thế cờ. Gói vào biến vì cả bốn chỗ đều viết đè cả box-shadow. */
  --vat-quan:
    inset .34cqw .34cqw 0 rgba(226,226,228,.92),
    inset -.34cqw -.34cqw 0 rgba(42,42,48,.68);
  --shadow:rgba(0,0,0,.45);
  --shadow-strong:rgba(0,0,0,.62);
  --hint:rgba(201,139,46,.92);
  --last:rgba(201,139,46,.30);
  --radius:14px;
}

/* ── Giao diện TỐI: tím, một bảng màu DUY NHẤT ──

   Trước đây bảng tối chép ra hai chỗ: một cho máy đặt "theo hệ thống", một cho
   người tự bấm nút tối. Đổi một màu phải nhớ sửa cả hai, quên một chỗ là hai
   chế độ lệch nhau — và không ai phát hiện ra cho tới khi có người bấm nút.

   Giờ giá trị thật nằm đúng MỘT chỗ (--t-*), hai khối dưới chỉ trỏ vào đó.
   Muốn chỉnh màu thì sửa một dòng.

   Độ sáng chọn theo số đo, không theo cảm tính:
     • thẻ phải nổi hơn nền ít nhất 1.2 lần thì mắt mới tách được hai lớp;
       bảng cũ chỉ 1.19 nên thẻ chìm lẫn vào nền.
     • chữ mờ (--faint) dùng cho hạt giống, lượt hiện, giờ giấc — phải đạt 4.5
       theo WCAG AA; bảng cũ chỉ 3.82, tức là không đọc nổi trong nắng.
     • nền cũ tối L=0.008, gần như đen tuyền; nâng lên 0.013 vẫn tối mà bớt
       cảm giác thủng một lỗ đen giữa màn hình. */
:root{
  --t-bg:#241640;
  --t-surface:#3A2768;
  --t-surface-2:#2E1D54;
  --t-edge:#59417F;
  --t-ink:#F4F0FF;
  --t-muted:#C3B4E0;
  --t-faint:#A695CB;
  --t-gold:#FFD84D;
  --t-gold-soft:#9A8038;
  --t-gold-vivid:#FFD84D;
  --t-grad:linear-gradient(135deg,#FFD84D 0%,#FFC01F 100%);
  --t-on-accent:#241541;
  --t-cinnabar:#FF8574;
  --t-jade:#5FE0B0;
  --t-piece-red:#C22E1B;
  --t-piece-black:#1C0F2E;
  --t-jet:#241541;
  --t-wood-1:#E6BE7E;
  --t-wood-2:#DBAF6B;
  --t-wood-3:#CFA25C;
  --t-wood-ink:rgba(70,38,8,.20);
  --t-board:#DBAF6B;
  --t-board-2:#CFA25C;
  --t-board-trim:#8A5C16;
  --t-line:#2A1405;
  --t-disc:#F0E6D2;
  --t-disc-2:#DDCDB0;
  --t-disc-edge:#7A5C36;
  --t-shadow:rgba(0,0,0,.5);
  --t-shadow-strong:rgba(0,0,0,.68);
  --t-hint:rgba(138,92,22,.95);
  --t-last:rgba(138,92,22,.34);
}

/* Hai lối vào chế độ tối, cùng trỏ về một bảng màu ở trên. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --bg:var(--t-bg); --surface:var(--t-surface); --surface-2:var(--t-surface-2);
    --edge:var(--t-edge); --ink:var(--t-ink); --muted:var(--t-muted); --faint:var(--t-faint);
    --gold:var(--t-gold); --gold-soft:var(--t-gold-soft); --gold-vivid:var(--t-gold-vivid);
    --grad:var(--t-grad); --on-accent:var(--t-on-accent); --cinnabar:var(--t-cinnabar);
    --jade:var(--t-jade);
    --jet:var(--t-jet);
    --shadow:var(--t-shadow); --shadow-strong:var(--t-shadow-strong);
    /* Màu BÀN CỜ cố tình KHÔNG đổi theo sáng/tối. Bàn cờ tướng là vật thật —
       gỗ vàng, chữ đỏ và đen — chứ không phải một khối giao diện; đổi nó theo
       chế độ máy thì cùng một ván nhìn ra hai bàn khác nhau, mà người chơi
       nhận diện quân bằng màu. Nên --wood-*, --board*, --line, --disc*,
       --piece-*, --hint, --last chỉ khai báo MỘT lần ở :root và giữ nguyên.
       Trang xung quanh vẫn đổi tối bình thường. */
  }
}
:root[data-theme="dark"]{
  --bg:var(--t-bg); --surface:var(--t-surface); --surface-2:var(--t-surface-2);
  --edge:var(--t-edge); --ink:var(--t-ink); --muted:var(--t-muted); --faint:var(--t-faint);
  --gold:var(--t-gold); --gold-soft:var(--t-gold-soft); --gold-vivid:var(--t-gold-vivid);
  --grad:var(--t-grad); --on-accent:var(--t-on-accent); --cinnabar:var(--t-cinnabar);
    --jade:var(--t-jade);
  --jet:var(--t-jet);
  --shadow:var(--t-shadow); --shadow-strong:var(--t-shadow-strong);
  /* Màu bàn cờ giữ nguyên — xem ghi chú ở khối tối phía trên. */
}

*{box-sizing:border-box}
body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:"Be Vietnam Pro","Segoe UI",system-ui,-apple-system,sans-serif;
  font-size:15px;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
}

/* ── Liên kết ─────────────────────────────────────────────────────────
   Trước đây KHÔNG có quy tắc nào cho <a>, nên trình duyệt lấy màu mặc định
   của chính nó: #0000EE khi chưa xem và #551A8B khi đã xem. Trên nền tối của
   trang, hai màu ấy chỉ đạt 1.14–1.95:1 — coi như không đọc được. Và vì màu
   "đã xem" tối hơn màu "chưa xem" nên cùng một bảng lại có dòng đậm dòng
   nhạt, trông như lỗi dữ liệu.

   Lấy màu nhấn của giao diện: 7.88:1 ở bảng sơn mài, 9.09:1 ở bảng tối.
   :visited giữ NGUYÊN màu — trong bảng danh sách, việc "đã bấm vào giải này
   chưa" không phải thông tin cần khoe, mà đổi màu thì hàng lại lem nhem.
   Chỗ nào cần khác (nút, chân trang, thẻ vinh danh) đã có quy tắc riêng đè
   lên nhờ độ ưu tiên cao hơn. */
a{color:var(--gold-vivid)}
a:visited{color:var(--gold-vivid)}
a:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:4px}

.wrap{
  max-width:1040px;
  margin:0 auto;
  padding:28px 20px 56px;
  display:flex;
  flex-direction:column;
  gap:22px;
}

/* ---------- header ---------- */
header{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap}
/* Khối tên trang CO ĐƯỢC. `header` là flex-wrap:wrap, nên khi tên trang cộng
   hàng công cụ dài hơn bề ngang một chút là hàng công cụ rơi hẳn xuống dòng
   thứ hai — đầu trang cao thêm chừng 80px, và mấy trang tính bàn cờ theo chỗ
   trống còn lại (trang đánh với máy, phòng đấu) mất đúng ngần ấy chiều cao
   bàn cờ. Đã xảy ra thật: thêm đúng một nút 36px vào hàng công cụ là trang
   "Đánh với máy" ở khổ 1440 rơi từ một dòng xuống hai.
   Cắt bớt dòng phụ đề bao giờ cũng đỡ hơn là gãy cả bố cục — và flex chỉ cắt
   khi THẬT SỰ hết chỗ, màn rộng thì phụ đề vẫn nguyên câu. */
/* `flex:1 1 200px` chứ không phải để mặc: flex XUỐNG DÒNG TRƯỚC KHI CO. Nó
   xếp từng khối lên dòng theo bề rộng NỘI DUNG, và chỉ co những khối đã nằm
   sẵn trên dòng ấy — nên `min-width:0` một mình không cứu được gì. Khai một
   bề rộng cơ sở nhỏ thì cả hai khối luôn vừa một dòng, rồi `flex-grow` trả
   lại cho tên trang đúng phần còn thừa. */
.brand{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1 1 200px}
.brand .tagline{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Mã phòng thì KHÔNG cắt: đó là dãy ký tự người ta đọc cho bạn qua điện
   thoại, mất một ký tự cuối là bạn vào nhầm phòng. Luật này lặp lại ở khổ hẹp
   (dòng ~1313) vì cùng một lý do. */
.brand .tagline.ma-phong{overflow:visible;text-overflow:clip}
h1{
  font-family:Fraunces,Georgia,serif;
  font-weight:700;
  font-size:clamp(28px,4.2vw,40px);
  letter-spacing:-.02em;
  line-height:1;
  margin:0;
  text-wrap:balance;
}
.tagline{color:var(--muted);font-size:13.5px}
.rule{height:2px;border-radius:2px;background:var(--grad);opacity:.55}

/* ---------- logo ban quản trị tải lên ----------
   Máy chủ chèn thẻ <img class="logo-anh"> vào trong <h1> và đánh dấu
   data-logo="thay" hoặc "canh". Không có logo thì không có thuộc tính nào,
   nên mọi luật dưới đây ngủ yên — đầu trang giữ nguyên như cũ.

   Đo bằng `em` chứ không phải px: cỡ chữ h1 đã là clamp() co theo bề ngang
   màn, nên logo tự đi theo và không cần thêm một nấc @media nào nữa. */
h1[data-logo], h1[data-logo] a{display:flex;align-items:center;gap:9px}
.logo-anh{
  height:1.15em; width:auto; max-width:min(46vw, 240px); flex:none;
  display:block; object-fit:contain;
}
/* "Ảnh thay chữ": giấu chữ khỏi MẮT chứ không xoá khỏi trang — máy đọc màn
   hình và máy tìm kiếm vẫn cần đọc được tên trang, mà <h1> rỗng thì Google
   coi như trang không có tiêu đề chính. */
h1[data-logo="thay"] .th-chu{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;
}

/* ---------- layout ---------- */
/* Một cột duy nhất, căn giữa. Trước đây có thêm cột phải 296px cho biên bản,
   nhưng biên bản đã chuyển xuống dưới bàn cờ nên cột đó chỉ còn là khoảng
   trống kéo lệch bàn cờ sang trái. */
.game{display:grid;grid-template-columns:minmax(0,1fr);justify-items:center}
.board-col{width:100%}

/* ---------- board ---------- */
.board-col{display:flex;flex-direction:column;gap:10px;align-items:center;
  /* Một bề ngang duy nhất cho bàn cờ, hai thanh kỳ thủ và thanh thoại — trước
     đây mấy thanh này co theo chữ nên hẹp hơn bàn cờ, nhìn rời rạc.
     Kẹp thêm theo chiều cao màn hình để cả cụm luôn nằm trong một khung hình:
     bàn cờ cao gấp 632/572 lần bề ngang, nên bề ngang tối đa = cao * 0.905. */
  --bw:min(100%, 660px, max(420px, (100vh  - 360px) * 0.905));
  --bw:min(100%, 660px, max(420px, (100svh - 360px) * 0.905));
}
.board-col > *{width:var(--bw)}          /* mọi thẻ rộng đúng bằng bàn cờ */
.tray{
  min-height:30px;display:flex;align-items:center;gap:5px;flex-wrap:wrap;
  padding:5px 10px;border-radius:9px;background:var(--surface-2);
  border:1px solid var(--edge);
}
.tray .lbl{font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:var(--faint);margin-right:4px}
.tray b{
  font-family:"Noto Serif TC","Songti SC",serif;font-weight:700;font-size:15px;
  width:21px;height:21px;display:grid;place-items:center;border-radius:50%;
  background:var(--disc-2);border:1px solid var(--disc-edge);
}
.tray b.r{color:var(--piece-red)}
.tray b.b{color:var(--piece-black)}

.board-shell{
  position:relative;
  container-type:inline-size;
  width:var(--bw, min(100%, 660px));
  margin:0 auto;
  border-radius:var(--radius);
  /* Vân gỗ dựng bằng gradient chồng lớp thay vì ảnh: không thêm byte tải về,
     nét sắc ở mọi mật độ điểm ảnh, và đổi màu theo chế độ sáng/tối được.
     Ba lớp sọc dọc mật độ lệch nhau (3px / 7px / 13px — số nguyên tố nên
     không trùng chu kỳ) cho ra vân không lặp lại lộ liễu, cộng một lớp
     loang ngang giả thớ gỗ và một lớp tối bốn góc cho có chiều sâu. */
  background-color:var(--board);
  /* Gỗ vàng, mặt mượt — không vân sọc. Chỉ hai lớp loang rất nhẹ để mặt bàn
     có chiều sâu chứ không phẳng lì như tờ giấy màu: một vệt sáng phía trên
     giả ánh đèn hắt xuống, một vệt tối bốn góc dưới. */
  background-image:
    radial-gradient(120% 80% at 50% -8%, rgba(255,255,255,.22), transparent 58%),
    radial-gradient(160% 130% at 50% 118%, var(--wood-ink), transparent 72%),
    linear-gradient(158deg, var(--wood-1) 0%, var(--wood-2) 62%, var(--wood-3) 100%);
  /* Viền ngoài cùng lấy ĐÚNG màu nét kẻ trên bàn, để cả bàn cờ nhìn như một
     mặt gỗ có khung chứ không phải mặt gỗ dán thêm một cái nẹp khác màu. */
  border:1px solid var(--line);
  box-shadow:0 1px 0 rgba(255,255,255,.16) inset, 0 14px 34px -18px var(--shadow-strong);
  padding:0;
  overflow:hidden;
}
/* SVG mặc định là phần tử NỘI TUYẾN, nên nó ngồi trên đường cơ chữ và chừa
   thêm khoảng trống cho phần đuôi chữ bên dưới — ở đây là ~6px. Quân cờ lại
   đặt theo phần trăm CHIỀU CAO CỦA THẺ BỌC, mà thẻ bọc cao hơn cái lưới đúng
   ngần ấy, nên quân trôi dần xuống theo từng hàng: hàng đầu lệch 0,5px còn
   hàng cuối lệch tới 5,8px — đúng hàng quân của chính mình. display:block bỏ
   khoảng đuôi chữ ấy đi, thẻ bọc cao đúng bằng lưới, quân nằm khít giao điểm. */
.board-shell > svg{display:block}
.board-shell::after{
  /* Khung trong. Đo bằng cqw (phần trăm bề ngang bàn cờ) chứ không phải px,
     nên kéo to kéo nhỏ thì khoảng hở ra mép vẫn đúng tỉ lệ — y như lưới ô cờ
     vẽ trong SVG. Để px thì bàn cờ 269px và bàn cờ 660px có khung dày như nhau,
     nhìn lệch hẳn. */
  content:"";position:absolute;inset:1.5cqw;border-radius:1.7cqw;
  border:.34cqw solid var(--line);opacity:.5;pointer-events:none;
}
#grid{display:block;width:100%;height:auto}
#layer{position:absolute;inset:0}

.pc{
  position:absolute;
  width:8.9cqw;height:8.9cqw;
  margin:-4.45cqw 0 0 -4.45cqw;
  border-radius:50%;
  display:grid;place-items:center;
  font-family:"Noto Serif TC","Songti SC",serif;
  font-weight:700;
  font-size:5.0cqw;
  line-height:1;
  cursor:pointer;
  /* Ba lớp nền chồng lên nhau cho ra một mặt CONG chứ không phải vòng tròn
     phẳng: đốm sáng lệch trên-trái (nguồn sáng), vệt tối gom ở đáy (phần
     khuất), rồi mới tới nền gỗ. */
  background:
    radial-gradient(circle at 33% 25%, rgba(255,255,255,.92) 0%, rgba(255,255,255,0) 44%),
    radial-gradient(circle at 50% 116%, rgba(112,66,20,.34) 0%, rgba(112,66,20,0) 56%),
    radial-gradient(circle at 34% 28%, var(--disc) 0%, var(--disc-2) 78%);
  /* Bóng đổ HAI tầng: một tầng sát chân quân (đậm, hẹp) và một tầng loang ra
     (nhạt, rộng). Một tầng duy nhất thì quân trông như dán lên mặt bàn.
     Rồi vành gỗ ngoài, rồi ba vệt vát trong — sáng ở mép trên, tối ở mép dưới
     — đó mới là thứ làm con cờ nhô lên khỏi mặt bàn. */
  box-shadow:
    var(--vanh-quan),
    var(--vat-quan),
    /* Bóng đổ BA tầng: sát chân, loang vừa, rồi một tầng rất rộng rất nhạt —
       tầng thứ ba mới là thứ cho cảm giác quân đứng CAO hẳn khỏi mặt bàn. */
    0 .42cqw .55cqw -.12cqw color-mix(in srgb, var(--line) 56%, transparent),
    0 1.45cqw 2.15cqw -.48cqw color-mix(in srgb, var(--line) 64%, transparent),
    0 2.70cqw 3.90cqw -1.10cqw color-mix(in srgb, var(--line) 50%, transparent),
    inset 0 .40cqw .48cqw -.28cqw rgba(255,255,255,.95),
    inset 0 -.52cqw .62cqw -.34cqw rgba(112,66,20,.44),
    inset .16cqw -.16cqw .30cqw -.16cqw rgba(112,66,20,.20);
  transition:left .26s cubic-bezier(.3,.8,.35,1),top .26s cubic-bezier(.3,.8,.35,1),opacity .18s,transform .18s;
  user-select:none;
  z-index:2;
}
/* Vòng trong: KHẮC CHÌM chứ không phải vẽ lên. Một nét sáng ngay dưới nét màu
   là đủ để mắt đọc ra chiều sâu. */
.pc::before{
  content:"";position:absolute;inset:.75cqw;border-radius:50%;
  border:.22cqw solid currentColor;opacity:.62;
  box-shadow:0 .1cqw 0 rgba(255,255,255,.55), inset 0 .1cqw .12cqw rgba(112,66,20,.18);
}
.pc.r{color:var(--piece-red)}
.pc.b{color:var(--piece-black)}
.pc.dead{opacity:0;transform:scale(.5);pointer-events:none}
/* Quân đang cầm: viền xanh sáng kèm một quầng loang mờ, và NHẤC LÊN một chút.
   Giữ nguyên bóng đổ với vệt vát — bỏ đi thì quân vừa được chọn lại bẹt
   xuống, trông như bị ấn chìm vào mặt bàn thay vì được nhấc lên. */
.pc.sel{
  box-shadow:
    /* Vành gỗ giữ NGUYÊN, viền xanh ôm ra ngoài nó chứ không đè lên: đè lên
       thì quân vừa được chọn lại mất mất bề dày, trông mỏng hơn lúc chưa chọn. */
    var(--vanh-quan),
    var(--vat-quan),
    0 0 0 .90cqw var(--chon),
    0 0 0 1.55cqw color-mix(in srgb, var(--chon) 30%, transparent),
    0 0 2.9cqw .18cqw color-mix(in srgb, var(--chon) 62%, transparent),
    0 .48cqw .58cqw -.16cqw color-mix(in srgb, var(--line) 46%, transparent),
    0 1.65cqw 2.40cqw -.50cqw color-mix(in srgb, var(--line) 54%, transparent),
    0 2.80cqw 4.00cqw -1.30cqw color-mix(in srgb, var(--line) 38%, transparent),
    inset 0 .40cqw .48cqw -.28cqw rgba(255,255,255,.95),
    inset 0 -.52cqw .62cqw -.34cqw rgba(112,66,20,.44);
  transform:translateY(-.45cqw);
  /* Vành xanh nhô ra sát quân bên cạnh, nên phải nổi lên trên chúng —
     không thì nó bị chính quân hàng xóm cắt mất một góc. */
  z-index:5;
}
.pc.idle{cursor:default}
/* Tướng đang bị chiếu: một quầng đỏ THỞ quanh quân — phồng lên rồi lặn xuống
   chứ không nhấp nháy tắt-bật, vì tắt-bật thì mắt đọc ra "lỗi" chứ không đọc
   ra "nguy".
   Quầng vẽ bằng ::after và chỉ đổi opacity với transform, nên nó chạy trên
   trình dựng hình chứ không bắt trình duyệt tính lại bóng đổ 60 lần mỗi giây.
   Tên khung hình phải RIÊNG: bản trước đặt tên "pulse", mà "pulse" đã là khung
   hình của chấm xanh "đang nói" ở dưới tệp — luật sau đè luật trước, nên suốt
   thời gian qua tướng bị chiếu chỉ mờ đi rồi rõ lại, không hề có màu đỏ nào. */
.pc.check{z-index:4}
.pc.check::after{
  content:"";position:absolute;inset:-1.25cqw;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,
    transparent 56%,
    color-mix(in srgb, var(--cinnabar) 42%, transparent) 71%,
    color-mix(in srgb, var(--cinnabar) 12%, transparent) 88%,
    transparent 100%);
  box-shadow:
    0 0 0 .34cqw color-mix(in srgb, var(--cinnabar) 92%, transparent),
    0 0 3.0cqw .35cqw color-mix(in srgb, var(--cinnabar) 66%, transparent);
  animation:chieuTho 1.5s ease-in-out infinite;
}
/* Đáy nhịp thở dừng ở .58 chứ không xuống .4: thấp quá thì có lúc quầng gần
   như biến mất, và người vừa ngước lên đúng nhịp ấy sẽ không thấy mình đang
   bị chiếu — thứ nguy hiểm nhất trên bàn cờ mà lại là thứ mờ nhất. */
@keyframes chieuTho{
  0%,100%{opacity:.58;transform:scale(.95)}
  50%    {opacity:1;  transform:scale(1.10)}
}
@media (prefers-reduced-motion: reduce){
  .pc.check::after{animation:none;opacity:.85;transform:none}
}

.dot{position:absolute;width:2.6cqw;height:2.6cqw;margin:-1.3cqw 0 0 -1.3cqw;border-radius:50%;background:var(--hint);z-index:1;cursor:pointer;transition:transform .15s}
.dot:hover{transform:scale(1.35)}
.ring{position:absolute;width:9.9cqw;height:9.9cqw;margin:-4.95cqw 0 0 -4.95cqw;border-radius:50%;border:.4cqw solid var(--hint);z-index:3;cursor:pointer}
.mark{position:absolute;width:10.6cqw;height:10.6cqw;margin:-5.3cqw 0 0 -5.3cqw;border-radius:50%;border:.34cqw solid var(--board-trim);opacity:.55;z-index:0}

/* ---------- rail ---------- */
.rail{display:flex;flex-direction:column;gap:12px;max-width:320px}
.card{background:var(--surface);border:1px solid var(--edge);border-radius:var(--radius);padding:14px}
.status{display:flex;flex-direction:column;gap:3px}
.status .who{font-family:Fraunces,Georgia,serif;font-size:19px;font-weight:600;letter-spacing:-.01em}
.status .sub{font-size:12.5px;color:var(--muted);min-height:19px}
.status.alert .who{color:var(--cinnabar)}

.field{display:flex;flex-direction:column;gap:6px}
.field + .field{margin-top:12px}
.field label{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.seg{display:flex;background:var(--surface-2);border:1px solid var(--edge);border-radius:9px;padding:3px;gap:3px}
.seg button{
  flex:1;appearance:none;border:0;background:transparent;color:var(--muted);
  font:inherit;font-size:13px;padding:6px 4px;border-radius:6px;cursor:pointer;transition:.15s;
}
.seg button:hover{color:var(--ink)}
.seg button[aria-pressed="true"]{background:var(--surface);color:var(--ink);font-weight:600;box-shadow:0 1px 3px var(--shadow)}
.seg button:focus-visible{outline:2px solid var(--gold);outline-offset:1px}

.row{display:flex;gap:8px;margin-top:12px}
.btn{
  flex:1;appearance:none;font:inherit;font-size:13.5px;cursor:pointer;
  padding:9px 10px;border-radius:9px;border:1px solid var(--edge);
  background:var(--surface-2);color:var(--ink);transition:.15s;
}
.btn:hover{border-color:var(--gold-soft)}
.btn:focus-visible{outline:2px solid var(--gold);outline-offset:1px}
/* Nút chính: vàng tươi + chữ tím thẫm ở CẢ hai chế độ. Tương phản ~9:1, và
   nhờ vậy không phải bịa ba luật khác nhau cho sáng/tối/theo-máy như trước. */
.btn.primary{background:var(--grad);border-color:transparent;
  color:var(--on-accent);font-weight:600}
.btn.primary:hover{filter:brightness(1.06)}
.btn:disabled{opacity:.42;cursor:not-allowed}

.log-head{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:8px}
.log-head span{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
#log{max-height:224px;overflow-y:auto;font-size:13px;font-variant-numeric:tabular-nums}
#log table{width:100%;border-collapse:collapse}
#log td{padding:2.5px 4px;vertical-align:top}
#log td.n{color:var(--faint);width:26px;text-align:right}
#log td.r{color:var(--cinnabar)}
#log td.b{color:var(--ink)}
#log tr:last-child td{font-weight:600}
.empty{color:var(--faint);font-size:12.5px;padding:4px}

footer{color:var(--faint);font-size:12px;line-height:1.7}
footer b{color:var(--muted);font-weight:500}

@media (prefers-reduced-motion: reduce){
  *{animation-duration:.001ms !important;transition-duration:.001ms !important}
}

@media (max-width:560px){
  .wrap{padding:18px 12px 28px}
  .game{gap:16px}
  .player{padding:10px 11px}
  .row{flex-direction:column}
  .btn{min-height:44px}
  .linkbox,.chat-form,.banner{flex-direction:column}
  .linkbox .btn,.chat-form .btn,.banner .btn{width:100%}
  .chat-bubble{max-width:100%}
  .status .who{font-size:18px}
}

/* ═══════════ phần riêng cho bản chơi online ═══════════ */

.player{display:flex;align-items:center;gap:10px;padding:11px 13px;border-radius:var(--radius);
  background:var(--surface);border:1px solid var(--edge)}
.player.turn{border-color:var(--gold);box-shadow:0 0 0 3px var(--last)}
.player .side{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;flex:none;
  font-family:"Noto Serif TC","Songti SC",serif;font-weight:700;font-size:16px;
  background:radial-gradient(circle at 34% 28%,var(--disc) 0%,var(--disc-2) 78%);
  border:1px solid var(--disc-edge)}
.player .side.r{color:var(--piece-red)}
.player .side.b{color:var(--piece-black)}
.player .meta{flex:1;min-width:0}
.player .nm{font-weight:600;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.player .st{font-size:11.5px;color:var(--muted);display:flex;align-items:center;gap:5px}
.player .st i{width:6px;height:6px;border-radius:50%;background:var(--faint);display:inline-block;flex:none}
.player .st i.on{background:#3E9E63}
.player .st i.off{background:#C2703F}
/* Dòng "Tới lượt bạn" / "Đang suy nghĩ…" phải đọc được từ xa: nó là thứ quyết
   định người ta có đang phải làm gì hay không. To hơn, đậm hơn, màu vàng nổi —
   chứ để bằng cỡ chữ chú thích xám nhạt thì liếc qua không thấy. */
.player .st.luot span{color:var(--gold-vivid); font-weight:600; font-size:13px}
.player .st.luot i{background:var(--gold-vivid); box-shadow:0 0 0 3px color-mix(in srgb, var(--gold) 28%, transparent)}
.clock{font-variant-numeric:tabular-nums;font-size:19px;font-weight:600;letter-spacing:-.01em;
  font-family:Fraunces,Georgia,serif}
.clock.low{color:var(--cinnabar)}

.invite{background:var(--surface);border:1px solid var(--gold-soft);border-radius:var(--radius);padding:14px;
  display:flex;flex-direction:column;gap:10px}
.invite h3{margin:0;font-family:Fraunces,Georgia,serif;font-size:16px;font-weight:600}
.invite p{margin:0;font-size:12.5px;color:var(--muted)}
.linkbox{display:flex;gap:6px}
.linkbox input{flex:1;min-width:0;font:inherit;font-size:12.5px;padding:8px 10px;border-radius:8px;
  border:1px solid var(--edge);background:var(--surface-2);color:var(--ink)}
.code{font-family:Fraunces,Georgia,serif;font-size:26px;letter-spacing:.16em;font-weight:700;color:var(--gold)}

.toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(12px);
  background:var(--ink);color:var(--bg);padding:10px 18px;border-radius:999px;font-size:13.5px;
  opacity:0;pointer-events:none;transition:.22s;z-index:50;box-shadow:0 8px 24px -8px var(--shadow-strong)}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

.banner{border-radius:var(--radius);padding:12px 14px;font-size:13.5px;display:flex;gap:10px;
  align-items:center;justify-content:space-between;background:var(--surface);border:1px solid var(--gold)}
.banner .btn{flex:none;padding:6px 12px;font-size:12.5px}

.chat-card{display:flex;flex-direction:column;gap:10px}
.chat-list{max-height:220px;overflow-y:auto;display:flex;flex-direction:column;gap:8px;padding-right:4px}
.chat-msg{display:flex}
.chat-msg.me{justify-content:flex-end}
.chat-bubble{max-width:86%;padding:8px 10px;border-radius:12px;background:var(--surface-2);border:1px solid var(--edge)}
.chat-msg.me .chat-bubble{background:rgba(156,122,51,.12);border-color:var(--gold-soft)}
.chat-head{display:flex;justify-content:space-between;gap:6px;font-size:10.5px;color:var(--muted);margin-bottom:3px}
.chat-head span{font-weight:600;color:var(--ink)}
.chat-text{font-size:13px;line-height:1.45;word-break:break-word}
.chat-form{display:flex;gap:8px;align-items:center;margin-top:2px}
.chat-form .text{flex:1;min-width:0}
/* Nút gửi là một BIỂU TƯỢNG, không phải nút chữ. .btn để flex:1 nên mặc định
   nó giằng co với ô nhập và ăn mất gần nửa hàng — ô nhập chỉ còn một mẩu.
   Ghim thành ô vuông để ô nhập lấy trọn phần còn lại.
   Cả luật màn hẹp ở trên (xếp dọc, nút rộng 100%) cũng phải trừ ra: một cái
   biểu tượng kéo dài hết bề ngang trông như lỗi.

   Nút phải VUÔNG và cao đúng bằng ô nhập, nên hai đứa lấy chung một con số
   `--cf-cao` thay vì mỗi đứa tự cao theo chữ bên trong.
   Đã thử `align-items:stretch` + `aspect-ratio:1`: KHÔNG chạy. Trình duyệt
   giải tỉ lệ trước rồi mới tới stretch, nên nút lấy chiều cao theo cái biểu
   tượng 19px bên trong và co thành ô vuông 21px. */
.chat-form:has(.btn.icon){flex-direction:row; align-items:center; --cf-cao:42px}
.chat-form:has(.btn.icon) .text{height:var(--cf-cao)}
.chat-form .btn.icon{
  flex:0 0 auto; padding:0; min-width:0;
  width:var(--cf-cao); height:var(--cf-cao); min-height:var(--cf-cao)}

/* ═══════════ trang sảnh ═══════════ */
.lobby{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:22px;align-items:start}
@media (max-width:760px){.lobby{grid-template-columns:minmax(0,1fr)}}
.stack{display:flex;flex-direction:column;gap:12px}
.card h2{margin:0 0 4px;font-family:Fraunces,Georgia,serif;font-size:18px;font-weight:600}
.card p.hint{margin:0 0 12px;font-size:12.5px;color:var(--muted)}
input.text{width:100%;font:inherit;font-size:14px;padding:10px 12px;border-radius:9px;
  border:1px solid var(--edge);background:var(--surface-2);color:var(--ink)}
input.text:focus-visible{outline:2px solid var(--gold);outline-offset:1px}
.roomlist{display:flex;flex-direction:column;gap:7px;max-height:340px;overflow-y:auto}
.roomrow{display:flex;align-items:center;gap:10px;padding:9px 11px;border-radius:9px;
  background:var(--surface-2);border:1px solid var(--edge)}
.roomrow .nm{flex:1;font-size:13.5px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.roomrow .tag{font-size:11px;color:var(--faint);letter-spacing:.06em;text-transform:uppercase}
.roomrow .btn{flex:none;width:auto;padding:6px 14px;font-size:12.5px}

/* ═══════════ bố cục điện thoại: bàn cờ không bao giờ bị che ═══════════ */
/*
  Nguyên tắc: bàn cờ + hai thanh kỳ thủ phải nằm gọn trong màn hình đầu tiên,
  mọi thứ khác (mời bạn, biên bản, chat, bình luận, quảng cáo) đẩy xuống dưới
  và chỉ đọc được khi cuộn. Không có gì dán đè, không có gì nổi lên trên.

  Dùng svh chứ không dùng dvh: svh là chiều cao khi thanh địa chỉ đang hiện
  ra hết, nên bàn cờ vẽ một lần là vừa và không co giật lúc cuộn.
*/
:root{ --chrome:389px; --sm-h:24px; --sm-gap:4px; --stream-h:52px; }  /* 2 dòng tin */
/* --chrome = tổng chiều cao mọi thứ KHÔNG phải bàn cờ trong màn hình đầu.
   Con số này ĐO ĐƯỢC bằng phép đo thật, không ước lượng — đổi bố cục thì
   phải đo lại: header 48 + gạch 1 + 2 thanh kỳ thủ 96 + dòng tin 44
   + lưới 2 cột 92 + 4 khoảng hở 32 + đệm trang 21 */

@media (max-width:860px){
  .wrap{gap:8px;padding-top:8px}
  h1{font-size:21px}
  header{align-items:center;gap:10px}
  .brand{flex-direction:row;align-items:baseline;gap:9px;min-width:0}
  .brand .tagline{font-size:12px;white-space:nowrap}
  /* Đường kẻ gradient chỉ để trang trí — trên điện thoại nó ăn mất cả khe hở
     lẫn chính nó, đủ để bàn cờ hụt gần chục px. */
  .rule{display:none}
  .board-col{gap:8px}
  .board-col{
    /* BỀ NGANG QUYẾT ĐỊNH, không phải chiều cao.

       Bản trước lấy `(chiều cao màn hình − --chrome) × 0,905`, mà --chrome
       gồm cả khung trò chuyện và hàng nút NẰM DƯỚI bàn cờ. Tức là bóp bàn cờ
       lại để chừa chỗ cho những thứ người ta có thể cuộn xuống xem — trên máy
       nhỏ bàn cờ chỉ còn 75% bề ngang, hai bên thừa gần 5cm trắng.

       Giờ bề ngang quyết định, chừa đúng chút lề của .wrap. Vẫn còn một chặn
       theo chiều cao, nhưng chỉ trừ ~175px cho những thứ Ở QUANH bàn cờ
       (header và hai thanh kỳ thủ), KHÔNG trừ phần đuôi cuộn được. Chặn ấy
       chỉ thật sự bám vào hai chỗ: máy tính bảng dựng đứng, và điện thoại xoay
       ngang — nơi màn hình thấp hơn bề ngang nhiều. Trên điện thoại cầm dọc
       thì bề ngang luôn thắng, bàn cờ chiếm 94–95% màn hình. */
    --bw:min(100%, 640px, max(240px, (100svh - 175px) * 0.905));
    --bw:min(100%, 640px, max(240px, (var(--vh, 100svh) - 175px) * 0.905));
  }
  /* Bóp mọi khối phụ trên điện thoại — chỗ tiết kiệm được đổ hết vào bàn cờ. */
  .player{padding:7px 11px}
  .player .side{width:28px;height:28px;font-size:15px}
  .player .nm{font-size:13.5px}
  .player .st{font-size:11px}
  .clock{font-size:18px}
  .deck .card{padding:8px}
  .deck-acts{gap:5px}
  .deck-acts .btn{min-height:33px;font-size:11.5px}
  .deck-status .who{font-size:14.5px}
  #sayForm .text{min-height:36px}
  #sayForm .btn{min-height:36px;padding:6px 14px}
}
/* Màn thấp: rút dòng tin còn một dòng, bóp thanh kỳ thủ, cho bàn cờ thở. */
/* Màn thấp: dòng tin còn một dòng, header thu lại, mọi thứ sát hơn nữa. */
@media (max-width:860px) and (max-height:700px){
  :root{ --chrome:343px; --sm-h:22px; --sm-gap:4px; --stream-h:22px; --bw-min:260px }
  /* Máy thấp: bỏ dòng nhắc phụ, giữ lại đúng thứ cần nhìn. */
  .deck-status .sub{display:none}
  .brand .tagline{display:none}
  .wrap{gap:8px;padding:10px 10px 18px}
  .board-col{gap:6px}
  h1{font-size:21px}
  .player{padding:6px 10px}
  .player .side{width:25px;height:25px;font-size:13px}
  .clock{font-size:16px}
  .deck .card{padding:7px}
  .deck-acts .btn{min-height:30px;font-size:10.5px;padding:4px 2px}
  #sayForm .text{min-height:32px}
  #sayForm .btn{min-height:32px;padding:5px 10px}
  .deck-status .who{font-size:13.5px}
  .deck-status .sub{font-size:11px}
}

/* Màn CỰC thấp (điện thoại nhỏ còn hiện cả thanh địa chỉ lẫn thanh dưới):
   không thể vừa mọi thứ vừa giữ bàn cờ bấm được. Ưu tiên bàn cờ: rút dòng tin
   xuống một dòng mảnh, nút thành một hàng, và chấp nhận phần đuôi cuộn nhẹ. */
@media (max-width:860px) and (max-height:585px){
  :root{ --chrome:290px; --sm-h:20px; --sm-gap:3px; --stream-h:20px; --bw-min:230px }
  .wrap{gap:6px;padding:8px 8px 14px}
  h1{font-size:18px}
  .board-col{gap:5px}
  .player{padding:4px 9px}
  .player .side{width:22px;height:22px;font-size:12px}
  .player .nm{font-size:12px}
  .player .st{display:none}
  .clock{font-size:15px}
  .deck{grid-template-columns:1fr}
  .deck .card{padding:6px}
  .deck-acts{grid-template-columns:repeat(5,1fr)}
  .deck-acts .btn{min-height:28px;font-size:10px;padding:3px 1px}
  .deck-status .who{font-size:13px}
}

/* ---------- nút chuyển sáng / tối ---------- */
/* `flex-wrap:wrap` là cái van an toàn. Số mục điều hướng thì cố định, nhưng
   chip người dùng co giãn theo TÊN (tối đa 170px), nên ở mấy khổ chật hàng
   công cụ có lúc dài hơn chỗ nó có. Không cho xuống dòng thì nó chảy quá mép
   phải và bị cắt — mà header không có thanh cuộn ngang để với tới phần bị cắt.
   Xuống dòng thì header cao thêm một nấc, đổi lại không mất nút nào. */
.head-tools{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  justify-content:flex-end}
.themebtn{
  display:inline-grid;place-items:center;width:36px;height:36px;flex:none;
  border-radius:50%;border:1px solid var(--edge);background:var(--surface);
  color:var(--muted);cursor:pointer;font-size:15px;line-height:1;transition:.18s;
}
.themebtn:hover{color:var(--ink);border-color:var(--gold-soft)}

/* Nút nhạc nền. Cùng khuôn với nút sáng/tối và đứng ngay cạnh, nhưng lúc TẮT
   thì gạch chéo một nét — chỉ làm nhạt đi thì ở khổ 32px không ai đọc ra là
   đang tắt hay đang bật. */
.nhacbtn{position:relative}
.nhacbtn.tat{color:var(--faint)}
.nhacbtn.tat::after{
  content:""; position:absolute; left:50%; top:50%;
  width:64%; height:1.5px; border-radius:2px; background:currentColor;
  transform:translate(-50%,-50%) rotate(-45deg);
}
.nhacbtn.dang-bat{color:var(--gold); border-color:var(--gold-soft)}
.themebtn:focus-visible{outline:2px solid var(--gold);outline-offset:2px}

/* ---------- thanh thoại ---------- */
.voice{
  display:flex;align-items:center;gap:9px;padding:8px 11px;font-size:12.5px;
  border-radius:var(--radius);background:var(--surface);border:1px solid var(--edge);
}
.voice .vs{flex:1;min-width:0;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.voice .btn{flex:none;padding:6px 12px;font-size:12.5px;min-height:34px}
.voice .btn.live{border-color:var(--gold);color:var(--gold);font-weight:600}
.voice[hidden]{display:none}
/* vòng sáng quanh quân của bên đang nói */
.player .side{transition:box-shadow .15s}
.player.talking .side{box-shadow:0 0 0 3px var(--hint)}
.dotlive{width:7px;height:7px;border-radius:50%;background:#3E9E63;flex:none;
  animation:pulse 1.4s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:.35}50%{opacity:1}}

/* ---------- tab: biên bản / trò chuyện / bình luận ---------- */
.tabs{display:flex;gap:4px;padding:3px;border-radius:10px;background:var(--surface-2);
  border:1px solid var(--edge);margin-bottom:10px}
.tabs button{
  flex:1;padding:7px 4px;border:0;border-radius:8px;background:transparent;cursor:pointer;
  font:inherit;font-size:12.5px;color:var(--muted);min-height:38px;transition:.15s;
}
.tabs button[aria-selected="true"]{background:var(--surface);color:var(--ink);font-weight:600;
  box-shadow:0 1px 3px var(--shadow)}
.tabs button:focus-visible{outline:2px solid var(--gold);outline-offset:1px}
.tabs .badge{display:inline-block;min-width:16px;padding:0 4px;margin-left:3px;border-radius:8px;
  background:var(--grad);color:var(--on-accent);font-size:10px;font-weight:700;line-height:16px}
.tabpane[hidden]{display:none}
.talk-msg .who{font-weight:600;color:var(--ink)}
.talk-msg .who.red{color:var(--cinnabar)}
.talk-msg .who.black{color:var(--jet)}
.talk-msg{font-size:13px;line-height:1.5;padding:5px 0;border-bottom:1px solid var(--surface-2)}
.talk-msg:last-child{border-bottom:0}
.talk-tag{font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:var(--faint);margin-left:5px}

/* ---------- ô quảng cáo ---------- */
/*
  Chỉ hiện khi đặt biến môi trường ADS_CLIENT. Luôn nằm SAU bàn cờ theo thứ tự
  cuộn, không position:fixed, không sticky, không popup, không chen giữa ván.
*/
.adslot{border-radius:var(--radius);border:1px solid var(--edge);background:var(--surface-2);
  padding:8px;overflow:hidden;text-align:center}
.adslot[hidden]{display:none}
.adslot .lbl{display:block;font-size:9.5px;text-transform:uppercase;letter-spacing:.12em;
  color:var(--faint);margin-bottom:6px}
.adslot ins{display:block}

/* ═══════════ màn đăng nhập ═══════════ */
.gate{position:fixed;inset:0;z-index:200;display:grid;place-items:center;padding:20px;
  background:color-mix(in srgb, var(--bg) 88%, transparent);backdrop-filter:blur(8px);
  opacity:0;transition:opacity .2s}
.gate.on{opacity:1}
.gate-card{width:min(100%,340px);background:var(--surface);border:1px solid var(--edge);
  border-radius:var(--radius);padding:26px 22px;text-align:center;
  box-shadow:0 24px 60px -24px var(--shadow-strong)}
.gate-mark{width:52px;height:52px;margin:0 auto 12px;border-radius:50%;display:grid;
  place-items:center;font-family:"Noto Serif TC","Songti SC",serif;font-size:26px;font-weight:700;
  color:var(--cinnabar);background:var(--disc);border:1px solid var(--disc-edge)}
.gate-card h2{margin:0;font-family:Fraunces,Georgia,serif;font-size:24px;font-weight:600}
.gate-sub{margin:6px 0 18px;font-size:13px;color:var(--muted)}
.gate-lbl{display:block;text-align:left;font-size:12px;color:var(--muted);margin-bottom:5px}
.gate-body .text{width:100%;margin-bottom:10px}
.gate-note{margin:12px 0 0;font-size:11.5px;color:var(--faint);line-height:1.5}
.gate-note.bad{color:var(--cinnabar)}
.btn.fb{width:100%;display:flex;align-items:center;justify-content:center;gap:9px;
  min-height:46px;background:#1877F2;border-color:#1877F2;color:#fff;font-weight:600}
.btn.fb:hover{background:#166FE5;border-color:#166FE5}
.btn.fb:disabled{opacity:.6;cursor:default}
.fbmark{width:20px;height:20px;border-radius:50%;background:#fff;color:#1877F2;
  display:grid;place-items:center;font-family:Georgia,serif;font-weight:700;font-size:14px;flex:none}

/* người đang đăng nhập, trên header */
.whoami{display:flex;align-items:center;gap:7px;padding:3px 10px 3px 3px;border-radius:999px;
  border:1px solid var(--edge);background:var(--surface);cursor:pointer;font:inherit;
  font-size:12.5px;color:var(--ink);max-width:170px}
.whoami:hover{border-color:var(--gold-soft)}
.whoami:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
.whoami img{width:26px;height:26px;border-radius:50%;flex:none;object-fit:cover;background:var(--surface-2)}
.whoami span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ═══════════ dòng tin trôi ═══════════ */
/*
  Tin mới chèn vào ĐẦU, tin cũ bị đẩy xuống rồi mờ dần và biến mất. Khối này
  cao cố định nên không bao giờ đẩy bàn cờ đi đâu — hết chỗ thì dòng cuối tự rụng.
*/
.stream{display:flex;flex-direction:column;gap:var(--sm-gap,4px);overflow:hidden;
  min-height:var(--stream-h);max-height:var(--stream-h);justify-content:flex-start}
/* Chiều cao MỘT dòng tin là hằng số, và --stream-h luôn là bội số của nó cộng
   khe hở. Nếu không thì dòng cuối bị xén ngang, trông như giao diện vỡ. */
.sm{display:flex;align-items:center;gap:6px;font-size:12.5px;line-height:1;
  height:var(--sm-h,24px);padding:0 9px;border-radius:999px;
  background:var(--surface);border:1px solid var(--edge);
  white-space:nowrap;overflow:hidden;flex:none;max-width:100%;box-sizing:border-box}
.sm-av{width:16px;height:16px;border-radius:50%;flex:none;object-fit:cover}
.sm-who{font-weight:600;flex:none;max-width:34%;overflow:hidden;text-overflow:ellipsis}
.sm-tag{font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--faint);flex:none}
.sm-txt{overflow:hidden;text-overflow:ellipsis;color:var(--muted)}
.sm-chat{border-color:var(--gold-soft);background:color-mix(in srgb,var(--gold) 8%,var(--surface))}
.sm-talk .sm-who{color:var(--ink)}
@keyframes smIn{from{opacity:0;transform:translateY(-9px) scale(.97)}to{opacity:1;transform:none}}
@keyframes smOut{to{opacity:0;transform:translateY(10px)}}
.sm-in{animation:smIn .26s cubic-bezier(.2,.9,.3,1.2)}
.sm-out{animation:smOut .6s ease forwards}

/* ═══════════ hai thẻ dưới bàn cờ ═══════════ */
/*
  Điện thoại: xếp DỌC, mỗi thẻ rộng bằng bàn cờ.
  Máy tính:   chia HAI CỘT, nhưng tổng bề ngang vẫn đúng bằng bàn cờ
              (vì .deck nằm trong .board-col và đã nhận width:var(--bw)).
*/
.deck{display:grid;grid-template-columns:minmax(0,1fr);gap:8px;align-items:stretch}
/* minmax(0,1fr) chứ không phải 1fr: mặc định cột không co được dưới kích thước
   tối thiểu của nội dung, mà hàng năm nút "không xuống dòng" có min-content
   ~400px — nó sẽ nong cột ra và bóp bẹp cột bên cạnh còn 83px. */
@media (min-width:861px){ .deck{grid-template-columns:minmax(0,1fr) minmax(0,1fr)} }
.deck > *{margin:0}
.deck .card{padding:10px 11px}

.deck-say{display:flex;flex-direction:column;justify-content:center;gap:4px;min-width:0}
.deck-say .who{font-family:Fraunces,Georgia,serif;font-size:16px;font-weight:600;
  letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.deck-say .sub{font-size:11.5px;color:var(--muted);white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.deck-say.alert .who{color:var(--cinnabar)}

/* Toàn bộ nút nằm MỘT hàng. Bốn nút chữ chia đều phần còn lại, mic/loa/ngắt
   là nút vuông chỉ có icon nên không ăn mất bề ngang của chữ. */
.deck-acts{display:flex;align-items:center;gap:6px;flex-wrap:nowrap}
.deck-acts .btn{flex:1 1 0;min-width:0;min-height:38px;padding:6px 2px;font-size:12px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.deck-acts .btn.icon{flex:0 0 auto;width:38px;padding:0}
/* Mic đang mở nghĩa là ĐANG GHI ÂM và đối thủ đang nghe được. Cái đó phải
   nhìn phát biết, không phải đoán qua một gạch chéo nhỏ xíu trên biểu tượng:
   nút đổi hẳn sang màu cảnh báo, và có vòng sóng lan ra liên tục — chuyển
   động là thứ mắt bắt được cả khi đang nhìn chỗ khác. */
.deck-acts .btn.live, #nutMicNoi.live{
  border-color:var(--cinnabar); color:var(--on-accent); font-weight:600;
  background:var(--cinnabar);
  animation:mic-song 1.7s ease-out infinite}
@keyframes mic-song{
  0%  {box-shadow:0 0 0 0   color-mix(in srgb, var(--cinnabar) 60%, transparent)}
  70% {box-shadow:0 0 0 11px color-mix(in srgb, var(--cinnabar) 0%, transparent)}
  100%{box-shadow:0 0 0 0   color-mix(in srgb, var(--cinnabar) 0%, transparent)}
}
/* Ai tắt hiệu ứng chuyển động thì vẫn phải biết mình đang bị ghi âm — giữ
   nguyên màu đỏ, chỉ bỏ vòng sóng. */
@media (prefers-reduced-motion: reduce){
  .deck-acts .btn.live, #nutMicNoi.live{animation:none}
}

/* Icon vẽ bằng mask nên nó ăn theo màu chữ của nút — đổi trạng thái là đổi
   màu luôn, không phải nạp hai file ảnh khác nhau. */
.btn.icon{position:relative;display:inline-grid;place-items:center}
.btn.icon::before{content:"";width:19px;height:19px;background:currentColor;
  -webkit-mask:var(--ic) center/contain no-repeat; mask:var(--ic) center/contain no-repeat}
#micBtn{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='9' y='2' width='6' height='11' rx='3'/><path d='M5 11a7 7 0 0 0 14 0'/><path d='M12 18v3'/><path d='M8 21h8'/></svg>")}
#micBtn[aria-pressed="false"]{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='9' y='2' width='6' height='11' rx='3'/><path d='M5 11a7 7 0 0 0 14 0'/><path d='M12 18v3'/><path d='M8 21h8'/><path d='M3 3l18 18'/></svg>")}
#deafBtn{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 9v6h4l5 4V5L8 9H4z'/><path d='M17 9a4 4 0 0 1 0 6'/></svg>")}
#deafBtn.off{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 9v6h4l5 4V5L8 9H4z'/><path d='M3 3l18 18'/></svg>")}
#nutToBan{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M15 3h6v6'/><path d='M9 21H3v-6'/><path d='M21 3l-7 7'/><path d='M3 21l7-7'/></svg>")}
#nutToBan[aria-pressed="true"]{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 14h6v6'/><path d='M20 10h-6V4'/><path d='M14 10l7-7'/><path d='M3 21l7-7'/></svg>");
  color:var(--gold-vivid)}
#hangBtn{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 10a14 14 0 0 1 18 0v3l-4 1-1-3a10 10 0 0 0-8 0l-1 3-4-1z'/></svg>");
  color:var(--cinnabar)}


/* Ô nhắn dưới bàn cờ phải giữ MỘT hàng kể cả trên màn hẹp — quy tắc chung ở
   trên cho .chat-form xếp dọc, ở đây nó sẽ ăn mất 50px chiều cao quý giá. */
#sayForm{flex-direction:row;align-items:center;gap:8px;margin-top:0}
#sayForm .text{flex:1;min-width:0;width:auto}
#sayForm .btn{width:auto;flex:none;padding:8px 16px;min-height:38px}

/* Ô nhắn nằm trong cột trái của lưới: một hàng, sát nhau. */
#sayForm{flex-direction:row;align-items:center;gap:6px;margin-top:2px}
#sayForm .text{flex:1;min-width:0;width:auto;min-height:34px;padding:6px 10px;font-size:13px}
#sayForm .btn{width:auto;flex:none;padding:6px 12px;min-height:34px;font-size:12px}

/* `hidden` là thuộc tính HTML, trình duyệt cho nó display:none bằng bảng kiểu
   mặc định — mà bảng kiểu mặc định thua MỌI luật mình viết. Đặt display cho
   .btn.icon là vô tình bật lại mấy nút đáng lẽ đang ẩn. */
[hidden]{display:none !important}
/* Ô rỗng vẫn ăn một khe hở của flex, để lại khoảng trắng không hiểu từ đâu ra. */
.board-col > div:empty{display:none}

/* Trước đây bốn nút này là nút CHỮ, thẻ hẹp thì rút nhãn còn "Hoà/Thua/Khoe/
   Link". Giờ cả bốn đã thành nút biểu tượng vuông 38px, nhét thêm dòng chữ
   vào là nó tràn ra ngoài viền — nên bỏ hẳn lối rút nhãn ấy. Tên đầy đủ vẫn
   nằm trong title/aria-label nên trình đọc màn hình không mất gì. */

/* Chạm hai lần để phóng to là thao tác dễ dính nhất khi đang bấm quân cờ.
   manipulation giữ nguyên cuộn và chạm thường, chỉ bỏ đúng cú phóng đó. */
html{touch-action:manipulation;-webkit-text-size-adjust:100%;
  /* Chặn kéo quá đà: cú nảy cao su ở đầu và cuối trang trên iOS làm cả bố cục
     trượt theo, trông y như trang đang co giãn. */
  overscroll-behavior-y:none}
/* KHÔNG dùng touch-action:none cho bàn cờ: bàn cờ chiếm gần hết màn hình nên
   đặt none là người dùng mất luôn đường vuốt để cuộn xuống xem biên bản.
   manipulation vẫn cho cuộn, chỉ bỏ đúng cú chạm-hai-lần-để-phóng. Chụm hai
   ngón đã có thẻ viewport và mấy handler gesture chặn rồi. */
.board-shell,.layer,.pc,.dot,.ring{touch-action:manipulation}

/* ═══════════ màn kết ván ═══════════ */
/*
  Chữ THẮNG / THUA / HOÀ nổ ra giữa bàn cờ: phóng từ rất nhỏ, vọt quá cỡ rồi
  co về — cảm giác mạnh chứ không phải hiện ra nhàn nhạt. Viền vàng nổi kèm
  quầng sáng đập nhịp để mắt bị hút vào đúng chỗ đó.
*/
.endgame{position:absolute;inset:0;z-index:20;display:grid;place-items:center;
  /* Màn phủ trộn từ --jet chứ KHÔNG phải --ink. Hai biến này từng cùng một
     giá trị ở bảng sáng cũ (#0F3A52) nên chẳng ai thấy khác, nhưng --ink là
     màu CHỮ: ở nền tối nó là #F4F0FF, và lớp phủ thành một màn SƯƠNG TRẮNG
     42% trùm lên bàn cờ thay vì làm tối bàn cờ đi. Hộp báo kết ván mất hẳn
     cảm giác nổi lên trên. --jet tối ở cả hai bảng, đúng việc của nó — và
     .hoi-roi với .hop-hoi vẫn luôn dùng nó. */
  padding:6%;background:color-mix(in srgb,var(--jet) 58%,transparent);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  animation:egFade .35s ease both}
.endgame[hidden]{display:none !important}
@keyframes egFade{from{opacity:0}to{opacity:1}}

.endgame-card{
  position:relative;max-width:92%;padding:5% 8%;border-radius:22px;text-align:center;
  background:linear-gradient(150deg,
    color-mix(in srgb,var(--surface) 94%,transparent),
    color-mix(in srgb,var(--surface-2) 94%,transparent));
  /* Viền dày: ba lớp lồng nhau — nét vàng đậm, viền sáng, rồi quầng vàng nhạt.
     Cộng lại 22px nên nhìn từ xa vẫn thấy ngay đây là khung kết quả. */
  border:7px solid var(--board-trim);
  box-shadow:
    0 0 0 3px  color-mix(in srgb,var(--surface) 88%,transparent),
    0 0 0 12px color-mix(in srgb,var(--board-trim) 34%,transparent),
    0 20px 50px -14px rgba(0,0,0,.6);
  animation:egPop .62s cubic-bezier(.16,1.3,.36,1) both;
}
/* Tự lui sau vài giây rồi trả lại bàn cờ cho người ta xem lại thế cuối. */
.endgame.go{animation:egOut .45s ease both;pointer-events:none}
@keyframes egOut{to{opacity:0;transform:scale(1.06)}}
/* Phóng mạnh: bắt đầu bé xíu và nghiêng, vọt qua cỡ thật rồi mới đứng yên. */
@keyframes egPop{
  0%  {transform:scale(.18) rotate(-14deg);opacity:0}
  55% {transform:scale(1.14) rotate(3deg); opacity:1}
  78% {transform:scale(.96) rotate(-1.5deg)}
  100%{transform:scale(1) rotate(0);opacity:1}
}
/* Quầng sáng đập nhịp quanh khung. */
.endgame-card::after{
  content:"";position:absolute;inset:-7px;border-radius:24px;pointer-events:none;
  /* Quầng sáng phải cùng tông với viền vàng của khung. Dùng --gold-vivid ở
     đây là ra vòng xanh chọi thẳng vào viền vàng, vì bảng sáng lấy xanh làm
     màu nhấn. */
  border:3px solid var(--board-trim);
  animation:egHalo 1.8s ease-in-out .55s infinite;
}
@keyframes egHalo{
  0%,100%{opacity:.15;transform:scale(1)}
  50%    {opacity:.85;transform:scale(1.045)}
}

.endgame-word{
  font-family:Fraunces,Georgia,serif;font-weight:700;letter-spacing:.04em;
  font-size:clamp(30px,15cqw,86px);line-height:1.02;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;
  color:transparent;
  /* Nền sau chữ là gỗ vàng nên chữ tô dải màu cần một nét viền tối, không thì
     phần sáng của dải màu chìm vào mặt bàn. */
  -webkit-text-stroke:1.5px color-mix(in srgb,var(--ink) 55%,transparent);
  paint-order:stroke fill;
}
.endgame-word.win  {--grad:linear-gradient(135deg,#FFC72C 0%,#FF7A18 100%)}
.endgame-word.lose {--grad:linear-gradient(135deg,#8FA3B8 0%,#4A6076 100%)}
.endgame-word.draw {--grad:linear-gradient(135deg,#54C2F0 0%,#3FD0A0 100%)}

.endgame-why{margin-top:.4em;font-size:clamp(11px,3.4cqw,16px);color:var(--muted);
  animation:egIn .5s ease .5s both}
@keyframes egIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* Ảnh do trang admin đặt — vẫn phóng đúng kiểu đó, không hiện phẳng lì. */
.endgame-art{display:block;max-width:100%;max-height:46cqw;object-fit:contain;
  filter:drop-shadow(0 10px 22px rgba(0,0,0,.45))}

@media (prefers-reduced-motion: reduce){
  .endgame,.endgame-card,.endgame-why,.endgame.go{animation-duration:.001ms !important}
  .endgame-card::after{animation:none;opacity:.5}
}

/* Header trên điện thoại: thêm nút tiếng là hàng công cụ tràn xuống dòng thứ
   hai và ăn mất chiều cao của bàn cờ. Bỏ chữ trong chip người dùng, giữ ảnh
   đại diện — tên vẫn còn trong title và aria-label. */
@media (max-width:520px){
  .head-tools{gap:6px}
  .whoami{padding:3px;max-width:none}
  .whoami span{display:none}
  .themebtn{width:32px;height:32px;font-size:14px}
  header{flex-wrap:nowrap}
  .brand{min-width:0;flex:1}
  h1{font-size:19px}
  .brand .tagline{overflow:hidden;text-overflow:ellipsis}
}

/* ═══════════ quảng cáo chèn giữa sau khi kết ván ═══════════ */
.adgate{position:absolute;inset:0;z-index:22;display:grid;place-items:center;padding:5%;
  background:color-mix(in srgb,var(--jet) 72%,transparent);   /* xem chú thích ở .endgame */
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}
.adgate[hidden]{display:none !important}
.adgate-card{width:100%;max-width:94%;background:var(--surface);border:1px solid var(--edge);
  border-radius:var(--radius);padding:12px;text-align:center;
  box-shadow:0 18px 44px -14px rgba(0,0,0,.5)}
.adgate-lbl{font-size:9.5px;text-transform:uppercase;letter-spacing:.12em;color:var(--faint);
  margin-bottom:8px}
.adgate-box{min-height:90px;display:grid;place-items:center;overflow:hidden;margin-bottom:10px}
.adgate-box img{max-width:100%;max-height:34cqw;object-fit:contain;border-radius:8px}
.adgate-card .btn{width:100%;min-height:42px}
.adgate-card .btn:disabled{opacity:.55}

/* Ô quảng cáo thường: có ảnh thì phải bó cho gọn */
.adslot img{max-width:100%;height:auto;border-radius:8px;display:block;margin:0 auto}
.adslot a{display:block}

/* ═══════════ giải đấu ═══════════ */
.giai-list{display:grid;gap:12px}
@media (min-width:861px){.giai-list{grid-template-columns:repeat(auto-fill,minmax(300px,1fr))}}
.giai-card{display:flex;gap:12px;text-decoration:none;color:inherit;align-items:stretch;
  transition:border-color .15s,transform .15s}
.giai-card:hover{border-color:var(--gold-soft);transform:translateY(-1px)}
.giai-anh{width:84px;height:84px;flex:none;border-radius:11px;object-fit:cover;background:var(--surface-2)}
/* Ảnh bìa mặc định vẽ bằng SVG (giai-bia.js) chứ không còn là một chữ ♟ đặt
   giữa ô xám — phần lớn giải không ai tải ảnh lên, nên đó mới là bộ mặt
   thường thấy nhất của trang giải đấu. */
.giai-anh.trong{display:block;padding:0;overflow:hidden}
.giai-bia-mac{display:block;width:100%;height:100%;object-fit:cover}
.giai-bia.trong{width:100%;height:190px;border-radius:11px;overflow:hidden;
  margin-bottom:10px;background:var(--surface-2)}
.giai-than{min-width:0;flex:1}
.giai-than h3{margin:4px 0 3px;font-family:Fraunces,Georgia,serif;font-size:17px;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.giai-than p{margin:0;font-size:12.5px;color:var(--muted);line-height:1.5;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.giai-dau{display:flex;gap:7px;align-items:center;flex-wrap:wrap}
.giai-so{font-size:11px;color:var(--faint)}
.giai-chan{margin-top:6px;font-size:11.5px;color:var(--faint)}
.giai-bia{width:100%;max-height:190px;object-fit:cover;border-radius:11px;margin-bottom:10px}
.giai-top h2{margin:6px 0 4px}

.tt{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;font-weight:600;
  padding:2px 8px;border-radius:999px;border:1px solid var(--edge);color:var(--muted)}
.tt.mo{border-color:var(--gold-soft);color:var(--gold)}
.tt.chay{border-color:#3E9E63;color:#3E9E63}
.tt.xong{border-color:var(--faint)}

.ai-list{display:flex;flex-wrap:wrap;gap:8px}
.ai{display:flex;align-items:center;gap:7px;padding:4px 11px 4px 4px;border-radius:999px;
  background:var(--surface-2);border:1px solid var(--edge);font-size:12.5px}
.ai img{width:24px;height:24px;border-radius:50%;object-fit:cover;background:var(--edge)}

/* cây đấu: mỗi vòng một cột, hẹp thì cuộn ngang trong khung của nó */
.cay{display:flex;gap:14px;overflow-x:auto;padding-bottom:6px;align-items:flex-start}
.cot{flex:0 0 200px;display:flex;flex-direction:column;gap:10px}
.cot-ten{font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:var(--faint);
  text-align:center;padding-bottom:2px}
.tran{border:1px solid var(--edge);border-radius:11px;overflow:hidden;background:var(--surface-2)}
.ke{display:flex;align-items:center;gap:7px;padding:6px 9px;font-size:12.5px;
  border-bottom:1px solid var(--edge)}
.ke:last-of-type{border-bottom:0}
.ke img{width:20px;height:20px;border-radius:50%;flex:none;object-fit:cover;background:var(--edge)}
.ke span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}
.ke.trong{color:var(--faint);font-style:italic}
.ke.thang{background:color-mix(in srgb,var(--gold-vivid) 14%,var(--surface));font-weight:600}
.ke.thang b{color:var(--gold)}
.ke.thua{opacity:.5}
.tran-vao{display:block;text-align:center;padding:6px;font-size:12px;font-weight:600;
  background:var(--grad);color:var(--on-accent);border:0;width:100%;cursor:pointer;
  text-decoration:none;font-family:inherit}

/* vinh danh */
.vinh-danh{background:linear-gradient(160deg,
  color-mix(in srgb,var(--gold-vivid) 12%,var(--surface)), var(--surface))}
.vd-list{display:flex;flex-wrap:wrap;gap:12px;justify-content:center}
.vd{text-align:center;padding:12px 16px;border-radius:14px;background:var(--surface);
  border:1px solid var(--edge);min-width:132px}
.vd-1{border-color:var(--gold-vivid);border-width:2px;transform:scale(1.06)}
.vd img{width:52px;height:52px;border-radius:50%;object-fit:cover;background:var(--edge);margin:6px 0}
.vd-hang{font-size:11.5px;color:var(--muted);font-weight:600}
.vd-ten{font-weight:600;font-size:14px}
.vd-thuong{font-size:11.5px;color:var(--gold);margin-top:3px}

/* Liên kết điều hướng trên header */
.btn.nav{padding:5px 12px;min-height:32px;font-size:12.5px;text-decoration:none;
  line-height:1.7;white-space:nowrap}
@media (max-width:640px){.btn.nav{padding:4px 9px;font-size:11.5px}}

/* ═══════════ menu hồ sơ người dùng ═══════════ */
.usermenu{position:relative}
.umenu{position:absolute;top:calc(100% + 8px);right:0;z-index:60;min-width:230px;
  background:var(--surface);border:1px solid var(--edge);border-radius:var(--radius);
  box-shadow:0 18px 44px -14px var(--shadow-strong);overflow:hidden;
  animation:umIn .16s ease both}
.umenu[hidden]{display:none !important}
@keyframes umIn{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
.umenu-top{display:flex;gap:10px;padding:12px;border-bottom:1px solid var(--edge);
  background:var(--surface-2)}
.umenu-top img{width:42px;height:42px;border-radius:50%;flex:none;object-fit:cover;background:var(--edge)}
.umenu-ten{font-weight:600;font-size:14px}
.umenu-cap{font-size:12px;color:var(--muted);margin-top:2px}
.umenu-tbh{font-size:11.5px;color:var(--faint);margin-top:2px}
.umenu-tbh span{opacity:.75}
.umenu-i{display:block;width:100%;text-align:left;padding:10px 13px;font:inherit;font-size:13px;
  color:var(--ink);background:none;border:0;border-bottom:1px solid var(--surface-2);
  cursor:pointer;text-decoration:none}
.umenu-i:last-child{border-bottom:0}
.umenu-i:hover{background:var(--surface-2)}
.umenu-i.thoat{color:var(--cinnabar)}

/* ═══════════ trang quản lý giải của ban tổ chức ═══════════ */
.qlgiai{display:grid;gap:12px}
.nguoi-row{display:flex;align-items:center;gap:9px;padding:7px 9px;border-radius:9px;
  border:1px solid var(--edge);background:var(--surface-2)}
.nguoi-row img{width:28px;height:28px;border-radius:50%;flex:none;object-fit:cover;background:var(--edge)}
.nguoi-row .nm{flex:1;min-width:0;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.nguoi-row .hat{font-size:11px;color:var(--faint);flex:none}
.nguoi-row .btn{padding:3px 9px;min-height:28px;font-size:11.5px;flex:none}
.nguoi-row.cho{border-color:var(--gold-soft);background:color-mix(in srgb,var(--gold-vivid) 9%,var(--surface))}
.nguoi-row .tay{font-size:10px;color:var(--faint);border:1px solid var(--edge);
  border-radius:6px;padding:1px 5px;flex:none}
.themnguoi{display:flex;gap:8px;flex-wrap:wrap;margin-top:8px}
.themnguoi .text{flex:1;min-width:150px}

/* Nút phụ đứng cạnh tiêu đề: .row cho con flex:1 nên nó bị kéo giãn hết hàng. */
.card > .row > h2 + .btn, .card > .row > .btn.gon{flex:0 0 auto;width:auto;padding:6px 14px}

/* ═══════════ khoảng cách giữa các thẻ ═══════════ */
/*
  .wrap là flex có gap, nhưng các thẻ nằm TRONG một khối con (#main, #panel,
  .rail…) thì khối đó mới là cha — mà chúng vốn là div thường, không gap,
  nên thẻ dính sát nhau. Cho chúng cùng một nhịp giãn.
*/
#main, #panel, #pane, .stack, .qlgiai, .giai-list, #formTao, #inviteBox, #offerBox, #againBox,
#tCuaToi{
  display:flex;flex-direction:column;gap:16px}
.giai-list{gap:14px}
@media (min-width:861px){
  .giai-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}
}
.qlgiai{gap:10px}
.wrap{gap:24px}
.card{padding:18px}
@media (max-width:640px){ .card{padding:14px} .wrap{gap:16px} #main,#panel,#pane{gap:12px} }
/* Thẻ trong lưới điều khiển dưới bàn cờ giữ nguyên nhịp chật của nó. */
.deck .card{padding:10px 11px}
.deck-acts, .deck-say{gap:6px}
.card h2{margin-bottom:6px}
.card > .row:first-child{margin-top:0}

/* ── Điều hướng trên đầu trang ──
   Bản trước GIẤU HẲN mấy liên kết này trên máy hẹp, với lý do "đã có trong menu
   hồ sơ rồi". Sai hai đường:
     • menu hồ sơ chỉ hiện khi ĐÃ ĐĂNG NHẬP, nên khách vào bằng điện thoại
       không còn lối đi nào cả;
     • trong menu vốn không có "Trang chủ", nên trang ấy thành không tới được.
   Giờ giữ nguyên nút, chỉ thu lại thành biểu tượng khi màn hình hẹp. */
.head-tools .btn.nav{
  flex:none;width:auto;padding:6px 12px;line-height:1.9;text-decoration:none;
  font-size:12.5px;white-space:nowrap;
}
.head-tools .btn.nav::before{content:attr(data-ic);margin-right:6px;font-size:14px}
/* Nút "Trận đang đấu": đưa về ván đang bỏ dở. Phải nổi hơn mấy mục điều
   hướng khác — nó là thứ duy nhất trên thanh này có một cái đồng hồ đang chạy
   phía sau, bỏ quên là thua. */
.head-tools .btn.nav.ve-tran{
  border-color:var(--gold); color:var(--gold-vivid); font-weight:600;
  background:color-mix(in srgb, var(--gold) 14%, var(--surface))}
.head-tools .btn.nav.ve-tran:hover{border-color:var(--gold-vivid)}

/* Hộp hỏi trước khi rời bàn giữa ván. Phủ kín màn hình và ĐÈ lên tất cả: đây
   là câu hỏi phải trả lời xong mới đi tiếp được, không phải một lời nhắc góc
   màn hình dễ bấm trượt. */
.hoi-roi{position:fixed; inset:0; z-index:120; display:grid; place-items:center;
  padding:18px; background:color-mix(in srgb, var(--jet) 55%, transparent)}
.hoi-roi[hidden]{display:none}
.hoi-roi-card{width:min(340px,100%); display:flex; flex-direction:column; gap:9px;
  padding:18px; border-radius:16px; background:var(--surface);
  border:1px solid var(--edge); box-shadow:0 22px 60px -14px var(--shadow-strong)}
.hoi-roi-card b{font-family:Fraunces,Georgia,serif; font-size:17px}
.hoi-roi-card .hint{margin:0}
.hoi-roi-card .btn{width:100%; min-height:40px}
/* "Ở lại bàn" là lối THOÁT chứ không phải một lựa chọn ngang hàng — để nhạt
   hơn, không thì ba nút cùng cỡ làm người ta phải đọc cả ba mới chọn được. */
.hoi-roi-card .hoi-roi-thoi{border-color:transparent; background:transparent;
  color:var(--muted); min-height:34px; font-size:12.5px}

/* Nút vào bàn cờ mang đúng con Tướng của bàn cờ: cùng mặt gỗ, cùng vòng viền
   trong, cùng nét chữ đỏ. Một chữ 帥 trần trụi trông như ký tự lạ lọt vào
   thanh menu; thành quân cờ rồi thì liếc một cái biết bấm vào là ra bàn cờ.
   Vòng viền trong vẽ bằng box-shadow inset vì ::before không có ::before. */
.head-tools .btn.nav[data-ic="帥"]::before{
  width:19px; height:19px; margin-right:7px;
  display:inline-grid; place-items:center;
  border-radius:50%;
  font-family:"Noto Serif TC","Songti SC",serif; font-weight:700;
  font-size:11px; line-height:1;
  color:var(--piece-red);
  background:radial-gradient(circle at 34% 28%, var(--disc) 0%, var(--disc-2) 78%);
  box-shadow:0 1px 2px -1px var(--shadow), 0 0 0 1px var(--disc-edge),
             inset 0 0 0 1px color-mix(in srgb, var(--piece-red) 45%, transparent);
}

/* ═══════════ nút báo cáo và hộp thoại kiểm duyệt ═══════════
   Nút phải KÍN ĐÁO: nó nằm cạnh từng dòng chat, mà chat thì đọc liên tục —
   một nút đỏ chói cạnh mỗi dòng biến khung trò chuyện thành bảng tố cáo. Mờ
   sẵn, rõ lên khi rê chuột vào dòng ấy, và luôn bấm được bằng bàn phím. */
.nut-bc{
  flex:none; width:20px; height:20px; padding:0; line-height:1;
  border:0; background:none; cursor:pointer;
  color:var(--faint); opacity:.35; font-size:12px;
  border-radius:6px; transition:opacity .15s, color .15s;
}
.nut-bc:hover{opacity:1; color:var(--cinnabar)}
.nut-bc:focus-visible{opacity:1; outline:2px solid var(--gold); outline-offset:1px}
*:hover > .nut-bc, li:hover .nut-bc, .chat-msg:hover .nut-bc{opacity:.75}

.bc-lop{position:fixed; inset:0; z-index:130; display:grid; place-items:center;
  padding:18px; background:color-mix(in srgb, var(--jet) 62%, transparent)}
.bc-lop[hidden]{display:none}
.bc-card{
  width:min(420px,100%); display:flex; flex-direction:column; gap:10px;
  padding:18px; border-radius:16px; background:var(--surface);
  border:1px solid var(--edge); box-shadow:0 22px 60px -14px var(--shadow-strong)}
.bc-card > b{font-family:Fraunces,Georgia,serif; font-size:17px}
.bc-card .hint{margin:0}
.bc-trich{padding:8px 11px; border-radius:9px; background:var(--surface-2);
  border-left:3px solid var(--edge); font-style:italic}
.bc-ly{display:grid; gap:2px}
.bc-ly-i, .bc-chan{display:flex; align-items:center; gap:9px; cursor:pointer;
  padding:7px 9px; border-radius:9px; font-size:13.5px}
.bc-ly-i:hover, .bc-chan:hover{background:var(--surface-2)}
.bc-chan{border:1px solid var(--edge); margin-top:4px}
.bc-card .row{margin-top:2px}

/* Câu trả lời của máy ở trang Hỏi đáp. Nền khác hẳn thẻ bao ngoài để mắt tách
   được ngay đâu là chữ người viết, đâu là chữ máy sinh — hai thứ ấy có độ tin
   cậy khác nhau, và trang nói thẳng như vậy. */
.hd-tra{
  margin-top:10px; padding:12px 14px; border-radius:10px;
  background:var(--surface-2); border:1px solid var(--edge);
  border-left:3px solid var(--gold-soft);
  font-size:14px; line-height:1.7; white-space:pre-wrap;
}
.hd-tra[hidden]{display:none}

/* Ô xem trước logo trong trang quản trị. Nền kẻ ô cờ nhạt để nhìn ra ngay
   phần TRONG SUỐT của tấm logo — trên nền phẳng thì một tấm PNG nền trắng và
   một tấm nền trong suốt trông y hệt nhau, tới lúc lên đầu trang nền tối mới
   lòi ra cái hộp trắng. */
.th-xem{
  display:flex; align-items:center; justify-content:center;
  min-height:96px; padding:14px; border-radius:12px;
  border:1px solid var(--edge);
  background-color:#2a2a30;
  background-image:linear-gradient(45deg,#3a3a42 25%,transparent 25%,transparent 75%,#3a3a42 75%),
                   linear-gradient(45deg,#3a3a42 25%,transparent 25%,transparent 75%,#3a3a42 75%);
  background-size:16px 16px; background-position:0 0, 8px 8px;
}
.th-xem img{max-width:100%; max-height:120px; object-fit:contain; display:block}
.th-xem.trong{color:var(--muted); font-size:12.5px; background-image:none}

/* Bảng sửa biểu tượng menu trong trang quản trị: mỗi mục một thẻ, có ô xem
   trước ngay trên đầu để thấy đổi màu ra sao mà không phải mở điện thoại. */
.menu-sua{display:grid; gap:14px; grid-template-columns:repeat(auto-fill,minmax(230px,1fr))}
.menu-o{padding:14px; border:1px solid var(--edge); border-radius:12px; background:var(--surface-2)}
.menu-o > b{display:block; margin:8px 0 10px}
.menu-xem{
  position:relative;
  width:54px; height:54px; border-radius:15px; display:grid; place-items:center;
  font-family:"Noto Serif TC","Songti SC",serif; font-size:25px; color:#fff;
  border:1.5px solid rgba(255,255,255,.42); overflow:hidden}
.menu-xem::after{
  content:""; position:absolute; inset:3px; border-radius:11px; pointer-events:none;
  border:1px solid rgba(255,255,255,.28)}
.menu-xem img{width:100%; height:100%; object-fit:cover; display:block}

/* ═══════════ nút ba gạch + bảng menu (điện thoại) ═══════════
   Trên màn 390px, sáu mục điều hướng teo còn sáu vòng tròn 36px không chữ —
   bấm theo trí nhớ chứ không đọc được. Gom hết vào một nút ba gạch, mở ra một
   bảng ô vuông CÓ MÀU và CÓ TÊN, đúng kiểu màn hình ứng dụng điện thoại. */
.nav-3g{display:none; width:36px; height:36px; padding:0; flex:none;
  border:1px solid var(--edge); border-radius:50%; background:var(--surface);
  cursor:pointer; place-items:center}
.nav-3g:hover{border-color:var(--gold-soft)}
.nav-3g i, .nav-3g i::before, .nav-3g i::after{
  display:block; width:15px; height:2px; border-radius:2px; background:var(--ink);
  transition:transform .18s}
.nav-3g i{position:relative}
.nav-3g i::before, .nav-3g i::after{content:""; position:absolute; left:0}
.nav-3g i::before{top:-5px}
.nav-3g i::after{top:5px}
.nav-3g[aria-expanded="true"] i{background:transparent}
.nav-3g[aria-expanded="true"] i::before{transform:translateY(5px) rotate(45deg)}
.nav-3g[aria-expanded="true"] i::after{transform:translateY(-5px) rotate(-45deg)}

.nav-bang{position:fixed; inset:0; z-index:120;
  background:color-mix(in srgb, var(--bg) 72%, transparent); backdrop-filter:blur(6px)}
.nav-bang[hidden]{display:none}
.nav-bang-luoi{
  /* CĂN GIỮA và không bao giờ rộng hơn màn. left/right = 0 cộng bề ngang xác
     định cộng margin auto là cách căn giữa không dùng transform — quan trọng,
     vì khung hình mở bảng đã dùng transform rồi, đặt thêm là nó nuốt mất.
     `minmax(0,1fr)` chứ không phải `1fr`: mặc định mỗi cột lưới rộng tối
     thiểu bằng NỘI DUNG, nên mấy ô 84px đẩy bảng phình ra quá bề ngang màn —
     tràn hẳn ra ngoài mép phải.
     BA cột chứ không phải bốn: sáu mục chia ba là hai hàng ĐỦ, chia bốn thì
     hàng dưới còn hai ô lệch hẳn về trái, nhìn như bảng vẽ dở. */
  position:absolute; top:var(--nav-top,64px); left:0; right:0;
  width:min(calc(100% - 24px), 360px); margin-inline:auto;
  display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:14px 8px;
  padding:18px 14px; border-radius:20px;
  background:var(--surface); border:2px solid var(--gold-soft);
  box-shadow:0 24px 60px -22px var(--shadow-strong), 0 0 0 1px rgba(0,0,0,.25);
  position:relative;
  animation:bangXuong .18s ease-out}
@keyframes bangXuong{from{opacity:0; transform:translateY(-8px)} to{opacity:1; transform:none}}
/* Đường viền THỨ HAI, nằm lùi vào trong. Một nét thì bảng đọc ra như một tấm
   phẳng dán lên; hai nét cách nhau vài pixel thì mắt đọc ra bề dày — cùng lối
   với vành gỗ nhiều vòng của con cờ. */
.nav-bang-luoi::before{
  content:""; position:absolute; inset:5px; border-radius:15px; pointer-events:none;
  border:1px solid color-mix(in srgb, var(--gold-soft) 45%, transparent)}
.nav-app{display:flex; flex-direction:column; align-items:center; gap:6px;
  min-width:0; text-decoration:none; color:var(--ink)}
/* Ô biểu tượng có VIỀN riêng: trên nền tối mà chỉ có màu nền thì mấy ô sẫm
   (tím, xanh đậm) chìm vào bảng. Viền sáng mảnh tách hẳn từng ô ra, đúng kiểu
   biểu tượng ứng dụng nằm trên hình nền. */
.nav-app-o{
  position:relative;
  width:54px; height:54px; border-radius:15px; display:grid; place-items:center;
  font-family:"Noto Serif TC","Songti SC",serif; font-size:25px; color:#fff;
  border:1.5px solid rgba(255,255,255,.42);
  box-shadow:0 6px 14px -6px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.35);
  overflow:hidden}
/* Nét viền trong của từng ô: cùng lý do với bảng — hai nét mới ra khối. Đặt
   sau ảnh trong thứ tự xếp lớp nên ảnh không đè mất nó. */
.nav-app-o::after{
  content:""; position:absolute; inset:3px; border-radius:11px; pointer-events:none;
  border:1px solid rgba(255,255,255,.28)}
/* Ảnh thay cho chữ: phủ kín ô, cắt theo bo góc. */
.nav-app-o img{width:100%; height:100%; object-fit:cover; display:block}
.nav-app-ten{font-size:11.5px; line-height:1.2; text-align:center; font-weight:500;
  max-width:100%; overflow-wrap:anywhere}
.nav-app.dang .nav-app-o{outline:2px solid var(--gold); outline-offset:2px}
.nav-app:active .nav-app-o{transform:scale(.94)}
body.menu-mo{overflow:hidden}

/* Ngưỡng cất mục điều hướng vào nút ba gạch. Trước là 560px, đo cho NĂM mục;
   thêm "Trang chủ" thành sáu thì hàng nút dài ra thêm chừng 96px và ở khổ
   561–659 nó chạy quá mép phải — mục cuối bị cắt mất một nửa mà không có
   thanh cuộn nào để với tới. Nên cất sớm hơn, từ 659px trở xuống.
   CHỪA "Trận đang đấu": nó không nằm trong bảng ba gạch (bảng ấy chỉ dựng từ
   NAV), nên giấu đi là mất hẳn lối về ván đang bỏ dở. Ở khổ này còn thừa chỗ
   cho đúng một nút, và nếu phải chọn một thì chọn nó. */
@media (max-width:659px){
  .head-tools .btn.nav:not(.ve-tran){display:none}
  .nav-3g{display:inline-grid}
}

@media (max-width:560px){
  /* Điện thoại hẹp: hết chỗ, cất nốt cả "Trận đang đấu". */
  .head-tools .btn.nav{display:none}
  h1{white-space:nowrap}
  /* Logo đứng CẠNH chữ ở khổ hẹp: chữ phải co được, không thì nó đẩy dòng
     tagline ra ngoài mép — mà tagline ở trang bàn cờ chính là MÃ PHÒNG, thứ
     người ta đọc cho bạn qua điện thoại. */
  h1[data-logo="canh"] .th-chu{min-width:0;overflow:hidden;text-overflow:ellipsis}
  .logo-anh{max-width:38vw}
  .brand .tagline{max-width:42vw;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  /* Mã phòng là thứ người ta đọc cho bạn bè qua điện thoại, cắt cụt thành
     "Phòng N…" là hỏng đúng cái đáng giữ. Bỏ chữ "Phòng", và cấm co lại —
     header chật thì nhường chỗ ở nơi khác, không nhường ở đây.
     (Các tagline khác — "Giải đấu", "Đăng quảng cáo" — vẫn cắt bình thường,
     mất một chữ cuối của chúng thì không sao.) */
  .brand .tagline .nhan{display:none}
  .brand .tagline.ma-phong{flex:none;max-width:none;overflow:visible;
    letter-spacing:.06em;font-variant-numeric:tabular-nums}

  /* Chỗ nhường: chip người dùng còn mỗi ảnh đại diện. Tên đầy đủ vẫn nằm
     trong menu bấm ra, nên không mất thông tin gì. */
  .whoami{max-width:none;padding:3px}
  .whoami > span{display:none}
}

/* ═══════════ cửa đăng nhập: ba tầng, không phải một chồng chữ ═══════════

   Trên cùng là mấy lối MỘT CHẠM (Facebook, Google) — nút đặc, to, cùng cỡ.
   Giữa là vạch "hoặc". Dưới là hai nút viền chia đôi hàng: tên đăng nhập và
   đăng ký. Cuối là lối khách.
   Bản trước xếp ba dòng chữ gạch chân giống hệt nhau chồng lên nhau, mắt
   không phân được cái nào quan trọng hơn cái nào — mà đó chính là việc duy
   nhất của màn này. */
.gate-alt{display:block;width:100%;margin-top:8px;padding:7px;font:inherit;font-size:12.5px;
  color:var(--muted);background:none;border:0;cursor:pointer;text-decoration:underline;
  text-underline-offset:3px}
.gate-alt:hover{color:var(--ink)}
.gate-hoac{display:flex;align-items:center;gap:10px;margin:16px 0 11px;
  color:var(--faint);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase}
.gate-hoac::before,.gate-hoac::after{content:"";flex:1;height:1px;background:var(--edge)}
.gate-doi{display:flex;gap:8px}
.gate-doi .btn{flex:1 1 0;min-width:0;min-height:42px;font-size:13px;padding:8px 6px}

/* ═══════════ chợ quảng cáo: bảng giá và đơn của tôi ═══════════ */
.giaqc{display:grid;gap:10px;grid-template-columns:repeat(auto-fill,minmax(190px,1fr))}
.giaqc-o{padding:12px;border-radius:11px;border:1px solid var(--edge);background:var(--surface-2)}
.giaqc-ten{font-weight:600;font-size:13.5px}
.giaqc-ta{font-size:11.5px;color:var(--muted);margin:3px 0 8px;line-height:1.45}
.giaqc-gia{font-family:Fraunces,Georgia,serif;font-size:19px;font-weight:600;color:var(--gold-vivid)}
.giaqc-gia span{font-family:inherit;font-size:11.5px;font-weight:400;color:var(--faint)}
.giaqc-tu{margin-top:6px;font-size:11px;color:var(--jade)}
.qc-row{flex-wrap:wrap}
.qc-thumb{width:56px !important;height:30px !important;border-radius:5px !important}
.qc-row .nm small{display:block;font-size:11px;color:var(--faint);font-weight:400}
.qc-lydo{flex-basis:100%;font-size:11.5px;color:var(--cinnabar)}

/* ═══════════ ô thông tin do ban tổ chức tự thêm ═══════════ */
.batbuoc{color:var(--cinnabar)}
.dkform{margin-top:12px;padding:14px;border-radius:11px;border:1px solid var(--gold-soft);
  background:var(--surface-2)}
.dkform h3{margin:0 0 4px;font-family:Fraunces,Georgia,serif;font-size:15.5px}
.tieu-nho{margin:16px 0 4px;font-family:Fraunces,Georgia,serif;font-size:14.5px;font-weight:600}
.othem{margin-top:12px;border:1px solid var(--edge);border-radius:11px;padding:10px 12px;
  background:var(--surface-2)}
.othem > summary{cursor:pointer;font-weight:600;font-size:13.5px;list-style:none}
.othem > summary::-webkit-details-marker{display:none}
.othem > summary::before{content:'▸ ';color:var(--faint)}
.othem[open] > summary::before{content:'▾ '}
.othem .hint{margin:8px 0 10px}
.o-hang{display:flex;gap:7px;align-items:center;flex-wrap:wrap;margin-bottom:7px}
.o-hang .o-nhan{flex:2 1 150px;width:auto}
.o-hang .o-kieu{flex:1 1 130px;width:auto}
.o-hang .o-chon{flex:2 1 100%;width:auto}
.o-hang .o-xoa{flex:none;width:auto;padding:5px 10px;color:var(--cinnabar)}
.tick{display:flex;align-items:center;gap:7px;font-size:13px;margin:8px 0;cursor:pointer}
.tick input{width:16px;height:16px;accent-color:var(--gold-vivid);flex:none}
.tick.gon{margin:0;font-size:11.5px;color:var(--muted);flex:none}

/* Hai lựa chọn loại trừ nhau, bày thành hai thẻ bấm được cho rõ hơn nút tròn. */
.chon2{display:grid;gap:9px;grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
.chon2-o{display:block;padding:11px 12px;border-radius:11px;cursor:pointer;
  border:1px solid var(--edge);background:var(--surface-2)}
.chon2-o.on{border-color:var(--gold-vivid);background:color-mix(in srgb,var(--gold-vivid) 8%,var(--surface))}
.chon2-o input{margin-right:7px;accent-color:var(--gold-vivid)}
.chon2-o b{font-size:13.5px}
.chon2-o small{display:block;margin-top:4px;font-size:11.5px;color:var(--muted);line-height:1.45}
.chon2-o:has(input:disabled){opacity:.6;cursor:not-allowed}

select.text{width:100%;font:inherit;font-size:14px;padding:10px 12px;border-radius:9px;
  border:1px solid var(--edge);background:var(--surface-2);color:var(--ink)}
textarea.text{width:100%;font:inherit;font-size:13.5px;line-height:1.5;padding:10px 12px;
  border-radius:9px;border:1px solid var(--edge);background:var(--surface-2);color:var(--ink);
  resize:vertical}

/* Hồ sơ dự giải, hiện dưới tên người thi đấu — chỉ ban tổ chức thấy. */
.nguoi-row{flex-wrap:wrap}
.nguoi-row .tay.tk{color:var(--jade);border-color:var(--jade)}
.hoso{flex-basis:100%;display:flex;flex-wrap:wrap;gap:4px 14px;margin:5px 0 1px;
  padding-top:6px;border-top:1px dashed var(--edge);font-size:11.5px;color:var(--muted)}
.hoso i{font-style:normal;color:var(--faint);margin-right:5px}

/* ═══════════ lịch thi đấu trong cây đấu ═══════════ */
.tran-lich{display:flex;flex-wrap:wrap;align-items:center;gap:5px 8px;margin-top:5px;font-size:11px}
.tran-lich .chot{color:var(--jade);font-weight:600}
.tran-lich .de{color:var(--gold-vivid)}
.tran-lich .han{color:var(--faint)}
.tran-hen{margin-left:auto;font:inherit;font-size:11px;padding:3px 9px;border-radius:7px;
  border:1px solid var(--edge);background:var(--surface-2);color:var(--ink);cursor:pointer}
.tran-hen:hover{border-color:var(--gold-vivid)}
.henbox{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-top:6px}
.henbox .text{flex:1 1 170px;width:auto;font-size:12.5px;padding:6px 9px}
.henbox .btn{flex:none;width:auto}
.henbox small{flex-basis:100%;font-size:11px;color:var(--faint)}

/* Form hồ sơ dự giải, mở ngay dưới dòng người thi đấu. */
.hosoform{flex-basis:100%;margin-top:8px;padding:11px 12px;border-radius:10px;
  border:1px solid var(--gold-soft);background:var(--surface)}
.hosoform .field{margin-bottom:8px}
.hosoform .row{margin-top:4px}
.hosoform .btn{width:auto;flex:0 0 auto}

/* Cổng thanh toán đang mở, hiện ở trang đăng quảng cáo. */
.congtt{display:grid;gap:9px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));margin-top:8px}
.congtt-o{padding:10px 12px;border-radius:10px;border:1px solid var(--edge);background:var(--surface-2)}
.congtt-o b{font-size:13.5px}
.congtt-o small{display:block;margin-top:3px;font-size:11.5px;color:var(--muted);line-height:1.45}
.congtt-o span{display:inline-block;margin-top:6px;font-size:11px;color:var(--faint);
  border:1px solid var(--edge);border-radius:6px;padding:1px 6px}
.qc-tra{flex-basis:100%;display:flex;flex-wrap:wrap;align-items:center;gap:7px;margin-top:7px;
  padding-top:8px;border-top:1px dashed var(--edge)}
.qc-tra > span{font-size:11.5px;color:var(--muted)}
.qc-tra .btn{width:auto;flex:0 0 auto;padding:4px 12px;font-size:12px}

/* ═══════════ bảng ván đang đấu (trang chủ) ═══════════ */
.tran-loc{display:flex;gap:6px;flex-wrap:wrap;margin:0 0 12px}
.tran-loc button{flex:0 1 auto;padding:6px 14px;border-radius:999px;cursor:pointer;
  border:1px solid var(--edge);background:var(--surface-2);color:var(--muted);
  font:inherit;font-size:12.5px;white-space:nowrap}
.tran-loc button[aria-selected="true"]{background:var(--grad);color:var(--on-accent);
  border-color:transparent;font-weight:600}

/* Hai cột trên máy tính, một cột trên điện thoại — đúng như đặt hàng. */
.tran-luoi,.tran-them{display:grid;gap:12px;grid-template-columns:minmax(0,1fr)}
@media (min-width:720px){ .tran-luoi,.tran-them{grid-template-columns:repeat(2,minmax(0,1fr))} }
.tran-them{margin-top:12px}

.tran-o{display:block;padding:11px 13px;border-radius:12px;text-decoration:none;
  border:1px solid var(--edge);background:var(--surface-2);color:var(--ink);transition:.16s}
.tran-o:hover{border-color:var(--gold-vivid);transform:translateY(-1px)}
.tran-ke{display:flex;align-items:center;gap:8px;padding:3px 0}
.tran-ke img{width:26px;height:26px;border-radius:50%;flex:none;object-fit:cover;background:var(--edge)}
.tran-ke .ten{flex:1;min-width:0;font-size:13.5px;font-weight:500;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tran-ke .cap{flex:none;font-size:11.5px;color:var(--muted)}
.tran-ke .cham{width:9px;height:9px;border-radius:50%;flex:none}
.tran-ke .cham.do{background:var(--piece-red)}
.tran-ke .cham.den{background:var(--piece-black);border:1px solid var(--edge)}
.tran-chan{display:flex;flex-wrap:wrap;align-items:center;gap:4px 12px;margin-top:1px;
  padding-top:7px;border-top:1px dashed var(--edge);font-size:11.5px;color:var(--faint)}
.tran-chan .song{color:var(--jade,var(--gold-vivid));font-weight:600}
.tran-chan .luc{margin-left:auto}

/* ═══════════ nút thao tác trong phòng: chữ → biểu tượng ═══════════ */
/*
  Bốn nút "Xin hoà / Xin thua / Khoe ván / Chép link" xếp một hàng dưới bàn cờ.
  Trên điện thoại hàng ấy chật tới mức "Khoe ván" bị cắt thành "Khoe v…" — chữ
  cụt còn khó đoán hơn biểu tượng. Chuyển hết sang biểu tượng, giữ nguyên
  aria-label và title nên vẫn đọc được tên đầy đủ khi rê chuột hoặc bằng
  trình đọc màn hình.

  "Xin thua" giữ hộp xác nhận như cũ: bấm nhầm cái cờ trắng thì thua luôn ván,
  không có đường lùi.
*/
.btn.icon.chu::before{content:attr(data-chu);background:none;-webkit-mask:none;mask:none;
  width:auto;height:auto;font-size:17px;font-weight:600;line-height:1}
#resignBtn{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M5 21V4'/><path d='M5 4h11l-2 4 2 4H5'/></svg>")}
#shareBtn{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 12v7a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7'/><path d='M12 16V3'/><path d='M8 7l4-4 4 4'/></svg>")}
#nutToanMan{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M8 3H5a2 2 0 0 0-2 2v3'/><path d='M16 3h3a2 2 0 0 1 2 2v3'/><path d='M8 21H5a2 2 0 0 1-2-2v-3'/><path d='M16 21h3a2 2 0 0 0 2-2v-3'/></svg>")}
#nutToanMan[aria-pressed="true"]{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 9h3a2 2 0 0 0 2-2V4'/><path d='M20 9h-3a2 2 0 0 1-2-2V4'/><path d='M4 15h3a2 2 0 0 1 2 2v3'/><path d='M20 15h-3a2 2 0 0 0-2 2v3'/></svg>")}
#copyBtn{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1'/><path d='M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1'/></svg>")}
/* Hàng nút giờ toàn biểu tượng. Khi bật thoại thì có tới bảy nút, mà thẻ này
   chỉ rộng bằng nửa bàn cờ trên máy tính — cố định 38px là tràn xuống hàng
   hai. Cho chúng chia đều chỗ còn lại và co được tới 30px, vẫn đủ to để bấm
   bằng ngón tay. */
/* align-items:center + cùng một chiều cao: nếu để mỗi nút tự cao theo nội dung
   thì cái mang chữ "½" và cái mang ảnh SVG lệch nhau chừng một pixel — mắt
   không thấy, nhưng đó là dấu hiệu chúng không thật sự cùng một hàng, và phép
   thử bố cục bắt đúng chỗ ấy. */
.deck-acts{flex-wrap:wrap;align-items:center}
.deck-acts .btn.icon{flex:1 1 32px;min-width:30px;max-width:46px;width:auto;
  height:38px;min-height:38px;padding:0}

/* Bàn cờ trong thẻ "đang đấu" rộng đúng bằng cột, để mở trang chủ là đọc được
   thế cờ luôn chứ không phải bấm vào từng ván mới biết đang đánh tới đâu.
   Hai kỳ thủ xếp trên dưới đúng như lúc ngồi đối diện: Đen trên, Đỏ dưới. */
.tran-o{display:flex;flex-direction:column;gap:7px}
.tran-ban{width:100%}
/* Bàn cờ nhỏ dùng ĐÚNG bộ biến màu của bàn cờ thật, nên đổi sáng/tối là hai
   bên đổi theo nhau, không bao giờ lệch tông. */
.ban-nho-defs{position:absolute;width:0;height:0;overflow:hidden}
.ban-nho{display:block;width:100%;height:auto;border-radius:5px;
  border:1px solid var(--line);
  box-shadow:0 1px 0 rgba(255,255,255,.14) inset, 0 8px 20px -12px var(--shadow-strong)}
.ban-nho .go{fill:url(#bn-go)}
.ban-nho .sang{fill:url(#bn-sang)}
.ban-nho .toi{fill:url(#bn-toi)}
.ban-nho .khung{fill:none;stroke:var(--line);stroke-width:.34;opacity:.5}
.ban-nho .ke path{fill:none;stroke:var(--line);stroke-width:.42;opacity:.62}
.ban-nho .ke circle{fill:var(--line);opacity:.4}
/* Bàn nhỏ trước đây là hình phẳng: một đĩa màu, một vòng khắc, hết. Cùng một
   bàn cờ mà bên phòng chơi thì bẹt còn bên bàn online thì có khối — nhìn như
   hai trò khác nhau. Mấy lớp dưới đây dựng lại đúng thứ tự của bàn lớn: hai
   tầng bóng đổ, thành bên, mặt cong, rồi đốm bắt sáng.
   HAI VÒNG của mặt cờ (đĩa và nét khắc) giữ nguyên — chỉ thêm khối ở PHÍA
   NGOÀI, không đụng vào mặt. */
.ban-nho .bong2{fill:var(--shadow-strong);opacity:.15}
.ban-nho .bong{fill:var(--shadow-strong);opacity:.34}
.ban-nho .loe{fill:url(#bn-loe)}
.ban-nho .dia{fill:url(#bn-quan)}
.ban-nho .day{fill:url(#bn-day)}
/* Vành gỗ: bảy vòng đồng tâm, CHÉP ĐÚNG dãy màu của --vanh-quan ở đầu tệp.
   SVG không dùng được box-shadow nên phải vẽ thành vòng thật. Đây là bản sao
   duy nhất của dãy màu ấy — sửa một bên thì sửa cả hai, không thì bàn nhỏ và
   bàn lớn ra hai con cờ khác nhau. Màu ĐẶT CỨNG, không theo chủ đề sáng/tối,
   y như bên kia. */
.ban-nho .v0{fill:#4A2C0E}
.ban-nho .v1{fill:#7C511E}
.ban-nho .v2{fill:#A6762F}
.ban-nho .v3{fill:#F6E4BC}
.ban-nho .v4{fill:#C79647}
.ban-nho .v5{fill:#E0B972}
.ban-nho .v6{fill:#F1DBAB}
/* Vành vát mặt trong — cùng vai với --vat-quan ở quân trên bàn lớn. */
.ban-nho .vat{fill:none;stroke:url(#bn-vat);stroke-width:.31}
.ban-nho .khac{fill:none;stroke-width:.2;opacity:.65}
.ban-nho .q-do  .khac{stroke:var(--piece-red)}
.ban-nho .q-do  text{fill:var(--piece-red)}
.ban-nho .q-den .khac{stroke:var(--piece-black)}
.ban-nho .q-den text{fill:var(--piece-black)}
.ban-nho text{text-anchor:middle;dominant-baseline:central;
  font-family:"Noto Serif TC","Songti SC","Noto Serif SC",Georgia,serif;font-weight:700}


/* Khung sau khi ván xong: chơi tiếp với người cũ, hoặc bắt cặp khác. */
.banner.xong{flex-wrap:wrap;gap:8px}
.banner .banner-nut{display:flex;gap:8px;flex-wrap:wrap;margin-left:auto}
.banner .banner-nut .btn{width:auto;flex:0 0 auto;padding:6px 16px}
.banner .hint{flex-basis:100%;margin:0;font-size:11.5px}
@media (max-width:520px){
  .banner .banner-nut{margin-left:0;width:100%}
  .banner .banner-nut .btn{flex:1 1 0}
}

/* Ô chọn thể thức thời gian có thêm dòng phụ nói rõ mấy phút mấy giây. */
.seg button small{display:block;margin-top:2px;font-size:10.5px;opacity:.75;font-weight:400}
.roomrow .tag.gio{font-variant-numeric:tabular-nums;text-transform:none;letter-spacing:0;
  border:1px solid var(--edge);border-radius:6px;padding:1px 6px}
.tran-chan .gio{font-variant-numeric:tabular-nums}

/* Bên tới lượt: một chấm sáng nhè nhẹ, đủ thấy mà không kéo mắt khỏi bàn cờ. */
.tran-ke.toi-luot .cham{box-shadow:0 0 0 3px color-mix(in srgb,var(--gold-vivid) 45%,transparent)}
.tran-ke.toi-luot .ten{font-weight:600}
.tran-chan .nuoc{font-variant-numeric:tabular-nums}
/* Ô của nước vừa đi. Vẽ dưới quân nên không che mặt chữ. */
.ban-nho .vua{fill:var(--gold-vivid);opacity:.28}
.ban-nho .song text{fill:var(--line);opacity:.5;letter-spacing:.1em;
  font-family:"Noto Serif SC",Georgia,serif}

/* Ô tìm và bộ lọc trên trang giải đấu. */
.loc-giai{padding:12px 14px}
.timo{display:flex;gap:8px;margin-bottom:10px}
.timo .text{flex:1;min-width:0}
.timo .btn{flex:0 0 auto;width:auto;padding:6px 14px}
.loc-giai .tran-loc{margin:0}
.giai-them{display:flex;flex-wrap:wrap;gap:4px 10px;margin-top:6px;
  font-size:11.5px;color:var(--faint)}
.giai-them .ban{color:var(--gold-vivid);font-weight:600}
.giai-them b{color:var(--muted);font-weight:600}

/* Liên kết đóng vai nút: .btn vốn viết cho <button>, thẻ <a> thiếu mấy nét căn. */
a.btn{display:inline-grid;place-items:center;text-decoration:none;line-height:1.35}

/* Sảnh chờ: ảnh đại diện và cấp độ người mở bàn, để chọn bàn có căn cứ. */
.roomrow .av{width:26px;height:26px;border-radius:50%;flex:none;object-fit:cover;
  background:var(--edge)}
.roomrow .tag.cap{text-transform:none;letter-spacing:0;color:var(--muted);
  font-variant-numeric:tabular-nums}
#locSanh{margin:0 0 10px}
/* Chấm nước đi trong hình minh hoạ ở trang Hỏi đáp. */
.ban-nho .di{fill:var(--jade,#2e9e6b);opacity:.75}
.ban-nho .tam{fill:none;stroke:var(--gold-vivid);stroke-width:.7;opacity:.9}

/* ═══════════ trang Hỏi đáp ═══════════ */
.hd{border:1px solid var(--edge);border-radius:11px;background:var(--surface-2);
  padding:10px 13px;margin-bottom:9px}
.hd > summary{cursor:pointer;font-weight:600;font-size:13.5px;list-style:none;
  display:flex;gap:8px;align-items:flex-start}
.hd > summary::-webkit-details-marker{display:none}
.hd > summary::before{content:'▸';color:var(--gold-vivid);flex:none;line-height:1.5}
.hd[open] > summary::before{content:'▾'}
.hd-than{margin-top:8px;font-size:13px;line-height:1.65;color:var(--muted)}
.hd-than p{margin:0 0 8px}
.hd-than p:last-child{margin-bottom:0}
.hd-than b{color:var(--ink)}

/* Bảng quân cờ: hình bên trái, lời bên phải; điện thoại thì xếp dọc. */
.hd-quan{display:grid;gap:14px;grid-template-columns:minmax(0,1fr)}
@media (min-width:860px){ .hd-quan{grid-template-columns:repeat(2,minmax(0,1fr))} }
.hd-o{display:flex;gap:13px;align-items:flex-start;padding:11px;border-radius:12px;
  border:1px solid var(--edge);background:var(--surface-2)}
.hd-ban{flex:0 0 132px}
.hd-loi{min-width:0;flex:1}
.hd-loi h3{margin:0 0 4px;font-family:Fraunces,Georgia,serif;font-size:16px}
.hd-loi h3 span{font-family:"Noto Serif TC",serif;font-size:14px;color:var(--muted);
  font-weight:400;margin-left:5px}
.hd-loi p{margin:0;font-size:12.5px;line-height:1.6;color:var(--muted)}
@media (max-width:420px){ .hd-o{flex-direction:column} .hd-ban{flex:none;width:60%;margin:0 auto} }

/* ═══════════ đồng hồ: thấy rõ bên nào đang bị trừ giờ ═══════════ */
.dh{display:flex;flex-direction:column;align-items:flex-end;flex:none;line-height:1.05}
.clock-sub{font-size:10px;color:var(--faint);margin-top:2px;white-space:nowrap;
  letter-spacing:.02em}
.clock.cho{opacity:.45}
/* Bên tới lượt: đồng hồ sáng lên và thở nhẹ. Không nhấp nháy gắt — người ta
   nhìn bàn cờ chứ không nhìn đồng hồ, nó chỉ cần cho biết mình đang bị trừ. */
.clock.chay{color:var(--gold-vivid);animation:tho 2s ease-in-out infinite}
.player.turn .clock-sub{color:var(--gold-vivid)}
@keyframes tho{0%,100%{opacity:1}50%{opacity:.62}}
@media (prefers-reduced-motion:reduce){ .clock.chay{animation:none} }

/* ═══════════ bàn cờ ghim ở đầu, phần dưới cuộn ═══════════ */
@media (max-width:860px){
  /* Nền của khối ghim tràn ra quá mép trang một chút cho kín; cắt phần thừa
     ở đây. Dùng `clip` chứ KHÔNG dùng `hidden`: hidden biến .wrap thành khung
     cuộn, mà position:sticky thì bám vào khung cuộn gần nhất — bàn cờ sẽ hết
     ghim. clip chỉ cắt, không tạo khung cuộn. */
  .wrap{overflow-x:clip}
  .ghim{
    position:sticky; top:0; z-index:20;
    display:flex; flex-direction:column; gap:8px;
    padding-bottom:8px;
  }
  /* Nền đặc, KÉO RỘNG BẰNG PSEUDO chứ không bằng margin âm: khối ghim phải
     rộng đúng bằng bàn cờ vì mọi thẻ dưới nó cũng lấy đúng bề ngang ấy — nới
     nó ra là thẻ nhắn tin, hàng nút và biên bản lệch theo 20px.
     Nền phải phủ hết mép trang, không thì lúc cuộn thấy chữ chạy ở hai bên. */
  .ghim::before{content:"";position:absolute;inset:0 -12px;z-index:-1;
    background:var(--bg);pointer-events:none}
  /* Bóng mờ dưới đáy, cho biết còn nội dung trượt bên dưới. */
  .ghim::after{content:"";position:absolute;left:-12px;right:-12px;bottom:-10px;height:10px;
    background:linear-gradient(var(--bg),transparent);pointer-events:none}
}

/* ═══════════ bóng chat nổi trên bàn cờ ═══════════ */
/* Trên điện thoại ô nhập nằm trong dòng chảy gần như không bấm trúng: thanh
   menu dưới đáy và bàn phím thay nhau che đúng chỗ nó đứng. Nên chạm vào
   khung tin là mở tấm kính này, nổi ĐÈ LÊN bàn cờ chứ không đẩy nó đi — nhìn
   xuyên qua vẫn thấy thế cờ, mà chữ vẫn đọc rõ nhờ lớp mờ.
   --kb do JS đo bằng visualViewport: chiều cao bàn phím khác nhau theo máy,
   theo bộ gõ, theo cả việc có thanh gợi ý từ hay không — đoán là hụt. */
.bong-chat{
  position:fixed; z-index:80; left:10px; right:10px;
  bottom:calc(var(--kb, 0px) + 10px);
  /* Cao THEO SỐ TIN, trần là NỬA màn hình.
     Cao cố định thì lúc mới có hai tin, giữa bàn phím và dòng đầu tiên hở một
     mảng trống to bằng bàn tay — nhìn như khung bị treo lơ lửng, và mắt phải
     nhảy qua khoảng trống ấy mới tới chữ. Còn cao quá nửa màn hình thì nuốt
     mất bàn cờ, mà cái hay của khung này là vẫn thấy thế cờ sau lớp kính. */
  max-height:min(50vh, 420px); display:flex; flex-direction:column;
  border-radius:18px; overflow:hidden;
  background:color-mix(in srgb, var(--surface) 68%, transparent);
  border:1px solid color-mix(in srgb, var(--ink) 13%, transparent);
  box-shadow:0 18px 48px -12px var(--shadow-strong), 0 1px 0 rgba(255,255,255,.18) inset;
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)){
  .bong-chat{-webkit-backdrop-filter:blur(30px) saturate(180%);
             backdrop-filter:blur(30px) saturate(180%)}
}
.bong-dau{display:flex; align-items:center; justify-content:space-between; gap:8px;
  padding:9px 12px; flex:none;
  border-bottom:1px solid color-mix(in srgb, var(--ink) 9%, transparent)}
.bong-dau b{font-size:13px; font-weight:600; color:var(--gold-vivid)}
.bong-x{width:30px; height:30px; flex:none; display:grid; place-items:center;
  border-radius:50%; cursor:pointer; font-size:13px; line-height:1;
  color:var(--ink); background:var(--surface-2); border:1px solid var(--edge)}
.bong-than{display:flex; flex-direction:column; gap:8px; padding:10px; min-height:0}
/* Bỏ chiều cao tính theo số dòng: ở đây khung ăn hết chỗ trống của bóng, nên
   được bao nhiêu tin thì hiện bấy nhiêu. */
.bong-than .khung-chat{height:auto; max-height:none; flex:1; min-height:0}
/* Riêng bóng chat thì flex-basis phải là auto, không phải 0: có 0 thì khung
   không đóng góp chiều cao nội dung nào cả, và bóng luôn cao kịch trần dù chỉ
   có một tin — đúng cái khoảng trống cần bỏ. min-height giữ chỗ cho câu
   "chưa có tin nào", không thì lúc trống bóng mỏng như một sợi chỉ. */
.bong-chat .khung-chat{flex:1 1 auto; min-height:44px}
.bong-than #sayForm{display:flex}
/* Máy tính có bàn phím rời, phím không che màn hình, nên bóng không bao giờ mở
   ở đó — chặn sẵn cho chắc. */
@media (min-width:861px){ .bong-chat{display:none} }

/* ═══════════ khung trò chuyện dưới tên kỳ thủ ═══════════ */
/*
  Một dòng thời gian duy nhất cho cả tin riêng lẫn bình luận. Cao cố định và
  cuộn bên trong, nên dù trăm tin cũng KHÔNG đẩy bàn cờ hay mấy nút đi đâu —
  đó là điều kiện đặt ra từ đầu: quảng cáo hay chat gì cũng không được ảnh
  hưởng ván chơi.
*/
/* Chiều cao khung tính theo SỐ DÒNG, không phải một con số tròn trịa bốc ra —
   để 132px thì dòng cuối bị xén ngang, nhìn như lỗi chứ không ra "còn nữa".
   Nhưng dòng chỉ có chiều cao TỐI THIỂU: tin dài phải được xuống dòng và cao
   thêm, chứ ghim cứng 30px thì chữ tràn ra ngoài khung. */
.khung-chat{
  --kc-dong:30px; --kc-khe:6px; --kc-so:3;
  height:calc(var(--kc-dong) * var(--kc-so) + var(--kc-khe) * (var(--kc-so) - 1));
  overflow-y:auto; overscroll-behavior:contain;
  display:flex; flex-direction:column; gap:var(--kc-khe);
  padding:0; border:0; background:none;
}
/* Thẻ bọc mới giữ phần nền và viền; khung tin bên trong chỉ lo cuộn. */
.the-chat{display:flex;flex-direction:column;gap:10px}
.the-chat .chat-form{margin:0}
.khung-chat .empty{margin:auto;font-size:12px;color:var(--faint);text-align:center}
.kc-d{display:flex;align-items:flex-start;gap:7px;font-size:12.5px;line-height:1.4;
  min-height:var(--kc-dong);flex:none;box-sizing:border-box;
  padding:6px 9px 6px 7px;border-radius:9px;background:var(--surface-2)}
/* Tên và giờ giữ nguyên một dòng; chỉ NỘI DUNG tin được xuống dòng. */
.kc-d .kc-av, .kc-d .kc-ten, .kc-d .kc-nhan, .kc-d time{margin-top:1px}
.kc-d.toi{background:color-mix(in srgb,var(--gold-vivid) 12%,var(--surface))}
.kc-ten{font-weight:600;color:var(--ink);flex:none;max-width:30%;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.kc-nhan{flex:none;font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--gold-vivid);border:1px solid var(--gold-soft);border-radius:5px;padding:0 4px}
/* Ba loại tin, ba màu nhãn. Cùng một màu cho cả ba thì nhãn thành đồ trang
   trí — vẫn phải dừng lại đọc chữ mới biết câu này những ai nghe được, mà
   trong lúc đánh cờ thì không ai dừng lại đọc nhãn. */
.kc-nhan.nhan-cong{color:var(--jade);
  border-color:color-mix(in srgb, var(--jade) 45%, transparent)}
.kc-nhan.nhan-xem{color:var(--muted); border-color:var(--edge)}
/* Nút chọn nói riêng hay nói to, đứng ngay trước ô nhập. Bề ngang cố định để
   đổi chữ "Riêng" ↔ "Công khai" không làm ô nhập co giật. */
.chat-form .kieu-noi{flex:none; min-width:88px; padding:0 10px; font-size:11.5px;
  white-space:nowrap}
.chat-form .kieu-noi.cong{color:var(--jade);
  border-color:color-mix(in srgb, var(--jade) 45%, transparent)}
.kc-chu{flex:1;min-width:0;color:var(--muted);
  white-space:pre-wrap;overflow-wrap:anywhere;word-break:normal}
.kc-d.toi .kc-chu{color:var(--ink)}
.kc-d time{flex:none;font-size:10px;color:var(--faint);font-variant-numeric:tabular-nums}
/* Điện thoại: hai dòng tin. Ba dòng thì cả cụm bàn cờ + trạng thái + chat
   vượt màn hình mất mấy chục pixel, mà mục đích là không phải vuốt. Muốn đọc
   nhiều hơn thì cuộn ngay trong khung, không phải cuộn cả trang. */
@media (max-width:860px){ .khung-chat{--kc-so:2} }
@media (min-width:861px){ .khung-chat{--kc-so:5} }

/* Ảnh đại diện trong khung trò chuyện. */
.kc-av{position:relative;flex:none;width:26px;height:26px;border-radius:50%;
  display:inline-grid;place-items:center;overflow:visible;
  background:var(--surface-2);border:1px solid var(--edge)}
.kc-av img{width:100%;height:100%;border-radius:50%;object-fit:cover}
.kc-av .chu{font-size:11px;font-weight:700;color:var(--muted)}
/* Kỳ thủ nổi hơn khán giả: viền theo màu quân, kèm chữ Soái/Tướng ở góc. */
.kc-av.ky-thu{border-width:2px}
.kc-av.ky-thu.do{border-color:var(--piece-red)}
.kc-av.ky-thu.den{border-color:var(--piece-black)}
/* Huy hiệu quân cầm, nhô ra góc dưới phải. Hàng chat có margin trái đủ rộng
   nên nó không đụng vào chữ của dòng bên. */
.kc-av.ky-thu i{position:absolute;right:-4px;bottom:-4px;
  width:13px;height:13px;border-radius:50%;display:grid;place-items:center;
  font-style:normal;font-size:8.5px;font-weight:700;line-height:1;
  font-family:"Noto Serif TC","Songti SC",serif;
  background:var(--disc);border:1px solid currentColor}
.kc-av.ky-thu.do i{color:var(--piece-red)}
.kc-av.ky-thu.den i{color:var(--piece-black)}
.kc-d{align-items:center}

/* ═══════════ mục "Ghim bàn cờ" trong menu ═══════════ */
/* Chỉnh một lần rồi thôi, nên nằm trong menu chứ không dán lên bàn cờ — để
   nổi ngay cạnh bàn cờ thì suốt ván cứ vướng mắt. */
.umenu-i.tick-i{display:flex;align-items:center;gap:8px}
.umenu-i.tick-i .dau{flex:none;width:14px;text-align:center;
  color:var(--gold-vivid);font-weight:700}
.umenu-i.tick-i[aria-pressed="false"]{color:var(--muted)}
/* Thả ghim: bàn cờ cuộn theo trang như mọi thứ khác. */
/* Máy tính vốn không ghim (chỉ có media query cho điện thoại), giấu mục đi. */
@media (min-width:861px){ .umenu-i.tick-i{display:none} }

/* ═══════════ máy tính rộng: khung trò chuyện sang cột phải ═══════════ */
/*
  Từ 1180px trở lên là thừa chỗ hai bên bàn cờ. Đưa khung trò chuyện, biên bản
  và ô quảng cáo sang cột phải: đọc chat mà không phải cuộn, và bàn cờ ngồi
  đúng giữa tầm mắt thay vì bị đẩy lên đỉnh màn hình.
  Dưới ngưỡng ấy thì xếp dọc như cũ — ép hai cột vào màn hẹp là cả hai đều chật.
*/
/* Hai cột, mỗi cột MỘT khối. Trên điện thoại chúng chỉ là hai đoạn xếp dọc
   nối nhau, cùng một nhịp giãn 12px như mọi thẻ khác trong trang. */
.cot-trai, .cot-phai{display:flex;flex-direction:column;gap:12px;width:100%}
/* Hai thẻ tên kỳ thủ cách bàn cờ ĐÚNG một khe thẻ, như mọi thẻ khác trong
   trang. Trước đây trên máy tính chúng dính sát vào bàn cờ (khe 0) trong khi
   mọi thẻ quanh đó cách nhau 12px — nhìn như ba thứ bị dán liền, không ra ba
   cái thẻ. Điện thoại đã có khe 8px riêng, khớp sẵn với nhịp giãn ở đó. */
@media (min-width:861px){
  .ghim{display:flex; flex-direction:column; gap:12px}
}
/* Điện thoại bóp nhịp lại: mỗi 4px tiết kiệm được là 4px bớt phải vuốt, mà
   cả cụm bàn cờ + trạng thái + chat chỉ hụt màn hình có mấy pixel. */
@media (max-width:860px){
  .cot-trai, .cot-phai, .hang-duoi{gap:8px}
  .game{gap:8px}
  .hang-duoi .card{padding:9px 11px}
  .the-chat{padding:10px}
}

/* CHỈ áp cho trang phòng cờ — nhận ra bằng sự có mặt của .cot-phai. Trang
   "đánh với máy" cũng có .game và .board-col nhưng bố cục khác hẳn (bàn cờ
   trái, bảng điều khiển phải); trước khi khoanh vùng, `display:contents` ở
   dưới đây xổ tung con của .board-col ra và trang ấy vỡ bố cục. */
@media (min-width:1100px){
  /* Chỉ hai ô lưới, mỗi ô một khối — không rải từng thẻ vào lưới nữa. */
  /* `justify-content:center` chứ không để lưới giãn hết bề ngang: để giãn thì
     cột trái được cấp rộng hơn bàn cờ, phần thừa nằm lại BÊN TRONG cột và đẩy
     cột phải ra xa — đo được khe 77px trong khi khe chuẩn giữa các thẻ là
     22px. Bàn cờ và cột phải phải nằm gần nhau, cách nhau đúng một khe thẻ,
     rồi cả cụm căn giữa trang. */
  .game:has(.cot-phai){display:grid; grid-template-columns:auto minmax(300px, 380px);
        gap:22px; justify-content:center; justify-items:start; align-items:start}
  /* Ở khổ này --bw phải BỎ nhánh `min(100%, …)`. Cột trái của lưới là `auto`,
     tức bề rộng do NỘI DUNG quyết định — nên `100%` quay lại hỏi đúng cái cột
     đang chờ nó trả lời. Trang phòng thoát được vì room.html tự đo rồi đặt
     --bw thành px thật (doBanTo), và style nội tuyến ấy vẫn thắng luật này.
     Trang xem lại và trang cờ thế không có đoạn JS đó nên rơi thẳng vào vòng:
     đo được cột trái 313px và 302px giữa màn hình 1440.
     Bỏ nhánh 100% ở đây là an toàn — cột trái luôn còn dư chỗ (1100 trừ cột
     phải 300 trừ khe), nên nhánh ấy chưa bao giờ là nhánh quyết định. */
  .game:has(.cot-phai) > .board-col{
    display:contents; width:auto;
    --bw:min(660px, max(420px, (100vh  - 360px) * 0.905));
    --bw:min(660px, max(420px, (100svh - 360px) * 0.905))}
  .cot-trai{grid-column:1; width:var(--bw); justify-self:start}
  .cot-phai{grid-column:2; align-self:start}
  .cot-phai .khung-chat{--kc-so:7}
}

/* Mấy khung báo chỉ có nội dung khi cần (lời xin hoà, nút chơi tiếp, khung
   mời). Lúc rỗng chúng vẫn là con của cột nên vẫn ăn một khe 12px — cộng lại
   thành khoảng hở gấp ba bốn lần chỗ khác, nhìn như bố cục vỡ. */
#offerBox:empty, #undoBox:empty, #againBox:empty, #inviteBox:empty{display:none}

/* ═══════════ hàng dưới bàn cờ: trạng thái | nút ═══════════ */
/* Hai cột thay vì hai thẻ chồng nhau: bớt được một tầng chiều cao, mà trên
   điện thoại mỗi tầng là một lần phải vuốt. */
.hang-duoi{display:flex;gap:12px;align-items:stretch;width:100%}
.hang-duoi .deck-say{flex:1 1 auto;min-width:0;justify-content:center}
/* Thẻ bọc .deck xoá khỏi bố cục: nó còn sót lại từ hồi bọc CẢ thẻ trạng thái
   lẫn hàng nút thành hai cột, mà giờ .hang-duoi làm đúng việc ấy. Để nguyên
   thì cái lưới hai cột cũ vẫn tính chỗ cho một cột rỗng, hàng nút phình gấp
   đôi và đẩy thẻ trạng thái teo lại còn 38px. */
.hang-duoi .deck{display:contents}
.hang-duoi .deck-acts{flex:0 0 auto}
/* Hàng nút rộng đúng bằng nội dung của nó: lưới cột cố định thì bề ngang tự
   nhiên là 6×38 + khe, nên .deck-say lấy phần còn lại thay vì ăn sạch rồi
   dồn mấy cái nút xuống thành sáu tầng. Chỉ máy tính mới cần — trên điện
   thoại cả thẻ này đã giấu đi, nút nằm trong quạt +. */
@media (min-width:861px){
  .hang-duoi .deck-acts{display:grid; grid-auto-flow:column; grid-auto-columns:38px;
    grid-auto-rows:38px; align-content:center; justify-content:center; gap:6px}
  .hang-duoi .deck-acts .btn.icon{width:38px; height:38px; min-height:38px; max-width:none}
}

/* ═══════════ hàng nút ngay dưới bàn cờ (chỉ máy tính) ═══════════ */
/*
  Trước đây trên máy tính cả hàng nút bị đẩy lên đầu cột phải, xa chỗ mắt đang
  nhìn: muốn xin hoà hay chép link phải rời mắt khỏi bàn cờ, quét sang cột kia,
  rồi dò trong một dãy ô vuông không tên xem cái nào là cái nào. Giờ nó nằm
  ngay dưới thanh tên của chính mình, sát bàn cờ, và MỖI NÚT CÓ TÊN.

  Tên lấy từ data-ten chứ không phải aria-label: aria-label nói cả trạng thái
  cho trình đọc màn hình ("Đang bật tiếng — bấm để tắt"), dài như thế bày ra
  màn hình là hàng nút vỡ. Hai nút đổi việc theo trạng thái (loa, phóng to) thì
  JS đổi luôn data-ten, nên tên không bao giờ nói sai việc nút đang làm.

  Chỉ máy tính: dưới 1100px hàng nút quay về trong .hang-duoi, và dưới 860px
  nó ẩn hẳn — ở đó mọi việc này đã nằm trong menu +, vốn đã có tên đầy đủ.
*/
@media (min-width:1100px){
  /* display:block đè luật hai cột ở trên (.deck từng bọc CẢ thẻ trạng thái lẫn
     hàng nút). Giờ trong này chỉ còn hàng nút, để nguyên lưới hai cột thì cột
     thứ hai rỗng và thẻ nút teo lại đúng một nửa bàn cờ. */
  .cot-trai > .deck{display:block; width:100%}
  /* MỘT hàng, không quấn. Quấn xuống ba tầng thì cụm nút cao bằng một phần tư
     bàn cờ và đẩy mọi thứ dưới nó đi — mà đây chỉ là hàng nút phụ. */
  .cot-trai > .deck .deck-acts{
    display:flex; flex-wrap:nowrap; gap:6px; align-items:stretch}
  /* Chia đều bề ngang bàn cờ. min-width:0 để lúc bật thoại (thêm ba nút) cả
     hàng vẫn co được thay vì tràn ra ngoài thẻ. */
  .cot-trai > .deck .deck-acts .btn.icon{
    flex:1 1 0; width:auto; min-width:0; max-width:none;
    height:auto; min-height:56px; padding:8px 4px 7px; row-gap:5px}
  /* Tên hẹp quá thì cắt bằng dấu ba chấm, không xuống dòng — xuống dòng là
     các nút cao so le, nhìn như hàng bị lỗi. */
  .cot-trai > .deck .deck-acts .btn.icon::after{
    content:attr(data-ten); font-size:10.5px; line-height:1.15; font-weight:500;
    display:block; max-width:100%; white-space:nowrap;
    overflow:hidden; text-overflow:ellipsis}
}

/* ═══════════ menu tab dưới đáy (chỉ điện thoại) ═══════════ */
.menu-duoi{display:none}
@media (max-width:860px){
  .menu-duoi{
    display:grid; grid-auto-flow:column; grid-auto-columns:1fr; gap:6px;
    position:fixed; left:0; right:0; bottom:0; z-index:65;
    padding:7px 10px calc(env(safe-area-inset-bottom, 0px) + 7px);
    border-radius:16px 16px 0 0;
    background:color-mix(in srgb, var(--surface) 84%, transparent);
    border:1px solid var(--edge); border-bottom:0;
    box-shadow:0 -8px 28px -14px var(--shadow-strong);
  }
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)){
    .menu-duoi{-webkit-backdrop-filter:blur(16px) saturate(160%);
               backdrop-filter:blur(16px) saturate(160%)}
  }
  .menu-duoi[hidden]{display:none}
  .menu-duoi button{
    min-height:40px; border-radius:12px; cursor:pointer; padding:0 8px;
    font:inherit; font-size:13px; font-weight:600; white-space:nowrap;
    color:var(--muted); background:transparent; border:0;
  }
  .menu-duoi button[aria-selected="true"]{color:var(--on-accent);background:var(--grad)}
  /* Còn ghế trống thì nhấn sáng mục "Mời": chỉ đường tới việc đang cần làm mà
     không bung cả cái khung mời ra chiếm chỗ. Nhấp nháy nhẹ thôi — chớp giật
     ngay cạnh bàn cờ thì suốt ván cứ vướng mắt. */
  .menu-duoi button.goi{color:var(--gold-vivid);border-color:var(--gold);
    animation:goiMoi 2.4s ease-in-out infinite}
  @media (prefers-reduced-motion: reduce){ .menu-duoi button.goi{animation:none} }
  /* Tấm nào không được chọn thì ẩn hẳn — đó là điểm của tab. */
  .tam.an{display:none}
  /* Đang gõ thì hạ menu xuống, nhường chỗ cho ô nhập và bàn phím. */
  /* Bóng chat mở thì hạ thanh menu và nút + xuống: hai lớp nổi chồng nhau
     vừa che mất tin vừa dễ bấm nhầm. */
  body.bong-mo .menu-duoi, body.bong-mo .quat{display:none}
}

/* ═══════════ trang văn bản dài: chính sách, điều khoản ═══════════ */
/* Chữ to hơn và dòng thưa hơn phần còn lại của trang. Đây là thứ người ta ĐỌC
   HẾT chứ không liếc qua, mà đọc một trang luật bằng cỡ chữ của thẻ danh sách
   thì mỏi mắt bỏ giữa chừng. Bề ngang cũng chặn lại ~68 ký tự: dòng dài quá,
   mắt nhảy xuống dòng dễ lạc mất chỗ. */
.vb{max-width:72ch;margin:0 auto;line-height:1.75;font-size:15px;color:var(--ink)}
.vb h2{margin:0 0 4px;font-size:23px}
.vb h3{margin:30px 0 8px;font-size:17px;color:var(--gold-vivid)}
.vb h4{margin:18px 0 4px;font-size:15px;color:var(--ink);font-weight:600}
.vb p{margin:0 0 12px}
.vb ul{margin:0 0 12px;padding-left:22px}
.vb li{margin:0 0 6px}
.vb code{font-size:13px;padding:1px 5px;border-radius:5px;
  background:var(--surface-2);border:1px solid var(--edge)}
.vb a{color:var(--gold-vivid)}
.vb-ngay{color:var(--muted);font-size:13px;margin:0 0 20px !important}
/* Tóm tắt đứng đầu: ai không đọc hết thì ít nhất nắm được ý chính. */
.vb-tom{margin:0 0 24px;padding:13px 15px;border-radius:12px;
  background:var(--surface-2);border:1px solid var(--edge);
  border-left:3px solid var(--gold)}
/* Chỗ phải đọc kỹ — viền đỏ son, không phải để doạ mà để mắt dừng lại. */
.vb-canh{padding:13px 15px;border-radius:12px;
  background:color-mix(in srgb, var(--cinnabar) 8%, transparent);
  border:1px solid color-mix(in srgb, var(--cinnabar) 30%, transparent)}
.vb-luu{padding:11px 14px;border-radius:12px;background:var(--surface-2);
  border:1px solid var(--edge)}
.vb-bang{width:100%;border-collapse:collapse;margin:0 0 12px;font-size:14px}
.vb-bang th,.vb-bang td{text-align:left;padding:8px 10px;
  border-bottom:1px solid var(--edge);vertical-align:top}
.vb-bang th{color:var(--muted);font-weight:600;font-size:13px}
.vb-lien{margin-top:30px;padding-top:16px;border-top:1px solid var(--edge);
  color:var(--muted);font-size:14px}
@media (max-width:560px){
  .vb{font-size:14.5px}
  .vb h2{font-size:20px}
  .vb-bang{font-size:13px}
  .vb-bang th,.vb-bang td{padding:7px 6px}
}

/* ═══════════ chân trang ═══════════ */
/* Link pháp lý phải THẤY ĐƯỢC trên điện thoại. Dòng phụ đề cạnh tên trang bị
   ẩn hẳn ở màn hẹp, nên để link ở đó là gần như giấu chúng đi. */
.chan{margin-top:26px;padding-top:16px;border-top:1px solid var(--edge);
  display:flex;flex-wrap:wrap;align-items:center;gap:6px 14px;
  color:var(--faint);font-size:12.5px;line-height:1.7}
.chan a{color:var(--muted);text-decoration:none}
.chan a:hover{color:var(--gold-vivid);text-decoration:underline}
.chan .cach{opacity:.45}
@media (max-width:560px){ .chan{gap:5px 10px;font-size:12px} }

/* ═══════════ phóng to bàn cờ (chỉ máy tính) ═══════════ */
/*
  Bình thường bàn cờ bị kẹp ở 660px vì .wrap rộng 1040px và còn phải chừa chỗ
  cho cột phải. Trên màn 27 inch thì bàn cờ bé tí giữa một biển chỗ trống.

  Bật phóng to: nới .wrap ra, bỏ trần 660px, và cho bàn cờ giãn tới gần hết
  CHIỀU CAO màn hình — chiều cao mới là thứ giới hạn thật, vì bàn cờ cao gấp
  632/572 lần bề ngang. Mọi thẻ khác JS đã dời sang cột phải, nên trên dưới bàn
  chỉ còn hai thanh tên kỳ thủ.

  Không đụng gì tới điện thoại: mọi thứ ở đây nằm trong @media máy tính, và JS
  tự tắt chế độ này khi màn hình co lại dưới ngưỡng.
*/
/* Phải là `.btn.chi-may` chứ không `.chi-may` trần: `.btn.icon` có độ ưu tiên
   cao hơn nên nó thắng, và nút phóng to vẫn hiện trên điện thoại — chỗ mà bàn
   cờ vốn đã chiếm gần hết bề ngang, phóng to chẳng để làm gì. */
.btn.chi-may{display:none}
@media (min-width:1100px){
  .btn.chi-may{display:inline-grid}
  .chi-may[hidden]{display:none}

  body.to-ban .wrap{max-width:min(1720px, 100vw - 40px)}
  /* Giấu đầu trang khi phóng to. Trên màn 900px, chiều cao mới là thứ chặn bàn
     cờ, nên bỏ trần bề ngang gần như chẳng được gì — đo được 537→555px, vỏn vẹn
     3%. Đầu trang và đường kẻ chiếm ~90px; nhường chỗ ấy cho bàn cờ thì mới
     đúng nghĩa "phóng to cho dễ nhìn". Nút thu nhỏ vẫn nằm ở cột phải nên lúc
     nào cũng quay ra được. */
  body.to-ban header, body.to-ban .rule{display:none}
  /* Bề ngang thật do JS đo và ghi đè (xem doBanTo trong room.html). Dòng dưới
     chỉ là mức đỡ cho khoảnh khắc trước khi JS chạy, để bàn cờ khỏi loé một
     nhịp ở cỡ cũ rồi mới nhảy sang cỡ mới. */
  body.to-ban .board-col{
    --bw:min(100%, max(420px, (100svh - 330px) * 0.905));
  }
  /* Bóp phần khung trên dưới lại để nhường chỗ cho bàn cờ. Mỗi pixel tiết kiệm
     ở đây là một pixel bàn cờ to thêm — mà phóng to thì chính là để bàn cờ to
     lên cho dễ nhìn, mấy thứ khác đã sang cột phải cả rồi. */
  body.to-ban .wrap{padding-top:12px; padding-bottom:12px}
  /* Hai thanh tên bóp gọn lại: mỗi pixel lấy được ở đây là một pixel bàn cờ to
     thêm. Vẫn đủ chỗ cho ảnh đại diện, tên và đồng hồ — chỉ bớt lề. */
  body.to-ban .player{padding:6px 12px}
  body.to-ban .player .side{width:30px;height:30px;font-size:16px}
  body.to-ban .player .clock{font-size:17px}
  body.to-ban .rule{margin:8px 0}
  body.to-ban header{margin-bottom:0}
  /* Cột phải rộng thêm chút: giờ nó ôm cả trạng thái, hàng nút, chat và biên
     bản, mà 300px thì hàng sáu nút bắt đầu chật. */
  body.to-ban .game:has(.cot-phai){grid-template-columns:auto minmax(340px, 400px)}

  /* Trong cột phải, hàng dưới XẾP DỌC: trạng thái một dòng, hàng nút một dòng.
     Ép hai cột vào bề ngang 340px thì hàng nút chiếm 326px, thẻ trạng thái còn
     đúng 62px và chữ "Đợi đối thủ đi" cụt thành "Đ…". */
  .cot-phai .hang-duoi{flex-direction:column; align-items:stretch; gap:8px}
  .cot-phai .hang-duoi .deck-say{width:100%; flex:none}
  .cot-phai .hang-duoi .deck-acts{width:100%; justify-content:center}
  /* Khung chat cao theo màn hình luôn, không thì cột phải hụt hẫng một mảng
     trống bên dưới trong khi bàn cờ cao vống lên. */
  body.to-ban .cot-phai .khung-chat{--kc-so:11}
}

/* ═══════════ ô địa chỉ chép được (superadmin) ═══════════ */
/* Địa chỉ dán sang Facebook phải khớp từng ký tự, nên cho bấm phát là chép —
   gõ tay hay bôi đen chuột đều dễ hụt ký tự đầu/cuối. */
.chep{cursor:pointer;user-select:all;display:inline-block;max-width:100%;
  overflow-wrap:anywhere;border-radius:5px;padding:2px 6px;
  background:var(--surface-2);border:1px solid var(--edge);
  transition:border-color .15s, color .15s}
.chep:hover,.chep:focus-visible{border-color:var(--gold);color:var(--gold-vivid);outline:none}
/* Dòng hay dán nhầm nhất — đánh dấu để mắt dừng lại ở đúng chỗ. */
.tbl tr.quan td{background:color-mix(in srgb, var(--gold) 9%, transparent)}
.tbl td.phu{color:var(--muted);font-size:12.5px}
.hint.canh{padding:9px 12px;border-radius:10px;
  background:color-mix(in srgb, var(--cinnabar) 8%, transparent);
  border:1px solid color-mix(in srgb, var(--cinnabar) 28%, transparent)}

/* ═══════════ hiệu ứng đi quân và ăn quân ═══════════ */
/* Mọi cỡ đo bằng cqw (phần trăm bề ngang bàn cờ) nên hiệu ứng co giãn đúng tỉ
   lệ khi bàn cờ phóng to hay thu nhỏ. Đặt px thì bàn 414px và bàn 738px có đốm
   lửa to bằng nhau, nhìn lệch hẳn. */

/* Quân đang bay: nhấc lên một chút và nổi trên các quân khác. Mắt bám được
   thứ đang chuyển động chứ không phải đoán xem quân nào vừa đổi chỗ. */
.pc.hu-bay{
  z-index:6;
  transform:scale(1.07);
  box-shadow:
    var(--vanh-quan),
    var(--vat-quan),
    0 0 0 1.05cqw color-mix(in srgb, var(--gold) 34%, transparent),
    0 1.9cqw 2.9cqw -.7cqw var(--shadow-strong);
}

/* Sóng lan ở ô vừa đặt quân xuống — dấu chấm hết cho nước đi, và chỉ đúng chỗ
   cần nhìn khi đối thủ vừa đi mà mình đang ngó chỗ khác. */
.hu-song{position:absolute;width:0;height:0;z-index:1;pointer-events:none}
.hu-song::before,.hu-song::after{
  content:"";position:absolute;left:0;top:0;border-radius:50%;
  width:11cqw;height:11cqw;margin:-5.5cqw 0 0 -5.5cqw;
  border:.34cqw solid var(--gold);
  animation:lanSong .58s cubic-bezier(.2,.7,.3,1) forwards;
}
.hu-song::after{animation-delay:.13s;opacity:0}
@keyframes lanSong{
  0%  {transform:scale(.28);opacity:.9}
  100%{transform:scale(1.3); opacity:0}
}

/* ── Cháy khi ăn quân ── */
.hu-lua{position:absolute;width:0;height:0;z-index:7;pointer-events:none}
/* Quầng lửa bùng lên rồi tắt. Vàng ở lõi, cam rồi đỏ son ra rìa — cùng hệ màu
   với quân Đỏ và nét kẻ trên bàn, nên nó vẫn thuộc về bàn cờ này. */
.hu-lua .hu-loe{
  position:absolute;left:0;top:0;width:15cqw;height:15cqw;margin:-7.5cqw 0 0 -7.5cqw;
  border-radius:50%;
  background:radial-gradient(circle,
    rgba(255,244,214,.95) 0%, rgba(255,196,84,.9) 26%,
    rgba(232,120,32,.75) 48%, rgba(163,47,28,.45) 66%, transparent 74%);
  animation:loeChay .5s ease-out forwards;
}
@keyframes loeChay{
  0%  {transform:scale(.3);opacity:0}
  18% {opacity:1}
  100%{transform:scale(1.45);opacity:0}
}
/* Tàn than văng ra. Nhỏ dần và tối dần khi bay xa — than nguội đi. */
.hu-lua .hu-than{
  position:absolute;left:0;top:0;width:1.6cqw;height:1.6cqw;margin:-.8cqw 0 0 -.8cqw;
  border-radius:50%;
  background:radial-gradient(circle at 35% 30%, #FFF0C4, #F59E2B 55%, #A32F1C 100%);
  box-shadow:0 0 .9cqw rgba(245,158,43,.85);
  animation:banThan .72s cubic-bezier(.12,.6,.25,1) forwards;
  animation-delay:var(--tre,0ms);
}
@keyframes banThan{
  0%  {transform:translate(0,0) scale(1);   opacity:1}
  70% {opacity:.85}
  100%{transform:translate(var(--x,0), var(--y,0)) scale(.15); opacity:0}
}
/* Quân bị ăn cháy rụi: loé sáng lên rồi co lại và tối đi, thay vì chỉ mờ dần. */
.pc.hu-tan{
  animation:tanChay .42s ease-in forwards;
  pointer-events:none;
}
@keyframes tanChay{
  0%  {opacity:1;   transform:scale(1);   filter:none}
  30% {opacity:.95; transform:scale(1.12); filter:brightness(2.1) saturate(1.6)}
  100%{opacity:0;   transform:scale(.35); filter:brightness(.35) saturate(.4)}
}

@media (prefers-reduced-motion: reduce){
  .pc.hu-bay{transform:none;box-shadow:var(--vanh-quan)}
  .hu-song{display:none}
  .hu-lua .hu-loe{animation:none;opacity:.55}
}

/* ═══════════ cụm nút nổi và menu dọc (điện thoại) ═══════════ */
/* Hàng nút tròn cho mấy việc HAY LÀM, menu dọc có tên cho phần còn lại.
   Bản trước cho mọi nút bay theo cung tròn quanh nút +: đẹp nhưng chỉ nhét vừa
   cái biểu tượng, mà biểu tượng trần thì phải đoán nghĩa — đoán sai ở nút "xin
   thua" là mất ván. Danh sách dọc là chỗ duy nhất chữ nằm vừa. */
.quat{position:fixed; z-index:75; right:12px;
  bottom:calc(env(safe-area-inset-bottom, 0px) + 12px)}
/* `flex:none` cho mọi nút: thiếu nó thì flex bóp nút + lại vài pixel để nhét
   vừa hàng, và nó tràn sang chỗ nút bên cạnh — đo được khe -3px, tức hai nút
   chồng lên nhau. */
.quat-hang{display:flex; align-items:center; gap:8px}
.quat-hang > button{flex:none}

.quat-tron{width:44px; height:44px; flex:none; display:grid; place-items:center;
  border-radius:50%; cursor:pointer; color:var(--ink);
  background:var(--surface); border:1px solid var(--edge);
  box-shadow:0 8px 22px -10px var(--shadow-strong);
  transition:opacity .18s, transform .18s, color .18s}
.quat-tron::before{content:""; width:20px; height:20px; background:currentColor;
  -webkit-mask:var(--ic) center/contain no-repeat; mask:var(--ic) center/contain no-repeat}
.quat-tron[hidden]{display:none}
/* Nút đang TẮT thì xám đi và có nét gạch chéo trong chính biểu tượng — chỉ đổi
   màu thôi thì người bị mù màu không phân biệt được bật hay tắt. */
.quat-tron.tat{color:var(--faint)}
/* Nút trò chuyện là việc hay làm nhất, cho nó nổi hơn một bậc. */
.quat-tron.chinh{color:var(--gold-vivid); border-color:var(--gold)}

.quat-nut{position:relative; width:52px; height:52px; flex:none;
  display:grid; place-items:center; border:0; border-radius:50%; cursor:pointer;
  color:var(--on-accent); background:var(--grad);
  box-shadow:0 10px 26px -8px var(--shadow-strong);
  transition:transform .24s cubic-bezier(.2,.9,.3,1.4)}
/* Dấu + xoay 135° thành ✕ khi mở: cùng một nét, nhìn là hiểu bấm lần nữa thì
   đóng. */
.quat-nut::before, .quat-nut::after{content:""; position:absolute;
  background:currentColor; border-radius:2px}
.quat-nut::before{width:20px; height:2.5px}
.quat-nut::after {width:2.5px; height:20px}
.quat.mo .quat-nut{transform:rotate(135deg)}
/* Còn ghế trống thì nhấn sáng nút + — mục "Mời" nằm bên trong nó. */
.quat-nut.goi{animation:goiMoi 2.4s ease-in-out infinite}

.quat-menu{position:absolute; right:0; bottom:60px; min-width:210px;
  display:flex; flex-direction:column; gap:6px; padding:8px; border-radius:16px;
  background:color-mix(in srgb, var(--surface) 92%, transparent);
  border:1px solid var(--edge);
  box-shadow:0 18px 44px -14px var(--shadow-strong)}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)){
  .quat-menu{-webkit-backdrop-filter:blur(18px) saturate(165%);
             backdrop-filter:blur(18px) saturate(165%)}
}
.quat-menu[hidden]{display:none}
.qm-i{display:flex; align-items:center; gap:11px; width:100%;
  padding:10px 12px; border-radius:11px; cursor:pointer; text-align:left;
  font:inherit; font-size:14px; color:var(--ink);
  background:transparent; border:0;
  /* Bung ra lệch nhau một nhịp, trông như mở ra chứ không nhảy phắt một cái. */
  animation:qmVao .22s cubic-bezier(.2,.8,.3,1) backwards;
  animation-delay:calc(var(--i, 0) * 26ms)}
.qm-i:hover, .qm-i:focus-visible{background:var(--surface-2); outline:none}
.qm-ic{width:20px; height:20px; flex:none; background:currentColor;
  -webkit-mask:var(--ic) center/contain no-repeat; mask:var(--ic) center/contain no-repeat}
@keyframes qmVao{from{opacity:0; transform:translateY(8px)} to{opacity:1; transform:none}}
@media (prefers-reduced-motion: reduce){
  .qm-i{animation:none}
  .quat-nut{transition:none}
}
/* Hộp nổi đang mở thì hạ cụm nút xuống: hai lớp nổi chồng nhau vừa che nội
   dung vừa dễ bấm nhầm. */
body.hop-mo .quat, body.bong-mo .quat{display:none}

/* Hộp nổi dùng chung, cùng dáng kính mờ với bóng chat. */
.hop-noi{position:fixed; z-index:80; left:10px; right:10px;
  bottom:calc(var(--kb, 0px) + 10px);
  max-height:min(64vh, 460px); display:flex; flex-direction:column;
  border-radius:18px; overflow:hidden;
  background:color-mix(in srgb, var(--surface) 76%, transparent);
  border:1px solid color-mix(in srgb, var(--ink) 13%, transparent);
  box-shadow:0 18px 48px -12px var(--shadow-strong), 0 1px 0 rgba(255,255,255,.18) inset}
.hop-noi[hidden]{display:none}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)){
  .hop-noi{-webkit-backdrop-filter:blur(20px) saturate(170%);
           backdrop-filter:blur(20px) saturate(170%)}
}
.hop-noi .bong-than{overflow:auto}
.hop-noi .card{background:transparent; border:0; padding:0; box-shadow:none}
@media (min-width:861px){ .hop-noi{display:none} }

/* Bộ biểu tượng cho menu dọc và hàng nút nổi. Vẽ bằng mask nên chúng ăn theo
   màu chữ của nút — đổi trạng thái là đổi màu luôn, không phải nạp hai ảnh. */
.ic-moi{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/><circle cx='9' cy='7' r='4'/><path d='M19 8v6M22 11h-6'/></svg>")}
.ic-log{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M8 6h13M8 12h13M8 18h13'/><circle cx='3.5' cy='6' r='1.2'/><circle cx='3.5' cy='12' r='1.2'/><circle cx='3.5' cy='18' r='1.2'/></svg>")}
.ic-share{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 12v7a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-7'/><path d='M16 6l-4-4-4 4'/><path d='M12 2v13'/></svg>")}
.ic-link{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7l-1.7 1.7'/><path d='M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.7-1.7'/></svg>")}
.ic-hoa{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M5 9h14M5 15h14'/><path d='M9 4.5 7 19.5'/><path d='M17 4.5 15 19.5'/></svg>")}
.ic-co{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M5 21V4'/><path d='M5 5h11l-1.6 3.5L16 12H5z'/></svg>")}
.ic-full{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M8 3H5a2 2 0 0 0-2 2v3'/><path d='M16 3h3a2 2 0 0 1 2 2v3'/><path d='M8 21H5a2 2 0 0 1-2-2v-3'/><path d='M16 21h3a2 2 0 0 0 2-2v-3'/></svg>")}
.ic-hang{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 10a14 14 0 0 1 18 0v3l-4 1-1-3a10 10 0 0 0-8 0l-1 3-4-1z'/></svg>")}
.ic-chat{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 11.5a8.4 8.4 0 0 1-9 8.4 9 9 0 0 1-3.3-.6L3 21l1.9-4.6A8.4 8.4 0 0 1 12 3a8.4 8.4 0 0 1 9 8.5z'/></svg>")}
.ic-nhac{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 18V5l12-2v13'/><circle cx='6' cy='18' r='3'/><circle cx='18' cy='16' r='3'/></svg>")}
.ic-loa{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 9v6h4l5 4V5L8 9H4z'/><path d='M16.5 8.5a5 5 0 0 1 0 7'/><path d='M19.5 6a9 9 0 0 1 0 12'/></svg>")}
.ic-loatat{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 9v6h4l5 4V5L8 9H4z'/><path d='M17 9.5l4 5M21 9.5l-4 5'/></svg>")}
.ic-mic{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='9' y='2' width='6' height='11' rx='3'/><path d='M5 11a7 7 0 0 0 14 0'/><path d='M12 18v3'/><path d='M8 21h8'/></svg>")}
.ic-mictat{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='9' y='2' width='6' height='11' rx='3'/><path d='M5 11a7 7 0 0 0 14 0'/><path d='M12 18v3'/><path d='M8 21h8'/><path d='M3 3l18 18'/></svg>")}
.ic-lui{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 14 4 9l5-5'/><path d='M4 9h11a5 5 0 0 1 0 10h-4'/></svg>")}
.ic-chat{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 11.5a8.4 8.4 0 0 1-9 8.4 9 9 0 0 1-3.3-.6L3 21l1.9-4.6A8.4 8.4 0 0 1 12 3a8.4 8.4 0 0 1 9 8.5z'/></svg>")}
.ic-loa,#nutLoaNoi{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 9v6h4l5 4V5L8 9H4z'/><path d='M16.5 8.5a5 5 0 0 1 0 7'/><path d='M19.5 6a9 9 0 0 1 0 12'/></svg>")}
.ic-loa.tat,#nutLoaNoi.tat{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 9v6h4l5 4V5L8 9H4z'/><path d='M17 9.5l4 5M21 9.5l-4 5'/></svg>")}
#nutMicNoi{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='9' y='2' width='6' height='11' rx='3'/><path d='M5 11a7 7 0 0 0 14 0'/><path d='M12 18v3'/><path d='M8 21h8'/></svg>")}
#nutMicNoi.tat{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='9' y='2' width='6' height='11' rx='3'/><path d='M5 11a7 7 0 0 0 14 0'/><path d='M12 18v3'/><path d='M8 21h8'/><path d='M3 3l18 18'/></svg>")}
#nutQuayLai{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 14 4 9l5-5'/><path d='M4 9h11a5 5 0 0 1 0 10h-4'/></svg>")}
/* Nút xin đi lại ở cụm nổi mượn đúng mũi tên lùi của .ic-lui — cùng một
   việc thì cùng một hình, dù nằm ở hàng nút máy tính hay cụm nổi điện thoại. */
#nutDiLaiNoi{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 14 4 9l5-5'/><path d='M4 9h11a5 5 0 0 1 0 10h-4'/></svg>")}
#nutChatNoi{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 11.5a8.4 8.4 0 0 1-9 8.4 9 9 0 0 1-3.3-.6L3 21l1.9-4.6A8.4 8.4 0 0 1 12 3a8.4 8.4 0 0 1 9 8.5z'/></svg>")}

/* Thẻ trạng thái ẩn trên điện thoại khi hai thẻ kỳ thủ đã nói đủ. Máy tính vẫn
   bày: ở đó nó nằm trong cột phải, không tranh chỗ với bàn cờ. */
@media (max-width:860px){
  .deck-say.an-dt{display:none}
  .hang-duoi:has(.deck-say.an-dt){display:none}
}

.ic-cai{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='3'/><path d='M19.4 15a1.6 1.6 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.6 1.6 0 0 0-2.7 1.1V21a2 2 0 1 1-4 0v-.1A1.6 1.6 0 0 0 7.9 19.4l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1A1.6 1.6 0 0 0 3 14a2 2 0 1 1 0-4h.1A1.6 1.6 0 0 0 4.6 7.9l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1A1.6 1.6 0 0 0 10 3.6V3a2 2 0 1 1 4 0v.1a1.6 1.6 0 0 0 2.1 1.5l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.6 1.6 0 0 0 1.1 2.7H21a2 2 0 1 1 0 4h-.1a1.6 1.6 0 0 0-1.5 1z'/></svg>")}
.ic-moi2{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 12a9 9 0 1 1 3 6.7'/><path d='M3 20v-6h6'/></svg>")}

/* Thẻ chỉ hiện khi được gọi vào hộp nổi (điện thoại). */
.tam.an{display:none}

/* ═══════════ điện thoại: dọn mọi thứ khỏi quanh bàn cờ ═══════════ */
/*
  Khối này từng bị xoá nhầm cùng lúc thay phần "nút + toả tròn" — cắt theo mốc
  tiêu đề mà không để ý nó nằm gọn giữa hai mốc ấy. Hậu quả im lặng: hàng nút
  cũ hiện lại dưới bàn cờ, ô quảng cáo thứ hai quay về, ô nhập chat lộ ra chỗ
  không bấm trúng. Bộ thử bắt được, còn mắt thường thì rất dễ bỏ qua.
*/
@media (max-width:860px){
  /* Nút thao tác đã dời hết vào menu +, nút khoe thì thành mục "Chia sẻ" —
     mục ấy bấm hộ chính nút này nên phần tử vẫn phải nằm trong cây, chỉ ẩn đi.
     Cả thẻ bọc coi như không còn việc gì. */
  .hang-duoi .deck-acts{display:none}
  .hang-duoi .deck-say{width:100%}

  /* Ô nhập trong dòng chảy bị ẩn: đường vào chat là nút trò chuyện ở cụm nút
     nổi, bấm cái đó thì bóng chat hiện lên ngay trên bàn phím. */
  .the-chat > #sayForm{display:none}
  .the-chat:not(:has(#sayForm)){gap:0}

  /* Một ô quảng cáo là đủ trên điện thoại. Xếp hai ô chồng nhau dưới bàn cờ
     thì gần trăm pixel nữa phải vuốt, mà ô thứ hai gần như không ai cuộn tới.
     Máy tính vẫn giữ cả hai: cột phải thừa chỗ. */
  #adChat{display:none}

  /* Không còn thanh menu neo đáy nữa, nên không phải chừa chỗ cho nó. Chỉ chừa
     đủ để cụm nút nổi không đè lên phần cuối trang. */
  .wrap{padding-bottom:calc(env(safe-area-inset-bottom, 0px) + 16px)}
}

/* ═══════════ màn chèn giữa sau khi kết ván ═══════════ */
/* Nút ✕ ở góc, và các lối đi tiếp xếp thành hàng ngay dưới tấm quảng cáo —
   xem xong là chọn được ngay, không phải đóng rồi mới thấy nút thật. */
.adgate-card{position:relative}
.adgate-x{position:absolute; top:8px; right:8px; width:30px; height:30px;
  display:grid; place-items:center; border-radius:50%; cursor:pointer;
  font-size:13px; line-height:1; color:var(--ink);
  background:var(--surface-2); border:1px solid var(--edge); z-index:2}
.adgate-x:disabled{opacity:.35; cursor:default}
.adgate-nut{display:flex; flex-wrap:wrap; justify-content:center; gap:8px;
  margin-top:12px}
.adgate-nut .btn{flex:0 1 auto; min-height:38px; padding:8px 16px}
.adgate-dem{color:var(--muted); font-size:13px; padding:9px 0}
@media (max-width:560px){
  .adgate-nut{flex-direction:column; align-items:stretch}
  .adgate-nut .btn{width:100%}
}
/* Đổi tấm thì mờ đi rồi hiện lại, không nhảy phắt. */
.adslot{transition:opacity .16s linear}
.ic-roi{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4'/><path d='M16 17l5-5-5-5'/><path d='M21 12H9'/></svg>")}

/* ═══════════ màn báo trong ván ═══════════ */
/* Có người vào bàn, đối thủ rời đi, đối thủ xin đánh lại. Nổi gần bằng màn
   thắng/thua/hoà — cùng cách nổ ra, cùng nền mờ — nhưng NHỎ HƠN MỘT BẬC và tự
   tắt sau vài giây: đây là tin cần biết ngay, không phải kết cục cần dừng lại
   ngắm. Trước đây mấy việc này chỉ đổi lặng lẽ một dòng chữ nhỏ, mà người đang
   nhìn bàn cờ thì không thấy — nhất là lúc ngồi chờ, đúng lúc cần biết nhất. */
.baonoi{
  position:absolute; inset:0; z-index:30; display:grid; place-items:center;
  cursor:pointer; padding:16px;
  background:color-mix(in srgb, var(--board) 52%, transparent);
}
.baonoi[hidden]{display:none}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)){
  .baonoi{-webkit-backdrop-filter:blur(6px) saturate(140%);
          backdrop-filter:blur(6px) saturate(140%)}
}
.baonoi-card{
  max-width:86%; text-align:center; padding:16px 20px; border-radius:16px;
  background:color-mix(in srgb, var(--surface) 88%, transparent);
  border:1px solid var(--gold);
  box-shadow:0 18px 44px -16px var(--shadow-strong), 0 0 0 .4cqw color-mix(in srgb, var(--gold) 22%, transparent);
}
.baonoi-hinh img{max-width:min(38cqw, 180px); max-height:26cqw; display:block; margin:0 auto 10px}
.baonoi-hinh[hidden]{display:none}
.baonoi-chu{
  font-family:'Fraunces',serif; font-weight:700; letter-spacing:.01em;
  font-size:clamp(19px, 5.2cqw, 30px); line-height:1.15; color:var(--gold-vivid);
}
.baonoi-phu{margin-top:6px; font-size:13px; color:var(--muted); line-height:1.5}
/* Nổ ra: phóng từ nhỏ, vọt quá cỡ một chút rồi co về — cùng nhịp với màn kết
   ván nhưng biên độ nhẹ hơn, để hai thứ không tranh nhau sự chú ý. */
.baonoi.go .baonoi-card{animation:baoNo .42s cubic-bezier(.2,.9,.3,1.5) both}
@keyframes baoNo{
  0%  {transform:scale(.72); opacity:0}
  60% {transform:scale(1.04); opacity:1}
  100%{transform:scale(1);    opacity:1}
}
@media (prefers-reduced-motion: reduce){ .baonoi.go .baonoi-card{animation:none} }

/* ═══════════ ba dòng chat gần nhất (điện thoại) ═══════════ */
/* Khung chat đầy đủ nằm trong hộp nổi nên bình thường không thấy gì. Đang đánh
   thì liếc một cái biết đối thủ vừa nói gì là đủ — không cần mở hộp, mà cũng
   không đáng để cả một thẻ chiếm chỗ. Ba dòng, mới nhất lên đầu. */
.chat-xem{display:none}
@media (max-width:860px){
  .chat-xem{
    display:block; cursor:pointer; padding:8px 10px; border-radius:12px;
    background:var(--surface); border:1px solid var(--edge);
  }
  .chat-xem[hidden]{display:none}
  .chat-xem:focus-visible{outline:2px solid var(--gold); outline-offset:2px}
}
.cx-d{display:flex; align-items:center; gap:7px; min-height:22px;
  font-size:12.5px; line-height:1.45; color:var(--ink)}
.cx-d + .cx-d{margin-top:3px; padding-top:3px;
  border-top:1px solid color-mix(in srgb, var(--ink) 7%, transparent)}
.cx-d b{color:var(--gold-vivid); font-weight:600; flex:none;
  max-width:34%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
/* Đặt tên lớp cho ô chữ, KHÔNG dùng `.cx-d > span`: ảnh đại diện cũng là một
   thẻ span, cho nó flex:1 là nó bị kéo dài thành hình bầu dục. */
.cx-d .cx-chu{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.cx-d .kc-av{width:20px; height:20px; flex:none}
.cx-d .kc-av.ky-thu i{width:10px; height:10px; font-size:7px; right:-3px; bottom:-3px}
.cx-d.trong{color:var(--muted); font-style:italic; display:block}

/* ═══════════ bảng chia sẻ (chỉ máy tính) ═══════════ */
/* Điện thoại dùng khay của hệ điều hành — ở đó Messenger, Zalo, SMS đều có
   sẵn. Bảng này chỉ để đỡ cho máy tính, nơi `navigator.share` thường không
   có. Xem ghi chú trong ui.js về vì sao Zalo phải làm khác hai cái kia. */
.share-bang{position:fixed; inset:0; z-index:90; display:grid; place-items:center;
  padding:16px; background:rgba(0,0,0,.42)}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)){
  .share-bang{-webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px)}
}
.share-card{width:min(380px, 100%); border-radius:16px; overflow:hidden;
  background:var(--surface); border:1px solid var(--edge);
  box-shadow:0 22px 56px -18px var(--shadow-strong)}
.share-dau{display:flex; align-items:center; justify-content:space-between;
  padding:11px 14px; border-bottom:1px solid var(--edge)}
.share-dau b{color:var(--gold-vivid); font-size:14px}
.share-ds{display:flex; flex-direction:column; gap:4px; padding:8px}
.share-i{display:flex; align-items:center; gap:11px; width:100%; padding:11px 12px;
  border:0; border-radius:11px; cursor:pointer; text-align:left;
  font:inherit; font-size:14px; color:var(--ink); background:transparent}
.share-i:hover, .share-i:focus-visible{background:var(--surface-2); outline:none}
.share-ic{width:21px; height:21px; flex:none; background:currentColor;
  -webkit-mask:var(--ic) center/contain no-repeat; mask:var(--ic) center/contain no-repeat}
.share-link{width:calc(100% - 16px); margin:0 8px 10px; padding:7px 9px;
  border-radius:9px; font-size:12px; color:var(--muted);
  background:var(--surface-2); border:1px solid var(--edge)}
.ic-mess{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 3C6.9 3 3 6.8 3 11.4c0 2.6 1.2 4.9 3.2 6.4V21l3-1.6c.9.2 1.8.4 2.8.4 5.1 0 9-3.8 9-8.4S17.1 3 12 3z'/><path d='M7.5 13.4l2.7-2.9 2.3 1.8 2.3-2.4-2.5 4-2.3-1.8-2.5 1.3z'/></svg>")}
.ic-fb{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M14 9h3V6h-3a4 4 0 0 0-4 4v2H8v3h2v6h3v-6h2.5l.5-3H13v-2a1 1 0 0 1 1-1z'/><rect x='3' y='3' width='18' height='18' rx='4'/></svg>")}
.ic-zalo{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='4' width='18' height='14' rx='4'/><path d='M7 21l3-3'/><path d='M8 9h5l-5 4h5'/><path d='M16 9v4'/></svg>")}

/* ═══════════ trang xem lại một ván đã đánh ═══════════ */
/*
  Hàng điều khiển nằm ngay dưới bàn cờ, cùng chỗ với hàng nút trong phòng —
  ai đã quen chơi thì không phải học lại chỗ nào bấm.
*/
.xl-dieu{display:flex; flex-direction:column; gap:9px}
.xl-dieu .row{gap:6px}
.xl-nut{flex:0 0 auto; min-width:44px; font-size:15px; line-height:1}
/* Thanh kéo: kéo tới đâu thấy thế cờ tới đó, nên nó phải to bằng cả bàn cờ. */
.xl-thanh{width:100%; accent-color:var(--gold-vivid); cursor:pointer}
.xl-dong{display:flex; justify-content:space-between; align-items:baseline; gap:10px;
  font-size:12.5px; color:var(--ink)}
.xl-dong .hint{margin:0; white-space:nowrap}
/* Nước đang xem sáng lên trong biên bản, và bấm vào nước nào là nhảy tới đó —
   biên bản mà không bấm được thì chỉ là một cột chữ để đọc. */
#log [data-nuoc]{cursor:pointer; border-radius:5px; padding:0 3px}
#log [data-nuoc]:hover{background:color-mix(in srgb, var(--gold) 16%, transparent)}
#log [data-nuoc].dang{background:color-mix(in srgb, var(--gold-vivid) 26%, transparent);
  font-weight:600}
/* Bên thắng được đánh dấu ngay trên thanh tên, khỏi phải đọc dòng kết quả. */
.player.thang{border-color:var(--gold); box-shadow:0 0 0 1px var(--gold) inset}
.player.thang .nm{color:var(--gold-vivid)}

/* Kết quả từng ván trong hồ sơ: thắng thua hoà đọc bằng MÀU trước, bằng chữ
   sau — lướt một danh sách mười lăm ván thì mắt bắt màu nhanh hơn đọc chữ. */
.ket-thang{color:var(--jade); border-color:color-mix(in srgb, var(--jade) 45%, transparent)}
.ket-thua{color:var(--cinnabar); border-color:color-mix(in srgb, var(--cinnabar) 45%, transparent)}
.ket-hoa{color:var(--muted)}
.nguoi-row .hat.ket-thang, .nguoi-row .hat.ket-thua, .nguoi-row .hat.ket-hoa{
  min-width:46px; text-align:center; font-weight:600}

/* Khung hình dùng chung cho mọi nút "đang gọi". Phải nằm NGOÀI mọi @media:
   trước đây nó ở trong khung điện thoại, nên cùng một tên lớp mà trên máy tính
   thì đứng im — một lỗi im lặng, không báo gì cả. */
@keyframes goiMoi{0%,100%{box-shadow:0 0 0 0 transparent}
                  50%{box-shadow:0 0 0 2px color-mix(in srgb, var(--gold) 35%, transparent)}}

/* Nút mic nhấp nháy khi đối thủ đang chờ mình bật mic. Thoại là việc hai bên:
   một người bấm mà người kia không biết thì cuộc gọi không bao giờ thành. */
.deck-acts .btn.goi, .quat-tron.goi{
  border-color:var(--gold); color:var(--gold-vivid);
  animation:goiMoi 2.4s ease-in-out infinite}
@media (prefers-reduced-motion: reduce){
  .deck-acts .btn.goi, .quat-tron.goi{animation:none}
}

/* ═══════════ nút "?" và hộp giải thích ═══════════ */
/* Tròn, nhỏ, đứng ngay sau nhãn. Đủ to để bấm bằng ngón tay (24px) nhưng
   không tranh chỗ với chính cái nhãn nó đi kèm. */
.nut-hoi{
  display:inline-grid; place-items:center; vertical-align:middle;
  width:20px; height:20px; margin-left:6px; padding:0; flex:none;
  border-radius:50%; border:1px solid var(--edge); background:var(--surface-2);
  color:var(--muted); font:inherit; font-size:11.5px; font-weight:700;
  line-height:1; cursor:pointer}
.nut-hoi:hover{border-color:var(--gold); color:var(--gold-vivid)}
.nut-hoi:focus-visible{outline:2px solid var(--gold); outline-offset:1px}

.hop-hoi{position:fixed; inset:0; z-index:130; display:grid; place-items:center;
  padding:18px; background:color-mix(in srgb, var(--jet) 55%, transparent)}
.hop-hoi[hidden]{display:none}
.hop-hoi-card{width:min(380px,100%); display:flex; flex-direction:column; gap:10px;
  padding:18px; border-radius:16px; background:var(--surface);
  border:1px solid var(--edge); box-shadow:0 22px 60px -14px var(--shadow-strong)}
.hop-hoi-tieu{font-family:Fraunces,Georgia,serif; font-size:16px}
.hop-hoi-chu{font-size:13px; line-height:1.55; color:var(--muted)}
.hop-hoi-card .btn{width:100%}

/* Huy hiệu bàn VIP trong sảnh chờ. Vàng như bậc cấp độ, nhưng viền đặc để
   phân biệt với thẻ điểm bên cạnh — hai thẻ cùng màu cạnh nhau thì mắt gộp
   chúng thành một. */
.roomrow .tag.vip{color:var(--gold-vivid); border-color:var(--gold);
  background:color-mix(in srgb, var(--gold) 14%, transparent); font-weight:600}

/* ═══════════ hàng chọn trình độ tối thiểu ═══════════ */
/* Bày ĐỦ cả hàng bậc, kể cả bậc chưa đạt. Giấu bớt thì người mới không biết
   trên mình còn gì; thấy ổ khoá thì vừa hiểu vì sao chưa chọn được, vừa biết
   leo tới đâu thì mở ra. */
.vip-seg{flex-wrap:nowrap}
.vip-seg .vip-o{
  flex:1 1 0; min-width:0; position:relative;
  display:grid; place-items:center; padding:7px 2px;
  appearance:none; border:0; background:transparent; border-radius:7px;
  cursor:pointer; transition:.15s}
.vip-seg .vip-ic{font-size:19px; line-height:1.15; filter:saturate(1.05)}
.vip-seg .vip-o[aria-pressed="true"]{
  background:var(--surface); box-shadow:0 1px 3px var(--shadow);
  outline:1px solid var(--gold-soft)}
.vip-seg .vip-o:hover:not(.khoa){background:color-mix(in srgb, var(--gold) 10%, transparent)}
.vip-seg .vip-o:focus-visible{outline:2px solid var(--gold); outline-offset:1px}
/* Bậc chưa đạt: icon mờ đi và đeo một ổ khoá nhỏ ở góc. Mờ THÔI thì dễ tưởng
   là lỗi hiển thị — cái ổ khoá mới nói rõ đây là chưa mở, không phải hỏng. */
.vip-seg .vip-o.khoa{cursor:not-allowed}
.vip-seg .vip-o.khoa .vip-ic{opacity:.32; filter:grayscale(1)}
.vip-seg .vip-o.khoa::after{
  content:"🔒"; position:absolute; right:1px; bottom:2px;
  font-size:10px; line-height:1; opacity:.85}

/* ═══════════ phòng chơi ═══════════ */
/* Dòng phòng trong danh sách: dùng lại .nguoi-row cho khớp mọi danh sách khác
   trong trang, chỉ thêm biểu tượng mở/kín ở đầu. */
.phong-o{text-decoration:none; color:inherit}
.phong-o:hover{border-color:var(--gold-soft)}
.phong-ic{flex:none; font-size:18px; line-height:1}

/* Lưới của trang phòng: khung trò chuyện rộng, danh sách người hẹp bên phải.
   KHÔNG dùng lại .game/.board-col — mấy lớp ấy lấy bề ngang theo biến --bw
   của bàn cờ, mượn sang đây thì cột chat bị bó còn một nửa. */
.phong-luoi{display:grid; gap:12px; grid-template-columns:minmax(0,1fr); align-items:start}
@media (min-width:900px){
  .phong-luoi{grid-template-columns:minmax(0,1fr) minmax(260px,300px)}
}
.phong-luoi > .card{margin:0}
/* Khung tin trong phòng đọc XUÔI (mới nhất ở dưới) nên nó cần cao hẳn — đây
   là chỗ người ta ngồi đọc, khác khung chat trong bàn cờ vốn chỉ để liếc. */
.phong-luoi .khung-chat{min-height:220px}
.phong-ai .qlgiai{max-height:none}

/* Cột người trong phòng hẹp (300px) mà hàng lại có tên + cấp độ + hai nút, nên
   tên bị bóp thành "Bạn ...". Cho hàng xuống dòng và để TÊN chiếm trọn dòng
   đầu — tên là thứ người ta đọc để biết đang nói chuyện với ai, không phải
   thứ được cắt cụt trước tiên. */
.phong-ai .nguoi-row{flex-wrap:wrap; row-gap:6px}
.phong-ai .nguoi-row .nm{flex:1 1 auto; min-width:0; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap}
.phong-ai .nguoi-row .btn{flex:0 0 auto}

/* Băng-rôn có kèm dòng giải thích thì phải cho XUỐNG DÒNG. .banner là một hàng
   ngang (space-between), ba khối chỉ vừa khi cột rộng; dồn vào cột phải 300px
   là chúng chồng lên nhau — và dòng chữ nằm đè lên chính cái nút bên dưới nên
   bấm không trúng. Lỗi này im lặng: nút vẫn hiện, vẫn sáng, chỉ là bấm không
   ăn, mà nhìn thì không thấy gì sai. */
.banner{flex-wrap:wrap}
.banner > .hint{flex:1 1 100%; margin:0; font-size:12px}
.banner > .banner-nut{display:flex; gap:8px; flex-wrap:wrap}

/* ═══════════ bàn đang đánh, bày trong phòng ═══════════ */
/* Nhiều ván thì xếp lưới, mỗi ván một ô vuông. Bàn cờ đặt GIỮA ô như mọi chỗ
   khác trong trang — nó là thứ mắt nhìn trước tiên, lệch một bên là phải đi
   tìm. Hai thanh tên ôm trên dưới đúng như lúc ngồi đối diện: Đen trên, Đỏ
   dưới, khớp với bàn thật để không phải đảo đầu khi bấm vào xem. */
.phong-ban{display:flex; flex-wrap:wrap; gap:12px; justify-content:center}
.phong-van{flex:0 1 270px; display:flex; flex-direction:column; gap:7px; align-items:center;
  padding:11px; border-radius:12px; text-decoration:none; color:inherit;
  border:1px solid var(--edge); background:var(--surface-2)}
.phong-van:hover{border-color:var(--gold-soft)}
.phong-van-ban{width:100%; max-width:260px; margin:0 auto}
.phong-van-ai{display:flex; align-items:center; gap:7px; width:100%;
  font-size:12.5px; min-width:0}
.phong-van-ai .nm{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.phong-van-ai img{width:22px; height:22px; border-radius:50%; flex:none; object-fit:cover}
.phong-van-chan{display:flex; gap:6px; flex-wrap:wrap; justify-content:center}

/* Đường về phòng, hiện trên bàn sinh ra từ một phòng chơi. Xanh lục như viền
   quân đang chọn — cùng một họ màu cho những thứ "đang thuộc về bạn". */
.banner.phong-ve{border-color:color-mix(in srgb, var(--jade) 55%, var(--edge));
  background:color-mix(in srgb, var(--jade) 7%, var(--surface))}

/* Trang phòng mượn đúng khung của trang đang đánh (.game/.cot-trai/.cot-phai)
   để người đã quen bàn cờ thì vào phòng không phải học lại chỗ nào là chỗ nào.
   Chỉ cần chỉnh ba thứ cho hợp nội dung của phòng: */
/* 1. Cột trái ở đây là danh sách VÁN, không phải một bàn cờ — nó không cần bị
      kẹp đúng bề ngang bàn cờ, nhưng giữ trần ấy thì hai cột vẫn cân. */
.phong-ban{width:100%}
/* 2. Khung trò chuyện của phòng là chỗ NGỒI ĐỌC, khác khung liếc trong ván. */
.cot-phai .the-chat .khung-chat{height:min(46vh, 380px); min-height:200px}
/* 3. Danh sách người đứng dưới cùng, cho nó tự cao theo số người. */
.cot-phai .phong-ai .qlgiai{max-height:min(38vh, 320px); overflow-y:auto}

/* ═══════════ bàn cờ cỡ thật trong phòng ═══════════ */
/* Phòng bày MỘT bàn cỡ thật ở giữa, đúng bề ngang và đúng bộ khung của trang
   đánh cờ: thanh tên Đen trên, bàn cờ, thanh tên Đỏ dưới, hàng công cụ dưới
   cùng. Chưa có ván nào thì vẫn bày bàn với đủ quân ở thế ban đầu — một phòng
   cờ mà giữa nhà trống trơn thì chẳng ra phòng cờ. */
#pBan{display:flex; flex-direction:column; gap:10px; width:100%}
/* Bàn trong phòng là .board-shell y như bàn online — cùng vân gỗ, cùng lưới,
   cùng quân. Chỗ này chỉ thêm bóng đổ đậm hơn cho nó tách khỏi nền thẻ. */
.phong-ban-to{width:100%;
  box-shadow:0 1px 0 rgba(255,255,255,.16) inset,
             0 18px 40px -16px var(--shadow-strong),
             0 6px 14px -8px var(--shadow-strong)}
.phong-ban-to svg{display:block; width:100%; height:auto}
.phong-ban-chu{margin:0; text-align:center}
/* Hàng công cụ mượn đúng dáng của hàng nút dưới bàn cờ thật: nút vuông có
   tên bên dưới, chia đều bề ngang, một hàng không quấn. */
.phong-cu{display:flex; flex-wrap:nowrap; gap:6px; align-items:stretch}
.phong-cu .btn.icon{flex:1 1 0; width:auto; min-width:0; max-width:none;
  height:auto; min-height:56px; padding:8px 4px 7px; row-gap:5px;
  line-height:1; text-decoration:none}
.phong-cu .btn.icon::after{content:attr(data-ten); font-size:10.5px; line-height:1.15;
  font-weight:500; display:block; max-width:100%; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis}

/* Cột trái của PHÒNG phải có bề ngang CỐ ĐỊNH, không co theo nội dung.
   Lưới hai cột của trang đánh cờ để cột đầu là `auto`, tức là co theo thứ nằm
   trong nó. Ở bàn cờ thật thì không sao vì trong đó chỉ có đúng một bàn cờ đã
   biết cỡ. Còn ở phòng thì nội dung đổi liên tục — lúc chưa có ván thì dòng
   chữ gợi ý làm cột phình ra, có ván rồi thì cột teo lại — và bàn cờ nhảy cỡ
   mỗi lần trạng thái đổi, nhìn như trang bị giật. */
@media (min-width:1100px){
  .cot-trai:has(#pBan){width:min(660px, max(420px, (100svh - 360px) * .905))}
}

/* Lời mời trong phòng — NEO CỨNG vào đáy màn.
   Trước đây băng-rôn nằm trong dòng chảy, trên đầu cột trái. Trên máy tính thì
   vừa mắt, nhưng trang phòng trên điện thoại dài gấp mấy lần màn hình: người ta
   cuộn xuống xem trò chuyện là băng-rôn trôi ra ngoài, mời xong bên kia không
   thấy gì và tưởng lời mời không tới nơi. Đo được lúc thử: top = -509px.
   Neo cứng thì cuộn kiểu gì nó cũng còn đó, và nằm dưới thì vừa tầm ngón cái. */
#pMoi.moi-noi{
  position:fixed; z-index:70; left:50%; transform:translateX(-50%);
  bottom:calc(12px + env(safe-area-inset-bottom));
  width:min(560px, calc(100vw - 20px));
  display:flex; flex-direction:column; gap:8px}
#pMoi.moi-noi .banner{
  background:color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter:blur(14px) saturate(1.5);
  -webkit-backdrop-filter:blur(14px) saturate(1.5);
  box-shadow:0 12px 32px -10px rgba(0,0,0,.5)}
#pMoi.moi-noi .banner.moi-den{
  border-color:var(--gold-vivid); animation:moiNhap 2.2s ease-in-out infinite}
@keyframes moiNhap{
  0%,100%{box-shadow:0 12px 32px -10px rgba(0,0,0,.5), 0 0 0 0 transparent}
  50%{box-shadow:0 12px 32px -10px rgba(0,0,0,.5),
      0 0 0 3px color-mix(in srgb, var(--gold-vivid) 45%, transparent)}}
@media (prefers-reduced-motion: reduce){
  #pMoi.moi-noi .banner.moi-den{animation:none}
}

/* ═══════════════ trang danh sách phòng ═══════════════
   Hai bố cục thật sự khác nhau, không phải một bố cục co lại. Trên máy tính
   thẻ mở phòng đứng sẵn ở cột trái — màn rộng thì cứ bày ra, không bắt bấm
   thêm một nút. Trên điện thoại thẻ đó biến mất hẳn và đổi thành một nút ở
   góc trên bên phải: nhét cả khối nhập liệu lên đầu thì đẩy danh sách — thứ
   người ta mở trang ra để xem — xuống dưới đáy màn hình. */
.phong-trang{display:grid; gap:14px}
.phong-cot-ds{display:grid; gap:14px; align-content:start; min-width:0}
@media (min-width:1100px){
  .phong-trang{grid-template-columns:320px minmax(0,1fr); align-items:start}
  .phong-cot-tao{position:sticky; top:14px}
  .phong-tao-dt{display:none}      /* thẻ đã đứng sẵn bên trái rồi */
}
@media (max-width:1099px){
  .phong-cot-tao{display:none}
}
.card-dau{display:flex; align-items:center; justify-content:space-between;
  gap:10px; margin-bottom:6px}
.card-dau .btn{flex:none}

/* Dòng phòng: phần bấm-để-vào là cái <a> bên trong, còn bánh răng đứng ngoài
   nó. Để nút nằm trong <a> thì vừa sai HTML vừa khiến bấm cài đặt lại nhảy
   luôn vào phòng. */
.phong-lk{display:flex; align-items:center; gap:9px; flex:1; min-width:0;
  text-decoration:none; color:inherit}
.phong-cai{width:32px; height:32px; min-height:32px; padding:0}
.phong-cai::before{width:16px; height:16px}

/* Khối nguy hiểm dưới đáy hộp cài đặt. Tách hẳn bằng một đường kẻ để nút xoá
   không bao giờ nằm ngang hàng với nút Lưu — hai việc này lệch nhau quá xa. */
.hop-nguy{margin-top:4px; padding-top:12px; border-top:1px solid var(--edge);
  display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap}
.hop-nguy .btn{flex:none}
/* Thẻ xoá tài khoản: viền ngả sang màu cảnh báo để mắt biết đây không phải
   một ô cài đặt bình thường. Không tô đỏ rực — nó vẫn là việc người dùng có
   quyền làm, không phải một cái bẫy. */
.hs-xoa{border-color:color-mix(in srgb, var(--cinnabar) 34%, var(--edge))}
.hs-xoa h2{color:var(--cinnabar)}
.btn.nguy{border-color:color-mix(in srgb, var(--cinnabar) 55%, var(--edge));
  color:var(--cinnabar)}
.btn.nguy:hover{border-color:var(--cinnabar);
  background:color-mix(in srgb, var(--cinnabar) 10%, transparent)}

/* Trên màn hẹp, tên phòng được đứng riêng một dòng. Để chung một hàng với ba
   cái nhãn thì tên — thứ duy nhất phân biệt phòng này với phòng kia — bị cắt
   thành "Phòng mở …", còn mã phòng sáu ký tự thì hiện đủ. Sai thứ tự ưu tiên. */
@media (max-width:600px){
  .phong-o{flex-wrap:wrap; row-gap:4px}
  .phong-o .phong-lk{flex:1 1 100%}
  .phong-o .hat{margin-left:0}
  .phong-o .phong-cai{margin-left:auto}
}

/* Ảnh đại diện giải trong danh sách ở sảnh. Nhỏ hơn ô ảnh ở trang giải đấu vì
   đây là một HÀNG trong danh sách, không phải một thẻ đứng riêng — để 84px
   như bên kia thì bốn cái giải chiếm hết màn hình đầu, đẩy danh sách bàn cờ
   xuống dưới, mà người ta vào sảnh là để tìm bàn. */
.roomrow .giai-av{width:36px; height:36px; flex:none; border-radius:9px;
  object-fit:cover; overflow:hidden; background:var(--surface-2)}
.roomrow .giai-av.trong{display:block; padding:0}


/* ═══════════ hàng thành viên trong phòng ═══════════
   Tên và nhãn ở dòng trên, nút ở dòng dưới và dồn hết về phải. Xếp chung một
   dòng thì ba cái nút bóp tên còn vài chữ, mà ở cột hẹp chúng lại tự quấn
   dòng mỗi hàng một kiểu — mỗi người một dáng, nhìn như danh sách bị vỡ.
   Nút chỉ còn icon vì cả ba việc đều có hình rõ nghĩa, và ba cái chữ xếp
   cạnh nhau thì chiếm gần trọn bề ngang cột. */
.phong-nguoi{flex-wrap:nowrap}
/* Tên trên, bậc dưới. Khối này ăn hết bề ngang còn lại nên tên được trọn chỗ,
   còn nút thì đứng cùng hàng với ảnh và tên chứ không tụt xuống dòng riêng. */
.phong-nguoi .nguoi-ten{flex:1 1 auto; min-width:0; display:block; line-height:1.25}
.phong-nguoi .nguoi-ten b{
  display:block; font-size:13.5px; font-weight:600;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.phong-nguoi .nguoi-ten small{
  display:flex; align-items:center; gap:6px; margin-top:2px;
  overflow:hidden; white-space:nowrap}
.phong-nguoi .nguoi-ten small:empty{display:none}
.phong-nguoi .nguoi-cu{display:flex; align-items:center; gap:6px; flex:none}
.phong-nguoi .nguoi-cu .btn.icon{
  width:32px; height:32px; min-height:32px; padding:0; flex:none}
.phong-nguoi .nguoi-cu .btn.icon::before{width:16px; height:16px}
/* Mic đang tắt: nút đổi màu cảnh báo, để nhìn hàng là biết ai đang bị tắt mà
   không phải đọc nhãn. */
.phong-nguoi .nguoi-cu .btn.icon.tat{
  color:var(--cinnabar);
  border-color:color-mix(in srgb, var(--cinnabar) 45%, var(--edge))}

/* Icon "thành viên": hai người. Bộ icon chưa có hình nào mang nghĩa NHÓM —
   ic-moi là một người kèm dấu cộng (rủ thêm ai đó), khác nghĩa hẳn. */
.ic-ai{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/><circle cx='9' cy='7' r='4'/><path d='M22 21v-2a4 4 0 0 0-3-3.87'/><path d='M16 3.13a4 4 0 0 1 0 7.75'/></svg>")}

/* ═══════════ thanh tên phòng, đứng trên cùng cột trái ═══════════
   Một hàng thấp: biểu tượng, tên (kèm dòng phụ nhỏ), rồi mấy nút icon dồn
   phải. Trước đây chỗ này là cả một thẻ có tiêu đề lớn, ô link, dòng nhắc và
   bốn nút chữ — chiếm gần một màn hình điện thoại cho những việc mỗi phiên
   chỉ làm một lần. */
.phong-dau{display:flex; align-items:center; gap:10px; padding:9px 12px}
.phong-dau-ic{font-size:18px; flex:none; line-height:1}
.phong-dau-ten{
  flex:1; min-width:0; font-weight:600; font-size:14.5px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.phong-dau-ten small{
  display:block; font-weight:400; font-size:11.5px; color:var(--muted);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.phong-dau-cu{display:flex; align-items:center; gap:6px; flex:none}
.phong-dau-cu .btn.icon{width:32px; height:32px; min-height:32px; padding:0}
.phong-dau-cu .btn.icon::before{width:16px; height:16px}
.phong-dau-cu .btn.primary{padding:6px 12px; font-size:12.5px; min-height:32px; width:auto}

/* Thẻ được mượn vào hộp nổi. Bỏ viền và nền của chính nó đi vì hộp đã có sẵn
   cả hai — để nguyên thì thành thẻ lồng trong thẻ, viền chồng viền. */
.hop-tam{margin:0 0 4px}
.hop-tam > .card{border:0; background:transparent; padding:0; box-shadow:none}
.hop-tam .khung-chat{max-height:min(50vh, 380px)}

/* #pBan chỉ là cái hộp để JavaScript đổ nội dung vào, không phải một tầng bố
   cục. Để nó là thẻ thật thì .ghim bên trong có cha vừa khít chính nó — mà
   position:sticky cần cha CAO HƠN mình mới có chỗ trượt, nên bàn cờ không hề
   dính lại khi cuộn. display:contents bỏ tầng thừa ấy đi: mấy thẻ bên trong
   thành con trực tiếp của .cot-trai, ghim bám vào cột và ăn luôn nhịp giãn
   chung của cột. */
#pBan{display:contents}

@media (max-width:860px){
  /* Trên điện thoại, trò chuyện và thành viên đã có icon dưới bàn cờ mở ra
     hộp nổi — nên không bày thêm hai thẻ dài bên dưới nữa. Trang gọn lại còn
     đúng bàn cờ với hàng công cụ, và bàn cờ thôi bị đẩy trôi mất khi cuộn:
     trước đây cột trái hết ở đâu là ghim rời ở đấy, mà hai thẻ kia lại nằm
     ngoài cột trái nên vừa cuộn tới chúng là bàn cờ biến mất. */
  .game-phong > .cot-phai{display:none}
}

@media (max-width:860px){
  /* Hàng công cụ dưới bàn cờ nhường chỗ cho cụm nút NỔI dán đáy màn: trên
     điện thoại bàn cờ chiếm gần trọn màn hình nên hàng ấy tụt xuống dưới nếp
     gấp, muốn mời ai một ván là phải cuộn đi tìm. */
  .game-phong .phong-cu{display:none}
}

/* Icon "gửi": máy bay giấy. Bộ icon chưa có hình nào mang nghĩa GỬI ĐI. */
.ic-gui{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M22 2 11 13'/><path d='M22 2 15 22l-4-9-9-4 20-7z'/></svg>")}

/* ═══════════ khung trò chuyện trong phòng ═══════════
   Ô nhập ăn hết bề ngang, nút gửi thu về đúng một icon vuông. Luật chung ở
   khổ hẹp bắt .chat-form xếp DỌC và cho nút rộng 100% — hợp với mấy thẻ có
   một nút to, nhưng ở khung chat thì nó đẩy ô nhập lên và chiếm mất một tầng
   chiều cao chỉ để hiện chữ "Gửi". */
/* Hàng soạn tin trong phòng chật hơn hẳn khung bàn luận: nó còn thêm nút "+"
   và nằm trong cột phải hẹp. Nên nó lấy chiều cao riêng — 38px thay vì 42 —
   nhưng vẫn là MỘT con số cho cả ba thứ, để ô nhập, nút gửi và nút + bằng
   nhau. Trước đây ba cái cao 42/40/36, lệch nhau ngay trong một hàng. */
#pGui{flex-direction:row; align-items:center; gap:8px; margin-top:2px; --cf-cao:38px}
#pGui .text{flex:1 1 auto; min-width:0}
/* Cùng lấy --cf-cao như luật chung của .chat-form. Đặt cứng 40px thì hàng có
   ba chiều cao khác nhau — ô nhập 42, nút gửi 40, nút + 36 — mà luật chung thì
   không với tới được vì mấy luật này có ID nên thắng. */
#pGui .btn.icon{
  width:var(--cf-cao, 40px); height:var(--cf-cao, 40px); min-height:var(--cf-cao, 40px);
  padding:0; flex:none; border-radius:10px}
#pGui .btn.icon::before{width:18px; height:18px}

/* Hộp mượn thẻ dựng theo dáng hộp trò chuyện của trang đánh online: thanh
   tiêu đề mảnh có ✕, thân hộp cao tối đa nửa màn và tự cuộn bên trong. */
.hop-hoi-card:has(.bong-dau){padding:0; gap:0; width:min(440px,100%); overflow:hidden}
.hop-hoi-card > .bong-dau{padding:10px 12px; border-bottom:1px solid var(--edge)}
.hop-hoi-card > .bong-than{padding:12px; gap:10px}
.hop-hoi-card .bong-x{width:30px; height:30px; flex:none}
.hop-hoi-card:has(.bong-dau) .btn{width:auto}
.hop-tam .khung-chat{height:auto; max-height:min(52vh, 400px); flex:1 1 auto}

/* Huy hiệu bậc dán góc trên tấm ảnh. Rời khỏi dòng chữ để nhìn lướt cả danh
   sách là thấy ngay ai cỡ nào — chữ thì phải đọc từng dòng một. */
.nguoi-av{position:relative; flex:none; display:block; line-height:0}
.nguoi-bac{
  position:absolute; top:-4px; right:-5px;
  font-size:11px; line-height:1; font-style:normal;
  padding:1px 2px; border-radius:6px;
  background:var(--surface); border:1px solid var(--edge);
  box-shadow:0 1px 3px var(--shadow); pointer-events:none}

/* Bảng biểu cảm: NẤP đi, bung ra từ nút + đầu ô nhập, nổi LÊN TRÊN ô nhập.
   Bày sẵn cả bốn chục cái thì chúng ăn đứt một tầng ngay trên ô nhập — chỗ ấy
   đáng để thêm hai dòng tin nhắn hơn. Nổi lên chứ không chen vào dòng chảy:
   chen vào thì mỗi lần mở là ô nhập nhảy xuống, mà ngón tay đang đặt sẵn ở đó. */
.chat-cx{
  position:absolute; left:0; right:0; bottom:100%; z-index:30;
  margin-bottom:6px; padding:8px; border-radius:12px;
  background:var(--surface); border:1px solid var(--edge);
  box-shadow:0 14px 34px -12px var(--shadow-strong);
  display:grid; grid-template-columns:repeat(8, 1fr); gap:4px;
  max-height:min(46vh, 220px); overflow-y:auto; overscroll-behavior:contain;
  scrollbar-width:none}
.chat-cx::-webkit-scrollbar{display:none}
.chat-cx[hidden]{display:none}
@media (max-width:520px){
  .chat-cx{grid-template-columns:repeat(6, 1fr)}
}
.chat-cx button:active{transform:scale(.9)}
.chat-cx button:focus-visible{outline:2px solid var(--gold); outline-offset:1px}

/* Ô tìm phòng phải rời hẳn khỏi danh sách bên dưới: dính sát thì trông như ô
   tìm kiếm là một dòng trong danh sách chứ không phải công cụ lọc nó. */
#pChung{margin-top:14px}

/* Chỗ soạn tin (hàng biểu cảm + ô nhập) tách hẳn khỏi dòng tin cuối bằng một
   đường kẻ mảnh và khoảng thở phía trên. Trước đây ô nhập dính ngay dưới dòng
   tin cuối nên nhìn như dòng ấy nằm trong ô nhập — mắt phải dò một lúc mới ra
   đâu là tin cũ, đâu là chỗ mình đang gõ. */
.chat-soan{
  position:relative;                 /* mốc neo cho bảng biểu cảm nổi lên trên */
  display:flex; flex-direction:column; gap:8px;
  margin-top:6px; padding-top:12px;
  border-top:1px solid var(--edge)}
.chat-soan .chat-cx{margin-top:0}
.chat-soan #pGui{margin-top:0}

/* Chat trong phòng: tên trên, GIỜ nhỏ ngay dưới tên — không đứng riêng một cột
   bên phải nữa. Cột giờ ăn mất chỗ theo chiều ngang ở đúng khung hẹp nhất, nên
   tên bị cắt thành "Nguyễn Đì…" trong khi ô giờ thì hiện đủ mười ký tự.
   Chỉ đổi ở phòng: bàn cờ và trang xem lại vẫn dựng dòng chat theo dáng cũ, và
   ở đó khung rộng hơn nên một hàng vẫn vừa. */
/* Khối chữ của một dòng chat: tên+giờ THẢ TRÁI, nội dung chảy quanh nó.
   Thả trái chứ không phải một cột riêng, vì đó là cách duy nhất cho ra đúng
   dáng người ta muốn:
       [ảnh]  Tên:      nội dung bắt đầu ngay sau tên
              5 phút    và khi dài quá thì chảy tiếp
       xuống đây, ngang đầu dòng với tên, chạy hết bề ngang.
   Nếu để ba thẻ nằm ngang trong một hàng flex thì nội dung dài bị bóp vào một
   cột hẹp bên phải, mỗi dòng vài chữ, đọc như đọc thơ. */
.kc-d .kc-than{flex:1; min-width:0; display:block}
.kc-d .kc-than::after{content:""; display:block; clear:both}
.kc-d .kc-ai{
  float:left; margin:1px 6px 0 0; max-width:42%;
  display:flex; flex-direction:column}
.kc-d .kc-ai b{
  font-weight:600; color:var(--ink); font-size:12.5px; line-height:1.3;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.kc-d .kc-ai time{
  font-size:9px; line-height:1.25; color:var(--faint); opacity:.85;
  font-variant-numeric:tabular-nums; white-space:nowrap}
/* Nội dung là chữ CHẢY, không phải một ô flex: có chảy được thì nó mới quấn
   xuống dưới khối tên khi dài. word-break để một chuỗi dài không ngắt được
   (đường link, dãy ký tự dán vào) không đẩy toác cả khung. */
.kc-d .kc-than .kc-chu{
  display:inline; flex:none; min-width:0;
  overflow-wrap:anywhere; word-break:break-word}

/* Nút mic đang ghi: đỏ và nhấp nháy, cho người ta biết máy đang nghe mình.
   Dùng chung nhịp với nút mic ở bàn cờ — cùng một việc thì phải cùng một dáng. */
.phong-cu .btn.icon.ghi, .quat-tron.ghi{
  color:#fff; background:var(--cinnabar); border-color:var(--cinnabar);
  animation:goiMoi 2.4s ease-in-out infinite}
@media (prefers-reduced-motion: reduce){
  .phong-cu .btn.icon.ghi, .quat-tron.ghi{animation:none}
}

/* Ẩn thanh cuộn của khung chat nhưng VẪN cuộn được — bánh xe, vuốt tay, phím
   mũi tên đều nguyên vẹn. Vệt trắng dựng đứng cạnh mấy dòng tin nhìn như một
   đường kẻ thừa, mà nó chỉ nói lại đúng điều người ta đã biết: còn tin ở trên.
   Đặt cho .khung-chat nói chung chứ không riêng phòng: cùng một khung, cùng
   một vệt trắng, sửa một nơi thì bàn cờ với trang xem lại cũng gọn theo. */
.khung-chat{scrollbar-width:none; -ms-overflow-style:none}
.khung-chat::-webkit-scrollbar{width:0; height:0; display:none}


/* Nút + đầu ô nhập. Xoay 45° khi bảng đang mở, thành dấu × — cùng một nút mở
   và đóng, khỏi phải đi tìm chỗ khác để tắt. */
.ic-cong{--ic:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'><path d='M12 5v14M5 12h14'/></svg>")}
#pGui .btn.icon#pCong{
  width:var(--cf-cao, 36px); height:var(--cf-cao, 36px); min-height:var(--cf-cao, 36px);
  padding:0; transition:transform .18s, color .18s}
#pGui .btn.icon#pCong::before{width:17px; height:17px}
#pGui .btn.icon#pCong.mo{transform:rotate(45deg); color:var(--gold-vivid)}
.chat-cx button{
  flex:none; width:100%; aspect-ratio:1; padding:0; font-size:17px; line-height:1;
  border-radius:8px; cursor:pointer;
  background:transparent; border:1px solid transparent}
.chat-cx button:hover{background:var(--surface-2); border-color:var(--edge)}

/* Ô chứa thanh điều hướng chỉ là chỗ để JavaScript đổ nội dung vào, không phải
   một tầng bố cục: display:contents cho mấy cái nút thành con trực tiếp của
   .head-tools, giữ nguyên khe giãn như lúc viết tay trong HTML. */
#navSlot{display:contents}
/* Trang đang mở: đánh dấu chứ KHÔNG gỡ khỏi thanh. Gỡ đi thì mấy nút còn lại
   xê dịch mỗi lần đổi trang — đúng thứ phá trí nhớ tay của người dùng. */
.head-tools .btn.nav.dang{
  border-color:var(--gold); color:var(--gold-vivid);
  background:color-mix(in srgb, var(--gold-vivid) 10%, var(--surface))}

/* ═══════════ khối "Tuỳ chọn khác" ở trang sảnh ═══════════
   Bốn mục ít ai đổi gói lại đây. Trước đây cả năm mục bày ra hết, và trên
   điện thoại thì trọn màn hình đầu là một cái form — người lạ vào lần đầu
   không hề thấy "Sảnh chờ", tức không biết trang này có ai đang chờ đối. */
.tuychon{margin-top:12px; border-top:1px solid var(--edge); padding-top:6px}
.tuychon > summary{
  cursor:pointer; list-style:none; user-select:none;
  display:flex; align-items:center; gap:8px;
  padding:8px 4px; border-radius:8px;
  font-size:12.5px; color:var(--muted)}
.tuychon > summary::-webkit-details-marker{display:none}
.tuychon > summary::before{
  content:"›"; display:inline-block; font-size:15px; line-height:1;
  transition:transform .16s}
.tuychon[open] > summary::before{transform:rotate(90deg)}
.tuychon > summary:hover{background:var(--surface-2); color:var(--ink)}
.tuychon > summary:focus-visible{outline:2px solid var(--gold); outline-offset:1px}
/* Tóm tắt những mục đã đổi khỏi mặc định. Không có dòng này thì gấp khối lại
   là người ta quên mất mình vừa đặt bàn ở chế độ riêng tư. */
.tuychon > summary small{margin-left:auto; color:var(--gold-vivid); font-size:11.5px}
.tuychon > summary small:empty{display:none}

/* Ô chọn trình độ: nới cho đủ tầm ngón tay. Ở khổ 390px tám ô này từng chỉ
   cao 33px và rộng chưa tới 30px — bấm là trúng ô bên cạnh. */
.vip-seg .vip-o{min-height:40px; padding:8px 2px}
@media (max-width:420px){
  .vip-seg{gap:1px}
  .vip-seg .vip-o{padding:8px 0}
  .vip-seg .vip-ic{font-size:17px}
}

/* Trên điện thoại: SẢNH CHỜ lên trước ô "vào bằng mã phòng". Thấy ai đang chờ
   đối thì hữu ích hơn hẳn việc gõ tay một cái mã mà mình chưa chắc đã có. */
@media (max-width:860px){
  /* `align-items:start` ở luật gốc là để thẻ bám mép TRÊN của ô lưới trên máy
     tính. Xuống một cột thì nó đổi nghĩa hẳn: trục ngang thành trục phụ, nên
     "start" nghĩa là KHÔNG kéo giãn — thẻ nào nội dung hẹp thì co lại đúng bề
     ngang chữ. Đo được "Vào bằng mã phòng" 236px trong khi mấy thẻ kia 366px.
     Xuống một cột thì mọi thẻ phải rộng bằng nhau. */
  .lobby{display:flex; flex-direction:column; align-items:stretch}
  .lobby > .stack:first-child{order:1; display:contents}
  .lobby > .stack:last-child{order:2; display:contents}
  .lobby .card.the-tao{order:1}
  .lobby .stack:last-child > *{order:2}
  .lobby .card.the-ma{order:3}
}

/* Nút "?" chỉ 20×20 — nhỏ hơn mọi khuyến nghị về tầm ngón tay. Nới VÙNG BẤM
   ra 34×34 bằng một lớp trong suốt, giữ nguyên cái chấm nhìn thấy: phóng to
   hình thì bốn cái dấu hỏi tranh mất chỗ của chính cái nhãn chúng đi kèm. */
.nut-hoi{position:relative}
.nut-hoi::after{content:""; position:absolute; inset:-7px; border-radius:50%}

/* ═══════════ khung xem trước ảnh vừa chọn ═══════════
   Lớp .bia trước đây KHÔNG có luật nào cả: thẻ <img> bên trong giữ nguyên cỡ
   thật, nên chọn một tấm 3000px là nó tràn khỏi thẻ, đè lên cả cột bên cạnh.
   Ba nơi cùng dùng lớp này — khai giải, đăng quảng cáo, và trang superadmin. */
.bia{
  width:100%; max-height:220px; overflow:hidden;
  display:grid; place-items:center;
  border-radius:11px; background:var(--surface-2); border:1px solid var(--edge)}
.bia img{max-width:100%; max-height:220px; object-fit:contain; display:block}
.bia .none{font-size:12px; color:var(--muted); text-align:center; padding:22px 12px}
/* Ảnh bìa giải được cắt sẵn thành dải 3:1 lúc nén, nên khung xem trước cũng
   phải đúng tỉ lệ ấy — thấy trước đúng phần sẽ được giữ, không phải đoán. */
.bia-giai{aspect-ratio:3/1; max-height:none}
.bia-giai img{width:100%; height:100%; max-height:none; object-fit:cover}

/* ═══════════ nút xin đánh thay ═══════════
   Mỗi nút mang màu và chữ của chính quân bên ấy — nhìn là biết mình sắp ngồi
   vào ghế nào, khỏi phải đọc hết dòng chữ. */
.thay-nut{display:inline-flex; align-items:center; gap:7px; font-weight:600}
.thay-nut i{
  font-style:normal; font-family:"Noto Serif TC","Songti SC",serif;
  font-size:15px; line-height:1; width:22px; height:22px; flex:none;
  display:grid; place-items:center; border-radius:50%;
  background:var(--disc); box-shadow:0 0 0 1px var(--disc-edge)}
.thay-nut.do{border-color:color-mix(in srgb, var(--piece-red) 45%, var(--edge))}
.thay-nut.do i{color:var(--piece-red)}
.thay-nut.do:hover{border-color:var(--piece-red)}
.thay-nut.den{border-color:color-mix(in srgb, var(--piece-black) 45%, var(--edge))}
.thay-nut.den i{color:var(--piece-black)}
.thay-nut.den:hover{border-color:var(--piece-black)}
/* Đã xin rồi thì nút chuyển sang "rút lời" — làm nhạt đi để không tranh mắt
   với nút của bên còn lại, thứ người ta còn có thể muốn bấm. */
.thay-nut.rut{color:var(--muted)}

@media (max-width:860px){
  /* Trên điện thoại hai việc này nằm trong menu dấu + ở cụm nút nổi, nên khối
     ở đây chỉ còn là lời giải thích — bày thêm hai nút nữa là bày hai lần. */
  .thay-xin .banner-nut{display:none}
}

/* Chấm xanh: ai đang MỞ phòng lúc này. Khác hẳn "đã vào phòng" — thứ nằm
   trong cơ sở dữ liệu và còn nguyên kể cả khi người ta đóng trình duyệt từ
   hôm kia. Nhìn danh sách là biết rủ ai thì có người trả lời. */
.nguoi-av.online::after{
  content:""; position:absolute; right:-1px; bottom:-1px;
  width:9px; height:9px; border-radius:50%;
  background:#3E9E63; box-shadow:0 0 0 2px var(--surface)}

/* ═══════════ thanh xem lại ═══════════
   Hàng nút phải nằm NGANG ở mọi khổ. Luật chung ở màn hẹp bắt .row xếp dọc và
   cho nút cao 44px — hợp với mấy thẻ có một hai nút to, nhưng ở đây thành sáu
   nút xếp chồng chiếm nửa màn hình, mà cái cần nhất là bàn cờ. */
/* stretch chứ không center: nút "Phát" có chữ nên cao hơn mấy nút mũi tên,
   canh giữa thì chúng so le nhau vài pixel — nhìn ra ngay là một hàng lệch. */
.xl-dieu .row{flex-direction:row; flex-wrap:nowrap; align-items:stretch}
.xl-dieu .row > .btn{flex:1 1 0; min-width:0; padding-left:4px; padding-right:4px}
.xl-nut{flex:0 0 auto}

@media (max-width:860px){
  /* Trên điện thoại thanh xem lại DÁN ĐÁY MÀN, đúng chỗ cụm nút nổi của trang
     đang đánh. Ngón cái đặt sẵn ở đó, và bàn cờ được trọn phần trên. */
  .xl-dieu{
    position:fixed; left:0; right:0; bottom:0; z-index:70;
    margin:0; border-radius:14px 14px 0 0;
    padding:8px 10px calc(8px + env(safe-area-inset-bottom));
    box-shadow:0 -10px 30px -14px var(--shadow-strong)}
  .xl-dieu .row{gap:4px}
  .xl-dieu .row > .btn{min-height:38px; font-size:13px}
  .xl-dieu .xl-thanh{margin:0}
  /* Dòng chữ "N nước · thắng vì…" bỏ đi ở khổ hẹp: nó đã có trên đầu trang,
     mà ở đây thì ăn thêm một tầng của thanh dán đáy. */
  .xl-dieu .xl-dong .hint{display:none}
  /* Chừa chỗ cho thanh ấy, không thì nó đè lên phần cuối trang. */
  .wrap:has(.xl-dieu){padding-bottom:118px}
}

/* ═══════════ cờ thế ═══════════
   Lưới hai cột: mỗi ô là một bàn cờ nhỏ kèm tên. Bàn cờ nhỏ mới là thứ người
   ta nhìn để chọn — tên thế cờ thì phần lớn không nói lên hình dạng gì. */
/* Các bước làm tuần tự trong trang quản trị: số thứ tự đậm, dòng thưa ra cho
   dễ dò tới đúng bước đang làm. */
.hd-buoc{margin:8px 0 12px; padding-left:22px; font-size:13px; line-height:1.6; color:var(--muted)}
.hd-buoc li{margin-bottom:7px}
.hd-buoc li::marker{color:var(--gold); font-weight:700}
.hd-buoc b{color:var(--ink)}

/* Hàng tìm kiếm: ô tìm co giãn, nút Thêm giữ đúng bề ngang chữ của nó.
   Trên màn hẹp thì xuống hàng chứ không ép ô tìm còn một mẩu. */
/* Mấy con số phụ (lượt xem, lượt chơi) nhạt hơn nhãn chính: chúng để liếc
   qua chứ không phải thứ cần đọc kỹ. */
.the-hat .hat.mo-nhat{color:var(--faint); border-color:transparent; padding-left:0}

/* Dấu "Của bạn" dán góc thẻ: bài mình gửi giờ nằm chung lưới với bài của cả
   nhà, nên phải nhận ra ngay mà không cần đọc chữ. */
.the-o{position:relative}
.the-cua-ban{
  position:absolute; top:8px; right:8px; z-index:2;
  font-size:10.5px; font-weight:600; letter-spacing:.04em;
  padding:3px 9px; border-radius:999px;
  background:var(--gold-vivid); color:var(--on-accent)}
.the-o.cua-toi{border-color:var(--gold-soft)}
.the-loc{margin-top:10px; max-width:280px}

.the-tim{display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-top:0}
.the-tim .text{flex:1 1 240px; min-width:0}
.the-tim .btn{flex:0 0 auto; width:auto}

/* Lưới TỰ THÍCH NGHI: rộng bao nhiêu thì xếp bấy nhiêu cột, đọc từ trái sang
   phải rồi xuống dòng. Ghim cứng hai cột thì màn 1600px phí một nửa bề ngang,
   còn điện thoại thì hai thẻ chen nhau bé xíu.
   280px là bề ngang nhỏ nhất mà bàn cờ tí hon còn đọc được thế; dưới ngần ấy
   thì rơi xuống một cột. Khe giữa các thẻ do `gap` giữ nên luôn đều nhau,
   hàng cuối thiếu thẻ cũng không kéo giãn cái nào. */
.the-luoi{display:grid; grid-template-columns:repeat(auto-fill, minmax(280px, 1fr));
  gap:14px; align-items:start}
@media (max-width:520px){ .the-luoi{grid-template-columns:1fr; gap:10px} }
.the-o{
  display:flex; flex-direction:column; gap:10px; text-decoration:none; color:inherit;
  transition:border-color .15s, transform .15s}
.the-o:hover{border-color:var(--gold-soft); transform:translateY(-1px)}
.the-ban{border-radius:9px; overflow:hidden}
.the-ban svg{display:block; width:100%; height:auto}
.the-chu{display:flex; flex-direction:column; gap:4px; min-width:0}
.the-chu b{font-size:14.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.the-chu .hint{margin:0; font-size:12px;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden}
.the-hat{display:flex; flex-wrap:wrap; gap:5px; margin-top:2px}
.the-hat .hat{font-size:10.5px; color:var(--faint);
  border:1px solid var(--edge); border-radius:6px; padding:1px 6px}

/* Trang một thế: bàn cờ to ở cột trái, bàn luận và bảng vàng ở cột phải —
   cùng khung với trang đang đánh, khỏi phải học lại chỗ nào là chỗ nào. */
.the-dau{display:flex; align-items:center; gap:10px; padding:9px 12px}
.the-dau-ten{flex:1; min-width:0; font-size:14.5px}
.the-dau-ten small{display:block; font-weight:400; font-size:11.5px; color:var(--muted)}
.the-dau .btn{flex:none; padding:6px 12px; font-size:12.5px; min-height:32px; width:auto}
/* Hàng ngay dưới bàn cờ, chia đôi: BÊN ĐI TRƯỚC | NÚT PHÁ THẾ, rồi dấu "?"
   ở cuối. Hai nửa đều flex:1 nên chia đúng đôi bề ngang bàn cờ.
   Chữ giữ màu mực thường, chỉ CHẤM mang màu quân: --piece-black là xanh thẫm
   #123048, in lên nền tím của chế độ tối thì gần như không đọc được. Chấm thì
   đeo thêm vành vàng nên nổi trên cả hai nền. */
/* Nút Đăng nhập ở góc trên bên phải, chỗ chip người dùng vẫn đứng. Viền vàng
   cho nó đọc ra là lối vào chứ không phải một nút thao tác nữa. */
.head-tools .btn.dangnhap{
  width:auto; flex:none; padding:8px 16px; font-size:13.5px; font-weight:600;
  border-color:var(--gold-soft); color:var(--gold)}
.head-tools .btn.dangnhap:hover{border-color:var(--gold); background:var(--surface-2)}
/* Lối khách trong hộp đăng nhập: nằm cuối, dưới một đường kẻ — đây là lối
   thoát cho người chỉ muốn thử một ván, không phải lối chính. */
/* Nút Google: trắng, viền xám, chữ G bốn màu — đúng hướng dẫn nhận diện của
   Google, và khác hẳn nút Facebook nên mắt không lẫn. */
/* Nút đóng hộp đăng nhập. Có lối chơi theo khách rồi thì đăng nhập không còn
   là cửa bắt buộc, nên phải có đường ra. */
.gate-x{
  position:absolute; top:8px; right:10px; width:32px; height:32px;
  display:grid; place-items:center; border:0; border-radius:50%;
  background:transparent; color:var(--faint); font-size:15px; cursor:pointer}
.gate-x:hover{background:var(--surface-2); color:var(--ink)}
.gate-card{position:relative}

.btn.gg{
  display:flex; align-items:center; justify-content:center; gap:10px;
  width:100%; margin-top:8px; min-height:44px; font-weight:600;
  background:#fff; color:#3c4043; border:1px solid #dadce0}
.btn.gg:hover{background:#f7f8f8; border-color:#c9cdd1}
.ggmark{
  width:20px; height:20px; flex:none; border-radius:50%;
  display:grid; place-items:center; font-weight:700; font-size:14px;
  font-family:Arial,Helvetica,sans-serif; color:#fff;
  background:conic-gradient(from -45deg,#EA4335 0 25%,#FBBC05 0 50%,#34A853 0 75%,#4285F4 0)}

/* Lối khách: nút viền vàng, đứng cuối. Không kẻ thêm vạch nữa — trên đã có
   một vạch "hoặc" rồi, hai vạch trong một hộp cao 400px là rối. */
.gate-khach{margin-top:12px; display:flex; flex-direction:column; gap:7px}
.btn.khach{width:100%; min-height:44px; font-weight:600; font-size:13.5px;
  color:var(--gold); border-color:var(--gold-soft); background:transparent}
.btn.khach:hover{background:var(--surface-2); border-color:var(--gold)}
.gate-nho{font-size:11.5px; line-height:1.45; color:var(--faint); text-align:center}
.umenu-i.nang{color:var(--gold); font-weight:600}

/* Cụm "bên đi trước + nút chơi" thả vào KHÚC SÔNG giữa bàn cờ.
   Toạ độ khớp chính xác chứ không ước lượng: SVG bàn cờ cao 104 đơn vị, hai
   mép sông nằm ở 47 và 57, nên tâm sông đúng bằng 50% chiều cao — top:50% là
   rơi giữa dải trống. Sông cũng là chỗ DUY NHẤT trên bàn không bao giờ có quân
   đứng (quân đứng trên các đường kẻ hai bên), nên mượn chỗ mà không che thế cờ.
   Cụm co theo nội dung chứ không kéo hết bề ngang như trước. */
.the-ban-khung{position:relative}
.the-hang{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); z-index:2;
  display:flex; align-items:stretch; justify-content:center; flex-wrap:wrap;
  /* width:max-content chứ không để auto: khối absolute đặt left:50% thì bề
     rộng khả dụng chỉ còn NỬA bàn cờ, nên auto sẽ bóp cụm lại và đẩy dấu ?
     xuống dòng thứ hai — lúc ấy cụm cao gấp đôi và tụt khỏi khúc sông. */
  /* Dải sông chỉ cao 10/104 chiều bàn cờ, nên cụm phải thấp hết mức mà vẫn
     bấm được: bó sát đệm trong, bỏ luôn đệm ngoài của tấm nền. */
  /* Một nhịp 5px cho TẤT CẢ: viền quanh tấm nền và khe giữa các nút bằng
     nhau, nên mắt đọc ra một cái khay chứ không phải mấy nút bị bóp dẹt vào
     một dải băng. Bản trước để 2px trên dưới và 5px hai bên cho tấm nền mỏng
     bớt — nhìn ra ngay là viền không đều.
     52px tổng (42 + 5 + 5) vẫn nằm gọn trong khúc sông: chỗ hẹp nhất đo được
     là 57px ở khổ màn rộng nhất. */
  gap:5px; width:max-content; max-width:calc(100% - 20px);
  padding:5px; border-radius:14px;
  /* Nền mờ để hai nút tách khỏi mặt gỗ, vẫn thấy đường kẻ bàn cờ phía sau. */
  background:color-mix(in srgb, var(--jet) 58%, transparent);
  backdrop-filter:blur(3px);
  box-shadow:0 10px 26px -12px rgba(0,0,0,.75)}
/* Chiều cao hai nửa khai MỘT chỗ, cho cả hai. Đặt riêng từng cái bằng đệm
   trong thì hai nửa lệch nhau vài pixel ngay — chữ trong chúng khác cỡ (13 và
   13.5) nên cùng một mức đệm ra hai chiều cao khác nhau.
   42px chứ không phải 35 như bản đầu: nút rộng 114 mà cao 35 là tỉ lệ 3.3:1,
   dẹt như một thanh nhãn chứ không ra một cái nút bấm. Đo trên bàn cờ thật,
   khúc sông cao 53–57px nên 42 + 8 đệm ngoài vẫn nằm gọn trong sông. */
.the-hang .the-ben, .the-hang .btn.primary{min-height:42px}
.the-hang .the-ben{
  flex:0 0 auto; min-width:0; display:flex; align-items:center; justify-content:center;
  gap:8px; padding:6px 11px; border-radius:9px; white-space:nowrap;
  background:var(--surface-2); border:1px solid var(--edge);
  font-size:13px; font-weight:600}
.the-hang .the-cham{
  width:13px; height:13px; border-radius:50%; flex:none;
  box-shadow:0 0 0 1px var(--disc-2), 0 0 0 2px #A6762F,
    inset 0 1px 1px rgba(255,255,255,.45)}
.the-ben.do  .the-cham{background:var(--piece-red)}
.the-ben.den .the-cham{background:var(--piece-black)}
.the-hang .btn.primary{flex:0 0 auto; min-width:0; padding:6px 22px; font-size:13.5px}
/* Nút Phá thế đập như nhịp tim: hai nhịp liền rồi nghỉ, chứ không phập phồng
   đều đều. Đều đều thì mắt đọc ra "cái gì đó đang tải"; hai nhịp rồi nghỉ mới
   đọc ra "bấm vào đây".
   Tên khung hình đặt RIÊNG. Trong tệp này đã có lần hai @keyframes trùng tên
   "pulse" đè nhau, và cái thua thì im lặng chứ không báo gì.
   Chế độ giảm chuyển động đã có luật chung ở đầu tệp tắt hộ. */
@keyframes nhipTim{
  0%   {box-shadow:0 0 0 0    color-mix(in srgb, var(--gold-vivid) 62%, transparent),
                   0 0 0    0 color-mix(in srgb, var(--gold-vivid)  0%, transparent)}
  10%  {box-shadow:0 0 0 6px color-mix(in srgb, var(--gold-vivid) 30%, transparent),
                   0 0 18px 2px color-mix(in srgb, var(--gold-vivid) 55%, transparent)}
  20%  {box-shadow:0 0 0 12px color-mix(in srgb, var(--gold-vivid) 0%, transparent),
                   0 0 6px  0 color-mix(in srgb, var(--gold-vivid) 12%, transparent)}
  30%  {box-shadow:0 0 0 5px color-mix(in srgb, var(--gold-vivid) 24%, transparent),
                   0 0 15px 1px color-mix(in srgb, var(--gold-vivid) 42%, transparent)}
  44%  {box-shadow:0 0 0 11px color-mix(in srgb, var(--gold-vivid) 0%, transparent),
                   0 0 0    0 color-mix(in srgb, var(--gold-vivid)  0%, transparent)}
  100% {box-shadow:0 0 0 0    color-mix(in srgb, var(--gold-vivid) 0%, transparent),
                   0 0 0    0 color-mix(in srgb, var(--gold-vivid) 0%, transparent)}
}
/* CHỈ quầng sáng đập, thân nút đứng yên. Cho nút phồng lên thu lại thì nó
   nhúc nhích dưới đầu ngón tay — bấm trượt, và máy tự bấm cũng chờ mãi không
   thấy nút "đứng im" mà bấm. Bạn cũng nói là "sáng nhấp nháy", không phải to
   nhỏ. */
.the-hang .btn.primary{animation:nhipTim 2.4s ease-in-out infinite}
.the-hang .btn.primary:hover,
.the-hang .btn.primary:focus-visible{animation-play-state:paused}
.the-hang .nut-hoi{flex:none; align-self:center}

/* Điện thoại: bàn cờ thu nhỏ thì dải sông cũng hẹp theo, đặt cụm lên đó là
   che mất quân hai bên bờ. Dưới mốc này trả về hàng riêng nằm dưới bàn như
   trước — vẫn gọn vì màn hình hẹp, hai nút chia đôi bề ngang là vừa tay bấm. */
@media (max-width:560px){
  .the-hang{
    position:static; transform:none;
    width:100%; max-width:none; padding:0; border-radius:0;
    background:none; backdrop-filter:none; box-shadow:none}
  /* Điện thoại: hàng nằm dưới bàn nên không bị khúc sông bó, cao thêm một
     chút nữa cho vừa ngón tay — 44px là mức Apple khuyên cho vùng chạm. */
  .the-hang .the-ben, .the-hang .btn.primary{min-height:44px}
  .the-hang .the-ben{flex:1 1 0; padding:9px 12px; font-size:13.5px}
  .the-hang .btn.primary{flex:1 1 0; padding:9px 10px}
  .the-hang .the-cham{width:15px; height:15px}
}

.the-ban-to{width:100%; border-radius:var(--radius); overflow:hidden;
  box-shadow:0 12px 30px -14px var(--shadow-strong)}
.the-ban-to svg{display:block; width:100%; height:auto}

/* Danh sách thế cờ CHỜ DUYỆT: bàn cờ tí hon bên trái, tên và mấy nút bên
   phải. Duyệt mà chỉ đọc được cái tên thì không duyệt được gì — phải nhìn
   thấy thế cờ. */
.cho-the{display:flex; gap:12px; align-items:flex-start; padding:10px 0;
  border-top:1px solid var(--edge)}
.cho-the:first-of-type{border-top:0}
.cho-ban{flex:0 0 132px; width:132px}
.cho-chu{flex:1; min-width:0; display:flex; flex-direction:column; gap:2px}
.cho-chu .hint{font-size:12px}

/* ═══════════ trình soạn thế cờ (superadmin) ═══════════ */
/* Màn hẹp: một cột, bàn trên công cụ dưới — thứ tự đọc tự nhiên.
   Máy tính (≥860px): bàn cờ chiếm 2 phần, cả cụm công cụ dồn sang cột phải 1
   phần. Trước đây công cụ nằm dưới bàn nên phải cuộn xuống mới thấy khay quân,
   mà kéo thả thì cần nhìn thấy CẢ HAI cùng lúc.
   Chặn bề ngang ở 1000px: để rộng nữa thì bàn soạn to hơn cả bàn đang đánh
   (trần 660px), soạn xong mở ra chơi lại thấy bé đi. */
.the-soan{display:flex; flex-direction:column; gap:12px; max-width:520px; margin-bottom:12px}
.soan-ban{min-width:0}
.soan-cu{display:flex; flex-direction:column; gap:12px; min-width:0}
@media (min-width:860px){
  .the-soan{display:grid; grid-template-columns:minmax(0,2fr) minmax(280px,1fr);
    gap:16px; align-items:start; max-width:1000px}
}
.soan-ban{display:flex; flex-direction:column; gap:10px}
/* Khay quân: bảy loại × hai màu, hai hàng cho khỏi phải vuốt ngang.

   Quân trong khay mượn lớp .pc để có đúng mặt gỗ của bàn cờ. Nhưng .pc là
   quân ĐANG NẰM TRÊN BÀN: nó định vị tuyệt đối, đo mọi thứ bằng cqw của khung
   bàn, và lùi nửa thân bằng margin ÂM. Đem ra khay thì không còn khung bàn nào
   để đo — cqw rơi về bề ngang MÀN HÌNH, quân phình thành quả trứng cao gần
   120px rồi margin âm kéo cả hàng tràn ra ngoài thẻ, đè lên bàn cờ phía trên.

   Nên khay tự dựng lấy khung đo (container-type), rồi khai lại đúng ba thứ
   .pc đã đặt cho bàn: cách định vị, margin, và cỡ. Giữ nguyên tỉ lệ chữ/thân
   của bàn cờ (5.0/8.9 ≈ 0.56) để chữ không bị to hơn hay bé hơn quân thật. */
/* Khay rộng đúng bằng bàn cờ và nằm sát trên/dưới nó, nên quân trong khay
   phải TO ĐÚNG BẰNG quân trên bàn — 8.9cqw, y như .pc. Lệch cỡ thì lúc nhấc
   lên hay thả xuống quân phình ra rồi teo lại, trông như bắt hụt.
   Xếp bằng flex chứ không lưới bảy cột: lưới thì mỗi ô rộng 1/7 bề ngang bàn
   (90px) trong khi quân chỉ 56px, bảy quân rải thưa hết cả hàng. */
.the-khay{display:flex; justify-content:center; flex-wrap:nowrap;
  container-type:inline-size}
.the-quan{
  /* Quân trong khay là <button>: trình duyệt tự đắp cho nó viền "2px outset".
     Suốt thời gian qua CHÍNH nó là vành vát của khay — đẹp, nhưng là tình cờ và
     mỗi trình duyệt vẽ một kiểu. Giờ vành ấy đã thành --vat-quan vẽ cố ý trong
     .pc, nên gỡ viền mặc định đi kẻo chồng hai lớp. */
  border:0;
  /* Khe giữa hai quân đặt bằng MARGIN của quân, không phải `gap` của khay.
     Một khối KHÔNG phải là khung đo của chính nó: `cqw` viết trong luật của
     .the-khay rơi ra khung bên ngoài — không có khung nào thì rơi hẳn về bề
     ngang MÀN HÌNH. Màn càng rộng khe càng nở, tới lúc bảy quân không đủ chỗ
     và con thứ bảy bị đẩy xuống hàng dưới. Viết ở con thì cqw đo đúng bề
     ngang khay, tức đúng bề ngang bàn cờ. */
  position:relative; margin:0 1.1cqw; padding:0;
  width:8.9cqw; height:8.9cqw; font-size:5cqw;
  cursor:grab; touch-action:none}
.the-quan:active{cursor:grabbing}
/* Quân đang được kéo, bám theo ngón tay. pointer-events:none để lớp bên dưới
   vẫn nhận được pointerup — không thì thả ở đâu cũng rơi vào chính nó. */
.the-bong{
  position:fixed; z-index:200; width:46px; height:46px; margin:-23px 0 0 -23px;
  display:grid; place-items:center; border-radius:50%;
  font-family:"Noto Serif TC","Songti SC",serif; font-weight:700; font-size:22px;
  pointer-events:none; opacity:.92;
  /* Bóng đổ, vòng trong và cả --vanh-quan của .pc đều đo bằng cqw. Quân bóng
     nằm position:fixed nên không có khung nào để đo — cqw rơi về bề ngang màn
     hình, quân 46px mà đeo vành gỗ dày 7px và kéo theo vệt mờ 36px.
     Khai lại bằng px. Vành ở đây rút còn hai vòng chứ không mượn --vanh-quan:
     quân bóng chỉ hiện lúc ngón tay đang kéo, bảy vòng đồng tâm ở cỡ này
     không ai kịp nhìn, mà lại thành một viền vàng dày trông như lỗi. */
  box-shadow:
    0 0 0 1px #E0B972,
    0 0 0 2px #A6762F,
    inset 1.75px 1.75px 0 rgba(226,226,228,.92),
    inset -1.75px -1.75px 0 rgba(42,42,48,.68),
    0 2px 3px -1px color-mix(in srgb, var(--line) 56%, transparent),
    0 7px 11px -3px color-mix(in srgb, var(--line) 64%, transparent),
    inset 0 2px 2px -1px rgba(255,255,255,.95),
    inset 0 -3px 3px -2px rgba(112,66,20,.44)}
.the-bong::before{inset:4px; border-width:1px; box-shadow:none}
/* Bàn soạn: không cho chọn chữ, kéo mà quét trúng chữ thì bôi đen cả trang. */
#stBan{user-select:none; touch-action:none}
#stBan .pc{cursor:grab}
